async def event_login_encryption(cls, evt: ConfirmEncryptionEvent): if evt.verify != evt._conn.verify_token: raise Exception("Invalid verification token!") evt._conn.cipher.enable(evt.secret) digest = make_digest( evt._conn.server_id.encode(), evt.secret, ServerCore.pubkey ) url = "https://sessionserver.mojang.com/session/minecraft/hasJoined" params = { "username": evt._conn.name, "serverId": digest } if ServerCore.options["prevent-proxy-connections"]: params["ip"] = evt._conn.client.server_hostname async with fail_after(ServerCore.auth_timeout): # FIXME: Fails on curio resp = await asks.get(url, params=params) data = resp.json() info(data) evt._conn.uuid = UUID(data["id"]) evt._conn.packet_decoder.status = 3 return PlayerRegistry.add_player(evt._conn)
async def decode_login_encryption_response(cls, msg: ClientMessage) ->...: # 1.7.x if msg.protocol_version <= 5: unpack_array = lambda b: b.read(b.unpack('h')) else: unpack_array = lambda b: b.read(b.unpack_varint(max_bits=16)) buffer = msg.buffer p_shared_secret = unpack_array(buffer) p_shared_verify = unpack_array(buffer) shared_secret = decrypt_secret(ServerCore.keypair, p_shared_secret) shared_verify = decrypt_secret(ServerCore.keypair, p_shared_verify) if shared_verify != msg.conn.verify_token: msg.close_connection("Invalid verify token!") msg.conn.cipher.enable(shared_secret) digest = make_digest(msg.conn.server_id.encode("ascii"), shared_secret, ServerCore.pubkey) url = ("https://sessionserver.mojang.com/session/minecraft/hasJoined" + f"?username={msg.conn.display_name}&serverId={digest}") if ServerCore.options["prevent-proxy-connections"]: url += f"&ip={msg.conn.client.server_hostname}" async with ClientSession() as session: async with session.get(url, timeout=ServerCore.auth_timeout) as resp: data = await resp.json() msg.conn.uuid = UUID(data["id"]) cls.update_protocol(msg, "play") return PlayerRegistry.add_player(msg.conn)
def update_protocol(cls, msg: ClientMessage, mode: str): if mode == "play": if msg.compression_threshold: # Send set compression msg.send_packet( "login_set_compression", msg.buffer_type.pack_varint(msg.compression_threshold)) # Send login success msg.send_packet( "login_success", msg.buffer_type.pack_string(str(msg.conn.uuid)) + msg.buffer_type.pack_string(msg.conn.display_name)) elif mode == "login": if PlayerRegistry.player_count( ) >= ServerCore.options["max-players"]: msg.close_connection("Server is full!") msg.conn.protocol_state = mode
async def decode_status_request(cls, msg: ClientMessage): d = { "description": { "text": ServerCore.options["motd"] }, "players": { "online": PlayerRegistry.player_count(), "max": ServerCore.options["max-players"] }, "version": { "name": packets.minecraft_versions.get(msg.protocol_version, "???"), "protocol": msg.protocol_version } } favicon = read_favicon() if favicon: d["favicon"] = f"data:image/png;base64,{favicon}" msg.send_packet("status_response", msg.buffer_type.pack_json(d))
async def event_status(cls, evt: StatusEvent): data = { "description": { "text": ServerCore.options["motd"] }, "players": { "online": PlayerRegistry.player_count(), "max": ServerCore.options["max-players"] }, "version": { "name": packets.minecraft_versions.get( evt._conn.protocol_version, "???"), "protocol": evt._conn.protocol_version, } } favicon = read_favicon() if favicon: data["favicon"] = f"data:image/png;base64,{favicon}" evt._conn.send_packet("status", data)
def player(self) -> Player: return PlayerRegistry.get_player(self.uuid)