home *** CD-ROM | disk | FTP | other *** search
- #include "Server.h"
-
- #include "Network.h"
-
-
- #include "PacketHandler.h"
- #include "log.h"
- #include "Game.h"
- #include "random.h"
- #include <string.h>
-
- Server::Server(){
- // ipAddress = NULL;
- socket = NULL;
-
- si.protocolVersion = NETWORK_PROTOCOL_VERSION;
- si.numClients = 0;
- si.maxClients = Network::info.var.server_maxClients;
- strcpy(si.name, Network::info.var.server_name);
- strcpy(si.description, Network::info.var.server_description);
- strcpy(si.arena, Game::info.var.arena);
- si.gamemode = Game::info.var.mode;
- si.ghostTime = Game::info.var.ghostTime;
-
- si.optionFlags = 0;
- if( Game::info.var.useArenaCycle )
- si.optionFlags |= PACKET_OPTION_FLAG_GAME_USE_ARENA_CYCLE;
- if( Game::info.var.enableFriendlyFire )
- si.optionFlags |= PACKET_OPTION_FLAG_GAME_ENABLE_FRIENDLY_FIRE;
-
- for(int i=0;i<NETWORK_MAX_CLIENTS;i++){
- clients[i] = NULL;
- }
- localClient = NULL;
-
- lastPingMillis = SDL_GetTicks();
- lastPlayerinfoMillis = SDL_GetTicks()+100; // THINKABOUTME: damit nicht zusammen gesendet wird?
- lastGamestateMillis = SDL_GetTicks(); // THINKABOUTME: damit nicht zusammen gesendet wird?
- }
-
- Server::~Server(){
- for(int i=0;i<NETWORK_MAX_CLIENTS;i++){
- if(clients[i] != NULL && clients[i] != localClient)
- delete clients[i];
-
-
- }
- }
-
-
- bool Server::openPort(){
-
- socket = SDLNet_UDP_Open(Network::info.var.server_port);
- if(socket == NULL){
- error("(in Server::openPort()): SDLNet_UDP_Open() failed: %s.\n\n", SDLNet_GetError());
- return false;
- }
-
- if(SDLNet_ResolveHost(&ipAddress, Network::info.var.server_hostName, Network::info.var.server_port) == -1){
- error("(in Server::openPort()): SDLNet_ResolveHost() failed: %s.\n\n", SDLNet_GetError());
- SDLNet_UDP_Close(socket);
- return false;
- }
-
- // ipAddress.host = 0x0100007F;
- // ipAddress.port = Network::info.var.serverPort;
- // printf("server addr: %s:%d\n", SDLNet_ResolveIP(&ipAddress), ipAddress.port);
-
- return true;
- }
-
- bool Server::closePort(){
- SDLNet_UDP_Close(socket);
-
- return true;
- }
-
-
- bool Server::disconnectAllClients(const char* reason){
- // IPaddress ip;
- // ip.host = 0;
- // ip.port = 0;
-
- if( localClient != NULL ){ // remove the local client first...
- removeClient(localClient); // if game::shutdown was called this has been already done!
- }
-
- // ... and send a disconnect packet to all others
- disconnectPacket_t d;
- strcpy(d.reason, reason);
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_DISCONNECT, this->ipAddress, &d, sizeof(d));
- if( p == NULL ){
- error("(in Server::disconnectAllClients()): Couldn't alloc packet.\n\n");
- return false;
-
- }
-
-
- if( !sendToAllClients(p) ){
- return false;
- }
-
- SDLNet_FreePacket(p);
-
- return true;
- }
-
- bool Server::disconnectClient(Client* client, const char* reason){
-
- if( client == localClient ){
- warn("(in Server::disconnectClient()): Disconnecting local client!\n\n");
- }
- if( clients[client->clientId] == NULL ){
- error("(in Server::disconnectClient()): Client is not connected to this server.\n\n");
- return false;
- }
-
- // ... and send a disconnect packet to all others
- disconnectPacket_t d;
- d.clientId = client->clientId;
- strncpy(d.reason, reason, CON_MAX_STRING_LENGTH);
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_DISCONNECT, client->ipAddress, &d, sizeof(d));
- if( p == NULL ){
- error("(in Server::disconnectClient()): Couldn't alloc packet.\n\n");
- return false;
- }
-
- if( !sendToClient(client, p) ){
- error("(in Server::disconnectClient()): Couldn't send packet.\n\n");
- SDLNet_FreePacket(p);
- return false;
- }
- SDLNet_FreePacket(p);
-
- removeClient(client);
-
- // inform the other clients
- clientDisconnectedPacket_t cd;
- cd.clientId = d.clientId;
- strncpy(cd.reason, reason, CON_MAX_STRING_LENGTH);
- p = PacketHandler::wrapPacket(PACKET_TYPE_CLIENT_DISCONNECTED, this->ipAddress, &cd, sizeof(cd));
- if( !sendToAllOtherRemoteClients(client, p) ){
- error("(in Server::handleDisconnect()): Couldn't send packet.\n\n");
- SDLNet_FreePacket(p);
- return false;
- }
- SDLNet_FreePacket(p);
-
- log("'%s' disconnected (reason: %s).\n", client->ci.name, reason);
-
-
- return true;
- }
-
-
- int Server::addClient(Client* client){
- for(int i=0;i<si.maxClients;i++){
- if(clients[i] == NULL){
- clients[i] = client;
- si.numClients++;
- return i;
- }
- }
-
- return -1;
- }
-
- void Server::removeClient(Client* client){
- for(int i=0;i<si.maxClients;i++){
- if(clients[i] == client){
- // removeClientFromAllTeams(client);
- if(clients[i] != localClient){
- delete clients[i];
- }
- clients[i] = NULL;
- si.numClients--;
- }
- }
- }
-
- void Server::checkClientName(char* name, char* newName){
- strncpy(newName, name, CLIENT_MAX_NAME_LENGTH);
- int number = 1;
-
- for(int i=0;i<si.maxClients;i++){
- if(clients[i] != NULL && !strcmp(newName, clients[i]->ci.name) ){
- sprintf(newName, "%s (%i)", name, number);
- number++;
- i = 0;
- }
- }
- }
-
- bool Server::hasFreeSlots(){
- // for(int i=0;i<maxClients;i++){
- // if(clients[i] == NULL)
- // return true;
- // }
- // return false;
- return (si.numClients < si.maxClients);
- }
-
- Client* Server::getClientByPacket(UDPpacket* packet){
- for(int i=0;i<si.maxClients;i++){
- if(clients[i] != NULL && clients[i]->ipAddress.host == packet->address.host && clients[i]->ipAddress.port == packet->address.port)
- return clients[i];
- }
-
- return NULL;
- }
-
- Client* Server::getClientByName(const char* name){
- for(int i=0;i<si.maxClients;i++){
- if(clients[i] != NULL && streq(name, clients[i]->ci.name) )
- return clients[i];
- }
-
- return NULL;
- }
-
- void Server::resetClients(){
- for(int i=0;i<si.maxClients;i++){
- if( clients[i] != NULL ){
- clients[i]->ci.score = 0;
- clients[i]->ci.kills = 0;
- clients[i]->ci.deaths = 0;
- clients[i]->ci.team = GAME_TEAM_SPECTATORS;
- clients[i]->cs.armor = 0;
- clients[i]->cs.energy = 0;
- clients[i]->vehicle = NULL;
-
- clients[i]->lastPingMillis = SDL_GetTicks();
- }
- }
- }
-
- bool Server::sendToClient(Client* client, UDPpacket* packet){
- packet->address.host = client->ipAddress.host;
- packet->address.port = client->ipAddress.port;
- if( !Network::sendPacket(socket, packet) ){
- error("(in Server::sendToClient()): Couldn't send packet.\n\n");
- return false;
- }
- return true;
- }
-
- bool Server::sendToAllClients(UDPpacket* packet){
- for(int i=0;i<si.maxClients;i++){
- if(clients[i] != NULL){
- packet->address.host = clients[i]->ipAddress.host;
- packet->address.port = clients[i]->ipAddress.port;
- if( !SDLNet_UDP_Send(socket, -1, packet) ){
- error("(in Server::sendToAllClients()): SDLNet_UDP_Send() failed: %s.\n\n", SDLNet_GetError());
- return false;
- }
- }
- }
- return true;
- }
-
- bool Server::sendToAllRemoteClients(UDPpacket* packet){
- for(int i=0;i<si.maxClients;i++){
- if(clients[i] != NULL && clients[i] != localClient){
- packet->address.host = clients[i]->ipAddress.host;
- packet->address.port = clients[i]->ipAddress.port;
- if( !SDLNet_UDP_Send(socket, -1, packet) ){
- error("(in Server::sendToAllRemoteClients()): SDLNet_UDP_Send() failed: %s.\n\n", SDLNet_GetError());
- return false;
- }
- }
- }
- return true;
- }
-
- bool Server::sendToAllOtherRemoteClients(Client* c, UDPpacket* packet){
- for(int i=0;i<si.maxClients;i++){
- if(clients[i] != NULL && clients[i] != c && clients[i] != localClient){
- packet->address.host = clients[i]->ipAddress.host;
- packet->address.port = clients[i]->ipAddress.port;
- if( !SDLNet_UDP_Send(socket, -1, packet) ){
- error("(in Server::sendToAllOtherRemoteClients()): SDLNet_UDP_Send() failed: %s.\n\n", SDLNet_GetError());
- return false;
- }
- }
- }
- return true;
- }
-
-
-
- void Server::sendGamestate(){
- int i;
- unsigned long currentMillis = SDL_GetTicks();
-
- gamestatePacket_t gs;
-
- for(i=0;i<si.maxClients;i++){
- Client* c = clients[i];
- if(c != NULL){
- if( c->vehicle != NULL ){ // alive -> tja, ?
- vectorCopy3d(c->vehicle->pos, c->cs.pos);
- vectorCopy3d(c->vehicle->dir, c->cs.dir);
- vectorCopy3d(c->vehicle->up, c->cs.up);
- vectorCopy3d(c->vehicle->vel_inp, c->cs.vel);
- c->cs.armor = (unsigned char)c->vehicle->armor;
- c->cs.energy = (unsigned char)c->vehicle->energy;
- }else{ // dead -> nothing?
- c->cs.armor = 0;
- c->cs.energy = 0;
- }
-
- gs.clientIds[i] = i;
- gs.cs[i] = c->cs;
- }else{
- gs.clientIds[i] = -1;
- }
- }
-
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_GAMESTATE, this->ipAddress, &gs, sizeof(gs));
- if( !sendToAllRemoteClients(p) ){
- error("(in Server::sendPackets()): Couldn't send gamestate packet.\n\n");
- SDLNet_FreePacket(p);
- return;
- }
- /*
- for(i=0;i<si.maxClients;i++){
- if( clients[i] != NULL && clients[i] != localClient && clients[i]->lastSpawnMillis != 0 ){
- p->address.host = clients[i]->ipAddress.host;
- p->address.port = clients[i]->ipAddress.port;
- if( !SDLNet_UDP_Send(socket, -1, p) ){
- error("(in Server::sendGamestate()): SDLNet_UDP_Send() failed: %s.\n\n", SDLNet_GetError());
- return;
- }
- }
- }
- */
- SDLNet_FreePacket(p);
-
- lastGamestateMillis = currentMillis;
- }
-
- void Server::sendPlayerinfo(){
- unsigned long currentMillis = SDL_GetTicks();
-
- playerinfoPacket_t pi;
-
- // fill pi
- for(int i=0;i<si.maxClients;i++){
- if(clients[i] != NULL){
- pi.clientIds[i] = i;
-
- clients[i]->ci.secondsOnServer = (short)( (currentMillis - clients[i]->momentOfConnectMillis) / 1000 );
- pi.ci[i] = clients[i]->ci;
- }else{
- pi.clientIds[i] = -1;
- }
- }
-
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_PLAYERINFO, this->ipAddress, &pi, sizeof(pi));
- if( !sendToAllRemoteClients(p) ){
- error("(in Server::sendPackets()): Couldn't send playerinfo packet.\n\n");
- SDLNet_FreePacket(p);
- return;
- }
- SDLNet_FreePacket(p);
-
- // log("Playerinfo send.\n");
- lastPlayerinfoMillis = currentMillis;
- }
-
- void Server::sendPing(){
- unsigned long currentMillis = SDL_GetTicks();
-
- pingPacket_t pp;
- pp.protocolVersion = Network::info.var.protocolVersion;
-
-
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_PING, this->ipAddress, &pp, sizeof(pp));
- if( !sendToAllClients(p) ){
- error("(in Server::sendPackets()): Couldn't send ping packet.\n\n");
- SDLNet_FreePacket(p);
- return;
- }
- SDLNet_FreePacket(p);
-
- for(int i=0;i<si.maxClients;i++){
- if(clients[i] == NULL || clients[i] == localClient)
- continue;
-
- // not responding -> set ping to server.pingInterval
- if( currentMillis > clients[i]->lastPingMillis + (unsigned long)5000 ){
- clients[i]->ci.ping = (unsigned long)9999;
- if( ((currentMillis - clients[i]->lastPingMillis) / 1000) % 5 == 0 ){
- log("Connection to '%s' interrupted\n", clients[i]->ci.name);
- }
- }
-
- // not responding for too long -> disconnect
- //printf("client %i t: %i\n", i, currentMillis - clients[i]->lastPingMillis);
- if(currentMillis - clients[i]->lastPingMillis > (unsigned long)Network::info.var.server_maxClientIdleTime){
- disconnectClient(clients[i], "server.maxClientIdleTime reached.");
- }
- }
-
- lastPingMillis = currentMillis;
-
- }
-
- void Server::sendClientHurt(char hurtClientId, char hurterClientId, unsigned char amount){
- clientHurtPacket_t ch;
-
- if( clients[hurtClientId] == NULL ){
- warn("(in Server::sendClientHurt()): hurtClientId is invalid.\n\n");
- return;
- }
- ch.hurtClientId = hurtClientId;
-
- if( clients[hurterClientId] == NULL ){
- warn("(in Server::sendClientHurt()): hurterClientId is invalid.\n\n");
- // maybe just disconnected
- ch.hurterClientId = -1;
- }else{
- ch.hurterClientId = hurterClientId;
- }
-
- ch.amount = amount;
-
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_CLIENT_HURT, this->ipAddress, &ch, sizeof(ch));
- if( !sendToAllRemoteClients(p) ){
- error("(in Server::sendClientHurt()): Couldn't send packet.\n\n");
- SDLNet_FreePacket(p);
- return;
- }
- SDLNet_FreePacket(p);
- }
-
-
- void Server::sendClientKill(char killedClientId, char killerClientId, char weapon){
- clientKillPacket_t ck;
-
- ck.killedClientId = killedClientId;
- ck.killerClientId = killerClientId;
- ck.weapon = weapon;
-
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_CLIENT_KILL, this->ipAddress, &ck, sizeof(ck));
- if( !sendToAllRemoteClients(p) ){
- error("(in Server::sendClientKill()): Couldn't send packet.\n\n");
- SDLNet_FreePacket(p);
- return;
- }
- SDLNet_FreePacket(p);
- }
-
- void Server::sendChatMessage(const char* message){
- chatMessagePacket_t cm;
- cm.clientId = -1;
- strncpy(cm.message, message, CON_MAX_STRING_LENGTH);
- cm.mode = GAME_CHAT_MODE_SERVER;
-
-
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_CHAT_MESSAGE, this->ipAddress, &cm, sizeof(cm));
- if(p == NULL){
- error("(in Server::sendChatMessage()): Couldn't alloc packet.\n\n");
- return;
- }
-
- if( !sendToAllClients(p) ){
- error("(in Server::sendChatMessage()): Couldn't send packet.\n\n");
- SDLNet_FreePacket(p);
- return;
- }
-
- }
-
- void Server::sendArenaChange(){
- arenaChangePacket_t ac;
- strcpy(ac.newArena, Game::info.var.arena);
-
-
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_ARENA_CHANGE, this->ipAddress, &ac, sizeof(ac));
- if(p == NULL){
- error("(in Server::sendArenaChange()): Couldn't alloc packet.\n\n");
- return;
- }
-
- if( !sendToAllRemoteClients(p) ){
- error("(in Server::sendArenaChange()): Couldn't send packet.\n\n");
- SDLNet_FreePacket(p);
- return;
- }
- }
-
- void Server::sendPackets(){
- unsigned long currentMillis = SDL_GetTicks();
-
- // do ping stuff
- if(currentMillis - lastPingMillis > (unsigned long)Network::info.var.server_pingInterval){
- // log("Pinging...\n");
- sendPing();
- }
-
- // do playerinfo stuff
- if(currentMillis - lastPlayerinfoMillis > (unsigned long)Network::info.var.server_playerinfoInterval){
- // log("Sending playerinfo...\n");
- sendPlayerinfo();
- }
-
-
-
- // do gamestate stuff
- if(currentMillis - lastGamestateMillis > (unsigned long)Network::info.var.server_gamestateInterval){
- // log("Sending gamestate...\n");
- sendGamestate();
- }
-
- }
-
- void Server::receivePackets(){
- UDPpacket** packets = SDLNet_AllocPacketV(NETWORK_MAX_PACKETS_PER_FRAME, NETWORK_MAX_PACKET_SIZE);
- if(packets == NULL){
- error("(in Server::receivePackets()): Unable to alloc packets.\n\n");
- return;
- }
-
- int numReceived = SDLNet_UDP_RecvV(socket, packets);
- if(numReceived == -1){
- error("(in Server::receivePackets()): SDLNet_UDP_RecvV failed: %s.\n\n", SDLNet_GetError());
- return;
- }
-
- for(int i=0;i<numReceived;i++){
- if(packets[i]->data[0] != NETWORK_FWP_PACKET_ID){
- warn("(in Server::receivePackets()): Received unknown packet.\n\n");
- continue;
- }
- handlePacket(packets[i]);
- }
-
- SDLNet_FreePacketV(packets);
- }
-
- void Server::handlePacket(UDPpacket* packet){
- // printf("Server::handlePacket(): received packet of type %i.\n", packet->data[1]);
-
- switch(packet->data[1]){
- case PACKET_TYPE_PING:
- // log("Server::handlePacket(): Received ping packet.\n");
- handlePing(packet);
- break;
-
- case PACKET_TYPE_SERVERINFO_REQUEST:
- // log("Server::handlePacket(): Received serverinfo request.\n");
- handleServerinfoRequest(packet);
- break;
-
- case PACKET_TYPE_PLAYERINFO_REQUEST:
- // log("Server::handlePacket(): Received playerinfo request.\n");
- // handlePlayerinfoRequest(packet);
- break;
-
- case PACKET_TYPE_CONNECTION_REQUEST:
-
- // log("Server::handlePacket(): Received connection request.\n");
- handleConnectionRequest(packet);
- break;
-
- case PACKET_TYPE_DISCONNECT:
- // log("Server::handlePacket(): Received disconnect packet.\n");
- handleDisconnect(packet);
- break;
-
- case PACKET_TYPE_CHAT_MESSAGE:
- // log("Server::handlePacket(): Received chatMessage packet.\n");
- handleChatMessage(packet);
- break;
-
- case PACKET_TYPE_VOICE_MESSAGE:
- // log("Server::handlePacket(): Received voiceMessage packet.\n");
- handleVoiceMessage(packet);
- break;
-
- case PACKET_TYPE_CLIENTSTATE:
- // log("Server::handlePacket(): Received clientstate packet.\n");
- handleClientstate(packet);
- break;
-
- case PACKET_TYPE_CLIENT_SPAWN:
- // log("Server::handlePacket(): Received clientSpawn packet.\n");
- handleClientSpawn(packet);
- break;
-
- case PACKET_TYPE_CLIENT_KILL:
- // log("Server::handlePacket(): Received clientKill packet.\n");
- handleClientKill(packet);
- break;
-
- case PACKET_TYPE_SHOT_SPAWN:
- // log("Server::handlePacket(): Received ShotSpawn packet.\n");
- handleShotSpawn(packet);
- break;
-
- default:
- warn("Server::handlePacket(): Received packet of unknown type. Ignoring.\n");
- break;
- }
- }
-
- void Server::emptyPacketQueue(){
- int numLoops = 0;
- int numReceived = 0;
-
- // receive packets
- do{
- UDPpacket** packets = SDLNet_AllocPacketV(NETWORK_MAX_PACKETS_PER_FRAME, NETWORK_MAX_PACKET_SIZE);
- if(packets == NULL){
- error("(in Server::receivePackets()): Unable to alloc packets.\n\n");
- return;
- }
-
- numReceived = SDLNet_UDP_RecvV(socket, packets);
- if(numReceived == -1){
- error("(in Server::emptyPacketQueue()): SDLNet_UDP_RecvV failed: %s.\n\n", SDLNet_GetError());
- return;
- }
- SDLNet_FreePacketV(packets);
-
- numLoops++;
- }while(numReceived > 0 && numLoops < 10);
-
- }
-
- void Server::handlePing(UDPpacket* packet){
- pingPacket_t pp;
- if( !PacketHandler::unwrapPacket(packet, &pp, sizeof(pp)) ){
- warn("(in Server::handlePing()): Couldn't unwrap packet. Ignoring.\n\n");
- return;
- }
-
- if( clients[pp.clientId] == NULL ){
- warn("(in Server::handlePing()): Received ping packet from unknown source. Ignoring.\n\n");
- return;
- }
-
- clients[pp.clientId]->lastPingMillis = SDL_GetTicks();
- clients[pp.clientId]->ci.ping = (short)( clients[pp.clientId]->lastPingMillis - this->lastPingMillis );
- }
-
- void Server::handleServerinfoRequest(UDPpacket* packet){
- serverinfoRequestPacket_t sir;
- serverinfoPacket_t si;
-
- if( !PacketHandler::unwrapPacket(packet, &sir, sizeof(sir)) ){
- warn("(in Server::handleServerinfoRequest()): Couldn't unwrap packet. Ignoring.\n\n");
- return;
- }
-
- // printf("address: %d:%d\n", packet->address.host, packet->address.port);
-
- si = this->si;
-
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_SERVERINFO, packet->address, &si, sizeof(si));
- if( !Network::sendAndFreePacket(socket, p) ){
- error("(in Server::handleServerinfoRequest()): Couldn't send packet.\n\n");
- return;
- }
- // printf("p->len: %i\n", p->len);
-
- // log("Serverinfo send.\n");
-
- }
-
- void Server::handleConnectionRequest(UDPpacket* packet){
- connectionRequestPacket_t cr;
-
- if( !PacketHandler::unwrapPacket(packet, &cr, sizeof(cr)) ){
- warn("(in Server::handleConnectionRequest()): Couldn't unwrap packet. Ignoring.\n\n");
- return;
- }
-
- if( getClientByPacket(packet) != NULL ){
- warn("(in Server::handleConnectionRequest()): Client already connected. Ignoring request.\n\n");
- return;
- }
-
- if(!hasFreeSlots()){ // server is full
- connectionRequestDeclinedPacket_t cd;
- strcpy(cd.reason, "server is full");
-
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_CONNECTION_REQUEST_DECLINED, packet->address, &cd, sizeof(cd));
- if( !Network::sendPacket(socket, p) ){
- error("(in Server::handleConnectionRequest()): Couldn't send packet.\n\n");
- SDLNet_FreePacket(p);
- return;
- }
- SDLNet_FreePacket(p);
-
- log("Declined connection request from '%s' (%s).\n", cr.name, cd.reason);
-
- }else if(cr.protocolVersion != NETWORK_PROTOCOL_VERSION){ // wrong protocol version
- connectionRequestDeclinedPacket_t cd;
- strcpy(cd.reason, "wrong protocol version");
-
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_CONNECTION_REQUEST_DECLINED, packet->address, &cd, sizeof(cd));
- if( !Network::sendPacket(socket, p) ){
- error("(in Server::handleConnectionRequest()): Couldn't send packet.\n\n");
- SDLNet_FreePacket(p);
- return;
- }
- SDLNet_FreePacket(p);
-
- log("Declined connection request from '%s' (%s).\n", cr.name, cd.reason);
-
- }else if( Game::info.var.useArenaCycle
- && SDL_GetTicks() + 60000 > Game::arenaCycle.playingSinceMillis + Game::arenaCycle.arenaCycleElements[Game::arenaCycle.currentArena].durationMillis ){ // arena change is imminent (60s)
- connectionRequestDeclinedPacket_t cd;
- strcpy(cd.reason, "arena change is imminent");
-
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_CONNECTION_REQUEST_DECLINED, packet->address, &cd, sizeof(cd));
- if( !Network::sendPacket(socket, p) ){
- error("(in Server::handleConnectionRequest()): Couldn't send packet.\n\n");
- SDLNet_FreePacket(p);
- return;
- }
- SDLNet_FreePacket(p);
-
- log("Declined connection request from '%s' (%s).\n", cr.name, cd.reason);
- }else{ // accept connection
- connectionRequestAcceptedPacket_t ca;
-
- // make new client and fill ca part
- Client* c = new Client();
- c->ipAddress.host = packet->address.host;
- c->ipAddress.port = packet->address.port;
- checkClientName(cr.name, ca.newName);
- c->setName(ca.newName);
- c->clientId = addClient(c);
- ca.clientId = c->clientId;
- // c->team = addClientToTeam(c, GAME_TEAM_SPECTATORS);
-
- // fill pi
- for(int i=0;i<si.maxClients;i++){
- if(clients[i] != NULL){
- ca.pi.clientIds[i] = i;
- ca.pi.ci[i] = clients[i]->ci;
- }else{
- ca.pi.clientIds[i] = -1;
- }
- }
-
- // fill si
- ca.si = this->si;
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_CONNECTION_REQUEST_ACCEPTED, packet->address, &ca, sizeof(ca));
- if(!Network::sendPacket(socket, p)){
- error("(in Server::handleConnectionRequest()): Couldn't send packet.\n\n");
- SDLNet_FreePacket(p);
- return;
- }
- SDLNet_FreePacket(p);
-
- log("Accepted connection request from %s.\n", c->ci.name);
-
-
- // inform the other clients!!!
- clientConnectedPacket_t cc;
- cc.clientId = ca.clientId;
- cc.ci = c->ci;
-
- UDPpacket* p2 = PacketHandler::wrapPacket(PACKET_TYPE_CLIENT_CONNECTED, packet->address, &cc, sizeof(cc));
- if( !sendToAllOtherRemoteClients(c, p2) ){
- error("(in Server::handleConnectionRequest()): Couldn't send packet.\n\n");
- SDLNet_FreePacket(p2);
- return;
- }
- SDLNet_FreePacket(p2);
-
- log("'%s' connected.\n", c->ci.name);
- }
- }
-
- void Server::handleDisconnect(UDPpacket* packet){
- disconnectPacket_t d;
-
- if( !PacketHandler::unwrapPacket(packet, &d, sizeof(d)) ){
- warn("(in Server::handleDisconnect()): Couldn't unwrap packet. Ignoring.\n\n");
- return;
- }
-
-
- Client* c = getClientByPacket(packet);
-
- if(c == NULL || clients[d.clientId] != c){
- warn("(in Server::handleDisconnect()): Received disconnect packet from unknown source. Ignoring.\n\n");
- return;
- }
-
- if( c->vehicle != NULL ){
- Game::unspawnVehicle(c->vehicle);
- }
-
- // inform the other clients
- clientDisconnectedPacket_t cd;
- cd.clientId = d.clientId;
- strcpy(cd.reason, "Client disconnected");
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_CLIENT_DISCONNECTED, packet->address, &cd, sizeof(cd));
- if( !sendToAllOtherRemoteClients(c, p) ){
- error("(in Server::handleDisconnect()): Couldn't send packet.\n\n");
- SDLNet_FreePacket(p);
- return;
- }
- SDLNet_FreePacket(p);
-
- log("'%s' disconnected.\n", c->ci.name);
-
- removeClient(c);
- }
-
-
- void Server::handleChatMessage(UDPpacket* packet){
- chatMessagePacket_t cm;
-
- if( !PacketHandler::unwrapPacket(packet, &cm, sizeof(cm)) ){
- warn("(in Server::handleChatMessage()): Couldn't unwrap packet. Ignoring.\n\n");
- return;
- }
-
- if( Network::server->clients[cm.clientId] == NULL ){
- warn("(in Server::handleChatMessage()): Received chat message from unknown client. Ignoring.\n\n");
- return;
- }
-
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_CHAT_MESSAGE, packet->address, &cm, sizeof(cm));
- for(int i=0;i<si.maxClients;i++){
- if(clients[i] != NULL){
- if( clients[i]->vehicle == NULL && clients[cm.clientId]->vehicle != NULL
- || clients[i]->vehicle != NULL && clients[cm.clientId]->vehicle == NULL ){
- continue;
- }
- if( cm.mode == GAME_CHAT_MODE_TEAM ){
- if( clients[i]->ci.team != clients[cm.clientId]->ci.team )
- continue;
- }
- packet->address.host = clients[i]->ipAddress.host;
- packet->address.port = clients[i]->ipAddress.port;
- if( !SDLNet_UDP_Send(socket, -1, packet) ){
- warn("(in Server::handleChatMessage()): SDLNet_UDP_Send() failed: %s.\n\n", SDLNet_GetError());
- }
- }
- }
- SDLNet_FreePacket(p);
- // log("Server: Send chatMessage.\n");
- }
-
- void Server::handleVoiceMessage(UDPpacket* packet){
- voiceMessagePacket_t vm;
-
- if( !PacketHandler::unwrapPacket(packet, &vm, sizeof(vm)) ){
- warn("(in Server::handleVoiceMessage()): Couldn't unwrap packet. Ignoring.\n\n");
- return;
- }
-
- if( Network::server->clients[vm.clientId] == NULL ){
- warn("(in Server::handleVoiceMessage()): Received voice message from unknown client. Ignoring.\n\n");
- return;
- }
-
- if( vm.messageId < 0 || vm.messageId >= GAME_NUM_VOICE_MESSAGES ){
- warn("(in Server::handleVoiceMessage()): MessageId out of bounds.\n\n");
- return;
- }
-
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_VOICE_MESSAGE, packet->address, &vm, sizeof(vm));
- for(int i=0;i<si.maxClients;i++){
- if(clients[i] != NULL){
- if( clients[i]->vehicle == NULL && clients[vm.clientId]->vehicle != NULL
- || clients[i]->vehicle != NULL && clients[vm.clientId]->vehicle == NULL ){
- continue;
- }
- if( vm.mode == GAME_CHAT_MODE_TEAM ){
- if( clients[i]->ci.team != clients[vm.clientId]->ci.team )
- continue;
- }
- packet->address.host = clients[i]->ipAddress.host;
- packet->address.port = clients[i]->ipAddress.port;
- if( !SDLNet_UDP_Send(socket, -1, packet) ){
- warn("(in Server::handleVoiceMessage()): SDLNet_UDP_Send() failed: %s.\n\n", SDLNet_GetError());
- }
- }
- }
- SDLNet_FreePacket(p);
-
- }
-
-
- void Server::handleClientstate(UDPpacket* packet){
- // log("Received clientstate.\n");
- clientstatePacket_t cs;
-
- if( !PacketHandler::unwrapPacket(packet, &cs, sizeof(cs)) ){
- warn("(in Server::handleClientstate()): Couldn't unwrap packet. Ignoring.\n\n");
- return;
- }
-
- Client* c = getClientByPacket(packet);
- if( c == NULL ){
- warn("(in Server::handleClientstate()): Received clientstate from unknown client. Ignoring.\n\n");
- return;
- }
-
- if( c->vehicle != NULL ){
- vectorCopy3d(cs.pos, c->cs.pos);
- vectorCopy3d(cs.vel, c->cs.vel);
- vectorCopy3d(cs.dir, c->cs.dir);
- vectorCopy3d(cs.up, c->cs.up);
- c->cs.energy = cs.energy;
-
- vectorCopy3d(cs.pos, c->vehicle->pos);
- vectorCopy3d(cs.vel, c->vehicle->vel_inp);
- vectorCopy3d(cs.dir, c->vehicle->dir);
- vectorCopy3d(cs.up, c->vehicle->up);
- c->vehicle->energy = cs.energy;
- }else{
- c->cs = cs;
- c->cs.armor = 0;
- c->cs.energy = 0;
- }
- }
-
-
- void Server::handleClientSpawn(UDPpacket* packet){
- // log("Received client spawn.\n");
- clientSpawnPacket_t cs;
-
- if( !PacketHandler::unwrapPacket(packet, &cs, sizeof(cs)) ){
- warn("(in Server::handleClientSpawn()): Couldn't unwrap packet. Ignoring.\n\n");
- return;
- }
-
- Client* c = getClientByPacket(packet);
- if( c == NULL ){
- warn("(in Server::handleClientSpawn()): Received spawn request from unknown client. Ignoring.\n\n");
- return;
- }
- if( cs.clientId < 0 || cs.clientId >= si.maxClients || c != clients[cs.clientId] ){
- warn("(in Server::handleClientSpawn()): Received spawn request with invalid clientId. Ignoring.\n\n");
- return;
- }
-
-
- // check values
- int newTeam = 0;
- if( Game::info.var.mode == GAME_MODE_DEATHMATCH /*|| Game::info.var.mode == GAME_MODE_SOLE_SURVIVOR*/ ){
- newTeam = cs.ci.team == 0 ? 0 : 1; // allow only spectators and players in deathmatch/ss games
- }else{
- if( cs.ci.team == GAME_TEAM_PLAYERS ){ // this means auto-join
- newTeam = frand() < 0.5f ? GAME_TEAM_RED : GAME_TEAM_BLUE;
- }else{
- newTeam = cs.ci.team;
- }
- }
- if( c->ci.team != newTeam || newTeam == GAME_TEAM_SPECTATORS ){ // log change team + reset score etc.
- log("%s joined %s.\n", cs.ci.name, Game::getTeamName(newTeam) );
- c->ci.score = 0;
- c->ci.kills = 0;
- c->ci.deaths = 0;
- }
-
- c->ci.team = newTeam;
- c->ci.vehicle = cs.ci.vehicle;
- c->ci.weapon1 = cs.ci.weapon1;
- c->ci.weapon2 = cs.ci.weapon2;
- c->ci.weapon3 = cs.ci.weapon3;
- c->ci.weapon4 = cs.ci.weapon4;
-
- vectorInit3d(0.0f, 0.0f, 0.0f, c->cs.pos);
- Game::findSpawnpointForClient(c);
-
- if( c == localClient ){
- // UPDATE GAME CVARS!!!!
- Game::info.var.player_team = c->ci.team;
- Game::info.cvar.game_player_team->setVal(c->ci.team); // THINKABOUTME: to avoid respawns caused by changing teams
- Game::info.var.player_vehicle = c->ci.vehicle;
- Game::info.var.player_weapon1 = c->ci.weapon1;
- Game::info.var.player_weapon2 = c->ci.weapon2;
- Game::info.var.player_weapon3 = c->ci.weapon3;
- Game::info.var.player_weapon4 = c->ci.weapon4;
- }
-
- if( c->vehicle != NULL ){
- Game::unspawnVehicle(c->vehicle);
- }
- Game::spawnVehicle(c);
-
- if( c->ci.team != GAME_TEAM_SPECTATORS ){ // update cs and vehicle armor / energy
- c->vehicle->armor = c->cs.armor = c->vehicle->maxArmor;
- c->vehicle->energy = c->cs.energy = c->vehicle->maxEnergy;
- // log("%s has spawned for %s with a %s.\n", c->ci.name, Game::getTeamName(c->ci.team), Game::getVehicleName(c->ci.vehicle) );
- }else{
- c->cs.armor = 0;
- c->cs.energy = 0;
- }
-
- // copy to packet
- cs.ci = c->ci;
- cs.cs = c->cs;
-
- // send the packet to all remote clients
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_CLIENT_SPAWN, this->ipAddress, &cs, sizeof(cs));
- if( !sendToAllRemoteClients(p) ){
- error("(in Server::handleClientSpawn()): Couldn't send packet.\n\n");
- SDLNet_FreePacket(p);
- return;
- }
- SDLNet_FreePacket(p);
-
- }
-
- void Server::handleClientKill(UDPpacket* packet){
- clientKillPacket_t ck;
-
- if( !PacketHandler::unwrapPacket(packet, &ck, sizeof(ck)) ){
- warn("(in Server::handleClientKill()): Couldn't unwrap packet. Ignoring.\n\n");
- return;
- }
-
- Client* killedClient = clients[ck.killedClientId];
- Client* killerClient = clients[ck.killerClientId];
- if( killedClient == NULL ){
- warn("(in Server::handleClientKill()): Received client kill packet with invalid killedClientId. Ignoring.\n\n");
- return;
- }
- if( killerClient == NULL ){ // May have disconnected
- warn("(in Server::handleClientKill()): Received client kill packet with invalid killerClientId.\n\n");
- // return;
- }
-
- if( ck.weapon == -1 ){ //
- warn("(in Server::handleClientKill()): Received AdminKill-Request from remote Client. Ignoring\n\n");
- return;
- }
-
- // tell the others
- sendClientKill(ck.killedClientId, ck.killerClientId, ck.weapon);
-
- Game::killClient(killedClient, killerClient, ck.weapon);
-
- }
-
- void Server::handleShotSpawn(UDPpacket* packet){
- shotSpawnPacket_t ss;
-
- if( !PacketHandler::unwrapPacket(packet, &ss, sizeof(ss)) ){
- warn("(in Server::handleShotSpawn()): Couldn't unwrap packet. Ignoring.\n\n");
- return;
- }
-
- if( clients[ss.clientId] == NULL ){
- warn("(in Server::handleShotSpawn()): Received ShotSpawnPacket from unknown client. Ignoring.\n\n");
- return;
- }
-
- if( clients[ss.clientId]->vehicle == NULL ){
- warn("(in Server::handleShotSpawn()): Received ShotSpawnPacket from dead client. Ignoring.\n\n");
- return;
- }
-
- Game::spawnShot(&ss);
-
- UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_SHOT_SPAWN, packet->address, &ss, sizeof(ss));
- if( !sendToAllRemoteClients(p) ){
- warn("(in Server::handleShotSpawn()): Couldn't send packet.\n\n");
- SDLNet_FreePacket(p);
- return;
- }
-
- }
-