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

Стартап Помощь новичкам и тем, кто мало писал плагины. (+ LifeHack'и)

Нет конечно. Ты это сам придумал из своего воображения.
Вообще-то не сам придумал, но спасибо, что побудил меня самому это протестить. Ты прав, все три способа одинаково быстрые. (0-1 ms)
 
Вообще-то не сам придумал, но спасибо, что побудил меня самому это протестить. Ты прав, все три способа одинаково быстрые. (0-1 ms)
Такие вещи изменяются в наносекундах и проверяются unit-тестами
 
Иииии еще один вопросик...
Имею ArmorStand_1 в переменной AS. Могу его менять, изменять, перемещать, удалять и т.д. и это отображается на сервере. Теперь я помещаю переменную AS в HashMap<String, Object> и сам HashMap помещаю в Metadata некоему ArmorStend_2. Затем при срабатывании определенных эвентов я беру мету ArmorStend_2.getMetadata.get(0).value и из неё вытаскиваю AS_1. Как будет вести себя сервер, если я попытаюсь что-то сделать с AS_1? Смогу ли я получить Location и вытащить мету из AS_1?
 
Иииии еще один вопросик...
Имею ArmorStand_1 в переменной AS. Могу его менять, изменять, перемещать, удалять и т.д. и это отображается на сервере. Теперь я помещаю переменную AS в HashMap<String, Object> и сам HashMap помещаю в Metadata некоему ArmorStend_2. Затем при срабатывании определенных эвентов я беру мету ArmorStend_2.getMetadata.get(0).value и из неё вытаскиваю AS_1. Как будет вести себя сервер, если я попытаюсь что-то сделать с AS_1? Смогу ли я получить Location и вытащить мету из AS_1?
Должно быть да.
 
Иииии еще один вопросик...
Имею ArmorStand_1 в переменной AS. Могу его менять, изменять, перемещать, удалять и т.д. и это отображается на сервере. Теперь я помещаю переменную AS в HashMap<String, Object> и сам HashMap помещаю в Metadata некоему ArmorStend_2. Затем при срабатывании определенных эвентов я беру мету ArmorStend_2.getMetadata.get(0).value и из неё вытаскиваю AS_1. Как будет вести себя сервер, если я попытаюсь что-то сделать с AS_1? Смогу ли я получить Location и вытащить мету из AS_1?
Если всё так, как ты сказал - сможешь вытащить AS_1 и работать с ним, как и сразу после спауна, например.
Более интересен вопрос, как ты собираешься помещать HashMap в метадату
 
Если всё так, как ты сказал - сможешь вытащить AS_1 и работать с ним, как и сразу после спауна, например.
Более интересен вопрос, как ты собираешься помещать HashMap в метадату
Так, как-как? Вот так:
PHP:
// Создаем контейнер для хранения переменных
HashMap<String, Object> player_meta_set = new HashMap<>();
// Запихиваем необходимые данные в контейнер
player_meta_set.put("Ne", AS);
player_meta_set.put("a", a);
player_meta_set.put("stage", 1);
// Ради удобства создаем локальный экземпляр плагина
Plugin plugin = Bukkit.getPluginManager().getPlugin("FirstTestMinecarts");
// На всякий противопожарный случай удолем мету с таким же именем
player.removeMetadata("FTM_player_meta", plugin);
// Зпихиваем данные в мету
player.setMetadata("FTM_player_meta", new FixedMetadataValue(plugin, player_meta_set));
А забирать вот так:
PHP:
Player player = event.getPlayer();

//Проверка наличия у player FTM_player_meta и валидность меты
if (player.hasMetadata("FTM_player_meta")&&(player.getMetadata("FTM_player_meta").get(0).value() instanceof HashMap)) {
	
	@SuppressWarnings("unchecked")
	HashMap<String, Object> player_meta_set = (HashMap<String, Object>) player.getMetadata("FTM_player_meta").get(0).value();
	//получим переменную stage ради примера
	Integer stage = (Integer) player_meta_set.get("stage");
	
	/*
	 * какой-то код
	 */
}
Правда мы должны наверняка знать, что в контейнере хранится именно то, что мы хотим получить. Но на случай если нет я обычно ловлю любой exception и удаляю мету FTM_player_meta
 
Последнее редактирование:
Так, как-как? Вот так:
PHP:
// Создаем контейнер для хранения переменных
HashMap<String, Object> player_meta_set = new HashMap<>();
// Запихиваем необходимые данные в контейнер
player_meta_set.put("Ne", AS);
player_meta_set.put("a", a);
player_meta_set.put("stage", 1);
// Ради удобства создаем локальный экземпляр плагина
Plugin plugin = Bukkit.getPluginManager().getPlugin("FirstTestMinecarts");
// На всякий противопожарный случай удолем мету с таким же именем
player.removeMetadata("FTM_player_meta", plugin);
// Зпихиваем данные в мету
player.setMetadata("FTM_player_meta", new FixedMetadataValue(plugin, player_meta_set));
А забирать вот так:
PHP:
Player player = event.getPlayer();

//Проверка наличия у player FTM_player_meta и валидность меты
if (player.hasMetadata("FTM_player_meta")&&(player.getMetadata("FTM_player_meta").get(0).value() instanceof HashMap)) {
   
    @SuppressWarnings("unchecked")
    HashMap<String, Object> player_meta_set = (HashMap<String, Object>) player.getMetadata("FTM_player_meta").get(0).value();
    //получим переменную stage ради примера
    Integer stage = (Integer) player_meta_set.get("stage");
   
    /*
     * какой-то код
     */
}
Правда мы должны наверняка знать, что в контейнере хранится именно то, что мы хотим получить. Но на случай если нет я обычно ловлю любой exception и удаляю мету FTM_player_meta
метадата не особо подходит для хранения чего либо продолжительное время ибо после рестарта оно превратится в тыкву.
 
Иииии еще один вопросик...
Имею ArmorStand_1 в переменной AS. Могу его менять, изменять, перемещать, удалять и т.д. и это отображается на сервере. Теперь я помещаю переменную AS в HashMap<String, Object> и сам HashMap помещаю в Metadata некоему ArmorStend_2. Затем при срабатывании определенных эвентов я беру мету ArmorStend_2.getMetadata.get(0).value и из неё вытаскиваю AS_1. Как будет вести себя сервер, если я попытаюсь что-то сделать с AS_1? Смогу ли я получить Location и вытащить мету из AS_1?
До рестарта сервера сможешь. Лучше юзай что то типо scoreboard.
 
До рестарта сервера сможешь. Лучше юзай что то типо scoreboard.
Ммм... Я не хочу использовать скорборды, т.к. к ней можно получить доступ из игры. К тому же я боюсь, что я не смогу сохранять объекты типа Location. Можно попробовать пихать в локальные файлы, а потом доставать их в глобальную переменную, но опять-таки, что будет с Entity и прочими Objects?
 
До рестарта сервера сможешь. Лучше юзай что то типо scoreboard.
Теперь я понял, что под scoreboards я понимал не то, что понимали Вы. Но этот вариант мне все равно не нравится. Т.к. сериализовывать объекты (например: Location), сохранять их как стринг, а затем доставать их из переменной и десериализировать обратно мне кажется неоправданно трудозатратным. Не уж-то в баките нет проще способа хранить объекты внутри энтити?
Пока искал варианты решения вопроса, родилась идея хранить данные в глобальном HashMap<String, Object>, где String, это UUID конкретного арморСтенда. Но это означает, что все объекты, которые я хочу иметь на карте будут хранить данные в этой штуке. А это много данных. Считай, каждый мой арморСтенд будет хранить как минимум 4 переменных типа double и 2 объекта типа Location, которые сами по себе занимают ХЗ сколько, но думаю то же не мало (как минимум 5 double на x, y, z, pitch и yaw). Итого по скромным оценкам 9 * 8 байт = 75 байт (!) занимают данные только одного АС при их общем количестве от 100 и более.
/* Можно было бы организовать хитрый механизм, который бы ловил ChunkLoadEvent и ChunkUnloadEvent и в зависимости от этого убирал бы или добавлял записи в мапу.. Но надо добавить в класс строку о чанке, в котором находится АС */
 
Т.к. сериализовывать объекты (например: Location), сохранять их как стринг, а затем доставать их из переменной и десериализировать обратно мне кажется неоправданно трудозатратным.
Ты сделал мой день. Достать строку это крайне тяжелая операция :D. Как только сервер вообще работает, бедняга. Там же миллион таких строк.
От куда вы вообще берете такие "познания"?
 
Можно было бы организовать хитрый механизм
Правильно мыслишь.
Но надо добавить в класс строку о чанке, в котором находится АС
Зачем строку? Можно хэш чанка. У каждого чанка свой хэш. Считать можно примерно так:
PHP:
public static int hash(Chunk chunk) {
    return hash(chunk.getWorld(), chunk.getX(), chunk.getZ());
}

public static int hash(World world, int chunkX, int chunkZ) {
    return world.hashCode() + 32765 * chunkX + 32767 * chunkZ;
}

Этот же хеш можно будет использовать в качестве ключа в какой-нибудь мапе вида Map<Integer, Set<ArmorStandData>>
Собственно, таким образом можно будет реализовать довольно быструю очистку информации при выгрузке чанка (дабы не перебирать все элементы).
 
Теперь я понял, что под scoreboards я понимал не то, что понимали Вы. Но этот вариант мне все равно не нравится. Т.к. сериализовывать объекты (например: Location), сохранять их как стринг, а затем доставать их из переменной и десериализировать обратно мне кажется неоправданно трудозатратным. Не уж-то в баките нет проще способа хранить объекты внутри энтити?
Пока искал варианты решения вопроса, родилась идея хранить данные в глобальном HashMap<String, Object>, где String, это UUID конкретного арморСтенда. Но это означает, что все объекты, которые я хочу иметь на карте будут хранить данные в этой штуке. А это много данных. Считай, каждый мой арморСтенд будет хранить как минимум 4 переменных типа double и 2 объекта типа Location, которые сами по себе занимают ХЗ сколько, но думаю то же не мало (как минимум 5 double на x, y, z, pitch и yaw). Итого по скромным оценкам 9 * 8 байт = 75 байт (!) занимают данные только одного АС при их общем количестве от 100 и более.
/* Можно было бы организовать хитрый механизм, который бы ловил ChunkLoadEvent и ChunkUnloadEvent и в зависимости от этого убирал бы или добавлял записи в мапу.. Но надо добавить в класс строку о чанке, в котором находится АС */
Ого, отсыпь мне тоже.
Это же тот самый тип людей, который борется за каждый байт памяти.
(21 век блджад, 16 гб оперативы на пк это уже норма, но ноунеймы на форуме все ещё пытаются сохранить 10 байт памяти)

А если серьезно, то начать можно с того, что Map хранит не объекты, а ссылки на них. Твой AC уже существует в памяти отдельно, а мапа по ключу будет лишь ссылаться на него.
И на этом, пожалуй, можно и закончить.

И вообще преждевременная оптимизация - это очень плохо. Начинать заниматься оптимизацией нужно только после возникновения проблем с ней.
 
Как он вообще не боится сервер запускать :D. Там же так много всего в нем. Голова опухнет.
 
Н-да... Соглашусь. Фигню сморозил (не надо мне на ночь глядя давать слова писать). Однакож колличество информации все же вызывает у меня беспокойство, точнее количество операций записи/чтения, а так же операции сериализации и десериализации.
Про занятие оптимизацией там, где этого не нужно - каюсь, грешен. Хочется сделать все сразу хорошо, чтоб ничего потом переделывать не пришлось. Хотя уже сейчас что-то из старого приходится переделывать. Я Вас понял и постараюсь больше такой ерундой без необходимости не заниматься, но не обещаю, потому что хочется :)
Про хэш - мысль интересная, но для меня не подходит, т.к. в одном и том же чанке могут находится несколько АС. Я ещё не до конца понял сериализацию и в ближайшие недели планирую плотно заняться изучением этого вопроса и возможно найду для хеша применение.
Спасибо большое за ваши ответы. Вы мне очень сильно помогаете двигаться вперёд :)
 
Однакож колличество информации все же вызывает у меня беспокойство, точнее количество операций записи/чтения, а так же операции сериализации и десериализации.
Ты похоже не понимаешь вообще как это работает. Причем тут твои сериализации и десериализации? Ты всего лишь работаешь с гетерами и сетерами.
 
Н-да... Соглашусь. Фигню сморозил (не надо мне на ночь глядя давать слова писать). Однакож колличество информации все же вызывает у меня беспокойство, точнее количество операций записи/чтения, а так же операции сериализации и десериализации.
Про занятие оптимизацией там, где этого не нужно - каюсь, грешен. Хочется сделать все сразу хорошо, чтоб ничего потом переделывать не пришлось. Хотя уже сейчас что-то из старого приходится переделывать. Я Вас понял и постараюсь больше такой ерундой без необходимости не заниматься, но не обещаю, потому что хочется :)
Про хэш - мысль интересная, но для меня не подходит, т.к. в одном и том же чанке могут находится несколько АС. Я ещё не до конца понял сериализацию и в ближайшие недели планирую плотно заняться изучением этого вопроса и возможно найду для хеша применение.
Спасибо большое за ваши ответы. Вы мне очень сильно помогаете двигаться вперёд :)
Тут смысл в том, что пока ты эволюционируешь в плане кода - весь твой более-менее старый код будет казаться тебе говном. И если ты только начал этим заниматься - советую не пытаться сделать сразу идеально - не выйдет, просто из-за отсутствия опыта. Думаешь что написал идеально, а через год твой старый код будет для тебя казаться дырявым ведром из костылей. Тру стори.
 
в одном и том же чанке могут находится несколько АС
Я понимаю. Именно поэтому в моём прошлом ответе в качестве значения элемента мапы был указан не просто ArmorStandData, а Set<ArmorStandData>
 

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

Назад
Верх