Avrei preferito non farlo, dato che le altre funzioni sono scritte ancora peggio del game. Ma se sostieni che non ci sia altro da fare...
bool prepareClient(int id)
{
bool done = true;
bool playerFound = false;
char buffer[MAX_BUFFER];
Socket::Status sstatus = Socket::Done;
size_t receivedBytes;
string stringBuffer;
string data[50];
stringstream ss;
int i = 0;
if(client[id].type == "helm")
{
client[id].status = "Looking for weapons";
stringBuffer = "WAIT";
memset(buffer, '\0', MAX_BUFFER);
strcpy(buffer, stringBuffer.c_str());
if(sstatus == Socket::Done)
{
while(client[id].mate == "no_mate" && done)
{
sleep(milliseconds(100));
sstatus = client[id].socket.send(buffer, MAX_BUFFER);
if(sstatus != Socket::Done and sstatus != Socket::NotReady)
done = false;
}
if (done == false)
{
cout <<"Error: client " <<id <<" disconnected." <<endl;
client[id].clean();
}
if(client[id].mate != "no_mate")
{
cout <<client[id].nickname <<" connected with " <<client[id].mate <<endl;
client[id].status = "In Game";
ss.str(string());
ss << id;
stringBuffer = "IN_GAME|" + ss.str();
Ship ship(id, client[id].mateid, "basic");
ships.push_back(ship);
//client[id].helm.initialize(0, 0, id, "basic", 100, 0);
memset(buffer, '\0', MAX_BUFFER);
strcpy(buffer, stringBuffer.c_str());
sstatus = client[id].socket.send(buffer, MAX_BUFFER);
thread communicate(communicationThread, id);
communicate.detach();
}
}
if (sstatus != Socket::Done && done == true)
{
cout <<"Error: client " <<id <<" disconnected." <<endl;
client[id].clean();
done = false;
}
}
else
{
while(done == true and client[id].status != "In Game")
{
stringBuffer = "SELECT_NICKNAMES";
i = 0;
while(i < MAX_CLIENTS)
{
if(client[i].status == "Looking for weapons")
{
stringBuffer = stringBuffer + "|" + client[i].nickname;
}
i++;
}
memset(buffer, '\0', MAX_BUFFER);
strcpy(buffer, stringBuffer.c_str());
sstatus = client[id].socket.send(buffer, MAX_BUFFER);
if(sstatus == Socket::Done)
{
sstatus = client[id].socket.receive(buffer, MAX_BUFFER, receivedBytes);
cout <<sizeof(buffer)<< " "<< receivedBytes <<endl;
if(sstatus == Socket::Done)
{
stringBuffer = buffer;
if(stringBuffer != "SEND_AGAIN")
{
i = 0;
while(i < MAX_CLIENTS)
{
if(client[i].status == "Looking for weapons" && stringBuffer == client[i].nickname && !playerFound)
{
client[id].mateid = client[i].id;
client[id].mate = client[i].nickname;
client[i].mate = client[id].nickname;
client[i].mateid = id;
playerFound = true;
//weapons[id].initialize(0, 0, id, "basic", 10);
client[id].status = "In Game";
ss.str(string());
ss << client[id].mateid;
stringBuffer = "IN_GAME|" + ss.str();
//client[id].helm.initialize(0, 0, id, "basic", 100, 0);
memset(buffer, '\0', MAX_BUFFER);
strcpy(buffer, stringBuffer.c_str());
sstatus = client[id].socket.send(buffer, MAX_BUFFER);
thread communicate(communicationThread, id);
communicate.detach();
}
i++;
}
if (!playerFound)
{
stringBuffer = "INVALID_PLAYER";
memset(buffer, '\0', MAX_BUFFER);
strcpy(buffer, stringBuffer.c_str());
sstatus = client[id].socket.send(buffer, MAX_BUFFER);
}
}
else
{
sleep(seconds(1));
}
}
}
if (sstatus != Socket::Done && sstatus != Socket::NotReady)
{
cout <<"Error: client " <<id <<" disconnected." <<endl;
client[id].clean();
done = false;
}
}
}
cout <<"USCITO"<<endl;
return done;
}
int manageClient(int id)
{
int result = 0;
int i = 0;
char buffer[MAX_BUFFER];
string stringBuffer;
string data[50];
Socket::Status sstatus = Socket::Done;
size_t receivedBytes;
bool error = false;
bool sent = false;
buffer[0] = '0';
client[id].ipAddress = client[id].socket.getRemoteAddress().toString();
client[id].id = id;
sstatus = client[id].socket.receive(buffer, MAX_BUFFER, receivedBytes);
do
{
if (sstatus == Socket::Done)
{
stringBuffer = buffer;
fragmentString(stringBuffer, "|", data);
while(i < MAX_CLIENTS)
{
if(!client[i].nickname.empty() and data[0] == client[i].nickname)
{
error = true;
}
i++;
}
i = 0;
if(error == false)
{
if(data[1] != "weapons" and data[1] != "helm")
error = true;
if(error == false)
{
client[id].nickname = data[0];
client[id].type = data[1];
cout <<"Client " <<id <<" has '" <<client[id].nickname <<"' as nickname and is a " <<client[id].type <<"." <<endl;
stringBuffer = "OK";
strcpy(buffer, stringBuffer.c_str());
sstatus = client[id].socket.send(buffer, MAX_BUFFER);
client[id].status = "Waiting game";
sent = true;
}
}
if (error == true)
{
stringBuffer = "ERROR:SEND AGAIN";
strcpy(buffer, stringBuffer.c_str());
sstatus = client[id].socket.send(buffer, MAX_BUFFER);
sstatus = client[id].socket.receive(buffer, MAX_BUFFER, receivedBytes);
error = false;
}
}
if(sstatus == Socket::Partial)
{
cout <<"Error: partial data received on client " <<id <<"." <<endl;
client[id].clean();
}
if(sstatus == Socket::Disconnected)
{
cout <<"Error: Client " <<id <<" disconnected" <<endl;
client[id].clean();
}
if(sstatus == Socket::Error)
{
cout <<"Error: Internal Error for client " <<id <<"." <<endl;
client[id].clean();
}
}
while(sstatus != Socket::Partial and sstatus != Socket::Disconnected and sstatus != Socket::Error and sent != true);
return result;
}
void communicationThread(int id) //shareyourmenu.ddns.net
{
Socket::Status status = Socket::Done;
string inputString, outputString;
string data[50];
stringstream ss;
list<ServerStatus>::iterator sStatus; //Server status
list<Ship>::iterator shipsItr;
char buffer[MAX_BUFFER];
size_t received;
client[id].socket.setBlocking(true);
while(status == Socket::Done || status == Socket::NotReady)
{
/*RECEIVE PHASE******************************/
memset(buffer, '\0', MAX_BUFFER);
//sleep(milliseconds(5));
status = client[id].socket.receive(buffer, MAX_BUFFER, received);
if (status == Socket::Done || status == Socket::NotReady)
{
if (!client[id].input.readable && status == Socket::Done && buffer[0] != '\0')
{
inputString = buffer;
fragmentString(inputString, "|", data);
if(!(data[0].empty()) && !(data[1].empty()) && !(data[2].empty()) && !(data[3].empty()) && !(data[4].empty()))
{
client[id].input.mousex = atoi(data[0].c_str());
client[id].input.mousey = atoi(data[1].c_str());
if(data[2] == "t")
client[id].input.leftMouseKey = true;
else
client[id].input.leftMouseKey = false;
if(data[3] == "t")
client[id].input.rightMouseKey = true;
else
client[id].input.rightMouseKey = false;
client[id].input.rotation = (float)atoi(data[4].c_str());
client[id].input.readable = true;
}
//sleep(milliseconds(5));
}
//cout <<"Received " <<inputString <<endl;
//cout <<"Received from " <<id <<" " <<client[id].input.mousex <<" " <<client[id].input.mousey <<" " <<client[id].input.leftMouseKey <<" " <<client[id].input.rightMouseKey <<" " <<client[id].input.rotation <<endl;
/*SEND PHASE******************************/
if(!serverStatus.empty())
{
outputString.clear();
sStatus = serverStatus.begin();
sStatus->nThreads->push_back(1);
shipsItr = sStatus->ships->begin();
while(shipsItr != sStatus->ships->end())
{
ss.str(string());
ss << "PL|";
ss << shipsItr->getPlayerId();
ss << "|";
ss << shipsItr->x;
ss << "|";
ss << shipsItr->y;
ss << "|";
ss << shipsItr->rotation;
ss << "|";
ss << shipsItr->weapon->rotation;
ss << "|";
if (shipsItr->moving)
ss << "t";
else
ss << "f";
ss << "|";
outputString = outputString + ss.str();
//cout <<"String: " <<outputString <<endl;
shipsItr++;
}
sStatus->nThreads->pop_back();
}
memset(buffer, '\0', MAX_BUFFER);
//cout <<outputString.size()<<endl;7
if (outputString.size() < MAX_BUFFER - 100)
strcpy(buffer, outputString.c_str());
else
cout <<"String too big"<<endl;
status = client[id].socket.send(buffer, MAX_BUFFER);
}
}
if (status != Socket::Done && status != Socket::NotReady)
{
cout <<"Client disconnected: " <<id <<"." <<endl;
client[id].clean();
}
}
Nel mentre che le leggi, e soprattutto
quando leggi come invio i messaggi con il TCP, ricordati che è un prototipo. Mi basta che resti acceso per qualche minuto. (questo della memoria invece è un problema che non ho nessuna idea di come risolvere, e sarebbe un problema che mi porterei anche nella versione stabile).
Da ciò che so nessuno di questi thread davvero fanno qualcosa alla memoria, e sono certo al 99,99%. L'unica cosa che
sembra faccia sovraccaricare la memoria è creare l'oggetto.