Например, это может пригодится если вы хотите сделать меню кланов. У вас есть плагин (либо самописный, либо с исходниками) и вам необходимо реализовать на клиенте ГУИ с информацией и всякими кнопочкам для редактирования («Выйти из клана», «Повысить игрока» и бла-бла-бла).
Часть мода
Спойлер: Обработчик пакетов в моде
Начнем сие процессию с создания класса-обработчика пакетов в МОДЕ.
Спойлер: BasePacket.class
/** Created by keelfy */ //Этот абстрактный класс — основа для остальных пакетов public abstract class BasePacket < //Да-да, нам нужен пустой конструктор public BasePacket()<>//Метод для записи в поток данных public abstract void write(ByteBuf data) throws IndexOutOfBoundsException; //Метод для чтения из потока данных public abstract void read(ByteBuf data) throws IndexOutOfBoundsException; //ООО-чень полезный метод для записи строки в поток public void writeString(String string, ByteBuf data) throws IndexOutOfBoundsException < byte[] stringBytes = string.getBytes(); data.writeInt(stringBytes.length); data.writeBytes(stringBytes); >//И для чтения строки из потока public String readString(ByteBuf data) throws IndexOutOfBoundsException < int length = data.readInt(); byte[] stringBytes = new byte[length]; data.readBytes(stringBytes); return new String(stringBytes); >>
Так же, нам нужны абстрактные классы отдельно для серверных пакетов (те пакеты, что мод будет принимать) и для клиентских (те пакеты, которые будут отправлены на сервер)
ПЛАГИН НА ЛОТЕРЕЮ В МАЙНКРАФТ!!! ОБЗОР ПЛАГИНА BLASTJACKPOT!!!
Спойлер: Enum of Packets
/** Created by keelfy */ public enum EnumPacket < //Клиентские пакеты GUILD_NAME(C0PacketName.class), //Этот пакет будет принимать отосланный сервером пакет с данными //Серверные пакеты GUILD_GETNAME(S0PacketGetName.class); //Этот пакет будет отправляться на сервер, из нужной части нашего мода, и говорить ему что нужно отправить в клиент иноформацию о нике игрока (в нашем случае) //Методами ниже я получаю класс пакета (в скобочках указан), нужно для установки дискриминаторов private ClasspacketClass; private EnumPacket(Class packetClass) < this.packetClass = packetClass; >public Class getPacketClass() < return packetClass; >>
Спойлер: Классы пакетов
Спойлер: Заключение работы с модом
Под конец добавим строку в инициализацию мода
new PacketHandlerClient();
Будем, для примера, посылать пакет-запрос на сервер по нажатию кнопки и выводить полученные данные в консоль
Созданим KeyHandler для обработчки биндов, а в чат информацию мы уже и так выводим
И регистрируем обработчик биндов в инициализации
new KeyHandler();
Часть плагина
Спойлер: Регистрация каналов в плагине
//ВНИМАНИЕ! Название каналов должно быть везде одинаковым! В моде, в плагине.
//В onEnable() Bukkit.getMessenger().registerOutgoingPluginChannel(plugin, «yourchannelfrommod»); Bukkit.getMessenger().registerIncomingPluginChannel(plugin, «yourchannelfrommod», new PacketHandlerPlugin(this)); //В onDisable() Bukkit.getMessenger().unregisterIncomingPluginChannel(plugin, «yourchannelfrommod»);
Спойлер: Классы пакетов
Базовый класс для пакетов
МАЙНКРАФТ ПЛАГИН НА ЛЕЧЕНИЕ ! #minecraft #plugins #shorts
//Без комментариев. Идентичен с его собратом из мода /** Created by keelfy */ public abstract class BasePacket < public abstract void write(ByteBuffer data) throws BufferOverflowException; public abstract void read(ByteBuffer data) throws BufferUnderflowException; //Только добавился один метод. Отвечает за настройку размера пакета public abstract int getSize(); public static void writeString(String string, ByteBuffer data) throws BufferOverflowException < byte[] stringBytes = string.getBytes(); data.putInt(stringBytes.length); data.put(stringBytes); >public static String readString(ByteBuffer data) throws BufferUnderflowException < int length = data.getInt(); byte[] stringBytes = new byte[length]; data.get(stringBytes); return new String(stringBytes); >>
2 абстрактных пакета для клиентских и серверных пакетов
Только в плагине значения клиентского и серверного пакетов меняются. Клиентский отправляет пакеты, серверный — наобарот
Сами пакеты
Спойлер: Enum of Packets
/** Created by keelfy */ public enum EnumPacket < //Клиентские пакеты GUILD_NAME(S0PacketName.class), //Этот пакет будет отправлять пакет с именем //Серверные пакеты GUILD_GETNAME(C0PacketGetName.class); //Этот пакет будет ловить информацию, отправленную модом private ClasspacketClass; private EnumPacket(Class packetClass) < this.packetClass = packetClass; >public Class getPacketClass() < return packetClass; >>
Спойлер: Работа с дискриминаторами пакетов (ID)
//Сие творение ОТ ЧАСТИ не мое, так что не осмелюсь тут ставить свои копирайты public class PacketManager < //Коллекция дискриминаторов private static HashMap, Byte> discriminators; //Коллекция классов-пакетов private static HashMap> classes; public PacketManager() < //Инициализируем нужные переменные discriminators = new HashMap, Byte>(); classes = new HashMap>(); //Добавляем дискриминаторы для наших пакетов initDiscriminators(); > private static void initDiscriminators() < //Система схожа с форджевской, только метод addDiscriminator() придется делать самим :с for (EnumPacket type : EnumPacket.values()) < addDiscriminator((byte) type.ordinal(), type.getPacketClass()); >> //Метод для добавления новых дискриминаторов public static void addDiscriminator(byte discriminator, Class clazz) < //Проверяем, не зарегистрирован ли уже указанный пакет if (!discriminators.containsKey(clazz) !classes.containsKey(discriminator)) < //Добавляем информацию о пакете и даем ему дискриминатор discriminators.put(clazz, discriminator); classes.put(discriminator, clazz); >> //Метод для получения дискриминатора public static byte getDiscriminator(Class clazz) < return discriminators.get(clazz); >//Метод для получения класса пакета по дискриминатору public static Class getDiscriminatorClass(byte discriminator) < return classes.get(discriminator); >//Метод опрделеяет какой пакет был получен в виде байтов и возвращает его public static BasePacket getPacketFromBytes(byte[] bytes) throws BufferUnderflowException, InstantiationException, IllegalAccessException < ByteBuffer data = ByteBuffer.wrap(bytes).asReadOnlyBuffer(); byte discriminator = data.get(); ClasspacketClass = getDiscriminatorClass(discriminator); BasePacket packet = packetClass.newInstance(); packet.read(data); return packet; > //Метод записывает указанный пакет в байты для отправки public static byte[] getBytesFromPacket(BasePacket packet) throws BufferOverflowException < byte discriminator = getDiscriminator(packet.getClass()); ByteBuffer buffer = ByteBuffer.allocate(packet.getSize() + Byte.SIZE); buffer.put(discriminator); packet.write(buffer); return buffer.array(); >>
Регистрируем дискриминаторы пакетов при запуске
//В onEnable() new PacketManager();
Спойлер: Обработчик пакетов
Регистрируем обработчик при запуске
//В onEnable() new PacketHandlerPlugin(this);
Все, должно работать! Ошибки пишите в комментарии, отзывы и предложения туда же
Обещал выпустить эту тему намного раньше, но время не хватило даже на одну тему :c
Последнее редактирование: 10 Авг 2018
Мои уроки и переводы иностранных (1.7.10 — устарело)
Связь со мной
Mastaxys
На 1.8.8 не хочет работать. При создании в Эклипсе выдает ошибки в главном классе PacketHandlerClient.
Во всех остальных классах без ошибок.
timaxa007
Модератор
5,831 409 672
Первый скриншот, говорит о не достающих методов, которые нужно создать. Возможно старые методы не подходят для новых.
Возможно WGSPacket должен быть BasePacket. И возможно из-за этого он и попросил добавить не достающий метод.
Ну, как-то так. Я тоже могу ошибаться. Я пишу на 1.7.10.
Mastaxys
timaxa007 написал(а):
Возможно WGSPacket должен быть BasePacket. И возможно из-за этого он и попросил добавить не достающий метод.
Так и есть. Спасибо.
PS. Исправьте в уроке )
keelfy
Mastaxys написал(а):
Так и есть. Спасибо.
PS. Исправьте в уроке )
Мои уроки и переводы иностранных (1.7.10 — устарело)
Связь со мной
Mastaxys
В части мода ошибок нет, но вот в части плагина да. Видимо копировали код из своего проекта и кое какие методы остались оттуда.
//В onEnable() Bukkit.getMessenger().registerOutgoingPluginChannel(plugin, «yourchannelfrommod»); Bukkit.getMessenger().registerIncomingPluginChannel(plugin, «yourchannelfrommod», new PacketHandlerServer(this));
Хотя тут же указывается что название класса не PacketHandlerServer, а PacketHandlerPlugin.
Скопированный EnumPacket из мода выдает ошибку, пришлось поправить:
public enum EnumPacket < //Клиентские пакеты GUILD_NAME(C0PacketGetName.class), //Этот пакет будет принимать отосланный сервером пакет с данными //Серверные пакеты GUILD_GETNAME(S0PacketName.class); //Этот пакет будет отправляться на сервер, из нужной части нашего мода, и говорить ему что нужно отправить в клиент иноформацию о нике игрока (в нашем случае) //Методами ниже я получаю класс пакета (в скобочках указан), нужно для установки дискриминаторов private ClasspacketClass; private EnumPacket(Class packetClass) < packetClass = packetClass; >public Class getPacketClass() < return packetClass; >>
Много где добавил к методам void.
В итоге при отправке пакета из мода, во время его обработки Дискриминатором вылетает ошибка в лог сервера:
[00:41:52] [Server thread/WARN]: java.lang.NullPointerException [00:41:52] [Server thread/WARN]: at com.packets.PacketManager.getPacketFromBytes(PacketManager.java:66) [00:41:52] [Server thread/WARN]: at com.packets.PacketHandlerPlugin.onPluginMessageReceived(PacketHandlerPlugin.java:30) [00:41:52] [Server thread/WARN]: at org.bukkit.plugin.messaging.StandardMessenger.dispatchIncomingMessage(StandardMessenger.java:427) [00:41:52] [Server thread/WARN]: at net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java:2114) [00:41:52] [Server thread/WARN]: at net.minecraft.server.v1_8_R3.PacketPlayInCustomPayload.a(SourceFile:55) [00:41:52] [Server thread/WARN]: at net.minecraft.server.v1_8_R3.PacketPlayInCustomPayload.a(SourceFile:8) [00:41:52] [Server thread/WARN]: at net.minecraft.server.v1_8_R3.PlayerConnectionUtils$1.run(SourceFile:13) [00:41:52] [Server thread/WARN]: at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [00:41:52] [Server thread/WARN]: at java.util.concurrent.FutureTask.run(Unknown Source) [00:41:52] [Server thread/WARN]: at net.minecraft.server.v1_8_R3.SystemUtils.a(SourceFile:44) [00:41:52] [Server thread/WARN]: at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:715) [00:41:52] [Server thread/WARN]: at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:374) [00:41:52] [Server thread/WARN]: at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:654) [00:41:52] [Server thread/WARN]: at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:557) [00:41:52] [Server thread/WARN]: at java.lang.Thread.run(Unknown Source)
Спойлер: Вот мой PacketManager
public class PacketManager < //Коллекция дискриминаторов private HashMap, Byte> discriminators; //Коллекция классов-пакетов private static HashMap> classes; public PacketManager() < //Инициализируем нужные переменные this.discriminators = new HashMap, Byte>(); this.classes = new HashMap>(); //Добавляем дискриминаторы для наших пакетов this.initDiscriminators(); > private void initDiscriminators() < //Система схожа с форджевской, только метод addDiscriminator() придется делать самим :с for (EnumPacket type : EnumPacket.values()) < this.addDiscriminator((byte) type.ordinal(), type.getPacketClass()); >> //Метод для добавления новых дискриминаторов public void addDiscriminator(byte discriminator, Class clazz) < //Проверяем, не зарегистрирован ли уже указанный пакет if (!this.discriminators.containsKey(clazz) !this.classes.containsKey(discriminator)) < //Добавляем информацию о пакете и даем ему дискриминатор this.discriminators.put(clazz, discriminator); this.classes.put(discriminator, clazz); >> //Метод для получения дискриминатора public byte getDiscriminator(Class clazz) < return this.discriminators.get(clazz); >//Метод для получения класса пакета по дискриминатору public static Class getDiscriminatorClass(byte discriminator) < return classes.get(discriminator); >//Метод опрделеяет какой пакет был получен в виде байтов и возвращает его public static BasePacket getPacketFromBytes(byte[] bytes) throws BufferUnderflowException, InstantiationException, IllegalAccessException < ByteBuffer data = ByteBuffer.wrap(bytes).asReadOnlyBuffer(); byte discriminator = data.get(); ClasspacketClass = getDiscriminatorClass(discriminator); BasePacket packet = packetClass.newInstance(); packet.read(data); return packet; > //Метод записывает указанный пакет в байты для отправки public byte[] getBytesFromPacket(BasePacket packet) throws BufferOverflowException
Источник: forum.mcmodding.ru
AskMe — плагин на викторины или чат-игру [Все версии]
AskMe — очень удобный и практичный плагин. Этот плагин служит для чат-игры или викторины. Он подойдёт для новичков имеющих свой сервер, а настройка не требует знаний программирования. В его конфиге есть инструкция и примеры, так же он переведён на русский язык.
Вот я рассказал плюсы этого плагина, но есть и минусы. Главный минус это что-бы участвовать в чат-игре/викторине, по умолчанию надо писать > перед ответом. Пример: >ответ .
Но если вы не хотите этого писать то можно поменять в этой строчке: answerPrefix: «>» , в скобках пишите любой знак или можно убрать вообще, ответ тоже будет засчитываться. Второй минус что надо делать вопросы в чётном количестве. Плагин не мой, автор этого плагина Qmaks.
# Плагин разработан пользователем форума rubukkit.org под ником Qmaks. # Официальная тема плагина -> http://rubukkit.org/threads/fun-askme-zadaj-igrokam-parochku-voprosov-vse-versii.130026/ # Страница создателя на форуме (Все вопросы, просьбы, предложения в личку) -> http://rubukkit.org/members/qmaks.45892/ # Порядок задавания вопросов: # 1 — рандомно (В неизвестном порядке). # 2 — по порядку (От первого до последнего вопроса и так по кругу). mode: 1 # Задержка перед задаванием следующего вопроса. # Время до следующего вопроса после ответа на поставленный вопрос или сообщения о истечении времени, отведенного на ответ на заданный вопрос. # Указывается в секундах. # 60 секунд — 1 минута (Пасиба, Кэп). gameDelay: 60 # Время, отведенное на ответ на заданный вопрос. # Указывается в секундах, соответственно. gamePeriod: 30 # Символ, который должен стоять вначале ответа или предложения и т.д. # Т.е если вы что-то напишите туда, то для того, чтоб сообщение считалось «ответом» надо поставить вначале этот символ. # Если же нам не нужна данная функция, то просто оставляем поле пустым. # По дефолту вначале сообщения должна стоять стрелочка вправо (Т.е в чат надо будет отвечать так: >Ответ на вопрос). # Если мы ее уберем (Смотреться будет так: answerPrefix: «»), то в чат надо будет отвечать так: Ответ на вопрос. answerPrefix: «>» # Выводимый в чат префикс плагина # Placeholder: # Используется в нижеприведенных примерах вопросов. pluginPrefix: «6AskMer» # То, что выводится в чат когда пробивает час умников и умниц. # Тут так-же используется placeholder , вместо него высвечивается вопрос. question-msg: — «#9608; c» — «#9608;» — «#9608; — «#9608;» — «#9608;» # Список вопросов. questions: # Номер вопроса 1: # Вопрос # Placeholder — question: «Чему равно число ПИ если его сократить до сотых?» # Все возможные ответы. Регистр не учитывается. answers: — «3.14» — «3,14» # Команда, выполняемая от имени консоли в случае правильного ответа от игрока. # Placeholder — игрок, отправивший ответ. # В данном примере правильно ответившему игроку прибавляется 3000$ на баланс. reward-command: «eco give 3000″ # Сообщение, выводимое при отправлении неверного ответа. # Placeholder — префикс плагина. # Placeholder — игрок, отправивший ответ. wrong-answer: » # Сообщение, выводимое при отправлении верного ответа. # Placeholder — префикс плагина. # Placeholder — игрок, отправивший ответ. correct-answer: » # Сообщение, выводимое в общий чат при истечении выделенного времени для ответа на вопрос. # Placeholder — префикс плагина. no-reply-msg: » # Сообщение, выводимое при отправлении игроком верного ответа. # Placeholder — префикс плагина. # Placeholder — игрок, отправивший ответ. massnotification: » 2: question: «Какая гора считается самой высокой?» answers: — «Эверест» reward-command: «give diamond_sword» wrong-answer: » correct-answer: » no-reply-msg: » massnotification: »
Установка:
- Скачать плагин
- Скачанный плагин переместить в папку plugins (Эта папка в папке с сервером)
- Включить | перезагрузить сервер
- Готово! Можно пользоваться!
Источник: tlauncher-download.ru
Скачать плагин ChatGames | Чат-игра Решение примеров
ChatGames — мини-игра для чата «Реши пример», из названия понятно что вам нужно будет решить пример за какой-то определенный отрезок времени, а если вы ответите на верно первым, Вы получите денежное вознаграждение.
Основные команды и права плагина ChatGames:
Команд нету, права не нужны.
Конфиг плагина ChatGames:
# Это будет одно из минимальных сгенерированных чисел. Целое число не будет идти ниже минимального числа.
# Должен быть положительным!
Minimum-Number: 10
# Это будет одно из максимальных сгенерированных чисел. Целое число не будет превышать максимальное число.
# Должен быть положительным!
Maximum-Number: 1000
# Время, через которое будет появляться пример
Cooldown: 120
# Время на обдумывание
Game-Timer: 30
# Вознаграждение за правильный ответ
Reward: 1000
Как установить?
1. Скачайте плагин.
2. Из архива возьмите скачанный файл и перенесите в папку plugins вашего сервера.
3. Перезапустите сервер.
4. Готово.
Источник: minesborka.com