Premium join verification

Discussion in 'Spigot Plugin Development' started by Zeuss, May 6, 2017.

Thread Status:
Not open for further replies.
  1. Good afternoon, I started creating a server (offline-mode) and I would like to make a system for "extra benefits in relation to the initial kits" for the players that are Premium but then comes my problem, like checking if the person who entered is Premium

    Because it has 3 types of logins that can Occur:

    1st - Premium player logs in to your account normally.
    2nd - Cracked player enters with Nick of a Player Premium.
    3rd - Cracked player enters with a Nick that does not exist.

    I would like to block the 2nd Login and only for the 3rd Login people of a different "Profit".

    If possible who can show some codes.

    Sorry for my English :(
     
    • Like Like x 1
    • Winner Winner x 1
  2. I think this would be extremely hard, if not impossible to do. Having your server in offline mode means it completely disables the authentication to Minecraft.net, meaning the server would have no idea, and no way of checking if a player is premium or not. Any cracked player could join with the username of a premium player and the server would never be able to tell the difference as far as my experience goes.
     
  3. Why are you even making offline server?
     
  4. At first you should read and understand this.
    Then you know how to use https://sessionserver.mojang.com/session/minecraft/hasJoined?username=<username>&serverId=<hash>.
    The only tricky part is to get the client-generated serverId hash of your server. But it's possible. I already did it at 1.10.2 like this, but i didn't found a proper way to get the server hash, i puzzled it out of the ever first send packets to the server.

    It's possible, but quite hard to listen to the correct packet.
     
    #5 Michel_0, May 6, 2017
    Last edited: May 6, 2017
    • Like Like x 1
  5. Now why would this be impossible to do? The server already does this authentication when a player joins in a online mode server, and since we have full control over the server, I would say its very logical to assume that it is possible.
     
  6. No, He's right. It's impossible to see if someone has payed for their account on an offline server. A cracked player can use a premium player's account and nothing is able to determine whether that's the real player or not. When the server is in offline mode, the Mojang servers are not contacted and the players are not verified.
     
  7. I think you would need a modified spigot .jar file, to see if the player can be authenticated, if not, then let the player in any way. But I am not sure if that is 100% possible either.
     
  8. AutoIn can perform a scan on any server except servers with MODS.
     
    • Agree Agree x 1
  9. Did you even read prior answers? I already proofed you wrong.
    No mod necessary. Not clientside, nor serverside.
     
  10. No.

    The server decides if the player is allowed to login, not the client and we have full control over the server.. I haven't done that much research yet however I believe if you set the server to online mode and call the method j (of version 1.7, probably is something different now) with an empty (non-null) string then it will let unauthed users login. I also don't know the side effects of this (UUIDs and whatnot).

    Or the other way of manually checking but would need to get the server hash which I don't know if it is generated while in offline mode or skipped over.
     
  11. Except a lot of clients that allow cracked users don't even let you connect to a server that isn't cracked as well, eliminating the use of this plugin.
     
  12. I'm fairly sure you cannot tell if the server is cracked until you start the connection process, as its not sent in the server ping

    EDIT:
    I think this code generates the server id/hash
    Code (Text):
    String s = (new BigInteger(MinecraftEncryption.a(LoginListener.b(this.a), LoginListener.c(this.a).K().getPublic(), LoginListener.d(this.a)))).toString(16);
    Although I don't know how you would get the login listener instance of a player
     
  13. You can just run the server in online mode, and skip authentication if the user connects through a specific host (which is known in the handshake). Then just check their UUID version (4 = authenticated, 3 = not authenticated)
     
  14. Many many rumors and unproofed opinions are taking place in here.
    So i start getting a little more in detail.

    This is how i did it on a 1.10.2 offline-mode spigot server:
    Code (Java):
    // channel is the netty channel of the player connection
    // handle is my debugging packet decoder i add on the player channel
    // all NMS inports related to net.minecraft.server.v1_10_R1
    ChannelHandler handle = new MessageToMessageDecoder<Packet>() {
        @Override
        protected void decode(ChannelHandlerContext chc, Packet packet, List<Object> out) throws Exception {
            System.out.println("Received " + packet.getClass().getSimpleName());
            if (packet instanceof PacketHandshakingInSetProtocol) {
                System.out.println("Handshake details:");
                System.out.println(" - protocol version: " + Integer.toString(((PacketHandshakingInSetProtocol) packet).b()));
                System.out.println(" - servername: " + ((PacketHandshakingInSetProtocol) packet).hostname);
                System.out.println(" - port: " + ((PacketHandshakingInSetProtocol) packet).port);
                System.out.println(" - next state: " + ((PacketHandshakingInSetProtocol) packet).a().toString());
            } else if (packet instanceof PacketLoginInStart) {
                System.out.println("Login details:");
                System.out.println(" - name: " + ((PacketLoginInStart) packet).a().getName());
                System.out.println(" - name: " + ((PacketLoginInStart) packet).a().getId());
            } else if (packet instanceof PacketLoginInEncryptionBegin) {
                /* ------------------------------ *
                 * Here starts the IMPORTANT part */

                MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer();
                System.out.println("Encryption details:");
                SecretKey loginKey = ((PacketLoginInEncryptionBegin) packet).a(server.O().getPrivate());
                String serverId = new BigInteger(MinecraftEncryption.a("", server.O().getPublic(), loginKey)).toString(16);
                System.out.println(" - serverId: " + serverId);
                /* End of IMPORTANT part *
                 * --------------------- */

            }
            out.add(packet);
        }
    };
    channel.pipeline().addAfter("decoder", "universalListener", handle);
    The variable "serverId" holds the valid server ID, ready to be used at https://sessionserver.mojang.com/session/minecraft/hasJoined?username=<username>&serverId=<hash>.
    The problem is to register this decoder right after the player joins. All this happens ages before any bukkit event is fired. I end up checking every tick for new players, which is a pretty bad way. I guess you should modify the future channel decoder thingy whatever... or try ProtocolLib.

    Have fun experimenting with it.
     
    #15 Michel_0, May 6, 2017
    Last edited: May 6, 2017
    • Useful Useful x 2
    • Winner Winner x 1
    • Informative Informative x 1
  15. It's possible on an online server, but as I said before, on the default spigot build, even with plugins, you cannot determine whether a player is the real owner of a premium account
     
  16.  
  17. I should have specified, I meant without NMS. Sorry.
     
  18. I've rated your post as winner, but also check for the UUID (I'm not sure if in offline-mode the UUID is the same as in online-mode)
     
  19. It's not.
     
Thread Status:
Not open for further replies.