Began implementation of networking
authorSam Moore <matches@ucc.asn.au>
Wed, 18 Jan 2012 15:48:36 +0000 (23:48 +0800)
committerSam Moore <matches@ucc.asn.au>
Wed, 18 Jan 2012 15:48:36 +0000 (23:48 +0800)
Slightly confused about the client/server thing

Server is going to run red
Client is going to run blue

Need to get them to talk nicely?

Doesn't work at the moment - server can't bind socket, client segfaults (NULL pointer).
Blergh.

judge/manager/Makefile
judge/manager/game.cpp
judge/manager/game.h
judge/manager/main.cpp
judge/manager/network_controller.cpp [new file with mode: 0644]
judge/manager/network_controller.h [new file with mode: 0644]

index 6a35950..199a3af 100644 (file)
@@ -4,8 +4,10 @@
 #LIBRARIES = -lSDL -lGL -lpthread
 #Use this to build without graphics
 LIBRARIES = -lpthread
+#Use this on Mac OSX (Thanks spartan)
+#LIBRARIES = -I/opt/local/include/ -L/opt/local/lib/ -lSDL -framework OpenGL -lpthread
 CPP = g++ -Wall -pedantic -g
-OBJ = main.o controller.o ai_controller.o human_controller.o program.o thread_util.o stratego.o graphics.o game.o
+OBJ = main.o controller.o network_controller.o ai_controller.o human_controller.o program.o thread_util.o stratego.o graphics.o game.o
 
 BIN = stratego
 
index 8d3eef0..92dc71a 100644 (file)
@@ -7,7 +7,7 @@ using namespace std;
 Game* Game::theGame = NULL;
 bool Game::gameCreated = false;
 
-Game::Game(const char * redPath, const char * bluePath, const bool enableGraphics, double newStallTime, const bool allowIllegal, FILE * newLog, const  Piece::Colour & newReveal, int newMaxTurns, bool newPrintBoard, double newTimeoutTime) : red(NULL), blue(NULL), turn(Piece::RED), theBoard(10,10), graphicsEnabled(enableGraphics), stallTime(newStallTime), allowIllegalMoves(allowIllegal), log(newLog), reveal(newReveal), turnCount(0), input(NULL), maxTurns(newMaxTurns), printBoard(newPrintBoard), timeoutTime(newTimeoutTime)
+Game::Game(const char * redPath, const char * bluePath, const bool enableGraphics, double newStallTime, const bool allowIllegal, FILE * newLog, const  Piece::Colour & newReveal, int newMaxTurns, bool newPrintBoard, double newTimeoutTime, bool server, bool client) : red(NULL), blue(NULL), turn(Piece::RED), theBoard(10,10), graphicsEnabled(enableGraphics), stallTime(newStallTime), allowIllegalMoves(allowIllegal), log(newLog), reveal(newReveal), turnCount(0), input(NULL), maxTurns(newMaxTurns), printBoard(newPrintBoard), timeoutTime(newTimeoutTime)
 {
        gameCreated = false;
        if (gameCreated)
@@ -25,16 +25,33 @@ Game::Game(const char * redPath, const char * bluePath, const bool enableGraphic
                        Graphics::Initialise("Stratego", theBoard.Width()*32, theBoard.Height()*32);
        #endif //BUILD_GRAPHICS
 
-       if (strcmp(redPath, "human") == 0)
-               red = new Human_Controller(Piece::RED, graphicsEnabled);
+
+       if (client)
+       {
+               red = new Client(Piece::RED, "server", redPath); //TODO: Retrieve server address
+       }
        else
-               red = new AI_Controller(Piece::RED, redPath, timeoutTime);
+       {
+               assert(redPath != NULL);
+               if (strcmp(redPath, "human") == 0)
+                       red = new Human_Controller(Piece::RED, graphicsEnabled);
+               else
+                       red = new AI_Controller(Piece::RED, redPath, timeoutTime);
+       }
        
        
-       if (strcmp(bluePath, "human") == 0)
-               blue = new Human_Controller(Piece::BLUE, graphicsEnabled);
+       if (server)
+       {
+               blue = new Server(Piece::BLUE, "client");
+       }
        else
-               blue = new AI_Controller(Piece::BLUE, bluePath, timeoutTime);
+       {
+               assert(bluePath != NULL);
+               if (strcmp(bluePath, "human") == 0)
+                       blue = new Human_Controller(Piece::BLUE, graphicsEnabled);
+               else
+                       blue = new AI_Controller(Piece::BLUE, bluePath, timeoutTime);
+       }
 
 
 }
index 2ed35f6..cc79e65 100644 (file)
@@ -4,6 +4,7 @@
 #include "stratego.h"
 #include "ai_controller.h"
 #include "human_controller.h"
+#include "network_controller.h"
 #include <cstring>
 
 
@@ -14,7 +15,7 @@
 class Game
 {
        public:
-               Game(const char * redPath, const char * bluePath, const bool enableGraphics, double newStallTime = 1.0, const bool allowIllegal=false, FILE * newLog = NULL, const Piece::Colour & newRevealed = Piece::BOTH, int maxTurns = 5000, const bool printBoard = false, double newTimeoutTime = 2.0);
+               Game(const char * redPath, const char * bluePath, const bool enableGraphics, double newStallTime = 1.0, const bool allowIllegal=false, FILE * newLog = NULL, const Piece::Colour & newRevealed = Piece::BOTH, int maxTurns = 5000, const bool printBoard = false, double newTimeoutTime = 2.0, bool server=false, bool client=false);
                Game(const char * fromFile, const bool enableGraphics, double newStallTime = 1.0, const bool allowIllegal=false, FILE * newLog = NULL, const Piece::Colour & newRevealed = Piece::BOTH, int maxTurns = 5000, const bool printBoard = false, double newTimeoutTime = 2.0);
                virtual ~Game();
 
index ce4cd20..83b3c63 100644 (file)
@@ -64,6 +64,7 @@ Piece::Colour SetupGame(int argc, char ** argv)
 {
        char * red = NULL; char * blue = NULL; double stallTime = 0.0; bool graphics = false; bool allowIllegal = false; FILE * log = NULL;
        Piece::Colour reveal = Piece::BOTH; char * inputFile = NULL; int maxTurns = 5000; bool printBoard = false; double timeoutTime = 2.0;
+       bool server = false; bool client = false;
        for (int ii=1; ii < argc; ++ii)
        {
                if (argv[ii][0] == '-')
@@ -184,6 +185,26 @@ Piece::Colour SetupGame(int argc, char ** argv)
                                                system("less manual.txt");
                                                exit(EXIT_SUCCESS);
                                        }
+                                       else if (strcmp(argv[ii]+2, "server") == 0)
+                                       {
+                                               if (client == true)
+                                               {
+                                                       fprintf(stderr, "ARGUMENT_ERROR - Can't be both a server and a client!\n");
+                                                       exit(EXIT_FAILURE);
+                                               }
+                                               server = true;
+                                               
+                                       }
+                                       else if (strcmp(argv[ii]+2, "client") == 0)
+                                       {
+                                               if (server == true)
+                                               {
+                                                       fprintf(stderr, "ARGUMENT_ERROR - Can't be both a server and a client!\n");
+                                                       exit(EXIT_FAILURE);
+                                               }
+                                               client = true;  
+                                               
+                                       }
                                        else
                                        {
                                                fprintf(stderr, "ARGUMENT_ERROR - Unrecognised switch \"%s\"...\n", argv[ii]);
@@ -211,15 +232,34 @@ Piece::Colour SetupGame(int argc, char ** argv)
 
        if (inputFile == NULL)
        {
-               if (red == NULL || blue == NULL) //Not enough arguments
+               if (server)  
+               {
+                       if (red != NULL && blue != NULL)
+                       {
+                               fprintf(stderr, "ARGUMENT_ERROR - When using the --server switch, only supply ONE (1) player.\n");
+                               exit(EXIT_FAILURE);
+                       }
+               }
+               else if (red == NULL || blue == NULL) //Not enough players
                {
                        fprintf(stderr, "ARGUMENT_ERROR - Did not recieve enough players (did you mean to use the -f switch?)\n");      
                        exit(EXIT_FAILURE);     
                }
-               Game::theGame = new Game(red,blue, graphics, stallTime, allowIllegal,log, reveal,maxTurns, printBoard, timeoutTime);
+               
+               if (client)
+               {
+                       blue = red; red = NULL;
+               }
+
+               Game::theGame = new Game(red,blue, graphics, stallTime, allowIllegal,log, reveal,maxTurns, printBoard, timeoutTime, server, client);
        }
        else
        {
+               if (server || client)
+               {
+                       fprintf(stderr, "ARGUMENT_ERROR - The -f switch is incompatable with the --server or --client switches!\n");
+                       exit(EXIT_FAILURE);
+               }
                Game::theGame = new Game(inputFile, graphics, stallTime, allowIllegal,log, reveal,maxTurns, printBoard, timeoutTime);
        }
 
diff --git a/judge/manager/network_controller.cpp b/judge/manager/network_controller.cpp
new file mode 100644 (file)
index 0000000..aed27b7
--- /dev/null
@@ -0,0 +1,102 @@
+#include "network_controller.h"
+
+NetworkController::NetworkController(const Piece::Colour & newColour, const char * newName) : Controller(newColour, newName), sfd(-1)
+{
+       struct protoent * tcp = getprotobyname("tcp");
+       sfd = socket(PF_INET, SOCK_STREAM, tcp->p_proto);
+       if (sfd == -1)
+       {
+               fprintf(stderr, "NetworkController::NetworkController - couldn't create a TCP socket!");
+               return;
+       }
+}
+
+NetworkController::~NetworkController()
+{
+       if (Valid())
+       {
+               if (shutdown(sfd, SHUT_RDWR) == -1)
+               {
+                       fprintf(stderr, "NetworkController::~NetworkController - Can't shutdown socket %d!", sfd);
+                       close(sfd);
+                       sfd = -1;
+               }
+       }
+       close(sfd);
+}
+
+Server::Server(const Piece::Colour & newColour, const char * newName) : NetworkController(newColour, newName)
+{
+       struct sockaddr_in ipa;
+       ipa.sin_family = AF_INET;
+       ipa.sin_port = htons(NetworkController::port);  
+       ipa.sin_addr.s_addr = INADDR_ANY;
+       memset(&ipa,0, sizeof ipa);
+
+       if (bind(sfd, (struct sockaddr*)&sfd, sizeof sfd) == -1)
+       {
+               fprintf(stderr, "Server::Server - Couldn't bind to socket! Abort\n");
+               close(sfd);
+               sfd = -1;
+               return;
+       }
+
+       //Listen for at most 1 connection
+       if (listen(sfd, 1) == -1)
+       {
+               fprintf(stderr, "Server::Server - listening failed.\n");
+               close(sfd);
+               sfd = -1;
+               return;
+       }       
+
+       //Accept the connection
+       sfd = accept(sfd, NULL, NULL);
+       if (sfd < 0)
+       {
+               fprintf(stderr, "Server::Server - couldn't accept connection.\n");
+               close(sfd);
+               sfd = -1;
+               return;
+       }
+
+       //We are now ready to play!
+}
+
+
+Client::Client(const Piece::Colour & newColour, const char * newName, const char * server) : NetworkController(newColour, newName)
+{
+       struct sockaddr_in ipa;
+       ipa.sin_family = AF_INET;
+       ipa.sin_port = htons(NetworkController::port);  
+       int Res = inet_pton(AF_INET, server, &ipa.sin_addr);
+
+       if (Res < 0)
+       {
+               fprintf(stderr, "Client::Client - First parameter is not a valid address family!\n");
+               close(sfd);
+               sfd = -1;
+               return;
+       }
+       else if (Res == 0)
+       {
+               fprintf(stderr, "Client::Client - Second parameter does not contain a valid IP Address!\n");
+               close(sfd);
+               sfd = -1;
+               return;
+       }
+       
+       if (connect(sfd, (struct sockaddr*)&sfd, sizeof sfd) == -1)
+       {
+               fprintf(stderr, "Client::Client - Connection to server at \"%s\" failed.\n", server);
+               close(sfd);
+               sfd = -1;
+               return;
+       }
+
+       //We are now ready to play!
+}
+//EOF
+
+
diff --git a/judge/manager/network_controller.h b/judge/manager/network_controller.h
new file mode 100644 (file)
index 0000000..cf80a80
--- /dev/null
@@ -0,0 +1,53 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <fcntl.h>
+
+
+
+#include "controller.h"
+
+#ifndef NETWORK_CONTROLLER_H
+#define NETWORK_CONTROLLER_H
+
+
+class NetworkController : public Controller
+{
+       public:
+               NetworkController(const Piece::Colour & newColour, const char * newName = "no-name");
+               virtual ~NetworkController();
+
+               virtual bool Valid() {return sfd != -1;}
+
+               virtual void Message(const char * string) {fprintf(stderr, "NetworkController unimplemented!\n"); assert(false);}
+               virtual MovementResult QuerySetup(const char * opponentName, std::string setup[]) {fprintf(stderr, "NetworkController unimplemented!\n"); assert(false);}
+               virtual MovementResult QueryMove(std::string & buffer) {fprintf(stderr, "NetworkController unimplemented!\n"); assert(false);}
+
+       protected:
+               int sfd; int cfd;
+               static const int port = 666;    
+};
+
+class Server : public NetworkController
+{
+       public:
+               Server(const Piece::Colour & newColour, const char * newName = "no-name");
+               virtual ~Server() {}
+};
+
+class Client : public NetworkController
+{
+       public:
+               Client(const Piece::Colour & newColour, const char * newName = "no-name", const char * server="127.0.0.1");
+               virtual ~Client() {}
+};
+
+#endif //NETWORK_CONTROLLER_H
+
+//EOF

UCC git Repository :: git.ucc.asn.au