Esempio n. 1
0
async def encrypted_login(stream: Stream, packet: Packet) -> tuple:
    shared_key, auth = await server_auth(packet, stream.remote,
                                         login_cache[stream.remote])

    del login_cache[stream.remote]  # No longer needed

    if not auth:  # If authentication failed, disconnect client
        stream.write(
            Buffer.pack_packet(
                login_packets.LoginDisconnect(
                    "Failed to authenticate your connection.")))
        await stream.drain()
        return False, stream

    # Generate a cipher for that client using the shared key from the client
    cipher = encryption.gen_aes_cipher(shared_key)

    # Replace stream with one which auto decrypts + encrypts data when reading/writing
    stream = EncryptedStream(stream, cipher)

    if share["comp_thresh"] > 0:  # Send set compression packet if needed
        stream.write(
            Buffer.pack_packet(LoginSetCompression(share["comp_thresh"])))
        await stream.drain()

    # Send LoginSuccess packet, tells client they've logged in succesfully
    stream.write(
        Buffer.pack_packet(login_packets.LoginSuccess(*auth),
                           share["comp_thresh"]))
    await stream.drain()

    return True, stream
Esempio n. 2
0
async def login_start(stream: Stream, packet: Packet) -> tuple:
    if share["conf"][
            "online_mode"]:  # Online mode is enabled, so we request encryption
        lc = login_cache[stream.remote] = {
            "username": packet.username,
            "verify": None
        }

        packet = login_packets.LoginEncryptionRequest(
            share["rsa"]["public"].public_bytes(
                encoding=serialization.Encoding.DER,
                format=serialization.PublicFormat.SubjectPublicKeyInfo))

        lc["verify"] = packet.verify_token

        stream.write(Buffer.pack_packet(packet))
        await stream.drain()
    else:  # No need for encryption since online mode is off, just send login success
        uuid_ = (
            uuid.uuid4()
        )  # This should be only generated if the player name isn't found in the world data, but no way to do that rn

        stream.write(
            Buffer.pack_packet(
                login_packets.LoginSuccess(uuid_, packet.username),
                share["comp_thresh"]))
        await stream.drain()

        states[stream.remote] = 3  # Update state to play

    return True, stream
Esempio n. 3
0
async def finish_join(r: StreamReader, w: StreamWriter, remote: tuple) -> None:
    lvl_name = share["conf"]["level_name"]
    entity_id = entity_id_cache.get(remote)

    if entity_id is None:
        entity_id = entity_id_cache[remote] = int(time.time())

    w.write(
        Buffer.pack_packet(
            packets_player.PlayJoinGame(
                entity_id,
                share["conf"]["hardcore"],
                0,  # Shoudl be current gamemode
                -1,  # Should be previous gamemode
                # Should be actual world names
                [f"minecraft:{lvl_name}", f"minecraft:{lvl_name}_nether", f"minecraft:{lvl_name}_the_end"],
                nbt.TAG_Int(name="bruh", value=1),
                nbt.TAG_Int(name="bruh", value=1),
                f"minecraft:{lvl_name}",  # should be actual current world name
                seed_hash(share["conf"]["seed"]),
                share["conf"]["max_players"],
                share["conf"]["view_distance"],
                (not share["conf"]["debug"]),
                True,  # should be (not doImmediateRespawn gamerule)
                False,
                False,  # Should be true if world is superflat
            )
        )
    )

    await w.drain()
Esempio n. 4
0
    async def send_packet(self, stream: Stream, packet: Packet, comp_thresh=None):
        self.console.debug(f"OUT: state:-1 | id:0x{packet.id:02X} | packet:{type(packet).__name__}")

        if comp_thresh is None:
            comp_thresh = self.comp_thresh

        stream.write(Buffer.pack_packet(packet, comp_thresh))
        await stream.drain()
Esempio n. 5
0
async def send_status(stream: Stream, packet: Packet) -> tuple:
    data = {
        "version": {
            "name": share["version"],
            "protocol": share["protocol"]
        },
        "players": {
            "max":
            share["conf"]["max_players"],
            "online":
            len(share["states"]),
            "sample": [
                {
                    "name": "Iapetus11",
                    "id": "cbcfa252-867d-4bda-a214-776c881cf370"
                },
                {
                    "name": "Sh_wayz",
                    "id": "cbcfa252-867d-4bda-a214-776c881cf370"
                },
                {
                    "name": "emeralddragonmc",
                    "id": "eb86dc19-c3f5-4aef-a50e-a4bf435a7528"
                },
            ],
        },
        "description": {
            "text": share["conf"]["motd"]
        },  # a Chat
    }

    if share["favicon"]:
        data["favicon"] = share["favicon"]

    stream.write(Buffer.pack_packet(status_packets.StatusStatusResponse(data)))
    await stream.drain()

    return True, stream
Esempio n. 6
0
async def send_pong(stream: Stream, packet: Packet) -> tuple:
    stream.write(Buffer.pack_packet(packet))
    await stream.drain()

    return False, stream