- Версия(и) Minecraft
- 1.7.10, 1.12.2, 1.14+
Недавно делал ремейк тутора по пакетной системе CodeChickenLib
и у меня сложилось новое виденье идеальной пакетной системы
и у меня сложилось новое виденье идеальной пакетной системы
ElegantNetworking - пакетная система, которая стремится максимально упростить разработку клиент-серверного взаимодействия в модах.
Примерно так выглядит объявление пакета:
Java:
@ElegantPacket
@Value //lombok
public class PacketExample implements ClientToServerPacket {
int someValue1;
MyClass someValue2;
Map<String, MyClass> someValue3;
@Override
public void onReceive(EntityPlayerMP player) {
//обработка пакета
}
}
Java:
new PacketExample(1, new MyClass(...), ImmutableMap.of(...)).sendToServer();
Основные фишки
- Авто-регистрация пакетов
- достаточно пометить аннотацией
- можно забыть про канал и идентификаторы пакетов
- Авто-сериализация/десериализация
- поддерживаются примитивы, коллекции и эквиваленты алгебраических типов данных
- возможно переопределить логику сериализации
- Структура пакета и его обработчик локализованы
- один пакет - один класс
- Дизайн апи располагает к тому, чтобы не зависеть от версии майнкрафта
- Совместимо с обфускаторами(чисто теоретически, еще не тестировал это)
Использование
Подключение к проектуДобавьте в свой build.gradle:
Выполните Gradle refresh в вашей ide
Если в проекте используется ломбок, то его процессор аннотаций нужно явно применять до процессора аннотаций ElegantNetworking. Для этого можно использовать плагин apt:
Gradle (Groovy):
dependencies {
compile fg.deobf("io.gitlab.hohserg.elegant.networking:elegant-networking-1.12:3.17")
compileOnly "io.gitlab.hohserg.elegant.networking:annotation-processor:3.16"
}
Если в проекте используется ломбок, то его процессор аннотаций нужно явно применять до процессора аннотаций ElegantNetworking. Для этого можно использовать плагин apt:
Gradle (Groovy):
buildscript {
repositories {
...
maven { url 'https://plugins.gradle.org/m2/' }
}
dependencies {
...
classpath 'net.ltgt.gradle:gradle-apt-plugin:0.9'
}
}
dependencies {
compile fg.deobf("io.gitlab.hohserg.elegant.networking:elegant-networking-1.12:3.17")
compileOnly "io.gitlab.hohserg.elegant.networking:annotation-processor:3.16" //для idea
apt 'org.projectlombok:lombok:1.18.8', "io.gitlab.hohserg.elegant.networking:annotation-processor:3.16"
}
Добавьте в свой build.gradle:
Если в проекте используется ломбок, то его процессор аннотаций нужно явно применять до процессора аннотаций ElegantNetworking:
Gradle (Groovy):
dependencies {
implementation fg.deobf("io.gitlab.hohserg.elegant.networking:elegant-networking-1.12:3.17")
compileOnly "io.gitlab.hohserg.elegant.networking:annotation-processor:3.16" //для idea
annotationProcessor "io.gitlab.hohserg.elegant.networking:annotation-processor:3.16"
}
Gradle (Groovy):
annotationProcessor 'org.projectlombok:lombok:1.18.8', "io.gitlab.hohserg.elegant.networking:annotation-processor:3.16"
fg.deobf
и deobfCompile
, CodeChickenCore для 1.7.10.В общем все тоже самое, что и при подключении к проекту любого другого мода как зависимости.
В заголовке ресурса через слеш: первая версия - версия процессора аннотаций, вторая - версия мод-либы
Создание пакета
1. Создайте новый класс для пакета.
Если ваш пакет должен отправляться с клиента на сервер, то он должен реализовывать
ClientToServerPacket
.Если должен отправляться с сервера на клиент, то он должен наследоваться от
ServerToClientPacket
2. Реализуйте нужный интерфейс.
Метод onReceive будет вызываться при получении пакета
3. Пометьте ваш класс пакета аннотацией
@ElegantPacket
Опционально, в ней можно указать строковый id канала(может иметь смысл, если в одном jar несколько модов)
4. Добавьте поля, представляющие передаваемую информацию
Можно использовать Lombok, чтобы сгенерировать удобный конструктор, геттеры и сеттеры
5. Опционально можно переопределить логику сериализации. Для этого переопределите метод serialize, он должен возвращать ByteBuf-представление вашего пакета. И создайте конструктор, принимающий ByteBuf, он должен делать обратное действие
Пример:
Java:
@ElegantPacket
@Value
public class ExamplePacket implements ServerToClientPacket {
int someInt;
Map<MyClass, String> someMap;
@Override
public void onReceive(Minecraft mc) {
System.out.println("test "+someInt+" "+someMap);
}
}
Просто создайте экземпляр вашего пакета с нужными значениями полей и вызовите один из send-методов
ClientToServerPacket
имеет один метод - sendToServer
ServerToClientPacket
имеет целый набор удобных методов для отправки пакета клиентам
Java:
//Отправка someInt=1 и someMap={new MyClass("test") -> "lol"} всем игрокам в измерении world
new ExamplePacket(1, ImmutableMap.of(new MyClass("test"), "lol")).sendToDimension(world);
Примеры
GitHub - ElegantNetworking/Examples: Examples projects with EN
Examples projects with EN. Contribute to ElegantNetworking/Examples development by creating an account on GitHub.
github.com
Благодарности
Спасибо @GlassSpirit за отличный гайд по пакетам и за вытаскивание меня из дерьма!Спасибо @Dahaka за обсуждение концепции и ревью
Спасибо @tox1cozZ за то что обратил моё внимание на процессоры аннотаций
Спасибо @Plasticable за совет о юзе 4.4.1 версии gradle
Спасибо @Icosider за консультацию по настройке gradle
Спасибо @AmaZ1nG за идею о сериализации нбт и других стандартных значений майна
Спасибо @jopi за черновой вариант порта на 1.7.10
Спасибо @CDAGaming за форк FG1.2, работающий с Gradle5+
Спасибо @Liahim за классную иконку
Спасибо @GoogleTan за тестирование и подробные репорты
Спасибо @anatawa12 за прекрасный форк FG1.2 и @GlassSpirit за помощь в настройке воркспейса с этим форком!
Ссылки
Гитхаб: ElegantNetworking/ElegantNetworkingRoot
Курс: curseforge.com/elegant-networking