Помогите Как из HashMap вытащить всех игроков которые там есть?

HunterGaming

Активный участник
Пользователь
Баллы
96
Имя в Minecraft
sqdFendy
Мне нужно чтобы у кого в HashMap<String, Boolean> было true, тому сообщение отправлялось с префиксом [Чат-Персонала] Имя игрок : Сообщение. А тех у кого в HashMap false, тем писались обычные сообщение от игроков
 
for (String a : hashmap.keySet()){
if (hashmap.get(a)) {
//do something
}}
 
Java:
        HashMap<String, Boolean> hash = new HashMap<String,Boolean>();
        for(String key : hash.keySet()){
            if(hash.get(key)){
                player.sendmessage(prefix + player.getDisplayName() + ":"+ msg);
            }
            else{
                player.sendmessage(player.getDisplayName() + ":"+ msg);
              
            }
        }
 
JavaScript:
for(Map.Entry<String, Boolean> entry : hashMap.entrySet()) {
    if(entry.getValue) {
        String playerName = entry.getKey();
        ...
    }
}
А вообще человек выше прав. Если это возможно, лучше просто не добавлять игроков в список. При этом HashMap можно будет заменить на HashSet...
 
+1
Java:
        HashSet<Player> hash = new HashSet<Player>();
        for(Player p : Bukkit.getOnlinePlayers()) {
            if(hash.contains(p)) {
              
            } else {
              
            }
        }
 
Причем тут ссылки на игроков?
Уже не раз обсуждалось это. Хранить ссылки на локации, миры и игроков не есть хорошо.

Зачем тебе Map? Можно обойтись HashSet добавляя в него только тех игроков, для которых нужен префикс.
Можно просто обойтись правами. Баккитовскими. И потом Bukkit.broadcast("You are now op!", "special.permission.for.nerds");
 
Последнее редактирование:
Вот с правами стафф чат
Java:
     if ((command.getName().equalsIgnoreCase("staffchat")) &&
       (p.hasPermission("staff.chat"))) {
       if (args.length == 0) {
          sender.sendMessage("Мало аргументов!");
         return false;
       }
       StringBuilder str = new StringBuilder();
       for (int i = 0; i < args.length; i++) {
         str.append(args[I] + " ");
       }
       String msg = str.toString();
       for (Player player : Bukkit.getOnlinePlayers()) {
         if (player.hasPermission("staff.chat")) {
           player.sendMessage(ChatColor.DARK_GRAY + "[" + ChatColor.YELLOW + "Персонал" + ChatColor.DARK_GRAY + "] " + p.getDisplayName() + ChatColor.YELLOW + ": " + msg);
         }
       }
     }
 
  • for (Player player : Bukkit.getOnlinePlayers()) {
  • if (player.hasPermission("staff.chat")) {
  • player.sendMessage(ChatColor.DARK_GRAY + "[" + ChatColor.YELLOW + "Персонал" + ChatColor.DARK_GRAY + "] " + p.getDisplayName() + ChatColor.YELLOW + ": " + msg);
  • }
  • }
Можно тупо Bukkit.broadcast(msg, "perm")
 
Уже не раз обсуждалось это. Хранить ссылки на локации, миры и игроков не есть хорошо.
Java:
Set<Player> set = Collections.newSetFromMap(new WeakHashMap<>());
Иногда это необходимо, так как частое использование getPlayer(UUID) - дорогое удовольствие при большом количестве игроков.
 
Сборщик мусора не сможет очищать объекты вышедших игроков, из-за того что ссылки на них висят в коллекции. Также после перезахода для игрока создаётся новый объект.
Утечка памяти будет и на обычных String, если не чистить.
 
Последнее редактирование:
Весит значительно меньше, нежели объект игрока со многими свойствами.

Для HashSet/Map это ничто. Они и с 5К элементов хорошо работать будут.
Uuid, либо ники хранить то можно. Но если получать через них постоянно игрока, то это может очень плохо кончиться для сервера.
 
Для HashSet/Map это ничто. Они и с 5К элементов хорошо работать будут.
Вот только getPlayer(UUID) дёргает не HashMap.get(Object), а getOnlinePlayers(), который каждый раз создаёт копию коллекции с игроками. Скорее всего, в последних версиях это исправлено, но на 1.7.10 у одного из моих клиентов getPlayer(UUID) отъедал около 20% CPU.
Так что в критичных участках WeakReference/WeakHashMap и прослушивание PlayerQuitEvent - наше всё.
 
Уже не раз обсуждалось это. Хранить ссылки на локации, миры и игроков не есть хорошо.
Ну давайте ещё раз обсудим... Я в таких обсуждениях ни разу не участвовал.
Сборщик мусора не сможет очищать объекты вышедших игроков, из-за того что ссылки на них висят в коллекции. Также после перезахода для игрока создаётся новый объект.

Т.е. если хранить не Player, а String, то GC будет удалять эти элементы что ли? Это уже вопрос говнокода. Т.е. при выходе игрока строку удалять можно, а игрока нет? Да с Player'ами даже с шедулерами всякими проще будет - у Player (OfflinePlayer) есть метод isOnline().
Хранить String есть только в том случае, если предполагается, что игрок потом будет перезаходить. Но прикол в том, что при остановке сервера в любом случае нужно будет сохранять всё это дело в файл.
Кто-то ещё, помнится, говорил, что объект Player нестабилен, но это больше звучит, как бред. По крайней мере в версиях 1.5+ Player не пересоздаётся, пока игрок находится на сервере.

Кстати в новых версиях следует использовать UUID (даже для offline-mode). Единственное, правда, что в этом случае регистр букв в нике нельзя учитывать.

С мирами такая же ситуация - ссылки нельзя хранить, только если предполагается, что миры будут выгружаться и загружаться в рантайме... Уж не знаю, для чего может пригодиться хранение имени мира вместо самого мира...
А с локациями вообще не понял. Локация может пострадать, только если, опять же, мир накроется. Это что ж обстоятельства такие должны быть?

А ещё ваши создаваемые строки весят значительно больше, чем ссылки на объекты.

Короче говоря, полный бред, по моему мнению. Храню Player'ов, World'ы, Location'ы, экономлю на процессорном времени, утечек нет.
Ещё, как отметил человек выше, существуют weak references, если уж кодер совсем ленивый (или дурак)...
 
Последнее редактирование:
Вот только getPlayer(UUID) дёргает не HashMap.get(Object), а getOnlinePlayers(), который каждый раз создаёт копию коллекции с игроками. Скорее всего, в последних версиях это исправлено, но на 1.7.10 у одного из моих клиентов getPlayer(UUID) отъедал около 20% CPU.
Так что в критичных участках WeakReference/WeakHashMap и прослушивание PlayerQuitEvent - наше всё.
Я кстати тоже замечал. что getOnlinePlayers прожорливый.
 
Это ещё почему? Строка - это набор байт, а вот игрок - объект со множеством свойств и содержит ссылки на другие объекты...
Ссылка на объект весит 4 байта. Новая строка - 20+ байт и опять же ссылка - ещё 4 = в сумме 24.
Почему хранить ник/UUID? Позволяет сохранить привязку к игроку после перезахода (объект player новый создаётся) и не мешает сборщику мусора удалять вышедших игроков.
Если уж прям так нужно хранить оффлайн-игроков, лучше для этого использовать отдельный список. Выше уже говорилось о том, что каждый раз получать игрока при помощи баккита - это не очень хорошо.
 
Почему вес объекта не учитываешь? Ссылка куда то же ссылается.
Потому что пока игрок онлайн, эта информация будет находиться в ядре в любом случае. Ты можешь в качестве ключа мапы хранить хоть String, хоть UUID, Player от этого весить меньше не будет.
 
Назад
Верх