#include #include #include "game.h" #include "client.h" #include "network.h" #include "protocol.h" int cl_playerid = -1; static IPaddress addr; static UDPsocket sock; static char nickname[32] = "Anonymous"; static Uint32 lastTime; static Uint32 currTime; static DoesBits does; static bool does_updated; static void cl_kill_client(ProtocolMessage m) { SDL_Log("Connection refused by server: %.*s\n", (int) sizeof(m.sv.kill.message), m.sv.kill.message); cl_disconnect(true); } static void cl_update_svinfo(ProtocolMessage m) { SDL_Log("Connected to server %.*s\n", (int) sizeof(m.sv.info.name), m.sv.info.name); cl_playerid = m.sv.info.clientid; assert(cl_playerid < MAX_PLAYERS); SDL_Log("Player id%i\n", cl_playerid); } static void cl_update_svplayer(ProtocolMessage m) { g_player_set( m.sv.splr.clid, m.sv.splr.live, b2f(m.sv.splr.x), b2f(m.sv.splr.y), b2f(m.sv.splr.r), b2f(m.sv.splr.vx), b2f(m.sv.splr.vy), b2f(m.sv.splr.vr), m.sv.splr.shoot ); } static void cl_update_svbullet(ProtocolMessage m) { g_bullet_set( m.sv.sbul.id, m.sv.sbul.owner, m.sv.sbul.live, b2f(m.sv.sbul.x), b2f(m.sv.sbul.y), b2f(m.sv.sbul.vx), b2f(m.sv.sbul.vy), m.sv.sbul.tick ); } static void cl_recv() { IPaddress address; ProtocolMessage m; if(!RecvMessage(sock, &address, &m)) return; switch(m.type) { case SV_INFO: cl_update_svinfo(m); break; case SV_KILL: cl_kill_client(m); break; case SV_SPLR: cl_update_svplayer(m); break; case SV_SBUL: cl_update_svbullet(m); break; default: SDL_Log("invalid message %i", m.type); } } static void cl_send() { if(does_updated) { SendMessage(sock, addr, cl_does(does)); does.bits = 0; does_updated = false; } } void cl_move(DoesBits code) { does_updated = true; does.bits |= code.bits; } void cl_connect(const char * host, uint16_t port) { if(SDLNet_ResolveHost(&addr, host, (port) ? (port) : (PROTOCOL_PORT)) != 0) { SDL_Log("Unable to resolve host: %s\n", SDLNet_GetError()); exit(1); } sock = OpenPort(0); SendMessage(sock, addr, cl_info(nickname)); ProtocolMessage m; bool received = WaitMessage(sock, NULL, &m, 10000); if(!received) { SDL_Log("Connection timeout"); exit(1); } if(m.type == SV_KILL) { cl_kill_client(m); } else if(m.type == SV_INFO) { cl_update_svinfo(m); } else { SDL_Log("Invalid first message %i", m.type); exit(1); } g_init(false); } void cl_disconnect(bool force) { if(cl_playerid < 0) return; if(!force) SendMessage(sock, addr, cl_kill()); ClosePort(sock); cl_playerid = -1; } void cl_handle() { cl_recv(); if(currTime - lastTime >= TICK_DELAY) { if(does_updated) g_player_does(cl_playerid, does); g_update(); cl_send(); lastTime = SDL_GetTicks(); } currTime = SDL_GetTicks(); }