- 808
- 3
- 124
В коммерческих проектах постоянно возникает необходимость защищать свой код от декомпиляции и от использования другими проектами. Не будем о том, насколько хорошо или плохо зарабатывать на игре, лицензионное соглашение которой этого не особо позволяет.
Для начала разделим проблему на две, серьезную и не очень.
1) Нехорошие люди на самом деле на самом деле декомпилируют мод и получают рабочие сорцы.
2) Нехорошие, но глупые люди думают, что декомпилировали мод, хотя на самом деле полученные сорцы работать как надо не будут. Несмотря на кажущуюся несерьезность проблемы, такие люди способны изрядно подпортить нервы.
Две проблемы - два решения. К счастью, первая проблема решается существенно проще. Я расскажу о том, как защищать серверную часть модов, и чуть-чуть о том, как обфусцировать моды.
[h]Защита серверной части[/h]
Довольно существенная часть кода в мультиплеере никогда не выполняется на клиентской стороне (в моем случае - около 15%). Два самых очевидных примера - обработка пакетов на сервере и подобные куски кода:
Если полностью вырезать такой код из клиента, то даже после успешной декомпиляции восстановить его будет почти невозможно. В большинстве случаев написать аналогичный мод с нуля будет быстрее, чем разбираться в том, каких участков кода где не хватает и что на их месте нужно дописать. Однако, каждый раз вырезать часть кода при сборке мода - сущая мука. К счастью, компилятор javac достаточно умён для того, чтобы нам в этом помочь.
Пишем где-нибудь (желательно - в отдельном классе) вот такую строку:
Допустим, эту константу завели в классе CompilationFlag. Тогда перед каждым серверным куском кода нужно проверить эту константу. Два простых примера:
При компиляции с SERVER == false такие участки кода попросту выбрасываются. Значение этой константы можно менять руками при каждой сборке и собирать по две версии мода - серверную и клиентскую. Когда надоест менять значение руками, напишете собирающий скрипт. Раз написали мод, должны справиться и с этим . Свой скрипт выкладывать не вижу смысла, это костыльная поделка конкретно под мой проект.
[h]Обфускация[/h]
Первое решение хорошо своей надежностью и простотой, но у него есть и свои недостатки. Я уже выше жаловался на дурачков, которые хвастаются тем, что "взломали мод", но это не единственная проблема. Есть еще как минимум две.
1) Выкидывание серверной части ломает синглплеер.
2) Иногда хочется защитить не весь мод, а какое-то конкретный элемент, который целиком выполняется на клиенте.
Если все три перечисленные проблемы вас не касаются, то можете смело закрывать гайд и идти реализовывать первое решение. Если же нет, то вам может придти на помощь обфускация.В самом простом варианте обфускация - это просто замена названий классов, полей и методов на не имеющие смысла. Именно такой вид обфускации применяется в Minecraft'e, и, как вы могли заметить, ее успешно "сломали" разработчики MCP . Тем не менее, более серьезная обфускация стоит денег, снижает производительность, да и вообще не очень понятно зачем нужна. Ваш мод - не Minecraft, и тратить сотни человекочасов на разбор обфусцированного кода никто не будет. Предупреждаю сразу: с обфускацией возни намного больше, чем с первым способом. Её сложно настраивать, легко сломать иневозможно забыть она усложняет отладку мода.
Я не рискну в подробностях рассказывать про обфускацию модов. Моё нынешнее решение - это велосипед из костылей, и учить кого-то такому мне стыдно. Расскажу лишь в общих чертах, как стоит делать. Я подобный путь не проверял, но оно должно работать.
1) Качаем ProGuard здесь. Он обфусцирует джарники по куче параметров, которые задаются через специальные конфиги. К счастью, вместе с ProGuard идет утилита под названием ProGuardGUI, через которую этот конфиг можно создать. Писать про эту кучу настроек долго, да и там всё более-менее понятно. Расскажу лишь про основные моменты.
2) В либы добавляем майн, либы майна и фордж (если он идет отдельным файлов).
3) В input добавляем джарник с модом, в output его же
4) В список классов, которые не нужно обфусцировать добавляем главный класс и CommonProxy/ClientProxy. Если есть еще какие-то классы, название которых указывается строками в коде, то их тоже добавляем.
5) Выключаем obfuscation -> use mixed-case class names. Ну то есть можно и оставить, но сами же будете страдать.
Для начала разделим проблему на две, серьезную и не очень.
1) Нехорошие люди на самом деле на самом деле декомпилируют мод и получают рабочие сорцы.
2) Нехорошие, но глупые люди думают, что декомпилировали мод, хотя на самом деле полученные сорцы работать как надо не будут. Несмотря на кажущуюся несерьезность проблемы, такие люди способны изрядно подпортить нервы.
Две проблемы - два решения. К счастью, первая проблема решается существенно проще. Я расскажу о том, как защищать серверную часть модов, и чуть-чуть о том, как обфусцировать моды.
[h]Защита серверной части[/h]
Довольно существенная часть кода в мультиплеере никогда не выполняется на клиентской стороне (в моем случае - около 15%). Два самых очевидных примера - обработка пакетов на сервере и подобные куски кода:
Код:
if (!world.isRemote){
//какой-нибудь серверный код
}
Пишем где-нибудь (желательно - в отдельном классе) вот такую строку:
Код:
public static final boolean SERVER = true; //или false, когда будете делать клиентскую сборку
Код:
public void someMethod(){
//общий код
if (CompilationFlag.SERVER){
if (!world.isRemote){
//серверный код
}
}
}
Код:
//метод, который выполняется только на сервере
public void serverSideMethod(){
if (!CompilationFlag.SERVER) return;
//код метода
}
При компиляции с SERVER == false такие участки кода попросту выбрасываются. Значение этой константы можно менять руками при каждой сборке и собирать по две версии мода - серверную и клиентскую. Когда надоест менять значение руками, напишете собирающий скрипт. Раз написали мод, должны справиться и с этим . Свой скрипт выкладывать не вижу смысла, это костыльная поделка конкретно под мой проект.
[h]Обфускация[/h]
Первое решение хорошо своей надежностью и простотой, но у него есть и свои недостатки. Я уже выше жаловался на дурачков, которые хвастаются тем, что "взломали мод", но это не единственная проблема. Есть еще как минимум две.
1) Выкидывание серверной части ломает синглплеер.
2) Иногда хочется защитить не весь мод, а какое-то конкретный элемент, который целиком выполняется на клиенте.
Если все три перечисленные проблемы вас не касаются, то можете смело закрывать гайд и идти реализовывать первое решение. Если же нет, то вам может придти на помощь обфускация.В самом простом варианте обфускация - это просто замена названий классов, полей и методов на не имеющие смысла. Именно такой вид обфускации применяется в Minecraft'e, и, как вы могли заметить, ее успешно "сломали" разработчики MCP . Тем не менее, более серьезная обфускация стоит денег, снижает производительность, да и вообще не очень понятно зачем нужна. Ваш мод - не Minecraft, и тратить сотни человекочасов на разбор обфусцированного кода никто не будет. Предупреждаю сразу: с обфускацией возни намного больше, чем с первым способом. Её сложно настраивать, легко сломать и
Я не рискну в подробностях рассказывать про обфускацию модов. Моё нынешнее решение - это велосипед из костылей, и учить кого-то такому мне стыдно. Расскажу лишь в общих чертах, как стоит делать. Я подобный путь не проверял, но оно должно работать.
1) Качаем ProGuard здесь. Он обфусцирует джарники по куче параметров, которые задаются через специальные конфиги. К счастью, вместе с ProGuard идет утилита под названием ProGuardGUI, через которую этот конфиг можно создать. Писать про эту кучу настроек долго, да и там всё более-менее понятно. Расскажу лишь про основные моменты.
2) В либы добавляем майн, либы майна и фордж (если он идет отдельным файлов).
3) В input добавляем джарник с модом, в output его же
4) В список классов, которые не нужно обфусцировать добавляем главный класс и CommonProxy/ClientProxy. Если есть еще какие-то классы, название которых указывается строками в коде, то их тоже добавляем.
5) Выключаем obfuscation -> use mixed-case class names. Ну то есть можно и оставить, но сами же будете страдать.