Сохранение и сброс хэшмапов

BlackBaroness

Модератор
Разработчик
Сообщения
1,680
Решения
72
Веб-сайт
vk.com
Сап спигот, раз нет альтернатив, хочу написать плагин на выдачу наград за наигранные часы, заодно улучшив уже существующий. У меня есть вот такой код:

Java:
public class handler implements Listener {

    private static final Baroness pluginInstance = Baroness.getInstance();
    HashMap<Player, Integer> clock = new HashMap<>();

    @EventHandler
    public void join(PlayerJoinEvent e) throws InterruptedException {
        Player p = e.getPlayer();
        clock.put(p, -1);
        new BukkitRunnable() {
            @Override
            public void run() {
                int some = clock.get(p);
                some++;
                clock.put(p, some);
                if (clock.get(p) == 1) {
                    p.sendMessage(ChatColor.AQUA + "Вы играете " + ChatColor.GOLD + clock.get(p) + ChatColor.AQUA + " час.");
                }
                if (clock.get(p) == 2 || clock.get(p) == 3 || clock.get(p) == 4) {
                    p.sendMessage(ChatColor.AQUA + "Вы играете уже " + ChatColor.GOLD + clock.get(p) + ChatColor.AQUA + " часа.");
                }
                if (clock.get(p) >= 5 && clock.get(p) <= 10) {
                    p.sendMessage(ChatColor.AQUA + "Вы играете уже " + ChatColor.GOLD + clock.get(p) + ChatColor.AQUA + " часов.");
                }
                if (clock.get(p) != 0) {
                    p.sendMessage(ChatColor.DARK_GREEN + "Не забывайте отдыхать.");
                }
            }
        }.runTaskTimer(pluginInstance, 0, 36000000 * 20);

Надо сделать, чтобы эта прелесть сохранялась при релоге и при этом сбрасывалась в определённое время. Например, в 0:00.
 
Решение
Black_Baroness, типа есть класс

Java:
public class PlayTime {
    private long start = System.currentTimeMillis();

    public long getStart() {
        return start;
}
}

Потом при в главный класс:

Java:
public class Main extends JavaPlugin implements Listener {

    private Map<UUID, PlayTime> playerTime = new HashMap<>();

    @Override
    public void onEnable() {
        Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> {
            playerTime.forEach((player, playTime) -> {
                long now = System.currentTimeMillis();
                long differenceInHours = TimeUnit.MILLISECONDS.toHours(now - playTime.getStart()));
                switch(differenceInHours) {
                    case 1...
а, щас) сегодня совсем с головой не дружу что-то
Авто объединение сообщений:

3 минуты простоял, плагин запустился, но в консоли ошибок нет

Java:
Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> playerTime.forEach((player, playTime) -> {
            long now = System.currentTimeMillis();
            long differenceInHours = TimeUnit.MILLISECONDS.toMinutes(now - playTime.getStart());
            Player p = Bukkit.getPlayer(player);
            switch((int) differenceInHours) {
                case 1:
                    p.sendMessage("письки");
                case 2:
                    p.sendMessage("письки2");
                case 3:
                    p.sendMessage("письки3");
                case 4:
                    p.sendMessage("письки4");
                case 5:
                    p.sendMessage("письки5");

                default:
                    break;
            }
        }), 0L, 1200L);
 
Последнее редактирование:
Black_Baroness,
В мапу суем игрока при входе и удаляем при выходе.
Игрок же в мапе с воздуха не появится.


Java:
@EventHandler
public void onJoin(e: PlayerJoinEvent) {
    Player player = e.getPlayer();
    UUID uuid = player.getUniqueID();
    if (!твоя_мапа.containsKey(uuid)) {
        твоя_мапа.put(uuid, new PlayTime());
    }
}
/*
P.S тоже накалякал тут, могут быть очепятки.
Можно и без класса обойтись вообще, тупо через <UUID, Long> сделать,
но наличие класса даст возможность добавить определенные фичи и свои условия.
*/
 
Последнее редактирование:
Black_Baroness, написал же выше готовый код - новый объект класса. На вопрос почему сделал именно классом, а не просто через Long, тоже написал.
Класс нужен для гибкости.
 
что-то с сайтом, он поздно грузит твои сообщения. Когда я написал вопрос, твой код еще не пришел
Тут технические шоколадки - new делать?
 

Вложения

  • Снимок экрана (98).png
    Снимок экрана (98).png
    104.6 KB · Просмотры: 9
Java:
Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> playerTime.forEach((player, playTime) -> {
            long now = System.currentTimeMillis();
            long differenceInHours = TimeUnit.MILLISECONDS.toMinutes(now - playTime.getStart());
            Player p = Bukkit.getPlayer(player);
            switch ((int) differenceInHours) {
                case 1:
                    p.sendMessage("1");
                case 2:
                    p.sendMessage("2");
                case 3:
                    p.sendMessage("3");
                case 4:
                    p.sendMessage("4");
                case 5:
                    p.sendMessage("5");

                default:
                    break;
            }
        }), 0L, 1200L);



@EventHandler
    public void onPJoin(PlayerJoinEvent e) {
        Player p = e.getPlayer();
        UUID id = p.getUniqueId();
        if (!playerTime.containsKey(id)) {
            playerTime.put(id, new PlayTime());
        }
    }

Итоговый код. Пойду тестить
 
[OFFTOPIC]Я понимаю, что я новичок в жаве, но не настолько же)[/OFFTOPIC] он давно зареган, я тебе кидаю только код, который напрямую относится к вопросу
 
Последнее редактирование модератором:
И я сказал при выходе удалять, игрока из мапы, а то будет смешно, когда игрок зайдет, выйдет а данные останутся (ООМ привет).
Либо суй в PlayerQuitEvent удаление, или используй LazyHashMap<T, V> который во время GC сам все очистит
 
Black_Baroness,
Тогда это совсем другая история, и готовься к нуль когда оно попытается отправить игроку сообщение.
Вообще это ужасный метод, чтобы оставались часы при релоге, потому что слишком много информации попадет в ОЗУ, что точно приведет к заполнению памяти. Тебе нужно все хранить тогда в локальной БД и создавать объект PlayTime только в том случае, когда, игрок зашел и его нет в БД и в противном уже учитывать время с последнего момента выхода, иначе ему часы буду засчитываться, пока он оффлайн.
 
[OFFTOPIC]Black_Baroness, я могу за полчасика написать это и кинуть в гитхаб, но точно не сейчас, ибо еще BedWars себе не дописал. [/OFFTOPIC]Пытайся, вроде все тебе разжевал, БД можешь юзать JSON, ее реализацию можешь повзаимствовать в одном из моих плагинов (BungeeTeleport/RandomHub).
Но точно не пытайся делать как в плагине выше, и таймер однозначно должен быть асинк
 
Последнее редактирование модератором:
Назад
Сверху Снизу