Minecraft Proxy Server - end of stream

Discussion in 'Plugin Development' started by Vecox, Nov 4, 2012.

  1. Offline

    Vecox

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    Hey guys,

    I am currently working on a proxy server for Minecraft (actually it is going to be an extensible packet filtering and redirecting stuff thing :D ). Now the problem is that even though all packets should pass the proxy flawlessly, I cannot connect to a server(Bukkit). After about one second the message "end of stream" appears in the client window, although the server keeps sending packets to the proxy.

    I had the packets logged and what I observed is the following (all in hexadecimal notation):
    1. Handshaking on both ends seems to work fine (packets: 02,FD,FC,FC,CD[actually passed through]) the onscreen message in the client changes to "downloading terrain"
    2.The server writes 01,FA,06,CA,04,03 now the client sends a CC then a 0D, this is the last packet from the client, server continues with a bunch of 03s,C9,0D,04,68,67 then 23 and 18 alternating for a time. The first chunk data (33) is sent about one second after the completion of the handshake. The last packet from the client is sent about 500ms after completion of the handshake. The server continues to send a diversity of packets for over 15 seconds after the client lost connection (then I stopped the proxy). If the complete log would help I can upload it somewhere.

    The lag introduced by the proxy is never more than 1-3ms so I think that shouldn't be a problem and since the major bottleneck is en-\decryption it isn't really improvable either. The proxy is based on netty if this information helps.

    So the question is: Why does the client quit after sending the 0D? What does it expect but fails to receive? The protocol documentation says that the server should send this and the client should answer with the same packet but with two fields swapped. But obviously the client sends it itself and the server does not seem to expect an answer to its own 0D.

    Thanks in advance.
     
  2. Offline

    Ranzdo

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    After reading, it is hard to figure out what the problem is if I can't see the source code too. FYI though, an open source project named https://github.com/ElasticPortalSuite/BungeeCord is an already working implementation of a proxy. So, you could fork that instead or help the development :).
     
  3. Offline

    Canownueasy

    My BukkitDev Profile
    My Plugins (6)
    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    You don't need to make a "proxy" specifically for MC... just receive data on the proxy server and send it to the real host.
     
  4. Offline

    Vecox

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    I know of BungeeCord and have already looked through it's source a few times but there are two problems:
    1. I started my work before it was available (as soon as I realised that raphrk's craftproxy would no longer work) and so it would be hard to drop all that finished work.

    2. It's approach to the problem is a different one. It is more based on nested streams and just letting x bytes pass those streams. I am instead parsing all packets into objects with methods and fields. That is probably slower but as I said above, the real performance problems lie elsewhere. But the reason I do this is because this is not just going to be a proxy - more like a platform which you can extend with plugins to play with those packets. Maybe I will even put the proxying into such a plugin.

    I will post the relevant parts of the source once I get home later.

    Canownueasy
    I could definitely do that but I would not be able to read any of the data (encryption). And if I have to read the actual packets in, then I must (thanks to the protocol design) actually parse all that data. So I don't need a Minecraft proxy but I do need a proxy specifically for the Minecraft protocol (as you do for example with HTTP).
     
  5. Offline

    ferrybig

    My BukkitDev Profile
    My Plugins (8)
    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    if minecraft is saying end of stream, or freezing up while using your proxy, 1 or more packets it not decoded and coded correctly
     
  6. Offline

    Vecox

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    I am aware of that but the question is which packet is it? Decoding the packets coming from the server seems to work fine, at least the internal hexdumps suggest that it does. So how can I find out which packet is the missing/corrupt one? Oh and I remembered that in some tests the client would completely crash and display that bluescreen like image. The resulting crashreports all contain the same stacktrace which is the following one:

    Code (Text):
    1. java.lang.NullPointerException
    2.     at up.<init>(SourceFile:100)
    3.     at atd.<init>(SourceFile:30)
    4.     at asv.a(SourceFile:131)
    5.     at cs.a(SourceFile:71)
    6.     at bb.b(SourceFile:333)
    7.     at asv.d(SourceFile:81)
    8.     at asy.c(SourceFile:69)
    9.     at net.minecraft.client.Minecraft.l(SourceFile:1080)
    10.     at net.minecraft.client.Minecraft.J(SourceFile:583)
    11.     at net.minecraft.client.Minecraft.run(SourceFile:535)
    12.     at java.lang.Thread.run(Unknown Source)
    Maybe someone can handle those obfuscated traces and tell me if it might be related or even tell us where the problem is?
     
  7. Offline

    ferrybig

    My BukkitDev Profile
    My Plugins (8)
    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    the up file is extending the file tt, whits contains lists from items names, so I think the "tt" class can be translated to net.minecraft.server.Items
    because the most logical is that the atd packet is related to inventory.
    if I open atd in a compiler, I see:
    "atd(int paramInt1, int paramInt2, int paramInt3, String paramString)"
    and its extending asd
    asd is containing "/gui/gui.png", so this confirms my suspect that its an inventory packet error

    up doesn't contain a line "100" at my minecraft, so or your not using 1.4.2 and I need to retrace the cause, or theres something else wrong
     
  8. Offline

    Vecox

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    The server was running on 1.3.1 and the client on 1.3.2
    I will have a closer look at inventory packets and thanks for your time.
     
  9. Offline

    Vecox

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    So now I did have a closer look at inventory packets and I might have found the actual problem. Slot data seems to be parsed somewhat wrongly. Specifically there are 0x00s in the output when there should be 0xFF or something else but they are always replaced by 0x00 (not all, just a couple at the end of the packet).

    I looked over my code a few times now but I seem to be unable to find the error so I would be really thankful if someone could have a look at it: http://dev.bukkit.org/paste/6525/ .The documentation of the slot data format can be found here: http://www.wiki.vg/Slot_Data . And the affected packets are 0x67 and 0x68.

    I hope the code is understandable but if someone wanting to help does not understand something or something is missing, I will do my best do get rid of those negligences of mine.

    Again thanks everybody for your time, I have already gotten much further thanks to your ideas.
     
  10. Offline

    md_5

    My BukkitDev Profile
    My Plugins (8)
    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    Just to let you know BungeeCord has actually been my work in some iteration or another (private until now), since before CraftProxyLitest came inactive. Its actually over 9 months old.
    If you could voice your issues with it, then maybe we can work together instead of having 2 things do the same thing.
     
  11. Offline

    Vecox

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    That is definitely interesting (helping me in getting over the fact my approach does not work within a week ;) ) but of course I did not know that a solution would appear shortly when I started my own version.

    And I don't have any "issues" with it, as I already said it is just a different approach. You chose the more effective way of leaving the bytes alone and I chose to parse them because I find it easier to work with packet objects on a high level. This would probably be unnecessary if I was just going to proxy connections, but I want to be able to access all the packets. Actually I only want to provide the bare connections, packet en-/decoding and probably handshaking and cryptography (which do already work) and let plugins handle the rest (proxying, filtering, commands and whatever you can imagine) which I guess just works better with objects.

    But even if I ignore all that and we were to make a collaborative work, it is just a question of my own ambitions to get the slot data parsing right at the moment, no matter what happens afterwards :D .
     

Share This Page