source: network-game/client/Client/main.cpp@ 5066e27

Last change on this file since 5066e27 was 60776f2, checked in by dportnoy <dmp1488@…>, 12 years ago

Changed the client to use serialize/deserialize and added serialization code for the player location

  • Property mode set to 100644
File size: 11.8 KB
RevLine 
[4c202e0]1#include "../../common/Compiler.h"
2
[e08572c]3#if defined WINDOWS
[0dde5da]4 #include <winsock2.h>
5 #include <WS2tcpip.h>
[e08572c]6#elif defined LINUX
[0dde5da]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>
[a845faf]13#endif
[1912323]14
[d352805]15#include <sys/types.h>
[1912323]16#include <stdio.h>
17#include <stdlib.h>
[a845faf]18#include <string>
[1912323]19#include <iostream>
20
[d352805]21#include <allegro5/allegro.h>
22#include <allegro5/allegro_font.h>
23#include <allegro5/allegro_ttf.h>
[7d7df47]24
[b53c6b3]25#include "../../common/Message.h"
[e607c0f]26#include "../../common/Common.h"
[4c202e0]27#include "../../common/Player.h"
[7d7df47]28
[87b3ee2]29#include "Window.h"
30#include "Textbox.h"
31#include "Button.h"
[6475138]32#include "chat.h"
33
[a845faf]34#ifdef WINDOWS
[6475138]35 #pragma comment(lib, "ws2_32.lib")
[a845faf]36#endif
[1912323]37
38using namespace std;
39
[0dde5da]40void initWinSock();
41void shutdownWinSock();
[87b3ee2]42void processMessage(NETWORK_MSG &msg, int &state, chat &chatConsole);
43
44// callbacks
45void registerAccount();
46void login();
47void logout();
48void quit();
49void sendChatMessage();
[4da5aa3]50
[1912323]51void error(const char *);
[7d7df47]52
[d352805]53const float FPS = 60;
54const int SCREEN_W = 640;
55const int SCREEN_H = 480;
56const int BOUNCER_SIZE = 32;
57enum MYKEYS {
[0cc431d]58 KEY_UP,
59 KEY_DOWN,
60 KEY_LEFT,
61 KEY_RIGHT
62};
63
64enum STATE {
65 STATE_START,
[87b3ee2]66 STATE_LOGIN // this means you're already logged in
[d352805]67};
[87b3ee2]68
69int state;
70
71bool doexit;
72
73Window* wndLogin;
74Window* wndMain;
75Window* wndCurrent;
76
77Textbox* txtUsername;
78Textbox* txtPassword;
79Textbox* txtChat;
80
81int sock;
82struct sockaddr_in server, from;
83struct hostent *hp;
84NETWORK_MSG msgTo, msgFrom;
85string username;
86chat chatConsole;
[d352805]87
88int main(int argc, char **argv)
89{
90 ALLEGRO_DISPLAY *display = NULL;
91 ALLEGRO_EVENT_QUEUE *event_queue = NULL;
92 ALLEGRO_TIMER *timer = NULL;
93 ALLEGRO_BITMAP *bouncer = NULL;
94 bool key[4] = { false, false, false, false };
95 bool redraw = true;
[87b3ee2]96 doexit = false;
[9a3e6b1]97
[87b3ee2]98 float bouncer_x = SCREEN_W / 2.0 - BOUNCER_SIZE / 2.0;
99 float bouncer_y = SCREEN_H / 2.0 - BOUNCER_SIZE / 2.0;
[0cc431d]100
[87b3ee2]101 state = STATE_START;
[9a3e6b1]102
[d352805]103 if(!al_init()) {
104 fprintf(stderr, "failed to initialize allegro!\n");
105 return -1;
106 }
107
[87b3ee2]108 al_init_primitives_addon();
[d352805]109 al_init_font_addon();
110 al_init_ttf_addon();
111
112 ALLEGRO_FONT *font = al_load_ttf_font("../pirulen.ttf", 12, 0);
113
114 if (!font) {
115 fprintf(stderr, "Could not load 'pirulen.ttf'.\n");
116 getchar();
117 return -1;
118 }
119
120 if(!al_install_keyboard()) {
121 fprintf(stderr, "failed to initialize the keyboard!\n");
122 return -1;
123 }
[87b3ee2]124
125 if(!al_install_mouse()) {
126 fprintf(stderr, "failed to initialize the mouse!\n");
127 return -1;
128 }
[d352805]129
130 timer = al_create_timer(1.0 / FPS);
131 if(!timer) {
132 fprintf(stderr, "failed to create timer!\n");
133 return -1;
134 }
135
136 display = al_create_display(SCREEN_W, SCREEN_H);
137 if(!display) {
138 fprintf(stderr, "failed to create display!\n");
139 al_destroy_timer(timer);
140 return -1;
141 }
[87b3ee2]142
143 wndLogin = new Window(0, 0, SCREEN_W, SCREEN_H);
144 wndLogin->addComponent(new Textbox(104, 40, 100, 20, font));
145 wndLogin->addComponent(new Textbox(104, 70, 100, 20, font));
146 wndLogin->addComponent(new Button(22, 100, 90, 20, font, "Register", registerAccount));
147 wndLogin->addComponent(new Button(122, 100, 60, 20, font, "Login", login));
148 wndLogin->addComponent(new Button(540, 10, 80, 20, font, "Quit", quit));
149
150 txtUsername = (Textbox*)wndLogin->getComponent(0);
151 txtPassword = (Textbox*)wndLogin->getComponent(1);
152
153 wndMain = new Window(0, 0, SCREEN_W, SCREEN_H);
154 wndMain->addComponent(new Textbox(95, 40, 525, 20, font));
155 wndMain->addComponent(new Button(95, 70, 160, 20, font, "Send Message", sendChatMessage));
156 wndMain->addComponent(new Button(540, 10, 80, 20, font, "Logout", logout));
157
158 txtChat = (Textbox*)wndMain->getComponent(0);
159
160 wndCurrent = wndLogin;
161
[d352805]162 bouncer = al_create_bitmap(BOUNCER_SIZE, BOUNCER_SIZE);
163 if(!bouncer) {
164 fprintf(stderr, "failed to create bouncer bitmap!\n");
165 al_destroy_display(display);
166 al_destroy_timer(timer);
167 return -1;
168 }
169
170 event_queue = al_create_event_queue();
171 if(!event_queue) {
172 fprintf(stderr, "failed to create event_queue!\n");
173 al_destroy_bitmap(bouncer);
174 al_destroy_display(display);
175 al_destroy_timer(timer);
176 return -1;
177 }
178
179 al_set_target_bitmap(bouncer);
180
181 al_clear_to_color(al_map_rgb(255, 0, 255));
182
183 al_set_target_bitmap(al_get_backbuffer(display));
184
185 al_register_event_source(event_queue, al_get_display_event_source(display));
186 al_register_event_source(event_queue, al_get_timer_event_source(timer));
187 al_register_event_source(event_queue, al_get_keyboard_event_source());
[87b3ee2]188 al_register_event_source(event_queue, al_get_mouse_event_source());
[d352805]189
190 al_clear_to_color(al_map_rgb(0,0,0));
191
192 al_flip_display();
[9a3e6b1]193
194 if (argc != 3) {
195 cout << "Usage: server port" << endl;
196 exit(1);
197 }
198
199 initWinSock();
200
201 sock = socket(AF_INET, SOCK_DGRAM, 0);
202 if (sock < 0)
203 error("socket");
204
[e607c0f]205 set_nonblock(sock);
206
[9a3e6b1]207 server.sin_family = AF_INET;
208 hp = gethostbyname(argv[1]);
209 if (hp==0)
210 error("Unknown host");
211
212 memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
213 server.sin_port = htons(atoi(argv[2]));
214
[d352805]215 al_start_timer(timer);
[e607c0f]216
[d352805]217 while(!doexit)
218 {
219 ALLEGRO_EVENT ev;
220 al_wait_for_event(event_queue, &ev);
[87b3ee2]221
222 if(wndCurrent->handleEvent(ev)) {
223 // do nothing
224 }
225 else if(ev.type == ALLEGRO_EVENT_TIMER) {
[d352805]226 if(key[KEY_UP] && bouncer_y >= 4.0) {
227 bouncer_y -= 4.0;
228 }
229
230 if(key[KEY_DOWN] && bouncer_y <= SCREEN_H - BOUNCER_SIZE - 4.0) {
231 bouncer_y += 4.0;
232 }
233
234 if(key[KEY_LEFT] && bouncer_x >= 4.0) {
235 bouncer_x -= 4.0;
236 }
237
238 if(key[KEY_RIGHT] && bouncer_x <= SCREEN_W - BOUNCER_SIZE - 4.0) {
239 bouncer_x += 4.0;
240 }
241
242 redraw = true;
243 }
244 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
[9a3e6b1]245 doexit = true;
[d352805]246 }
247 else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) {
[87b3ee2]248 switch(ev.keyboard.keycode) {
249 case ALLEGRO_KEY_UP:
250 key[KEY_UP] = true;
251 break;
[d352805]252
[87b3ee2]253 case ALLEGRO_KEY_DOWN:
254 key[KEY_DOWN] = true;
255 break;
[d352805]256
[87b3ee2]257 case ALLEGRO_KEY_LEFT:
258 key[KEY_LEFT] = true;
259 break;
[d352805]260
[87b3ee2]261 case ALLEGRO_KEY_RIGHT:
262 key[KEY_RIGHT] = true;
263 break;
[d352805]264 }
265 }
266 else if(ev.type == ALLEGRO_EVENT_KEY_UP) {
267 switch(ev.keyboard.keycode) {
268 case ALLEGRO_KEY_UP:
269 key[KEY_UP] = false;
270 break;
271
272 case ALLEGRO_KEY_DOWN:
273 key[KEY_DOWN] = false;
274 break;
275
276 case ALLEGRO_KEY_LEFT:
277 key[KEY_LEFT] = false;
278 break;
279
280 case ALLEGRO_KEY_RIGHT:
281 key[KEY_RIGHT] = false;
282 break;
283
284 case ALLEGRO_KEY_ESCAPE:
285 doexit = true;
286 break;
287 }
288 }
[e607c0f]289
290 if (receiveMessage(&msgFrom, sock, &from) >= 0)
291 {
292 processMessage(msgFrom, state, chatConsole);
293 cout << "state: " << state << endl;
294 }
[d352805]295
[e607c0f]296 if (redraw && al_is_event_queue_empty(event_queue))
297 {
[d352805]298 redraw = false;
299
[87b3ee2]300 wndCurrent->draw(display);
[d352805]301
302 al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0);
[9a3e6b1]303
[6475138]304 chatConsole.draw(font, al_map_rgb(255,255,255));
[9a3e6b1]305
[87b3ee2]306 if(wndCurrent == wndLogin) {
307 al_draw_text(font, al_map_rgb(0, 255, 0), 4, 43, ALLEGRO_ALIGN_LEFT, "Username:");
308 al_draw_text(font, al_map_rgb(0, 255, 0), 1, 73, ALLEGRO_ALIGN_LEFT, "Password:");
309 }
310 else if(wndCurrent == wndMain) {
311 al_draw_text(font, al_map_rgb(0, 255, 0), 4, 43, ALLEGRO_ALIGN_LEFT, "Message:");
312 }
313
[d352805]314 al_flip_display();
315 }
316 }
[9a3e6b1]317
318 #if defined WINDOWS
319 closesocket(sock);
320 #elif defined LINUX
321 close(sock);
322 #endif
323
324 shutdownWinSock();
[d352805]325
[87b3ee2]326 delete wndLogin;
327 delete wndMain;
328
[d352805]329 al_destroy_event_queue(event_queue);
330 al_destroy_bitmap(bouncer);
331 al_destroy_display(display);
332 al_destroy_timer(timer);
333
334 return 0;
335}
336
[4da5aa3]337// need to make a function like this that works on windows
338void error(const char *msg)
339{
340 perror(msg);
341 shutdownWinSock();
342 exit(1);
343}
344
[0dde5da]345void initWinSock()
346{
347#if defined WINDOWS
348 WORD wVersionRequested;
349 WSADATA wsaData;
350 int wsaerr;
351
352 wVersionRequested = MAKEWORD(2, 2);
353 wsaerr = WSAStartup(wVersionRequested, &wsaData);
354
355 if (wsaerr != 0) {
356 cout << "The Winsock dll not found." << endl;
357 exit(1);
358 }else
359 cout << "The Winsock dll was found." << endl;
360#endif
361}
362
363void shutdownWinSock()
364{
365#if defined WINDOWS
366 WSACleanup();
367#endif
[1912323]368}
369
[87b3ee2]370void processMessage(NETWORK_MSG &msg, int &state, chat &chatConsole)
[1912323]371{
[4da5aa3]372 string response = string(msg.buffer);
373
[60776f2]374 cout << "Got message: " << msg.type << endl;
375
[4da5aa3]376 switch(state)
377 {
378 case STATE_START:
379 {
[e607c0f]380 cout << "In STATE_START" << endl;
381
[4da5aa3]382 chatConsole.addLine(response);
383
[87b3ee2]384 switch(msg.type)
[4da5aa3]385 {
[87b3ee2]386 case MSG_TYPE_REGISTER:
387 {
388 break;
389 }
390 case MSG_TYPE_LOGIN:
391 {
392 if (response.compare("Player has already logged in.") == 0)
393 {
394 username.clear();
395 cout << "User login failed" << endl;
396 }
397 else if (response.compare("Incorrect username or password") == 0)
398 {
399 username.clear();
400 cout << "User login failed" << endl;
401 }
402 else
403 {
404 state = STATE_LOGIN;
405 wndCurrent = wndMain;
406 cout << "User login successful" << endl;
407 }
408 break;
409 }
[4da5aa3]410 }
411
412 break;
413 }
414 case STATE_LOGIN:
415 {
416 chatConsole.addLine(response);
417
[87b3ee2]418 switch(msg.type)
[4da5aa3]419 {
[87b3ee2]420 case MSG_TYPE_REGISTER:
421 {
422 break;
423 }
424 case MSG_TYPE_LOGIN:
425 {
426 if (response.compare("You have successfully logged out.") == 0)
427 {
428 cout << "Logged out" << endl;
429 state = STATE_START;
430 wndCurrent = wndLogin;
431 }
432 else
433 {
434 cout << "Added new line" << endl;
435 }
436
[4c202e0]437 break;
438 }
439 case MSG_TYPE_PLAYER:
440 {
[60776f2]441 Player p("", "");
442 p.deserialize(msg.buffer);
[4c202e0]443
[60776f2]444 cout << "p.name: " << p.name << endl;
445 cout << "p.pos.x: " << p.pos.x << endl;
446 cout << "p.pos.y: " << p.pos.y << endl;
[4c202e0]447
[87b3ee2]448 break;
449 }
[4da5aa3]450 }
451
452 break;
453 }
454 default:
455 {
456 cout << "The state has an invalid value: " << state << endl;
457
458 break;
459 }
460 }
[0dde5da]461}
[87b3ee2]462
463void registerAccount()
464{
465 string username = txtUsername->getStr();
466 string password = txtPassword->getStr();
467
468 txtUsername->clear();
469 txtPassword->clear();
470
471 msgTo.type = MSG_TYPE_REGISTER;
472
473 strcpy(msgTo.buffer, username.c_str());
474 strcpy(msgTo.buffer+username.size()+1, password.c_str());
475
476 sendMessage(&msgTo, sock, &server);
477}
478
479void login()
480{
481 string strUsername = txtUsername->getStr();
482 string strPassword = txtPassword->getStr();
483 username = strUsername;
484
485 txtUsername->clear();
486 txtPassword->clear();
487
488 msgTo.type = MSG_TYPE_LOGIN;
489
490 strcpy(msgTo.buffer, strUsername.c_str());
491 strcpy(msgTo.buffer+username.size()+1, strPassword.c_str());
492
493 sendMessage(&msgTo, sock, &server);
494}
495
496void logout()
497{
498 txtChat->clear();
499
500 msgTo.type = MSG_TYPE_LOGOUT;
501
502 strcpy(msgTo.buffer, username.c_str());
503
504 sendMessage(&msgTo, sock, &server);
505}
506
507void quit()
508{
509 doexit = true;
510}
511
512void sendChatMessage()
513{
514 string msg = txtChat->getStr();
515
516 txtChat->clear();
517
518 msgTo.type = MSG_TYPE_CHAT;
519
520 strcpy(msgTo.buffer, msg.c_str());
521
522 sendMessage(&msgTo, sock, &server);
523}
Note: See TracBrowser for help on using the repository browser.