diff --git a/JGE/include/JNetwork.h b/JGE/include/JNetwork.h index 7dc1c8fe1..547678678 100644 --- a/JGE/include/JNetwork.h +++ b/JGE/include/JNetwork.h @@ -6,47 +6,41 @@ #include "JGE.h" #include +#include using namespace std; +class JSocket; +#include +#include +#include "Threading.h" -class JNetwork{ +typedef void(*processCmd)(istream&, ostream&); + +class JNetwork { private: - static JNetwork * mInstance; - static int connected_to_ap; - + int connected_to_ap; + JSocket* socket; + boost::mutex sendMutex; + boost::mutex receiveMutex; + stringstream received; + stringstream toSend; + static map sCommandMap; + public: - static string error; JNetwork(); - static JNetwork * GetInstance(); - static void EndInstance(); - static string serverIP; - int receive(char * buffer, int length); - int send(char * buffer, int length); + ~JNetwork(); + string serverIP; + int connect(string serverIP = ""); - static int isConnected(); -#if defined (WIN32) - static int net_thread(void* param); -#elif defined (LINUX) - static void* net_thread(void* param); -#else + bool isConnected(); + static void ThreadProc(void* param); +#if !defined (WIN32) && !defined (LINUX) static int connect_to_apctl(int config); #endif + bool sendCommand(string command); + static void registerCommand(string command, processCmd processCommand, processCmd processResponse); private: - -#if defined (WIN32) - static DWORD netthread; -#elif defined (LINUX) - static pthread_t netthread; -#else - static int netthread; -#endif - + boost::thread *mpWorkerThread; }; -#if defined (WIN32) -#elif defined (LINUX) -#else - static int net_thread(SceSize args, void *argp); -#endif - #endif diff --git a/JGE/include/JSocket.h b/JGE/include/JSocket.h index 9a7fd3333..eeb52e493 100644 --- a/JGE/include/JSocket.h +++ b/JGE/include/JSocket.h @@ -2,29 +2,48 @@ #define _JSOCKET_H_ #include +#include "Threading.h" using namespace std; -//TODO config ? -#define SERVER_PORT 20666 - class JSocket{ public: - queue received_data; - queue tosend_data; - static JSocket * mInstance; - int start_server(const char *szIpAddr); - int start_client(const char *szIpAddr); - + typedef enum { + // no network available currently from the device + NOT_AVAILABLE, + // network available but disconnected from another socket + DISCONNECTED, + // connected with another socket + CONNECTED, + // some fatal problem + FATAL_ERROR, + } SOCKET_STATE; + + + // Server creation + JSocket(string ipAddr); + // Client creation JSocket(); ~JSocket(); - static int connected; + + JSocket* Accept(); + int Read(char* buff, int size); + int Write(char* buff, int size); + bool isConnected() { return state == CONNECTED; }; + void Disconnect(); + private: - void init(); - void readWrite(int sock); -#if defined (WIN32) || defined (LINUX) -#else - int make_socket(uint16_t port); + // socket creation when server accepts a connection + JSocket(int fd); + // convert the socket into non-blocking state + bool SetNonBlocking(int sock); + // socket handle +#ifdef WIN32 + SOCKET mfd; +#elif LINUX + int mfd; #endif + // socket state + SOCKET_STATE state; }; #endif diff --git a/JGE/src/JNetwork.cpp b/JGE/src/JNetwork.cpp index d61674631..31c9cdfe5 100644 --- a/JGE/src/JNetwork.cpp +++ b/JGE/src/JNetwork.cpp @@ -4,7 +4,7 @@ */ - +#include "../include/DebugRoutines.h" #include "../include/JNetwork.h" #if defined (WIN32) || defined (LINUX) @@ -30,144 +30,154 @@ #endif - - +#include #include "../include/JSocket.h" -JNetwork* JNetwork::mInstance = NULL; -string JNetwork::serverIP = ""; -string JNetwork::error = ""; +map JNetwork::sCommandMap; -JNetwork * JNetwork::GetInstance(){ - if (!mInstance) mInstance = new JNetwork(); - return mInstance; +bool JNetwork::isConnected(){ + if (connected_to_ap !=1) return false; + return socket->isConnected(); } -void JNetwork::EndInstance(){ - SAFE_DELETE(mInstance); -} - - - -#if defined (WIN32) - DWORD JNetwork::netthread = 0; - int JNetwork::connected_to_ap = 1; -#elif defined (LINUX) - pthread_t JNetwork::netthread = NULL; - int JNetwork::connected_to_ap = 1; +JNetwork::JNetwork() + : mpWorkerThread(NULL) +{ +#if (defined WIN32) || (defined LINUX) + connected_to_ap = 1; #else - int JNetwork::connected_to_ap = 0; - int JNetwork::netthread = 0; + connected_to_ap = 0; #endif -int JNetwork::isConnected(){ - if (connected_to_ap !=1) return 0; - return JSocket::connected; } -JNetwork::JNetwork(){ -} - -int JNetwork::receive(char * buffer, int length){ - JSocket * socket = JSocket::mInstance; - if (!socket) return 0; - int size = 0; - while(!socket->received_data.empty() && size < length){ - buffer[size] = socket->received_data.front(); - socket->received_data.pop(); - size++; - } - return size; -} - -int JNetwork::send(char * buffer, int length){ - JSocket * socket = JSocket::mInstance; - if (!socket) return 0; - for (int i = 0; i < length; i++){ - socket->tosend_data.push(buffer[i]); - } - return length; -} - - - -#if defined (WIN32) -int JNetwork::net_thread(void* param) +JNetwork::~JNetwork() { - do + if(mpWorkerThread) { + socket->Disconnect(); + mpWorkerThread->join(); + delete mpWorkerThread; + } + if(socket) + delete socket; +} + +bool JNetwork::sendCommand(string xString) +{ + string aString = xString; + boost::mutex::scoped_lock l(sendMutex); + if(!socket) { + DebugTrace("sendCommand failed: no sockeet"); + return false; + } + aString = aString + "Command"; + if(sCommandMap.find(aString) == sCommandMap.end()) { + DebugTrace("sendCommand failed: command not registered"); + return false; + } + aString = aString + "\n"; + + toSend << aString; + + return true; +} + +void JNetwork::registerCommand(string command, processCmd processCommand, processCmd processResponse) +{ + sCommandMap[command + "Command"] = processCommand; + sCommandMap[command + "Response"] = processResponse; +} + +void JNetwork::ThreadProc(void* param) +{ + JNetwork* pThis = reinterpret_cast(param); + JSocket* pSocket = NULL; + if (pThis->serverIP.size()) { + DebugTrace("Starting Client Thread"); + pThis->socket = new JSocket(pThis->serverIP); + if(pThis->socket->isConnected()) + pSocket = pThis->socket; + } else { + DebugTrace("Starting Server Thread"); + pThis->socket = new JSocket(); + // Wait for some client + pSocket = pThis->socket->Accept(); + } + + while(pSocket && pSocket->isConnected()) { + char buff[1024]; { - JSocket::mInstance = new JSocket(); - JSocket * s = JSocket::mInstance; - if (JNetwork::serverIP.size()){ - OutputDebugString(JNetwork::serverIP.c_str()); - s->start_client(JNetwork::serverIP.c_str()); - }else{ - s->start_server(""); //IP address useless for server ? + boost::mutex::scoped_lock l(pThis->receiveMutex); + int len = pSocket->Read(buff, sizeof(buff)); + if(len) { + DebugTrace("receiving " << len << " bytes : " << buff); + pThis->received << buff; + } + // Checking for some command to execute + size_t found = pThis->received.str().find("Command"); + if(found != string::npos) + { + map::iterator ite = sCommandMap.find((pThis->received.str()).substr(0, found) + "Command"); + if(ite != sCommandMap.end()) + { + DebugTrace("begin of command received : "<< pThis->received.str() ); + DebugTrace("begin of command toSend : "<< pThis->toSend.str() ); + + boost::mutex::scoped_lock l(pThis->sendMutex); + pThis->toSend << pThis->received.str().substr(0, found) + "Response "; + pThis->received.str(""); + processCmd theMethod = (ite)->second; + theMethod(pThis->received, pThis->toSend); + + DebugTrace("end of command received : "<< pThis->received.str() ); + DebugTrace("end of command toSend : "<< pThis->toSend.str() ); + } + } + // Checking for some response to execute + found = pThis->received.str().find("Response"); + if(found != string::npos) + { + map::iterator ite = sCommandMap.find((pThis->received.str()).substr(0, found) + "Response"); + if(ite != sCommandMap.end()) + { + DebugTrace("begin of response received : "<< pThis->received.str() ); + DebugTrace("begin of response toSend : "<< pThis->toSend.str() ); + + boost::mutex::scoped_lock l(pThis->sendMutex); + string aString; + pThis->received >> aString; + processCmd theMethod = (ite)->second; + theMethod(pThis->received, pThis->toSend); + pThis->received.str(""); + + DebugTrace("end of response received : "<< pThis->received.str() ); + DebugTrace("end of response toSend : "<< pThis->toSend.str() ); + } } } - while(0); - return 0; -} -int JNetwork::connect(string serverIP){ - if(netthread) return 0; - - JNetwork::serverIP = serverIP; - /* Create a user thread to do the real work */ - HANDLE hthread; - hthread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)net_thread,0,0,&netthread); - return netthread; -} - -#elif defined (LINUX) -void* JNetwork::net_thread(void* param __attribute__((unused))) -{ - do + boost::mutex::scoped_lock l(pThis->sendMutex); + if(!pThis->toSend.str().empty()) { - JSocket::mInstance = new JSocket(); - JSocket * s = JSocket::mInstance; - if (JNetwork::serverIP.size()) - s->start_client(JNetwork::serverIP.c_str()); - else - s->start_server(""); //IP address useless for server ? + DebugTrace("sending " << pThis->toSend.str().size() << " bytes : " << pThis->toSend.str()); + pSocket->Write((char*)pThis->toSend.str().c_str(), pThis->toSend.str().size()+1); + pThis->toSend.str(""); } - while (0); - return NULL; + } + + DebugTrace("Quitting Thread"); } -int JNetwork::connect(string serverIP) +#if defined (WIN32) || defined (LINUX) +int JNetwork::connect(string ip) { - if (netthread) return 0; - JNetwork::serverIP = serverIP; - return pthread_create(&netthread, NULL, net_thread, NULL); + if (mpWorkerThread) return 0; + serverIP = ip; + mpWorkerThread = new boost::thread(JNetwork::ThreadProc, this); + return 42; } #else -int net_thread(SceSize args, void *argp) -{ -#ifdef NETWORK_SUPPORT - do - { - JSocket::mInstance = new JSocket(); - JSocket * s = JSocket::mInstance; - if (JNetwork::serverIP.size()){ - s->start_client(JNetwork::serverIP.c_str()); - - }else{ - // connected, get my IPADDR and run test - SceNetApctlInfo szMyIPAddr; - if (sceNetApctlGetInfo(8, &szMyIPAddr) != 0){ - }else{ - s->start_server(szMyIPAddr.ip); - } - - } - } - while(0); -#endif - return 0; -} - int JNetwork::connect(string serverIP){ #ifdef NETWORK_SUPPORT diff --git a/JGE/src/JSocket.cpp b/JGE/src/JSocket.cpp index b06e2a602..5cf1ead03 100644 --- a/JGE/src/JSocket.cpp +++ b/JGE/src/JSocket.cpp @@ -1,3 +1,5 @@ +#if 0 +// need a complete rewrite to comply to the new interface #ifdef NETWORK_SUPPORT #include @@ -223,5 +225,6 @@ int JSocket::start_server(const char *szIpAddr) return 0; } +#endif //NETWORK_SUPPORT diff --git a/JGE/src/pc/JSocket.cpp b/JGE/src/pc/JSocket.cpp index 52749e8bb..d205aa6c2 100644 --- a/JGE/src/pc/JSocket.cpp +++ b/JGE/src/pc/JSocket.cpp @@ -1,230 +1,301 @@ +#include "PrecompiledHeader.h" + +#include +#ifdef WIN32 #pragma comment(lib,"WSOCK32.LIB") #include #include #include -#include #include +#include +#elif LINUX +#include +#include +#include +#include +#include +#endif //WINDOWS #include "../../include/JSocket.h" -JSocket * JSocket::mInstance = NULL; +//JSocket * JSocket::mInstance = NULL; -#define SERVER_PORT 20666 +//#define SERVER_PORT 20666 +#define SERVER_PORT 5001 unsigned char ADRESSE_IP_SERVEUR [4] = {127,0,0,1}; -int JSocket::connected = 0; - -void JSocket::init(){ - //TODO ? -} - -JSocket::JSocket(){ - init(); -} - -JSocket::~JSocket(){ - //TODO ? -} - - -void JSocket::readWrite(int val){ - char data[1024]; - - fd_set set; - FD_ZERO(&set); - FD_SET(val, &set); - struct timeval tv; - int result = select(0, &set, NULL, NULL, &tv); - if( result< 0) - { - printf("Socket %d closed\n", val); - closesocket(val); - connected= 0; - printf("select error\n"); - return; - } - - if (result > 0){ - OutputDebugString("Receiving!\n"); - int readbytes = recv(val, data, sizeof(data),0); - if(readbytes < 0) - { - int error = WSAGetLastError(); - if (error != WSAEWOULDBLOCK){ - printf("Socket %d closed\n", val); - closesocket(val); - connected= 0; - } - } - else - { - OutputDebugString("received Data!!!\n"); - for (int i = 0; i < readbytes; i++){ - received_data.push(data[i]); - OutputDebugString("getting byte\n"); - } - } - } - - //Write - int size = 0; - while(!tosend_data.empty()){ - size++; - if (size > sizeof(data)){ - send(val,data,sizeof(data),0); - size = 0; - } - data[size-1] = tosend_data.front(); - tosend_data.pop(); - } - if (size) { - send(val,data,size-1,0); - OutputDebugString("sending Data\n"); - } -} - -/* Start a client */ -int JSocket::start_client(const char *szIpAddr){ +JSocket::JSocket(string ipAddr) + : state(NOT_AVAILABLE), + mfd(-1) +{ + int result = -1; +#ifdef WIN32 SOCKET Desc_Socket_Cliente; - SOCKADDR_IN Adresse_Socket_Serveur; +#elif LINUX + int Desc_Socket_Cliente; +#endif + + struct hostent *hostentptr; +#ifdef WIN32 + SOCKADDR_IN Adresse_Socket_Server; WORD wVersionRequested; WSADATA wsaData; - struct hostent *hostentptr; - wVersionRequested=MAKEWORD(1,1); - WSAStartup(wVersionRequested,&wsaData); + result = WSAStartup(wVersionRequested,&wsaData); + if(result!=0){ + DebugTrace("WSAStartup\t"); + return; + } +#elif LINUX + struct sockaddr_in Adresse_Socket_Server; +#endif - Desc_Socket_Cliente=socket(AF_INET,SOCK_STREAM,0); - unsigned int addr_dest = inet_addr(szIpAddr); + mfd=socket(AF_INET,SOCK_STREAM,0); + if(mfd < 0) + return; + DebugTrace("Connecting " << ipAddr); + +#ifdef WIN32 + unsigned int addr_dest = inet_addr(ipAddr.c_str()); hostentptr=gethostbyaddr((char*) &addr_dest,4,AF_INET); +#elif LINUX + hostentptr = gethostbyname(ipAddr.c_str()); +#endif + if (hostentptr == NULL) { + DebugTrace("ERROR, no such host\n"); + return; + } - ZeroMemory(&Adresse_Socket_Serveur,sizeof(Adresse_Socket_Serveur)); +#ifdef WIN32 + ZeroMemory( (char*)&Adresse_Socket_Server,sizeof(Adresse_Socket_Server)); +#elif LINUX + bzero( (char*)&Adresse_Socket_Server,sizeof(Adresse_Socket_Server)); +#endif //WINDOWS - Adresse_Socket_Serveur.sin_family=(*hostentptr).h_addrtype; - Adresse_Socket_Serveur.sin_port=htons(SERVER_PORT); - Adresse_Socket_Serveur.sin_addr=*((struct in_addr*)(*hostentptr).h_addr); - - int result = connect( - Desc_Socket_Cliente, - (const struct sockaddr*)&Adresse_Socket_Serveur, - sizeof(Adresse_Socket_Serveur)); - -OutputDebugString("client state 0\n"); + Adresse_Socket_Server.sin_family=(*hostentptr).h_addrtype; + Adresse_Socket_Server.sin_port=htons(SERVER_PORT); + Adresse_Socket_Server.sin_addr=*((struct in_addr*)(*hostentptr).h_addr); + result = connect( + mfd, + (const struct sockaddr*)&Adresse_Socket_Server, + sizeof(Adresse_Socket_Server)); if (result != 0){ - connected = 0; - return 0; + DebugTrace("client connect failed :" << strerror(errno)); + state = FATAL_ERROR; + return; } -OutputDebugString("client state 1\n"); + state = CONNECTED; +} +bool JSocket::SetNonBlocking(int sock) +{ + int opts; - connected = 1; - -while(1){ - readWrite(Desc_Socket_Cliente); -/* Nb_Caracteres_Recus=recv(Desc_Socket_Cliente,Message_Recu,sizeof(Message_Recu),0); - if(Nb_Caracteres_Recus<=0){ - //continuer=FALSE; - }else{ - strcpy(message,Message_Recu); - len=strlen(message); +#ifdef WIN32 +#elif LINUX + opts = fcntl(sock,F_GETFL); + if (opts < 0) { + perror("fcntl(F_GETFL)"); + return false; } - */ -} -# -closesocket(Desc_Socket_Cliente); -WSACleanup(); -return 0; + opts = (opts | O_NONBLOCK); + if (fcntl(sock,F_SETFL,opts) < 0) { + perror("fcntl(F_SETFL)"); + return false; + } +#endif //WINDOWS + return true; } -/* Start a server */ -int JSocket::start_server(const char *szIpAddr){ - OutputDebugString("server state 0\n"); - connected= 0; - int Code_Retour; - SOCKET Desc_Socket_Connection; +JSocket::JSocket() + : state(NOT_AVAILABLE), + mfd(-1) +{ + int result; +#ifdef WIN32 SOCKADDR_IN Adresse_Socket_Connection; WORD wVersionRequested; WSADATA wsaData; wVersionRequested=MAKEWORD(1,1); + result=WSAStartup(wVersionRequested,&wsaData); - Code_Retour=WSAStartup(wVersionRequested,&wsaData); - - if(Code_Retour!=0){ - perror("WSAStartup\t"); - _getch(); - WSACleanup(); - return Code_Retour; + if(result!=0){ + DebugTrace("WSAStartup\t"); + return; } - OutputDebugString("server state 1\n"); -/* printf("la version supportee est : %d.%d\n", -LOBYTE(wsaData.wHighVersion), -HIBYTE(wsaData.wHighVersion) -);*/ +#elif LINUX + struct sockaddr_in Adresse_Socket_Connection; +#endif //WINDOWS - Desc_Socket_Connection=socket( AF_INET, SOCK_STREAM,0); + mfd=socket( AF_INET, SOCK_STREAM,0); -//printf("valeur de la socket = %d\n",Desc_Socket_Connection); +#ifdef WIN32 +#elif LINUX + int reuse_addr = 1; /* Used so we can re-bind to our port + while a previous connection is still + in TIME_WAIT state. */ + /* So that we can re-bind to it without TIME_WAIT problems */ + setsockopt(mfd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, + sizeof(reuse_addr)); +#endif //WINDOWS - ZeroMemory(&Adresse_Socket_Connection,sizeof(Adresse_Socket_Connection)); + SetNonBlocking(mfd); + +#ifdef WIN32 + ZeroMemory( &Adresse_Socket_Connection,sizeof(Adresse_Socket_Connection)); +#elif LINUX + bzero( &Adresse_Socket_Connection,sizeof(Adresse_Socket_Connection)); +#endif //WINDOWS Adresse_Socket_Connection.sin_family=AF_INET; Adresse_Socket_Connection.sin_port=htons(SERVER_PORT); - Code_Retour=bind(Desc_Socket_Connection, + result=bind(mfd, (struct sockaddr*)&Adresse_Socket_Connection, sizeof(Adresse_Socket_Connection)); - - - - if(Code_Retour!=0){ - perror("bind\t"); - _getch(); - closesocket(Desc_Socket_Connection); - WSACleanup(); - return Code_Retour; + if(result!=0){ + state = FATAL_ERROR; + DebugTrace("bind error:" << strerror(errno)); + return; } - OutputDebugString("server state 3\n"); - Code_Retour=listen(Desc_Socket_Connection,1); - if(Code_Retour!=0){ - perror("listen\n"); - WSACleanup(); - return Code_Retour; + result=listen(mfd,1); + if(result!=0){ + state = FATAL_ERROR; + DebugTrace("listen error:" << strerror(errno)); + return; } - OutputDebugString("server state 4\n"); - printf("serveur en attente d'une connection\n\n"); - printf("***************arret du serveur par**************\n\n"); - connected = 1; - while(1){ - SOCKET * pt_Nouveau_Socket_Serveur; - SOCKADDR_IN Adresse_Socket_Cliente; - int Longueur_Adresse; - pt_Nouveau_Socket_Serveur = new SOCKET; + state = DISCONNECTED; +} - Longueur_Adresse = sizeof(Adresse_Socket_Cliente); +JSocket::JSocket(int fd) + : state(CONNECTED), + mfd(fd) +{ +} - int val=accept( - Desc_Socket_Connection, - (struct sockaddr*)&Adresse_Socket_Cliente, - &Longueur_Adresse); - printf("connection accepte depuis le port client %d\n", ntohs(Adresse_Socket_Cliente.sin_port)); - OutputDebugString("connection accepte depuis le port client\n"); +JSocket::~JSocket(){ + Disconnect(); +#ifdef WIN32 + WSACleanup(); +#endif +} - - while(1) - { - readWrite(val); - } - closesocket(*pt_Nouveau_Socket_Serveur); - return 0; +void JSocket::Disconnect() +{ + state = JSocket::DISCONNECTED; + if(mfd) { +#ifdef WIN32 + closesocket(mfd); +#elif LINUX + close(mfd); +#endif + mfd = 0; } } - - +JSocket* JSocket::Accept() +{ + #ifdef WIN32 + SOCKADDR_IN Adresse_Socket_Cliente; + int Longueur_Adresse; + #elif LINUX + struct sockaddr_in Adresse_Socket_Cliente; + socklen_t Longueur_Adresse; + #endif //WINDOWS + + while(mfd) { + fd_set set; + FD_ZERO(&set); + FD_SET(mfd, &set); + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 1000*100; + + int result = select(mfd+1, &set, NULL, NULL, &tv); + if( result > 0 && FD_ISSET(mfd, &set) ) { + + Longueur_Adresse = sizeof(Adresse_Socket_Cliente); + int val=accept( + mfd, + (struct sockaddr*)&Adresse_Socket_Cliente, + &Longueur_Adresse); + DebugTrace("connection on client port "<< ntohs(Adresse_Socket_Cliente.sin_port)); + + if(val >=0 ) { + state = CONNECTED; + return new JSocket(val); + } else { + return NULL; + } + } + } +} + +int JSocket::Read(char* buff, int size) +{ + if(state == CONNECTED) + { + fd_set set; + FD_ZERO(&set); + FD_SET(mfd, &set); + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 1000*100; + + int result = select(mfd+1, &set, NULL, NULL, &tv); + if( result > 0 && FD_ISSET(mfd, &set) ) + { + #ifdef WIN32 + int readbytes = recv(mfd, buff, size,0); + #elif LINUX + int readbytes = read(mfd, buff, size); + #endif //WINDOWS + if(readbytes < 0) + { + DebugTrace("Error reading from socket\n"); + return -1; + } + else + return readbytes; + } + else if( result < 0) + { + return -1; + } + } + return 0; +} + +int JSocket::Write(char* buff, int size) +{ + int size1 = size; + while (size > 0 && state == CONNECTED) { + fd_set set; + FD_ZERO(&set); + FD_SET(mfd, &set); + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 1000*100; + + int result = select(mfd+1, NULL, &set, NULL, &tv); + if( result > 0 && FD_ISSET(mfd, &set)) + { + int len = send(mfd, buff, size, 0); + if (len < 0) { + return -1; + } + size -= len; + buff += len; + } else if (result < 0) { + return -1; + } + } + return size1 - size; +} diff --git a/projects/mtg/include/AIMomirPlayer.h b/projects/mtg/include/AIMomirPlayer.h index cfa32ef79..603573c68 100644 --- a/projects/mtg/include/AIMomirPlayer.h +++ b/projects/mtg/include/AIMomirPlayer.h @@ -6,7 +6,7 @@ class AIMomirPlayer: public AIPlayerBaka { public: - AIMomirPlayer(MTGDeck * deck, string file, string fileSmall, string avatarFile); + AIMomirPlayer(string file, string fileSmall, string avatarFile, MTGDeck * deck = NULL); int getEfficiency(AIAction * action); int momir(); int computeActions(); diff --git a/projects/mtg/include/AIPlayer.h b/projects/mtg/include/AIPlayer.h index 2d21734e6..79b1062d1 100644 --- a/projects/mtg/include/AIPlayer.h +++ b/projects/mtg/include/AIPlayer.h @@ -100,7 +100,7 @@ public: int receiveEvent(WEvent * event); void Render(); ManaCost * getPotentialMana(MTGCardInstance * card = NULL); - AIPlayer(MTGDeck * deck, string deckFile, string deckFileSmall); + AIPlayer(string deckFile, string deckFileSmall, MTGDeck * deck = NULL); virtual ~AIPlayer(); virtual MTGCardInstance * chooseCard(TargetChooser * tc, MTGCardInstance * source, int random = 0); virtual int chooseTarget(TargetChooser * tc = NULL, Player * forceTarget =NULL,MTGCardInstance * Choosencard = NULL); @@ -123,7 +123,7 @@ class AIPlayerBaka: public AIPlayer{ MTGCardInstance * FindCardToPlay(ManaCost * potentialMana, const char * type); public: int deckId; - AIPlayerBaka(MTGDeck * deck, string deckFile, string deckfileSmall, string avatarFile); + AIPlayerBaka(string deckFile, string deckfileSmall, string avatarFile, MTGDeck * deck = NULL); virtual int Act(float dt); void initTimer(); virtual int computeActions(); diff --git a/projects/mtg/include/GameApp.h b/projects/mtg/include/GameApp.h index c9f6fcf26..bc349d257 100644 --- a/projects/mtg/include/GameApp.h +++ b/projects/mtg/include/GameApp.h @@ -22,12 +22,18 @@ #include "MTGGameZones.h" #include "CardEffect.h" +#ifdef NETWORK_SUPPORT +#include "JNetwork.h" +#endif //NETWORK_SUPPORT enum { PLAYER_TYPE_CPU = 0, PLAYER_TYPE_HUMAN=1, - PLAYER_TYPE_TESTSUITE=2 + PLAYER_TYPE_TESTSUITE=2, +#ifdef NETWORK_SUPPORT + PLAYER_TYPE_REMOTE=3 +#endif //NETWORK_SUPPORT }; enum @@ -37,7 +43,10 @@ enum GAME_TYPE_RANDOM1, GAME_TYPE_RANDOM2, GAME_TYPE_STORY, - GAME_TYPE_DEMO + GAME_TYPE_DEMO, +#ifdef NETWORK_SUPPORT + GAME_TYPE_SLAVE, +#endif //NETWORK_SUPPORT }; class MTGAllCards; @@ -61,6 +70,9 @@ public: int gameType; CardEffect *effect; +#ifdef NETWORK_SUPPORT + JNetwork* mpNetwork; +#endif //NETWORK_SUPPORT GameApp(); virtual ~GameApp(); diff --git a/projects/mtg/include/GameStateDuel.h b/projects/mtg/include/GameStateDuel.h index c50d5b0aa..935b27e0c 100644 --- a/projects/mtg/include/GameStateDuel.h +++ b/projects/mtg/include/GameStateDuel.h @@ -15,6 +15,9 @@ class TestSuite; #endif class Credits; class Rules; +#ifdef NETWORK_SUPPORT +class JNetwork; +#endif class GameStateDuel: public GameState, public JGuiListener { @@ -22,6 +25,7 @@ private: #ifdef TESTSUITE TestSuite * testSuite; #endif + Credits * credits; int mGamePhase; Player * mCurrentPlayer; @@ -40,7 +44,7 @@ private: Rules * rules; bool MusicExist(string FileName); - void loadPlayer(int playerId, int decknb = 0, int isAI = 0); + void loadPlayer(int playerId, int decknb = 0, bool isAI = false, bool isNetwork = false); void ConstructOpponentMenu(); //loads the opponentMenu if it doesn't exist void initScroller(); @@ -66,6 +70,10 @@ public: MENUITEM_MAIN_MENU = -13, MENUITEM_EVIL_TWIN = -14, MENUITEM_MULLIGAN = -15, +#ifdef NETWORK_SUPPORT + MENUITEM_REMOTE_CLIENT = -16, + MENUITEM_REMOTE_SERVER = -17, +#endif MENUITEM_MORE_INFO = kInfoMenuID }; diff --git a/projects/mtg/include/NetworkPlayer.h b/projects/mtg/include/NetworkPlayer.h new file mode 100644 index 000000000..dc62678d4 --- /dev/null +++ b/projects/mtg/include/NetworkPlayer.h @@ -0,0 +1,33 @@ +#ifndef NETWORKPLAYER_H +#define NETWORKPLAYER_H + +#include "PrecompiledHeader.h" +#include "Player.h" +#include "JNetwork.h" + +extern void RegisterNetworkPlayers(); + +class ProxyPlayer +{ +protected: + Player* mpPlayer; + JNetwork* mpNetwork; + static ProxyPlayer* mInstance; +public: + ProxyPlayer(Player* pxPlayer, JNetwork* pxNetwork); + static void Serialize(istream& in, ostream& out); +}; + + +class RemotePlayer : public Player +{ +protected: + JNetwork* mpNetwork; + static RemotePlayer* mInstance; +public: + RemotePlayer(JNetwork*); + static void Deserialize(istream& in, ostream& out); + bool isLoaded() {return game!=NULL;}; +}; + +#endif // NETWORKPLAYER_H diff --git a/projects/mtg/include/Player.h b/projects/mtg/include/Player.h index eb734d4b8..66e4e7b62 100644 --- a/projects/mtg/include/Player.h +++ b/projects/mtg/include/Player.h @@ -35,7 +35,7 @@ public: string deckName; string phaseRing; - Player(MTGDeck * deck, string deckFile, string deckFileSmall); + Player(string deckFile, string deckFileSmall, MTGDeck * deck = NULL); virtual ~Player(); virtual void End(); @@ -98,7 +98,7 @@ public: class HumanPlayer: public Player { public: - HumanPlayer(MTGDeck * deck, string deckFile, string deckFileSmall); + HumanPlayer(string deckFile, string deckFileSmall, MTGDeck * deck = NULL); HumanPlayer(string deckFile); }; diff --git a/projects/mtg/src/AIMomirPlayer.cpp b/projects/mtg/src/AIMomirPlayer.cpp index fdb6352f4..b59aef232 100644 --- a/projects/mtg/src/AIMomirPlayer.cpp +++ b/projects/mtg/src/AIMomirPlayer.cpp @@ -8,8 +8,8 @@ MTGAbility * AIMomirPlayer::momirAbility = NULL; -AIMomirPlayer::AIMomirPlayer(MTGDeck * deck, string file, string fileSmall, string avatarFile) : - AIPlayerBaka(deck, file, fileSmall, avatarFile) +AIMomirPlayer::AIMomirPlayer(string file, string fileSmall, string avatarFile, MTGDeck * deck) : + AIPlayerBaka(file, fileSmall, avatarFile, deck) { momirAbility = NULL; agressivity = 100; diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index bca5ca116..0d5483411 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -38,8 +38,8 @@ int AIAction::Act() return 0; } -AIPlayer::AIPlayer(MTGDeck * deck, string file, string fileSmall) : - Player(deck, file, fileSmall) +AIPlayer::AIPlayer(string file, string fileSmall, MTGDeck * deck) : + Player(file, fileSmall, deck) { nextCardToPlay = NULL; stats = NULL; @@ -1189,10 +1189,8 @@ AIPlayer * AIPlayerFactory::createAIPlayer(MTGAllCards * collection, Player * op if ( meta->getVictoryPercentage() >= 65) deckSetting = HARD; } - MTGDeck * tempDeck = NEW MTGDeck(deckFile, collection,0, deckSetting); - AIPlayerBaka * baka = NEW AIPlayerBaka(tempDeck, deckFile, deckFileSmall, avatarFile); + AIPlayerBaka * baka = NEW AIPlayerBaka(deckFile, deckFileSmall, avatarFile); baka->deckId = deckid; - SAFE_DELETE(tempDeck); return baka; } @@ -1272,8 +1270,8 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty return nextCardToPlay; } -AIPlayerBaka::AIPlayerBaka(MTGDeck * deck, string file, string fileSmall, string avatarFile) : - AIPlayer(deck, file, fileSmall) +AIPlayerBaka::AIPlayerBaka(string file, string fileSmall, string avatarFile, MTGDeck * deck) : + AIPlayer(file, fileSmall, deck) { mAvatarTex = WResourceManager::Instance()->RetrieveTexture(avatarFile, RETRIEVE_LOCK, TEXTURE_SUB_AVATAR); diff --git a/projects/mtg/src/DuelLayers.cpp b/projects/mtg/src/DuelLayers.cpp index 3c4cb4c21..53bda5207 100644 --- a/projects/mtg/src/DuelLayers.cpp +++ b/projects/mtg/src/DuelLayers.cpp @@ -81,7 +81,7 @@ void DuelLayers::CheckUserInput(int isAI) break; } } - if (JGE::GetInstance()->GetLeftClickCoordinates(x, y)) + if ((!isAI) && JGE::GetInstance()->GetLeftClickCoordinates(x, y)) { if (avatars->CheckUserInput(x, y)) { diff --git a/projects/mtg/src/GameApp.cpp b/projects/mtg/src/GameApp.cpp index d84040450..6cadd2543 100644 --- a/projects/mtg/src/GameApp.cpp +++ b/projects/mtg/src/GameApp.cpp @@ -44,6 +44,9 @@ GameState::GameState(GameApp* parent) : GameApp::GameApp() : JApp() +#ifdef NETWORK_SUPPORT + ,mpNetwork(NULL) +#endif //NETWORK_SUPPORT { #ifdef DEBUG nbUpdates = 0; diff --git a/projects/mtg/src/GameStateDuel.cpp b/projects/mtg/src/GameStateDuel.cpp index 408f32e9e..259faf640 100644 --- a/projects/mtg/src/GameStateDuel.cpp +++ b/projects/mtg/src/GameStateDuel.cpp @@ -20,6 +20,10 @@ #include "TestSuiteAI.h" #endif +#ifdef NETWORK_SUPPORT +#include "NetworkPlayer.h" +#endif + #if defined (WIN32) || defined (LINUX) #include #endif @@ -41,6 +45,9 @@ enum ENUM_DUEL_STATE DUEL_STATE_PLAY, DUEL_STATE_BACK_TO_MAIN_MENU, DUEL_STATE_MENU, +#ifdef NETWORK_SUPPORT + DUEL_STATE_OPPONENT_WAIT, +#endif //NETWORK_SUPPORT DUEL_STATE_ERROR }; @@ -77,6 +84,10 @@ GameState(parent) credits = NULL; rules = NULL; +#ifdef NETWORK_SUPPORT + RegisterNetworkPlayers(); +#endif //NETWORK_SUPPORT + } GameStateDuel::~GameStateDuel() @@ -156,22 +167,34 @@ void GameStateDuel::Start() } } -void GameStateDuel::loadPlayer(int playerId, int decknb, int isAI) +void GameStateDuel::loadPlayer(int playerId, int decknb, bool isAI, bool isNetwork) { if (decknb) { if (!isAI) { //Human Player - char deckFile[255]; - if (premadeDeck) - sprintf(deckFile, JGE_GET_RES("player/premade/deck%i.txt").c_str(), decknb); + if(playerId == 0) + { + char deckFile[255]; + if (premadeDeck) + sprintf(deckFile, JGE_GET_RES("player/premade/deck%i.txt").c_str(), decknb); + else + sprintf(deckFile, "%s/deck%i.txt", options.profileFile().c_str(), decknb); + char deckFileSmall[255]; + sprintf(deckFileSmall, "player_deck%i", decknb); + mPlayers[playerId] = NEW HumanPlayer(deckFile, deckFileSmall); +#ifdef NETWORK_SUPPORT + if(isNetwork) + { + ProxyPlayer* mProxy; + mProxy = NEW ProxyPlayer(mPlayers[playerId], mParent->mpNetwork); + } + } else - sprintf(deckFile, "%s/deck%i.txt", options.profileFile().c_str(), decknb); - char deckFileSmall[255]; - sprintf(deckFileSmall, "player_deck%i", decknb); - MTGDeck * tempDeck = NEW MTGDeck(deckFile, MTGCollection()); - mPlayers[playerId] = NEW HumanPlayer(tempDeck, deckFile, deckFileSmall); - SAFE_DELETE( tempDeck ); + { //Remote player + mPlayers[playerId] = NEW RemotePlayer(mParent->mpNetwork); +#endif //NETWORK_SUPPORT + } } else { //AI Player, chooses deck @@ -471,6 +494,29 @@ void GameStateDuel::Update(float dt) mGamePhase = DUEL_STATE_MENU; } break; +#ifdef NETWORK_SUPPORT + case DUEL_STATE_OPPONENT_WAIT: + { + if(mPlayers[1] && mPlayers[1]->game) + { // Player loaded + menu->Close(); + SAFE_DELETE(menu); + mGamePhase = DUEL_STATE_PLAY; + } else if(menu == NULL) + { + loadPlayer(1, 42/* 0 not good*/, false, true); + menu = NEW SimpleMenu(DUEL_STATE_OPPONENT_WAIT, this, Fonts::MENU_FONT, 150, 60); + if (menu) + { + menu->Add(MENUITEM_MAIN_MENU, "Back to main menu"); + } + } else + { + menu->Update(dt); + } + } + break; +#endif //NETWORK_SUPPORT case DUEL_STATE_MENU: menu->Update(dt); break; @@ -565,7 +611,11 @@ void GameStateDuel::Render() case DUEL_STATE_CHOOSE_DECK2_TO_PLAY: case DUEL_STATE_DECK1_DETAILED_INFO: case DUEL_STATE_DECK2_DETAILED_INFO: - if (mParent->gameType != GAME_TYPE_CLASSIC) + if (mParent->gameType != GAME_TYPE_CLASSIC +#ifdef NETWORK_SUPPORT + && mParent->gameType != GAME_TYPE_SLAVE +#endif //NETWORK_SUPPORT + ) mFont->DrawString(_("LOADING DECKS").c_str(), 0, SCREEN_HEIGHT / 2); else { @@ -582,6 +632,11 @@ void GameStateDuel::Render() mFont->DrawString(_("NO DECK AVAILABLE,").c_str(), 0, SCREEN_HEIGHT / 2); mFont->DrawString(_("PRESS CIRCLE TO GO TO THE DECK EDITOR!").c_str(), 0, SCREEN_HEIGHT / 2 + 20); break; +#ifdef NETWORK_SUPPORT + case DUEL_STATE_OPPONENT_WAIT: + if (menu) menu->Render(); + break; +#endif //NETWORK_SUPPORT case DUEL_STATE_MENU: case DUEL_STATE_CANCEL: case DUEL_STATE_BACK_TO_MAIN_MENU: @@ -742,9 +797,22 @@ void GameStateDuel::ButtonPressed(int controllerId, int controlId) vector * playerDeck = deckManager->getPlayerDeckOrderList(); if (!premadeDeck && controlId > 0) deckNumber = playerDeck->at(controlId - 1)->getDeckId(); - loadPlayer(0, deckNumber); + loadPlayer(0, deckNumber, false +#ifdef NETWORK_SUPPORT + ,(mParent->players[1] == PLAYER_TYPE_REMOTE) +#endif //NETWORK_SUPPORT + ); deckmenu->Close(); - mGamePhase = DUEL_STATE_CHOOSE_DECK1_TO_2; +#ifdef NETWORK_SUPPORT + if(mParent->players[1] == PLAYER_TYPE_REMOTE) + { // no need to choose an opponent deck in network mode + mGamePhase = DUEL_STATE_OPPONENT_WAIT; + } + else +#endif //NETWORK_SUPPORT + { + mGamePhase = DUEL_STATE_CHOOSE_DECK1_TO_2; + } playerDeck = NULL; } else diff --git a/projects/mtg/src/GameStateMenu.cpp b/projects/mtg/src/GameStateMenu.cpp index 5cd8c7968..4d893475e 100644 --- a/projects/mtg/src/GameStateMenu.cpp +++ b/projects/mtg/src/GameStateMenu.cpp @@ -39,7 +39,10 @@ enum ENUM_MENU_STATE_MAJOR MENU_STATE_MAJOR_FIRST_TIME = 0x05, MENU_STATE_MAJOR_DUEL = 0x06, MENU_STATE_MAJOR_LANG = 0x07, - +#ifdef NETWORK_SUPPORT + MENU_STATE_NETWORK_DEFINE = 0x08, + MENU_STATE_NETWORK_WAIT = 0x09, +#endif //NETWORK_SUPPORT MENU_STATE_MAJOR = 0xFF }; @@ -61,8 +64,9 @@ enum MENUITEM_EXIT, SUBMENUITEM_1PLAYER, #ifdef NETWORK_SUPPORT - SUBMENUITEM_2PLAYER_SERVER, - SUBMENUITEM_2PLAYER_CLIENT, + SUBMENUITEM_2PLAYERS, + SUBMENUITEM_HOST_GAME, + SUBMENUITEM_JOIN_GAME, #endif //NETWORK_SUPPORT SUBMENUITEM_DEMO, SUBMENUITEM_TESTSUITE, @@ -535,6 +539,44 @@ void GameStateMenu::Update(float dt) if (mEngine->GetButtonState(JGE_BTN_NEXT)) //Hook for GameStateAward state mParent->DoTransition(TRANSITION_FADE, GAME_STATE_AWARDS); //TODO: A slide transition would be nice. break; +#ifdef NETWORK_SUPPORT + case MENU_STATE_NETWORK_DEFINE: + currentState = MENU_STATE_MAJOR_SUBMENU; + subMenuController = NEW SimpleMenu(MENU_FIRST_DUEL_SUBMENU, this, Fonts::MENU_FONT, 150, 60); + if (subMenuController) + { + subMenuController->Add(SUBMENUITEM_HOST_GAME, "Host a game"); + subMenuController->Add(SUBMENUITEM_JOIN_GAME, "Join a game"); + subMenuController->Add(SUBMENUITEM_CANCEL, "Cancel"); + } + break; + case MENU_STATE_NETWORK_WAIT: + if(MENU_STATE_MINOR_NONE == (currentState & MENU_STATE_MINOR)) + { + if(mParent->mpNetwork->isConnected()) + { + if(subMenuController) subMenuController->Close(); + currentState = MENU_STATE_MAJOR_DUEL | MENU_STATE_MINOR_SUBMENU_CLOSING; + } + else if(!subMenuController) + { +// currentState = MENU_STATE_MAJOR_SUBMENU; + subMenuController = NEW SimpleMenu(MENU_FIRST_DUEL_SUBMENU, this, Fonts::MENU_FONT, 150, 60); + if (subMenuController) + { + subMenuController->Add(SUBMENUITEM_CANCEL, "Cancel connection"); + } + } + else{ + if (subMenuController) + subMenuController->Update(dt); + ensureMGuiController(); + mGuiController->Update(dt); + break; + } + } + break; +#endif //NETWORK_SUPPORT case MENU_STATE_MAJOR_SUBMENU: if (subMenuController) subMenuController->Update(dt); @@ -751,8 +793,7 @@ void GameStateMenu::ButtonPressed(int controllerId, int controlId) // TODO Put 2 players mode back // This requires to fix the hand (to accept 2 players) OR to implement network game #ifdef NETWORK_SUPPORT - subMenuController->Add(SUBMENUITEM_2PLAYER_SERVER, "2 Players - server"); - subMenuController->Add(SUBMENUITEM_2PLAYER_CLIENT, "2 Players - client"); + subMenuController->Add(SUBMENUITEM_2PLAYERS, "2 Players"); #endif //NETWORK_SUPPORT subMenuController->Add(SUBMENUITEM_DEMO, "Demo"); subMenuController->Add(SUBMENUITEM_CANCEL, "Cancel"); @@ -781,22 +822,39 @@ void GameStateMenu::ButtonPressed(int controllerId, int controlId) currentState = MENU_STATE_MAJOR_DUEL | MENU_STATE_MINOR_SUBMENU_CLOSING; break; #ifdef NETWORK_SUPPORT - case SUBMENUITEM_2PLAYER_SERVER: + case SUBMENUITEM_2PLAYERS: mParent->players[0] = PLAYER_TYPE_HUMAN; - mParent->players[1] = PLAYER_TYPE_HUMAN; - this->hasChosenGameType = true; - mParent->gameType = GAME_TYPE_CLASSIC; + mParent->players[1] = PLAYER_TYPE_REMOTE; subMenuController->Close(); - currentState = MENU_STATE_MAJOR_DUEL | MENU_STATE_MINOR_SUBMENU_CLOSING; + currentState = MENU_STATE_NETWORK_DEFINE | MENU_STATE_MINOR_SUBMENU_CLOSING; break; - case SUBMENUITEM_2PLAYER_CLIENT: - mParent->players[0] = PLAYER_TYPE_HUMAN; - mParent->players[1] = PLAYER_TYPE_HUMAN; - this->hasChosenGameType = true; - mParent->gameType = GAME_TYPE_CLASSIC; + case SUBMENUITEM_HOST_GAME: + { + if(!mParent->mpNetwork) + { + mParent->mpNetwork = new JNetwork(); + } + mParent->mpNetwork->connect(); subMenuController->Close(); - currentState = MENU_STATE_MAJOR_DUEL | MENU_STATE_MINOR_SUBMENU_CLOSING; + currentState = MENU_STATE_NETWORK_WAIT | MENU_STATE_MINOR_SUBMENU_CLOSING; break; + } + case SUBMENUITEM_JOIN_GAME: + { + if(!mParent->mpNetwork) + { + mParent->mpNetwork = new JNetwork(); + } + // FIXME needs to be able to specify the server ip + mParent->mpNetwork->connect("127.0.0.1"); + // we let the server choose the game mode + mParent->gameType = GAME_TYPE_SLAVE; + hasChosenGameType = true; + subMenuController->Close(); +// currentState = MENU_STATE_MAJOR_DUEL | MENU_STATE_MINOR_SUBMENU_CLOSING; + currentState = MENU_STATE_NETWORK_WAIT; + break; + } #endif //NETWORK_SUPPORT case SUBMENUITEM_DEMO: mParent->players[0] = PLAYER_TYPE_CPU; @@ -810,6 +868,12 @@ void GameStateMenu::ButtonPressed(int controllerId, int controlId) { subMenuController->Close(); } +#ifdef NETWORK_SUPPORT + if(mParent->mpNetwork) + { + SAFE_DELETE(mParent->mpNetwork); + } +#endif //NETWORK_SUPPORT currentState = MENU_STATE_MAJOR_MAINMENU | MENU_STATE_MINOR_SUBMENU_CLOSING; break; diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index 34d83eebb..3411948c3 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -974,11 +974,10 @@ ostream& operator<<(ostream& out, const MTGGameZone& z) } ostream& operator<<(ostream& out, const MTGPlayerCards& z) { - out << z.library->nb_cards << endl; + out << z.library->nb_cards << " "; for (int i = 0; i < z.library->nb_cards; i++) out << z.library->cards[i]->getMTGId() << " "; - out << endl; return out; } diff --git a/projects/mtg/src/NetworkPlayer.cpp b/projects/mtg/src/NetworkPlayer.cpp new file mode 100644 index 000000000..ade7a7e7d --- /dev/null +++ b/projects/mtg/src/NetworkPlayer.cpp @@ -0,0 +1,41 @@ +#include "NetworkPlayer.h" +#include + +RemotePlayer* RemotePlayer::mInstance = NULL; +ProxyPlayer* ProxyPlayer::mInstance = NULL; + +void RegisterNetworkPlayers() +{ +// JNetwork::registerCommand("GetPlayer", ProxyPlayer::Serialize, RemotePlayer::Deserialize); +} + + +RemotePlayer::RemotePlayer(JNetwork* pxNetwork) + : Player("remote", "", NULL), mpNetwork(pxNetwork) +{ + mInstance = this; + mpNetwork->sendCommand("GetPlayer"); +} + +void RemotePlayer::Deserialize(istream& in, ostream& out) +{ +// istringstream ss(mInstance->mpNetwork->receiveString()); + in >> *mInstance; +} + + +ProxyPlayer::ProxyPlayer(Player* pxPlayer, JNetwork* pxNetwork) + : mpPlayer(pxPlayer), mpNetwork(pxNetwork) +{ + mInstance = this; + JNetwork::registerCommand("GetPlayer", ProxyPlayer::Serialize, RemotePlayer::Deserialize); + +// ostringstream ss; +// ss << "Player : " << *mpPlayer; +// mpNetwork->send(ss.str()); +} + +void ProxyPlayer::Serialize(istream& in, ostream& out) +{ + out << *(mInstance->mpPlayer); +} diff --git a/projects/mtg/src/Player.cpp b/projects/mtg/src/Player.cpp index 48ac0c529..c9334e2ea 100644 --- a/projects/mtg/src/Player.cpp +++ b/projects/mtg/src/Player.cpp @@ -5,9 +5,16 @@ #include "DeckStats.h" #include "ManaCost.h" -Player::Player(MTGDeck * deck, string file, string fileSmall) : +Player::Player(string file, string fileSmall, MTGDeck * deck) : Damageable(20) { + bool deleteDeckPlease = false; + if(deck == NULL && file != "testsuite" && file != "remote") + { + deck = NEW MTGDeck(file.c_str(), MTGCollection()); + deleteDeckPlease = true; + } + game = NULL; deckFile = file; deckFileSmall = fileSmall; @@ -25,6 +32,10 @@ Damageable(20) game->setOwner(this); deckName = deck->meta_name; } + if(deleteDeckPlease) + { + SAFE_DELETE(deck); + } } /*Method to call at the end of a game, before all objects involved in the game are destroyed */ @@ -87,8 +98,8 @@ Player * Player::opponent() return this == game->players[0] ? game->players[1] : game->players[0]; } -HumanPlayer::HumanPlayer(MTGDeck * deck, string file, string fileSmall) : - Player(deck, file, fileSmall) +HumanPlayer::HumanPlayer(string file, string fileSmall, MTGDeck * deck) : + Player(file, fileSmall, deck) { loadAvatar("avatar.jpg"); playMode = MODE_HUMAN; @@ -203,6 +214,7 @@ istream& operator>>(istream& in, Player& p) } in >> *(p.game); + p.game->setOwner(&p); return in; } diff --git a/projects/mtg/src/Rules.cpp b/projects/mtg/src/Rules.cpp index 2da693b19..3416680c2 100644 --- a/projects/mtg/src/Rules.cpp +++ b/projects/mtg/src/Rules.cpp @@ -191,7 +191,11 @@ void Rules::addExtraRules() if (p->playMode != Player::MODE_TEST_SUITE && g->mRules->gamemode != GAME_TYPE_MOMIR && g->mRules->gamemode != GAME_TYPE_RANDOM1 && g->mRules->gamemode != GAME_TYPE_RANDOM2 && g->mRules->gamemode != GAME_TYPE_STORY && - g->mRules->gamemode != GAME_TYPE_DEMO && (!g->players[0] == PLAYER_TYPE_CPU && !g->players[1] == PLAYER_TYPE_CPU))//keep this out of mimor and other game modes. + g->mRules->gamemode != GAME_TYPE_DEMO && (!g->players[0] == PLAYER_TYPE_CPU && !g->players[1] == PLAYER_TYPE_CPU) +#ifdef NETWORK_SUPPORT + && !g->players[1] == PLAYER_TYPE_REMOTE +#endif //NETWORK_SUPPORT + )//keep this out of mimor and other game modes. { difficultyRating = DeckManager::getDifficultyRating(g->players[0], g->players[1]); } @@ -273,9 +277,9 @@ Player * Rules::loadPlayerMomir(int isAI) Player *player = NULL; if (!isAI) // Human Player - player = NEW HumanPlayer(tempDeck, options.profileFile("momir.txt", "", true).c_str(), deckFileSmall); + player = NEW HumanPlayer(options.profileFile("momir.txt", "", true).c_str(), deckFileSmall, tempDeck); else - player = NEW AIMomirPlayer(tempDeck, options.profileFile("momir.txt", "", true).c_str(), deckFileSmall, empty); + player = NEW AIMomirPlayer(options.profileFile("momir.txt", "", true).c_str(), deckFileSmall, empty, tempDeck); delete tempDeck; return player; @@ -308,9 +312,9 @@ Player * Rules::loadPlayerRandom(int isAI, int mode) Player *player = NULL; if (!isAI) // Human Player - player = NEW HumanPlayer(tempDeck, deckFile, deckFileSmall); + player = NEW HumanPlayer(deckFile, deckFileSmall, tempDeck); else - player = NEW AIPlayerBaka(tempDeck, deckFile, deckFileSmall, ""); + player = NEW AIPlayerBaka(deckFile, deckFileSmall, "", tempDeck); delete tempDeck; return player; diff --git a/projects/mtg/src/StoryFlow.cpp b/projects/mtg/src/StoryFlow.cpp index 45127982b..c479c602c 100644 --- a/projects/mtg/src/StoryFlow.cpp +++ b/projects/mtg/src/StoryFlow.cpp @@ -305,16 +305,12 @@ void StoryDuel::init() sprintf(folder, JGE_GET_RES(CAMPAIGNS_FOLDER"%s/%s").c_str(), mParent->folder.c_str(), pageId.c_str()); sprintf(deckFile, "%s/deck.txt", folder); - MTGDeck * tempDeck = NEW MTGDeck(deckFile, MTGCollection()); sprintf(deckFileSmall, "campaign_%s", mParent->folder.c_str()); - players[0] = NEW HumanPlayer(tempDeck, deckFile, deckFileSmall); - SAFE_DELETE(tempDeck); + players[0] = NEW HumanPlayer(deckFile, deckFileSmall); sprintf(deckFile, "%s/opponent_deck.txt", folder); - tempDeck = NEW MTGDeck(deckFile, MTGCollection()); sprintf(deckFileSmall, "campaign_ennemy_%s_%s", mParent->folder.c_str(), pageId.c_str()); - players[1] = NEW AIPlayerBaka(tempDeck, deckFile, deckFileSmall, "baka.jpg"); - SAFE_DELETE(tempDeck); + players[1] = NEW AIPlayerBaka(deckFile, deckFileSmall, "baka.jpg"); string rulesFile = folder; rulesFile.append("/rules.txt"); diff --git a/projects/mtg/src/TestSuiteAI.cpp b/projects/mtg/src/TestSuiteAI.cpp index 7ed5f4ab1..f912710b1 100644 --- a/projects/mtg/src/TestSuiteAI.cpp +++ b/projects/mtg/src/TestSuiteAI.cpp @@ -16,7 +16,7 @@ using std::string; // NULL is sent in place of a MTGDeck since there is no way to create a MTGDeck without a proper deck file. // TestSuiteAI will be responsible for managing its own deck state. TestSuiteAI::TestSuiteAI(TestSuite * _suite, int playerId) : - AIPlayerBaka(NULL, "testsuite", "testsuite", "baka.jpg") + AIPlayerBaka("testsuite", "testsuite", "baka.jpg", NULL) { this->game = _suite->buildDeck(playerId); game->setOwner(this);