source: network-game/server/server.cpp@ 8554263

Last change on this file since 8554263 was 8554263, checked in by dportnoy <dmp1488@…>, 11 years ago

Restructuring and code cleanup

  • Property mode set to 100644
File size: 40.4 KB
RevLine 
[2488852]1#include <cstdlib>
[371ce29]2#include <cstdio>
[e3535b3]3#include <unistd.h>
[2488852]4#include <string>
[e3535b3]5#include <iostream>
[3b1efcc]6#include <sstream>
[d05086b]7#include <fstream>
[edfd1d0]8#include <cstring>
[60017fc]9#include <cmath>
[371ce29]10
[01d0d00]11#include <vector>
12#include <map>
13
[d05086b]14#include <csignal>
15
[d211210]16#include <sys/time.h>
17
[73f75c1]18#include <sys/socket.h>
[371ce29]19#include <netdb.h>
[73f75c1]20#include <netinet/in.h>
21#include <arpa/inet.h>
22
[b128109]23#include <crypt.h>
24
[edfd1d0]25/*
[e3535b3]26#include <openssl/bio.h>
27#include <openssl/ssl.h>
28#include <openssl/err.h>
[edfd1d0]29*/
[e3535b3]30
[b53c6b3]31#include "../common/Compiler.h"
[3b1efcc]32#include "../common/Common.h"
[9b5d30b]33#include "../common/MessageProcessor.h"
[60017fc]34#include "../common/WorldMap.h"
[edfd1d0]35#include "../common/Player.h"
[8dad966]36#include "../common/Projectile.h"
[99afbb8]37#include "../common/Game.h"
[c9f6a1c]38#include "../common/GameSummary.h"
[b53c6b3]39
[36082e8]40#include "DataAccess.h"
[d2b411a]41
[e3535b3]42using namespace std;
43
[d05086b]44bool done;
45
[d211210]46// from used to be const. Removed that so I could take a reference
47// and use it to send messages
[8554263]48void processMessage(const NETWORK_MSG &clientMsg, struct sockaddr_in &from, MessageProcessor &msgProcessor, map<unsigned int, Player*>& mapPlayers, map<string, Game*>& mapGames, WorldMap* gameMap, unsigned int& unusedPlayerId, NETWORK_MSG &serverMsg, int &scoreBlue, int &scoreRed);
[01d0d00]49
[8554263]50void broadcastMessage(MessageProcessor &msgProcessor, NETWORK_MSG &serverMsg, map<unsigned int, Player*>& players);
[95ffe57]51void updateUnusedPlayerId(unsigned int& id, map<unsigned int, Player*>& mapPlayers);
52Player *findPlayerByName(map<unsigned int, Player*> &m, string name);
53Player *findPlayerByAddr(map<unsigned int, Player*> &m, const sockaddr_in &addr);
[c76134b]54void damagePlayer(Player *p, int damage);
[8e540f4]55
[8554263]56void addObjectToMap(WorldMap::ObjectType objectType, int x, int y, WorldMap* gameMap, map<unsigned int, Player*>& mapPlayers, MessageProcessor &msgProcessor);
[e3535b3]57
[d05086b]58void quit(int sig) {
59 done = true;
60}
61
[e3535b3]62int main(int argc, char *argv[])
63{
[8554263]64 int sock, length;
[e3535b3]65 struct sockaddr_in server;
[3b1efcc]66 struct sockaddr_in from; // info of client sending the message
[e084950]67 NETWORK_MSG clientMsg, serverMsg;
[9b5d30b]68 MessageProcessor msgProcessor;
[95ffe57]69 map<unsigned int, Player*> mapPlayers;
[8dad966]70 map<unsigned int, Projectile> mapProjectiles;
[f41a7f9]71 map<string, Game*> mapGames;
[8dad966]72 unsigned int unusedPlayerId = 1, unusedProjectileId = 1;
[b8601ee]73 int scoreBlue, scoreRed;
[d05086b]74 ofstream outputLog;
75
76 done = false;
[b8601ee]77
78 scoreBlue = 0;
79 scoreRed = 0;
[e084950]80
[d05086b]81 signal(SIGINT, quit);
82
[edfd1d0]83 //SSL_load_error_strings();
84 //ERR_load_BIO_strings();
85 //OpenSSL_add_all_algorithms();
[e3535b3]86
[95ffe57]87 if (argc != 2)
88 {
89 cerr << "ERROR, expected server [domain] [port]" << endl;
[73f75c1]90 exit(1);
[e3535b3]91 }
[60017fc]92
[d05086b]93 outputLog.open("server.log", ios::app);
94 outputLog << "Started server on " << getCurrentDateTimeString() << endl;
95
[7b43385]96 WorldMap* gameMap = WorldMap::loadMapFromFile("../data/map.txt");
[6e66ffd]97
98 // add some items to the map. They will be sent out
99 // to players when they login
[95ffe57]100 for (int y=0; y<gameMap->height; y++)
101 {
102 for (int x=0; x<gameMap->width; x++)
103 {
104 switch (gameMap->getStructure(x, y))
105 {
[5f868c0]106 case WorldMap::STRUCTURE_BLUE_FLAG:
107 gameMap->addObject(WorldMap::OBJECT_BLUE_FLAG, x*25+12, y*25+12);
108 break;
109 case WorldMap::STRUCTURE_RED_FLAG:
110 gameMap->addObject(WorldMap::OBJECT_RED_FLAG, x*25+12, y*25+12);
111 break;
112 }
113 }
114 }
[6e66ffd]115
[371ce29]116 sock = socket(AF_INET, SOCK_DGRAM, 0);
[5b1e31e]117 if (sock < 0)
118 error("Opening socket");
[e3535b3]119 length = sizeof(server);
120 bzero(&server,length);
121 server.sin_family=AF_INET;
122 server.sin_port=htons(atoi(argv[1]));
[2488852]123 server.sin_addr.s_addr=INADDR_ANY;
124 if ( bind(sock, (struct sockaddr *)&server, length) < 0 )
[e084950]125 error("binding");
[73f75c1]126
[371ce29]127 set_nonblock(sock);
128
[8554263]129 msgProcessor = MessageProcessor(sock, &outputLog);
130
[d211210]131 timespec ts;
[430c80e]132 int timeLastUpdated = 0, curTime = 0, timeLastBroadcast = 0;
[95ffe57]133 while (!done)
134 {
[371ce29]135 usleep(5000);
136
[d211210]137 clock_gettime(CLOCK_REALTIME, &ts);
[430c80e]138 // make the number smaller so millis can fit in an int
[d69eb32]139 ts.tv_sec -= 1368000000;
[430c80e]140 curTime = ts.tv_sec*1000 + ts.tv_nsec/1000000;
[d211210]141
[95ffe57]142 if (timeLastUpdated == 0 || (curTime-timeLastUpdated) >= 50)
143 {
[d211210]144 timeLastUpdated = curTime;
145
[8554263]146 msgProcessor.cleanAckedMessages();
147 msgProcessor.resendUnackedMessages();
[9b5d30b]148
[95ffe57]149 map<unsigned int, Player*>::iterator it;
[11d21ee]150
[ce2bb87]151 cout << "Updating player targets and respawning dead players" << endl;
152
[11d21ee]153 // set targets for all chasing players (or make them attack if they're close enough)
[8554263]154 // this should be moved into the games loop
[95ffe57]155 for (it = mapPlayers.begin(); it != mapPlayers.end(); it++)
156 {
[ffadc8e]157 Player* p = it->second;
158
[c76134b]159 // check if it's time to revive dead players
[ffadc8e]160 if (p->isDead)
[95ffe57]161 {
[e1af80c]162 cout << "Player is dead" << endl;
[35f6097]163
[ffadc8e]164 if (getCurrentMillis() - p->timeDied >= 10000)
[95ffe57]165 {
[ffadc8e]166 p->isDead = false;
[c76134b]167
168 POSITION spawnPos;
169
[ffadc8e]170 switch (p->team)
[95ffe57]171 {
[c76134b]172 case 0:// blue team
[35f6097]173 spawnPos = p->currentGame->getMap()->getStructureLocation(WorldMap::STRUCTURE_BLUE_FLAG);
[c76134b]174 break;
175 case 1:// red team
[35f6097]176 spawnPos = p->currentGame->getMap()->getStructureLocation(WorldMap::STRUCTURE_RED_FLAG);
[c76134b]177 break;
178 default:
179 // should never go here
180 cout << "Error: Invalid team" << endl;
181 break;
182 }
183
184 // spawn the player to the right of their flag location
185 spawnPos.x = (spawnPos.x+1) * 25 + 12;
186 spawnPos.y = spawnPos.y * 25 + 12;
187
[ffadc8e]188 p->pos = spawnPos.toFloat();
189 p->target = spawnPos;
190 p->health = p->maxHealth;
[c76134b]191
192 serverMsg.type = MSG_TYPE_PLAYER;
[ffadc8e]193 p->serialize(serverMsg.buffer);
[c76134b]194
[8554263]195 broadcastMessage(msgProcessor, serverMsg, p->currentGame->getPlayers());
[c76134b]196 }
197
198 continue;
199 }
200
[ffadc8e]201 if (p->currentGame != NULL) {
202 map<unsigned int, Player*> playersInGame = p->currentGame->getPlayers();
203 if (p->updateTarget(playersInGame))
[5b1e31e]204 {
[ffadc8e]205 serverMsg.type = MSG_TYPE_PLAYER;
206 p->serialize(serverMsg.buffer);
207
[8554263]208 broadcastMessage(msgProcessor, serverMsg, playersInGame);
[11d21ee]209 }
210 }
211 }
212
[ce2bb87]213 cout << "Processing players in a game" << endl;
214
[402cf86]215 // process players currently in a game
[23559e7]216 FLOAT_POSITION oldPos;
[e62b56c]217 map<string, Game*>::iterator itGames;
218 Game* game = NULL;
219 WorldMap* gameMap = NULL;
[e5b96e2]220 bool gameFinished;
[ce2bb87]221
[e5b96e2]222 for (itGames = mapGames.begin(); itGames != mapGames.end();) {
[e62b56c]223 game = itGames->second;
224 gameMap = game->getMap();
225 map<unsigned int, Player*>& playersInGame = game->getPlayers();
[e5b96e2]226 gameFinished = false;
[402cf86]227
[e62b56c]228 for (it = game->getPlayers().begin(); it != game->getPlayers().end(); it++)
229 {
230 Player* p = it->second;
[483a2cb]231
[e62b56c]232 cout << "moving player" << endl;
233 bool broadcastMove = false;
[23559e7]234
[e62b56c]235 // xompute playersInGame here
[23559e7]236
[e62b56c]237 // move player and perform associated tasks
238 oldPos = p->pos;
239 if (p->move(gameMap)) {
[b73bc28]240
[e62b56c]241 cout << "player moved" << endl;
242 if (game->processPlayerMovement(p, oldPos))
243 broadcastMove = true;
244 cout << "player move processed" << endl;
[b73bc28]245
[e62b56c]246 WorldMap::ObjectType flagType;
247 POSITION pos;
248 bool flagTurnedIn = false;
249 bool flagReturned = false;
250 bool ownFlagAtBase = false;
251
252 // need to figure out how to move this to a different file
253 // while still sending back flag type and position
254 switch(gameMap->getStructure(p->pos.x/25, p->pos.y/25))
[e4c60ba]255 {
[e62b56c]256 case WorldMap::STRUCTURE_BLUE_FLAG:
[7553db9]257 {
[e62b56c]258 if (p->team == 0 && p->hasRedFlag)
[95ffe57]259 {
[e62b56c]260 // check that your flag is at your base
261 pos = gameMap->getStructureLocation(WorldMap::STRUCTURE_BLUE_FLAG);
262
263 vector<WorldMap::Object>* vctObjects = gameMap->getObjects();
264 vector<WorldMap::Object>::iterator itObjects;
265
266 for (itObjects = vctObjects->begin(); itObjects != vctObjects->end(); itObjects++)
[95ffe57]267 {
[e62b56c]268 if (itObjects->type == WorldMap::OBJECT_BLUE_FLAG)
[95ffe57]269 {
[e62b56c]270 if (itObjects->pos.x == pos.x*25+12 && itObjects->pos.y == pos.y*25+12)
271 {
272 ownFlagAtBase = true;
273 break;
274 }
[446dc65]275 }
276 }
277
[e62b56c]278 if (ownFlagAtBase)
279 {
280 p->hasRedFlag = false;
281 flagType = WorldMap::OBJECT_RED_FLAG;
282 pos = gameMap->getStructureLocation(WorldMap::STRUCTURE_RED_FLAG);
283 flagTurnedIn = true;
284 scoreBlue++;
285 }
[446dc65]286 }
[7553db9]287
[e62b56c]288 break;
289 }
290 case WorldMap::STRUCTURE_RED_FLAG:
[7553db9]291 {
[e62b56c]292 if (p->team == 1 && p->hasBlueFlag)
293 {
294 // check that your flag is at your base
295 pos = gameMap->getStructureLocation(WorldMap::STRUCTURE_RED_FLAG);
[446dc65]296
[e62b56c]297 vector<WorldMap::Object>* vctObjects = gameMap->getObjects();
298 vector<WorldMap::Object>::iterator itObjects;
[446dc65]299
[e62b56c]300 for (itObjects = vctObjects->begin(); itObjects != vctObjects->end(); itObjects++)
[95ffe57]301 {
[e62b56c]302 if (itObjects->type == WorldMap::OBJECT_RED_FLAG)
[95ffe57]303 {
[e62b56c]304 if (itObjects->pos.x == pos.x*25+12 && itObjects->pos.y == pos.y*25+12)
305 {
306 ownFlagAtBase = true;
307 break;
308 }
[446dc65]309 }
310 }
311
[e62b56c]312 if (ownFlagAtBase)
313 {
314 p->hasBlueFlag = false;
315 flagType = WorldMap::OBJECT_BLUE_FLAG;
316 pos = gameMap->getStructureLocation(WorldMap::STRUCTURE_BLUE_FLAG);
317 flagTurnedIn = true;
318 scoreRed++;
319 }
[446dc65]320 }
[e4c60ba]321
[e62b56c]322 break;
323 }
[7553db9]324 }
[e4c60ba]325
[e62b56c]326 if (flagTurnedIn)
327 {
328 // send an OBJECT message to add the flag back to its spawn point
329 pos.x = pos.x*25+12;
330 pos.y = pos.y*25+12;
331 gameMap->addObject(flagType, pos.x, pos.y);
[e4c60ba]332
[e62b56c]333 serverMsg.type = MSG_TYPE_OBJECT;
334 gameMap->getObjects()->back().serialize(serverMsg.buffer);
[8554263]335 broadcastMessage(msgProcessor, serverMsg, playersInGame);
[7553db9]336
[e62b56c]337 serverMsg.type = MSG_TYPE_SCORE;
338 memcpy(serverMsg.buffer, &scoreBlue, 4);
339 memcpy(serverMsg.buffer+4, &scoreRed, 4);
[8554263]340 broadcastMessage(msgProcessor, serverMsg, playersInGame);
[b8601ee]341
[e5b96e2]342 // check to see if the game should end
343 // move to its own method
[e62b56c]344 if (scoreBlue == 3 || scoreRed == 3) {
[e5b96e2]345 gameFinished = true;
[e4c60ba]346
[e62b56c]347 unsigned int winningTeam;
348 if (scoreBlue == 3)
349 winningTeam = 0;
350 else if (scoreRed == 3)
351 winningTeam = 1;
[446dc65]352
[e62b56c]353 serverMsg.type = MSG_TYPE_FINISH_GAME;
[c9f6a1c]354
355 // I should create an instance of the GameSummary object here and just serialize it into this message
[778d0c9]356 memcpy(serverMsg.buffer, &winningTeam, 4);
[e62b56c]357 memcpy(serverMsg.buffer+4, &scoreBlue, 4);
358 memcpy(serverMsg.buffer+8, &scoreRed, 4);
[778d0c9]359 strcpy(serverMsg.buffer+12, game->getName().c_str());
[8554263]360 broadcastMessage(msgProcessor, serverMsg, playersInGame);
[e62b56c]361 }
362
363 // this means a PLAYER message will be sent
364 broadcastMove = true;
365 }
366
367 // go through all objects and check if the player is close to one and if its their flag
368 vector<WorldMap::Object>* vctObjects = gameMap->getObjects();
369 vector<WorldMap::Object>::iterator itObjects;
370 POSITION structPos;
371
372 for (itObjects = vctObjects->begin(); itObjects != vctObjects->end(); itObjects++)
[95ffe57]373 {
[e62b56c]374 POSITION pos = itObjects->pos;
375
376 if (posDistance(p->pos, pos.toFloat()) < 10)
[95ffe57]377 {
[e62b56c]378 if (p->team == 0 &&
379 itObjects->type == WorldMap::OBJECT_BLUE_FLAG)
380 {
381 structPos = gameMap->getStructureLocation(WorldMap::STRUCTURE_BLUE_FLAG);
382 flagReturned = true;
383 break;
384 }
385 else if (p->team == 1 &&
386 itObjects->type == WorldMap::OBJECT_RED_FLAG)
387 {
388 structPos = gameMap->getStructureLocation(WorldMap::STRUCTURE_RED_FLAG);
389 flagReturned = true;
390 break;
391 }
[95ffe57]392 }
[e62b56c]393 }
394
395 if (flagReturned)
396 {
397 itObjects->pos.x = structPos.x*25+12;
398 itObjects->pos.y = structPos.y*25+12;
399
400 serverMsg.type = MSG_TYPE_OBJECT;
401 itObjects->serialize(serverMsg.buffer);
[8554263]402 broadcastMessage(msgProcessor, serverMsg, playersInGame);
[446dc65]403 }
404
[e62b56c]405 if (broadcastMove)
406 {
407 serverMsg.type = MSG_TYPE_PLAYER;
408 p->serialize(serverMsg.buffer);
[8554263]409 broadcastMessage(msgProcessor, serverMsg, playersInGame);
[446dc65]410 }
411 }
412
[e62b56c]413 cout << "processing player attack" << endl;
414
415 // check if the player's attack animation is complete
416 if (p->isAttacking && p->timeAttackStarted+p->attackCooldown <= getCurrentMillis())
[95ffe57]417 {
[e62b56c]418 p->isAttacking = false;
419 cout << "Attack animation is complete" << endl;
420
421 //send everyone an ATTACK message
422 cout << "about to broadcast attack" << endl;
[23559e7]423
[e62b56c]424 serverMsg.type = MSG_TYPE_ATTACK;
425 memcpy(serverMsg.buffer, &p->id, 4);
426 memcpy(serverMsg.buffer+4, &p->targetPlayer, 4);
[8554263]427 broadcastMessage(msgProcessor, serverMsg, playersInGame);
[8dad966]428
[e62b56c]429 if (p->attackType == Player::ATTACK_MELEE)
430 {
431 cout << "Melee attack" << endl;
[ff2133a]432
[e62b56c]433 Player* target = playersInGame[p->targetPlayer];
434 damagePlayer(target, p->damage);
[8dad966]435
[e62b56c]436 if (target->isDead)
437 {
438 WorldMap::ObjectType flagType = WorldMap::OBJECT_NONE;
439 if (target->hasBlueFlag)
440 flagType = WorldMap::OBJECT_BLUE_FLAG;
441 else if (target->hasRedFlag)
442 flagType = WorldMap::OBJECT_RED_FLAG;
[411c1ae]443
[e62b56c]444 if (flagType != WorldMap::OBJECT_NONE) {
[8554263]445 addObjectToMap(flagType, target->pos.x, target->pos.y, gameMap, playersInGame, msgProcessor);
[e62b56c]446 }
[411c1ae]447 }
448
[e62b56c]449 serverMsg.type = MSG_TYPE_PLAYER;
450 target->serialize(serverMsg.buffer);
451 }
452 else if (p->attackType == Player::ATTACK_RANGED)
453 {
454 cout << "Ranged attack" << endl;
[ff2133a]455
[e62b56c]456 Projectile proj(p->pos.x, p->pos.y, p->targetPlayer, p->damage);
457 game->assignProjectileId(&proj);
458 game->addProjectile(proj);
[8dad966]459
[e62b56c]460 int x = p->pos.x;
461 int y = p->pos.y;
[8795a38]462
[e62b56c]463 serverMsg.type = MSG_TYPE_PROJECTILE;
464 memcpy(serverMsg.buffer, &proj.id, 4);
465 memcpy(serverMsg.buffer+4, &x, 4);
466 memcpy(serverMsg.buffer+8, &y, 4);
467 memcpy(serverMsg.buffer+12, &p->targetPlayer, 4);
468 }
469 else
470 cout << "Invalid attack type: " << p->attackType << endl;
[8dad966]471
[8554263]472 broadcastMessage(msgProcessor, serverMsg, playersInGame);
[8dad966]473 }
474 }
[e5b96e2]475
476 if (gameFinished) {
477 // send a GAME_INFO message with 0 players to force clients to delete the game
478 int numPlayers = 0;
479 serverMsg.type = MSG_TYPE_GAME_INFO;
480 memcpy(serverMsg.buffer, &numPlayers, 4);
[8554263]481 broadcastMessage(msgProcessor, serverMsg, mapPlayers);
[e5b96e2]482
483 // erase game from server
[8ce793b]484 mapGames.erase(itGames++);
[3b6f46b]485 delete game;
[e5b96e2]486 }else
487 itGames++;
[8dad966]488 }
489
[ce2bb87]490 cout << "Processing projectiles" << endl;
491
[8dad966]492 // move all projectiles
[483a2cb]493 // see if this can be moved inside the game class
[45734ff]494 // this method can be moved when I add a MessageProcessor to the Game class
[8dad966]495 map<unsigned int, Projectile>::iterator itProj;
[5ae8dca]496 for (itGames = mapGames.begin(); itGames != mapGames.end(); itGames++) {
497 game = itGames->second;
498 for (itProj = game->getProjectiles().begin(); itProj != game->getProjectiles().end(); itProj++)
[95ffe57]499 {
[5ae8dca]500 cout << "About to call projectile move" << endl;
501 if (itProj->second.move(game->getPlayers()))
[8dad966]502 {
[5ae8dca]503 // send a REMOVE_PROJECTILE message
504 cout << "send a REMOVE_PROJECTILE message" << endl;
505 serverMsg.type = MSG_TYPE_REMOVE_PROJECTILE;
506 memcpy(serverMsg.buffer, &itProj->second.id, 4);
507 game->removeProjectile(itProj->second.id);
[8554263]508 broadcastMessage(msgProcessor, serverMsg, game->getPlayers());
[5ae8dca]509
510 Player* target = game->getPlayers()[itProj->second.target];
511 damagePlayer(target, itProj->second.damage);
[8dad966]512
[5ae8dca]513 if (target->isDead)
514 {
515 WorldMap::ObjectType flagType = WorldMap::OBJECT_NONE;
516 if (target->hasBlueFlag)
517 flagType = WorldMap::OBJECT_BLUE_FLAG;
518 else if (target->hasRedFlag)
519 flagType = WorldMap::OBJECT_RED_FLAG;
[411c1ae]520
[5ae8dca]521 if (flagType != WorldMap::OBJECT_NONE)
[8554263]522 addObjectToMap(flagType, target->pos.x, target->pos.y, game->getMap(), game->getPlayers(), msgProcessor);
[5ae8dca]523 }
[8dad966]524
[8554263]525 // send a PLAYER message after dealing damage
[5ae8dca]526 serverMsg.type = MSG_TYPE_PLAYER;
527 target->serialize(serverMsg.buffer);
[8554263]528 broadcastMessage(msgProcessor, serverMsg, game->getPlayers());
[8dad966]529 }
530 }
[d211210]531 }
532 }
533
[8554263]534 if (msgProcessor.receiveMessage(&clientMsg, &from) >= 0)
[95ffe57]535 {
[8554263]536 processMessage(clientMsg, from, msgProcessor, mapPlayers, mapGames, gameMap, unusedPlayerId, serverMsg, scoreBlue, scoreRed);
[ce2bb87]537
538 cout << "Finished processing the message" << endl;
[7b43385]539 }
[8e540f4]540 }
[371ce29]541
[d05086b]542 outputLog << "Stopped server on " << getCurrentDateTimeString() << endl;
543 outputLog.close();
544
[f41a7f9]545 // delete all games
546 map<string, Game*>::iterator itGames;
[95ffe57]547 for (itGames = mapGames.begin(); itGames != mapGames.end(); itGames++)
548 {
[f41a7f9]549 delete itGames->second;
550 }
551
[95ffe57]552 map<unsigned int, Player*>::iterator itPlayers;
553 for (itPlayers = mapPlayers.begin(); itPlayers != mapPlayers.end(); itPlayers++)
554 {
555 delete itPlayers->second;
556 }
557
[8e540f4]558 return 0;
559}
560
[8554263]561void processMessage(const NETWORK_MSG &clientMsg, struct sockaddr_in &from, MessageProcessor &msgProcessor, map<unsigned int, Player*>& mapPlayers, map<string, Game*>& mapGames, WorldMap* gameMap, unsigned int& unusedPlayerId, NETWORK_MSG &serverMsg, int &scoreBlue, int &scoreRed)
[8e540f4]562{
[41ad8ed]563 DataAccess da;
564
[9a4fa04]565 cout << "Inside processMessage" << endl;
566
[b8cb03f]567 cout << "Received message" << endl;
[8e540f4]568 cout << "MSG: type: " << clientMsg.type << endl;
569 cout << "MSG contents: " << clientMsg.buffer << endl;
570
571 // Check that if an invalid message is sent, the client will correctly
572 // receive and display the response. Maybe make a special error msg type
573 switch(clientMsg.type)
574 {
575 case MSG_TYPE_REGISTER:
[d2b411a]576 {
[8e540f4]577 string username(clientMsg.buffer);
578 string password(strchr(clientMsg.buffer, '\0')+1);
[521c88b]579 Player::PlayerClass playerClass;
580
[4509648]581 memcpy(&playerClass, clientMsg.buffer+username.length()+password.length()+2, 4);
[c4c2a3c]582
[8e540f4]583 cout << "username: " << username << endl;
584 cout << "password: " << password << endl;
[d2b411a]585
[8554263]586 bool validClass = false;
587
588 switch(playerClass) {
589 case Player::CLASS_WARRIOR:
590 case Player::CLASS_RANGER:
591 validClass = true;
592 break;
593 default:
594 validClass = false;
595 break;
[c4c2a3c]596 }
[521c88b]597
[8554263]598 serverMsg.type = MSG_TYPE_REGISTER;
[41ad8ed]599
[8554263]600 if (validClass) {
601 int error = da.insertPlayer(username, password, playerClass);
602
603 if (error)
604 strcpy(serverMsg.buffer, "Registration failed. Please try again.");
605 else
606 strcpy(serverMsg.buffer, "Registration successful.");
607 }else
608 strcpy(serverMsg.buffer, "You didn't select a class");
609
610 msgProcessor.sendMessage(&serverMsg, &from);
[d2b411a]611
[8e540f4]612 break;
613 }
614 case MSG_TYPE_LOGIN:
615 {
[60017fc]616 cout << "Got login message" << endl;
617
[8e540f4]618 string username(clientMsg.buffer);
[41ad8ed]619 string password(strchr(clientMsg.buffer, '\0')+1);
[8e540f4]620
[41ad8ed]621 Player* p = da.getPlayer(username);
[d2b411a]622
[b128109]623 if (p == NULL || !da.verifyPassword(password, p->password))
[41ad8ed]624 {
625 strcpy(serverMsg.buffer, "Incorrect username or password");
[95ffe57]626 if (p != NULL)
627 delete(p);
[41ad8ed]628 }
[01d0d00]629 else if(findPlayerByName(mapPlayers, username) != NULL)
[41ad8ed]630 {
631 strcpy(serverMsg.buffer, "Player has already logged in.");
[95ffe57]632 delete(p);
[41ad8ed]633 }
634 else
[8e540f4]635 {
[8dad966]636 updateUnusedPlayerId(unusedPlayerId, mapPlayers);
637 p->id = unusedPlayerId;
[d211210]638 cout << "new player id: " << p->id << endl;
[df79cfd]639 p->setAddr(from);
[ce2bb87]640 p->currentGame = NULL;
[df79cfd]641
642 // choose a random team (either 0 or 1)
643 p->team = rand() % 2;
[d211210]644
[f203c5c]645 serverMsg.type = MSG_TYPE_PLAYER;
[d211210]646 // tell the new player about all the existing players
647 cout << "Sending other players to new player" << endl;
648
[95ffe57]649 map<unsigned int, Player*>::iterator it;
[d211210]650 for (it = mapPlayers.begin(); it != mapPlayers.end(); it++)
651 {
[95ffe57]652 it->second->serialize(serverMsg.buffer);
[d211210]653
[95ffe57]654 cout << "sending info about " << it->second->name << endl;
655 cout << "sending id " << it->second->id << endl;
[8554263]656 msgProcessor.sendMessage(&serverMsg, &from);
[5f868c0]657 }
658
659 // tell the new player about all map objects
660 // (currently just the flags)
661 serverMsg.type = MSG_TYPE_OBJECT;
[e487381]662 vector<WorldMap::Object>* vctObjects = gameMap->getObjects();
[5f868c0]663 vector<WorldMap::Object>::iterator itObjects;
664 cout << "sending items" << endl;
[e487381]665 for (itObjects = vctObjects->begin(); itObjects != vctObjects->end(); itObjects++) {
[5f868c0]666 itObjects->serialize(serverMsg.buffer);
667 cout << "sending item id " << itObjects->id << endl;
[8554263]668 msgProcessor.sendMessage(&serverMsg, &from);
[d3efa1a]669 }
670
671 // send info about existing games to new player
672 map<string, Game*>::iterator itGames;
673 Game* g;
674 int numPlayers;
675 serverMsg.type = MSG_TYPE_GAME_INFO;
676
677 for (itGames = mapGames.begin(); itGames != mapGames.end(); itGames++)
678 {
679 g = itGames->second;
680 numPlayers = g->getNumPlayers();
681 memcpy(serverMsg.buffer, &numPlayers, 4);
682 strcpy(serverMsg.buffer+4, g->getName().c_str());
[8554263]683 msgProcessor.sendMessage(&serverMsg, &from);
[d211210]684 }
[59061f6]685
[b8601ee]686 // send the current score
687 serverMsg.type = MSG_TYPE_SCORE;
688 memcpy(serverMsg.buffer, &scoreBlue, 4);
689 memcpy(serverMsg.buffer+4, &scoreRed, 4);
[8554263]690 msgProcessor.sendMessage(&serverMsg, &from);
[b8601ee]691
692 serverMsg.type = MSG_TYPE_PLAYER;
[594d2e9]693 p->serialize(serverMsg.buffer);
[8554263]694 broadcastMessage(msgProcessor, serverMsg, mapPlayers);
[d211210]695
[95ffe57]696 mapPlayers[unusedPlayerId] = p;
[07028b9]697 }
698
[f203c5c]699 serverMsg.type = MSG_TYPE_LOGIN;
[8554263]700 msgProcessor.sendMessage(&serverMsg, &from);
[07028b9]701
[8e540f4]702 break;
703 }
704 case MSG_TYPE_LOGOUT:
705 {
706 string name(clientMsg.buffer);
707 cout << "Player logging out: " << name << endl;
708
[01d0d00]709 Player *p = findPlayerByName(mapPlayers, name);
[633f42a]710
[8e540f4]711 if (p == NULL)
712 {
[90eaad2]713 strcpy(serverMsg.buffer+4, "That player is not logged in. This is either a bug, or you're trying to hack the server.");
[8a3ef42]714 cout << "Player not logged in" << endl;
[07028b9]715 }
[01d0d00]716 else if ( p->addr.sin_addr.s_addr != from.sin_addr.s_addr ||
717 p->addr.sin_port != from.sin_port )
[07028b9]718 {
[90eaad2]719 strcpy(serverMsg.buffer+4, "That player is logged in using a differemt connection. This is either a bug, or you're trying to hack the server.");
[8a3ef42]720 cout << "Player logged in using a different connection" << endl;
[2488852]721 }
[8e540f4]722 else
[2488852]723 {
[411c1ae]724 if (!p->isDead) {
725 WorldMap::ObjectType flagType = WorldMap::OBJECT_NONE;
726 if (p->hasBlueFlag)
727 flagType = WorldMap::OBJECT_BLUE_FLAG;
728 else if (p->hasRedFlag)
729 flagType = WorldMap::OBJECT_RED_FLAG;
730
731 if (flagType != WorldMap::OBJECT_NONE) {
[8554263]732 addObjectToMap(flagType, p->pos.x, p->pos.y, gameMap, mapPlayers, msgProcessor);
[411c1ae]733 }
734 }
735
[1a47469]736 // broadcast to all players before deleting p from the map
[4509648]737 serverMsg.type = MSG_TYPE_LOGOUT;
738 memcpy(serverMsg.buffer, &p->id, 4);
739
[8554263]740 broadcastMessage(msgProcessor, serverMsg, mapPlayers);
[1a47469]741
[8dad966]742 if (p->id < unusedPlayerId)
743 unusedPlayerId = p->id;
[8554263]744
[01d0d00]745 mapPlayers.erase(p->id);
[95ffe57]746 delete p;
[8554263]747
[90eaad2]748 strcpy(serverMsg.buffer+4, "You have successfully logged out.");
[8e540f4]749 }
[07028b9]750
[d211210]751 serverMsg.type = MSG_TYPE_LOGOUT;
[8554263]752 msgProcessor.sendMessage(&serverMsg, &from);
[8a3ef42]753
[8e540f4]754 break;
755 }
756 case MSG_TYPE_CHAT:
757 {
[da692b9]758 cout << "Got a chat message" << endl;
759
[8554263]760 serverMsg.type = MSG_TYPE_CHAT;
761
[01d0d00]762 Player *p = findPlayerByAddr(mapPlayers, from);
[07028b9]763
[8e540f4]764 if (p == NULL)
765 {
766 strcpy(serverMsg.buffer, "No player is logged in using this connection. This is either a bug, or you're trying to hack the server.");
[8554263]767 msgProcessor.sendMessage(&serverMsg, &from);
[2488852]768 }
[8e540f4]769 else
770 {
[b128109]771 ostringstream oss;
772 oss << p->name << ": " << clientMsg.buffer;
[3b1efcc]773
[b128109]774 strcpy(serverMsg.buffer, oss.str().c_str());
[8554263]775 broadcastMessage(msgProcessor, serverMsg, mapPlayers);
[8e540f4]776 }
777
778 break;
[e084950]779 }
[b128109]780 case MSG_TYPE_PLAYER_MOVE:
781 {
782 cout << "PLAYER_MOVE" << endl;
783
784 int id, x, y;
785
786 memcpy(&id, clientMsg.buffer, 4);
787 memcpy(&x, clientMsg.buffer+4, 4);
788 memcpy(&y, clientMsg.buffer+8, 4);
[7b43385]789
[b128109]790 cout << "x: " << x << endl;
791 cout << "y: " << y << endl;
792 cout << "id: " << id << endl;
[7b43385]793
[95ffe57]794 Player* p = mapPlayers[id];
[8554263]795 bool validMessage = false;
[95ffe57]796
797 if ( p->addr.sin_addr.s_addr == from.sin_addr.s_addr &&
798 p->addr.sin_port == from.sin_port )
[b128109]799 {
[0129700]800 if (p->currentGame->startPlayerMovement(id, x, y)) {
[60017fc]801 serverMsg.type = MSG_TYPE_PLAYER_MOVE;
802
803 memcpy(serverMsg.buffer, &id, 4);
[95ffe57]804 memcpy(serverMsg.buffer+4, &p->target.x, 4);
805 memcpy(serverMsg.buffer+8, &p->target.y, 4);
[60017fc]806
[8554263]807 broadcastMessage(msgProcessor, serverMsg, mapPlayers);
808
809 validMessage = true;
[60017fc]810 }
811 else
812 cout << "Bad terrain detected" << endl;
[b128109]813 }
[8554263]814 else
[b128109]815 cout << "Player id (" << id << ") doesn't match sender" << endl;
816
[8554263]817 if (!validMessage)
818 msgProcessor.sendMessage(&serverMsg, &from);
819
[b128109]820 break;
821 }
[5299436]822 case MSG_TYPE_PICKUP_FLAG:
823 {
824 // may want to check the id matches the sender, just like for PLAYER_NOVE
825 cout << "PICKUP_FLAG" << endl;
826
827 int id;
828
829 memcpy(&id, clientMsg.buffer, 4);
830 cout << "id: " << id << endl;
831
[95ffe57]832 Player* p = mapPlayers[id];
[ce2bb87]833 int objectId = p->currentGame->processFlagPickupRequest(p);
[95ffe57]834
[ce2bb87]835 if (objectId >= 0) {
[8554263]836 map<unsigned int, Player*> players = p->currentGame->getPlayers();
837
[ce2bb87]838 serverMsg.type = MSG_TYPE_REMOVE_OBJECT;
839 memcpy(serverMsg.buffer, &objectId, 4);
[8554263]840 broadcastMessage(msgProcessor, serverMsg, players);
[5c84d54]841
[8554263]842 serverMsg.type = MSG_TYPE_PLAYER;
843 p->serialize(serverMsg.buffer);
844 broadcastMessage(msgProcessor, serverMsg, players);
[5c84d54]845 }
846
[5299436]847 break;
848 }
[e487381]849 case MSG_TYPE_DROP_FLAG:
850 {
851 // may want to check the id matches the sender, just like for PLAYER_NOVE
852 cout << "DROP_FLAG" << endl;
853
854 int id;
855
856 memcpy(&id, clientMsg.buffer, 4);
857 cout << "id: " << id << endl;
858
[95ffe57]859 Player* p = mapPlayers[id];
860
[e487381]861 WorldMap::ObjectType flagType = WorldMap::OBJECT_NONE;
[95ffe57]862 if (p->hasBlueFlag)
[e487381]863 flagType = WorldMap::OBJECT_BLUE_FLAG;
[95ffe57]864 else if (p->hasRedFlag)
[e487381]865 flagType = WorldMap::OBJECT_RED_FLAG;
866
[8554263]867 map<unsigned int, Player*> players = p->currentGame->getPlayers();
868
869 addObjectToMap(flagType, p->pos.x, p->pos.y, p->currentGame->getMap(), players, msgProcessor);
[e487381]870
[95ffe57]871 p->hasBlueFlag = false;
872 p->hasRedFlag = false;
[e487381]873
874 serverMsg.type = MSG_TYPE_PLAYER;
[95ffe57]875 p->serialize(serverMsg.buffer);
[8554263]876 broadcastMessage(msgProcessor, serverMsg, players);
[e487381]877
878 break;
879 }
[4b4b153]880 case MSG_TYPE_START_ATTACK:
881 {
882 cout << "Received a START_ATTACK message" << endl;
883
[8a4ed74]884 int id, targetId;
885
886 memcpy(&id, clientMsg.buffer, 4);
887 memcpy(&targetId, clientMsg.buffer+4, 4);
888
[ffadc8e]889 // need to make sure the target is in the sender's game
890
[8554263]891 Player* p = mapPlayers[id];
892 p->targetPlayer = targetId;
893 p->isChasing = true;
894
895 map<unsigned int, Player*> players = p->currentGame->getPlayers();
[8dad966]896
[4b4b153]897 serverMsg.type = MSG_TYPE_START_ATTACK;
[8dad966]898 memcpy(serverMsg.buffer, &id, 4);
899 memcpy(serverMsg.buffer+4, &targetId, 4);
[8554263]900 broadcastMessage(msgProcessor, serverMsg, players);
[8a4ed74]901
902 break;
[4b4b153]903 }
[b8f789d]904 case MSG_TYPE_CREATE_GAME:
[8e540f4]905 {
[b8f789d]906 cout << "Received a CREATE_GAME message" << endl;
907
908 string gameName(clientMsg.buffer);
909 cout << "Game name: " << gameName << endl;
910
[b48ef09]911 // check if this game already exists
912 if (mapGames.find(gameName) != mapGames.end()) {
[3ef8cf4]913 cout << "Error: Game already exists" << endl;
[b48ef09]914 serverMsg.type = MSG_TYPE_JOIN_GAME_FAILURE;
[8554263]915 }else {
916 Game* g = new Game(gameName, "../data/map.txt");
917 mapGames[gameName] = g;
918
919 // add flag objects to the map
920 WorldMap* m = g->getMap();
921 for (int y=0; y<m->height; y++) {
922 for (int x=0; x<m->width; x++) {
923 switch (m->getStructure(x, y)) {
924 case WorldMap::STRUCTURE_BLUE_FLAG:
925 m->addObject(WorldMap::OBJECT_BLUE_FLAG, x*25+12, y*25+12);
926 break;
927 case WorldMap::STRUCTURE_RED_FLAG:
928 m->addObject(WorldMap::OBJECT_RED_FLAG, x*25+12, y*25+12);
929 break;
930 }
[70fc3e8]931 }
932 }
[8554263]933
934 serverMsg.type = MSG_TYPE_JOIN_GAME_SUCCESS;
935 strcpy(serverMsg.buffer, gameName.c_str());
[70fc3e8]936 }
937
[8554263]938 msgProcessor.sendMessage(&serverMsg, &from);
[b92e6a7]939
[b48ef09]940 break;
941 }
942 case MSG_TYPE_JOIN_GAME:
943 {
944 cout << "Received a JOIN_GAME message" << endl;
[b92e6a7]945
[b48ef09]946 string gameName(clientMsg.buffer);
947 cout << "Game name: " << gameName << endl;
[b92e6a7]948
[b48ef09]949 // check if this game already exists
950 if (mapGames.find(gameName) == mapGames.end()) {
[3ef8cf4]951 cout << "Error: Game does not exist" << endl;
[b48ef09]952 serverMsg.type = MSG_TYPE_JOIN_GAME_FAILURE;
[8554263]953 }else {
954 Game* g = mapGames[gameName];
955 map<unsigned int, Player*>& players = g->getPlayers();
956 Player* p = findPlayerByAddr(mapPlayers, from);
957
958 if (players.find(p->id) != players.end()) {
959 cout << "Player " << p->name << " trying to join a game he's already in" << endl;
960 serverMsg.type = MSG_TYPE_JOIN_GAME_FAILURE;
961 }else {
962 serverMsg.type = MSG_TYPE_JOIN_GAME_SUCCESS;
963 strcpy(serverMsg.buffer, gameName.c_str());
964 }
[b92e6a7]965 }
966
[8554263]967 msgProcessor.sendMessage(&serverMsg, &from);
[b8f789d]968
969 break;
970 }
[ab8fd40]971 case MSG_TYPE_LEAVE_GAME:
972 {
973 cout << "Received a LEAVE_GAME message" << endl;
974
975 Player* p = findPlayerByAddr(mapPlayers, from);
976 Game* g = p->currentGame;
977
978 if (g == NULL) {
979 cout << "Player " << p->name << " is trying to leave a game, but is not currently in a game." << endl;
980
981 /// should send a response back, maybe a new message type is needed
[8554263]982 // not sure what to do here
983 }else {
984 cout << "Game name: " << g->getName() << endl;
985 p->currentGame = NULL;
[ab8fd40]986
[8554263]987 serverMsg.type = MSG_TYPE_LEAVE_GAME;
988 memcpy(serverMsg.buffer, &p->id, 4);
989 strcpy(serverMsg.buffer+4, g->getName().c_str());
990 broadcastMessage(msgProcessor, serverMsg, g->getPlayers());
[95ffe57]991
[8554263]992 g->removePlayer(p->id);
[ab8fd40]993
[8554263]994 int numPlayers = g->getNumPlayers();
[ab8fd40]995
[8554263]996 serverMsg.type = MSG_TYPE_GAME_INFO;
997 memcpy(serverMsg.buffer, &numPlayers, 4);
998 strcpy(serverMsg.buffer+4, g->getName().c_str());
999 broadcastMessage(msgProcessor, serverMsg, mapPlayers);
1000
1001 // if there are no more players in the game, remove it
1002 if (numPlayers == 0) {
1003 mapGames.erase(g->getName());
1004 delete g;
1005 }
[1248984]1006 }
1007
[ab8fd40]1008 break;
1009 }
[b48ef09]1010 case MSG_TYPE_JOIN_GAME_ACK:
[b8f789d]1011 {
[b48ef09]1012 cout << "Received a JOIN_GAME_ACK message" << endl;
[e084950]1013
[b8f789d]1014 string gameName(clientMsg.buffer);
1015 cout << "Game name: " << gameName << endl;
1016
[b48ef09]1017 // check if this game already exists
1018 if (mapGames.find(gameName) == mapGames.end()) {
1019 serverMsg.type = MSG_TYPE_JOIN_GAME_FAILURE;
[8554263]1020
1021 msgProcessor.sendMessage(&serverMsg, &from);
[b48ef09]1022 }
[b92e6a7]1023
[f41a7f9]1024 Game* g = mapGames[gameName];
[b92e6a7]1025
[b48ef09]1026 Player* p = findPlayerByAddr(mapPlayers, from);
[f41a7f9]1027 p->team = rand() % 2; // choose a random team (either 0 or 1)
[e62b56c]1028 p->currentGame = g;
[b92e6a7]1029
1030 // tell the new player about all map objects
1031 // (currently just the flags)
1032
1033 serverMsg.type = MSG_TYPE_OBJECT;
[f41a7f9]1034 vector<WorldMap::Object>* vctObjects = g->getMap()->getObjects();
[b92e6a7]1035 vector<WorldMap::Object>::iterator itObjects;
1036 cout << "sending items" << endl;
1037 for (itObjects = vctObjects->begin(); itObjects != vctObjects->end(); itObjects++) {
1038 itObjects->serialize(serverMsg.buffer);
1039 cout << "sending item id " << itObjects->id << endl;
[8554263]1040 msgProcessor.sendMessage(&serverMsg, &from);
[b92e6a7]1041 }
1042
1043
1044 // send the current score
1045 serverMsg.type = MSG_TYPE_SCORE;
1046
[f41a7f9]1047 int game_blueScore = g->getBlueScore();
1048 int game_redScore = g->getRedScore();
[b92e6a7]1049 memcpy(serverMsg.buffer, &game_blueScore, 4);
1050 memcpy(serverMsg.buffer+4, &game_redScore, 4);
1051
[8554263]1052 msgProcessor.sendMessage(&serverMsg, &from);
[b92e6a7]1053
[8554263]1054 // send info to other players
[453087e]1055 serverMsg.type = MSG_TYPE_PLAYER_JOIN_GAME;
[b92e6a7]1056 p->serialize(serverMsg.buffer);
1057 cout << "Should be broadcasting the message" << endl;
[8554263]1058 broadcastMessage(msgProcessor, serverMsg, g->getPlayers());
[b8f789d]1059
[b48ef09]1060 g->addPlayer(p);
[453087e]1061
1062
1063 // tell the new player about all the players in the game (including himself)
1064 cout << "Sending other players to new player" << endl;
1065 serverMsg.type = MSG_TYPE_PLAYER_JOIN_GAME;
1066
[8554263]1067
1068 map<unsigned int, Player*>& allPlayers = g->getPlayers();
1069 map<unsigned int, Player*>::iterator it;
[453087e]1070 for (it = allPlayers.begin(); it != allPlayers.end(); it++)
1071 {
1072 it->second->serialize(serverMsg.buffer);
1073
1074 cout << "sending info about " << it->second->name << endl;
1075 cout << "sending id " << it->second->id << endl;
[8554263]1076 msgProcessor.sendMessage(&serverMsg, &from);
[453087e]1077 }
1078
[b48ef09]1079 int numPlayers = g->getNumPlayers();
1080
[b8f789d]1081 serverMsg.type = MSG_TYPE_GAME_INFO;
1082 memcpy(serverMsg.buffer, &numPlayers, 4);
1083 strcpy(serverMsg.buffer+4, gameName.c_str());
[8554263]1084 broadcastMessage(msgProcessor, serverMsg, mapPlayers);
[ab8fd40]1085
[b8f789d]1086 break;
1087 }
1088 default:
1089 {
[8554263]1090 // probably want to log the error rather than sending a chat message,
1091 // especially since chat isn't currently visible on all screens
1092
[8e540f4]1093 serverMsg.type = MSG_TYPE_CHAT;
[b8f789d]1094 strcpy(serverMsg.buffer, "Server error occured. Report this please.");
[e084950]1095
[8e540f4]1096 break;
1097 }
[e3535b3]1098 }
[8554263]1099}
[da692b9]1100
[8554263]1101void broadcastMessage(MessageProcessor &msgProcessor, NETWORK_MSG &serverMsg, map<unsigned int, Player*>& players) {
1102 map<unsigned int, Player*>::iterator it;
1103 for (it = players.begin(); it != players.end(); it++) {
1104 msgProcessor.sendMessage(&serverMsg, &(it->second->addr));
1105 }
[e3535b3]1106}
[da692b9]1107
[95ffe57]1108void updateUnusedPlayerId(unsigned int& id, map<unsigned int, Player*>& mapPlayers)
[01d0d00]1109{
[1106210]1110 while (mapPlayers.find(id) != mapPlayers.end())
1111 id++;
[01d0d00]1112}
[8dad966]1113
[95ffe57]1114Player *findPlayerByName(map<unsigned int, Player*> &m, string name)
1115{
1116 map<unsigned int, Player*>::iterator it;
1117
1118 for (it = m.begin(); it != m.end(); it++)
1119 {
1120 if ( it->second->name.compare(name) == 0 )
1121 return it->second;
1122 }
1123
1124 return NULL;
1125}
1126
1127Player *findPlayerByAddr(map<unsigned int, Player*> &m, const sockaddr_in &addr)
1128{
1129 map<unsigned int, Player*>::iterator it;
1130
1131 for (it = m.begin(); it != m.end(); it++)
1132 {
1133 if ( it->second->addr.sin_addr.s_addr == addr.sin_addr.s_addr &&
1134 it->second->addr.sin_port == addr.sin_port )
1135 return it->second;
1136 }
1137
1138 return NULL;
1139}
1140
[c76134b]1141void damagePlayer(Player *p, int damage) {
1142 p->health -= damage;
1143 if (p->health < 0)
1144 p->health = 0;
1145 if (p->health == 0) {
[66c4ec4]1146 cout << "Player died" << endl;
[c76134b]1147 p->isDead = true;
1148 p->timeDied = getCurrentMillis();
1149 }
1150}
[411c1ae]1151
[8554263]1152void addObjectToMap(WorldMap::ObjectType objectType, int x, int y, WorldMap* gameMap, map<unsigned int, Player*>& mapPlayers, MessageProcessor &msgProcessor) {
[411c1ae]1153 NETWORK_MSG serverMsg;
1154
1155 gameMap->addObject(objectType, x, y);
1156
1157 serverMsg.type = MSG_TYPE_OBJECT;
1158 gameMap->getObjects()->back().serialize(serverMsg.buffer);
1159
[8554263]1160 broadcastMessage(msgProcessor, serverMsg, mapPlayers);
[411c1ae]1161}
Note: See TracBrowser for help on using the repository browser.