Ticket #3575: 3575_differentPorts_v2.5.patch

File 3575_differentPorts_v2.5.patch, 18.7 KB (added by Imarok, 3 years ago)

use only u16. Added tooltip for port input field. Only allow valid ports

  • binaries/data/mods/public/gui/gamesetup/gamesetup.js

     
    160160 * To report the game to the lobby bot.
    161161 */
    162162var g_ServerName;
     163var g_ServerPort;
    163164
    164165/**
    165166 * States whether the GUI is currently updated in response to network messages instead of user input
     
    243244    g_IsNetworked = attribs.type != "offline";
    244245    g_IsController = attribs.type != "client";
    245246    g_ServerName = attribs.serverName || undefined;
     247    g_ServerPort = attribs.serverPort;
    246248
    247249    // Replace empty playername when entering a singleplayermatch for the first time
    248250    if (!g_IsNetworked)
     
    19401942
    19411943    let stanza = {
    19421944        "name": g_ServerName,
     1945        "port": g_ServerPort,
    19431946        "mapName": g_GameAttributes.map,
    19441947        "niceMapName": getMapDisplayName(g_GameAttributes.map),
    19451948        "mapSize": mapSize,
  • binaries/data/mods/public/gui/gamesetup/gamesetup_mp.js

     
    11var g_IsConnecting = false;
    22var g_GameType; // "server" or "client"
    33var g_ServerName = "";
     4var g_ServerPort;
    45
    56var g_IsRejoining = false;
    67var g_GameAttributes; // used when rejoining
     
    1516    case "join":
    1617        if(Engine.HasXmppClient())
    1718        {
    18             if (startJoin(attribs.name, attribs.ip))
     19            if (startJoin(attribs.name, attribs.ip, getValidPort(attribs.port)))
    1920                switchSetupPage("pageJoin", "pageConnecting");
    2021        }
    2122        else
     
    2728    case "host":
    2829        Engine.GetGUIObjectByName("pageJoin").hidden = true;
    2930        Engine.GetGUIObjectByName("pageHost").hidden = false;
     31        Engine.GetGUIObjectByName("hostPortWrapper").hidden = false;
    3032        if(Engine.HasXmppClient())
    3133        {
    3234            Engine.GetGUIObjectByName("hostServerNameWrapper").hidden = false;
     
    6062    {
    6163        let joinPlayerName = Engine.GetGUIObjectByName("joinPlayerName").caption;
    6264        let joinServer = Engine.GetGUIObjectByName("joinServer").caption;
    63         if (startJoin(joinPlayerName, joinServer))
     65        let joinPort = getValidPort(Engine.GetGUIObjectByName("joinPort").caption);
     66        if (startJoin(joinPlayerName, joinServer, joinPort))
    6467            switchSetupPage("pageJoin", "pageConnecting");
    6568    }
    6669    else if (!Engine.GetGUIObjectByName("pageHost").hidden)
     
    6770    {
    6871        let hostPlayerName = Engine.GetGUIObjectByName("hostPlayerName").caption;
    6972        let hostServerName = Engine.GetGUIObjectByName("hostServerName").caption;
    70         if (startHost(hostPlayerName, hostServerName))
     73        let hostPort = getValidPort(Engine.GetGUIObjectByName("hostPort").caption);
     74        if (startHost(hostPlayerName, hostServerName, hostPort))
    7175            switchSetupPage("pageHost", "pageConnecting");
    7276    }
    7377}
    7478
     79function getValidPort(port)
     80{
     81    if (+port && +port >= 0 && +port <=65535)
     82        return +port
     83    return Engine.GetDefaultPort();
     84}
     85
    7586function startConnectionStatus(type)
    7687{
    7788    g_GameType = type;
     
    177188                    }
    178189                    else
    179190                    {
    180                         Engine.SwitchGuiPage("page_gamesetup.xml", { "type": g_GameType, "serverName": g_ServerName });
     191                        Engine.SwitchGuiPage("page_gamesetup.xml", {
     192                            "type": g_GameType,
     193                            "serverName": g_ServerName,
     194                            "serverPort": g_ServerPort
     195                        });
    181196                        return; // don't process any more messages - leave them for the game GUI loop
    182197                    }
    183198
     
    210225    Engine.GetGUIObjectByName("continueButton").hidden = true;
    211226}
    212227
    213 function startHost(playername, servername)
     228function startHost(playername, servername, port)
    214229{
    215230    // Save player name
    216231    Engine.ConfigDB_CreateValue("user", "playername.multiplayer", playername);
    217232    Engine.ConfigDB_WriteValueToFile("user", "playername.multiplayer", playername, "config/user.cfg");
     233    Engine.ConfigDB_CreateValue("user", "multiplayerhosting.port", port);
     234    Engine.ConfigDB_WriteValueToFile("user", "multiplayerhosting.port", port, "config/user.cfg");
    218235
    219236    // Disallow identically named games in the multiplayer lobby
    220237    if (Engine.HasXmppClient())
     
    231248    try
    232249    {
    233250        if (g_UserRating)
    234             Engine.StartNetworkHost(playername + " (" + g_UserRating + ")");
     251            Engine.StartNetworkHost(playername + " (" + g_UserRating + ")", port);
    235252        else
    236             Engine.StartNetworkHost(playername);
     253            Engine.StartNetworkHost(playername, port);
    237254    }
    238255    catch (e)
    239256    {
     
    248265
    249266    startConnectionStatus("server");
    250267    g_ServerName = servername;
     268    g_ServerPort = port;
    251269
    252270    if (Engine.HasXmppClient())
    253271        Engine.LobbySetPlayerPresence("playing");
     
    255273    return true;
    256274}
    257275
    258 function startJoin(playername, ip)
     276function startJoin(playername, ip, port)
    259277{
    260278    try
    261279    {
    262280        if (g_UserRating)
    263             Engine.StartNetworkJoin(playername + " (" + g_UserRating + ")", ip);
     281            Engine.StartNetworkJoin(playername + " (" + g_UserRating + ")", ip, port);
    264282        else
    265             Engine.StartNetworkJoin(playername, ip);
     283            Engine.StartNetworkJoin(playername, ip, port);
    266284    }
    267285    catch (e)
    268286    {
     
    286304        Engine.ConfigDB_WriteValueToFile("user", "playername.multiplayer", playername, "config/user.cfg");
    287305        Engine.ConfigDB_CreateValue("user", "multiplayerserver", ip);
    288306        Engine.ConfigDB_WriteValueToFile("user", "multiplayerserver", ip, "config/user.cfg");
     307        Engine.ConfigDB_CreateValue("user", "multiplayerjoining.port", port);
     308        Engine.ConfigDB_WriteValueToFile("user", "multiplayerjoining.port", port, "config/user.cfg");
    289309    }
    290310    return true;
    291311}
  • binaries/data/mods/public/gui/gamesetup/gamesetup_mp.xml

     
    4545                    this.caption = Engine.ConfigDB_GetValue("user", "multiplayerserver");
    4646                </action>
    4747            </object>
     48
     49            <object type="text" size="20 120 50% 150" style="ModernLabelText" text_align="right">
     50                <translatableAttribute id="caption">Server Port:</translatableAttribute>
     51            </object>
     52
     53            <object name="joinPort" type="input" size="50%+10 120 100%-20 144" style="ModernInput">
     54                <translatableAttribute id="tooltip">Leave blank to use the default port.</translatableAttribute>
     55                <action on="Load">
     56                    this.caption = Engine.ConfigDB_GetValue("user", "multiplayerjoining.port");
     57                </action>
     58            </object>
    4859        </object>
    4960
    5061        <object name="pageHost" size="0 32 100% 100%" hidden="true">
     
    5465            </object>
    5566
    5667            <object name="hostPlayerNameWrapper" hidden="true">
    57             <object type="text" size="20 40 50% 70" style="ModernLabelText" text_align="right">
    58                 <translatableAttribute id="caption">Player name:</translatableAttribute>
    59             </object>
     68                <object type="text" size="20 40 50% 70" style="ModernLabelText" text_align="right">
     69                    <translatableAttribute id="caption">Player name:</translatableAttribute>
     70                </object>
    6071
    61             <object name="hostPlayerName" type="input" size="50%+10 40 100%-20 64" style="ModernInput">
    62                 <action on="Load">
    63                     this.caption = multiplayerName();
    64                 </action>
     72                <object name="hostPlayerName" type="input" size="50%+10 40 100%-20 64" style="ModernInput">
     73                    <action on="Load">
     74                        this.caption = multiplayerName();
     75                    </action>
     76                </object>
    6577            </object>
    66             </object>
    6778
    6879            <!-- Host server name is only used on games started through the lobby. -->
    6980            <object name="hostServerNameWrapper" hidden="true">
     
    7788                    </action>
    7889                </object>
    7990            </object>
     91
     92            <object name="hostPortWrapper" hidden="true">
     93                <object type="text" size="20 120 50% 150" style="ModernLabelText" text_align="right">
     94                    <translatableAttribute id="caption">Server Port:</translatableAttribute>
     95                </object>
     96
     97                <object name="hostPort" type="input" size="50%+10 120 100%-20 144" style="ModernInput">
     98                    <translatableAttribute id="tooltip">Leave blank to use the default port.</translatableAttribute>
     99                    <action on="Load">
     100                        this.caption = Engine.ConfigDB_GetValue("user", "multiplayerhosting.port");
     101                    </action>
     102                </object>
     103            </object>
    80104        </object>
    81105
    82106        <object name="hostFeedback" type="text" style="ModernLabelText" size="50 100%-90 100%-50 100%-50" textcolor="red" />
  • binaries/data/mods/public/gui/lobby/lobby.js

     
    102102var g_SelectedGameIP = "";
    103103
    104104/**
     105 * Used to restore the selection after updating the gamelist.
     106 */
     107var g_SelectedGamePort = "";
     108
     109/**
    105110 * Notifications sent by XmppClient.cpp
    106111 */
    107112var g_NetMessageTypes = {
     
    509514    var sortOrder = gamesBox.selected_column_order || 1;
    510515
    511516    if (gamesBox.selected > -1)
     517    {
    512518        g_SelectedGameIP = g_GameList[gamesBox.selected].ip;
     519        g_SelectedGamePort = g_GameList[gamesBox.selected].port;
     520    }
    513521
    514522    g_GameList = Engine.GetGameList().filter(game => !filterGame(game)).sort((a, b) => {
    515523        var sortA, sortB;
     
    556564        let gameName = escapeText(game.name);
    557565        let mapTypeIdx = g_MapTypes.Name.indexOf(game.mapType);
    558566
    559         if (game.ip == g_SelectedGameIP)
     567        if (game.ip == g_SelectedGameIP && game.port == g_SelectedGamePort)
    560568            selectedGameIndex = +i;
    561569
    562570        list_name.push('[color="' + g_GameColors[game.state] + '"]' + gameName);
     
    672680        });
    673681        return;
    674682    }
     683    if (!game.port)
     684    {
     685        addChatMessage({
     686            "from": "system",
     687            "text": translate("The game's port is missing.")
     688        });
     689        return;
     690    }
    675691
    676692    Engine.PushGuiPage("page_gamesetup_mp.xml", {
    677693        "multiplayerGameType": "join",
    678694        "ip": game.ip,
     695        "port": game.port,
    679696        "name": g_Username,
    680697        "rating": g_UserRating
    681698    });
  • source/gui/scripting/ScriptFunctions.cpp

     
    341341    g_NetClient->SendGameSetupMessage(&attribs, *(pCxPrivate->pScriptInterface));
    342342}
    343343
    344 void StartNetworkHost(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& playerName)
     344void StartNetworkHost(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& playerName, unsigned int serverPort)
    345345{
    346346    ENSURE(!g_NetClient);
    347347    ENSURE(!g_NetServer);
     
    348348    ENSURE(!g_Game);
    349349
    350350    g_NetServer = new CNetServer();
    351     if (!g_NetServer->SetupConnection())
     351    if (!g_NetServer->SetupConnection(serverPort))
    352352    {
    353353        pCxPrivate->pScriptInterface->ReportError("Failed to start server");
    354354        SAFE_DELETE(g_NetServer);
     
    359359    g_NetClient = new CNetClient(g_Game, true);
    360360    g_NetClient->SetUserName(playerName);
    361361
    362     if (!g_NetClient->SetupConnection("127.0.0.1"))
     362    if (!g_NetClient->SetupConnection("127.0.0.1", serverPort))
    363363    {
    364364        pCxPrivate->pScriptInterface->ReportError("Failed to connect to server");
    365365        SAFE_DELETE(g_NetClient);
     
    367367    }
    368368}
    369369
    370 void StartNetworkJoin(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& playerName, const std::string& serverAddress)
     370void StartNetworkJoin(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& playerName, const std::string& serverAddress, u16 serverPort)
    371371{
    372372    ENSURE(!g_NetClient);
    373373    ENSURE(!g_NetServer);
     
    376376    g_Game = new CGame();
    377377    g_NetClient = new CNetClient(g_Game, false);
    378378    g_NetClient->SetUserName(playerName);
    379     if (!g_NetClient->SetupConnection(serverAddress))
     379    if (!g_NetClient->SetupConnection(serverAddress, serverPort))
    380380    {
    381381        pCxPrivate->pScriptInterface->ReportError("Failed to connect to server");
    382382        SAFE_DELETE(g_NetClient);
     
    384384    }
    385385}
    386386
     387u16 GetDefaultPort(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
     388{
     389    return PS_DEFAULT_PORT;
     390}
     391
    387392void DisconnectNetworkGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
    388393{
    389394    // TODO: we ought to do async reliable disconnections
     
    10271032    scriptInterface.RegisterFunction<void, &StartNetworkGame>("StartNetworkGame");
    10281033    scriptInterface.RegisterFunction<void, JS::HandleValue, int, &StartGame>("StartGame");
    10291034    scriptInterface.RegisterFunction<void, &Script_EndGame>("EndGame");
    1030     scriptInterface.RegisterFunction<void, std::wstring, &StartNetworkHost>("StartNetworkHost");
    1031     scriptInterface.RegisterFunction<void, std::wstring, std::string, &StartNetworkJoin>("StartNetworkJoin");
     1035    scriptInterface.RegisterFunction<void, std::wstring, unsigned int, &StartNetworkHost>("StartNetworkHost");
     1036    scriptInterface.RegisterFunction<void, std::wstring, std::string, u16, &StartNetworkJoin>("StartNetworkJoin");
     1037    scriptInterface.RegisterFunction<u16, &GetDefaultPort>("GetDefaultPort");
    10321038    scriptInterface.RegisterFunction<void, &DisconnectNetworkGame>("DisconnectNetworkGame");
    10331039    scriptInterface.RegisterFunction<std::string, &GetPlayerGUID>("GetPlayerGUID");
    10341040    scriptInterface.RegisterFunction<void, CStrW, bool, &KickPlayer>("KickPlayer");
  • source/lobby/XmppClient.cpp

     
    502502    JSAutoRequest rq(cx);
    503503
    504504    scriptInterface.Eval("([])", ret);
    505     const char* stats[] = { "name", "ip", "state", "nbp", "tnbp", "players", "mapName", "niceMapName", "mapSize", "mapType", "victoryCondition" };
     505    const char* stats[] = { "name", "ip", "port", "state", "nbp", "tnbp", "players", "mapName", "niceMapName", "mapSize", "mapType", "victoryCondition" };
    506506    for(const glooxwrapper::Tag* const& t : m_GameList)
    507507    {
    508508        JS::RootedValue game(cx);
  • source/network/NetClient.cpp

     
    154154    m_UserName = username;
    155155}
    156156
    157 bool CNetClient::SetupConnection(const CStr& server)
     157bool CNetClient::SetupConnection(const CStr& server, u16 port)
    158158{
    159159    CNetClientSession* session = new CNetClientSession(*this);
    160     bool ok = session->Connect(PS_DEFAULT_PORT, server, m_IsLocalClient);
     160    bool ok = session->Connect(port, server, m_IsLocalClient);
    161161    SetAndOwnSession(session);
    162162    return ok;
    163163}
  • source/network/NetClient.h

     
    9999     * @param server IP address or host name to connect to
    100100     * @return true on success, false on connection failure
    101101     */
    102     bool SetupConnection(const CStr& server);
     102    bool SetupConnection(const CStr& server, u16 port);
    103103
    104104    /**
    105105     * Destroy the connection to the server.
  • source/network/NetServer.cpp

     
    169169    delete m_ServerTurnManager;
    170170}
    171171
    172 bool CNetServerWorker::SetupConnection()
     172bool CNetServerWorker::SetupConnection(u16 port)
    173173{
    174174    ENSURE(m_State == SERVER_STATE_UNCONNECTED);
    175175    ENSURE(!m_Host);
     
    177177    // Bind to default host
    178178    ENetAddress addr;
    179179    addr.host = ENET_HOST_ANY;
    180     addr.port = PS_DEFAULT_PORT;
     180    addr.port = port;
    181181
    182182    // Create ENet server
    183183    m_Host = enet_host_create(&addr, MAX_CLIENTS, CHANNEL_COUNT, 0, 0);
     
    14271427    delete m_Worker;
    14281428}
    14291429
    1430 bool CNetServer::SetupConnection()
     1430bool CNetServer::SetupConnection(u16 port)
    14311431{
    1432     return m_Worker->SetupConnection();
     1432    return m_Worker->SetupConnection(port);
    14331433}
    14341434
    14351435void CNetServer::StartGame()
  • source/network/NetServer.h

     
    113113     * This function is synchronous (it won't return until the connection is established).
    114114     * @return true on success, false on error (e.g. port already in use)
    115115     */
    116     bool SetupConnection();
     116    bool SetupConnection(u16 port);
    117117
    118118    /**
    119119     * Call from the GUI to asynchronously notify all clients that they should start loading the game.
     
    184184     * Begin listening for network connections.
    185185     * @return true on success, false on error (e.g. port already in use)
    186186     */
    187     bool SetupConnection();
     187    bool SetupConnection(u16 port);
    188188
    189189    /**
    190190     * Call from the GUI to update the player assignments.
  • source/network/tests/test_Net.h

     
    1 /* Copyright (C) 2014 Wildfire Games.
     1/* Copyright (C) 2016 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
     
    2424#include "network/NetServer.h"
    2525#include "network/NetClient.h"
    2626#include "network/NetTurnManager.h"
     27#include "network/NetMessage.h"
     28#include "network/NetMessages.h"
    2729#include "ps/CLogger.h"
    2830#include "ps/Game.h"
    2931#include "ps/Filesystem.h"
     
    7173
    7274    void connect(CNetServer& server, const std::vector<CNetClient*>& clients)
    7375    {
    74         TS_ASSERT(server.SetupConnection());
     76        TS_ASSERT(server.SetupConnection(PS_DEFAULT_PORT));
    7577        for (size_t j = 0; j < clients.size(); ++j)
    76             TS_ASSERT(clients[j]->SetupConnection("127.0.0.1"));
     78            TS_ASSERT(clients[j]->SetupConnection("127.0.0.1", PS_DEFAULT_PORT));
    7779
    7880        for (size_t i = 0; ; ++i)
    7981        {
     
    273275        client2B.SetUserName(L"bob");
    274276        clients.push_back(&client2B);
    275277
    276         TS_ASSERT(client2B.SetupConnection("127.0.0.1"));
     278        TS_ASSERT(client2B.SetupConnection("127.0.0.1", PS_DEFAULT_PORT));
    277279
    278280        for (size_t i = 0; ; ++i)
    279281        {
  • source/ps/GameSetup/GameSetup.cpp

     
    5050#include "maths/MathUtil.h"
    5151#include "network/NetServer.h"
    5252#include "network/NetClient.h"
     53#include "network/NetMessage.h"
     54#include "network/NetMessages.h"
    5355
    5456#include "ps/CConsole.h"
    5557#include "ps/CLogger.h"
     
    14831485
    14841486        g_NetServer->UpdateGameAttributes(&attrs, scriptInterface);
    14851487
    1486         bool ok = g_NetServer->SetupConnection();
     1488        bool ok = g_NetServer->SetupConnection(PS_DEFAULT_PORT);
    14871489        ENSURE(ok);
    14881490
    14891491        g_NetClient = new CNetClient(g_Game, true);
    14901492        g_NetClient->SetUserName(userName);
    1491         g_NetClient->SetupConnection("127.0.0.1");
     1493        g_NetClient->SetupConnection("127.0.0.1", PS_DEFAULT_PORT);
    14921494    }
    14931495    else if (args.Has("autostart-client"))
    14941496    {
     
    15011503        if (ip.empty())
    15021504            ip = "127.0.0.1";
    15031505
    1504         bool ok = g_NetClient->SetupConnection(ip);
     1506        bool ok = g_NetClient->SetupConnection(ip, PS_DEFAULT_PORT);
    15051507        ENSURE(ok);
    15061508    }
    15071509    else