Logo Search packages:      
Sourcecode: castle-combat version File versions

server.c

#include "SDL_net/SDL_net.h"
#include "netdefs.h"
#include "stdlib.h"

//#define DEBUG

#define OUT stdout
#define NET_MAXPEOPLE 9
#define NET_BYE 255

static TCPsocket servsock = NULL;
static SDLNet_SocketSet socketset = NULL;
static struct {
      int active,ReadyForStart,ReadyForEnd;
      TCPsocket sock;
      IPaddress peer;
      Uint8 name[256+1];
} people[NET_MAXPEOPLE];
char PlayerFree[NET_MAXPEOPLE],PlayersOnThisClient[NET_MAXPEOPLE],ServerPlayerNum,ServerConquer,
     GameStarted=0,PlayersJoined=0,ClientsJoined=0,Name[NET_MAXPEOPLE][100],
     PlayerNamesSent=0;

void RemovePlayer(int which)
{
    PlayersOnThisClient[which] = 0;
    PlayerFree[which] = 1;
    people[which].ReadyForEnd = 0;
    PlayersJoined--;
    people[which].sock = NULL;
    printf("\t\t Server: (--) Removing Player %d.\n",which);
}

void HandleServer(void)
{
      TCPsocket newsock;
      int which;
      unsigned char data;

      newsock = SDLNet_TCP_Accept(servsock);
      if ( newsock == NULL ) {
            return;
      }

      /* Look for unconnected person slot */
      for ( which=0; which<NET_MAXPEOPLE; ++which ) {
            if ( ! people[which].sock ) {
                  break;
            }
      }
      if ( which == NET_MAXPEOPLE ) {
            /* Look for inactive person slot */
            for ( which=0; which<NET_MAXPEOPLE; ++which ) {
                  if ( people[which].sock && ! people[which].active ) {
                        /* Kick them out.. */
                        data = NET_BYE;
                        SDLNet_TCP_Send(people[which].sock, &data, 1);
                        SDLNet_TCP_DelSocket(socketset,
                                    people[which].sock);
                        SDLNet_TCP_Close(people[which].sock);
#ifdef DEBUG
      printf("\t\t Server: Killed inactive socket %d\n", which);
#endif
                        RemovePlayer(which);
                        break;
                  }
            }
      }
      if ( which == NET_MAXPEOPLE ) {
            /* No more room... */
            data = NET_BYE;
            SDLNet_TCP_Send(newsock, &data, 1);
            SDLNet_TCP_Close(newsock);
#ifdef DEBUG
            printf("\t\t Server: Connection refused -- Net full ;-)\n");
#endif
      } else {
            /* Add socket as an inactive person */
            people[which].sock = newsock;
            people[which].peer = *SDLNet_TCP_GetPeerAddress(newsock);
            SDLNet_TCP_AddSocket(socketset, people[which].sock);
#ifdef DEBUG
            printf("\t\t Server: New inactive socket %d\n", which);
#endif
            ClientsJoined++;
      }
}

/* Send a "new client" notification */
void SendNew(int about, int to)
{
    printf("\t\t Server: New Connection: %s (%d)\n", people[about].name, people[about].peer.port);
}

void SendTo( int which, char *data )
{
    if (SDLNet_TCP_Send(people[which].sock, data, data[0]+1) <= 0 ) {
      printf("\t\t Server: Network connection error!");
      exit(1);
    }
}

void HandleClient(int which)
{
      char data[512],send[512],len;
      int i,NumberOfReadyPlayers;

      /* Has the connection been closed? */
      if ( SDLNet_TCP_Recv(people[which].sock, data, 1) <= 0 ) {
#ifdef DEBUG
      printf("\t\t Server: Closing socket %d (was%s active)\n",
                  which, people[which].active ? "" : " not");
#endif
            SDLNet_TCP_DelSocket(socketset, people[which].sock);
            SDLNet_TCP_Close(people[which].sock);
            RemovePlayer(which);
            return;
      } else {
          SDLNet_TCP_Recv(people[which].sock, data, len=data[0]);
          //printf("Data Report: %5d    %5d\n",data[0],data[1]);
          switch (data[0]) {
            case NET_HELLO: {
                /* Yay!  An active connection */
                memcpy(people[which].name,
                  &data[NET_HELLO_NAME], 256);
                people[which].name[256] = 0;
                people[which].ReadyForStart = 0;
                people[which].ReadyForEnd = 0;
#ifdef DEBUG
                printf("\t\t Server: Activating socket %d (%s)\n",
                  which, people[which].name);
#endif                /* Notify about all active clients */
                people[which].active = 1;
                SendNew(0, which);
                if (which==0) {
                  ServerPlayerNum=data[NET_HELLO_PLAYERNUM];
                  ServerConquer=data[NET_HELLO_CONQUER];
                  printf("\t\t Server: ServerPlayerNum is set to %d.\n",ServerPlayerNum);
                }
                send[0]=3;
                send[1]=NET_HELLO;
                send[2]=ServerPlayerNum;
                send[3]=ServerConquer;
                SendTo(which, send);
            }
            break;
            case NET_SELECTION_FINISHED:
            case NET_OTHER_SELECTION:
            case NET_BPLAYER_MOVE: 
            case NET_PLACE_PLAYER_MOVE: 
            case NET_BLOCKGEN: 
            case NET_TURN:
            case NET_PUTBLOCK:
            case NET_PUTCANNON:
            case NET_ADDHOUSE:
              case NET_SHOOT:
            case NET_BATTLE_MOVE:
            case NET_BUTTON2:
            case NET_CLEAN:
            case NET_NEWTANK:
            case NET_TANKMOVE:
            case NET_TANKSHOOT:
            case NET_SYNC_WALL:
            case NET_SYNC_GARBAGE:
            case NET_SYNC_HOUSE:
            case NET_CASTLE_RANDOMIZE:
            {
                send[0] = len+1;
                for ( i=0; i<len; i++ )
                  send[i+1] = data[i];
                i = 0;
                while ( people[i].active ) {
                  if (i != which)
                      SendTo(i, send);
                  i++;
                }
            }
            break;
            case NET_NEWPLAYER: {
                printf("\t\t Server: (++) New Player!\n");
                if (!PlayerFree[NET_MAXPEOPLE-1])
                  printf("\t\t Server: Maximal number of player has been reached. Request denied.\n");
                else {
                  i=0;
                  while (!PlayerFree[i])
                      i++;
            
                  PlayerFree[i]=0;
                  strcpy(Name[i], &data[1]);
                  printf("\t\t Server: Player %d has joined (%s)\n", i, Name[i]);
                  PlayersOnThisClient[which]++;
                  PlayersJoined++;
                  // confirm player
                  send[0] = 2;
                  send[1] = NET_NEWPLAYER;
                  send[2] = i;                  
                  SendTo( which, send);               
                }
            }
            break;
            case NET_ENDGAME: {
                people[which].ReadyForEnd = 1;
                NumberOfReadyPlayers=0;
                for ( i=0; i<NET_MAXPEOPLE; ++i ) {
                  if (people[i].ReadyForEnd) {
                      NumberOfReadyPlayers += PlayersOnThisClient[i];
                      //printf("\t\tServer: +%d Players -> %d total!", PlayersOnThisClient[i], NumberOfReadyPlayers);
                  }
                }
                if (NumberOfReadyPlayers == ServerPlayerNum) {
#ifdef DEBUG
                  printf("\t\t Server: All players are ready.\n");
#endif
                  // waiting finished
                  send[0]=1;
                  send[1]=NET_ENDGAME;
                  i=0;
                  while ( people[i].active ) {
                      SendTo(i, send);
                      people[i].ReadyForEnd = 0;
                      i++;
                  }

                  // send player names
                  if (!PlayerNamesSent) {
                      int player;
                      
                      for (player=0; player<ServerPlayerNum; player++) {
                        send[0] = 3+strlen(Name[player]);
                        send[1] = NET_PLAYERNAME;
                        send[2] = player;
                        strcpy(&send[3], Name[player]);
                        i=0;
                        while ( people[i].active ) {
                            SendTo(i, send);
                            i++;
                        }
                        PlayerNamesSent = 1;
                      }
                  }
                }
            } break;
            default: {
                printf("\t\t Server: Unknown packet type received!\n");
            } break;
          }
      }
}

void ServerCleanUp()
{
      int i;

      for ( i=0; i<NET_MAXPEOPLE; ++i ) {
            if (  people[i].sock != NULL ) {
                  SDLNet_TCP_DelSocket(socketset, people[i].sock);
                  SDLNet_TCP_Close(people[i].sock);
                  people[i].sock = NULL;
            }
            people[i].active = 0;
      }
      if ( servsock != NULL ) {
            SDLNet_TCP_DelSocket(socketset, servsock);
            SDLNet_TCP_Close(servsock);
            servsock = NULL;
      }
      if ( socketset != NULL ) {
            SDLNet_FreeSocketSet(socketset);
            socketset = NULL;
      }
}

int InitServer(int NetworkOpened)
{
      IPaddress serverIP;
      int i;

      GameStarted = 0;
      PlayersJoined = 0;
      PlayerNamesSent = 0;
      
      for ( i=0; i<NET_MAXPEOPLE; ++i ) {
          PlayersOnThisClient[i] = 0;
          PlayerFree[i]=1;
          people[i].ReadyForEnd=0;
      }
            
      if (!NetworkOpened) {
      
          ClientsJoined=0;
          
          /* Initialize SDL */
          if ( SDL_Init(0) < 0 ) {
                printf("\t\t Server: Couldn't initialize SDL: %s\n",SDL_GetError());
                exit(1);
          }
          atexit(SDL_Quit);

          /* Initialize the network */
          if ( SDLNet_Init() < 0 ) {
            printf("\t\t Server: Couldn't initialize net: %s\n",
                                    SDLNet_GetError());
            exit(1);
          }
          atexit(ServerCleanUp);

          /* Allocate the socket set */
          socketset = SDLNet_AllocSocketSet(NET_MAXPEOPLE+1);
          if ( socketset == NULL ) {
            printf("\t\t Server: Couldn't create socket set: %s\n",
                                    SDLNet_GetError());
            exit(2);
          }
            
          /* Create the server socket */
          SDLNet_ResolveHost(&serverIP, NULL, NET_PORT);
          servsock = SDLNet_TCP_Open(&serverIP);
          if ( servsock == NULL ) {
            printf("\t\t Server: Couldn't get server socket: %s\n",
                                    SDLNet_GetError());
            printf("\t\t Server: Waiting for socket.\n");
            while ( servsock == NULL ) {
                SDL_Event event;
                
                servsock = SDLNet_TCP_Open(&serverIP);
                SDL_Delay(10);
                SDL_PollEvent(&event);
                if (event.key.keysym.sym == SDLK_ESCAPE)
                  return 1;
            }
            printf("\t\t Server: Got socket!\n");
          }
          SDLNet_TCP_AddSocket(socketset, servsock);
      }
      
      /* Initialize the channels */
      for ( i=0; i<NET_MAXPEOPLE; ++i ) {
            people[i].active = 0;
            people[i].sock = NULL;
      }

      printf("\t\t Server: ** Server started **\n");
      return 0;
}

void ServerLoop()
{
      int i;
            
      /* Wait for events */
      SDLNet_CheckSockets(socketset, 0);

      /* Check for new connections */
      if ( SDLNet_SocketReady(servsock) ) {
            HandleServer();
      }

      /* Check for events on existing clients */
      for ( i=0; i<NET_MAXPEOPLE; ++i ) {
            if ( SDLNet_SocketReady(people[i].sock) ) {
                  HandleClient(i);
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index