Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

Помогите Как добавить в класс поле или метод не переписывая сам класс?

JonBoss

Активный участник
Пользователь
Баллы
76
Имя в Minecraft
Jon
Я хочу добавить в класс Player дополнительное поле, чтобы не юзать HashMap. Это возможно как-то сделать, не переписывая ядро?
 
А чем HashMap не угодил?
Ожидал этого вопроса :)
Ну он дает нагрузку, особенно когда его используешь в PlayerMoveEvent.
Да и мне вообще интересно, возможно ли сделать, как я хочу.
Много хочешь. Юзай метадату
Тоесть это невозможно? Я не говорю даже про плагин. Например, написать java программу, которая будет предварительно изменять класс Player, а после уже запускать ядро сервера. Своего рода запускатор.
Это позволит изменять ядро сервера без каких либо правок.
 
Тоесть это невозможно? Я не говорю даже про плагин. Например, написать java программу, которая будет предварительно изменять класс Player, а после уже запускать ядро сервера. Своего рода запускатор.
Это позволит изменять ядро сервера без каких либо правок.
NMS/OBC можно изменить и без таких ухищрений. Сделать объект расширяющий CraftPlayer, а потом подменять им настоящего игрока с помощью рефлексий. Правда это не всегда подходит.
 
NMS можно изменить и без таких ухищрений. Сделать объект расширяющий CraftPlayer, а потом подменять им настоящего игрока с помощью рефлексий.
Как сделать объект расширяющий CraftPlayer?
Есть идея еще размещать нужные мне объекты рядом друг с другом в оперативной памяти. И ссылаться по ним, как по массиву. Но я не знаю, как это все делать..
 
Есть идея еще размещать нужные мне объекты рядом друг с другом в оперативной памяти. И ссылаться по ним, как по массиву. Но я не знаю, как это все делать..
А как тогда выбирать объект именно для определенного игрока?
Как сделать объект расширяющий CraftPlayer?
Для начала надо подключить craftbukkit как билиотеку
И чтобы плагин работал на разных версиях, придется писать этот класс отдельно под каждую версию (ну почти) и в зависимости от того на какой версии запускается, создавать нужный объект.
 
А как тогда выбирать объект именно для определенного игрока?

Для начала надо подключить craftbukkit как билиотеку
Ну брать Player, получать его указатель и сдвинуться на след. ячейку в ОП, а там уже будет нужный мне указатель на мою мета дату. Но это костыли в квадрате :)

craftbukkit? А spigot не подходит?
А как тогда выбирать объект именно для определенного игрока?

Для начала надо подключить craftbukkit как билиотеку
И чтобы плагин работал на разных версиях, придется писать этот класс отдельно под каждую версию (ну почти) и в зависимости от того на какой версии запускается, создавать нужный объект.
А почему под каждую версию, если я только хочу добавить поле, а не убрать, например? Тоесть по идее, не важно какая версия класса

Кароче я нашел инфу, щас будем вникать http://www.quizful.net/post/java-reflection-api
 
Ну он дает нагрузку, особенно когда его используешь в PlayerMoveEvent.
Слушать PME 4 раза в секунду - ?
Этого обычно достаточно чтобы творить с игроком что хочешь. Правда, если ты будешь отменять эвент, то тут уже грустнее всё.
 
А почему под каждую версию, если я только хочу добавить поле, а не убрать, например? Тоесть по идее, не важно какая версия класса
Потому что в разных версиях этот класс находится в разных пакетах. Вот например в 1.8.4 - 1.8.8 он в
org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer
А в 1.7.10 в org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer
Ну брать Player, получать его указатель и сдвинуться на след. ячейку в ОП, а там уже будет нужный мне указатель на мою мета дату. Но это костыли в квадрате :)
Указатели в Java? o.o
Даже если такое существует, то кто гарантирует, что место в памяти рядом с Player не занято?
По сути сама переменная, является ссылкой на объект в памяти.

craftbukkit? А spigot не подходит?
Подходит, в него же входит craftbukkit. Но лучше все-таки тык чтобы ничего лишнего не порасширять (я не в курсе что там в Spigot'e)
 
Последнее редактирование:
Слушать PME 4 раза в секунду - ?
Этого обычно достаточно чтобы творить с игроком что хочешь. Правда, если ты будешь отменять эвент, то тут уже грустнее всё.
Это неплохая идея.
Но я все же хочу попробовать сделать по своему, ибо всегда приходится что-то хранить о игроке. Почему бы не сделать проще?
Потому что в разных версиях этот класс находится в разных пакетах. Вот например в 1.8.4 - 1.8.8 он в
org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer
А в 1.7.10 в org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer

Указатели в Java? o.o
Даже если такое существует, то кто гарантирует, что место в памяти рядом с Player не занято?


Подходит, в него же входит craftbukkit. Но лучше все-таки тык чтобы ничего лишнего не порасширять (я не в курсе что там в Spigot'e)
Зачем тогда использовать craftbukkit, если Player всегда находится в одном пакете?
Да и всегда можно получить версию майна и составить путь к carftbukkit
 
Я хочу добавить в класс Player дополнительное поле, чтобы не юзать HashMap. Это возможно как-то сделать, не переписывая ядро?
Player это интерфейс, в нём нет полей. Чтобы обращаться к твоему полю без всяких костылей, придётся ручками допиливать CraftPlayer. Или патчить(я тут не спец) его в рантайме и лазить рефлексиями, что медленее хешмапы.
 
что медленее хешмапы
Зато это надо будет сделать только один раз)
Да и всегда можно получить версию майна и составить путь к carftbukkit
Составить-то путь можно, но вот наследовать от этого пути объект? Не знаю возможно ли это.
Об этом писал тут но пока не искал решения
 
Player это интерфейс, в нём нет полей. Чтобы обращаться к твоему полю без всяких костылей, придётся ручками допиливать CraftPlayer. Или патчить(я тут не спец) его в рантайме и лазить рефлексиями, что медленее хешмапы.
В интерфейсе нет полей? Я думал там только они и есть.. Ну без унаследования они не дают толка. Попробую рефлексиями изменить.
Ладно, спасибо ребят. Отпишусь, если будут успехи
 
Чем Вам HashMap не угодил? Я например, удаляю из него игроков, когда они отключаются от сервера, тогда элементов будет не так много. Либо можно использовать очередь с автоматическим выталкиванием.
В некоторых случаях и правда удобней создать своего CraftPlayer'а (например, если полей очень много). К тому же в нем можно изменить базовые значения переменных.
Но это может напрочь убить совместимость с плагинами, которые делают так же.
 
Чем Вам HashMap не угодил? Я например, удаляю из него игроков, когда они отключаются от сервера, тогда элементов будет не так много. Либо можно использовать очередь с автоматическим выталкиванием.
Потому что проще
В некоторых случаях и правда удобней создать своего CraftPlayer'а (например, если полей очень много). К тому же в нем можно изменить базовые значения переменных.
Но это может напрочь убить совместимость с плагинами, которые делают так же.
Ну тут остается помолиться :D
 
Кароче, ребята.
Сначала изучал библиотеку "bsh". Там можно добавлять код в класс, добавить можно все, что только угодно. Но мне это не понравилось, т.к. это делается через библиотеку, и непонятно, как оно работает. Но оно действительно работает :)
Кароче, буду юзать метадату Player, как мне и предлагали изначально. В принципе это то, чего я хотел.

Как это делается, если кому интересно:

У меня есть класс, который хранит дополнительные данные о игроке:
Код:
package me.govnojon.essentials;

import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;

public class PlayerData {
    public Player player;
    public int mana = 100;
    public int poins = 0;
    public FileConfiguration file;

    PlayerData(Player player) {
       this.player = player;
    }
}

Как его связать с игроком? Очень просто:
Код:
package me.govnojon.essentials;

import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.metadata.FixedMetadataValue;

public class Listeners implements Listener
{
    @EventHandler
    public void onPlayerJoinEvent(PlayerJoinEvent event) {
       Player p = event.getPlayer(); //Игрок
       PlayerData pd = new PlayerData(p); //Доп данные о игроке
       p.setMetadata("data", new FixedMetadataValue(Essentials.plugin, pd)); //Сохраняим их под названием "data"
    }
}

Как достать данные?
Код:
    public static PlayerData getPlayerData(Player player) {
      List<MetadataValue> values = player.getMetadata("data"); //Получаем список метадат "data"

      for (MetadataValue value : values) { //Идем по списку (Будет только один проход, если вы добавили только одину метадату "data")
           if (value.value() instanceof PlayerData) { //Если нашли, проверяем нужный ли это объект
              return (PlayerData) value.value(); //Возращаем его
           }
       }
       return null; //Если не наши, то возращаем null
    }
 
Последнее редактирование:

Поделиться этой страницей

Назад
Верх