Port game speed selection to new lobby backend.

This commit is contained in:
Paul Chote
2016-07-02 10:51:55 +01:00
parent e858e13da7
commit 7caf636222
10 changed files with 52 additions and 118 deletions

View File

@@ -192,7 +192,6 @@ namespace OpenRA.Network
public int OrderLatency = 3; // net tick frames (x 120 = ms) public int OrderLatency = 3; // net tick frames (x 120 = ms)
public int RandomSeed = 0; public int RandomSeed = 0;
public bool AllowSpectators = true; public bool AllowSpectators = true;
public string GameSpeedType = "default";
public bool AllowVersionMismatch; public bool AllowVersionMismatch;
public string GameUid; public string GameUid;
public bool EnableSingleplayer; public bool EnableSingleplayer;

View File

@@ -403,8 +403,6 @@ namespace OpenRA.Server
if (handshake.Mod == "{DEV_VERSION}") if (handshake.Mod == "{DEV_VERSION}")
SendMessage("{0} is running an unversioned development build, ".F(client.Name) + SendMessage("{0} is running an unversioned development build, ".F(client.Name) +
"and may desynchronize the game state if they have incompatible rules."); "and may desynchronize the game state if they have incompatible rules.");
SetOrderLag();
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -414,24 +412,6 @@ namespace OpenRA.Server
} }
} }
void SetOrderLag()
{
int latency = 1;
if (!LobbyInfo.IsSinglePlayer)
{
var gameSpeeds = ModData.Manifest.Get<GameSpeeds>();
GameSpeed speed;
if (gameSpeeds.Speeds.TryGetValue(LobbyInfo.GlobalSettings.GameSpeedType, out speed))
latency = speed.OrderLatency;
else
latency = 3;
}
LobbyInfo.GlobalSettings.OrderLatency = latency;
SyncLobbyGlobalSettings();
}
void DispatchOrdersToClient(Connection c, int client, int frame, byte[] data) void DispatchOrdersToClient(Connection c, int client, int frame, byte[] data)
{ {
try try
@@ -620,8 +600,6 @@ namespace OpenRA.Server
toDrop.Socket.Disconnect(false); toDrop.Socket.Disconnect(false);
} }
catch { } catch { }
SetOrderLag();
} }
public void SyncLobbyInfo() public void SyncLobbyInfo()
@@ -702,6 +680,10 @@ namespace OpenRA.Server
DropClient(c); DropClient(c);
} }
// HACK: Turn down the latency if there is only one real player
if (LobbyInfo.IsSinglePlayer)
LobbyInfo.GlobalSettings.OrderLatency = 1;
SyncLobbyInfo(); SyncLobbyInfo();
State = ServerState.GameStarted; State = ServerState.GameStarted;

View File

@@ -356,7 +356,7 @@ namespace OpenRA.Mods.Common.Server
.Where(ss => ss != null) .Where(ss => ss != null)
.ToDictionary(ss => ss.PlayerReference, ss => ss); .ToDictionary(ss => ss.PlayerReference, ss => ss);
LoadMapSettings(server.LobbyInfo.GlobalSettings, server.Map.Rules); LoadMapSettings(server, server.LobbyInfo.GlobalSettings, server.Map.Rules);
// Reset client states // Reset client states
foreach (var c in server.LobbyInfo.Clients) foreach (var c in server.LobbyInfo.Clients)
@@ -463,6 +463,13 @@ namespace OpenRA.Mods.Common.Server
oo.Value = oo.PreferredValue = split[1]; oo.Value = oo.PreferredValue = split[1];
if (option.Id == "gamespeed")
{
var speed = server.ModData.Manifest.Get<GameSpeeds>().Speeds[oo.Value];
server.LobbyInfo.GlobalSettings.Timestep = speed.Timestep;
server.LobbyInfo.GlobalSettings.OrderLatency = speed.OrderLatency;
}
server.SyncLobbyGlobalSettings(); server.SyncLobbyGlobalSettings();
server.SendMessage(option.ValueChangedMessage(client.Name, split[1])); server.SendMessage(option.ValueChangedMessage(client.Name, split[1]));
@@ -510,38 +517,6 @@ namespace OpenRA.Mods.Common.Server
return true; return true;
} }
}, },
{ "gamespeed",
s =>
{
if (server.LobbyInfo.GlobalSettings.GameSpeedType == s)
return true;
if (!client.IsAdmin)
{
server.SendOrderTo(conn, "Message", "Only the host can set that option.");
return true;
}
var gameSpeeds = server.ModData.Manifest.Get<GameSpeeds>();
GameSpeed speed;
if (!gameSpeeds.Speeds.TryGetValue(s, out speed))
{
server.SendOrderTo(conn, "Message", "Invalid game speed selected.");
return true;
}
server.LobbyInfo.GlobalSettings.GameSpeedType = s;
server.LobbyInfo.GlobalSettings.Timestep = speed.Timestep;
server.LobbyInfo.GlobalSettings.OrderLatency =
server.LobbyInfo.IsSinglePlayer ? 1 : speed.OrderLatency;
server.SyncLobbyInfo();
server.SendMessage("{0} changed Game Speed to {1}.".F(client.Name, speed.Name));
return true;
}
},
{ "kick", { "kick",
s => s =>
{ {
@@ -786,7 +761,7 @@ namespace OpenRA.Mods.Common.Server
.Where(s => s != null) .Where(s => s != null)
.ToDictionary(s => s.PlayerReference, s => s); .ToDictionary(s => s.PlayerReference, s => s);
LoadMapSettings(server.LobbyInfo.GlobalSettings, server.Map.Rules); LoadMapSettings(server, server.LobbyInfo.GlobalSettings, server.Map.Rules);
} }
static Session.Slot MakeSlotFromPlayerReference(PlayerReference pr) static Session.Slot MakeSlotFromPlayerReference(PlayerReference pr)
@@ -805,7 +780,7 @@ namespace OpenRA.Mods.Common.Server
}; };
} }
public static void LoadMapSettings(Session.Global gs, Ruleset rules) public static void LoadMapSettings(S server, Session.Global gs, Ruleset rules)
{ {
var options = rules.Actors["player"].TraitInfos<ILobbyOptions>() var options = rules.Actors["player"].TraitInfos<ILobbyOptions>()
.Concat(rules.Actors["world"].TraitInfos<ILobbyOptions>()) .Concat(rules.Actors["world"].TraitInfos<ILobbyOptions>())
@@ -836,6 +811,13 @@ namespace OpenRA.Mods.Common.Server
state.Value = value; state.Value = value;
state.PreferredValue = preferredValue; state.PreferredValue = preferredValue;
gs.LobbyOptions[o.Id] = state; gs.LobbyOptions[o.Id] = state;
if (o.Id == "gamespeed")
{
var speed = server.ModData.Manifest.Get<GameSpeeds>().Speeds[value];
server.LobbyInfo.GlobalSettings.Timestep = speed.Timestep;
server.LobbyInfo.GlobalSettings.OrderLatency = speed.OrderLatency;
}
} }
} }

View File

@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Server
return; return;
var defaults = new Session.Global(); var defaults = new Session.Global();
LobbyCommands.LoadMapSettings(defaults, server.Map.Rules); LobbyCommands.LoadMapSettings(server, defaults, server.Map.Rules);
var options = server.Map.Rules.Actors["player"].TraitInfos<ILobbyOptions>() var options = server.Map.Rules.Actors["player"].TraitInfos<ILobbyOptions>()
.Concat(server.Map.Rules.Actors["world"].TraitInfos<ILobbyOptions>()) .Concat(server.Map.Rules.Actors["world"].TraitInfos<ILobbyOptions>())

View File

@@ -30,6 +30,12 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Prevent the tech level from being changed in the lobby.")] [Desc("Prevent the tech level from being changed in the lobby.")]
public readonly bool TechLevelLocked = false; public readonly bool TechLevelLocked = false;
[Desc("Default game speed.")]
public readonly string GameSpeed = "default";
[Desc("Prevent the game speed from being changed in the lobby.")]
public readonly bool GameSpeedLocked = false;
IEnumerable<LobbyOption> ILobbyOptions.LobbyOptions(Ruleset rules) IEnumerable<LobbyOption> ILobbyOptions.LobbyOptions(Ruleset rules)
{ {
yield return new LobbyBooleanOption("shortgame", "Short Game", ShortGameEnabled, ShortGameLocked); yield return new LobbyBooleanOption("shortgame", "Short Game", ShortGameEnabled, ShortGameLocked);
@@ -41,6 +47,14 @@ namespace OpenRA.Mods.Common.Traits
yield return new LobbyOption("techlevel", "Tech Level", yield return new LobbyOption("techlevel", "Tech Level",
new ReadOnlyDictionary<string, string>(techLevels), new ReadOnlyDictionary<string, string>(techLevels),
TechLevel, TechLevelLocked); TechLevel, TechLevelLocked);
var gameSpeeds = Game.ModData.Manifest.Get<GameSpeeds>().Speeds
.ToDictionary(s => s.Key, s => s.Value.Name);
// NOTE: The server hardcodes special-case logic for this option id
yield return new LobbyOption("gamespeed", "Game Speed",
new ReadOnlyDictionary<string, string>(gameSpeeds),
GameSpeed, GameSpeedLocked);
} }
public object Create(ActorInitializer init) { return new MapOptions(this); } public object Create(ActorInitializer init) { return new MapOptions(this); }
@@ -52,6 +66,7 @@ namespace OpenRA.Mods.Common.Traits
public bool ShortGame { get; private set; } public bool ShortGame { get; private set; }
public string TechLevel { get; private set; } public string TechLevel { get; private set; }
public GameSpeed GameSpeed { get; private set; }
public MapOptions(MapOptionsInfo info) public MapOptions(MapOptionsInfo info)
{ {
@@ -65,6 +80,11 @@ namespace OpenRA.Mods.Common.Traits
TechLevel = self.World.LobbyInfo.GlobalSettings TechLevel = self.World.LobbyInfo.GlobalSettings
.OptionOrDefault("techlevel", info.TechLevel); .OptionOrDefault("techlevel", info.TechLevel);
var speed = self.World.LobbyInfo.GlobalSettings
.OptionOrDefault("gamespeed", info.GameSpeed);
GameSpeed = Game.ModData.Manifest.Get<GameSpeeds>().Speeds[speed];
} }
} }
} }

View File

@@ -10,6 +10,7 @@
#endregion #endregion
using System; using System;
using OpenRA.Mods.Common.Traits;
using OpenRA.Network; using OpenRA.Network;
using OpenRA.Widgets; using OpenRA.Widgets;
@@ -43,12 +44,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
// Timers in replays should be synced to the effective game time, not the playback time. // Timers in replays should be synced to the effective game time, not the playback time.
var timestep = world.Timestep; var timestep = world.Timestep;
if (world.IsReplay) if (world.IsReplay)
{ timestep = world.WorldActor.Trait<MapOptions>().GameSpeed.Timestep;
GameSpeed speed;
var gameSpeeds = Game.ModData.Manifest.Get<GameSpeeds>();
if (gameSpeeds.Speeds.TryGetValue(world.LobbyInfo.GlobalSettings.GameSpeedType, out speed))
timestep = speed.Timestep;
}
timer.GetText = () => timer.GetText = () =>
{ {

View File

@@ -372,7 +372,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{ "TECHLEVEL", "techlevel" }, { "TECHLEVEL", "techlevel" },
{ "STARTINGUNITS", "startingunits" }, { "STARTINGUNITS", "startingunits" },
{ "STARTINGCASH", "startingcash" }, { "STARTINGCASH", "startingcash" },
{ "DIFFICULTY", "difficulty" } { "DIFFICULTY", "difficulty" },
{ "GAMESPEED", "gamespeed" }
}; };
var allOptions = new CachedTransform<MapPreview, LobbyOption[]>( var allOptions = new CachedTransform<MapPreview, LobbyOption[]>(
@@ -428,44 +429,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
} }
} }
var gameSpeed = optionsBin.GetOrNull<DropDownButtonWidget>("GAMESPEED_DROPDOWNBUTTON");
if (gameSpeed != null)
{
var speeds = modData.Manifest.Get<GameSpeeds>().Speeds;
gameSpeed.IsDisabled = configurationDisabled;
gameSpeed.GetText = () =>
{
if (Map.Status != MapStatus.Available)
return "Not Available";
GameSpeed speed;
if (!speeds.TryGetValue(orderManager.LobbyInfo.GlobalSettings.GameSpeedType, out speed))
return "Unknown";
return speed.Name;
};
gameSpeed.OnMouseDown = _ =>
{
var options = speeds.Select(s => new DropDownOption
{
Title = s.Value.Name,
IsSelected = () => orderManager.LobbyInfo.GlobalSettings.GameSpeedType == s.Key,
OnClick = () => orderManager.IssueOrder(Order.Command("gamespeed {0}".F(s.Key)))
});
Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
{
var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
return item;
};
gameSpeed.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
};
}
var disconnectButton = lobby.Get<ButtonWidget>("DISCONNECT_BUTTON"); var disconnectButton = lobby.Get<ButtonWidget>("DISCONNECT_BUTTON");
disconnectButton.OnClick = () => { Ui.CloseWindow(); onExit(); }; disconnectButton.OnClick = () => { Ui.CloseWindow(); onExit(); };

View File

@@ -365,7 +365,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return; return;
var orders = new[] { var orders = new[] {
Order.Command("gamespeed {0}".F(gameSpeed)), Order.Command("option gamespeed {0}".F(gameSpeed)),
Order.Command("option difficulty {0}".F(difficulty)), Order.Command("option difficulty {0}".F(difficulty)),
Order.Command("state {0}".F(Session.ClientState.Ready)) Order.Command("state {0}".F(Session.ClientState.Ready))
}; };

View File

@@ -44,13 +44,10 @@ namespace OpenRA.Mods.Common.Widgets
clocks = new Dictionary<string, Animation>(); clocks = new Dictionary<string, Animation>();
icon = new Animation(world, "icon"); icon = new Animation(world, "icon");
// Timers should be synced to the effective game time, not the playback time. // Timers in replays should be synced to the effective game time, not the playback time.
GameSpeed speed; timestep = world.Timestep;
var gameSpeeds = Game.ModData.Manifest.Get<GameSpeeds>(); if (world.IsReplay)
if (gameSpeeds.Speeds.TryGetValue(world.LobbyInfo.GlobalSettings.GameSpeedType, out speed)) timestep = world.WorldActor.Trait<MapOptions>().GameSpeed.Timestep;
timestep = speed.Timestep;
else
timestep = world.Timestep;
} }
protected ObserverSupportPowerIconsWidget(ObserverSupportPowerIconsWidget other) protected ObserverSupportPowerIconsWidget(ObserverSupportPowerIconsWidget other)

View File

@@ -39,12 +39,7 @@ namespace OpenRA.Mods.Common.Widgets
// Timers in replays should be synced to the effective game time, not the playback time. // Timers in replays should be synced to the effective game time, not the playback time.
timestep = world.Timestep; timestep = world.Timestep;
if (world.IsReplay) if (world.IsReplay)
{ timestep = world.WorldActor.Trait<MapOptions>().GameSpeed.Timestep;
GameSpeed speed;
var gameSpeeds = Game.ModData.Manifest.Get<GameSpeeds>();
if (gameSpeeds.Speeds.TryGetValue(world.LobbyInfo.GlobalSettings.GameSpeedType, out speed))
timestep = speed.Timestep;
}
} }
public override void Tick() public override void Tick()