From 9f9259aad3644f25822ee2440014d2f5abf5983a Mon Sep 17 00:00:00 2001 From: c0repwn3r Date: Fri, 14 Apr 2023 10:42:45 -0400 Subject: [PATCH] finish gateway client - onwards to texture loading --- client/src/gateway.ts | 87 +++++++++++++++++++++++++++++++++++++------ client/src/index.ts | 12 +++++- 2 files changed, 85 insertions(+), 14 deletions(-) diff --git a/client/src/gateway.ts b/client/src/gateway.ts index 59fad299c8de4943898f34d26899ce0b45cfbd9a..f502392572d6a060b58e23843628e88434b33f7b 100644 --- a/client/src/gateway.ts +++ b/client/src/gateway.ts @@ -1,13 +1,26 @@ import {Logger} from "./logger"; -import {MessageC2SHello, MessageC2SHello_packetInfo} from "./protocol/message_c2s"; +import { + MessageC2SGoodbye, MessageC2SGoodbye_packetInfo, + MessageC2SHello, + MessageC2SHello_packetInfo, MessageC2SPing, + MessageC2SPing_packetInfo +} from "./protocol/message_c2s"; import {State} from "./protocol/state"; import {decode, encode} from "./serde"; import { + MessageS2CChat, + MessageS2CChat_packetInfo, MessageS2CGoodbye, MessageS2CGoodbye_packetInfo, MessageS2CHello, - MessageS2CHello_packetInfo + MessageS2CHello_packetInfo, + MessageS2CPlanetData, MessageS2CPlanetData_packetInfo, + MessageS2CPlayersUpdate, + MessageS2CPlayersUpdate_packetInfo, + MessageS2CPong_packetInfo } from "./protocol/message_s2c"; +import {GoodbyeReason} from "./protocol/goodbye_reason"; +import {global} from "./index"; const logger = new Logger("Gateway"); @@ -16,15 +29,10 @@ export interface GatewayClient { socket: WebSocket; username: string | null; version: number | null; + ping_timeout: Timeout | null; // i am aware that these types dont exist + ping_timeout_left: Timeout; // its fine } -function toHexString(byteArray) { - return Array.from(byteArray, function(byte) { - return ('0' + (byte & 0xFF).toString(16)).slice(-2); - }).join('') -} - - export async function gateway_connect(gateway_url: string, username: string): GatewayClient { logger.info("FAST CONNECT - Connecting to gateway socket at " + gateway_url); @@ -36,9 +44,29 @@ export async function gateway_connect(gateway_url: string, username: string): Ga state: State.Handshake, socket: ws, username: null, - version: null + version: null, + ping_timeout: null, + ping_timeout_left: null }; + let ping_timeout_fn = () => { + logger.error("Server didn't send back pong in time."); + let cya = MessageC2SGoodbye.encode({reason: GoodbyeReason.PingPongTimeout}).finish(); + client.socket.send(encode(MessageC2SGoodbye_packetInfo.type, cya)); + client.state = State.Handshake; + client.username = null; + client.version = null; + client.socket.close(); + } + client.ping_timeout_left = setTimeout(ping_timeout_fn, 10 * 1000); + + let ping_fn = () => { + let ping = MessageC2SPing.encode({}).finish(); + client.socket.send(encode(MessageC2SPing_packetInfo.type, ping)); + setTimeout(ping_fn, 5 * 1000); + } + client.ping_timeout = setTimeout(ping_fn, 5 * 1000); + let handshake_start_msg = MessageC2SHello.encode({ version: 1, requestedUsername: username, @@ -79,9 +107,44 @@ export async function gateway_connect(gateway_url: string, username: string): Ga logger.warn(`server sent unexpected packet ${pkt_id} for state Handshake`); } } else if (client.state == State.Play) { - // TODO + if (pkt_id == MessageS2CGoodbye_packetInfo.type) { + let pkt = MessageS2CGoodbye.decode(pkt_data); + + logger.error(`Disconnected by server. Reason: ${pkt.reason}`); + + client.state = State.Handshake; + client.username = null; + client.version = null; + + throw "Disconnected by server"; + } else if (pkt_id == MessageS2CChat_packetInfo.type) { + let pkt = MessageS2CChat.decode(pkt_data); + + logger.info(`CHAT: [${pkt.from}] ${pkt.message}`); + } else if (pkt_id == MessageS2CPong_packetInfo.type) { + clearTimeout(client.ping_timeout_left); + client.ping_timeout_left = setTimeout(ping_timeout_fn, 10 * 1000); + } else if (pkt_id == MessageS2CPlayersUpdate_packetInfo.type) { + let pkt = MessageS2CPlayersUpdate.decode(pkt_data); + global.players = pkt.players; + + for (let i = 0; i < pkt.players.length; i++) { + if (pkt.players[i].username == client.username) { + global.me = pkt.players[i]; + } + } + } else if (pkt_id == MessageS2CPlanetData_packetInfo.type) { + let pkt = MessageS2CPlanetData.decode(pkt_data); + global.planets = pkt.planets; + } else { + logger.warn(`server sent unexpected packet ${pkt_id} for state Play`); + } } - }) + }); + + + + return client; } let socket: WebSocket | undefined = undefined; diff --git a/client/src/index.ts b/client/src/index.ts index 7a8aec7a0bc0cacd94c7004c8cfd9760742cfd8c..97689417dac0ef1883baafc16a8ed5a948550ec2 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -2,16 +2,24 @@ import {Logger, logSetup} from "./logger"; import {gateway_connect, GatewayClient} from "./gateway"; +import {Player} from "./protocol/player"; +import {Planet} from "./protocol/planet"; logSetup(); const logger = new Logger("client"); export interface GlobalData { - client: GatewayClient | null + client: GatewayClient | null, + players: Player[], + planets: Planet[], + me: Player | null } export const global: GlobalData = { - client: null + client: null, + players: [], + planets: [], + me: null } async function client_main(server: string, username: string) {