source: network-game/client/Client/main.cpp@ 4da5aa3

Last change on this file since 4da5aa3 was 4da5aa3, checked in by dportnoy <dmp1488@…>, 12 years ago

Created a process message function to handle message received from the server

  • Property mode set to 100644
File size: 9.9 KB
Line 
1#include "../../common/compiler.h"
2
3#if defined WINDOWS
4 #include <winsock2.h>
5 #include <WS2tcpip.h>
6#elif defined LINUX
7 #include <sys/types.h>
8 #include <unistd.h>
9 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #include <netdb.h>
12 #include <cstring>
13#endif
14
15#include <sys/types.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string>
19#include <iostream>
20#include <vector>
21
22#include <allegro5/allegro.h>
23#include <allegro5/allegro_font.h>
24#include <allegro5/allegro_ttf.h>
25
26#include "../../common/message.h"
27
28#include "chat.h"
29
30#ifdef WINDOWS
31 #pragma comment(lib, "ws2_32.lib")
32#endif
33
34using namespace std;
35
36void initWinSock();
37void shutdownWinSock();
38void processMessage(NETWORK_MSG &msg, int &state, chat &chatConsole, string &username);
39
40void error(const char *);
41
42const float FPS = 60;
43const int SCREEN_W = 640;
44const int SCREEN_H = 480;
45const int BOUNCER_SIZE = 32;
46enum MYKEYS {
47 KEY_UP,
48 KEY_DOWN,
49 KEY_LEFT,
50 KEY_RIGHT
51};
52
53enum STATE {
54 STATE_START,
55 STATE_LOGIN,
56 STATE_LOGOUT
57};
58
59int main(int argc, char **argv)
60{
61 ALLEGRO_DISPLAY *display = NULL;
62 ALLEGRO_EVENT_QUEUE *event_queue = NULL;
63 ALLEGRO_TIMER *timer = NULL;
64 ALLEGRO_BITMAP *bouncer = NULL;
65 float bouncer_x = SCREEN_W / 2.0 - BOUNCER_SIZE / 2.0;
66 float bouncer_y = SCREEN_H / 2.0 - BOUNCER_SIZE / 2.0;
67 bool key[4] = { false, false, false, false };
68 bool redraw = true;
69 bool doexit = false;
70
71 int state = STATE_START;
72
73 chat chatConsole;
74
75 if(!al_init()) {
76 fprintf(stderr, "failed to initialize allegro!\n");
77 return -1;
78 }
79
80 al_init_font_addon();
81 al_init_ttf_addon();
82
83 ALLEGRO_FONT *font = al_load_ttf_font("../pirulen.ttf", 12, 0);
84
85 if (!font) {
86 fprintf(stderr, "Could not load 'pirulen.ttf'.\n");
87 getchar();
88 return -1;
89 }
90
91 if(!al_install_keyboard()) {
92 fprintf(stderr, "failed to initialize the keyboard!\n");
93 return -1;
94 }
95
96 timer = al_create_timer(1.0 / FPS);
97 if(!timer) {
98 fprintf(stderr, "failed to create timer!\n");
99 return -1;
100 }
101
102 display = al_create_display(SCREEN_W, SCREEN_H);
103 if(!display) {
104 fprintf(stderr, "failed to create display!\n");
105 al_destroy_timer(timer);
106 return -1;
107 }
108
109 bouncer = al_create_bitmap(BOUNCER_SIZE, BOUNCER_SIZE);
110 if(!bouncer) {
111 fprintf(stderr, "failed to create bouncer bitmap!\n");
112 al_destroy_display(display);
113 al_destroy_timer(timer);
114 return -1;
115 }
116
117 event_queue = al_create_event_queue();
118 if(!event_queue) {
119 fprintf(stderr, "failed to create event_queue!\n");
120 al_destroy_bitmap(bouncer);
121 al_destroy_display(display);
122 al_destroy_timer(timer);
123 return -1;
124 }
125
126 al_set_target_bitmap(bouncer);
127
128 al_clear_to_color(al_map_rgb(255, 0, 255));
129
130 al_set_target_bitmap(al_get_backbuffer(display));
131
132 al_register_event_source(event_queue, al_get_display_event_source(display));
133
134 al_register_event_source(event_queue, al_get_timer_event_source(timer));
135
136 al_register_event_source(event_queue, al_get_keyboard_event_source());
137
138 al_clear_to_color(al_map_rgb(0,0,0));
139
140 al_flip_display();
141
142 int sock;
143 struct sockaddr_in server, from;
144 struct hostent *hp;
145 NETWORK_MSG msgTo, msgFrom;
146 string username;
147
148 if (argc != 3) {
149 cout << "Usage: server port" << endl;
150 exit(1);
151 }
152
153 initWinSock();
154
155 sock = socket(AF_INET, SOCK_DGRAM, 0);
156 if (sock < 0)
157 error("socket");
158
159 server.sin_family = AF_INET;
160 hp = gethostbyname(argv[1]);
161 if (hp==0)
162 error("Unknown host");
163
164 memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
165 server.sin_port = htons(atoi(argv[2]));
166
167 al_start_timer(timer);
168
169 while(!doexit)
170 {
171 ALLEGRO_EVENT ev;
172 al_wait_for_event(event_queue, &ev);
173
174 if(ev.type == ALLEGRO_EVENT_TIMER) {
175 if(key[KEY_UP] && bouncer_y >= 4.0) {
176 bouncer_y -= 4.0;
177 }
178
179 if(key[KEY_DOWN] && bouncer_y <= SCREEN_H - BOUNCER_SIZE - 4.0) {
180 bouncer_y += 4.0;
181 }
182
183 if(key[KEY_LEFT] && bouncer_x >= 4.0) {
184 bouncer_x -= 4.0;
185 }
186
187 if(key[KEY_RIGHT] && bouncer_x <= SCREEN_W - BOUNCER_SIZE - 4.0) {
188 bouncer_x += 4.0;
189 }
190
191 redraw = true;
192 }
193 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
194 doexit = true;
195 }
196 else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) {
197 bool eventConsumed = chatConsole.processEvent(ev);
198
199 if (eventConsumed) {
200 string input = chatConsole.getInput();
201 if (!input.empty()) {
202 cout << "input: " << input << endl;
203 strcpy(msgTo.buffer, input.c_str());
204
205 switch(state)
206 {
207 case STATE_START:
208 {
209 msgTo.type = MSG_TYPE_LOGIN;
210 username = input;
211
212 sendMessage(&msgTo, sock, &server);
213 receiveMessage(&msgFrom, sock, &from);
214 processMessage(msgFrom, state, chatConsole, username);
215 cout << "state: " << state << endl;
216
217 break;
218 }
219 case STATE_LOGIN:
220 {
221 if (input.compare("quit") == 0 ||
222 input.compare("exit") == 0 ||
223 input.compare("logout") == 0)
224 {
225 strcpy(msgTo.buffer, username.c_str());
226 msgTo.type = MSG_TYPE_LOGOUT;
227 }
228 else
229 msgTo.type = MSG_TYPE_CHAT;
230
231 sendMessage(&msgTo, sock, &server);
232 receiveMessage(&msgFrom, sock, &from);
233 processMessage(msgFrom, state, chatConsole, username);
234 cout << "state: " << state << endl;
235
236 break;
237 }
238 case STATE_LOGOUT:
239 {
240 chatConsole.addLine("You're logged out, so you can't send any messages to the server.");
241
242 cout << "You're logged out, so you can't send any messages to the server." << endl;
243
244 break;
245 }
246 default:
247 {
248 cout << "The state has an invalid value: " << state << endl;
249
250 break;
251 }
252 }
253 }
254 }else {
255 switch(ev.keyboard.keycode) {
256 case ALLEGRO_KEY_UP:
257 key[KEY_UP] = true;
258 break;
259
260 case ALLEGRO_KEY_DOWN:
261 key[KEY_DOWN] = true;
262 break;
263
264 case ALLEGRO_KEY_LEFT:
265 key[KEY_LEFT] = true;
266 break;
267
268 case ALLEGRO_KEY_RIGHT:
269 key[KEY_RIGHT] = true;
270 break;
271 }
272 }
273 }
274 else if(ev.type == ALLEGRO_EVENT_KEY_UP) {
275 switch(ev.keyboard.keycode) {
276 case ALLEGRO_KEY_UP:
277 key[KEY_UP] = false;
278 break;
279
280 case ALLEGRO_KEY_DOWN:
281 key[KEY_DOWN] = false;
282 break;
283
284 case ALLEGRO_KEY_LEFT:
285 key[KEY_LEFT] = false;
286 break;
287
288 case ALLEGRO_KEY_RIGHT:
289 key[KEY_RIGHT] = false;
290 break;
291
292 case ALLEGRO_KEY_ESCAPE:
293 doexit = true;
294 break;
295 }
296 }
297
298 if(redraw && al_is_event_queue_empty(event_queue)) {
299 redraw = false;
300
301 al_clear_to_color(al_map_rgb(0,0,0));
302
303 al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0);
304
305 chatConsole.draw(font, al_map_rgb(255,255,255));
306
307 al_flip_display();
308 }
309 }
310
311 #if defined WINDOWS
312 closesocket(sock);
313 #elif defined LINUX
314 close(sock);
315 #endif
316
317 shutdownWinSock();
318
319 al_destroy_event_queue(event_queue);
320 al_destroy_bitmap(bouncer);
321 al_destroy_display(display);
322 al_destroy_timer(timer);
323
324 return 0;
325}
326
327// need to make a function like this that works on windows
328void error(const char *msg)
329{
330 perror(msg);
331 shutdownWinSock();
332 exit(1);
333}
334
335void initWinSock()
336{
337#if defined WINDOWS
338 WORD wVersionRequested;
339 WSADATA wsaData;
340 int wsaerr;
341
342 wVersionRequested = MAKEWORD(2, 2);
343 wsaerr = WSAStartup(wVersionRequested, &wsaData);
344
345 if (wsaerr != 0) {
346 cout << "The Winsock dll not found." << endl;
347 exit(1);
348 }else
349 cout << "The Winsock dll was found." << endl;
350#endif
351}
352
353void shutdownWinSock()
354{
355#if defined WINDOWS
356 WSACleanup();
357#endif
358}
359
360void processMessage(NETWORK_MSG &msg, int &state, chat &chatConsole, string &username)
361{
362 string response = string(msg.buffer);
363
364 // this whole select block should go in a new function.
365 // Figure out how to pass and return params properly
366 switch(state)
367 {
368 case STATE_START:
369 {
370 chatConsole.addLine(response);
371
372 if (response.compare("Player has already logged in.") == 0)
373 {
374 cout << "User login failed" << endl;
375 username.clear();
376 }
377 else
378 {
379 cout << "User login successful" << endl;
380 state = STATE_LOGIN;
381 }
382
383 break;
384 }
385 case STATE_LOGIN:
386 {
387 chatConsole.addLine(response);
388
389 if (response.compare("You have successfully logged out. You may quit the game.") == 0)
390 {
391 cout << "Logged out" << endl;
392 state = STATE_LOGOUT;
393 }
394 else
395 {
396 cout << "Added new line" << endl;
397 }
398
399 break;
400 }
401 case STATE_LOGOUT:
402 {
403 cout << "Bug: You're logged out, so you shouldn't be receiving any messages." << endl;
404
405 break;
406 }
407 default:
408 {
409 cout << "The state has an invalid value: " << state << endl;
410
411 break;
412 }
413 }
414}
Note: See TracBrowser for help on using the repository browser.