DEADSOFTWARE

6c00cd29460d141be8b819193194005c95a7ec36
[netwar.git] / client.c
1 #include <assert.h>
2 #include <SDL2/SDL_net.h>
4 #include "game.h"
5 #include "client.h"
6 #include "network.h"
7 #include "protocol.h"
9 int cl_playerid = -1;
11 static IPaddress addr;
12 static UDPsocket sock;
13 static char nickname[32] = "Anonymous";
15 static Uint32 lastTime;
16 static Uint32 currTime;
18 static DoesBits does;
19 static bool does_updated;
21 static void cl_kill_client(ProtocolMessage m) {
22 SDL_Log("Connection refused by server: %.*s\n", (int) sizeof(m.sv.kill.message), m.sv.kill.message);
23 cl_disconnect(true);
24 }
26 static void cl_update_svinfo(ProtocolMessage m) {
27 SDL_Log("Connected to server %.*s\n", (int) sizeof(m.sv.info.name), m.sv.info.name);
28 cl_playerid = m.sv.info.clientid;
29 assert(cl_playerid < MAX_PLAYERS);
30 SDL_Log("Player id%i\n", cl_playerid);
31 }
33 static void cl_update_svplayer(ProtocolMessage m) {
34 g_player_set(
35 m.sv.splr.clid,
36 m.sv.splr.live,
37 b2f(m.sv.splr.x),
38 b2f(m.sv.splr.y),
39 b2f(m.sv.splr.r),
40 b2f(m.sv.splr.vx),
41 b2f(m.sv.splr.vy),
42 b2f(m.sv.splr.vr)
43 );
44 }
46 static void cl_update_svbullet(ProtocolMessage m) {
47 g_bullet_set(
48 m.sv.sbul.id,
49 m.sv.sbul.owner,
50 m.sv.sbul.live,
51 b2f(m.sv.sbul.x),
52 b2f(m.sv.sbul.y),
53 b2f(m.sv.sbul.vx),
54 b2f(m.sv.sbul.vy),
55 m.sv.sbul.tick
56 );
57 }
59 static void cl_recv() {
60 IPaddress address;
61 ProtocolMessage m;
62 if(!RecvMessage(sock, &address, &m))
63 return;
65 switch(m.type) {
66 case SV_INFO: cl_update_svinfo(m); break;
67 case SV_KILL: cl_kill_client(m); break;
68 case SV_SPLR: cl_update_svplayer(m); break;
69 case SV_SBUL: cl_update_svbullet(m); break;
70 default: SDL_Log("invalid message %i", m.type);
71 }
72 }
74 static void cl_send() {
75 if(does_updated) {
76 SendMessage(sock, addr, cl_does(does));
78 does.bits = 0;
79 does_updated = false;
80 }
81 }
83 void cl_move(DoesBits code) {
84 does_updated = true;
85 does.bits |= code.bits;
86 }
88 void cl_connect(const char * host, uint16_t port) {
89 if(SDLNet_ResolveHost(&addr, host, (port) ? (port) : (PROTOCOL_PORT)) != 0) {
90 SDL_Log("Unable to resolve host: %s\n", SDLNet_GetError());
91 exit(1);
92 }
94 sock = OpenPort(0);
95 SendMessage(sock, addr, cl_info(nickname));
97 ProtocolMessage m;
98 bool received = WaitMessage(sock, NULL, &m, 10000);
99 if(!received) {
100 SDL_Log("Connection timeout");
101 exit(1);
104 if(m.type == SV_KILL) {
105 cl_kill_client(m);
106 } else if(m.type == SV_INFO) {
107 cl_update_svinfo(m);
108 } else {
109 SDL_Log("Invalid first message %i", m.type);
110 exit(1);
115 void cl_disconnect(bool force) {
116 if(cl_playerid < 0)
117 return;
119 if(!force)
120 SendMessage(sock, addr, cl_kill());
122 ClosePort(sock);
124 cl_playerid = -1;
127 void cl_handle() {
128 cl_recv();
130 if(currTime - lastTime >= TICK_DELAY) {
131 if(does_updated)
132 g_player_does(cl_playerid, does);
134 g_update();
136 cl_send();
138 lastTime = SDL_GetTicks();
140 currTime = SDL_GetTicks();