Хостинг серверов Minecraft playvds.com
  1. Вы находитесь в русском сообществе Bukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на русский язык плагины наших собратьев из других стран.
    Скрыть объявление

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

Тема в разделе "Разработка плагинов для новичков", создана пользователем JonBoss, 20 сен 2015.

  1. Автор темы
    JonBoss

    JonBoss Активный участник Пользователь

    Баллы:
    76
    Skype:
    ya_narik1
    Имя в Minecraft:
    Jon
    Я хочу добавить в класс Player дополнительное поле, чтобы не юзать HashMap. Это возможно как-то сделать, не переписывая ядро?
     
  2. Хостинг MineCraft
    <
  3. Plasticable

    Plasticable Старожил Девелопер Пользователь

    Баллы:
    173
    Skype:
    plasticable
    Имя в Minecraft:
    Plasticable
    Много хочешь. Юзай метадату
     
  4. OsipXD

    OsipXD Старожил Пользователь

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    А чем HashMap не угодил?
     
  5. Автор темы
    JonBoss

    JonBoss Активный участник Пользователь

    Баллы:
    76
    Skype:
    ya_narik1
    Имя в Minecraft:
    Jon
    Ожидал этого вопроса :)
    Ну он дает нагрузку, особенно когда его используешь в PlayerMoveEvent.
    Да и мне вообще интересно, возможно ли сделать, как я хочу.[DOUBLEPOST=1442751577,1442751343][/DOUBLEPOST]
    Тоесть это невозможно? Я не говорю даже про плагин. Например, написать java программу, которая будет предварительно изменять класс Player, а после уже запускать ядро сервера. Своего рода запускатор.
    Это позволит изменять ядро сервера без каких либо правок.
     
  6. OsipXD

    OsipXD Старожил Пользователь

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    NMS/OBC можно изменить и без таких ухищрений. Сделать объект расширяющий CraftPlayer, а потом подменять им настоящего игрока с помощью рефлексий. Правда это не всегда подходит.
     
  7. Автор темы
    JonBoss

    JonBoss Активный участник Пользователь

    Баллы:
    76
    Skype:
    ya_narik1
    Имя в Minecraft:
    Jon
    Как сделать объект расширяющий CraftPlayer?[DOUBLEPOST=1442752001,1442751851][/DOUBLEPOST]Есть идея еще размещать нужные мне объекты рядом друг с другом в оперативной памяти. И ссылаться по ним, как по массиву. Но я не знаю, как это все делать..
     
  8. OsipXD

    OsipXD Старожил Пользователь

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    А как тогда выбирать объект именно для определенного игрока?[DOUBLEPOST=1442752176,1442752097][/DOUBLEPOST]
    Для начала надо подключить craftbukkit как билиотеку[DOUBLEPOST=1442752272][/DOUBLEPOST]И чтобы плагин работал на разных версиях, придется писать этот класс отдельно под каждую версию (ну почти) и в зависимости от того на какой версии запускается, создавать нужный объект.
     
  9. Автор темы
    JonBoss

    JonBoss Активный участник Пользователь

    Баллы:
    76
    Skype:
    ya_narik1
    Имя в Minecraft:
    Jon
    Ну брать Player, получать его указатель и сдвинуться на след. ячейку в ОП, а там уже будет нужный мне указатель на мою мета дату. Но это костыли в квадрате :)

    craftbukkit? А spigot не подходит?[DOUBLEPOST=1442752403][/DOUBLEPOST]
    А почему под каждую версию, если я только хочу добавить поле, а не убрать, например? Тоесть по идее, не важно какая версия класса

    Кароче я нашел инфу, щас будем вникать http://www.quizful.net/post/java-reflection-api
     
  10. Dereku

    Dereku Старожил

    Баллы:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    Слушать PME 4 раза в секунду - ?
    Этого обычно достаточно чтобы творить с игроком что хочешь. Правда, если ты будешь отменять эвент, то тут уже грустнее всё.
     
  11. OsipXD

    OsipXD Старожил Пользователь

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    Потому что в разных версиях этот класс находится в разных пакетах. Вот например в 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[DOUBLEPOST=1442752807,1442752554][/DOUBLEPOST]
    Указатели в Java? o.o
    Даже если такое существует, то кто гарантирует, что место в памяти рядом с Player не занято?
    По сути сама переменная, является ссылкой на объект в памяти.

    Подходит, в него же входит craftbukkit. Но лучше все-таки тык чтобы ничего лишнего не порасширять (я не в курсе что там в Spigot'e)
     
    Последнее редактирование: 20 сен 2015
  12. Автор темы
    JonBoss

    JonBoss Активный участник Пользователь

    Баллы:
    76
    Skype:
    ya_narik1
    Имя в Minecraft:
    Jon
    Это неплохая идея.
    Но я все же хочу попробовать сделать по своему, ибо всегда приходится что-то хранить о игроке. Почему бы не сделать проще?[DOUBLEPOST=1442752928,1442752830][/DOUBLEPOST]
    Зачем тогда использовать craftbukkit, если Player всегда находится в одном пакете?
    Да и всегда можно получить версию майна и составить путь к carftbukkit
     
  13. Den_Abr

    Den_Abr Старожил Девелопер Пользователь

    Баллы:
    173
    Skype:
    Den_Abr
    Имя в Minecraft:
    Den_Abr
    Player это интерфейс, в нём нет полей. Чтобы обращаться к твоему полю без всяких костылей, придётся ручками допиливать CraftPlayer. Или патчить(я тут не спец) его в рантайме и лазить рефлексиями, что медленее хешмапы.
     
  14. OsipXD

    OsipXD Старожил Пользователь

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    Зато это надо будет сделать только один раз)
    Составить-то путь можно, но вот наследовать от этого пути объект? Не знаю возможно ли это.
    Об этом писал тут но пока не искал решения
     
  15. Автор темы
    JonBoss

    JonBoss Активный участник Пользователь

    Баллы:
    76
    Skype:
    ya_narik1
    Имя в Minecraft:
    Jon
    В интерфейсе нет полей? Я думал там только они и есть.. Ну без унаследования они не дают толка. Попробую рефлексиями изменить.[DOUBLEPOST=1442753661,1442753619][/DOUBLEPOST]Ладно, спасибо ребят. Отпишусь, если будут успехи
     
  16. OsipXD

    OsipXD Старожил Пользователь

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    В интерфейсе только методы, а полей нет.
     
  17. Автор темы
    JonBoss

    JonBoss Активный участник Пользователь

    Баллы:
    76
    Skype:
    ya_narik1
    Имя в Minecraft:
    Jon
    PlayerMoveEvent я написал как пример.[DOUBLEPOST=1442754121,1442754089][/DOUBLEPOST]
    лол, перепутал
     
  18. OsipXD

    OsipXD Старожил Пользователь

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    В некоторых случаях и правда удобней создать своего CraftPlayer'а (например, если полей очень много). К тому же в нем можно изменить базовые значения переменных.
    Но это может напрочь убить совместимость с плагинами, которые делают так же.
     
  19. Автор темы
    JonBoss

    JonBoss Активный участник Пользователь

    Баллы:
    76
    Skype:
    ya_narik1
    Имя в Minecraft:
    Jon
    Потому что проще[DOUBLEPOST=1442754849,1442754794][/DOUBLEPOST]
    Ну тут остается помолиться :D
     
  20. OsipXD

    OsipXD Старожил Пользователь

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    Не знаю насчет проще, т.к. надо будет все время делать преобразование типов
     
    Последнее редактирование: 20 сен 2015
  21. Автор темы
    JonBoss

    JonBoss Активный участник Пользователь

    Баллы:
    76
    Skype:
    ya_narik1
    Имя в Minecraft:
    Jon
    Кароче, ребята.
    Сначала изучал библиотеку "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
        }
     
    Последнее редактирование: 20 сен 2015

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