Send mod title, website, and an icon URL to the master server.

Prefer the title returned by the master server in the games list.
This commit is contained in:
Paul Chote
2018-05-28 14:42:05 +00:00
committed by reaperrr
parent 10aaa8eea8
commit 6ef802b929
2 changed files with 60 additions and 28 deletions

View File

@@ -46,6 +46,8 @@ namespace OpenRA
{
public string Title;
public string Version;
public string Website;
public string WebIcon32;
public bool Hidden;
}

View File

@@ -45,7 +45,18 @@ namespace OpenRA.Network
public class GameServer
{
static readonly string[] SerializeFields = { "Name", "Address", "Mod", "Version", "Map", "State", "MaxPlayers", "Protected" };
static readonly string[] SerializeFields =
{
// Server information
"Name", "Address",
// Mod information
"Mod", "Version", "ModTitle", "ModWebsite", "ModIcon32",
// Current server state
"Map", "State", "MaxPlayers", "Protected"
};
public const int ProtocolVersion = 2;
/// <summary>Online game number or -1 for LAN games</summary>
@@ -75,6 +86,15 @@ namespace OpenRA.Network
/// <summary>Mod Version</summary>
public readonly string Version = "";
/// <summary>Human-readable mod title</summary>
public readonly string ModTitle = "";
/// <summary>URL to show in game listings for custom/unknown mods.</summary>
public readonly string ModWebsite = "";
/// <summary>URL to a 32x32 px icon for the mod.</summary>
public readonly string ModIcon32 = "";
/// <summary>Password protected</summary>
public readonly bool Protected = false;
@@ -101,13 +121,11 @@ namespace OpenRA.Network
[FieldLoader.Ignore]
public readonly bool IsJoinable = false;
/// <summary>Label to display in the multiplayer browser. Only defined if GameServer is parsed from yaml.</summary>
[FieldLoader.Ignore]
public readonly string ModLabel = "";
[FieldLoader.LoadUsing("LoadClients")]
public readonly GameClient[] Clients;
public string ModLabel { get { return "{0} ({1})".F(ModTitle, Version); } }
static object LoadClients(MiniYaml yaml)
{
var clients = new List<GameClient>();
@@ -147,33 +165,40 @@ namespace OpenRA.Network
PlayTime = (int)(DateTime.UtcNow - startTime).TotalSeconds;
}
Manifest mod;
ExternalMod external;
var externalKey = ExternalMod.MakeKey(Mod, Version);
if (Game.ExternalMods.TryGetValue(externalKey, out external) && external.Version == Version)
{
ModLabel = "{0} ({1})".F(external.Title, external.Version);
IsCompatible = true;
}
else if (Game.Mods.TryGetValue(Mod, out mod))
{
// Use internal mod data to populate the section header, but
// on-connect switching must use the external mod plumbing.
ModLabel = "{0} ({1})".F(mod.Metadata.Title, Version);
}
else
{
// Some platforms (e.g. macOS) package each mod separately, so the Mods check above won't work.
// Guess based on the most recent ExternalMod instead.
var guessMod = Game.ExternalMods.Values
.OrderByDescending(m => m.Version)
.FirstOrDefault(m => m.Id == Mod);
if (guessMod != null)
ModLabel = "{0} ({1})".F(guessMod.Title, Version);
// Games advertised using the old API used local mod metadata
if (string.IsNullOrEmpty(ModTitle))
{
Manifest mod;
if (external != null && external.Version == Version)
{
// Use external mod registration to populate the section header
ModTitle = external.Title;
}
else if (Game.Mods.TryGetValue(Mod, out mod))
{
// Use internal mod data to populate the section header, but
// on-connect switching must use the external mod plumbing.
ModTitle = mod.Metadata.Title;
}
else
ModLabel = "Unknown mod: {0} ({1})".F(Mod, Version);
{
// Some platforms (e.g. macOS) package each mod separately, so the Mods check above won't work.
// Guess based on the most recent ExternalMod instead.
var guessMod = Game.ExternalMods.Values
.OrderByDescending(m => m.Version)
.FirstOrDefault(m => m.Id == Mod);
if (guessMod != null)
ModTitle = "{0}".F(guessMod.Title);
else
ModTitle = "Unknown mod: {0}".F(Mod);
}
}
var mapAvailable = Game.Settings.Game.AllowDownloading || Game.ModData.MapCache[Map].Status == MapStatus.Available;
@@ -182,6 +207,8 @@ namespace OpenRA.Network
public GameServer(Server.Server server)
{
var manifest = server.ModData.Manifest;
Name = server.Settings.Name;
// IP address will be replaced with a real value by the master server / receiving LAN client
@@ -189,8 +216,11 @@ namespace OpenRA.Network
State = (int)server.State;
MaxPlayers = server.LobbyInfo.Slots.Count(s => !s.Value.Closed) - server.LobbyInfo.Clients.Count(c1 => c1.Bot != null);
Map = server.Map.Uid;
Mod = server.ModData.Manifest.Id;
Version = server.ModData.Manifest.Metadata.Version;
Mod = manifest.Id;
Version = manifest.Metadata.Version;
ModTitle = manifest.Metadata.Title;
ModWebsite = manifest.Metadata.Website;
ModIcon32 = manifest.Metadata.WebIcon32;
Protected = !string.IsNullOrEmpty(server.Settings.Password);
Clients = server.LobbyInfo.Clients.Select(c => new GameClient(c)).ToArray();
}