source: network-game/client/Client/main.cpp@ 07028b9

Last change on this file since 07028b9 was 171c4fe, checked in by dportnoy <dmp1488@…>, 12 years ago

Added a logout message and the ability for the client to save it's username once it logs in

  • Property mode set to 100644
File size: 8.8 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 error(const char *);
39
40const float FPS = 60;
41const int SCREEN_W = 640;
42const int SCREEN_H = 480;
43const int BOUNCER_SIZE = 32;
44enum MYKEYS {
45 KEY_UP,
46 KEY_DOWN,
47 KEY_LEFT,
48 KEY_RIGHT
49};
50
51enum STATE {
52 STATE_START,
53 STATE_LOGIN
54};
55
56int main(int argc, char **argv)
57{
58 ALLEGRO_DISPLAY *display = NULL;
59 ALLEGRO_EVENT_QUEUE *event_queue = NULL;
60 ALLEGRO_TIMER *timer = NULL;
61 ALLEGRO_BITMAP *bouncer = NULL;
62 float bouncer_x = SCREEN_W / 2.0 - BOUNCER_SIZE / 2.0;
63 float bouncer_y = SCREEN_H / 2.0 - BOUNCER_SIZE / 2.0;
64 bool key[4] = { false, false, false, false };
65 bool redraw = true;
66 bool doexit = false;
67
68 int state = STATE_START;
69
70 chat chatConsole;
71
72 if(!al_init()) {
73 fprintf(stderr, "failed to initialize allegro!\n");
74 return -1;
75 }
76
77 al_init_font_addon();
78 al_init_ttf_addon();
79
80 ALLEGRO_FONT *font = al_load_ttf_font("../pirulen.ttf", 12, 0);
81
82 if (!font) {
83 fprintf(stderr, "Could not load 'pirulen.ttf'.\n");
84 getchar();
85 return -1;
86 }
87
88 if(!al_install_keyboard()) {
89 fprintf(stderr, "failed to initialize the keyboard!\n");
90 return -1;
91 }
92
93 timer = al_create_timer(1.0 / FPS);
94 if(!timer) {
95 fprintf(stderr, "failed to create timer!\n");
96 return -1;
97 }
98
99 display = al_create_display(SCREEN_W, SCREEN_H);
100 if(!display) {
101 fprintf(stderr, "failed to create display!\n");
102 al_destroy_timer(timer);
103 return -1;
104 }
105
106 bouncer = al_create_bitmap(BOUNCER_SIZE, BOUNCER_SIZE);
107 if(!bouncer) {
108 fprintf(stderr, "failed to create bouncer bitmap!\n");
109 al_destroy_display(display);
110 al_destroy_timer(timer);
111 return -1;
112 }
113
114 event_queue = al_create_event_queue();
115 if(!event_queue) {
116 fprintf(stderr, "failed to create event_queue!\n");
117 al_destroy_bitmap(bouncer);
118 al_destroy_display(display);
119 al_destroy_timer(timer);
120 return -1;
121 }
122
123 al_set_target_bitmap(bouncer);
124
125 al_clear_to_color(al_map_rgb(255, 0, 255));
126
127 al_set_target_bitmap(al_get_backbuffer(display));
128
129 al_register_event_source(event_queue, al_get_display_event_source(display));
130
131 al_register_event_source(event_queue, al_get_timer_event_source(timer));
132
133 al_register_event_source(event_queue, al_get_keyboard_event_source());
134
135 al_clear_to_color(al_map_rgb(0,0,0));
136
137 al_flip_display();
138
139 int sock, n;
140 struct sockaddr_in server, from;
141 struct hostent *hp;
142 NETWORK_MSG msgTo, msgFrom;
143 string username;
144
145 if (argc != 3) {
146 cout << "Usage: server port" << endl;
147 exit(1);
148 }
149
150 initWinSock();
151
152 sock = socket(AF_INET, SOCK_DGRAM, 0);
153 if (sock < 0)
154 error("socket");
155
156 server.sin_family = AF_INET;
157 hp = gethostbyname(argv[1]);
158 if (hp==0)
159 error("Unknown host");
160
161 memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
162 server.sin_port = htons(atoi(argv[2]));
163
164 al_start_timer(timer);
165
166 while(!doexit)
167 {
168 ALLEGRO_EVENT ev;
169 al_wait_for_event(event_queue, &ev);
170
171 if(ev.type == ALLEGRO_EVENT_TIMER) {
172 if(key[KEY_UP] && bouncer_y >= 4.0) {
173 bouncer_y -= 4.0;
174 }
175
176 if(key[KEY_DOWN] && bouncer_y <= SCREEN_H - BOUNCER_SIZE - 4.0) {
177 bouncer_y += 4.0;
178 }
179
180 if(key[KEY_LEFT] && bouncer_x >= 4.0) {
181 bouncer_x -= 4.0;
182 }
183
184 if(key[KEY_RIGHT] && bouncer_x <= SCREEN_W - BOUNCER_SIZE - 4.0) {
185 bouncer_x += 4.0;
186 }
187
188 redraw = true;
189 }
190 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
191 doexit = true;
192 }
193 else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) {
194 bool eventConsumed = chatConsole.processEvent(ev);
195
196 if (eventConsumed) {
197 string input = chatConsole.getInput();
198 if (!input.empty()) {
199 cout << "input: " << input << endl;
200 strcpy(msgTo.buffer, input.c_str());
201
202 switch(state)
203 {
204 case STATE_START:
205 msgTo.type = MSG_TYPE_LOGIN;
206 username = input;
207 break;
208 case STATE_LOGIN:
209 if (input.compare("quit") == 0 ||
210 input.compare("exit") == 0 ||
211 input.compare("logout") == 0)
212 {
213 strcpy(msgTo.buffer, username.c_str());
214 msgTo.type = MSG_TYPE_LOGOUT;
215 }
216 else
217 msgTo.type = MSG_TYPE_CHAT;
218 break;
219 default:
220 cout << "The state has an invalid value: " << state << endl;
221 break;
222 }
223
224 n=sendMessage(&msgTo, sock, &server);
225 if (n < 0)
226 error("sendMessage");
227
228 n = receiveMessage(&msgFrom, sock, &from);
229 if (n < 0)
230 error("receiveMessage");
231
232 switch(state)
233 {
234 case STATE_START:
235 {
236 string loginResponse = string(msgFrom.buffer);
237 chatConsole.addLine(string(msgFrom.buffer));
238
239 if (loginResponse.compare("Player has already logged in.") == 0)
240 {
241 cout << "User login failed" << endl;
242 username.clear();
243 }
244 else
245 {
246 cout << "User login successful" << endl;
247 state = STATE_LOGIN;
248 }
249 break;
250 }
251 case STATE_LOGIN:
252 {
253 chatConsole.addLine(string(msgFrom.buffer));
254 cout << "Added new line" << endl;
255 break;
256 }
257 default:
258 {
259 cout << "The state has an invalid value: " << state << endl;
260 break;
261 }
262 }
263 }
264 }else {
265 switch(ev.keyboard.keycode) {
266 case ALLEGRO_KEY_UP:
267 key[KEY_UP] = true;
268 break;
269
270 case ALLEGRO_KEY_DOWN:
271 key[KEY_DOWN] = true;
272 break;
273
274 case ALLEGRO_KEY_LEFT:
275 key[KEY_LEFT] = true;
276 break;
277
278 case ALLEGRO_KEY_RIGHT:
279 key[KEY_RIGHT] = true;
280 break;
281 }
282 }
283 }
284 else if(ev.type == ALLEGRO_EVENT_KEY_UP) {
285 switch(ev.keyboard.keycode) {
286 case ALLEGRO_KEY_UP:
287 key[KEY_UP] = false;
288 break;
289
290 case ALLEGRO_KEY_DOWN:
291 key[KEY_DOWN] = false;
292 break;
293
294 case ALLEGRO_KEY_LEFT:
295 key[KEY_LEFT] = false;
296 break;
297
298 case ALLEGRO_KEY_RIGHT:
299 key[KEY_RIGHT] = false;
300 break;
301
302 case ALLEGRO_KEY_ESCAPE:
303 doexit = true;
304 break;
305 }
306 }
307
308 if(redraw && al_is_event_queue_empty(event_queue)) {
309 redraw = false;
310
311 al_clear_to_color(al_map_rgb(0,0,0));
312
313 al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0);
314
315 chatConsole.draw(font, al_map_rgb(255,255,255));
316
317 al_flip_display();
318 }
319 }
320
321 #if defined WINDOWS
322 closesocket(sock);
323 #elif defined LINUX
324 close(sock);
325 #endif
326
327 shutdownWinSock();
328
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
337void initWinSock()
338{
339#if defined WINDOWS
340 WORD wVersionRequested;
341 WSADATA wsaData;
342 int wsaerr;
343
344 wVersionRequested = MAKEWORD(2, 2);
345 wsaerr = WSAStartup(wVersionRequested, &wsaData);
346
347 if (wsaerr != 0) {
348 cout << "The Winsock dll not found." << endl;
349 exit(1);
350 }else
351 cout << "The Winsock dll was found." << endl;
352#endif
353}
354
355void shutdownWinSock()
356{
357#if defined WINDOWS
358 WSACleanup();
359#endif
360}
361
362// need to make a function like this that works on windows
363void error(const char *msg)
364{
365 perror(msg);
366 shutdownWinSock();
367 exit(1);
368}
Note: See TracBrowser for help on using the repository browser.