DEADSOFTWARE

Добавлена задержка между выстрелами. У клиента пули не создаются без подтвеждения...
[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 m.sv.splr.shoot
44 );
45 }
47 static void cl_update_svbullet(ProtocolMessage m) {
48 g_bullet_set(
49 m.sv.sbul.id,
50 m.sv.sbul.owner,
51 m.sv.sbul.live,
52 b2f(m.sv.sbul.x),
53 b2f(m.sv.sbul.y),
54 b2f(m.sv.sbul.vx),
55 b2f(m.sv.sbul.vy),
56 m.sv.sbul.tick
57 );
58 }
60 static void cl_recv() {
61 IPaddress address;
62 ProtocolMessage m;
63 if(!RecvMessage(sock, &address, &m))
64 return;
66 switch(m.type) {
67 case SV_INFO: cl_update_svinfo(m); break;
68 case SV_KILL: cl_kill_client(m); break;
69 case SV_SPLR: cl_update_svplayer(m); break;
70 case SV_SBUL: cl_update_svbullet(m); break;
71 default: SDL_Log("invalid message %i", m.type);
72 }
73 }
75 static void cl_send() {
76 if(does_updated) {
77 SendMessage(sock, addr, cl_does(does));
79 does.bits = 0;
80 does_updated = false;
81 }
82 }
84 void cl_move(DoesBits code) {
85 does_updated = true;
86 does.bits |= code.bits;
87 }
89 void cl_connect(const char * host, uint16_t port) {
90 if(SDLNet_ResolveHost(&addr, host, (port) ? (port) : (PROTOCOL_PORT)) != 0) {
91 SDL_Log("Unable to resolve host: %s\n", SDLNet_GetError());
92 exit(1);
93 }
95 sock = OpenPort(0);
96 SendMessage(sock, addr, cl_info(nickname));
98 ProtocolMessage m;
99 bool received = WaitMessage(sock, NULL, &m, 10000);
100 if(!received) {
101 SDL_Log("Connection timeout");
102 exit(1);
105 if(m.type == SV_KILL) {
106 cl_kill_client(m);
107 } else if(m.type == SV_INFO) {
108 cl_update_svinfo(m);
109 } else {
110 SDL_Log("Invalid first message %i", m.type);
111 exit(1);
114 g_init(false);
118 void cl_disconnect(bool force) {
119 if(cl_playerid < 0)
120 return;
122 if(!force)
123 SendMessage(sock, addr, cl_kill());
125 ClosePort(sock);
127 cl_playerid = -1;
130 void cl_handle() {
131 cl_recv();
133 if(currTime - lastTime >= TICK_DELAY) {
134 if(does_updated)
135 g_player_does(cl_playerid, does);
137 g_update();
139 cl_send();
141 lastTime = SDL_GetTicks();
143 currTime = SDL_GetTicks();