what is the best way to save the amount of players that logged in?

Discussion in 'Spigot Plugin Development' started by ScoRpyoN, Jan 13, 2018.

  1. I want to save an integer that store the number of logins in the day.
    I mean, if "Notch" logs in for the first time today, it'll add 1 to this integer
    any ideas?
     
  2. Mas

    Mas

    Store a set of player UUIDs and if a player logs in and their UUID is not in the set, add it. Then you can just use the size of the set as the unique logins.
     
    • Agree Agree x 1
  3. Create a HashMap <UUID, Integer>

    For each login (PlayerLoginEvent or PlayerJoinEvent) add an int to the UUID in the HashMap
     
  4. Is the server going off sometime?
     
  5. He want to get the Number of unique connection in 24h so no he should use a set of uuid
     
  6. I think it's better to use the real Names of the players for what he's trying to do
     
  7. I think UUID would give a more accurate reading. Otherwise name changes will be counted even if their previous name was already counted that day.
     
    • Agree Agree x 1
  8. There's no valid point in using usernames over UUID at this point. UUID's can always be translated back to usernames, guarenteed. With name changing, you can't guarentee the opposite with usernames to UUID.
     
  9. Ya you're right sorry.
     
  10. I don't know how to explain this without giving you code, so here is some code I wrote.
    I will leave the file writing and reading to you.
    Code (Text):
    package me.struck;

    import java.util.ArrayList;
    import java.util.Date;
    import java.util.UUID;

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

    public class LoginSystem implements Listener {

        private Date date;
        private Set<UUID> allPlayers;
        private Set<UUID> today;
       
        public LoginSystem() {
            this.date = new Date();
            this.allPlayers = loadAllPlayers();
            this.today = loadDate(date);
        }

        @SuppressWarnings("deprecation")
        @EventHandler
        public void onJoin(PlayerJoinEvent event) {
           
            Date date = new Date();
            if (date.getDay() != this.date.getDay()) {
                saveToday(today);
                today.clear();
                this.date = date;
            }
           
            Player player = event.getPlayer();
            UUID uuid = player.getUniqueId();
            if (!allPlayers.contains(uuid)) {
                today.add(uuid);
                allPlayers.add(uuid);
            }
        }

        private void saveToday(Set<UUID> uuids) {
        }
       
        private Set<UUID> loadDate(Date date2) {
            return null;
        }

        private Set<UUID> loadAllPlayers() {
            return null;
        }
       
    }
     
     
    • Like Like x 1
  11. Code (Text):
    private Set<UUID> playerConnected = new HashSet<>();

    @Override
    public void onEnable() {
        new BukkitRunnable() {
            Calendar calendar = Calendar.getInstance();
            int lastUpdate = calendar.get(Calendar.DAY_OF_MONTH);
            @Override
            public void run() {
                if (lastUpdate != calendar.get(Calendar.DAY_OF_MONTH)) {
                    playerConnected.clear();
                    lastUpdate = calendar.get(Calendar.DAY_OF_MONTH);
                }
            }
        }.runTaskTimer(this, 0L, 20L * 60 * 10);
        getServer().getPluginManager().registerEvents(this, this);
    }

    @EventHandler
    public void onPlayerLogin(PlayerLoginEvent e) {
        if (!playerConnected.contains(e.getPlayer().getUniqueId()))
            playerConnected.add(e.getPlayer().getUniqueId());
    }
    Not tested but i think you can do like this.
    A runnable checking every 30 mn if the day changed if yes clear the players set.
     
    #11 FrozenLegend, Jan 13, 2018
    Last edited: Jan 14, 2018
    • Like Like x 1
  12. Why schedule a Runnable when you don't need one?
     
  13. Well, I don't see why you wouldn't just do a 1 minute runnable, it's not that you're doing very intensive stuff inside of it
     
  14. Why did you use deprecated stuff when u can use something who is not ?
     
  15. That doesn't change the fact that you're using a Scheduled Task, which is unnecessary..
    Code (Text):
    package me.struck;

    import java.util.ArrayList;
    import java.util.Date;
    import java.util.UUID;

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

    public class LoginSystem implements Listener {

        private int day;
        private Set<UUID> allPlayers;
        private Set<UUID> today;
     
        public LoginSystem() {
            this.day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
            this.allPlayers = loadAllPlayers();
            this.today = loadDate(date);
        }

        @EventHandler
        public void onJoin(PlayerJoinEvent event) {
         
            int day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
            if (day != this.day) {
                saveToday(today);
                today.clear();
                this.day = day;
            }
         
            Player player = event.getPlayer();
            UUID uuid = player.getUniqueId();
            if (!allPlayers.contains(uuid)) {
                today.add(uuid);
                allPlayers.add(uuid);
            }
        }

        private void saveToday(Set<UUID> uuids) {
        }
     
        private Set<UUID> loadDate(Date date2) {
            return null;
        }

        private Set<UUID> loadAllPlayers() {
            return null;
        }
     
    }
     
     
    Woah, would you look at that, no more deprecation. :)
     
    • Like Like x 1
  16. Your code will reset the amount of player connected when the first player join on the next day, mine will update it every time at 00:00 that's the difference. If no one connect the value will still be the same for you.
    Good job ! It was not so hard huh?
    Btw why are you getting Calendar instance for each connection ? :rolleyes: instead of just storing this instance in your object ?
     
    #16 FrozenLegend, Jan 13, 2018
    Last edited: Jan 13, 2018
  17. Your code will not update exactly at 00:00. If I start my server at 11:40 pm, the player array will reset at 00:10. Also, how is he supposed to know if the player is new? If a player logs out at 11:30 and joins at 12:00, your system has no way to tell if that player is new or old. All your code does is add players to an array and clear it when the day changes, it doesn't actually fulfill the OP's request. I'm still being a hypocrite, so I will stop.
     
    • Agree Agree x 1
  18. Flaming each other doesn't help the topic at hand.

    If you really want to use a scheduler, then just onEnable check current system time, and how long is left until midnight, schedule an AsyncDelayedTask with whatever inside. That way it doesn't run every 30 mins, and it resets and can do anything it likes at midnight (if ThreadSafety needed, then just DelayedSyncTask or whatever).

    Not going to spoonfeed code as it's a simple task.

    WORKFLOW:

    LoginEvent, get ArrayList<UUID> contains logged in players UUID, if it does, do nothing, if not, add them to the ArrayList, that's all.

    onEnable > Shedule delayedTask > in task get teh ArrayList length and boom, that's your total logins for the day. Use a calendar to get the date if you really need it for some kind of stats tracking.

    onDisable > cancel all tasks, general cleanup.

    Don't need leave event at all, since you never remove their UUID.
     
  19. You would just have to translate that time into ticks, then once it is midnight, you would schedule a new task that would run all day. Didn't even think about it like that, good idea @xNameless
     
  20. If you want to update it at 00:00 change the task delay to 1mn and he will.
    It's the player first connection of the day if he is not in the list maybe ?
    And btw what i have done is exactly what the op want, he want the amount of unique connection of the day and he can get it using Set#size() and this list will be reset at 00:00 everyday no matter if a player connect or not. You don't know what he want to do, if he want to do some stats or something don't reset the list if nobody connect will completely fuck up his statistics because number of connection will be the same as the last day as long as a player connect.
    That's a bit stupid to use async for a task as small as that and if i understand what you said, your delayed task will start on plugin load and will run only one time.
     
    #20 FrozenLegend, Jan 14, 2018
    Last edited: Jan 14, 2018

Share This Page