Solved Issue with PlayerLoginEvent

Discussion in 'Spigot Plugin Development' started by Justin393, Apr 14, 2019.

  1. I am trying to make a sort of new player limiter plugin so that if X amount of new players join within X amount of time it stops accepting new players, but still allows for players that have played before to login.

    I have been testing with a friend, and we limit it to 1 new player, and we're wiping our player data every time we try. He will connect perfectly fine, I connect and it doesn't let me, so that part is working. If he then logs out and tries to log back in (Which would make him a returning player) It prevents him from logging back in. Here is my code


    Code (Java):
    @EventHandler
        public void onLogin(PlayerLoginEvent event) {
            if (core.isJoinLimited()) {
               
                Player p = event.getPlayer();
                if (!p.hasPlayedBefore()) {
                    event.disallow(Result.KICK_OTHER, "Not accepting new players in order to prevent ruining the experience for our returning players. Please try again later");
                    core.log("Prevented " + p.getName() + " from joining, server is join limited!", false);
                }
            }
        }
     
  2. Your code is only letting those who have not played before join. This is what is causing it:
    Code (Java):
    if (!p.hasPlayedBefore())
    You have to make sure you add something else along with your current method that says something like
    Code (Java):
    if (p.hasPlayedBefore())
    and make it so they bypass the previous method.
     
    • Funny Funny x 1
    • Optimistic Optimistic x 1
  3. I have tried


    Code (Java):
    @EventHandler
        public void onLogin(PlayerLoginEvent event) {
            if (core.isJoinLimited()) {
             
                Player p = event.getPlayer();
                if (!p.hasPlayedBefore()) {
                    event.disallow(Result.KICK_OTHER, "Not accepting new players in order to prevent ruining the experience for our returning players. Please try again later");
                    core.log("Prevented " + p.getName() + " from joining, server is join limited!", false);
                } else {
                 event.allow();
                }
            }
        }
    and it still didn't work
     
    #3 Justin393, Apr 14, 2019
    Last edited: Apr 14, 2019
  4. Maybe try an else if statement
     
    • Optimistic Optimistic x 3
    • Funny Funny x 1
  5. Having read the javadocs, you shouldn't interact with the player object in the PlayerLoginEvent:

    PlayerLoginEvent:
    Stores details for players attempting to log in.
    Note that this event is called early in the player initialization process. It is recommended that most options involving the Player entity be postponed to the PlayerJoinEvent instead.


    Translation: some methods related to the player may not work as supposed.
    I remember trying to get the player's IP address by using the player object and failed each time. I then realised that the event had a method already :cry:
     
    • Agree Agree x 1
  6. If I am not mistaken. He means to check if the player has played before using the uuid from the AsyncPlayerPreLoginEvent
    as that event does not have a method to get the player only the UUID.
     
  7. This would require you to get the offlineplayer using Bukkit#getOfflinePlayer which can be retrieved by casting OfflinePlayer to PlayerLoginEvent#getPlayer()
     
  8. I suggested completely different thing than PlayerLoginEvent...
     
  9. The benefits of using the AsyncPlayerPreLoginEvent instead of the PlayerLoginEvent is
    1. The request to get the OfflinePlayer will not block the main thread which we know lags a lot
    2. I've got nothing only 1 :ROFLMAO:

    Most useful for anti bots, website login integration, ban management and much more!
    (this is me trying to sell the idea :giggle:)
     
  10. Not quite, the difference between AsyncPlayerLoginEvent and PlayerLoginEvent is that... one of them is clearly not running in the main thread .-.

    Yeah, I see. Seems reasonable.
     
  11. Not only that tho. AsyncPlayerPreLoginEvent is called before PlayerLoginEvent :)

    EDIT: Just noticed you said AsyncPlayerLoginEvent. We talk abolut AsyncPlayerPreLoginEvent, not AsyncPlayerLoginEvent.
     
  12. Just noticed that as well, mb.
     
  13. Strahan

    Benefactor

    Issues with Player objects aside, the idea of using the "has played before" method is flawed from the get go as mentioned prior. What you need to do is keep a List of UUIDs of who is on and when you close new joins, just check the list when a person joins the game and if they aren't in, punt them. Just don't forget to remove players from the list when they disconnect, though if new joins are closed I'd defer the removal in case they wish to relog. Then when the new joins are opened again, remove any non current players from the list.
     
  14. Could you elaborate more on that? Later on in PlayerJoinEvent I'm adding players to a HashMap and removing them when they leave


    Code (Java):
    @EventHandler
        public void onJoin(PlayerJoinEvent event) {
            Player p = event.getPlayer();
            if (p.hasPlayedBefore()) {
                EPlayer ePlayer = new EPlayer(core, event.getPlayer());
                core.ePlayers.put(event.getPlayer().getUniqueId(), ePlayer);
            } else {
                core.addNewPlayer();
                core.startJoinTimer(); // Not positive how I want to handle this
                EPlayer ePlayer = new EPlayer(core, event.getPlayer());
                core.ePlayers.put(event.getPlayer().getUniqueId(), ePlayer);
            }
        }

    Code (Java):
    @EventHandler
        public void onLeave(PlayerQuitEvent event) {
            Player p = event.getPlayer();
            EPlayer ePlayer = core.getEPlayer(p.getUniqueId());
            if (core.ePlayers.containsKey(ePlayer)) {
                core.ePlayers.remove(ePlayer);
                ePlayer.getName();
            }
        }
    The idea is like an "anti-bot spam" type of plugin so if a brand new player joins it starts a timer and if X amount of players join within X amount of minutes it stops accepting brand new players, but continues to allow returning players
     
  15. Strahan

    Benefactor

    Oh, well if you are trying to restrict to players who literally haven't played before, nevermind. I thought you mean for it to cover anyone joining who wasn't on at the time of a closing of new logins.
     
  16. To create an anti bot spam I suggest to check player's Ip. If the same ip spam the login, it's probably a bot.
     
  17.  
  18. The solution is Player#hasPlayedBefore() doesn't work as intended for some reason. I created my own and track the UUIDs in a local file to my plugin and it works perfectly fine now.

    When I used PlayerLoginEvent it was blocking players who had played before. When I used AsyncPlayerPreLoginEvent it just outright wouldn't work. Now I use PlayerLoginEvent to register all of my players and check if they have played before.