Thread: [Gcblue-commits] gcb_wx/src/network tcMultiplayerInterface.cpp,1.24,1.25 tcUpdateMessageHandler.cpp,
Status: Alpha
Brought to you by:
ddcforge
|
From: Dewitt C. <ddc...@us...> - 2005-05-05 02:15:33
|
Update of /cvsroot/gcblue/gcb_wx/src/network In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv777/src/network Modified Files: tcMultiplayerInterface.cpp tcUpdateMessageHandler.cpp Log Message: Index: tcUpdateMessageHandler.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/network/tcUpdateMessageHandler.cpp,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** tcUpdateMessageHandler.cpp 29 Apr 2005 18:52:54 -0000 1.14 --- tcUpdateMessageHandler.cpp 5 May 2005 02:14:52 -0000 1.15 *************** *** 34,37 **** --- 34,38 ---- #include "common/tcStream.h" #include "common/tcObjStream.h" + #include "tcSimPythonInterface.h" #ifdef _DEBUG *************** *** 76,81 **** --- 77,93 ---- } + void tcUpdateMessageHandler::AddControlRelease(long id, tcStream& stream) + { + bool releaseControl = true; + + stream << releaseControl; + stream << id; + } + void tcUpdateMessageHandler::AddControlRequest(long id, tcStream& stream) { + bool releaseControl = false; + + stream << releaseControl; stream << id; } *************** *** 122,125 **** --- 134,147 ---- /** + * Adds sound effect info to stream + * @param id entity id that sound effect is associated with + */ + void tcUpdateMessageHandler::AddSoundEffect(long id, const std::string& effect, tcStream& stream) + { + stream << id; + stream << effect; + } + + /** * Saves update data for obj to stream. Obj must be * created first for this data to be applied. *************** *** 176,179 **** --- 198,205 ---- case CONTROL_REQUEST: break; + case SOUND_EFFECT: + break; + case SCRIPT_COMMANDS: + break; default: fprintf(stderr, "tcUpdateMessageHandler::InitializeMessage - bad message type\n"); *************** *** 231,234 **** --- 257,265 ---- } break; + case SCRIPT_COMMANDS: + { + HandleScriptCommands(stream, connectionId); + } + break; default: fprintf(stderr, "tcUpdateMessageHandler::Handle - unknown msg type for server\n"); *************** *** 282,285 **** --- 313,321 ---- } break; + case SOUND_EFFECT: + { + HandleSoundEffect(stream); + } + break; default: fprintf(stderr, "tcUpdateMessageHandler::Handle - " *************** *** 409,420 **** fprintf(stdout, "<< Received obj control req msg, time %.1f: ", simState->GetTime()); long id; ! while ((stream >> id).eof() == false) { // lookup obj if (tcGameObject* obj = simState->GetObject(id)) { ! if (obj->IsAvailable(playerAlliance, playerRank)) { obj->SetController(playerName); --- 445,470 ---- fprintf(stdout, "<< Received obj control req msg, time %.1f: ", simState->GetTime()); + bool releaseControl; long id; ! while ((stream >> releaseControl).eof() == false) { + stream >> id; + // lookup obj if (tcGameObject* obj = simState->GetObject(id)) { ! if (releaseControl) ! { ! if (obj->GetController() == playerName) ! { ! obj->SetController(""); ! } ! else ! { ! fprintf(stdout, "N%d ", obj->mnID); ! } ! } ! else if (obj->IsAvailable(playerAlliance, playerRank)) { obj->SetController(playerName); *************** *** 556,559 **** --- 606,628 ---- } + /** + * Handle SCRIPT_COMMANDS message (server only) + */ + void tcUpdateMessageHandler::HandleScriptCommands(tcStream& stream, int connectionId) + { + wxASSERT(isServer); + + tcPlayerStatus& pstatus = + tcMultiplayerInterface::Get()->GetPlayerStatus(connectionId); + + fprintf(stdout, "<< Received script commands for connection %d\n", connectionId); + + stream.SetMetaString(pstatus.GetName()); + + tcCommandStream& commandStream = (tcCommandStream&)stream; + + tcSimPythonInterface::Get()->operator<<(commandStream); + + } /** *************** *** 590,593 **** --- 659,682 ---- /** + * Handle SOUND_EFFECT message (client only) + */ + void tcUpdateMessageHandler::HandleSoundEffect(tcStream& stream) + { + wxASSERT(!isServer); + + long id; + unsigned int nEffects = 0; + while (((stream >> id).eof() == false) && (nEffects++ < 8)) + { + std::string effect; + + stream >> effect; + + tcSound::Get()->PlayEffect(effect); + } + + } + + /** * Handle UPDATE update message (client only) */ Index: tcMultiplayerInterface.cpp =================================================================== RCS file: /cvsroot/gcblue/gcb_wx/src/network/tcMultiplayerInterface.cpp,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** tcMultiplayerInterface.cpp 29 Apr 2005 18:52:54 -0000 1.24 --- tcMultiplayerInterface.cpp 5 May 2005 02:14:52 -0000 1.25 *************** *** 256,259 **** --- 256,260 ---- { playerStatus.isAuthenticated = true; + SendSoundEffect(connectionId, "Welcome"); } else if (loginStatus == tcAccountDatabase::DUPLICATE_LOGIN) *************** *** 312,315 **** --- 313,317 ---- playerStatus.SetConnectionId(connectionId); + playerToConnection[username] = connectionId; msg = wxString::Format("Welcome %s (Alliance %d)\n", playerStatus.GetNameWithRank().c_str(), *************** *** 340,344 **** if (iter->second.isAuthenticated) { ! tcAccountDatabase::Get()->LogOut(iter->second.name); iter->second.isAuthenticated = false; } --- 342,346 ---- if (iter->second.isAuthenticated) { ! LogOutPlayer(iter->second.name); iter->second.isAuthenticated = false; } *************** *** 347,350 **** --- 349,379 ---- } + void tcMultiplayerInterface::LogOutPlayer(const std::string& username) + { + std::map<std::string, int>::iterator iter = + playerToConnection.find(username); + + if (iter == playerToConnection.end()) + { + fprintf(stderr, "tcMultiplayerInterface::LogOutPlayer - not found in playerToConnection map\n"); + return; + } + + playerToConnection.erase(iter); + tcAccountDatabase::Get()->LogOut(username); + + // iterate through objects and release control of objects controller by player + tcGameObjIterator objIter; + unsigned updateCount = 0; + for (objIter.First(); objIter.NotDone(); objIter.Next()) + { + tcGameObject* obj = objIter.Get(); + if (obj->GetController() == username) + { + obj->SetController(""); + } + } + } + /** * Broadcast chat text to all connected clients *************** *** 467,470 **** --- 496,517 ---- } + /** + * @return -1 if not found + */ + int tcMultiplayerInterface::GetPlayerConnectionId(const std::string& playerName) + { + std::map<std::string, int>::const_iterator iter = + playerToConnection.find(playerName); + + if (iter != playerToConnection.end()) + { + return iter->second; + } + else + { + return -1; + } + } + const std::string& tcMultiplayerInterface::GetPlayerName(int connectionId) { *************** *** 672,695 **** SendChatText(connectionId, "*** /gm help ***"); SendChatText(connectionId, " /gm help - print GM command list"); SendChatText(connectionId, " /gm create '<class>' '<unitname>' <alliance>"); SendChatText(connectionId, " /gm destroy <id>"); SendChatText(connectionId, " /gm move <id> <lat_deg> <lon_deg> (<alt>)"); SendChatText(connectionId, " /gm repair <id>"); } else if (command == "create") { syntaxError = false; ! const char delim = '\''; ! wxString s1 = args.AfterFirst(delim); ! wxString unitClass = s1.BeforeFirst(delim); ! s1 = s1.AfterFirst(delim); ! s1 = s1.AfterFirst(delim); ! wxString unitName = s1.BeforeFirst(delim); ! s1 = s1.AfterFirst(delim); ! s1 = s1.AfterFirst(' '); ! ! msg = wxString::Format("*** Received create, class '%s', unit '%s'", ! unitClass.c_str(), unitName.c_str()); } else if (command == "destroy") --- 719,744 ---- SendChatText(connectionId, "*** /gm help ***"); SendChatText(connectionId, " /gm help - print GM command list"); + SendChatText(connectionId, " /gm addaccount '<username>' '<email>'"); + // SendChatText(connectionId, " /gm getaccountdata '<username>' '<param>'"); + // SendChatText(connectionId, " /gm setaccountdata '<username>' '<param>' <value>"); SendChatText(connectionId, " /gm create '<class>' '<unitname>' <alliance>"); SendChatText(connectionId, " /gm destroy <id>"); SendChatText(connectionId, " /gm move <id> <lat_deg> <lon_deg> (<alt>)"); + // SendChatText(connectionId, " /gm reload <id>"); SendChatText(connectionId, " /gm repair <id>"); + // SendChatText(connectionId, " /gm setalliance <id> <alliance>"); + // SendChatTest(connectionId, " /gm setcontroller <id> '<player>'"); } + else if (command == "addaccount") + { + syntaxError = false; + + ProcessGMAddAccount(args, msg); + } else if (command == "create") { syntaxError = false; ! ProcessGMCreate(args, msg); } else if (command == "destroy") *************** *** 703,706 **** --- 752,761 ---- } } + else if (command == "move") + { + syntaxError = false; + + ProcessGMMove(args, msg); + } else if (command == "repair") { *************** *** 738,741 **** --- 793,958 ---- /** + * Adds new player account to database + * /gm addaccount '<username>' '<email>' + * @param args argument string + * @param msg message text to be returned + */ + void tcMultiplayerInterface::ProcessGMAddAccount(const wxString& args, wxString& msg) + { + + const char delim = '\''; + wxString s1 = args.AfterFirst(delim); + std::string username = s1.BeforeFirst(delim).c_str(); + s1 = s1.AfterFirst(delim); + s1 = s1.AfterFirst(delim); + std::string email = s1.BeforeFirst(delim).c_str(); + + if (username.size() < 3) + { + msg.Printf("*** Username too short (%s)", username.c_str()); + return; + } + + int status = tcAccountDatabase::Get()->AddUser(username, "", email); + if (status == tcAccountDatabase::SUCCESS) + { + msg.Printf("*** Added account for %s", username.c_str()); + } + else + { + msg.Printf("*** Error adding account %s (%d)", username.c_str(), status); + } + } + + + /** + * Creates a new game entity + * /gm create '<class>' '<unitname>' <alliance> + * @param args argument string + * @param msg message text to be returned + */ + void tcMultiplayerInterface::ProcessGMCreate(const wxString& args, wxString& msg) + { + const char delim = '\''; + wxString s1 = args.AfterFirst(delim); + wxString unitClass = s1.BeforeFirst(delim); + s1 = s1.AfterFirst(delim); + s1 = s1.AfterFirst(delim); + wxString unitName = s1.BeforeFirst(delim); + s1 = s1.AfterFirst(delim); + s1 = s1.AfterFirst(' '); + long alliance = 0; + if ((!s1.ToLong(&alliance)) || (alliance < 0)) + { + msg = wxString::Format("*** Bad alliance value for create, class '%s', unit '%s'", + unitClass.c_str(), unitName.c_str()); + return; + } + + tcScenarioInterface* scenarioInterface = tcSimPythonInterface::Get()->GetScenarioInterface(); + wxASSERT(scenarioInterface); + + tcScenarioUnit unit; + + unit.className = unitClass.c_str(); + unit.unitName = unitName.c_str(); + unit.lat = 0; + unit.lon = 0; + unit.alt = 0; + unit.heading = 0; + unit.speed = 0; + unit.throttle = 1.0; + + if (scenarioInterface->AddUnitToAlliance(unit, alliance)) + { + tcGameObject* obj = scenarioInterface->GetLastObjectAdded(); + wxASSERT(obj); + long id = obj->mnID; + + msg = wxString::Format("*** Created %d, class '%s', unit '%s' alliance %d", + id, unitClass.c_str(), unitName.c_str(), alliance); + } + else + { + msg = wxString::Format("*** Create FAILED, class '%s', unit '%s' alliance %d", + unitClass.c_str(), unitName.c_str(), alliance); + } + + } + + /** + * Moves a game entity + * move <id> <lat_deg> <lon_deg> (<alt>) + * use "move <id> 0 0 <alt>" to only change altitude + * @param args argument string + * @param msg message text to be returned + */ + void tcMultiplayerInterface::ProcessGMMove(const wxString& args, wxString& msg) + { + wxString params = args.AfterFirst(' '); + wxString s1 = params.BeforeFirst(' '); + + long id = -1; + if (!s1.ToLong(&id)) + { + msg = wxString::Format("*** Syntax error for /gm move"); + return; + } + + double lat_deg = 0; + params = params.AfterFirst(' '); + s1 = params.BeforeFirst(' '); + if (!s1.ToDouble(&lat_deg)) + { + msg = wxString::Format("*** Syntax error for /gm move"); + return; + } + + double lon_deg = 0; + params = params.AfterFirst(' '); + s1 = params.BeforeFirst(' '); + if (!s1.ToDouble(&lon_deg)) + { + msg = wxString::Format("*** Syntax error for /gm move"); + return; + } + + bool changeLatLon = (lat_deg != 0) || (lon_deg != 0); + + double alt_m = 0; + bool changeAlt = true; + params = params.AfterFirst(' '); + s1 = params.BeforeFirst(' '); + if (!s1.ToDouble(&alt_m)) + { + changeAlt = false; + } + + tcSimState* simState = tcSimState::Get(); + + if (tcGameObject* obj = simState->GetObject(id)) + { + if (changeLatLon) + { + obj->mcKin.mfLat_rad = C_PIOVER180 * lat_deg; + obj->mcKin.mfLon_rad = C_PIOVER180 * lon_deg; + } + if (changeAlt) + { + obj->mcKin.mfAlt_m = (float)alt_m; + } + + msg = wxString::Format("*** Entity %d moved", id); + } + else + { + msg = wxString::Format("*** Entity %d not found", id); + } + + + + } + + /** * Process command from client (after command is received at server) * text commands start with a forward slash '/' *************** *** 966,969 **** --- 1183,1218 ---- /** + * Sends control request message to server requesting release of control of object id by player + */ + void tcMultiplayerInterface::SendControlRelease(long id) + { + if (IsServer()) + { + fprintf(stderr, "tcMultiplayerInterface::SendControlRelease - called by server\n"); + wxASSERT(false); + return; + } + + // server should be only connection + const std::list<int>& connectionList = networkInterface->GetConnectionList(); + if (connectionList.size() == 0) + { + fprintf(stderr, "tcMultiplayerInterface::SendControlRelease - no connections\n"); + wxASSERT(false); + return; + } + + std::list<int>::const_iterator iter = connectionList.begin(); + int destination = *iter; + + tcStream stream; + tcUpdateMessageHandler::InitializeMessage(tcUpdateMessageHandler::CONTROL_REQUEST, stream); + + tcUpdateMessageHandler::AddControlRelease(id, stream); + + SendUpdateMessageAck(destination, stream); + } + + /** * Sends control request message to server requesting control of object id by player */ *************** *** 997,1000 **** --- 1246,1270 ---- } + void tcMultiplayerInterface::SendSoundEffect(const std::string& player, const std::string& effect, long id) + { + int connectionId = GetPlayerConnectionId(player); + + if (connectionId != -1) + { + SendSoundEffect(connectionId, effect, id); + } + } + + void tcMultiplayerInterface::SendSoundEffect(int destination, const std::string& effect, long id) + { + tcStream stream; + tcUpdateMessageHandler::InitializeMessage(tcUpdateMessageHandler::SOUND_EFFECT, stream); + + tcUpdateMessageHandler::AddSoundEffect(id, effect, stream); + + SendUpdateMessage(destination, stream); + + } + void tcMultiplayerInterface::SendTestUDP(int destination, const std::string& message) { *************** *** 1233,1236 **** --- 1503,1531 ---- + /** + * Send script command messages to server + */ + void tcMultiplayerInterface::UpdateScriptCommands(int connectionId) + { + wxASSERT(!IsServer()); + + tcSimPythonInterface* pythonInterface = tcSimPythonInterface::Get(); + + if (!pythonInterface->HasNewCommand()) return; + + tcCommandStream commandStream; + tcUpdateMessageHandler::InitializeMessage(tcUpdateMessageHandler::SCRIPT_COMMANDS, commandStream); + + pythonInterface->operator>>(commandStream); + + pythonInterface->ClearNewCommand(); + + SendUpdateMessageAck(connectionId, commandStream); + #ifdef _DEBUG + fprintf(stdout, "Sent script commands\n"); + #endif + + } + *************** *** 1348,1351 **** --- 1643,1652 ---- int id = *iter; + // always do script command update at client + if (!IsServer()) + { + UpdateScriptCommands(id); + } + /* always do new cmd update, clear flag on last only. ** New commands need to be send to all clients at once with *************** *** 1458,1462 **** tcSound::Get()->PlayEffect("fslide"); ! tcAccountDatabase::Get()->LogOut(iter->second.name); } --- 1759,1763 ---- tcSound::Get()->PlayEffect("fslide"); ! LogOutPlayer(iter->second.name); } |