barneygale / quarry

Python library that implements the Minecraft network protocol and data types
Other
532 stars 74 forks source link

'factory.favicon' not work #48

Closed paulzzh closed 5 years ago

paulzzh commented 6 years ago

My code: (It's a copy of 'example/server_downtime.py')

from twisted.internet import reactor from quarry.net.server import ServerFactory, ServerProtocol class DowntimeProtocol(ServerProtocol): def packet_login_start(self, buff): buff.discard()

self.close(self.factory.motd)

    self.close("balabalbalabalabala...")
    logger.info("someone tryed to join,Start Server")
    reactor.callLater(3,reactor.stop)

class DowntimeFactory(ServerFactory): protocol = DowntimeProtocol

def waitmain():

Create factory

factory = DowntimeFactory()
factory.motd = "balabalabala...."
factory.max_players = 8
factory.online_mode = False
factory.favicon = 'icon.png'
# Listen
factory.listen("0.0.0.0", 25565)
reactor.run()

waitmain()

In fact, it doesn't work very well: image I have delete the 'server.dat' ,but it‘s useless.. I 'm sure I have put a 'icon.png' with the script. This 'icon.png' works well in a 1.13 vanilla server.

dries007 commented 6 years ago

This is due to a MC bug, the protocol has remained but something about the data has changed. The relevant issue on the MC tracker has been reopened: https://bugs.mojang.com/browse/MC-121282 After inspection with wireshark I found that if you copy-paste the data the vanilla client sends, it works correctly, but that data is not a plain 1:1 base64 encoding of the PNG anymore.

Another note about the relevant code: It's not really efficient to reload the file every launch, so I'm locally patching the code to do this now, which also allows me to paste in a working string and get an icon for the time being:

# in file 'quarry/net/server.py' at line 255:
        if self.factory.favicon is not None:
            d["favicon"] = self.factory.favicon # todo: Patch! Also, stop using 'base64.encodestring', it's deprecated and adds \n's for no reason.
            #with open(self.factory.favicon, "rb") as fd:
            #    d["favicon"] = "data:image/png;base64," + base64.encodestring(
            #        fd.read()).decode('ascii')

Edit: I should have waited a bit longer before posting this, for a quicker fix, see the PR linked below.

barneygale commented 5 years ago

Fixed in #49, thanks @dries007!