Ticket #3806: 3556_dedServer_v1.2.patch

File 3556_dedServer_v1.2.patch, 15.6 KB (added by Imarok, 3 years ago)

Still needs testing

  • binaries/data/mods/public/gui/common/network.js

     
    8989
    9090function kickPlayer(username, ban)
    9191{
    92     if (!Engine.KickPlayer(username, ban))
     92    if (g_IsController)
    9393        addChatMessage({
    9494            "type": "system",
    9595            "text": sprintf(ban ? translate("Could not ban %(name)s.") : translate("Could not kick %(name)s."), {
     
    9696                "name": username
    9797            })
    9898        });
     99    else
     100        Engine.KickPlayer(username, ban);
    99101}
    100102
    101103/**
  • source/gui/scripting/ScriptFunctions.cpp

     
    248248
    249249void StartNetworkGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
    250250{
    251     ENSURE(g_NetServer);
    252     g_NetServer->StartGame();
     251    ENSURE(g_NetClient);
     252    g_NetClient->SendStartGameMessage();
    253253}
    254254
    255255void StartGame(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue attribs, int playerID)
     
    332332
    333333void SetNetworkGameAttributes(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue attribs1)
    334334{
    335     ENSURE(g_NetServer);
     335    ENSURE(g_NetClient);
    336336    //TODO: This is a workaround because we need to pass a MutableHandle to a JSAPI functions somewhere
    337337    // (with no obvious reason).
    338338    JSContext* cx = pCxPrivate->pScriptInterface->GetContext();
     
    339339    JSAutoRequest rq(cx);
    340340    JS::RootedValue attribs(cx, attribs1);
    341341
    342     g_NetServer->UpdateGameAttributes(&attribs, *(pCxPrivate->pScriptInterface));
     342    g_NetClient->SendGameSetupMessage(&attribs, *(pCxPrivate->pScriptInterface));
    343343}
    344344
    345345void StartNetworkHost(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& playerName)
     
    402402    return g_NetClient->GetGUID();
    403403}
    404404
    405 bool KickPlayer(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const CStrW& playerName, bool ban)
     405void KickPlayer(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const CStrW& playerName, bool ban)
    406406{
    407     if (!g_NetServer)
    408         return false;
     407    if (!g_NetClient)
     408        return;
    409409
    410     return g_NetServer->KickPlayer(playerName, ban);
     410    g_NetClient->SendKickPlayerMessage(playerName, ban);
     411    return;
    411412}
    412413
    413414JS::Value PollNetworkClient(ScriptInterface::CxPrivate* pCxPrivate)
     
    425426
    426427void AssignNetworkPlayer(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int playerID, const std::string& guid)
    427428{
    428     ENSURE(g_NetServer);
     429    ENSURE(g_NetClient);
    429430
    430     g_NetServer->AssignPlayer(playerID, guid);
     431    g_NetClient->SendAssignPlayerMessage(playerID, guid);
    431432}
    432433
    433434void SetNetworkPlayerStatus(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& guid, int ready)
    434435{
    435     ENSURE(g_NetServer);
     436    ENSURE(g_NetClient);
    436437
    437     g_NetServer->SetPlayerReady(guid, ready);
     438    g_NetClient->SendSetPlayerStatusMessage(guid, ready);
    438439}
    439440
    440441void ClearAllPlayerReady (ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
    441442{
    442     ENSURE(g_NetServer);
     443    ENSURE(g_NetClient);
    443444
    444     g_NetServer->ClearAllPlayerReady();
     445    g_NetClient->ClearAllPlayerReady();
    445446}
    446447
    447448void SendNetworkChat(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& message)
     
    655656    return g_Game->GetSimRate();
    656657}
    657658
    658 void SetTurnLength(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int length)
    659 {
    660     if (g_NetServer)
    661         g_NetServer->SetTurnLength(length);
    662     else
    663         LOGERROR("Only network host can change turn length");
    664 }
    665 
    666659// Focus the game camera on a given position.
    667660void SetCameraTarget(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), float x, float y, float z)
    668661{
     
    10401033    scriptInterface.RegisterFunction<void, std::wstring, std::string, &StartNetworkJoin>("StartNetworkJoin");
    10411034    scriptInterface.RegisterFunction<void, &DisconnectNetworkGame>("DisconnectNetworkGame");
    10421035    scriptInterface.RegisterFunction<std::string, &GetPlayerGUID>("GetPlayerGUID");
    1043     scriptInterface.RegisterFunction<bool, CStrW, bool, &KickPlayer>("KickPlayer");
     1036    scriptInterface.RegisterFunction<void, CStrW, bool, &KickPlayer>("KickPlayer");
    10441037    scriptInterface.RegisterFunction<JS::Value, &PollNetworkClient>("PollNetworkClient");
    10451038    scriptInterface.RegisterFunction<void, JS::HandleValue, &SetNetworkGameAttributes>("SetNetworkGameAttributes");
    10461039    scriptInterface.RegisterFunction<void, int, std::string, &AssignNetworkPlayer>("AssignNetworkPlayer");
     
    11061099    scriptInterface.RegisterFunction<void, unsigned int, &StopJsTimer>("StopXTimer");
    11071100    scriptInterface.RegisterFunction<void, float, &SetSimRate>("SetSimRate");
    11081101    scriptInterface.RegisterFunction<float, &GetSimRate>("GetSimRate");
    1109     scriptInterface.RegisterFunction<void, int, &SetTurnLength>("SetTurnLength");
    11101102    scriptInterface.RegisterFunction<void, float, float, float, &SetCameraTarget>("SetCameraTarget");
    11111103    scriptInterface.RegisterFunction<int, &Crash>("Crash");
    11121104    scriptInterface.RegisterFunction<void, &DebugWarn>("DebugWarn");
  • source/network/NetClient.cpp

     
    323323    SetCurrState(NCS_UNCONNECTED);
    324324}
    325325
     326void CNetClient::SendGameSetupMessage(JS::MutableHandleValue attrs, ScriptInterface& scriptInterface)
     327{
     328    JSContext* cx = scriptInterface.GetContext();
     329    JS::RootedValue attrsRooted(cx);
     330    attrsRooted = attrs;
     331
     332    CGameSetupMessage gameSetup(scriptInterface);
     333    gameSetup.m_Data = attrsRooted;
     334    SendMessage(&gameSetup);
     335}
     336
     337void CNetClient::SendAssignPlayerMessage(const int playerID, const std::string& guid)
     338{
     339    CAssignPlayerMessage assignPlayer;
     340    assignPlayer.m_PlayerID = playerID;
     341    assignPlayer.m_GUIDToAssign = guid;
     342    SendMessage(&assignPlayer);
     343}
     344
    326345void CNetClient::SendChatMessage(const std::wstring& text)
    327346{
    328347    CChatMessage chat;
     
    337356    SendMessage(&readyStatus);
    338357}
    339358
     359void CNetClient::SendSetPlayerStatusMessage(const std::string& guid, const int ready)
     360{
     361    CSetPlayerStatusMessage setStatus;
     362    setStatus.m_GUID = guid;
     363    setStatus.m_Ready = ready;
     364    SendMessage(&setStatus);
     365}
     366
     367void CNetClient::SendStartGameMessage()
     368{
     369    CGameStartMessage gameStart;
     370    SendMessage(&gameStart);
     371}
     372
    340373void CNetClient::SendRejoinedMessage()
    341374{
    342375    CRejoinedMessage rejoinedMessage;
     
    343376    SendMessage(&rejoinedMessage);
    344377}
    345378
     379void CNetClient::SendKickPlayerMessage(const CStrW& playerName, bool ban)
     380{
     381    CKickedMessage kickPlayer;
     382    kickPlayer.m_Name = playerName;
     383    kickPlayer.m_Ban = ban;
     384    SendMessage(&kickPlayer);
     385}
     386
    346387void CNetClient::SendPausedMessage(bool pause)
    347388{
    348389    CClientPausedMessage pausedMessage;
     
    350391    SendMessage(&pausedMessage);
    351392}
    352393
     394void CNetClient::ClearAllPlayerReady()
     395{
     396    for (PlayerAssignmentMap::iterator it = m_PlayerAssignments.begin(); it != m_PlayerAssignments.end(); ++it)
     397        SendSetPlayerStatusMessage(it->first, 0);
     398}
     399
    353400bool CNetClient::HandleMessage(CNetMessage* message)
    354401{
    355402    // Handle non-FSM messages first
  • source/network/NetClient.h

     
    187187     */
    188188    void LoadFinished();
    189189
     190    void SendGameSetupMessage(JS::MutableHandleValue attrs, ScriptInterface& scriptInterface);
     191
     192    void SendAssignPlayerMessage(const int playerID, const std::string& guid);
     193
    190194    void SendChatMessage(const std::wstring& text);
    191195
    192196    void SendReadyMessage(const int status);
    193197
     198    void SendSetPlayerStatusMessage(const std::string& guid, const int ready);
     199
     200    void SendStartGameMessage();
     201
    194202    /**
    195203     * Call when the client has rejoined a running match and finished
    196204     * the loading screen.
     
    198206    void SendRejoinedMessage();
    199207
    200208    /**
     209     * Call when a client kicks/ban a player
     210     */
     211    void SendKickPlayerMessage(const CStrW& playerName, bool ban);
     212
     213    /**
    201214     * Call when the client has paused or unpaused the game.
    202215     */
    203216    void SendPausedMessage(bool pause);
    204217
     218    /**
     219     *
     220     */
     221    void ClearAllPlayerReady();
     222
    205223private:
    206224    // Net message / FSM transition handlers
    207225    static bool OnConnect(void* context, CFsmEvent* event);
  • source/network/NetMessage.cpp

     
    203203        pNewMessage = new CSimulationMessage(scriptInterface);
    204204        break;
    205205
     206    case NMT_ASSIGN_PLAYER:
     207        pNewMessage = new CAssignPlayerMessage;
     208        break;
     209
     210    case NMT_SET_PLAYER_STATUS:
     211        pNewMessage = new CSetPlayerStatusMessage;
     212        break;
     213
    206214    default:
    207215        LOGERROR("CNetMessageFactory::CreateMessage(): Unknown message type '%d' received", header.GetType());
    208216        break;
  • source/network/NetMessages.h

     
    2828
    2929#define PS_PROTOCOL_MAGIC               0x5073013f      // 'P', 's', 0x01, '?'
    3030#define PS_PROTOCOL_MAGIC_RESPONSE      0x50630121      // 'P', 'c', 0x01, '!'
    31 #define PS_PROTOCOL_VERSION             0x01010013      // Arbitrary protocol
     31#define PS_PROTOCOL_VERSION             0x01010014      // Arbitrary protocol
    3232#define PS_DEFAULT_PORT                 0x5073          // 'P', 's'
    3333
    3434// Defines the list of message types. The order of the list must not change.
     
    5151    NMT_CHAT,
    5252    NMT_READY,
    5353    NMT_GAME_SETUP,
     54    NMT_ASSIGN_PLAYER,
    5455    NMT_PLAYER_ASSIGNMENT,
     56    NMT_SET_PLAYER_STATUS,
    5557
    5658    NMT_FILE_TRANSFER_REQUEST,
    5759    NMT_FILE_TRANSFER_RESPONSE,
     
    145147    NMT_END_ARRAY()
    146148END_NMT_CLASS()
    147149
     150START_NMT_CLASS_(SetPlayerStatus, NMT_SET_PLAYER_STATUS)
     151    NMT_FIELD(CStr, m_GUID)
     152    NMT_FIELD_INT(m_Ready, u8, 1)
     153END_NMT_CLASS()
     154
    148155START_NMT_CLASS_(FileTransferRequest, NMT_FILE_TRANSFER_REQUEST)
    149156    NMT_FIELD_INT(m_RequestID, u32, 4)
    150157END_NMT_CLASS()
     
    218225    NMT_END_ARRAY()
    219226END_NMT_CLASS()
    220227
     228START_NMT_CLASS_(AssignPlayer, NMT_ASSIGN_PLAYER)
     229    NMT_FIELD_INT(m_PlayerID, i8, 1)
     230    NMT_FIELD(CStr, m_GUIDToAssign)
     231END_NMT_CLASS()
     232
    221233END_NMTS()
    222234
    223235#else
  • source/network/NetServer.cpp

     
    649649    session->AddTransition(NSS_PREGAME, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, (void*)&OnDisconnect, context);
    650650    session->AddTransition(NSS_PREGAME, (uint)NMT_CHAT, NSS_PREGAME, (void*)&OnChat, context);
    651651    session->AddTransition(NSS_PREGAME, (uint)NMT_READY, NSS_PREGAME, (void*)&OnReady, context);
     652    session->AddTransition(NSS_PREGAME, (uint)NMT_SET_PLAYER_STATUS, NSS_PREGAME, (void*)&OnSetPlayerStatus, context);
     653    session->AddTransition(NSS_PREGAME, (uint)NMT_GAME_SETUP, NSS_PREGAME, (void*)&OnGameSetup, context);
     654    session->AddTransition(NSS_PREGAME, (uint)NMT_ASSIGN_PLAYER, NSS_PREGAME, (void*)&OnAssignPlayer, context);
     655    session->AddTransition(NSS_PREGAME, (uint)NMT_KICKED, NSS_PREGAME, (void*)&OnKickPlayer, context);
     656    session->AddTransition(NSS_PREGAME, (uint)NMT_GAME_START, NSS_PREGAME, (void*)&OnStartGame, context);
    652657    session->AddTransition(NSS_PREGAME, (uint)NMT_LOADED_GAME, NSS_INGAME, (void*)&OnLoadedGame, context);
    653658
    654659    session->AddTransition(NSS_JOIN_SYNCING, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, (void*)&OnDisconnect, context);
     
    655660    session->AddTransition(NSS_JOIN_SYNCING, (uint)NMT_LOADED_GAME, NSS_INGAME, (void*)&OnJoinSyncingLoadedGame, context);
    656661
    657662    session->AddTransition(NSS_INGAME, (uint)NMT_REJOINED, NSS_INGAME, (void*)&OnRejoined, context);
     663    session->AddTransition(NSS_INGAME, (uint)NMT_KICKED, NSS_INGAME, (void*)&OnKickPlayer, context);
    658664    session->AddTransition(NSS_INGAME, (uint)NMT_CLIENT_PAUSED, NSS_INGAME, (void*)&OnClientPaused, context);
    659665    session->AddTransition(NSS_INGAME, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, (void*)&OnDisconnect, context);
    660666    session->AddTransition(NSS_INGAME, (uint)NMT_CHAT, NSS_INGAME, (void*)&OnChat, context);
     
    792798
    793799    // and return if no one or the host has that name
    794800    if (it == m_Sessions.end() || (*it)->GetGUID() == m_HostGUID)
     801    {
     802        LOGERROR("Couldn't %s player", ban ? "ban" : "kick");
    795803        return false;
     804    }
    796805
    797806    if (ban)
    798807    {
     
    11111120    return true;
    11121121}
    11131122
     1123bool CNetServerWorker::OnSetPlayerStatus(void* context, CFsmEvent* event)
     1124{
     1125    ENSURE(event->GetType() == (uint)NMT_SET_PLAYER_STATUS);
     1126
     1127    CNetServerSession* session = (CNetServerSession*)context;
     1128    CNetServerWorker& server = session->GetServer();
     1129
     1130    if (session->GetGUID() != server.m_HostGUID)
     1131        return true;
     1132
     1133    CSetPlayerStatusMessage* message = (CSetPlayerStatusMessage*)event->GetParamRef();
     1134
     1135    server.SetPlayerReady(message->m_GUID, message->m_Ready);
     1136    return true;
     1137}
     1138
     1139bool CNetServerWorker::OnGameSetup(void* context, CFsmEvent* event)
     1140{
     1141    ENSURE(event->GetType() == (uint)NMT_GAME_SETUP);
     1142
     1143    CNetServerSession* session = (CNetServerSession*)context;
     1144    CNetServerWorker& server = session->GetServer();
     1145
     1146    if (session->GetGUID() != server.m_HostGUID)
     1147        return true;
     1148
     1149    CGameSetupMessage* message = (CGameSetupMessage*)event->GetParamRef();
     1150
     1151    server.UpdateGameAttributes(&(message->m_Data));
     1152    return true;
     1153}
     1154
     1155bool CNetServerWorker::OnAssignPlayer(void* context, CFsmEvent* event)
     1156{
     1157    ENSURE(event->GetType() == (uint)NMT_ASSIGN_PLAYER);
     1158    CNetServerSession* session = (CNetServerSession*)context;
     1159    CNetServerWorker& server = session->GetServer();
     1160
     1161    if (session->GetGUID() != server.m_HostGUID)
     1162        return true;
     1163
     1164    CAssignPlayerMessage* message = (CAssignPlayerMessage*)event->GetParamRef();
     1165    server.m_AssignPlayerQueue.emplace_back(message->m_PlayerID, message->m_GUIDToAssign);
     1166    return true;
     1167}
     1168
     1169bool CNetServerWorker::OnStartGame(void* context, CFsmEvent* event)
     1170{
     1171    ENSURE(event->GetType() == (uint)NMT_GAME_START);
     1172    CNetServerSession* session = (CNetServerSession*)context;
     1173    CNetServerWorker& server = session->GetServer();
     1174
     1175    if (session->GetGUID() != server.m_HostGUID)
     1176        return true;
     1177
     1178    server.StartGame();
     1179    return true;
     1180}
     1181
    11141182bool CNetServerWorker::OnLoadedGame(void* context, CFsmEvent* event)
    11151183{
    11161184    ENSURE(event->GetType() == (uint)NMT_LOADED_GAME);
     
    12031271    return true;
    12041272}
    12051273
     1274bool CNetServerWorker::OnKickPlayer(void* context, CFsmEvent* event)
     1275{
     1276    ENSURE(event->GetType() == (uint)NMT_KICKED);
     1277
     1278    CNetServerSession* session = (CNetServerSession*)context;
     1279    CNetServerWorker& server = session->GetServer();
     1280
     1281    if (session->GetGUID() != server.m_HostGUID)
     1282        return true;
     1283
     1284    CKickedMessage* message = (CKickedMessage*)event->GetParamRef();
     1285    server.KickPlayer(message->m_Name, message->m_Ban);
     1286    return true;
     1287}
     1288
    12061289bool CNetServerWorker::OnDisconnect(void* context, CFsmEvent* event)
    12071290{
    12081291    ENSURE(event->GetType() == (uint)NMT_CONNECTION_LOST);
  • source/network/NetServer.h

     
    270270    static bool OnInGame(void* context, CFsmEvent* event);
    271271    static bool OnChat(void* context, CFsmEvent* event);
    272272    static bool OnReady(void* context, CFsmEvent* event);
     273    static bool OnSetPlayerStatus(void* context, CFsmEvent* event);
     274    static bool OnGameSetup(void* context, CFsmEvent* event);
     275    static bool OnAssignPlayer(void* context, CFsmEvent* event);
     276    static bool OnStartGame(void* context, CFsmEvent* event);
    273277    static bool OnLoadedGame(void* context, CFsmEvent* event);
    274278    static bool OnJoinSyncingLoadedGame(void* context, CFsmEvent* event);
    275279    static bool OnRejoined(void* context, CFsmEvent* event);
     280    static bool OnKickPlayer(void* context, CFsmEvent* event);
    276281    static bool OnDisconnect(void* context, CFsmEvent* event);
    277282    static bool OnClientPaused(void* context, CFsmEvent* event);
    278283