use mcproto; use strings; use trace; use uuid; fn login_start() void = { let buf: []u8 = []; mcproto::encode_handshake(&buf, &mcproto::Handshake { proto_ver = PROTO_VER, // TODO: is there a way to get these from the dial api? server_addr = CLIENT_ADDR, server_port = 25565, next_state = mcproto::NextState::LOGIN, }); network_send(mcproto::SB_HANDSHAKE, buf); let buf: []u8 = []; mcproto::encode_string(&buf, CLIENT_USERNAME); mcproto::encode_bool(&buf, false); network_send(0x00, buf); }; fn login_handle_packet(ctx: *mcproto::Context, packet_id: i32) (void | trace::failed) = { switch (packet_id) { case 0x00 => const ctx = mcproto::context(ctx, "0x00 disconnect"); const ctx_ = mcproto::context(&ctx, "reason"); const reason = mcproto::decode_string(&ctx_, 262144)?; mcproto::expect_end(&ctx)?; return trace::error(&trace::root, "Kicked by server: {}", reason); case 0x04 => const ctx = mcproto::context(ctx, "0x04 login plugin request"); const ctx_ = mcproto::context(&ctx, "id"); const id = mcproto::decode_varint(&ctx_)?; let buf: []u8 = []; mcproto::encode_varint(&buf, id); network_send(0x02, buf); case 0x02 => const ctx = mcproto::context(ctx, "0x02 login success"); const ctx_ = mcproto::context(&ctx, "uuid"); const uuid = mcproto::decode_uuid(&ctx_)?; const ctx_ = mcproto::context(&ctx, "username"); const username = mcproto::decode_string(&ctx_, 16)?; // TODO: more stuff... free(CLIENT_USERNAME); CLIENT_USERNAME = strings::dup(username); trace::info(&trace::root, "logged in as {} ({})", username, uuid::encodestr(uuid)); CLIENT_STATE = ClientState::JOIN; case => return mcproto::error(ctx, "Unexpected packet id 0x{:02x} (only uncompressed offline mode is supported)", packet_id); }; };