Ticket #3806: 3806_player_gamesetup_v2.3.patch

File 3806_player_gamesetup_v2.3.patch, 44.7 KB (added by Imarok, 3 years ago)

cpp part is finished. js part needs to wait for #3994

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

     
    1616    let aiSelection = Engine.GetGUIObjectByName("aiSelection");
    1717    aiSelection.list = g_AIDescriptions.map(ai => ai.data.name);
    1818    aiSelection.selected = g_AIDescriptions.findIndex(ai => ai.id == settings.id);
    19     aiSelection.hidden = !settings.isController;
     19    aiSelection.hidden = !settings.canBeChanged;
    2020
    2121    let aiSelectionText = Engine.GetGUIObjectByName("aiSelectionText");
    2222    aiSelectionText.caption = aiSelection.list[aiSelection.selected];
    23     aiSelectionText.hidden = settings.isController;
     23    aiSelectionText.hidden = settings.canBeChanged;
    2424
    2525    let aiDiff = Engine.GetGUIObjectByName("aiDifficulty");
    2626    aiDiff.list = prepareForDropdown(g_Settings.AIDifficulties).Title;
    2727    aiDiff.selected = settings.difficulty;
    28     aiDiff.hidden = !settings.isController;
     28    aiDiff.hidden = !settings.canBeChanged;
    2929
    3030    let aiDiffText = Engine.GetGUIObjectByName("aiDifficultyText");
    3131    aiDiffText.caption = aiDiff.list[aiDiff.selected];
    32     aiDiffText.hidden = settings.isController;
     32    aiDiffText.hidden = settings.canBeChanged;
    3333}
    3434
    3535function selectAI(idx)
  • binaries/data/mods/public/gui/common/settings.js

     
    3737        "MapTypes": loadMapTypes(),
    3838        "MapSizes": loadSettingValuesFile("map_sizes.json"),
    3939        "PlayerDefaults": loadPlayerDefaults(),
     40        "GuestSettings": loadSettingValuesFile("guest_settings.json"),
    4041        "PopulationCapacities": loadPopulationCapacities(),
    4142        "StartingResources": loadSettingValuesFile("starting_resources.json"),
    4243        "VictoryConditions": loadVictoryConditions()
  • binaries/data/mods/public/gui/gamesetup/gamesetup.js

     
    55const g_GameSpeeds = prepareForDropdown(g_Settings && g_Settings.GameSpeeds.filter(speed => !speed.ReplayOnly));
    66const g_MapSizes = prepareForDropdown(g_Settings && g_Settings.MapSizes);
    77const g_MapTypes = prepareForDropdown(g_Settings && g_Settings.MapTypes);
     8const g_GuestSettings = prepareForDropdown(g_Settings && g_Settings.GuestSettings);
    89const g_PopulationCapacities = prepareForDropdown(g_Settings && g_Settings.PopulationCapacities);
    910const g_StartingResources = prepareForDropdown(g_Settings && g_Settings.StartingResources);
    1011const g_VictoryConditions = prepareForDropdown(g_Settings && g_Settings.VictoryConditions);
     
    3132    "netstatus": msg => handleNetStatusMessage(msg),
    3233    "netwarn": msg => addNetworkWarning(msg),
    3334    "gamesetup": msg => handleGamesetupMessage(msg),
     35    "changesetting": msg => handleChangeSettingMessage(msg),
    3436    "players": msg => handlePlayerAssignmentMessage(msg),
    3537    "ready": msg => handleReadyMessage(msg),
    3638    "start": msg => handleGamestartMessage(msg),
     
    270272    initCivNameList();
    271273    initMapTypes();
    272274    initMapFilters();
     275    initDropdowns();
    273276
    274277    if (g_IsController)
    275278    {
     
    277280        g_GameAttributes.matchID = Engine.GetMatchID();
    278281        g_GameAttributes.settings.CheatsEnabled = !g_IsNetworked;
    279282        g_GameAttributes.settings.RatingEnabled = Engine.IsRankedGame() || undefined;
    280 
    281         initMapNameList();
    282         initNumberOfPlayers();
    283         initGameSpeed();
    284         initPopulationCaps();
    285         initStartingResources();
    286         initCeasefire();
    287         initWonderDurations();
    288         initVictoryConditions();
    289         initMapSizes();
    290         initRadioButtons();
    291283    }
    292284    else
    293285        hideControls();
     
    309301    }
    310302}
    311303
     304function initDropdowns()
     305{
     306    initMapNameList();
     307    initNumberOfPlayers();
     308    initGameSpeed();
     309    initGuestSettings();
     310    initPopulationCaps();
     311    initStartingResources();
     312    initCeasefire();
     313    initWonderDurations();
     314    initVictoryConditions();
     315    initMapSizes();
     316    initRadioButtons();
     317}
     318
    312319function initMapTypes()
    313320{
    314321    let mapTypes = Engine.GetGUIObjectByName("mapType");
     
    316323    mapTypes.list_data = g_MapTypes.Name;
    317324    mapTypes.onSelectionChange = function() {
    318325        if (this.selected != -1)
     326        {
     327            if (!g_IsController)
     328            {
     329                changeSetting("mapType", this.list_data[this.selected]);
     330                return;
     331            }
    319332            selectMapType(this.list_data[this.selected]);
     333        }
    320334    };
    321     if (g_IsController)
    322         mapTypes.selected = g_MapTypes.Default;
     335    mapTypes.selected = g_MapTypes.Default;
    323336}
    324337
    325338function initMapFilters()
     
    329342    mapFilters.list_data = g_MapFilters.map(mapFilter => mapFilter.id);
    330343    mapFilters.onSelectionChange = function() {
    331344        if (this.selected != -1)
     345        {
     346            if (!g_IsController)
     347            {
     348                changeSetting("mapFilter", this.list_data[this.selected]);
     349                return;
     350            }
    332351            selectMapFilter(this.list_data[this.selected]);
     352        }
    333353    };
    334     if (g_IsController)
    335         mapFilters.selected = 0;
     354    mapFilters.selected = 0;
    336355    g_GameAttributes.mapFilter = "default";
    337356}
    338357
     
    349368        "optionPopulationCap",
    350369        "optionStartingResources",
    351370        "optionCeasefire",
     371        "optionGuestSettings",
    352372        "optionRevealMap",
    353373        "optionExploreMap",
    354374        "optionDisableTreasures",
     
    390410    numPlayers.list_data = playersArray;
    391411    numPlayers.onSelectionChange = function() {
    392412        if (this.selected != -1)
     413        {
     414            if (!g_IsController)
     415            {
     416                changeSetting("numPlayers", this.list_data[this.selected]);
     417                return;
     418            }
    393419            selectNumPlayers(this.list_data[this.selected]);
     420        }
    394421    };
    395422    numPlayers.selected = g_MaxPlayers - 1;
    396423}
     
    398425function initGameSpeed()
    399426{
    400427    let gameSpeed = Engine.GetGUIObjectByName("gameSpeed");
    401     gameSpeed.hidden = false;
    402     Engine.GetGUIObjectByName("gameSpeedText").hidden = true;
    403428    gameSpeed.list = g_GameSpeeds.Title;
    404429    gameSpeed.list_data = g_GameSpeeds.Speed;
    405430    gameSpeed.onSelectionChange = function() {
    406431        if (this.selected != -1)
     432        {
     433            if (!g_IsController)
     434            {
     435                changeSetting("gameSpeed", this.list_data[this.selected]);
     436                return;
     437            }
    407438            g_GameAttributes.gameSpeed = g_GameSpeeds.Speed[this.selected];
    408 
     439        }
    409440        updateGameAttributes();
    410441    };
    411442    gameSpeed.selected = g_GameSpeeds.Default;
     
    419450    populationCaps.selected = g_PopulationCapacities.Default;
    420451    populationCaps.onSelectionChange = function() {
    421452        if (this.selected != -1)
     453        {
     454            if (!g_IsController)
     455            {
     456                changeSetting("populationCap", this.list_data[this.selected]);
     457                return;
     458            }
    422459            g_GameAttributes.settings.PopulationCap = g_PopulationCapacities.Population[this.selected];
     460        }
    423461
    424462        updateGameAttributes();
    425463    };
     
    433471    startingResourcesL.selected = g_StartingResources.Default;
    434472    startingResourcesL.onSelectionChange = function() {
    435473        if (this.selected != -1)
     474        {
     475            if (!g_IsController)
     476            {
     477                changeSetting("startingResources", this.list_data[this.selected]);
     478                return;
     479            }
    436480            g_GameAttributes.settings.StartingResources = g_StartingResources.Resources[this.selected];
     481        }
    437482
    438483        updateGameAttributes();
    439484    };
     
    447492    ceasefireL.selected = g_Ceasefire.Default;
    448493    ceasefireL.onSelectionChange = function() {
    449494        if (this.selected != -1)
     495        {
     496            if (!g_IsController)
     497            {
     498                changeSetting("ceasefire", this.list_data[this.selected]);
     499                return;
     500            }
    450501            g_GameAttributes.settings.Ceasefire = g_Ceasefire.Duration[this.selected];
     502        }
    451503
    452504        updateGameAttributes();
    453505    };
    454506}
    455507
     508function initGuestSettings()
     509{
     510    let guestSettings = Engine.GetGUIObjectByName("guestSettings");
     511    guestSettings.list = g_GuestSettings.Title;
     512    guestSettings.list_data = g_GuestSettings.Data;
     513    guestSettings.onSelectionChange = function() {
     514        if (this.selected != -1)
     515        {
     516            if (!g_IsController)
     517            {
     518                changeSetting("guestSettings", this.list_data[this.selected]);
     519                return;
     520            }
     521            g_GameAttributes.GuestSettings = g_GuestSettings.Data[this.selected];
     522        }
     523
     524        updateGameAttributes();
     525    };
     526    if (guestSettings.selected == -1)
     527        guestSettings.selected = g_GuestSettings.Default;
     528}
     529
    456530function initVictoryConditions()
    457531{
    458532    let victoryConditions = Engine.GetGUIObjectByName("victoryCondition");
     
    461535    victoryConditions.onSelectionChange = function() {
    462536        if (this.selected != -1)
    463537        {
     538            if (!g_IsController)
     539            {
     540                changeSetting("victoryCondition", this.list_data[this.selected]);
     541                return;
     542            }
    464543            g_GameAttributes.settings.GameType = g_VictoryConditions.Name[this.selected];
    465544            g_GameAttributes.settings.VictoryScripts = g_VictoryConditions.Scripts[this.selected];
    466545        }
     
    478557    wonderConditions.onSelectionChange = function()
    479558    {
    480559        if (this.selected != -1)
     560        {
     561            if (!g_IsController)
     562            {
     563                changeSetting("wonderDuration", this.list_data[this.selected]);
     564                return;
     565            }
    481566            g_GameAttributes.settings.WonderDuration = g_WonderDurations.Duration[this.selected];
     567        }
    482568
    483569        updateGameAttributes();
    484570    };
     
    492578    mapSize.list_data = g_MapSizes.Tiles;
    493579    mapSize.onSelectionChange = function() {
    494580        if (this.selected != -1)
     581        {
     582            if (!g_IsController)
     583            {
     584                changeSetting("mapSice", this.list_data[this.selected]);
     585                return;
     586            }
    495587            g_GameAttributes.settings.Size = g_MapSizes.Tiles[this.selected];
     588        }
    496589        updateGameAttributes();
    497590    };
    498591    mapSize.selected = 0;
     
    513606
    514607    Object.keys(options).forEach(attribute => {
    515608        Engine.GetGUIObjectByName(options[attribute]).onPress = function() {
     609            if (!g_IsController)
     610            {
     611                changeSetting(attribute, this.checked);
     612                return;
     613            }
    516614            g_GameAttributes.settings[attribute] = this.checked;
    517615            updateGameAttributes();
    518616        };
     
    519617    });
    520618
    521619    Engine.GetGUIObjectByName("enableRating").onPress = function() {
     620        if (!g_IsController)
     621        {
     622            changeSetting("enableRating", this.checked);
     623            return;
     624        }
    522625        g_GameAttributes.settings.RatingEnabled = this.checked;
    523626        Engine.SetRankedGame(this.checked);
    524627        Engine.GetGUIObjectByName("enableCheats").enabled = !this.checked;
     
    533636function hideControls()
    534637{
    535638    for (let ctrl of ["mapType", "mapFilter", "mapSelection", "victoryCondition", "gameSpeed", "numPlayers"])
    536         hideControl(ctrl, ctrl + "Text");
     639        hideControl(ctrl, ctrl + "Text", canPlayerChange(ctrl));
    537640
    538     // TODO: Shouldn't players be able to choose their own assignment?
    539641    for (let i = 0; i < g_MaxPlayers; ++i)
    540642    {
    541         Engine.GetGUIObjectByName("playerAssignment["+i+"]").hidden = true;
    542         Engine.GetGUIObjectByName("playerCiv["+i+"]").hidden = true;
    543         Engine.GetGUIObjectByName("playerTeam["+i+"]").hidden = true;
     643        Engine.GetGUIObjectByName("playerAssignment["+i+"]").hidden = !canPlayerChange("playerAssignment", i);
     644        Engine.GetGUIObjectByName("playerCiv["+i+"]").hidden = !canPlayerChange("playerCiv", i);
     645        Engine.GetGUIObjectByName("playerTeam["+i+"]").hidden = !canPlayerChange("playerTeam", i);
    544646    }
    545647
    546648    Engine.GetGUIObjectByName("startGame").enabled = true;
     
    573675}
    574676
    575677/**
     678 * Returns if the player is allowed to change this setting
     679 */
     680function canPlayerChange(setting, index = -1)
     681{
     682    if (g_GameAttributes.mapType == "scenario" &&
     683         ["victoryCondition", "wonderDuration", "populationCap",
     684         "startingResources", "ceasefire", "revealMap", "exploreMap",
     685         "disableTreasures", "lockTeams", "playerCiv", "playerTeam", "playerColor"].indexOf(setting) >= 0)
     686        return false;
     687
     688    if (g_GameAttributes.mapType != "random" && setting == "numPlayers")
     689        return false;
     690
     691    if (g_IsController)
     692        return true;
     693 
     694     if (setting == "guestSettings")
     695        return false;
     696
     697    if (g_GuestSettings.Data.indexOf(setting) == -1)
     698        return g_GameAttributes.GuestSettings == "all";
     699
     700    if (index >= 0 && g_PlayerAssignments[Engine.GetPlayerGUID()] !== undefined && index != g_PlayerAssignments[Engine.GetPlayerGUID()].player-1)
     701        return g_GameAttributes.GuestSettings == "all";
     702
     703    return g_GuestSettings.Data.indexOf(g_GameAttributes.GuestSettings) >= g_GuestSettings.Data.indexOf(setting);
     704}
     705/**
     706 * helper function for Engine.NetworkChangeSetting
     707 */
     708function changeSetting(setting, value)
     709{
     710    Engine.NetworkChangeSetting({"setting": setting, "value": value});
     711}
     712
     713/**
    576714 * Hide and set some elements depending on whether we play single- or multiplayer.
    577715 */
    578716function initMultiplayerSettings()
     
    579717{
    580718    Engine.GetGUIObjectByName("chatPanel").hidden = !g_IsNetworked;
    581719    Engine.GetGUIObjectByName("optionCheats").hidden = !g_IsNetworked;
     720    Engine.GetGUIObjectByName("optionGuestSettings").hidden = !g_IsNetworked;
    582721    Engine.GetGUIObjectByName("optionRating").hidden = !Engine.HasXmppClient();
    583722
    584723    Engine.GetGUIObjectByName("enableCheats").enabled = !Engine.IsRankedGame();
     
    615754        let playerSlot = i; // declare for inner function use
    616755        team.onSelectionChange = function() {
    617756            if (this.selected != -1)
    618                 g_GameAttributes.settings.PlayerData[playerSlot].Team = this.selected - 1;
     757            {
     758                if (!g_IsController)
     759                {
     760                    changeSetting("playerTeam["+i+"]", this.list_data[this.selected]);
     761                    return;
     762                }
     763            g_GameAttributes.settings.PlayerData[playerSlot].Team = this.selected - 1;
     764            }
    619765
    620766            updateGameAttributes();
    621767        };
     
    624770        colorPicker.list = g_PlayerColors.map(color => ' ' + '[color="' + rgbToGuiColor(color) + '"]■[/color]');
    625771        colorPicker.list_data = g_PlayerColors.map((color, index) => index);
    626772        colorPicker.selected = -1;
    627         colorPicker.onSelectionChange = function() { selectPlayerColor(playerSlot, this.selected); };
     773        colorPicker.onSelectionChange = function() {
     774            if (!g_IsController)
     775            {
     776                changeSetting("playerColorPicker["+i+"]", this.list_data[this.selected]);
     777                return;
     778            }
     779            selectPlayerColor(playerSlot, this.selected);
     780        };
    628781
    629782        Engine.GetGUIObjectByName("playerCiv["+i+"]").onSelectionChange = function() {
    630783            if ((this.selected != -1)&&(g_GameAttributes.mapType !== "scenario"))
     784            {
     785                if (!g_IsController)
     786                {
     787                    changeSetting("playerCiv["+i+"]", this.list_data[this.selected]);
     788                    return;
     789                }
    631790                g_GameAttributes.settings.PlayerData[playerSlot].Civ = this.list_data[this.selected];
     791            }
    632792
    633793            updateGameAttributes();
    634794        };
     
    695855}
    696856
    697857/**
    698  * Called whenever the host changed any setting.
     858 * Called whenever the host sent new game attributes.
    699859 * @param {Object} message
    700860 */
    701861function handleGamesetupMessage(message)
     
    717877}
    718878
    719879/**
     880 * Called whenever a client changes a setting.
     881 * @param {Object} message
     882 */
     883function handleChangeSettingMessage(message)
     884{
     885    if (!message.guid || !message.data || !message.data.setting || message.data.value === undefined)
     886        return;
     887
     888    warn("The player with guid " + message.guid + " has changed the setting " +
     889         message.data.setting + " to the value " + message.data.value + ". Type is " + typeof message.data.value);
     890    updateGUIObjects();
     891 }
     892
     893/**
    720894 * Called whenever a client joins/leaves or any gamesetting is changed.
    721895 * @param {Object} message
    722896 */
     
    8691043    mapSelectionBox.list_data = mapListFiles;
    8701044    mapSelectionBox.onSelectionChange = function() {
    8711045        if (this.selected != -1)
     1046        {
     1047            if (!g_IsController)
     1048            {
     1049                changeSetting("mapSelection", this.list_data[this.selected]);
     1050                return;
     1051            }
    8721052            selectMap(this.list_data[this.selected]);
     1053        }
    8731054    };
    8741055    mapSelectionBox.selected = Math.max(0, mapListFiles.indexOf(g_GameAttributes.map || ""));
    8751056}
     
    10461227function selectNumPlayers(num)
    10471228{
    10481229    // Avoid recursion
    1049     if (g_IsInGuiUpdate || !g_IsController || g_GameAttributes.mapType != "random")
     1230    if (g_IsInGuiUpdate || !canPlayerChange("numPlayers") || g_GameAttributes.mapType != "random")
    10501231        return;
    10511232
    10521233    // Unassign players from nonexistent slots
     
    11101291function selectMapType(type)
    11111292{
    11121293    // Avoid recursion
    1113     if (g_IsInGuiUpdate || !g_IsController)
     1294    if (g_IsInGuiUpdate)
    11141295        return;
    11151296
    11161297    if (!g_MapPath[type])
     
    11401321function selectMapFilter(id)
    11411322{
    11421323    // Avoid recursion
    1143     if (g_IsInGuiUpdate || !g_IsController)
     1324    if (g_IsInGuiUpdate)
    11441325        return;
    11451326
    11461327    g_GameAttributes.mapFilter = id;
     
    11531334function selectMap(name)
    11541335{
    11551336    // Avoid recursion
    1156     if (g_IsInGuiUpdate || !g_IsController || !name)
     1337    if (g_IsInGuiUpdate || !name)
    11571338        return;
    11581339
    11591340    // Reset some map specific properties which are not necessarily redefined on each map
     
    12851466
    12861467    if (g_IsNetworked)
    12871468    {
    1288         Engine.SetNetworkGameAttributes(g_GameAttributes);
     1469        Engine.NetworkSetGameAttributes(g_GameAttributes);
    12891470        Engine.StartNetworkGame();
    12901471    }
    12911472    else
     
    13241505    let mapFilterIdx = g_MapFilters.findIndex(mapFilter => mapFilter.id == (g_GameAttributes.mapFilter || "default"));
    13251506    let mapTypeIdx = g_GameAttributes.mapType !== undefined ? g_MapTypes.Name.indexOf(g_GameAttributes.mapType) : g_MapTypes.Default;
    13261507    let gameSpeedIdx = g_GameAttributes.gameSpeed !== undefined ? g_GameSpeeds.Speed.indexOf(g_GameAttributes.gameSpeed) : g_GameSpeeds.Default;
     1508    let guestSettingsIdx = g_GameAttributes.GuestSettings !== undefined ? g_GuestSettings.Data.indexOf(g_GameAttributes.GuestSettings) : g_GuestSettings.Default;
    13271509
    13281510    // These dropdowns might set the default (as they ignore g_IsInGuiUpdate)
    13291511    let mapSizeIdx = mapSettings.Size !== undefined ? g_MapSizes.Tiles.indexOf(mapSettings.Size) : g_MapSizes.Default;
     
    13341516    let ceasefireIdx = mapSettings.Ceasefire !== undefined ? g_Ceasefire.Duration.indexOf(mapSettings.Ceasefire) : g_Ceasefire.Default;
    13351517    let numPlayers = mapSettings.PlayerData ? mapSettings.PlayerData.length : g_MaxPlayers;
    13361518
    1337     if (g_IsController)
    1338     {
    1339         Engine.GetGUIObjectByName("mapType").selected = mapTypeIdx;
    1340         Engine.GetGUIObjectByName("mapFilter").selected = mapFilterIdx;
    1341         Engine.GetGUIObjectByName("mapSelection").selected = Engine.GetGUIObjectByName("mapSelection").list_data.indexOf(mapName);
    1342         Engine.GetGUIObjectByName("mapSize").selected = mapSizeIdx;
    1343         Engine.GetGUIObjectByName("numPlayers").selected = numPlayers - 1;
    1344         Engine.GetGUIObjectByName("victoryCondition").selected = victoryIdx;
    1345         Engine.GetGUIObjectByName("wonderDuration").selected = wonderDurationIdx;
    1346         Engine.GetGUIObjectByName("populationCap").selected = popIdx;
    1347         Engine.GetGUIObjectByName("gameSpeed").selected = gameSpeedIdx;
    1348         Engine.GetGUIObjectByName("ceasefire").selected = ceasefireIdx;
    1349         Engine.GetGUIObjectByName("startingResources").selected = startingResIdx;
    1350     }
    1351     else
    1352     {
    1353         Engine.GetGUIObjectByName("mapTypeText").caption = g_MapTypes.Title[mapTypeIdx];
    1354         Engine.GetGUIObjectByName("mapFilterText").caption = g_MapFilters[mapFilterIdx].name;
    1355         Engine.GetGUIObjectByName("mapSelectionText").caption = mapName == "random" ? g_RandomMap : translate(getMapDisplayName(mapName));
    1356         initMapNameList();
    1357     }
     1519    Engine.GetGUIObjectByName("mapType").selected = mapTypeIdx;
     1520    Engine.GetGUIObjectByName("mapFilter").selected = mapFilterIdx;
     1521    Engine.GetGUIObjectByName("mapSelection").selected = Engine.GetGUIObjectByName("mapSelection").list_data.indexOf(mapName);
     1522    Engine.GetGUIObjectByName("mapSize").selected = mapSizeIdx;
     1523    Engine.GetGUIObjectByName("numPlayers").selected = numPlayers - 1;
     1524    Engine.GetGUIObjectByName("victoryCondition").selected = victoryIdx;
     1525    Engine.GetGUIObjectByName("wonderDuration").selected = wonderDurationIdx;
     1526    Engine.GetGUIObjectByName("populationCap").selected = popIdx;
     1527    Engine.GetGUIObjectByName("gameSpeed").selected = gameSpeedIdx;
     1528    Engine.GetGUIObjectByName("ceasefire").selected = ceasefireIdx;
     1529    Engine.GetGUIObjectByName("startingResources").selected = startingResIdx;
     1530    Engine.GetGUIObjectByName("guestSettings").selected = guestSettingsIdx;
    13581531
     1532
     1533    initMapNameList();
     1534
    13591535    // Can be visible to both host and clients
    13601536    Engine.GetGUIObjectByName("mapSizeText").caption = g_GameAttributes.mapType == "random" ? g_MapSizes.LongName[mapSizeIdx] : translate("Default");
    13611537    Engine.GetGUIObjectByName("numPlayersText").caption = numPlayers;
    13621538    Engine.GetGUIObjectByName("victoryConditionText").caption = g_VictoryConditions.Title[victoryIdx];
    13631539    Engine.GetGUIObjectByName("wonderDurationText").caption = g_WonderDurations.Title[wonderDurationIdx];
     1540    Engine.GetGUIObjectByName("guestSettingsText").caption = g_GuestSettings.Title[guestSettingsIdx];
    13641541    Engine.GetGUIObjectByName("populationCapText").caption = g_PopulationCapacities.Title[popIdx];
    13651542    Engine.GetGUIObjectByName("startingResourcesText").caption = g_StartingResources.Title[startingResIdx];
    13661543    Engine.GetGUIObjectByName("ceasefireText").caption = g_Ceasefire.Title[ceasefireIdx];
    13671544    Engine.GetGUIObjectByName("gameSpeedText").caption = g_GameSpeeds.Title[gameSpeedIdx];
     1545    Engine.GetGUIObjectByName("mapTypeText").caption = g_MapTypes.Title[mapTypeIdx];
     1546    Engine.GetGUIObjectByName("mapFilterText").caption = g_MapFilters[mapFilterIdx].name;
     1547    Engine.GetGUIObjectByName("mapSelectionText").caption = mapName == "random" ? g_RandomMap : translate(getMapDisplayName(mapName));
    13681548
    13691549    setGUIBoolean("enableCheats", "enableCheatsText", !!mapSettings.CheatsEnabled);
    13701550    setGUIBoolean("disableTreasures", "disableTreasuresText", !!mapSettings.DisableTreasures);
     
    13871567    Engine.GetGUIObjectByName("mapSizeDesc").hidden = !isRandom;
    13881568    Engine.GetGUIObjectByName("mapSize").hidden = !isRandom || !g_IsController;
    13891569    Engine.GetGUIObjectByName("mapSizeText").hidden = !isRandom || g_IsController;
    1390     hideControl("numPlayers", "numPlayersText", isRandom && g_IsController);
    13911570
    1392     let notScenario = g_GameAttributes.mapType != "scenario" && g_IsController ;
    1393 
    13941571    for (let ctrl of ["victoryCondition", "wonderDuration", "populationCap",
    13951572                      "startingResources", "ceasefire", "revealMap",
    1396                       "exploreMap", "disableTreasures", "lockTeams"])
    1397         hideControl(ctrl, ctrl + "Text", notScenario);
     1573                      "exploreMap", "disableTreasures", "lockTeams",
     1574                      "gameSpeed", "guestSettings", "enableCheats",
     1575                      "mapSelection", "numPlayers", "mapType", "mapFilter"])
     1576        hideControl(ctrl, ctrl + "Text", canPlayerChange(ctrl));
    13981577
     1578    let notScenario = g_GameAttributes.mapType != "scenario" && g_IsController ;
    13991579    Engine.GetGUIObjectByName("civResetButton").hidden = !notScenario;
    14001580
    14011581    for (let i = 0; i < g_MaxPlayers; ++i)
     
    14311611        pCiv.selected = civ ? pCiv.list_data.indexOf(civ) : 0;
    14321612        pTeam.selected = team !== undefined && team >= 0 ? team+1 : 0;
    14331613
    1434         hideControl("playerAssignment["+i+"]", "playerAssignmentText["+i+"]", g_IsController);
    1435         hideControl("playerCiv["+i+"]", "playerCivText["+i+"]", notScenario);
    1436         hideControl("playerTeam["+i+"]", "playerTeamText["+i+"]", notScenario);
     1614        hideControl("playerAssignment["+i+"]", "playerAssignmentText["+i+"]", canPlayerChange("playerAssignment", i));
     1615        hideControl("playerCiv["+i+"]", "playerCivText["+i+"]", canPlayerChange("playerCiv", i));
     1616        hideControl("playerTeam["+i+"]", "playerTeamText["+i+"]", canPlayerChange("playerTeam", i));
    14371617
    14381618        // Allow host to chose player colors on non-scenario maps
    14391619        let pColorPicker = Engine.GetGUIObjectByName("playerColorPicker["+i+"]");
    14401620        let pColorPickerHeading = Engine.GetGUIObjectByName("playerColorHeading");
    1441         let canChangeColors = g_IsController && g_GameAttributes.mapType != "scenario";
    1442         pColorPicker.hidden = !canChangeColors;
    1443         pColorPickerHeading.hidden = !canChangeColors;
    1444         if (canChangeColors)
     1621        pColorPicker.hidden = !canPlayerChange("playerColor", i);
     1622        pColorPickerHeading.hidden = !canPlayerChange("playerColor", i);
     1623        if (canPlayerChange("playerColor", i))
    14451624            pColorPicker.selected = g_PlayerColors.findIndex(col => sameColor(col, color));
    14461625    }
    14471626
     
    15321711
    15331712    if (g_IsNetworked)
    15341713    {
    1535         Engine.SetNetworkGameAttributes(g_GameAttributes);
     1714        Engine.NetworkSetGameAttributes(g_GameAttributes);
    15361715        if (g_LoadingState >= 2)
    15371716            sendRegisterGameStanza();
    15381717    }
     
    15461725
    15471726    Engine.PushGuiPage("page_aiconfig.xml", {
    15481727        "callback": "AIConfigCallback",
    1549         "isController": g_IsController,
     1728        "canBeChanged": canPlayerChange("playerConfig"),
    15501729        "playerSlot": playerSlot,
    15511730        "id": g_GameAttributes.settings.PlayerData[playerSlot].AI,
    15521731        "difficulty": g_GameAttributes.settings.PlayerData[playerSlot].AIDiff
     
    15601739{
    15611740    g_LastViewedAIPlayer = -1;
    15621741
    1563     if (!ai.save || !g_IsController)
     1742    if (!ai.save)
    15641743        return;
    15651744
    15661745    g_GameAttributes.settings.PlayerData[ai.playerSlot].AI = ai.id;
    15671746    g_GameAttributes.settings.PlayerData[ai.playerSlot].AIDiff = ai.difficulty;
    15681747
     1748    if (!g_IsController)
     1749    {
     1750        changeSetting("playerConfig["+i+"]", JSON.stringify(ai));
     1751        return;
     1752    }
    15691753    if (g_IsNetworked)
    1570         Engine.SetNetworkGameAttributes(g_GameAttributes);
     1754        Engine.NetworkSetGameAttributes(g_GameAttributes);
    15711755    else
    15721756        updatePlayerList();
    15731757}
     
    16631847        {
    16641848            g_GameAttributes.settings.PlayerData[playerSlot].AI = "";
    16651849            if (g_IsNetworked)
    1666                 Engine.SetNetworkGameAttributes(g_GameAttributes);
     1850                Engine.NetworkSetGameAttributes(g_GameAttributes);
    16671851        }
    16681852
    16691853        let assignBox = Engine.GetGUIObjectByName("playerAssignment["+i+"]");
     
    16741858            assignBox.selected = selection;
    16751859        assignBoxText.caption = hostNameList[selection];
    16761860
    1677         if (g_IsController)
    1678             assignBox.onselectionchange = function() {
    1679                 if (g_IsInGuiUpdate)
    1680                     return;
     1861        assignBox.onSelectionChange = function() {
     1862            if (g_IsInGuiUpdate)
     1863                return;
     1864            if (!g_IsController)
     1865            {
     1866                changeSetting("playerAssignment["+i+"]", this.list_data[this.selected]);
     1867                return;
     1868            }
    16811869
    1682                 let guid = hostGuidList[this.selected];
    1683                 if (!guid)
    1684                 {
    1685                     if (g_IsNetworked)
    1686                         // Unassign any host from this player slot
    1687                         Engine.AssignNetworkPlayer(playerID, "");
    1688                     // Remove AI from this player slot
    1689                     g_GameAttributes.settings.PlayerData[playerSlot].AI = "";
    1690                 }
    1691                 else if (guid.substr(0, 3) == "ai:")
    1692                 {
    1693                     if (g_IsNetworked)
    1694                         // Unassign any host from this player slot
    1695                         Engine.AssignNetworkPlayer(playerID, "");
    1696                     // Set the AI for this player slot
    1697                     g_GameAttributes.settings.PlayerData[playerSlot].AI = guid.substr(3);
    1698                 }
    1699                 else
    1700                     swapPlayers(guid, playerSlot);
     1870            let guid = hostGuidList[this.selected];
     1871            if (!guid)
     1872            {
     1873                if (g_IsNetworked)
     1874                    // Unassign any host from this player slot
     1875                    Engine.AssignNetworkPlayer(playerID, "");
     1876                // Remove AI from this player slot
     1877                g_GameAttributes.settings.PlayerData[playerSlot].AI = "";
     1878            }
     1879            else if (guid.substr(0, 3) == "ai:")
     1880            {
     1881                if (g_IsNetworked)
     1882                    // Unassign any host from this player slot
     1883                    Engine.AssignNetworkPlayer(playerID, "");
     1884                // Set the AI for this player slot
     1885                g_GameAttributes.settings.PlayerData[playerSlot].AI = guid.substr(3);
     1886            }
     1887            else
     1888                swapPlayers(guid, playerSlot);
    17011889
    1702                 if (g_IsNetworked)
    1703                     Engine.SetNetworkGameAttributes(g_GameAttributes);
    1704                 else
    1705                     updatePlayerList();
    1706                 updateReadyUI();
    1707             };
     1890            if (g_IsNetworked)
     1891                Engine.NetworkSetGameAttributes(g_GameAttributes);
     1892            else
     1893                updatePlayerList();
     1894            updateReadyUI();
     1895        };
    17081896    }
    17091897
    17101898    g_IsInGuiUpdate = false;
  • binaries/data/mods/public/gui/gamesetup/gamesetup.xml

     
    9090                            <object name="playerAssignment[n]" type="dropdown" style="ModernDropDown" size="22%+37 2 50%+35 30" tooltip_style="onscreenToolTip">
    9191                                <translatableAttribute id="tooltip">Select player.</translatableAttribute>
    9292                            </object>
    93                             <object name="playerAssignmentText[n]" type="text" style="ModernLabelText" size="22%+5 0 50%+35 30"/>
     93                            <object name="playerAssignmentText[n]" type="text" style="ModernLabelText" size="22%+33 0 50%+35 30"/>
    9494                            <object name="playerConfig[n]" type="button" style="StoneButton" size="50%+40 4 50%+64 28"
    9595                                tooltip_style="onscreenToolTip"
    9696                                font="sans-bold-stroke-12"
     
    346346                    </object>
    347347                </object>
    348348
     349                <object name="optionGuestSettings" size="14 188 94% 206">
     350                    <object size="0 0 40% 28" type="text" style="ModernRightLabelText">
     351                        <translatableAttribute id="caption">Guest Settings:</translatableAttribute>
     352                    </object>
     353                    <object name="guestSettingsText" size="40% 0 100% 100%" type="text" style="ModernLeftLabelText"/>
     354                    <object name="guestSettings" size="40%+10 0 100% 28" type="dropdown" style="ModernDropDown" hidden="true" tooltip_style="onscreenToolTip">
     355                        <translatableAttribute id="tooltip">Set which settings can be changed by every player.</translatableAttribute>
     356                    </object>
     357                </object>
     358
    349359                <object name="optionRevealMap" size="14 218 94% 246">
    350360                    <object size="0 0 40% 28" type="text" style="ModernRightLabelText">
    351361                        <translatableAttribute id="caption" comment="Make sure to differentiate between the revealed map and explored map options!">Revealed Map:</translatableAttribute>
  • binaries/data/mods/public/simulation/data/settings/guest_settings.json

     
     1{
     2    "TranslatedKeys": ["Title"],
     3    "TranslationContext": "players can change",
     4    "Data":
     5    [
     6        {
     7            "Title": "None",
     8            "Data": "none"
     9        },
     10        {
     11            "Title": "Color",
     12            "Data": "playerColor",
     13            "Default": true
     14        },
     15        {
     16            "Title": "Color & Civilization",
     17            "Data": "playerCiv"
     18        },
     19        {
     20            "Title": "Color, Civilization & Team",
     21            "Data": "playerTeam"
     22        },
     23        {
     24            "Title": "All",
     25            "Data": "all"
     26        }
     27    ]
     28}
  • source/gui/scripting/ScriptFunctions.cpp

     
    330330        LOGERROR("Failed to save game");
    331331}
    332332
    333 void SetNetworkGameAttributes(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue attribs1)
     333void NetworkChangeSetting(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue keyValuePair1)
    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);
     340    JS::RootedValue keyValuePair(cx, keyValuePair1);
     341
     342    g_NetClient->SendChangeSettingMessage(&keyValuePair, *(pCxPrivate->pScriptInterface));
     343}
     344
     345void NetworkSetGameAttributes(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue attribs1)
     346{
     347    ENSURE(g_NetClient);
     348    //TODO: This is a workaround because we need to pass a MutableHandle to a JSAPI functions somewhere
     349    // (with no obvious reason).
     350    JSContext* cx = pCxPrivate->pScriptInterface->GetContext();
     351    JSAutoRequest rq(cx);
    340352    JS::RootedValue attribs(cx, attribs1);
    341353
    342     g_NetServer->UpdateGameAttributes(&attribs, *(pCxPrivate->pScriptInterface));
     354    g_NetClient->SendGameSetupMessage(&attribs, *(pCxPrivate->pScriptInterface));
    343355}
    344356
    345357void StartNetworkHost(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& playerName)
     
    425437
    426438void AssignNetworkPlayer(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int playerID, const std::string& guid)
    427439{
    428     ENSURE(g_NetServer);
     440    ENSURE(g_NetClient);
    429441
    430     g_NetServer->AssignPlayer(playerID, guid);
     442    g_NetClient->SendAssignPlayerMessage(playerID, guid);
    431443}
    432444
    433445void SetNetworkPlayerStatus(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& guid, int ready)
     
    10421054    scriptInterface.RegisterFunction<std::string, &GetPlayerGUID>("GetPlayerGUID");
    10431055    scriptInterface.RegisterFunction<bool, CStrW, bool, &KickPlayer>("KickPlayer");
    10441056    scriptInterface.RegisterFunction<JS::Value, &PollNetworkClient>("PollNetworkClient");
    1045     scriptInterface.RegisterFunction<void, JS::HandleValue, &SetNetworkGameAttributes>("SetNetworkGameAttributes");
     1057    scriptInterface.RegisterFunction<void, JS::HandleValue, &NetworkChangeSetting>("NetworkChangeSetting");
     1058    scriptInterface.RegisterFunction<void, JS::HandleValue, &NetworkSetGameAttributes>("NetworkSetGameAttributes");
    10461059    scriptInterface.RegisterFunction<void, int, std::string, &AssignNetworkPlayer>("AssignNetworkPlayer");
    10471060    scriptInterface.RegisterFunction<void, std::string, int, &SetNetworkPlayerStatus>("SetNetworkPlayerStatus");
    10481061    scriptInterface.RegisterFunction<void, &ClearAllPlayerReady>("ClearAllPlayerReady");
  • source/network/NetClient.cpp

     
    9696    AddTransition(NCS_PREGAME, (uint)NMT_READY, NCS_PREGAME, (void*)&OnReady, context);
    9797    AddTransition(NCS_PREGAME, (uint)NMT_GAME_SETUP, NCS_PREGAME, (void*)&OnGameSetup, context);
    9898    AddTransition(NCS_PREGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_PREGAME, (void*)&OnPlayerAssignment, context);
     99    AddTransition(NCS_PREGAME, (uint)NMT_CHANGE_SETTING, NCS_PREGAME, (void*)&OnChangeSetting, context);
    99100    AddTransition(NCS_PREGAME, (uint)NMT_KICKED, NCS_PREGAME, (void*)&OnKicked, context);
    100101    AddTransition(NCS_PREGAME, (uint)NMT_CLIENT_TIMEOUT, NCS_PREGAME, (void*)&OnClientTimeout, context);
    101102    AddTransition(NCS_PREGAME, (uint)NMT_CLIENT_PERFORMANCE, NCS_PREGAME, (void*)&OnClientPerformance, context);
     
    323324    SetCurrState(NCS_UNCONNECTED);
    324325}
    325326
     327void CNetClient::SendChangeSettingMessage(JS::MutableHandleValue keyValuePair, ScriptInterface& scriptInterface)
     328{
     329    JSContext* cx = scriptInterface.GetContext();
     330    JS::RootedValue keyValuePairRooted(cx);
     331    keyValuePairRooted = keyValuePair;
     332
     333    CChangeSettingMessage changeSetting(GetScriptInterface());
     334    changeSetting.m_Data.set(keyValuePairRooted);
     335    SendMessage(&changeSetting);
     336}
     337
     338void CNetClient::SendGameSetupMessage(JS::MutableHandleValue attrs, ScriptInterface& scriptInterface)
     339{
     340    JSContext* cx = scriptInterface.GetContext();
     341    JS::RootedValue attrsRooted(cx);
     342    attrsRooted = attrs;
     343
     344    CGameSetupMessage gameSetup(scriptInterface);
     345    gameSetup.m_Data = attrsRooted;
     346    SendMessage(&gameSetup);
     347}
     348
     349void CNetClient::SendAssignPlayerMessage(const int playerID, const std::string& guid)
     350{
     351    CAssignPlayerMessage assignPlayer;
     352    assignPlayer.m_PlayerID = playerID;
     353    assignPlayer.m_GUIDToAssign = guid;
     354    SendMessage(&assignPlayer);
     355}
     356
    326357void CNetClient::SendChatMessage(const std::wstring& text)
    327358{
    328359    CChatMessage chat;
     
    592623    return true;
    593624}
    594625
     626bool CNetClient::OnChangeSetting(void* context, CFsmEvent* event)
     627{
     628    ENSURE(event->GetType() == (uint)NMT_CHANGE_SETTING);
     629
     630    CNetClient* client = (CNetClient*)context;
     631    JSContext* cx = client->GetScriptInterface().GetContext();
     632    JSAutoRequest rq(cx);
     633
     634    CChangeSettingMessage* message = (CChangeSettingMessage*)event->GetParamRef();
     635
     636    JS::RootedValue msg(cx);
     637    client->GetScriptInterface().Eval("({'type':'changesetting'})", &msg);
     638    client->GetScriptInterface().SetProperty(msg, "guid", std::string(message->m_GUID), false);
     639    client->GetScriptInterface().SetProperty(msg, "data", message->m_Data, false);
     640    client->PushGuiMessage(msg);
     641
     642    return true;
     643}
     644
    595645bool CNetClient::OnGameStart(void* context, CFsmEvent* event)
    596646{
    597647    ENSURE(event->GetType() == (uint)NMT_GAME_START);
  • source/network/NetClient.h

     
    187187     */
    188188    void LoadFinished();
    189189
     190    void SendChangeSettingMessage(JS::MutableHandleValue keyValuePair, ScriptInterface& scriptInterface);
     191
     192    void SendGameSetupMessage(JS::MutableHandleValue attrs, ScriptInterface& scriptInterface);
     193
     194    void SendAssignPlayerMessage(const int playerID, const std::string& guid);
     195
    190196    void SendChatMessage(const std::wstring& text);
    191197
    192198    void SendReadyMessage(const int status);
     
    212218    static bool OnReady(void* context, CFsmEvent* event);
    213219    static bool OnGameSetup(void* context, CFsmEvent* event);
    214220    static bool OnPlayerAssignment(void* context, CFsmEvent* event);
     221    static bool OnChangeSetting(void* context, CFsmEvent* event);
    215222    static bool OnInGame(void* context, CFsmEvent* event);
    216223    static bool OnGameStart(void* context, CFsmEvent* event);
    217224    static bool OnJoinSyncStart(void* context, CFsmEvent* event);
  • source/network/NetMessage.cpp

     
    103103
    104104    switch (header.GetType())
    105105    {
     106    case NMT_CHANGE_SETTING:
     107        pNewMessage = new CChangeSettingMessage(scriptInterface);
     108        break;
     109
    106110    case NMT_GAME_SETUP:
    107111        pNewMessage = new CGameSetupMessage(scriptInterface);
    108112        break;
     
    203207        pNewMessage = new CSimulationMessage(scriptInterface);
    204208        break;
    205209
     210    case NMT_ASSIGN_PLAYER:
     211        pNewMessage = new CAssignPlayerMessage;
     212        break;
     213
    206214    default:
    207215        LOGERROR("CNetMessageFactory::CreateMessage(): Unknown message type '%d' received", header.GetType());
    208216        break;
  • source/network/NetMessage.h

     
    1 /* Copyright (C) 2015 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
     
    154154    ScriptInterface& m_ScriptInterface;
    155155};
    156156
     157/**
     158* Special message type to send single setting changes.
     159*/
     160class CChangeSettingMessage : public CNetMessage
     161{
     162    NONCOPYABLE(CChangeSettingMessage);
     163public:
     164    CChangeSettingMessage(ScriptInterface& scriptInterface);
     165    CChangeSettingMessage(ScriptInterface& scriptInterface, CStr& guid, JS::HandleValue data);
     166    virtual u8* Serialize(u8* pBuffer) const;
     167    virtual const u8* Deserialize(const u8* pStart, const u8* pEnd);
     168    virtual size_t GetSerializedLength() const;
     169    virtual CStr ToString() const;
     170
     171    CStr m_GUID;
     172    JS::PersistentRootedValue m_Data;
     173private:
     174    ScriptInterface& m_ScriptInterface;
     175};
     176
    157177// This time, the classes are created
    158178#include "NetMessages.h"
    159179
  • 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_CHANGE_SETTING,
     55    NMT_ASSIGN_PLAYER,
    5456    NMT_PLAYER_ASSIGNMENT,
    5557
    5658    NMT_FILE_TRANSFER_REQUEST,
     
    218220    NMT_END_ARRAY()
    219221END_NMT_CLASS()
    220222
     223START_NMT_CLASS_(AssignPlayer, NMT_ASSIGN_PLAYER)
     224    NMT_FIELD_INT(m_PlayerID, i8, 1)
     225    NMT_FIELD(CStr, m_GUIDToAssign)
     226END_NMT_CLASS()
     227
    221228END_NMTS()
    222229
    223230#else
  • source/network/NetMessageSim.cpp

     
    1 /* Copyright (C) 2011 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
     
    229229    stream << "CGameSetupMessage { m_Data: " << source << " }";
    230230    return CStr(stream.str());
    231231}
     232
     233
     234CChangeSettingMessage::CChangeSettingMessage(ScriptInterface& scriptInterface) :
     235CNetMessage(NMT_CHANGE_SETTING), m_ScriptInterface(scriptInterface), m_Data(scriptInterface.GetJSRuntime())
     236{
     237}
     238
     239CChangeSettingMessage::CChangeSettingMessage(ScriptInterface& scriptInterface, CStr& guid, JS::HandleValue data) :
     240CNetMessage(NMT_CHANGE_SETTING), m_ScriptInterface(scriptInterface),
     241m_GUID(guid), m_Data(scriptInterface.GetJSRuntime(), data)
     242{
     243}
     244
     245u8* CChangeSettingMessage::Serialize(u8* pBuffer) const
     246{
     247    // TODO: ought to handle serialization exceptions
     248    u8* pos = CNetMessage::Serialize(pBuffer);
     249    CBufferBinarySerializer serializer(m_ScriptInterface, pos);
     250    serializer.StringASCII("guid", m_GUID, 0, UINT32_MAX);
     251    serializer.ScriptVal("command", const_cast<JS::PersistentRootedValue*>(&m_Data));
     252    return serializer.GetBuffer();
     253}
     254
     255const u8* CChangeSettingMessage::Deserialize(const u8* pStart, const u8* pEnd)
     256{
     257    // TODO: ought to handle serialization exceptions
     258    const u8* pos = CNetMessage::Deserialize(pStart, pEnd);
     259    std::istringstream stream(std::string(pos, pEnd));
     260    CStdDeserializer deserializer(m_ScriptInterface, stream);
     261    deserializer.StringASCII("guid", m_GUID, 0, UINT32_MAX);
     262    deserializer.ScriptVal("command", const_cast<JS::PersistentRootedValue*>(&m_Data));
     263    return pEnd;
     264}
     265
     266size_t CChangeSettingMessage::GetSerializedLength() const
     267{
     268    CLengthBinarySerializer serializer(m_ScriptInterface);
     269    serializer.StringASCII("guid", m_GUID, 0, UINT32_MAX);
     270    serializer.ScriptVal("command", const_cast<JS::PersistentRootedValue*>(&m_Data));
     271    return CNetMessage::GetSerializedLength() + serializer.GetLength();
     272}
     273
     274CStr CChangeSettingMessage::ToString() const
     275{
     276    std::string source = m_ScriptInterface.ToString(const_cast<JS::PersistentRootedValue*>(&m_Data));
     277
     278    std::stringstream stream;
     279    stream << "CChangeSettingMessage { m_GUID: " << m_GUID << ", m_Data: " << source << " }";
     280    return CStr(stream.str());
     281}
  • 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_CHANGE_SETTING, NSS_PREGAME, (void*)&OnChangeSetting, 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);
    652655    session->AddTransition(NSS_PREGAME, (uint)NMT_LOADED_GAME, NSS_INGAME, (void*)&OnLoadedGame, context);
    653656
    654657    session->AddTransition(NSS_JOIN_SYNCING, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, (void*)&OnDisconnect, context);
     
    11111114    return true;
    11121115}
    11131116
     1117bool CNetServerWorker::OnChangeSetting(void* context, CFsmEvent* event)
     1118{
     1119    ENSURE(event->GetType() == (uint)NMT_CHANGE_SETTING);
     1120
     1121    CNetServerSession* session = (CNetServerSession*)context;
     1122    CNetServerWorker& server = session->GetServer();
     1123
     1124    CChangeSettingMessage* message = (CChangeSettingMessage*)event->GetParamRef();
     1125    message->m_GUID = session->GetGUID();
     1126    // Forward message to host
     1127    for (CNetServerSession* session : server.m_Sessions)
     1128        if (session->GetGUID() == server.m_HostGUID)
     1129            return session->SendMessage(message);
     1130    LOGERROR("No host found to send the ChaneSettingMessage to.");
     1131}
     1132
     1133bool CNetServerWorker::OnGameSetup(void* context, CFsmEvent* event)
     1134{
     1135    ENSURE(event->GetType() == (uint)NMT_GAME_SETUP);
     1136
     1137    CNetServerSession* session = (CNetServerSession*)context;
     1138    CNetServerWorker& server = session->GetServer();
     1139
     1140    if (session->GetGUID() != server.m_HostGUID) // Client wasn't allowed to send new attributes
     1141        return true;
     1142
     1143    CGameSetupMessage* message = (CGameSetupMessage*)event->GetParamRef();
     1144
     1145    server.UpdateGameAttributes(&(message->m_Data));
     1146    return true;
     1147}
     1148
     1149bool CNetServerWorker::OnAssignPlayer(void* context, CFsmEvent* event)
     1150{
     1151    ENSURE(event->GetType() == (uint)NMT_ASSIGN_PLAYER);
     1152    CNetServerSession* session = (CNetServerSession*)context;
     1153    CNetServerWorker& server = session->GetServer();
     1154
     1155    if (session->GetGUID() != server.m_HostGUID) // Client wasn't allowed to assign a player
     1156        return true;
     1157
     1158    CAssignPlayerMessage* message = (CAssignPlayerMessage*)event->GetParamRef();
     1159    server.m_AssignPlayerQueue.emplace_back(message->m_PlayerID, message->m_GUIDToAssign);
     1160    return true;
     1161}
     1162
    11141163bool CNetServerWorker::OnLoadedGame(void* context, CFsmEvent* event)
    11151164{
    11161165    ENSURE(event->GetType() == (uint)NMT_LOADED_GAME);
  • 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 OnChangeSetting(void* context, CFsmEvent* event);
     274    static bool OnGameSetup(void* context, CFsmEvent* event);
     275    static bool OnAssignPlayer(void* context, CFsmEvent* event);
    273276    static bool OnLoadedGame(void* context, CFsmEvent* event);
    274277    static bool OnJoinSyncingLoadedGame(void* context, CFsmEvent* event);
    275278    static bool OnRejoined(void* context, CFsmEvent* event);