Skip to content

Commit

Permalink
Enable dedicated server lint checks.
Browse files Browse the repository at this point in the history
  • Loading branch information
pchote committed Apr 5, 2021
1 parent 8de6a9d commit 14d6b7b
Show file tree
Hide file tree
Showing 23 changed files with 436 additions and 146 deletions.
58 changes: 58 additions & 0 deletions OpenRA.Game/Map/MapPreview.cs
Expand Up @@ -64,13 +64,15 @@ public class RemoteMapData
public readonly string tileset;
public readonly string rules;
public readonly string players_block;
public readonly int mapformat;
}

public class MapPreview : IDisposable, IReadOnlyFileSystem
{
/// <summary>Wrapper that enables map data to be replaced in an atomic fashion</summary>
class InnerData
{
public int MapFormat;
public string Title;
public string[] Categories;
public string Author;
Expand Down Expand Up @@ -171,6 +173,7 @@ public InnerData Clone()

volatile InnerData innerData;

public int MapFormat => innerData.MapFormat;
public string Title => innerData.Title;
public string[] Categories => innerData.Categories;
public string Author => innerData.Author;
Expand All @@ -185,6 +188,9 @@ public InnerData Clone()
public MapClassification Class => innerData.Class;
public MapVisibility Visibility => innerData.Visibility;

public MiniYaml RuleDefinitions => innerData.RuleDefinitions;
public MiniYaml WeaponDefinitions => innerData.WeaponDefinitions;

public ActorInfo WorldActorInfo => innerData.WorldActorInfo;
public ActorInfo PlayerActorInfo => innerData.PlayerActorInfo;

Expand Down Expand Up @@ -241,6 +247,7 @@ public MapPreview(ModData modData, string uid, MapGridType gridType, MapCache ca
Uid = uid;
innerData = new InnerData
{
MapFormat = 0,
Title = "Unknown Map",
Categories = new[] { "Unknown" },
Author = "Unknown Author",
Expand All @@ -257,6 +264,53 @@ public MapPreview(ModData modData, string uid, MapGridType gridType, MapCache ca
};
}

// For linting purposes only!
public MapPreview(Map map, ModData modData)
{
this.modData = modData;
cache = modData.MapCache;

Uid = map.Uid;
Package = map.Package;

var mapPlayers = new MapPlayers(map.PlayerDefinitions);
var spawns = new List<CPos>();
foreach (var kv in map.ActorDefinitions.Where(d => d.Value.Value == "mpspawn"))
{
var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
spawns.Add(s.Get<LocationInit>().Value);
}

innerData = new InnerData
{
MapFormat = map.MapFormat,
Title = map.Title,
Categories = map.Categories,
Author = map.Author,
TileSet = map.Tileset,
Players = mapPlayers,
PlayerCount = mapPlayers.Players.Count(x => x.Value.Playable),
SpawnPoints = spawns.ToArray(),
GridType = map.Grid.Type,
Bounds = map.Bounds,
Preview = null,
Status = MapStatus.Available,
Class = MapClassification.Unknown,
Visibility = map.Visibility,
};

innerData.SetCustomRules(modData, this, new Dictionary<string, MiniYaml>()
{
{ "Rules", map.RuleDefinitions },
{ "Weapons", map.WeaponDefinitions },
{ "Voices", map.VoiceDefinitions },
{ "Music", map.MusicDefinitions },
{ "Notifications", map.NotificationDefinitions },
{ "Sequences", map.SequenceDefinitions },
{ "ModelSequences", map.ModelSequenceDefinitions }
});
}

public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassification classification, string[] mapCompatibility, MapGridType gridType)
{
Dictionary<string, MiniYaml> yaml;
Expand Down Expand Up @@ -304,6 +358,9 @@ public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassi
if (yaml.TryGetValue("RequiresMod", out temp))
requiresMod = temp.Value;

if (yaml.TryGetValue("MapFormat", out temp))
newData.MapFormat = FieldLoader.GetValue<int>("MapFormat", temp.Value);

newData.Status = mapCompatibility == null || mapCompatibility.Contains(requiresMod) ?
MapStatus.Available : MapStatus.Unavailable;

Expand Down Expand Up @@ -379,6 +436,7 @@ public void UpdateRemoteSearch(MapStatus status, MiniYaml yaml, Action<MapPrevie
newData.PlayerCount = r.players;
newData.Bounds = r.bounds;
newData.TileSet = r.tileset;
newData.MapFormat = r.mapformat;

var spawns = new CPos[r.spawnpoints.Length / 2];
for (var j = 0; j < r.spawnpoints.Length; j += 2)
Expand Down
49 changes: 21 additions & 28 deletions OpenRA.Mods.Common/Lint/CheckActorReferences.cs
Expand Up @@ -15,47 +15,46 @@
using System.Reflection;
using OpenRA.GameRules;
using OpenRA.Mods.Common.Traits;
using OpenRA.Network;
using OpenRA.Traits;

namespace OpenRA.Mods.Common.Lint
{
public class CheckActorReferences : ILintRulesPass
public class CheckActorReferences : ILintRulesPass, ILintServerMapPass
{
Action<string> emitError;

public void Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
void ILintRulesPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
{
this.emitError = emitError;

foreach (var actorInfo in rules.Actors)
foreach (var traitInfo in actorInfo.Value.TraitInfos<TraitInfo>())
CheckTrait(actorInfo.Value, traitInfo, rules);
CheckTrait(emitError, actorInfo.Value, traitInfo, rules);
}

void ILintServerMapPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, MapPreview map, Ruleset mapRules)
{
foreach (var actorInfo in mapRules.Actors)
foreach (var traitInfo in actorInfo.Value.TraitInfos<TraitInfo>())
CheckTrait(emitError, actorInfo.Value, traitInfo, mapRules);
}

void CheckTrait(ActorInfo actorInfo, TraitInfo traitInfo, Ruleset rules)
void CheckTrait(Action<string> emitError, ActorInfo actorInfo, TraitInfo traitInfo, Ruleset rules)
{
var actualType = traitInfo.GetType();
foreach (var field in actualType.GetFields())
{
if (field.HasAttribute<ActorReferenceAttribute>())
CheckActorReference(actorInfo, traitInfo, field, rules.Actors,
CheckActorReference(emitError, actorInfo, traitInfo, field, rules.Actors,
field.GetCustomAttributes<ActorReferenceAttribute>(true)[0]);

if (field.HasAttribute<WeaponReferenceAttribute>())
CheckWeaponReference(actorInfo, traitInfo, field, rules.Weapons,
field.GetCustomAttributes<WeaponReferenceAttribute>(true)[0]);
CheckWeaponReference(emitError, actorInfo, traitInfo, field, rules.Weapons);

if (field.HasAttribute<VoiceSetReferenceAttribute>())
CheckVoiceReference(actorInfo, traitInfo, field, rules.Voices,
field.GetCustomAttributes<VoiceSetReferenceAttribute>(true)[0]);
CheckVoiceReference(emitError, actorInfo, traitInfo, field, rules.Voices);
}
}

void CheckActorReference(ActorInfo actorInfo,
TraitInfo traitInfo,
FieldInfo fieldInfo,
IReadOnlyDictionary<string, ActorInfo> dict,
ActorReferenceAttribute attribute)
void CheckActorReference(Action<string> emitError, ActorInfo actorInfo, TraitInfo traitInfo,
FieldInfo fieldInfo, IReadOnlyDictionary<string, ActorInfo> dict, ActorReferenceAttribute attribute)
{
var values = LintExts.GetFieldValues(traitInfo, fieldInfo, emitError, attribute.DictionaryReference);
foreach (var value in values)
Expand All @@ -82,11 +81,8 @@ void CheckTrait(ActorInfo actorInfo, TraitInfo traitInfo, Ruleset rules)
}
}

void CheckWeaponReference(ActorInfo actorInfo,
TraitInfo traitInfo,
FieldInfo fieldInfo,
IReadOnlyDictionary<string, WeaponInfo> dict,
WeaponReferenceAttribute attribute)
void CheckWeaponReference(Action<string> emitError, ActorInfo actorInfo, TraitInfo traitInfo,
FieldInfo fieldInfo, IReadOnlyDictionary<string, WeaponInfo> dict)
{
var values = LintExts.GetFieldValues(traitInfo, fieldInfo, emitError);
foreach (var value in values)
Expand All @@ -100,11 +96,8 @@ void CheckTrait(ActorInfo actorInfo, TraitInfo traitInfo, Ruleset rules)
}
}

void CheckVoiceReference(ActorInfo actorInfo,
TraitInfo traitInfo,
FieldInfo fieldInfo,
IReadOnlyDictionary<string, SoundInfo> dict,
VoiceSetReferenceAttribute attribute)
void CheckVoiceReference(Action<string> emitError, ActorInfo actorInfo, TraitInfo traitInfo,
FieldInfo fieldInfo, IReadOnlyDictionary<string, SoundInfo> dict)
{
var values = LintExts.GetFieldValues(traitInfo, fieldInfo, emitError);
foreach (var value in values)
Expand Down
15 changes: 13 additions & 2 deletions OpenRA.Mods.Common/Lint/CheckAngle.cs
Expand Up @@ -11,12 +11,23 @@

using System;
using OpenRA.Mods.Common.Projectiles;
using OpenRA.Network;

namespace OpenRA.Mods.Common.Lint
{
class CheckAngle : ILintRulesPass
class CheckAngle : ILintRulesPass, ILintServerMapPass
{
public void Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
void ILintRulesPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
{
Run(emitError, rules);
}

void ILintServerMapPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, MapPreview map, Ruleset mapRules)
{
Run(emitError, mapRules);
}

void Run(Action<string> emitError, Ruleset rules)
{
foreach (var weaponInfo in rules.Weapons)
{
Expand Down
15 changes: 13 additions & 2 deletions OpenRA.Mods.Common/Lint/CheckConditions.cs
Expand Up @@ -12,13 +12,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Network;
using OpenRA.Traits;

namespace OpenRA.Mods.Common.Lint
{
public class CheckConditions : ILintRulesPass
public class CheckConditions : ILintRulesPass, ILintServerMapPass
{
public void Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
void ILintRulesPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
{
Run(emitError, emitWarning, rules);
}

void ILintServerMapPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, MapPreview map, Ruleset mapRules)
{
Run(emitError, emitWarning, mapRules);
}

void Run(Action<string> emitError, Action<string> emitWarning, Ruleset rules)
{
foreach (var actorInfo in rules.Actors)
{
Expand Down
3 changes: 2 additions & 1 deletion OpenRA.Mods.Common/Lint/CheckConflictingMouseBounds.cs
Expand Up @@ -12,12 +12,13 @@
using System;
using System.Linq;
using OpenRA.Mods.Common.Traits;
using OpenRA.Network;

namespace OpenRA.Mods.Common.Lint
{
public class CheckConflictingMouseBounds : ILintRulesPass
{
public void Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
void ILintRulesPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
{
foreach (var actorInfo in rules.Actors)
{
Expand Down
15 changes: 13 additions & 2 deletions OpenRA.Mods.Common/Lint/CheckCursors.cs
Expand Up @@ -12,13 +12,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Network;
using OpenRA.Traits;

namespace OpenRA.Mods.Common.Lint
{
class CheckCursors : ILintRulesPass
class CheckCursors : ILintRulesPass, ILintServerMapPass
{
public void Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
void ILintRulesPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
{
Run(emitError, modData, rules);
}

void ILintServerMapPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, MapPreview map, Ruleset mapRules)
{
Run(emitError, modData, mapRules);
}

void Run(Action<string> emitError, ModData modData, Ruleset rules)
{
var fileSystem = modData.DefaultFileSystem;
var sequenceYaml = MiniYaml.Merge(modData.Manifest.Cursors.Select(s => MiniYaml.FromStream(fileSystem.Open(s), s)));
Expand Down
15 changes: 13 additions & 2 deletions OpenRA.Mods.Common/Lint/CheckDefaultVisibility.cs
Expand Up @@ -12,13 +12,24 @@
using System;
using System.Linq;
using OpenRA.Mods.Common.Traits;
using OpenRA.Network;
using OpenRA.Traits;

namespace OpenRA.Mods.Common.Lint
{
class CheckDefaultVisibility : ILintRulesPass
class CheckDefaultVisibility : ILintRulesPass, ILintServerMapPass
{
public void Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
void ILintRulesPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
{
Run(emitError, rules);
}

void ILintServerMapPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, MapPreview map, Ruleset mapRules)
{
Run(emitError, mapRules);
}

void Run(Action<string> emitError, Ruleset rules)
{
foreach (var actorInfo in rules.Actors)
{
Expand Down
15 changes: 13 additions & 2 deletions OpenRA.Mods.Common/Lint/CheckHitShapes.cs
Expand Up @@ -12,13 +12,24 @@
using System;
using System.Linq;
using OpenRA.Mods.Common.Traits;
using OpenRA.Network;
using OpenRA.Traits;

namespace OpenRA.Mods.Common.Lint
{
class CheckHitShapes : ILintRulesPass
class CheckHitShapes : ILintRulesPass, ILintServerMapPass
{
public void Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
void ILintRulesPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
{
Run(emitError, rules);
}

void ILintServerMapPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, MapPreview map, Ruleset mapRules)
{
Run(emitError, mapRules);
}

void Run(Action<string> emitError, Ruleset rules)
{
foreach (var actorInfo in rules.Actors)
{
Expand Down
15 changes: 13 additions & 2 deletions OpenRA.Mods.Common/Lint/CheckLocomotorReferences.cs
Expand Up @@ -12,13 +12,24 @@
using System;
using System.Linq;
using OpenRA.Mods.Common.Traits;
using OpenRA.Network;
using OpenRA.Traits;

namespace OpenRA.Mods.Common.Lint
{
public class CheckLocomotorReferences : ILintRulesPass
public class CheckLocomotorReferences : ILintRulesPass, ILintServerMapPass
{
public void Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
void ILintRulesPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
{
Run(emitError, rules);
}

void ILintServerMapPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, MapPreview map, Ruleset mapRules)
{
Run(emitError, mapRules);
}

void Run(Action<string> emitError, Ruleset rules)
{
var worldActor = rules.Actors["world"];
var locomotorInfos = worldActor.TraitInfos<LocomotorInfo>().ToArray();
Expand Down

0 comments on commit 14d6b7b

Please sign in to comment.