Clients now connect and recieve gamestate information
This commit is contained in:
parent
4285770d52
commit
56e767bb5b
5 changed files with 109 additions and 45 deletions
|
@ -71,10 +71,17 @@ int runClient(int argc, char* argv[])
|
||||||
|
|
||||||
while ( n >= 0 )
|
while ( n >= 0 )
|
||||||
{
|
{
|
||||||
// Get the message to send
|
|
||||||
printf("Please enter the message: ");
|
|
||||||
memset(buffer,0,sizeof(buffer));
|
memset(buffer,0,sizeof(buffer));
|
||||||
fgets(buffer,sizeof(buffer)-1,stdin);
|
|
||||||
|
// Receive gamestate
|
||||||
|
if (read(sockfd,buffer,sizeof(buffer)-1) < 0)
|
||||||
|
error("ERROR reading from client");
|
||||||
|
|
||||||
|
std::cout<<buffer<<std::endl;
|
||||||
|
|
||||||
|
// Output orders
|
||||||
|
memset(buffer,0,sizeof(buffer));
|
||||||
|
strcpy(buffer, "ORDER:F id:1\nEND");
|
||||||
|
|
||||||
// Place a test message into the buffer
|
// Place a test message into the buffer
|
||||||
strncpy(buffer,buffer,sizeof(buffer));
|
strncpy(buffer,buffer,sizeof(buffer));
|
||||||
|
|
|
@ -79,17 +79,13 @@ std::string getGamesDir()
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =====================================================================================================================
|
CTTRTSGame GetGameFromFile( const std::string& filename )
|
||||||
int runFromFilesystem(int argc, char* argv[])
|
|
||||||
{
|
{
|
||||||
std::string gamefile = argv[1];
|
std::string gamefile = filename;
|
||||||
|
|
||||||
// Default for maps
|
// Default for maps
|
||||||
std::string ttrts_maps_dir = getMapsDir();
|
std::string ttrts_maps_dir = getMapsDir();
|
||||||
|
|
||||||
// Default for games
|
|
||||||
std::string ttrts_games_dir = getGamesDir();
|
|
||||||
|
|
||||||
// If file path is not local path and file doesn't exist
|
// If file path is not local path and file doesn't exist
|
||||||
if( gamefile.find("/") == std::string::npos
|
if( gamefile.find("/") == std::string::npos
|
||||||
&& access( gamefile.c_str(), F_OK ) == -1 )
|
&& access( gamefile.c_str(), F_OK ) == -1 )
|
||||||
|
@ -101,13 +97,11 @@ int runFromFilesystem(int argc, char* argv[])
|
||||||
if( access( gamefile.c_str(), F_OK ) == -1 )
|
if( access( gamefile.c_str(), F_OK ) == -1 )
|
||||||
{
|
{
|
||||||
std::cerr<<"Error: "<< gamefile <<" file not found"<<std::endl;
|
std::cerr<<"Error: "<< gamefile <<" file not found"<<std::endl;
|
||||||
return -1;
|
return CTTRTSGame(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ifstream file(gamefile);
|
std::ifstream file(gamefile);
|
||||||
|
|
||||||
std::cout<<"Launching TTRTS with "<<gamefile<<std::endl;
|
|
||||||
|
|
||||||
std::string gameDescriptor;
|
std::string gameDescriptor;
|
||||||
|
|
||||||
// Reserve the string needed up front
|
// Reserve the string needed up front
|
||||||
|
@ -121,15 +115,27 @@ int runFromFilesystem(int argc, char* argv[])
|
||||||
if( gameDescriptor.size() == 0 )
|
if( gameDescriptor.size() == 0 )
|
||||||
{
|
{
|
||||||
std::cerr<<"Error: failed to read in any information from "<<gamefile<<std::endl;
|
std::cerr<<"Error: failed to read in any information from "<<gamefile<<std::endl;
|
||||||
return -1;
|
return CTTRTSGame(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the game
|
// Create the game
|
||||||
CTTRTSGame game = GetGameFromString(gameDescriptor);
|
return GetGameFromString(gameDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =====================================================================================================================
|
||||||
|
int runFromFilesystem(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
std::string gamefile = argv[1];
|
||||||
|
|
||||||
|
std::cout<<"Launching TTRTS with "<<gamefile<<std::endl;
|
||||||
|
CTTRTSGame game = GetGameFromFile(gamefile);
|
||||||
|
|
||||||
// Grab the players involved
|
// Grab the players involved
|
||||||
auto players = game.GetPlayers();
|
auto players = game.GetPlayers();
|
||||||
|
|
||||||
|
// Default for games
|
||||||
|
std::string ttrts_games_dir = getGamesDir();
|
||||||
|
|
||||||
// Current game directory
|
// Current game directory
|
||||||
std::string gameDir = ttrts_games_dir + game.GetName();
|
std::string gameDir = ttrts_games_dir + game.GetName();
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@ void WaitForFile( const std::string& name, const std::chrono::milliseconds& time
|
||||||
|
|
||||||
bool OutputGameStateFile(CTTRTSGame &game, const std::string &gameDir);
|
bool OutputGameStateFile(CTTRTSGame &game, const std::string &gameDir);
|
||||||
|
|
||||||
|
CTTRTSGame GetGameFromFile( const std::string& file );
|
||||||
|
|
||||||
std::string getMapsDir();
|
std::string getMapsDir();
|
||||||
std::string getGamesDir();
|
std::string getGamesDir();
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -14,35 +15,35 @@
|
||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <game.h>
|
||||||
|
#include <formatters.h>
|
||||||
|
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
#include "filesystem.h"
|
||||||
|
|
||||||
std::vector<std::thread> gClientThreads;
|
// Struct for net client info
|
||||||
|
struct ClientInfo
|
||||||
int clientHandler( sockaddr_in cli_addr, socklen_t clilen, int clientsockfd)
|
|
||||||
{
|
{
|
||||||
std::cout<<"Client connected from "<<inet_ntoa(cli_addr.sin_addr)<<std::endl;
|
sockaddr_in cli_addr;
|
||||||
|
int clientsockfd;
|
||||||
|
};
|
||||||
|
|
||||||
char buffer[1028]; // buffer for socked read
|
int waitForOrdersFromClient(const ClientInfo& info, std::mutex& mut, CTTRTSGame& game )
|
||||||
|
{
|
||||||
|
char buffer[1028]; // buffer for orders
|
||||||
memset(buffer,0,sizeof(buffer));
|
memset(buffer,0,sizeof(buffer));
|
||||||
|
|
||||||
// loop
|
// Read in the new socket
|
||||||
int n = 0; // return value for read and write calls
|
// read will block until the client has called write
|
||||||
while( n >= 0 )
|
// up to the full size of the buffer
|
||||||
{
|
if (read(info.clientsockfd,buffer,sizeof(buffer)-1) < 0)
|
||||||
// empty the buffer
|
error("ERROR reading from client");
|
||||||
memset(buffer,0,sizeof(buffer));
|
|
||||||
|
|
||||||
// Read in the new socket
|
std::cout<<"Recieved orders from "<<inet_ntoa(info.cli_addr.sin_addr)<<std::endl;
|
||||||
// read will block until the client has called write
|
|
||||||
// up to the full size of the buffer
|
|
||||||
n = read(clientsockfd,buffer,sizeof(buffer)-1);
|
|
||||||
if (n < 0)
|
|
||||||
error("ERROR reading from socket");
|
|
||||||
|
|
||||||
// print the message recieved
|
mut.lock();
|
||||||
printf("%s",buffer);
|
game.IssueOrders(player_t::Red , buffer);
|
||||||
}
|
mut.unlock();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -98,20 +99,26 @@ int runServer(int argc, char* argv[])
|
||||||
// max is usually set to 5
|
// max is usually set to 5
|
||||||
listen(sockfd,5);
|
listen(sockfd,5);
|
||||||
|
|
||||||
|
// Set up game
|
||||||
|
CTTRTSGame game = GetGameFromFile("Tiny2Player.txt");
|
||||||
|
unsigned int numClients = game.GetPlayers().size();
|
||||||
|
|
||||||
|
// game mutex
|
||||||
|
std::mutex gameMutex;
|
||||||
|
|
||||||
|
// Set of clients
|
||||||
|
std::vector<ClientInfo> myClients;
|
||||||
|
|
||||||
std::cout<<"Waiting for clients"<<std::endl;
|
std::cout<<"Waiting for clients"<<std::endl;
|
||||||
|
|
||||||
// Loop while we're connecting the clients
|
// Loop while we're connecting the clients
|
||||||
bool connectingClients = true;
|
while ( myClients.size() < numClients )
|
||||||
while ( connectingClients )
|
|
||||||
{
|
{
|
||||||
|
|
||||||
// information for each client
|
// information for each client
|
||||||
sockaddr_in cli_addr; // Client address
|
sockaddr_in cli_addr; // Client address
|
||||||
socklen_t clilen; // length of client address
|
|
||||||
int clientsockfd; // new socket File descriptor
|
int clientsockfd; // new socket File descriptor
|
||||||
|
|
||||||
clilen = sizeof(sockaddr_in);
|
socklen_t clilen = sizeof(sockaddr_in);
|
||||||
|
|
||||||
|
|
||||||
// accept waits for a connection from a client
|
// accept waits for a connection from a client
|
||||||
// it returns a new socket file descriptor for this connection
|
// it returns a new socket file descriptor for this connection
|
||||||
|
@ -120,12 +127,54 @@ int runServer(int argc, char* argv[])
|
||||||
if (clientsockfd < 0)
|
if (clientsockfd < 0)
|
||||||
error("ERROR on accept");
|
error("ERROR on accept");
|
||||||
|
|
||||||
std::cout<<"Client recieved"<<std::endl;
|
std::cout<<"Client connected from "<<inet_ntoa(cli_addr.sin_addr)<<std::endl;
|
||||||
std::thread clientThread = std::thread(clientHandler,cli_addr,clilen,clientsockfd);
|
myClients.push_back({cli_addr,clientsockfd});
|
||||||
|
|
||||||
gClientThreads.push_back(std::move(clientThread));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout<<"All clients connected"<<std::endl;
|
||||||
|
|
||||||
|
// Loop for each turn
|
||||||
|
while ( !game.GameOver() )
|
||||||
|
{
|
||||||
|
// Grab the current game state string
|
||||||
|
gameMutex.lock();
|
||||||
|
std::string gamestate_string = GetStringFromGame(game);
|
||||||
|
gameMutex.unlock();
|
||||||
|
|
||||||
|
// Send data to clients
|
||||||
|
std::cout<<"Sending clients gamedata"<<std::endl;
|
||||||
|
for (auto client : myClients)
|
||||||
|
{
|
||||||
|
// Write to the socket with the buffer
|
||||||
|
if ( write( client.clientsockfd, gamestate_string.c_str(), gamestate_string.length() ) < 0 )
|
||||||
|
error("ERROR sending to client");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for orders from clients
|
||||||
|
std::cout<<"Waiting for client orders"<<std::endl;
|
||||||
|
|
||||||
|
std::vector<std::thread> clientThreads;
|
||||||
|
for(auto client : myClients)
|
||||||
|
{
|
||||||
|
std::thread clientThread(waitForOrdersFromClient,std::ref(client), std::ref(gameMutex), std::ref(game));
|
||||||
|
clientThreads.push_back(std::move(clientThread));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Join up all the threads
|
||||||
|
for ( std::thread& thread : clientThreads )
|
||||||
|
{
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step to the next turn
|
||||||
|
gameMutex.lock();
|
||||||
|
game.SimulateToNextTurn();
|
||||||
|
gameMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// end game and disconnect clients
|
||||||
|
|
||||||
// Return
|
// Return
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
|
@ -33,7 +33,7 @@ int main()
|
||||||
//------
|
//------
|
||||||
{
|
{
|
||||||
CTTRTSGame game(6, 6);
|
CTTRTSGame game(6, 6);
|
||||||
game.SetName("Tiny2player");
|
game.SetName("Tiny2Player");
|
||||||
|
|
||||||
AddUnitToGame( player_t::Red, '<', uvector2(4, 2), game);
|
AddUnitToGame( player_t::Red, '<', uvector2(4, 2), game);
|
||||||
AddUnitToGame( player_t::Red, '<', uvector2(4, 4), game);
|
AddUnitToGame( player_t::Red, '<', uvector2(4, 4), game);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue