diff options
author | Lassi Pulkkinen <lassi@pulk.fi> | 2024-10-31 03:11:21 +0200 |
---|---|---|
committer | Lassi Pulkkinen <lassi@pulk.fi> | 2024-10-31 03:51:35 +0200 |
commit | ae44478b30d890fe0fb04022f44d474dcdcc3f9d (patch) | |
tree | 5f462459ae4b47d22114eed717d1382d08cf4dfe /mcproto/handshake.ha |
Diffstat (limited to 'mcproto/handshake.ha')
-rw-r--r-- | mcproto/handshake.ha | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/mcproto/handshake.ha b/mcproto/handshake.ha new file mode 100644 index 0000000..8df5254 --- /dev/null +++ b/mcproto/handshake.ha @@ -0,0 +1,46 @@ +use trace; + +export def SB_HANDSHAKE: i32 = 0x00; + +export type Handshake = struct { + proto_ver: i32, + server_addr: str, + server_port: u16, + next_state: NextState, +}; + +export type NextState = enum i32 { + STATUS = 1, + LOGIN = 2, +}; + +export fn encode_handshake(out: *[]u8, pkt: *Handshake) void = { + encode_varint(out, pkt.proto_ver); + encode_string(out, pkt.server_addr); + encode_short(out, pkt.server_port); + encode_varint(out, pkt.next_state); +}; + +export fn decode_handshake(ctx: *Context) (Handshake | trace::failed) = { + const ctx_ = context(ctx, "protocol version"); + const proto_ver = decode_varint(&ctx_)?; + const ctx_ = context(ctx, "server address"); + const server_addr = decode_string(&ctx_, 255)?; + const ctx_ = context(ctx, "server port"); + const server_port = decode_short(&ctx_)?; + const ctx_ = context(ctx, "next state"); + const next_state = decode_varint(&ctx_)?: NextState; + if (next_state != NextState::STATUS + && next_state != NextState::LOGIN) { + return error(&ctx_, "Invalid next state 0x{:02x}", + next_state: i32); + }; + expect_end(ctx)?; + + return Handshake { + proto_ver = proto_ver, + server_addr = server_addr, + server_port = server_port, + next_state = next_state, + }; +}; |