void NetworkThread::ReceiveActions() { char* buffer; size_t packet_size; Network* net = Network::GetInstance(); std::list<DistantComputer*>::iterator dst_cpu; std::list<DistantComputer*>& cpu = net->GetRemoteHosts(); // While the connection is up while (Continue()) { if (net->GetState() == WNet::NETWORK_PLAYING && cpu.empty()) { // If while playing everybody disconnected, just quit break; } //Loop while nothing is received while (Continue()) { IndexServer::GetInstance()->Refresh(); // Check forced disconnections dst_cpu = cpu.begin(); while (Continue() && dst_cpu != cpu.end()) { // Disconnection is in 2 phases to be handled by one thread if ((*dst_cpu)->MustBeDisconnected()) { net->CloseConnection(dst_cpu); dst_cpu = cpu.begin(); } else dst_cpu++; } // List is now maybe empty if (cpu.empty() && net->IsClient()) { fprintf(stderr, "you are alone!\n"); Stop(); return; // We really don't need to go through the loops } net->WaitActionSleep(); int num_ready = net->CheckActivity(100); // Means something is available if (num_ready>0) break; // Means an error else if (num_ready == -1) { //Spams a lot under windows without the errno check... fprintf(stderr, "SDLNet_CheckSockets: %s\n", SDLNet_GetError()); continue; //Or break? } } for (dst_cpu = cpu.begin(); Continue() && dst_cpu != cpu.end(); dst_cpu++) { // Check if this socket contains data to receive if ((*dst_cpu)->SocketReady()) { if (!(*dst_cpu)->ReceiveData(&buffer, &packet_size)) { // An error occured during the reception (*dst_cpu)->ForceDisconnection(); continue; } if (!buffer && !packet_size) { // Client is valid but there is not yet enough data to read an action continue; } #ifdef LOG_NETWORK if (fin != 0) { int tmp = 0xFFFFFFFF; write(fin, &packet_size, 4); write(fin, buffer, packet_size); write(fin, &tmp, 4); } #endif Action* a = new Action(buffer, (*dst_cpu)); free(buffer); MSG_DEBUG("network.traffic", "Received action %s", ActionHandler::GetActionName(a->GetType()).c_str()); net->HandleAction(a, *dst_cpu); } } } }