Persistent Chunks

Discussion in 'Bukkit Discussion' started by legendblade, Jan 4, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    legendblade

    ... I don't know. It's in the protocol for the login packet, but... I've never seen it. Will have to test later.
     
  2. Offline

    Raphfrk

    Yeah, maybe it isn't present. That would be pretty annoying, as then you couldn't password protect the proxy <-> server link.
     
  3. Offline

    legendblade

    Annoying, but definitely not a deal-breaker (in most cases). You'll still be able to firewall the connection so that only the proxy server can connect to the other servers. Of course, if the proxy server doesn't have a static IP, then, that wouldn't work as well as it could otherwise.

    I suppose you could also use an SSH tunnel and not open up any port (other than SSH) on the realm servers.
     
  4. Offline

    Obsidian

    Might be the best option in that case, especially if you have the ssh tunnel use an RSA keypair for authentication.
     
  5. Offline

    legendblade

    @Obsidian You don't know how happy I am that there are people on this forum who understand me when I say things like that... my friends and coworkers all look at me like: "You did what with the why now?" >.<

    I have a feeling that's the best course of action either way (if the servers have to connect across the cloud); I don't think they're as necessary for local networks, but... security is nice.
     
  6. Offline

    Obsidian

    Not to mention, paranoia is a perfectly normal state of mind when you're dealing with anything that faces the internet. If there's a way, it will eventually be found and exploited. :)
     
  7. Offline

    Raphfrk

    Well, what I would probably do would just tell them to not open the ports and then use Shields up or something like that to verify that the ports are closed.

    My version can now do authentication against the minecraft server (but doesn't handle the virtual login to the game server yet).

    However, the last step is that the server sends the client a login packet.

    This contains

    Client's entity ID
    Blank string
    Blank string
    Map seed
    Dimension

    Hopefully, I can just set the map seed to zero (i.e. with luck it is a planned feature and does nothing at the moment)

    For example, the intention might be that this allows the server say "use the standard blocks for this chunk" with but these modifications. For chunks that haven't been changed much, this would reduce the blocks that need to be sent. However, it requires the 2 terrain generators to be locked.

    The dimension issue has already been covered. When everything is working, I am going to see what happens if you send a 2nd login packet with a different hell value. We might be lucky and it will just update the variable, but that doesn't seem likely since, it would have to re-load the graphics.

    The entity ID is potentially a problem. I think what is needed is to have an entity map of some kind.

    If the server sends an entity to the client, the map would have to remember it.

    At startup, there would be two entries:

    The default player ID must map to whatever the server actually uses.
    -1 must map to -1
     
  8. Offline

    Obsidian

    Hmm, I was wondering if the setup you guys are toying with will account for a couple things.

    1) Compass changes between the servers. Upon transitions between the servers, the compass (if it is out) will need a new origin point to aim to. Is this handled?

    2) Time synchronization. Flipping between the servers, day should still remain day, night remain night (when applicable of course). It might be easy for the servers to fall out of sync, so is it already handled, and if not, what should a good interval for resync be? Every ten minutes, every hour, or beyond that?

    3) Nether effects on watch/compass. Upon entering the nether server, the watch and compass both need to start the crazy spinning that happens in SSP. Handled?
     
  9. Offline

    legendblade

    Thus far, on my end: no, no, and no... as far as I know. There's still a lot that needs to be discovered about the process of server to client communication and how it'll react to this.
     
  10. Offline

    Raphfrk

    There is a time update packet, I would assume that it is one of the major burst of packets that the server sends the player at login.

    Worst case, it could be manually sent as a re-resyn packet.

    The site also says:

    Thus, that can also be corrected (and again is likely part of the massive data burst on login).

    I don't know about the spinning thing, that could be internal to the client. The question is if sending a fake additional login packet would cause the client to update things like that.
     
  11. Offline

    AnonymousJohn

    I'm sorry if this has been said before, but I think I know how you can do account authentication. Basically, set all your servers NOT to do server authentication, and you do it yourself on your login server. Figure out how to generate a server hash (this may be the hardest part, I dunno). Then, during the handshake, send said server hash in a packet like described here:
    http://mc.kev009.com/wiki/Protocol#Server_to_Client_2
    Then you use the following HTTP GET request to the minecraft website:
    http://www.minecraft.net/game/checkserver.jsp?user=<username>&serverId=<server hash>
    if it returns YES, the user is properly authenticated and ready to connect. Otherwise, kick him.
     
  12. Offline

    legendblade

    Mhmm. Raphfrk and I (mostly Raphfrk) came to that conclusion as well. :)

    The only thing that we leave up to question at that point is what the server hash is based on. Maybe just an MD5 hash. Will have to do more research.

    On the whole, though, this project's going really rather well. I'm still a bit behind Raphfrk's development, but... ;)
     
  13. Offline

    AnonymousJohn

    Well, that's alright. I've actually decided I'm making custom server software as well. Don't worry, though, it's not competing with yours. It's more akin to a ground-up rewrite of the official software, but (at least for now) just for testing purposes so I can test functionality I'm helping the Mineserver project with. Although now that I think about it, that's kinda silly. Oh well, it's a good excersize and it'd help me understand the communications/dynamics of the server much better. Maybe if I progress fast enough I can surpass the Mineserver project. Unlikely, though, as I'm working by myself. I'm relatively good, but I'm not THAT good. That'd just be outrageously good. :confused: But anyways, I'm rambling now, I need to get off to sleep. And finishing installing Ubuntu on my old laptop (why so laggy???) and Cygwin on my current. Been going a couple hours now, and it's finally at 60%! Shouldn't have chosen to include all those friggen libraries. ><

    On a side note, I think I butchered the spelling of excersize. Oh well.
    --- merged: Jan 9, 2011 7:32 AM ---
    Actually now that I think about it, it'd be relatively simple to test. Just get a bunch of different hashes (Notch probably used an old one instead of coming up with his own) to one of your servers, and have your loginserver print out whatever the server sends back as the hash. It's possible, though, that it's a hash of the connection, and not of the server. Or I suppose we could go trudging through obfuscated code. I'll go looking through the code right now, considering I don't have anything better to do while Cygwin's installing.

    Searched through the obfuscated code (Cygwin's still not done). It's not a SERVER hash. It appears to actually be just a random Long in Hex form. I found that the 'h' class represented the packet we were looking for (id 2), and I also found that password-protection really ISN'T implemented yet. Check this code out (from the 'gi' class):
    Code:
    public void a(h paramh) {
      if (this.e.l) {
        this.i = Long.toHexString(d.nextLong());
        this.b.a(new h(this.i));
      } else {
        this.b.a(new h("-"));
      }
    }
    
    'this.e' is the MinecraftServer object, and its 'l' parameter indicates the value from the 'online-mode' configuration. 'this.i' is a String object, not entirely sure the purpose of it. 'this.b' is a 'bs' object, and its 'a(h)' method I believe sends out packets. As you can see from this code, if 'online-mode' is on, it sends the hash (like stated on the MinecraftCoalition wiki), but if it's not, it sends a "-" (again like stated on MinecraftCoalition). 'd.nextLong()' gets a random long, as 'd' is a Random object. So as long as you generate a random long and send it in hexadecimal form, you should be fine.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jan 8, 2016
  14. Offline

    Raphfrk

    It looks like it isn't actually a hash of anything. Authentication ticket ID might be a better name.

    I used a random number and it worked fine.

    Yeah, I did the same thing when trying to see if passwords were implemented. I actually grepped the decompiled source code for "-" and came to the same conclusion.

    Well, I managed to get the proxy (which was acting as a normal world server), to log into a nether server, and this is the result:

    [​IMG]

    While interesting, it does seem that an auto-switch between servers will be weird to say the least. Hopefully, there is a way to jump the client from one mode to another "live".
    --- merged: Jan 9, 2011 1:57 PM ---
    Hmm, ok I re-sent the login packet and it kicked the client back to the "Downloading Terrain" screen.

    I wonder if that wipes the client's chunk and entity memory, but it is looking more promising :).

    Later, I need to try sending the barebones

    login packet -> player position

    and see if the player inv etc is still loaded.

    Looks like it doesn't work so easily. I had a look at the deobfuscated code from the MCP and there is a boolean that is initialised to false. When a player position packed is received, if that variable is false, the download screen is removed and it is set to true.

    However, the login packet doesn't set it back to false. This means that only 1 download can use the login screen.

    I tried it a modified client (changed it so that the login packet resets that variable) and it still was a little weird. I didn't unload any chunks, so it may just have been that it ran out of memory.

    The latest version can now handle teleporting between servers.

    If I don't unload the chunks, the memory use shoots up. However, with chunk unloading, it seems OK. There is a still a slight rise, but sometimes it drops. It could be a garbage collection thing.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jan 8, 2016
  15. Offline

    legendblade

    Good to know about the hash.

    I'm still working through the last little bit of deconstructing / constructing packets (it's easy, I've just been short on time the past few days).

    Still... even if it does have weird issues, it looks a lot more promising than what we were at... what, four or five days ago? :)
    --- merged: Jan 9, 2011 9:27 PM ---
    Damnit, stop getting ahead of me. (kidding; it's great that you've gotten it to work)
     
  16. Offline

    Raphfrk

    Yeah.

    Not planning to take it that much further. The only potential additions would be destroying all entities and I think there might be an issue with inventories.
     
  17. Offline

    legendblade

    So, ironically, while working on my login server, I realized why Notch's server-side inventory is "broken" in terms of item damage.

    Item uses (pickaxes / shovels / etc) are stored in a short, like is sent by packet 0x68. However, packets 0x0F, 0x66, and 0x67 all sent the uses as a byte.
     
  18. Offline

    AnonymousJohn

    lol, fail. That's funny. Maybe you should tell Notch. Anyways, apparently writing custom server software is harder than I thought. I think I have the sending/receiving packets down, though. Need to test with the real client instead of the fake one I've had to use (the school computers don't have good enough graphics to run Minecraft, apparently. :p)
     
  19. Offline

    legendblade

    I'm in the same boat with my work laptop. <.<

    I was thinking about it, but, I'm hoping it's already been brought up.

    I was thinking about writing my own server as well (with integration with my login server), and probably reading from a DB for everything instead of the flatfiles. I think the hardest part about it would be the terrain generation, to be honest.
     
  20. Offline

    AnonymousJohn

    Terrain generation, yeah. That'd definitely be hard, although I'm sure we could find some algorithms already out there for it. Then there's plugin support, and I'm also not entirely sure how to handle TNT. When you finish with the login server, we could form a github and work together on it if you'd like. I'm writing it in C++ (did I already say that?).
     
  21. Offline

    legendblade

    I'd love to, but my C++ is... well it's been 8-9 years since I wrote anything with it, and looking at it these days gives me a headache (mostly because my company insists on making websites that require the use of DLLs, writen in C/C++...).

    I may try and pick it back up, though, once I'm done with the login server. :)
     
  22. Offline

    AnonymousJohn

    If you can do Java, you can do C++. Only really new thing you need to pick up are certain variable names and small syntax things, and pointers. Pointers aren't too hard to learn if you find a good tutorial/explanation. BTW, what've you been writing your login server with, if not C/C++?
     
  23. Offline

    legendblade

    <.< Java. Java is a very comfortable language for me to write things in; but I did look at installing the C/C++ extensions for my IDE today. At work. :)
    --- merged: Jan 13, 2011 9:56 PM ---
    So, it looks like he did fix it, as packets 0x05, 0x0F, 0x15, 0x66,and 0x67 were updated to use a short.

    He also added a few new packets... which I have no idea what they do yet. XD
     
  24. Offline

    Raphfrk

    That is interesting. Will probably need to update the proxy :p.
     
  25. Offline

    legendblade

    Yep. I have a few of the new/updated packets in already, but not all of them are documented on MinecraftCoalition yet (and I'm too lazy to go try and figure 'em out myself)

    Code:
    ENTITY_EQUIPMENT ((byte)0x05, 9, new Class[] {Integer.class, Short.class, Short.class, Short.class})
    ENTITY_ACTION ((byte)0x13, 6, new Class[] {Integer.class, Byte.class})
    PICKUP_SPAWN ((byte)0x15, 23, new Class[] {Integer.class, Short.class, Byte.class, Short.class, Integer.class, Integer.class, Integer.class, Byte.class, Byte.class, Byte.class})
    
    And some of the unknown ones, but still semi-documented:
    Code:
    UNKNOWN2 ((byte)0x19, Packet.VARIABLE_LENGTH, new Class[] {Integer.class, String.class, Integer.class, Integer.class, Integer.class, Integer.class})
    UNKNOWN4 ((byte)0x36, 11, new Class[] {Integer.class, Short.class, Integer.class, Byte.class, Byte.class})
    
    There are a few (0x18 and 0x28) that have what was dubbed as "Insanity" on the end of them. Their pastebin from that looks a little something like:

    Code:
    int i = paramDataInputStream.readByte();
    while(i != 127)
    {
            if(localArrayList ==null){
                    localArrayList =newArrayList();
            }
            int j =(i & 0xE0)>>5;
            int k = i & 0x1F;
            b localb =null;
            switch(j){
                    case 0:
                            localb =new b(j, k, Byte.valueOf(paramDataInputStream.readByte()));
                            break;
                    case 1:
                            localb =new b(j, k, Short.valueOf(paramDataInputStream.readShort()));
                            break;
                    case 2:
                            localb =new b(j, k, Integer.valueOf(paramDataInputStream.readInt()));
                            break;
                    case 3:
                            localb =new b(j, k, Float.valueOf(paramDataInputStream.readFloat()));
                            break;
                    case 4:
                            localb =new b(j, k, paramDataInputStream.readUTF());
                            break;
                    case 5:
                            int m = paramDataInputStream.readShort();
                            int n = paramDataInputStream.readByte();
                            int i1 = paramDataInputStream.readShort();
                            localb =new b(j, k, new jl(m, n, i1));
            }
            localArrayList.add(localb);
            i = paramDataInputStream.readByte();
    }
    
     
  26. Offline

    Afforess

    b() is Notch's vector class, IIRC, so he's just creating a vector with the input data. Not insanity.
     
  27. Offline

    legendblade

    Good to know (and I was just calling it what they did. :))

    Still... for parsing out the packets, that is a bit of a pain.
     
Thread Status:
Not open for further replies.

Share This Page