mirror of
https://github.com/glest/glest-source.git
synced 2025-02-24 19:52:25 +01:00
- Added partial threaded network server handling of incoming socket data to try to improve performance
- Small changes to client network handling to be more accurate and efficient - Added observer mode when a user loses a network game
This commit is contained in:
parent
9ab6732f86
commit
1ae2a9ae10
@ -37,11 +37,13 @@ ChatManager::ChatManager(){
|
||||
editEnabled= false;
|
||||
teamMode= false;
|
||||
thisTeamIndex= -1;
|
||||
disableTeamMode = false;
|
||||
}
|
||||
|
||||
void ChatManager::init(Console* console, int thisTeamIndex){
|
||||
this->console= console;
|
||||
this->thisTeamIndex= thisTeamIndex;
|
||||
this->disableTeamMode= false;
|
||||
}
|
||||
|
||||
void ChatManager::keyUp(char key){
|
||||
@ -64,6 +66,13 @@ void ChatManager::keyUp(char key){
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
}
|
||||
|
||||
void ChatManager::setDisableTeamMode(bool value) {
|
||||
disableTeamMode = value;
|
||||
|
||||
if(disableTeamMode == true) {
|
||||
teamMode = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ChatManager::keyDown(char key){
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
@ -72,7 +81,7 @@ void ChatManager::keyDown(char key){
|
||||
Lang &lang= Lang::getInstance();
|
||||
|
||||
//toggle team mode
|
||||
if(!editEnabled && key=='H'){
|
||||
if(editEnabled == false && disableTeamMode == false && key=='H') {
|
||||
if(teamMode){
|
||||
teamMode= false;
|
||||
console->addLine(lang.get("ChatMode") + ": " + lang.get("All"));
|
||||
|
@ -31,6 +31,7 @@ private:
|
||||
private:
|
||||
bool editEnabled;
|
||||
bool teamMode;
|
||||
bool disableTeamMode;
|
||||
Console* console;
|
||||
string text;
|
||||
int thisTeamIndex;
|
||||
@ -47,6 +48,9 @@ public:
|
||||
bool getEditEnabled() const {return editEnabled;}
|
||||
bool getTeamMode() const {return teamMode;}
|
||||
string getText() const {return text;}
|
||||
|
||||
bool getDisableTeamMode() const { return disableTeamMode; }
|
||||
void setDisableTeamMode(bool value);
|
||||
};
|
||||
|
||||
}}//end namespace
|
||||
|
@ -375,17 +375,17 @@ Command* Commander::buildCommand(const NetworkCommand* networkCommand) const{
|
||||
//validate unit
|
||||
if(unit == NULL) {
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"In [%s::%s - %d] Can not find unit with id: %d. Game out of synch.",__FILE__,__FUNCTION__,__LINE__,networkCommand->getUnitId());
|
||||
sprintf(szBuf,"In [%s::%s Line: %d] Can not find unit with id: %d. Game out of synch.",__FILE__,__FUNCTION__,__LINE__,networkCommand->getUnitId());
|
||||
throw runtime_error(szBuf);
|
||||
}
|
||||
else if(unit->getType() == NULL) {
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"In [%s::%s - %d] unit->getType() == NULL for unit with id: %d",__FILE__,__FUNCTION__,__LINE__,networkCommand->getUnitId());
|
||||
sprintf(szBuf,"In [%s::%s Line: %d] unit->getType() == NULL for unit with id: %d",__FILE__,__FUNCTION__,__LINE__,networkCommand->getUnitId());
|
||||
throw runtime_error(szBuf);
|
||||
}
|
||||
else if(unit->getFaction() == NULL) {
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"In [%s::%s - %d] unit->getFaction() == NULL for unit with id: %d",__FILE__,__FUNCTION__,__LINE__,networkCommand->getUnitId());
|
||||
sprintf(szBuf,"In [%s::%s Line: %d] unit->getFaction() == NULL for unit with id: %d",__FILE__,__FUNCTION__,__LINE__,networkCommand->getUnitId());
|
||||
throw runtime_error(szBuf);
|
||||
}
|
||||
|
||||
@ -395,8 +395,8 @@ Command* Commander::buildCommand(const NetworkCommand* networkCommand) const{
|
||||
//validate command type
|
||||
if(ct == NULL) {
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"In [%s::%s - %d] Can not find command type with id = %d\n%s\n in unit = %d [%s][%s].\nGame out of synch.",
|
||||
__FILE__,__FUNCTION__,__LINE__,networkCommand->getCommandTypeId(),unit->getType()->getCommandTypeListDesc().c_str(),unit->getId(), unit->getFullName().c_str(),unit->getDesc().c_str());
|
||||
sprintf(szBuf,"In [%s::%s Line: %d] Can not find command type for network command = [%s]\n%s\n in unit = %d [%s][%s].\nGame out of synch.",
|
||||
__FILE__,__FUNCTION__,__LINE__,networkCommand->toString().c_str(),unit->getType()->getCommandTypeListDesc().c_str(),unit->getId(), unit->getFullName().c_str(),unit->getDesc().c_str());
|
||||
|
||||
throw runtime_error(szBuf);
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Marti<74>o Figueroa
|
||||
@ -1061,36 +1060,43 @@ void Game::checkWinner(){
|
||||
void Game::checkWinnerStandard(){
|
||||
//lose
|
||||
bool lose= false;
|
||||
if(!hasBuilding(world.getThisFaction())){
|
||||
if(hasBuilding(world.getThisFaction()) == false) {
|
||||
lose= true;
|
||||
for(int i=0; i<world.getFactionCount(); ++i){
|
||||
if(!world.getFaction(i)->isAlly(world.getThisFaction())){
|
||||
for(int i=0; i<world.getFactionCount(); ++i) {
|
||||
if(world.getFaction(i)->isAlly(world.getThisFaction()) == false) {
|
||||
world.getStats()->setVictorious(i);
|
||||
}
|
||||
}
|
||||
gameOver= true;
|
||||
// Let the poor user watch everything unfold
|
||||
world.setFogOfWar(false);
|
||||
// but don't let him cheat via teamchat
|
||||
chatManager.setDisableTeamMode(true);
|
||||
showLoseMessageBox();
|
||||
}
|
||||
|
||||
//win
|
||||
if(!lose){
|
||||
if(lose == false) {
|
||||
bool win= true;
|
||||
for(int i=0; i<world.getFactionCount(); ++i){
|
||||
for(int i=0; i<world.getFactionCount(); ++i) {
|
||||
if(i!=world.getThisFactionIndex()){
|
||||
if(hasBuilding(world.getFaction(i)) && !world.getFaction(i)->isAlly(world.getThisFaction())){
|
||||
if(hasBuilding(world.getFaction(i)) && world.getFaction(i)->isAlly(world.getThisFaction()) == false) {
|
||||
win= false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if win
|
||||
if(win){
|
||||
for(int i=0; i< world.getFactionCount(); ++i){
|
||||
if(world.getFaction(i)->isAlly(world.getThisFaction())){
|
||||
if(win) {
|
||||
for(int i=0; i< world.getFactionCount(); ++i) {
|
||||
if(world.getFaction(i)->isAlly(world.getThisFaction())) {
|
||||
world.getStats()->setVictorious(i);
|
||||
}
|
||||
}
|
||||
gameOver= true;
|
||||
// Let the happy winner view everything left in the world
|
||||
world.setFogOfWar(false);
|
||||
|
||||
showWinMessageBox();
|
||||
}
|
||||
}
|
||||
@ -1169,7 +1175,14 @@ int Game::getUpdateLoops(){
|
||||
|
||||
void Game::showLoseMessageBox(){
|
||||
Lang &lang= Lang::getInstance();
|
||||
showMessageBox(lang.get("YouLose")+", "+lang.get("ExitGame?"), lang.get("BattleOver"), false);
|
||||
|
||||
NetworkManager &networkManager= NetworkManager::getInstance();
|
||||
if(networkManager.isNetworkGame() == true && networkManager.getNetworkRole() == nrServer) {
|
||||
showMessageBox(lang.get("YouLose")+", "+lang.get("ExitGameServer?"), lang.get("BattleOver"), false);
|
||||
}
|
||||
else {
|
||||
showMessageBox(lang.get("YouLose")+", "+lang.get("ExitGame?"), lang.get("BattleOver"), false);
|
||||
}
|
||||
}
|
||||
|
||||
void Game::showWinMessageBox(){
|
||||
|
@ -428,8 +428,7 @@ void ClientInterface::updateKeyframe(int frameCount)
|
||||
{
|
||||
bool done= false;
|
||||
|
||||
while(done == false)
|
||||
{
|
||||
while(done == false) {
|
||||
//wait for the next message
|
||||
waitForMessage();
|
||||
|
||||
@ -446,9 +445,10 @@ void ClientInterface::updateKeyframe(int frameCount)
|
||||
int waitCount = 0;
|
||||
//make sure we read the message
|
||||
NetworkMessageCommandList networkMessageCommandList;
|
||||
while(receiveMessage(&networkMessageCommandList) == false)
|
||||
{
|
||||
sleep(waitSleepTime);
|
||||
while(receiveMessage(&networkMessageCommandList) == false &&
|
||||
isConnected() == true) {
|
||||
//sleep(waitSleepTime);
|
||||
sleep(0);
|
||||
waitCount++;
|
||||
}
|
||||
|
||||
@ -456,8 +456,7 @@ void ClientInterface::updateKeyframe(int frameCount)
|
||||
|
||||
chrono.start();
|
||||
//check that we are in the right frame
|
||||
if(networkMessageCommandList.getFrameCount() != frameCount)
|
||||
{
|
||||
if(networkMessageCommandList.getFrameCount() != frameCount) {
|
||||
string sErr = "Network synchronization error, frame counts do not match";
|
||||
//throw runtime_error("Network synchronization error, frame counts do not match");
|
||||
sendTextMessage(sErr,-1);
|
||||
@ -468,8 +467,7 @@ void ClientInterface::updateKeyframe(int frameCount)
|
||||
}
|
||||
|
||||
// give all commands
|
||||
for(int i= 0; i<networkMessageCommandList.getCommandCount(); ++i)
|
||||
{
|
||||
for(int i= 0; i<networkMessageCommandList.getCommandCount(); ++i) {
|
||||
pendingCommands.push_back(*networkMessageCommandList.getCommand(i));
|
||||
}
|
||||
|
||||
@ -482,10 +480,12 @@ void ClientInterface::updateKeyframe(int frameCount)
|
||||
case nmtQuit:
|
||||
{
|
||||
NetworkMessageQuit networkMessageQuit;
|
||||
if(receiveMessage(&networkMessageQuit))
|
||||
{
|
||||
quit= true;
|
||||
//if(receiveMessage(&networkMessageQuit)) {
|
||||
while(receiveMessage(&networkMessageQuit) == false &&
|
||||
isConnected() == true) {
|
||||
sleep(0);
|
||||
}
|
||||
quit= true;
|
||||
done= true;
|
||||
}
|
||||
break;
|
||||
@ -493,12 +493,14 @@ void ClientInterface::updateKeyframe(int frameCount)
|
||||
case nmtText:
|
||||
{
|
||||
NetworkMessageText networkMessageText;
|
||||
if(receiveMessage(&networkMessageText))
|
||||
{
|
||||
chatText = networkMessageText.getText();
|
||||
chatSender = networkMessageText.getSender();
|
||||
chatTeamIndex = networkMessageText.getTeamIndex();
|
||||
while(receiveMessage(&networkMessageText) == false &&
|
||||
isConnected() == true) {
|
||||
sleep(0);
|
||||
}
|
||||
|
||||
chatText = networkMessageText.getText();
|
||||
chatSender = networkMessageText.getSender();
|
||||
chatTeamIndex = networkMessageText.getTeamIndex();
|
||||
}
|
||||
break;
|
||||
case nmtInvalid:
|
||||
@ -673,10 +675,8 @@ void ClientInterface::waitForMessage()
|
||||
chrono.start();
|
||||
|
||||
int waitLoopCount = 0;
|
||||
while(getNextMessageType(true) == nmtInvalid)
|
||||
{
|
||||
if(isConnected() == false)
|
||||
{
|
||||
while(getNextMessageType(true) == nmtInvalid) {
|
||||
if(isConnected() == false) {
|
||||
//throw runtime_error("Disconnected");
|
||||
sendTextMessage("Server has Disconnected.",-1);
|
||||
DisplayErrorMessage("Server has Disconnected.");
|
||||
@ -685,8 +685,7 @@ void ClientInterface::waitForMessage()
|
||||
return;
|
||||
}
|
||||
|
||||
if(chrono.getMillis() > messageWaitTimeout)
|
||||
{
|
||||
if(chrono.getMillis() > messageWaitTimeout) {
|
||||
//throw runtime_error("Timeout waiting for message");
|
||||
sendTextMessage("Timeout waiting for message",-1);
|
||||
DisplayErrorMessage("Timeout waiting for message");
|
||||
|
@ -60,15 +60,12 @@ ConnectionSlot::~ConnectionSlot()
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
void ConnectionSlot::update()
|
||||
{
|
||||
void ConnectionSlot::update() {
|
||||
update(true);
|
||||
}
|
||||
|
||||
void ConnectionSlot::update(bool checkForNewClients)
|
||||
{
|
||||
if(socket == NULL)
|
||||
{
|
||||
void ConnectionSlot::update(bool checkForNewClients) {
|
||||
if(socket == NULL) {
|
||||
if(networkGameDataSynchCheckOkMap) networkGameDataSynchCheckOkMap = false;
|
||||
if(networkGameDataSynchCheckOkTile) networkGameDataSynchCheckOkTile = false;
|
||||
if(networkGameDataSynchCheckOkTech) networkGameDataSynchCheckOkTech = false;
|
||||
@ -76,8 +73,7 @@ void ConnectionSlot::update(bool checkForNewClients)
|
||||
|
||||
// Is the listener socket ready to be read?
|
||||
//if(serverInterface->getServerSocket()->isReadable() == true)
|
||||
if(checkForNewClients == true)
|
||||
{
|
||||
if(checkForNewClients == true) {
|
||||
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] BEFORE accept new client connection, serverInterface->getOpenSlotCount() = %d\n",__FILE__,__FUNCTION__,serverInterface->getOpenSlotCount());
|
||||
bool hasOpenSlots = (serverInterface->getOpenSlotCount() > 0);
|
||||
if(serverInterface->getServerSocket()->hasDataToRead() == true) {
|
||||
@ -110,10 +106,8 @@ void ConnectionSlot::update(bool checkForNewClients)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(socket->isConnected())
|
||||
{
|
||||
else {
|
||||
if(socket->isConnected()) {
|
||||
chatText.clear();
|
||||
chatSender.clear();
|
||||
chatTeamIndex= -1;
|
||||
@ -121,7 +115,7 @@ void ConnectionSlot::update(bool checkForNewClients)
|
||||
NetworkMessageType networkMessageType= getNextMessageType();
|
||||
|
||||
//process incoming commands
|
||||
switch(networkMessageType){
|
||||
switch(networkMessageType) {
|
||||
|
||||
case nmtInvalid:
|
||||
break;
|
||||
@ -131,8 +125,7 @@ void ConnectionSlot::update(bool checkForNewClients)
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtText\n",__FILE__,__FUNCTION__);
|
||||
|
||||
NetworkMessageText networkMessageText;
|
||||
if(receiveMessage(&networkMessageText))
|
||||
{
|
||||
if(receiveMessage(&networkMessageText)) {
|
||||
chatText = networkMessageText.getText();
|
||||
chatSender = networkMessageText.getSender();
|
||||
chatTeamIndex = networkMessageText.getTeamIndex();
|
||||
@ -148,10 +141,8 @@ void ConnectionSlot::update(bool checkForNewClients)
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtCommandList\n",__FILE__,__FUNCTION__);
|
||||
|
||||
NetworkMessageCommandList networkMessageCommandList;
|
||||
if(receiveMessage(&networkMessageCommandList))
|
||||
{
|
||||
for(int i= 0; i<networkMessageCommandList.getCommandCount(); ++i)
|
||||
{
|
||||
if(receiveMessage(&networkMessageCommandList)) {
|
||||
for(int i= 0; i<networkMessageCommandList.getCommandCount(); ++i) {
|
||||
serverInterface->requestCommand(networkMessageCommandList.getCommand(i));
|
||||
}
|
||||
}
|
||||
@ -222,19 +213,15 @@ void ConnectionSlot::update(bool checkForNewClients)
|
||||
|
||||
if( networkGameDataSynchCheckOkMap == true &&
|
||||
networkGameDataSynchCheckOkTile == true &&
|
||||
networkGameDataSynchCheckOkTech == true) // &&
|
||||
//networkGameDataSynchCheckOkFogOfWar == true)
|
||||
{
|
||||
networkGameDataSynchCheckOkTech == true) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] client data synch ok\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] mapCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,mapCRC,networkMessageSynchNetworkGameDataStatus.getMapCRC());
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] tilesetCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,tilesetCRC,networkMessageSynchNetworkGameDataStatus.getTilesetCRC());
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] techCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,techCRC,networkMessageSynchNetworkGameDataStatus.getTechCRC());
|
||||
|
||||
if(allowDownloadDataSynch == true)
|
||||
{
|
||||
if(allowDownloadDataSynch == true) {
|
||||
// Now get all filenames with their CRC values and send to the client
|
||||
vctFileList.clear();
|
||||
|
||||
@ -250,34 +237,27 @@ void ConnectionSlot::update(bool checkForNewClients)
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getGameSettings()->getScenarioDir().c_str(),serverInterface->getGameSettings()->getScenario().c_str(),scenarioDir.c_str());
|
||||
}
|
||||
|
||||
if(networkGameDataSynchCheckOkTile == false)
|
||||
{
|
||||
if(tilesetCRC == 0)
|
||||
{
|
||||
if(networkGameDataSynchCheckOkTile == false) {
|
||||
if(tilesetCRC == 0) {
|
||||
//vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_tilesets) + "/" + serverInterface->getGameSettings()->getTileset() + "/*", "", &vctFileList);
|
||||
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + serverInterface->getGameSettings()->getTileset() + string("/*"), "", &vctFileList);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
//vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_tilesets) + "/" + serverInterface->getGameSettings()->getTileset() + "/*", ".xml", &vctFileList);
|
||||
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTilesets,scenarioDir), "/" + serverInterface->getGameSettings()->getTileset() + "/*", ".xml", &vctFileList);
|
||||
}
|
||||
}
|
||||
if(networkGameDataSynchCheckOkTech == false)
|
||||
{
|
||||
if(techCRC == 0)
|
||||
{
|
||||
if(networkGameDataSynchCheckOkTech == false) {
|
||||
if(techCRC == 0) {
|
||||
//vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_techs) + "/" + serverInterface->getGameSettings()->getTech() + "/*", "", &vctFileList);
|
||||
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),"/" + serverInterface->getGameSettings()->getTech() + "/*", "", &vctFileList);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
//vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_techs) + "/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", &vctFileList);
|
||||
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),"/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", &vctFileList);
|
||||
}
|
||||
}
|
||||
if(networkGameDataSynchCheckOkMap == false)
|
||||
{
|
||||
if(networkGameDataSynchCheckOkMap == false) {
|
||||
vctFileList.push_back(std::pair<string,int32>(Map::getMapPath(serverInterface->getGameSettings()->getMap(),scenarioDir),mapCRC));
|
||||
}
|
||||
|
||||
@ -313,8 +293,7 @@ void ConnectionSlot::update(bool checkForNewClients)
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataFileGet\n",__FILE__,__FUNCTION__);
|
||||
|
||||
NetworkMessageSynchNetworkGameDataFileGet networkMessageSynchNetworkGameDataFileGet;
|
||||
if(receiveMessage(&networkMessageSynchNetworkGameDataFileGet))
|
||||
{
|
||||
if(receiveMessage(&networkMessageSynchNetworkGameDataFileGet)) {
|
||||
FileTransferInfo fileInfo;
|
||||
fileInfo.hostType = eServer;
|
||||
//fileInfo.serverIP = this->ip.getString();
|
||||
@ -330,10 +309,8 @@ void ConnectionSlot::update(bool checkForNewClients)
|
||||
case nmtSwitchSetupRequest:
|
||||
{
|
||||
SwitchSetupRequest switchSetupRequest;
|
||||
if(receiveMessage(&switchSetupRequest))
|
||||
{
|
||||
if(serverInterface->getSwitchSetupRequests()[switchSetupRequest.getCurrentFactionIndex()]==NULL)
|
||||
{
|
||||
if(receiveMessage(&switchSetupRequest)) {
|
||||
if(serverInterface->getSwitchSetupRequests()[switchSetupRequest.getCurrentFactionIndex()]==NULL) {
|
||||
serverInterface->getSwitchSetupRequests()[switchSetupRequest.getCurrentFactionIndex()]= new SwitchSetupRequest();
|
||||
}
|
||||
*(serverInterface->getSwitchSetupRequests()[switchSetupRequest.getCurrentFactionIndex()])=switchSetupRequest;
|
||||
@ -367,8 +344,7 @@ void ConnectionSlot::update(bool checkForNewClients)
|
||||
close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] calling close...\n",__FILE__,__FUNCTION__);
|
||||
|
||||
close();
|
||||
@ -376,8 +352,7 @@ void ConnectionSlot::update(bool checkForNewClients)
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectionSlot::close()
|
||||
{
|
||||
void ConnectionSlot::close() {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
delete socket;
|
||||
@ -394,15 +369,7 @@ void ConnectionSlot::close()
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
/*
|
||||
bool ConnectionSlot::getFogOfWar()
|
||||
{
|
||||
return networkGameDataSynchCheckOkFogOfWar;
|
||||
}
|
||||
*/
|
||||
|
||||
bool ConnectionSlot::hasValidSocketId()
|
||||
{
|
||||
bool ConnectionSlot::hasValidSocketId() {
|
||||
bool result = (socket != NULL && socket->getSocketId() > 0);
|
||||
return result;
|
||||
}
|
||||
|
58
source/glest_game/network/network_manager.h
Normal file
58
source/glest_game/network/network_manager.h
Normal file
@ -0,0 +1,58 @@
|
||||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Martio Figueroa
|
||||
//
|
||||
// You can redistribute this code and/or modify it under
|
||||
// the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version
|
||||
// ==============================================================
|
||||
|
||||
#ifndef _GLEST_GAME_NETWORKMANAGER_H_
|
||||
#define _GLEST_GAME_NETWORKMANAGER_H_
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "socket.h"
|
||||
#include "checksum.h"
|
||||
#include "server_interface.h"
|
||||
#include "client_interface.h"
|
||||
|
||||
using Shared::Util::Checksum;
|
||||
|
||||
namespace Glest{ namespace Game{
|
||||
|
||||
// =====================================================
|
||||
// class NetworkManager
|
||||
// =====================================================
|
||||
|
||||
enum NetworkRole{
|
||||
nrServer,
|
||||
nrClient,
|
||||
nrIdle
|
||||
};
|
||||
|
||||
class NetworkManager{
|
||||
private:
|
||||
GameNetworkInterface* gameNetworkInterface;
|
||||
NetworkRole networkRole;
|
||||
|
||||
public:
|
||||
static NetworkManager &getInstance();
|
||||
|
||||
NetworkManager();
|
||||
void init(NetworkRole networkRole);
|
||||
void end();
|
||||
void update();
|
||||
|
||||
bool isNetworkGame();
|
||||
GameNetworkInterface* getGameNetworkInterface();
|
||||
ServerInterface* getServerInterface();
|
||||
ClientInterface* getClientInterface();
|
||||
NetworkRole getNetworkRole() { return networkRole; }
|
||||
};
|
||||
|
||||
}}//end namespace
|
||||
|
||||
#endif
|
@ -37,6 +37,7 @@ NetworkCommand::NetworkCommand(World *world, int networkCommandType, int unitId,
|
||||
, wantQueue(wantQueue) {
|
||||
assert(targetId == -1 || facing == -1);
|
||||
this->targetId = targetId >= 0 ? targetId : facing;
|
||||
this->fromFactionIndex = world->getThisFactionIndex();
|
||||
|
||||
if(this->networkCommandType == nctGiveCommand) {
|
||||
const Unit *unit= world->findUnitById(this->unitId);
|
||||
@ -74,8 +75,8 @@ void NetworkCommand::preprocessNetworkCommand(World *world) {
|
||||
|
||||
string NetworkCommand::toString() const {
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"networkCommandType = %d\nunitId = %d\ncommandTypeId = %d\npositionX = %d\nthis->positionY = %d\nunitTypeId = %d\ntargetId = %d\nwantQueue= %d",
|
||||
networkCommandType,unitId,commandTypeId,positionX,this->positionY,unitTypeId,targetId,wantQueue);
|
||||
sprintf(szBuf,"networkCommandType = %d\nunitId = %d\ncommandTypeId = %d\npositionX = %d\npositionY = %d\nunitTypeId = %d\ntargetId = %d\nwantQueue= %d\nfromFactionIndex = %d",
|
||||
networkCommandType,unitId,commandTypeId,positionX,this->positionY,unitTypeId,targetId,wantQueue,fromFactionIndex);
|
||||
|
||||
string result = szBuf;
|
||||
return result;
|
||||
|
@ -1,7 +1,7 @@
|
||||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Martiño Figueroa
|
||||
// Copyright (C) 2001-2008 Martio Figueroa
|
||||
//
|
||||
// You can redistribute this code and/or modify it under
|
||||
// the terms of the GNU General Public License as published
|
||||
@ -68,6 +68,7 @@ private:
|
||||
int16 unitTypeId;
|
||||
int16 targetId;
|
||||
int16 wantQueue;
|
||||
int16 fromFactionIndex;
|
||||
|
||||
public:
|
||||
NetworkCommand(){};
|
||||
@ -91,6 +92,7 @@ public:
|
||||
int getUnitTypeId() const {return unitTypeId;}
|
||||
int getTargetId() const {return targetId;}
|
||||
int getWantQueue() const {return wantQueue;}
|
||||
int getFromFactionIndex() const {return fromFactionIndex;}
|
||||
|
||||
void preprocessNetworkCommand(World *world);
|
||||
string toString() const;
|
||||
|
@ -30,6 +30,113 @@ using namespace Shared::Util;
|
||||
|
||||
namespace Glest{ namespace Game{
|
||||
|
||||
ConnectionSlotThread::ConnectionSlotThread() : BaseThread() {
|
||||
this->slotInterface = NULL;
|
||||
}
|
||||
|
||||
ConnectionSlotThread::ConnectionSlotThread(ConnectionSlotCallbackInterface *slotInterface) : BaseThread() {
|
||||
this->slotInterface = slotInterface;
|
||||
}
|
||||
|
||||
void ConnectionSlotThread::setQuitStatus(bool value) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d value = %d\n",__FILE__,__FUNCTION__,__LINE__,value);
|
||||
|
||||
BaseThread::setQuitStatus(value);
|
||||
if(value == true) {
|
||||
signalUpdate(NULL);
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
}
|
||||
|
||||
void ConnectionSlotThread::signalUpdate(ConnectionSlotEvent *event) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
if(event != NULL) {
|
||||
triggerIdMutex.p();
|
||||
this->event = event;
|
||||
triggerIdMutex.v();
|
||||
}
|
||||
semTaskSignalled.signal();
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
}
|
||||
|
||||
void ConnectionSlotThread::setTaskCompleted(ConnectionSlotEvent *event) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
if(event != NULL) {
|
||||
triggerIdMutex.p();
|
||||
event->eventCompleted = true;
|
||||
triggerIdMutex.v();
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
}
|
||||
|
||||
bool ConnectionSlotThread::isSignalCompleted() {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
triggerIdMutex.p();
|
||||
bool result = this->event->eventCompleted;
|
||||
triggerIdMutex.v();
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void ConnectionSlotThread::execute() {
|
||||
try {
|
||||
setRunningStatus(true);
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
unsigned int idx = 0;
|
||||
for(;this->slotInterface != NULL;) {
|
||||
if(getQuitStatus() == true) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
break;
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
semTaskSignalled.waitTillSignalled();
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
if(getQuitStatus() == true) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
break;
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
this->slotInterface->slotUpdateTask(this->event);
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
if(getQuitStatus() == true) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
break;
|
||||
}
|
||||
|
||||
setTaskCompleted(this->event);
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
}
|
||||
catch(const exception &ex) {
|
||||
setRunningStatus(false);
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
throw runtime_error(ex.what());
|
||||
}
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
setRunningStatus(false);
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// class ServerInterface
|
||||
// =====================================================
|
||||
@ -41,6 +148,7 @@ ServerInterface::ServerInterface(){
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i){
|
||||
slots[i]= NULL;
|
||||
switchSetupRequests[i]= NULL;
|
||||
slotThreads[i] = NULL;
|
||||
}
|
||||
serverSocket.setBlock(false);
|
||||
serverSocket.bind(Config::getInstance().getInt("ServerPort",intToStr(GameConstants::serverPort).c_str()));
|
||||
@ -50,6 +158,10 @@ ServerInterface::~ServerInterface(){
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i){
|
||||
BaseThread::shutdownAndWait(slotThreads[i]);
|
||||
delete slotThreads[i];
|
||||
slotThreads[i] = NULL;
|
||||
|
||||
delete slots[i];
|
||||
slots[i]=NULL;
|
||||
delete switchSetupRequests[i];
|
||||
@ -71,12 +183,15 @@ void ServerInterface::addSlot(int playerIndex){
|
||||
slots[playerIndex]= new ConnectionSlot(this, playerIndex);
|
||||
updateListen();
|
||||
|
||||
slotThreads[playerIndex] = new ConnectionSlotThread(this);
|
||||
slotThreads[playerIndex]->start();
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
bool ServerInterface::switchSlot(int fromPlayerIndex,int toPlayerIndex){
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
bool result=false;
|
||||
assert(fromPlayerIndex>=0 && fromPlayerIndex<GameConstants::maxPlayers);
|
||||
assert(toPlayerIndex>=0 && toPlayerIndex<GameConstants::maxPlayers);
|
||||
@ -95,19 +210,27 @@ bool ServerInterface::switchSlot(int fromPlayerIndex,int toPlayerIndex){
|
||||
result=true;
|
||||
updateListen();
|
||||
}
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
return result;
|
||||
}
|
||||
|
||||
void ServerInterface::removeSlot(int playerIndex){
|
||||
void ServerInterface::removeSlot(int playerIndex) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
//BaseThread::shutdownAndWait(slotThreads[playerIndex]);
|
||||
//delete slotThreads[playerIndex];
|
||||
//slotThreads[playerIndex] = NULL;
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
|
||||
|
||||
delete slots[playerIndex];
|
||||
slots[playerIndex]= NULL;
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
|
||||
|
||||
updateListen();
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
|
||||
}
|
||||
|
||||
ConnectionSlot* ServerInterface::getSlot(int playerIndex){
|
||||
@ -125,83 +248,139 @@ int ServerInterface::getConnectedSlotCount(){
|
||||
return connectedSlotCount;
|
||||
}
|
||||
|
||||
void ServerInterface::update()
|
||||
{
|
||||
void ServerInterface::slotUpdateTask(ConnectionSlotEvent *event) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
if(event != NULL) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
updateSlot(event);
|
||||
}
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
}
|
||||
|
||||
void ServerInterface::updateSlot(ConnectionSlotEvent *event) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
if(event != NULL) {
|
||||
ConnectionSlot *connectionSlot = event->connectionSlot;
|
||||
bool &socketTriggered = event->socketTriggered;
|
||||
bool checkForNewClients = true;
|
||||
|
||||
if(connectionSlot != NULL &&
|
||||
(gameHasBeenInitiated == false || (connectionSlot->getSocket() != NULL && socketTriggered == true))) {
|
||||
if(connectionSlot->isConnected() == false || socketTriggered == true) {
|
||||
if(gameHasBeenInitiated) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] socketTriggeredList[i] = %i\n",__FILE__,__FUNCTION__,(socketTriggered ? 1 : 0));
|
||||
|
||||
if(connectionSlot->isConnected()) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to call connectionSlot->update() for socketId = %d\n",__FILE__,__FUNCTION__,__LINE__,connectionSlot->getSocket()->getSocketId());
|
||||
}
|
||||
else {
|
||||
if(gameHasBeenInitiated) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] getSocket() == NULL\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
connectionSlot->update(checkForNewClients);
|
||||
|
||||
// This means no clients are trying to connect at the moment
|
||||
if(connectionSlot != NULL && connectionSlot->getSocket() == NULL) {
|
||||
checkForNewClients = false;
|
||||
}
|
||||
|
||||
if(connectionSlot != NULL &&
|
||||
connectionSlot->getChatText().empty() == false) {
|
||||
chatText = connectionSlot->getChatText();
|
||||
chatSender = connectionSlot->getChatSender();
|
||||
chatTeamIndex = connectionSlot->getChatTeamIndex();
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 about to broadcast nmtText chatText [%s] chatSender [%s] chatTeamIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,chatText.c_str(),chatSender.c_str(),chatTeamIndex);
|
||||
|
||||
NetworkMessageText networkMessageText(chatText,chatSender,chatTeamIndex);
|
||||
broadcastMessage(&networkMessageText, connectionSlot->getPlayerIndex());
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
}
|
||||
|
||||
void ServerInterface::update() {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
std::map<PLATFORM_SOCKET,bool> socketTriggeredList;
|
||||
//update all slots
|
||||
for(int i= 0; i < GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
for(int i= 0; i < GameConstants::maxPlayers; ++i) {
|
||||
ConnectionSlot* connectionSlot= slots[i];
|
||||
if(connectionSlot != NULL && connectionSlot->getSocket() != NULL &&
|
||||
slots[i]->getSocket()->getSocketId() > 0)
|
||||
{
|
||||
slots[i]->getSocket()->getSocketId() > 0) {
|
||||
socketTriggeredList[connectionSlot->getSocket()->getSocketId()] = false;
|
||||
}
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
chatText.clear();
|
||||
chatSender.clear();
|
||||
chatTeamIndex= -1;
|
||||
|
||||
if(gameHasBeenInitiated == false || socketTriggeredList.size() > 0)
|
||||
{
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
if(gameHasBeenInitiated == false || socketTriggeredList.size() > 0) {
|
||||
if(gameHasBeenInitiated) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] socketTriggeredList.size() = %d\n",__FILE__,__FUNCTION__,socketTriggeredList.size());
|
||||
|
||||
std::map<int,ConnectionSlotEvent> eventList;
|
||||
bool hasData = Socket::hasDataToRead(socketTriggeredList);
|
||||
|
||||
if(hasData) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] hasData == true\n",__FILE__,__FUNCTION__);
|
||||
|
||||
if(gameHasBeenInitiated == false || hasData == true)
|
||||
{
|
||||
//if(gameHasBeenInitiated && Socket::enableNetworkDebugInfo) printf("In [%s::%s] hasData == true\n",__FILE__,__FUNCTION__);
|
||||
|
||||
//std::vector<TeamMessageData> vctTeamMessages;
|
||||
|
||||
if(gameHasBeenInitiated == false || hasData == true) {
|
||||
//update all slots
|
||||
bool checkForNewClients = true;
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i) {
|
||||
ConnectionSlot* connectionSlot= slots[i];
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
bool socketTriggered = (connectionSlot != NULL && connectionSlot->getSocket() != NULL ? socketTriggeredList[connectionSlot->getSocket()->getSocketId()] : false);
|
||||
ConnectionSlotEvent &event = eventList[i];
|
||||
event.connectionSlot = connectionSlot;
|
||||
event.socketTriggered = socketTriggered;
|
||||
event.triggerId = i;
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
if(slotThreads[i] != NULL) {
|
||||
slotThreads[i]->signalUpdate(&event);
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
}
|
||||
//updateSlot(event);
|
||||
|
||||
/*
|
||||
if(connectionSlot != NULL &&
|
||||
(gameHasBeenInitiated == false || (connectionSlot->getSocket() != NULL && socketTriggeredList[connectionSlot->getSocket()->getSocketId()] == true)))
|
||||
{
|
||||
(gameHasBeenInitiated == false || (connectionSlot->getSocket() != NULL && socketTriggeredList[connectionSlot->getSocket()->getSocketId()] == true))) {
|
||||
if(connectionSlot->isConnected() == false ||
|
||||
(socketTriggeredList[connectionSlot->getSocket()->getSocketId()] == true))
|
||||
{
|
||||
(socketTriggeredList[connectionSlot->getSocket()->getSocketId()] == true)) {
|
||||
if(gameHasBeenInitiated) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] socketTriggeredList[i] = %i\n",__FILE__,__FUNCTION__,(socketTriggeredList[connectionSlot->getSocket()->getSocketId()] ? 1 : 0));
|
||||
|
||||
if(connectionSlot->isConnected())
|
||||
{
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] calling slots[i]->update() for slot = %d socketId = %d\n",
|
||||
if(connectionSlot->isConnected()) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] about to call slots[i]->update() for slot = %d socketId = %d\n",
|
||||
__FILE__,__FUNCTION__,i,connectionSlot->getSocket()->getSocketId());
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
if(gameHasBeenInitiated) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] slot = %d getSocket() == NULL\n",__FILE__,__FUNCTION__,i);
|
||||
}
|
||||
connectionSlot->update(checkForNewClients);
|
||||
|
||||
// This means no clients are trying to connect at the moment
|
||||
if(connectionSlot != NULL && connectionSlot->getSocket() == NULL)
|
||||
{
|
||||
if(connectionSlot != NULL && connectionSlot->getSocket() == NULL) {
|
||||
checkForNewClients = false;
|
||||
}
|
||||
|
||||
if(connectionSlot != NULL &&
|
||||
//connectionSlot->isConnected() == true &&
|
||||
connectionSlot->getChatText().empty() == false)
|
||||
{
|
||||
connectionSlot->getChatText().empty() == false) {
|
||||
chatText = connectionSlot->getChatText();
|
||||
chatSender = connectionSlot->getChatSender();
|
||||
chatTeamIndex = connectionSlot->getChatTeamIndex();
|
||||
|
||||
//TeamMessageData teamMessageData;
|
||||
//teamMessageData.chatSender = connectionSlot->getChatSender();
|
||||
//teamMessageData.chatText = connectionSlot->getChatText();
|
||||
//teamMessageData.chatTeamIndex = connectionSlot->getChatTeamIndex();
|
||||
//teamMessageData.sourceTeamIndex = i;
|
||||
//vctTeamMessages.push_back(teamMessageData);
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 about to broadcast nmtText chatText [%s] chatSender [%s] chatTeamIndex = %d for SlotIndex# %d\n",__FILE__,__FUNCTION__,__LINE__,chatText.c_str(),chatSender.c_str(),chatTeamIndex,i);
|
||||
|
||||
NetworkMessageText networkMessageText(chatText,chatSender,chatTeamIndex);
|
||||
@ -212,32 +391,51 @@ void ServerInterface::update()
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
std::map<int,bool> slotsCompleted;
|
||||
for(bool threadsDone = false; threadsDone == false;) {
|
||||
threadsDone = true;
|
||||
// Examine all threads for completion of delegation
|
||||
for(int i= 0; i< GameConstants::maxPlayers; ++i) {
|
||||
if(slotThreads[i] != NULL && slotsCompleted.find(i) == slotsCompleted.end()) {
|
||||
if(slotThreads[i]->isSignalCompleted() == false &&
|
||||
slotThreads[i]->getQuitStatus() == false &&
|
||||
slotThreads[i]->getRunningStatus() == true) {
|
||||
threadsDone = false;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
slotsCompleted[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
sleep(0);
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
//process text messages
|
||||
if(chatText.empty() == true)
|
||||
{
|
||||
if(chatText.empty() == true) {
|
||||
chatText.clear();
|
||||
chatSender.clear();
|
||||
chatTeamIndex= -1;
|
||||
|
||||
for(int i= 0; i< GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
for(int i= 0; i< GameConstants::maxPlayers; ++i) {
|
||||
ConnectionSlot* connectionSlot= slots[i];
|
||||
|
||||
if(connectionSlot!= NULL &&
|
||||
(gameHasBeenInitiated == false || (connectionSlot->getSocket() != NULL && socketTriggeredList[connectionSlot->getSocket()->getSocketId()] == true)))
|
||||
{
|
||||
if(connectionSlot->isConnected() && socketTriggeredList[connectionSlot->getSocket()->getSocketId()] == true)
|
||||
{
|
||||
(gameHasBeenInitiated == false || (connectionSlot->getSocket() != NULL && socketTriggeredList[connectionSlot->getSocket()->getSocketId()] == true))) {
|
||||
if(connectionSlot->isConnected() && socketTriggeredList[connectionSlot->getSocket()->getSocketId()] == true) {
|
||||
if(connectionSlot->getSocket() != NULL) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] calling connectionSlot->getNextMessageType() for slots[i]->getSocket()->getSocketId() = %d\n",
|
||||
__FILE__,__FUNCTION__,connectionSlot->getSocket()->getSocketId());
|
||||
|
||||
if(connectionSlot->getNextMessageType() == nmtText)
|
||||
{
|
||||
if(connectionSlot->getNextMessageType() == nmtText) {
|
||||
NetworkMessageText networkMessageText;
|
||||
if(connectionSlot->receiveMessage(&networkMessageText))
|
||||
{
|
||||
if(connectionSlot->receiveMessage(&networkMessageText)) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] #2 about to broadcast nmtText msg for SlotIndex# %d\n",__FILE__,__FUNCTION__,i);
|
||||
|
||||
broadcastMessage(&networkMessageText, i);
|
||||
@ -251,8 +449,12 @@ void ServerInterface::update()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
}
|
||||
|
||||
void ServerInterface::updateKeyframe(int frameCount){
|
||||
@ -262,12 +464,12 @@ void ServerInterface::updateKeyframe(int frameCount){
|
||||
NetworkMessageCommandList networkMessageCommandList(frameCount);
|
||||
|
||||
//build command list, remove commands from requested and add to pending
|
||||
while(!requestedCommands.empty()){
|
||||
if(networkMessageCommandList.addCommand(&requestedCommands.back())){
|
||||
while(!requestedCommands.empty()) {
|
||||
if(networkMessageCommandList.addCommand(&requestedCommands.back())) {
|
||||
pendingCommands.push_back(requestedCommands.back());
|
||||
requestedCommands.pop_back();
|
||||
}
|
||||
else{
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -507,6 +709,8 @@ bool ServerInterface::launchGame(const GameSettings* gameSettings){
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
serverSynchAccessor.p();
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
ConnectionSlot *connectionSlot= slots[i];
|
||||
@ -522,6 +726,8 @@ bool ServerInterface::launchGame(const GameSettings* gameSettings){
|
||||
}
|
||||
}
|
||||
|
||||
serverSynchAccessor.v();
|
||||
|
||||
if(bOkToStart == true)
|
||||
{
|
||||
serverSocket.stopBroadCastThread();
|
||||
@ -535,7 +741,7 @@ bool ServerInterface::launchGame(const GameSettings* gameSettings){
|
||||
return bOkToStart;
|
||||
}
|
||||
|
||||
void ServerInterface::broadcastGameSetup(const GameSettings* gameSettings){
|
||||
void ServerInterface::broadcastGameSetup(const GameSettings* gameSettings) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
NetworkMessageLaunch networkMessageLaunch(gameSettings,nmtBroadCastSetup);
|
||||
@ -546,61 +752,64 @@ void ServerInterface::broadcastGameSetup(const GameSettings* gameSettings){
|
||||
|
||||
|
||||
void ServerInterface::broadcastMessage(const NetworkMessage* networkMessage, int excludeSlot){
|
||||
serverSynchAccessor.p();
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i) {
|
||||
ConnectionSlot* connectionSlot= slots[i];
|
||||
|
||||
if(i != excludeSlot && connectionSlot != NULL)
|
||||
{
|
||||
if(connectionSlot->isConnected())
|
||||
{
|
||||
if(i != excludeSlot && connectionSlot != NULL) {
|
||||
if(connectionSlot->isConnected()) {
|
||||
|
||||
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] before sendMessage\n",__FILE__,__FUNCTION__);
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] before sendMessage\n",__FILE__,__FUNCTION__);
|
||||
connectionSlot->sendMessage(networkMessage);
|
||||
}
|
||||
else if(gameHasBeenInitiated == true)
|
||||
{
|
||||
else if(gameHasBeenInitiated == true) {
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] #1 before removeSlot for slot# %d\n",__FILE__,__FUNCTION__,i);
|
||||
removeSlot(i);
|
||||
}
|
||||
}
|
||||
else if(i == excludeSlot && gameHasBeenInitiated == true &&
|
||||
connectionSlot != NULL && connectionSlot->isConnected() == false)
|
||||
{
|
||||
connectionSlot != NULL && connectionSlot->isConnected() == false) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] #2 before removeSlot for slot# %d\n",__FILE__,__FUNCTION__,i);
|
||||
removeSlot(i);
|
||||
}
|
||||
}
|
||||
|
||||
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
serverSynchAccessor.v();
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
}
|
||||
|
||||
void ServerInterface::broadcastMessageToConnectedClients(const NetworkMessage* networkMessage, int excludeSlot){
|
||||
serverSynchAccessor.p();
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i){
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i) {
|
||||
ConnectionSlot* connectionSlot= slots[i];
|
||||
|
||||
if(i!= excludeSlot && connectionSlot!= NULL){
|
||||
if(connectionSlot->isConnected()){
|
||||
if(i!= excludeSlot && connectionSlot!= NULL) {
|
||||
if(connectionSlot->isConnected()) {
|
||||
|
||||
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] before sendMessage\n",__FILE__,__FUNCTION__);
|
||||
|
||||
connectionSlot->sendMessage(networkMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
serverSynchAccessor.v();
|
||||
}
|
||||
|
||||
void ServerInterface::updateListen()
|
||||
{
|
||||
void ServerInterface::updateListen() {
|
||||
if(gameHasBeenInitiated == true) {
|
||||
return;
|
||||
}
|
||||
|
||||
serverSynchAccessor.p();
|
||||
|
||||
int openSlotCount= 0;
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
@ -611,11 +820,15 @@ void ServerInterface::updateListen()
|
||||
}
|
||||
|
||||
serverSocket.listen(openSlotCount);
|
||||
|
||||
serverSynchAccessor.v();
|
||||
}
|
||||
|
||||
int ServerInterface::getOpenSlotCount() {
|
||||
int openSlotCount= 0;
|
||||
|
||||
serverSynchAccessor.p();
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
if(slots[i] != NULL && slots[i]->isConnected() == false)
|
||||
@ -624,6 +837,8 @@ int ServerInterface::getOpenSlotCount() {
|
||||
}
|
||||
}
|
||||
|
||||
serverSynchAccessor.v();
|
||||
|
||||
return openSlotCount;
|
||||
}
|
||||
|
||||
|
@ -18,32 +18,71 @@
|
||||
#include "network_interface.h"
|
||||
#include "connection_slot.h"
|
||||
#include "socket.h"
|
||||
#include "base_thread.h"
|
||||
|
||||
using std::vector;
|
||||
using Shared::Platform::ServerSocket;
|
||||
|
||||
namespace Glest{ namespace Game{
|
||||
|
||||
|
||||
// =====================================================
|
||||
// class ConnectionSlotThread
|
||||
// =====================================================
|
||||
|
||||
class ConnectionSlotEvent {
|
||||
public:
|
||||
|
||||
int64 triggerId;
|
||||
ConnectionSlot* connectionSlot;
|
||||
bool socketTriggered;
|
||||
bool eventCompleted;
|
||||
};
|
||||
|
||||
//
|
||||
// This interface describes the methods a callback object must implement
|
||||
//
|
||||
class ConnectionSlotCallbackInterface {
|
||||
public:
|
||||
virtual void slotUpdateTask(ConnectionSlotEvent *event) = 0;
|
||||
};
|
||||
|
||||
class ConnectionSlotThread : public BaseThread
|
||||
{
|
||||
protected:
|
||||
|
||||
ConnectionSlotCallbackInterface *slotInterface;
|
||||
Semaphore semTaskSignalled;
|
||||
Mutex triggerIdMutex;
|
||||
ConnectionSlotEvent *event;
|
||||
|
||||
virtual void setQuitStatus(bool value);
|
||||
virtual void setTaskCompleted(ConnectionSlotEvent *event);
|
||||
|
||||
public:
|
||||
ConnectionSlotThread();
|
||||
ConnectionSlotThread(ConnectionSlotCallbackInterface *slotInterface);
|
||||
virtual void execute();
|
||||
void signalUpdate(ConnectionSlotEvent *event);
|
||||
bool isSignalCompleted();
|
||||
|
||||
};
|
||||
|
||||
// =====================================================
|
||||
// class ServerInterface
|
||||
// =====================================================
|
||||
|
||||
typedef struct
|
||||
{
|
||||
string chatText;
|
||||
string chatSender;
|
||||
int chatTeamIndex;
|
||||
int sourceTeamIndex;
|
||||
class ServerInterface: public GameNetworkInterface, public ConnectionSlotCallbackInterface {
|
||||
|
||||
} TeamMessageData;
|
||||
|
||||
class ServerInterface: public GameNetworkInterface{
|
||||
private:
|
||||
ConnectionSlot* slots[GameConstants::maxPlayers];
|
||||
ServerSocket serverSocket;
|
||||
bool gameHasBeenInitiated;
|
||||
int gameSettingsUpdateCount;
|
||||
SwitchSetupRequest* switchSetupRequests[GameConstants::maxPlayers];
|
||||
Mutex serverSynchAccessor;
|
||||
|
||||
ConnectionSlotThread* slotThreads[GameConstants::maxPlayers];
|
||||
|
||||
public:
|
||||
ServerInterface();
|
||||
@ -81,10 +120,13 @@ public:
|
||||
void updateListen();
|
||||
virtual bool getConnectHasHandshaked() const { return false; }
|
||||
|
||||
virtual void slotUpdateTask(ConnectionSlotEvent *event);
|
||||
|
||||
private:
|
||||
void broadcastMessage(const NetworkMessage* networkMessage, int excludeSlot= -1);
|
||||
void broadcastMessageToConnectedClients(const NetworkMessage* networkMessage, int excludeSlot = -1);
|
||||
bool shouldDiscardNetworkMessage(NetworkMessageType networkMessageType,ConnectionSlot* connectionSlot);
|
||||
void updateSlot(ConnectionSlotEvent *event);
|
||||
};
|
||||
|
||||
}}//end namespace
|
||||
|
Loading…
x
Reference in New Issue
Block a user