Compare commits
8 Commits
log_chat_s
...
ef0c9533a4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef0c9533a4 | ||
|
|
3aa84277a3 | ||
|
|
f9bca71b15 | ||
|
|
0bbe6e58f6 | ||
|
|
ee4403f923 | ||
|
|
aacf0e2b8d | ||
|
|
499a40e32d | ||
|
|
68fd987856 |
@@ -637,6 +637,11 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
return new LineSplitEnumerator(str.AsSpan(), separator);
|
return new LineSplitEnumerator(str.AsSpan(), separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool TryParseInt32Invariant(string s, out int i)
|
||||||
|
{
|
||||||
|
return int.TryParse(s, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ref struct LineSplitEnumerator
|
public ref struct LineSplitEnumerator
|
||||||
|
|||||||
@@ -20,24 +20,6 @@ namespace OpenRA.Network
|
|||||||
{
|
{
|
||||||
public const int ChatMessageMaxLength = 2500;
|
public const int ChatMessageMaxLength = 2500;
|
||||||
|
|
||||||
[FluentReference("player")]
|
|
||||||
const string Joined = "notification-joined";
|
|
||||||
|
|
||||||
[FluentReference("player")]
|
|
||||||
const string Left = "notification-lobby-disconnected";
|
|
||||||
|
|
||||||
[FluentReference]
|
|
||||||
const string GameStarted = "notification-game-has-started";
|
|
||||||
|
|
||||||
[FluentReference]
|
|
||||||
const string GameSaved = "notification-game-saved";
|
|
||||||
|
|
||||||
[FluentReference("player")]
|
|
||||||
const string GamePaused = "notification-game-paused";
|
|
||||||
|
|
||||||
[FluentReference("player")]
|
|
||||||
const string GameUnpaused = "notification-game-unpaused";
|
|
||||||
|
|
||||||
public static int? KickVoteTarget { get; internal set; }
|
public static int? KickVoteTarget { get; internal set; }
|
||||||
|
|
||||||
static Player FindPlayerByClient(this World world, Session.Client c)
|
static Player FindPlayerByClient(this World world, Session.Client c)
|
||||||
@@ -78,8 +60,16 @@ namespace OpenRA.Network
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "DisableChatEntry":
|
case "DisableChatEntry":
|
||||||
{
|
{
|
||||||
if (OrderNotFromServerOrWorldIsReplay(clientId, world))
|
if (OrderNotFromServerOrWorldIsReplay(clientId, world))
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Server may send MaxValue to indicate that it is disabled until further notice
|
||||||
|
if (order.ExtraData == uint.MaxValue)
|
||||||
|
TextNotificationsManager.ChatDisabledUntil = uint.MaxValue;
|
||||||
|
else
|
||||||
|
TextNotificationsManager.ChatDisabledUntil = Game.RunTime + order.ExtraData;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Server may send MaxValue to indicate that it is disabled until further notice
|
// Server may send MaxValue to indicate that it is disabled until further notice
|
||||||
@@ -111,6 +101,26 @@ namespace OpenRA.Network
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "StartKickVote":
|
||||||
|
{
|
||||||
|
if (OrderNotFromServerOrWorldIsReplay(clientId, world))
|
||||||
|
break;
|
||||||
|
|
||||||
|
KickVoteTarget = (int)order.ExtraData;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "EndKickVote":
|
||||||
|
{
|
||||||
|
if (OrderNotFromServerOrWorldIsReplay(clientId, world))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (KickVoteTarget == (int)order.ExtraData)
|
||||||
|
KickVoteTarget = null;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case "Chat":
|
case "Chat":
|
||||||
{
|
{
|
||||||
var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
|
var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<PackageReference Include="System.Collections.Immutable" Version="6.0.0" />
|
<PackageReference Include="System.Collections.Immutable" Version="6.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Linguini.Bundle" Version="0.8.1" />
|
<PackageReference Include="Linguini.Bundle" Version="0.5.0" />
|
||||||
<PackageReference Include="OpenRA-Eluant" Version="1.0.22" />
|
<PackageReference Include="OpenRA-Eluant" Version="1.0.22" />
|
||||||
<PackageReference Include="Mono.NAT" Version="3.0.4" />
|
<PackageReference Include="Mono.NAT" Version="3.0.4" />
|
||||||
<PackageReference Include="SharpZipLib" Version="1.4.2" />
|
<PackageReference Include="SharpZipLib" Version="1.4.2" />
|
||||||
|
|||||||
@@ -319,7 +319,7 @@ namespace OpenRA.Server
|
|||||||
|
|
||||||
MapStatusCache = new MapStatusCache(modData, MapStatusChanged, type == ServerType.Dedicated && settings.EnableLintChecks);
|
MapStatusCache = new MapStatusCache(modData, MapStatusChanged, type == ServerType.Dedicated && settings.EnableLintChecks);
|
||||||
|
|
||||||
playerMessageTracker = new PlayerMessageTracker(this, DispatchOrdersToClient, SendFluentMessageTo);
|
playerMessageTracker = new PlayerMessageTracker(this, DispatchOrdersToClient, SendLocalizedMessageTo);
|
||||||
VoteKickTracker = new VoteKickTracker(this);
|
VoteKickTracker = new VoteKickTracker(this);
|
||||||
|
|
||||||
LobbyInfo = new Session
|
LobbyInfo = new Session
|
||||||
|
|||||||
@@ -17,22 +17,22 @@ namespace OpenRA.Server
|
|||||||
{
|
{
|
||||||
public sealed class VoteKickTracker
|
public sealed class VoteKickTracker
|
||||||
{
|
{
|
||||||
[FluentReference("kickee")]
|
[TranslationReference("kickee")]
|
||||||
const string InsufficientVotes = "notification-insufficient-votes-to-kick";
|
const string InsufficientVotes = "notification-insufficient-votes-to-kick";
|
||||||
|
|
||||||
[FluentReference]
|
[TranslationReference]
|
||||||
const string AlreadyVoted = "notification-kick-already-voted";
|
const string AlreadyVoted = "notification-kick-already-voted";
|
||||||
|
|
||||||
[FluentReference("kicker", "kickee")]
|
[TranslationReference("kicker", "kickee")]
|
||||||
const string VoteKickStarted = "notification-vote-kick-started";
|
const string VoteKickStarted = "notification-vote-kick-started";
|
||||||
|
|
||||||
[FluentReference]
|
[TranslationReference]
|
||||||
const string UnableToStartAVote = "notification-unable-to-start-a-vote";
|
const string UnableToStartAVote = "notification-unable-to-start-a-vote";
|
||||||
|
|
||||||
[FluentReference("kickee", "percentage")]
|
[TranslationReference("kickee", "percentage")]
|
||||||
const string VoteKickProgress = "notification-vote-kick-in-progress";
|
const string VoteKickProgress = "notification-vote-kick-in-progress";
|
||||||
|
|
||||||
[FluentReference("kickee")]
|
[TranslationReference("kickee")]
|
||||||
const string VoteKickEnded = "notification-vote-kick-ended";
|
const string VoteKickEnded = "notification-vote-kick-ended";
|
||||||
|
|
||||||
readonly Dictionary<int, bool> voteTracker = new();
|
readonly Dictionary<int, bool> voteTracker = new();
|
||||||
@@ -76,7 +76,7 @@ namespace OpenRA.Server
|
|||||||
|| (voteInProgress && this.kickee.Client != kickee) // Disallow starting new votes when one is already ongoing.
|
|| (voteInProgress && this.kickee.Client != kickee) // Disallow starting new votes when one is already ongoing.
|
||||||
|| !ClientHasPower(kicker))
|
|| !ClientHasPower(kicker))
|
||||||
{
|
{
|
||||||
server.SendFluentMessageTo(conn, UnableToStartAVote);
|
server.SendLocalizedMessageTo(conn, UnableToStartAVote);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ namespace OpenRA.Server
|
|||||||
if (!kickee.IsObserver && !server.HasClientWonOrLost(kickee))
|
if (!kickee.IsObserver && !server.HasClientWonOrLost(kickee))
|
||||||
{
|
{
|
||||||
// Vote kick cannot be the sole deciding factor for a game.
|
// Vote kick cannot be the sole deciding factor for a game.
|
||||||
server.SendFluentMessageTo(conn, InsufficientVotes, new object[] { "kickee", kickee.Name });
|
server.SendLocalizedMessageTo(conn, InsufficientVotes, Translation.Arguments("kickee", kickee.Name));
|
||||||
EndKickVote();
|
EndKickVote();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -126,7 +126,7 @@ namespace OpenRA.Server
|
|||||||
{
|
{
|
||||||
if (time + server.Settings.VoteKickerCooldown > kickeeConn.ConnectionTimer.ElapsedMilliseconds)
|
if (time + server.Settings.VoteKickerCooldown > kickeeConn.ConnectionTimer.ElapsedMilliseconds)
|
||||||
{
|
{
|
||||||
server.SendFluentMessageTo(conn, UnableToStartAVote);
|
server.SendLocalizedMessageTo(conn, UnableToStartAVote);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -135,7 +135,7 @@ namespace OpenRA.Server
|
|||||||
|
|
||||||
Log.Write("server", $"Vote kick started on {kickeeID}.");
|
Log.Write("server", $"Vote kick started on {kickeeID}.");
|
||||||
voteKickTimer = Stopwatch.StartNew();
|
voteKickTimer = Stopwatch.StartNew();
|
||||||
server.SendFluentMessage(VoteKickStarted, "kicker", kicker.Name, "kickee", kickee.Name);
|
server.SendLocalizedMessage(VoteKickStarted, Translation.Arguments("kicker", kicker.Name, "kickee", kickee.Name));
|
||||||
server.DispatchServerOrdersToClients(new Order("StartKickVote", null, false) { ExtraData = (uint)kickeeID }.Serialize());
|
server.DispatchServerOrdersToClients(new Order("StartKickVote", null, false) { ExtraData = (uint)kickeeID }.Serialize());
|
||||||
this.kickee = (kickee, kickeeConn);
|
this.kickee = (kickee, kickeeConn);
|
||||||
voteKickerStarter = (kicker, conn);
|
voteKickerStarter = (kicker, conn);
|
||||||
@@ -145,7 +145,7 @@ namespace OpenRA.Server
|
|||||||
voteTracker[conn.PlayerIndex] = vote;
|
voteTracker[conn.PlayerIndex] = vote;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
server.SendFluentMessageTo(conn, AlreadyVoted);
|
server.SendLocalizedMessageTo(conn, AlreadyVoted, null);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,9 +168,9 @@ namespace OpenRA.Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
var votesNeeded = eligiblePlayers / 2 + 1;
|
var votesNeeded = eligiblePlayers / 2 + 1;
|
||||||
server.SendFluentMessage(VoteKickProgress,
|
server.SendLocalizedMessage(VoteKickProgress, Translation.Arguments(
|
||||||
"kickee", kickee.Name,
|
"kickee", kickee.Name,
|
||||||
"percentage", votesFor * 100 / eligiblePlayers);
|
"percentage", votesFor * 100 / eligiblePlayers));
|
||||||
|
|
||||||
// If a player or players during a vote lose or disconnect, it is possible that a downvote will
|
// If a player or players during a vote lose or disconnect, it is possible that a downvote will
|
||||||
// kick a client. Guard against that situation.
|
// kick a client. Guard against that situation.
|
||||||
@@ -210,7 +210,7 @@ namespace OpenRA.Server
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (sendMessage)
|
if (sendMessage)
|
||||||
server.SendFluentMessage(VoteKickEnded, "kickee", kickee.Client.Name);
|
server.SendLocalizedMessage(VoteKickEnded, Translation.Arguments("kickee", kickee.Client.Name));
|
||||||
|
|
||||||
server.DispatchServerOrdersToClients(new Order("EndKickVote", null, false) { ExtraData = (uint)kickee.Client.Index }.Serialize());
|
server.DispatchServerOrdersToClients(new Order("EndKickVote", null, false) { ExtraData = (uint)kickee.Client.Index }.Serialize());
|
||||||
|
|
||||||
|
|||||||
@@ -57,10 +57,10 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
[FluentReference]
|
[FluentReference]
|
||||||
const string NoKickGameStarted = "notification-no-kick-game-started";
|
const string NoKickGameStarted = "notification-no-kick-game-started";
|
||||||
|
|
||||||
[FluentReference("admin", "player")]
|
[TranslationReference("admin", "player")]
|
||||||
const string AdminKicked = "notification-admin-kicked";
|
const string AdminKicked = "notification-admin-kicked";
|
||||||
|
|
||||||
[FluentReference("player")]
|
[TranslationReference("player")]
|
||||||
const string Kicked = "notification-kicked";
|
const string Kicked = "notification-kicked";
|
||||||
|
|
||||||
[FluentReference("admin", "player")]
|
[FluentReference("admin", "player")]
|
||||||
@@ -159,37 +159,35 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
[FluentReference]
|
[FluentReference]
|
||||||
const string YouWereKicked = "notification-you-were-kicked";
|
const string YouWereKicked = "notification-you-were-kicked";
|
||||||
|
|
||||||
[FluentReference]
|
[TranslationReference]
|
||||||
const string VoteKickDisabled = "notification-vote-kick-disabled";
|
const string VoteKickDisabled = "notification-vote-kick-disabled";
|
||||||
|
|
||||||
readonly IDictionary<string, Func<S, Connection, Session.Client, string, bool>> commandHandlers =
|
readonly IDictionary<string, Func<S, Connection, Session.Client, string, bool>> commandHandlers = new Dictionary<string, Func<S, Connection, Session.Client, string, bool>>
|
||||||
new Dictionary<string, Func<S, Connection, Session.Client, string, bool>>
|
{
|
||||||
{
|
{ "state", State },
|
||||||
{ "state", State },
|
{ "startgame", StartGame },
|
||||||
{ "startgame", StartGame },
|
{ "slot", Slot },
|
||||||
{ "slot", Slot },
|
{ "allow_spectators", AllowSpectators },
|
||||||
{ "allow_spectators", AllowSpectators },
|
{ "spectate", Specate },
|
||||||
{ "spectate", Specate },
|
{ "slot_close", SlotClose },
|
||||||
{ "slot_close", SlotClose },
|
{ "slot_open", SlotOpen },
|
||||||
{ "slot_open", SlotOpen },
|
{ "slot_bot", SlotBot },
|
||||||
{ "slot_bot", SlotBot },
|
{ "map", Map },
|
||||||
{ "map", Map },
|
{ "option", Option },
|
||||||
{ "option", Option },
|
{ "assignteams", AssignTeams },
|
||||||
{ "reset_options", ResetOptions },
|
{ "kick", Kick },
|
||||||
{ "assignteams", AssignTeams },
|
{ "vote_kick", VoteKick },
|
||||||
{ "kick", Kick },
|
{ "make_admin", MakeAdmin },
|
||||||
{ "vote_kick", VoteKick },
|
{ "make_spectator", MakeSpectator },
|
||||||
{ "make_admin", MakeAdmin },
|
{ "name", Name },
|
||||||
{ "make_spectator", MakeSpectator },
|
{ "faction", Faction },
|
||||||
{ "name", Name },
|
{ "team", Team },
|
||||||
{ "faction", Faction },
|
{ "handicap", Handicap },
|
||||||
{ "team", Team },
|
{ "spawn", Spawn },
|
||||||
{ "handicap", Handicap },
|
{ "clear_spawn", ClearPlayerSpawn },
|
||||||
{ "spawn", Spawn },
|
{ "color", PlayerColor },
|
||||||
{ "clear_spawn", ClearPlayerSpawn },
|
{ "sync_lobby", SyncLobby }
|
||||||
{ "color", PlayerColor },
|
};
|
||||||
{ "sync_lobby", SyncLobby }
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool ValidateSlotCommand(S server, Connection conn, Session.Client client, string arg, bool requiresHost)
|
static bool ValidateSlotCommand(S server, Connection conn, Session.Client client, string arg, bool requiresHost)
|
||||||
{
|
{
|
||||||
@@ -873,7 +871,7 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
Log.Write("server", $"Kicking client {kickClientID}.");
|
Log.Write("server", $"Kicking client {kickClientID}.");
|
||||||
server.SendFluentMessage(AdminKicked, "admin", client.Name, "player", kickClient.Name);
|
server.SendLocalizedMessage(AdminKicked, Translation.Arguments("admin", client.Name, "player", kickClient.Name));
|
||||||
server.SendOrderTo(kickConn, "ServerError", YouWereKicked);
|
server.SendOrderTo(kickConn, "ServerError", YouWereKicked);
|
||||||
server.DropClient(kickConn);
|
server.DropClient(kickConn);
|
||||||
|
|
||||||
@@ -898,13 +896,13 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
var split = s.Split(' ');
|
var split = s.Split(' ');
|
||||||
if (split.Length != 2)
|
if (split.Length != 2)
|
||||||
{
|
{
|
||||||
server.SendFluentMessageTo(conn, MalformedCommand, new object[] { "command", "vote_kick" });
|
server.SendLocalizedMessageTo(conn, MalformedCommand, Translation.Arguments("command", "vote_kick"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!server.Settings.EnableVoteKick)
|
if (!server.Settings.EnableVoteKick)
|
||||||
{
|
{
|
||||||
server.SendFluentMessageTo(conn, VoteKickDisabled);
|
server.SendLocalizedMessageTo(conn, VoteKickDisabled);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -913,27 +911,27 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
|
|
||||||
if (kickConn == null)
|
if (kickConn == null)
|
||||||
{
|
{
|
||||||
server.SendFluentMessageTo(conn, KickNone);
|
server.SendLocalizedMessageTo(conn, KickNone);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var kickClient = server.GetClient(kickConn);
|
var kickClient = server.GetClient(kickConn);
|
||||||
if (client == kickClient)
|
if (client == kickClient)
|
||||||
{
|
{
|
||||||
server.SendFluentMessageTo(conn, NoKickSelf);
|
server.SendLocalizedMessageTo(conn, NoKickSelf);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bool.TryParse(split[1], out var vote))
|
if (!bool.TryParse(split[1], out var vote))
|
||||||
{
|
{
|
||||||
server.SendFluentMessageTo(conn, MalformedCommand, new object[] { "command", "vote_kick" });
|
server.SendLocalizedMessageTo(conn, MalformedCommand, Translation.Arguments("command", "vote_kick"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server.VoteKickTracker.VoteKick(conn, client, kickConn, kickClient, kickClientID, vote))
|
if (server.VoteKickTracker.VoteKick(conn, client, kickConn, kickClient, kickClientID, vote))
|
||||||
{
|
{
|
||||||
Log.Write("server", $"Kicking client {kickClientID}.");
|
Log.Write("server", $"Kicking client {kickClientID}.");
|
||||||
server.SendFluentMessage(Kicked, "player", kickClient.Name);
|
server.SendLocalizedMessage(Kicked, Translation.Arguments("player", kickClient.Name));
|
||||||
server.SendOrderTo(kickConn, "ServerError", YouWereKicked);
|
server.SendOrderTo(kickConn, "ServerError", YouWereKicked);
|
||||||
server.DropClient(kickConn);
|
server.DropClient(kickConn);
|
||||||
|
|
||||||
|
|||||||
@@ -192,8 +192,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
var dropRange = carryall.Info.DropRange;
|
var dropRange = carryall.Info.DropRange;
|
||||||
QueueChild(new DeliverUnit(self, Target.FromCell(self.World, carryable.Destination ?? self.Location), dropRange, carryall.Info.TargetLineColor));
|
self.QueueActivity(true, new DeliverUnit(self, Target.FromCell(self.World, carryable.Destination ?? self.Location), dropRange, carryall.Info.TargetLineColor));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,31 +103,31 @@ namespace OpenRA.Mods.Common.UpdateRules.Rules
|
|||||||
{
|
{
|
||||||
case "cnc":
|
case "cnc":
|
||||||
fromBackup = true;
|
fromBackup = true;
|
||||||
tilesetExtensionsNode = new List<MiniYamlNodeBuilder>()
|
tilesetExtensionsNode = new List<MiniYamlNode>()
|
||||||
{
|
{
|
||||||
new("TEMPERAT", ".tem"),
|
new MiniYamlNode("TEMPERAT", ".tem"),
|
||||||
new("SNOW", ".sno"),
|
new MiniYamlNode("SNOW", ".sno"),
|
||||||
new("INTERIOR", ".int"),
|
new MiniYamlNode("INTERIOR", ".int"),
|
||||||
new("DESERT", ".des"),
|
new MiniYamlNode("DESERT", ".des"),
|
||||||
new("JUNGLE", ".jun"),
|
new MiniYamlNode("JUNGLE", ".jun"),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case "ra":
|
case "ra":
|
||||||
fromBackup = true;
|
fromBackup = true;
|
||||||
tilesetExtensionsNode = new List<MiniYamlNodeBuilder>()
|
tilesetExtensionsNode = new List<MiniYamlNode>()
|
||||||
{
|
{
|
||||||
new("TEMPERAT", ".tem"),
|
new MiniYamlNode("TEMPERAT", ".tem"),
|
||||||
new("SNOW", ".sno"),
|
new MiniYamlNode("SNOW", ".sno"),
|
||||||
new("INTERIOR", ".int"),
|
new MiniYamlNode("INTERIOR", ".int"),
|
||||||
new("DESERT", ".des"),
|
new MiniYamlNode("DESERT", ".des"),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case "ts":
|
case "ts":
|
||||||
fromBackup = true;
|
fromBackup = true;
|
||||||
tilesetExtensionsNode = new List<MiniYamlNodeBuilder>()
|
tilesetExtensionsNode = new List<MiniYamlNode>()
|
||||||
{
|
{
|
||||||
new("TEMPERATE", ".tem"),
|
new MiniYamlNode("TEMPERATE", ".tem"),
|
||||||
new("SNOW", ".sno"),
|
new MiniYamlNode("SNOW", ".sno"),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -148,10 +148,10 @@ namespace OpenRA.Mods.Common.UpdateRules.Rules
|
|||||||
if (tilesetCodesNode == null && modData.Manifest.Id == "ts")
|
if (tilesetCodesNode == null && modData.Manifest.Id == "ts")
|
||||||
{
|
{
|
||||||
fromBackup = true;
|
fromBackup = true;
|
||||||
tilesetCodesNode = new List<MiniYamlNodeBuilder>()
|
tilesetCodesNode = new List<MiniYamlNode>()
|
||||||
{
|
{
|
||||||
new("TEMPERATE", "t"),
|
new MiniYamlNode("TEMPERATE", "t"),
|
||||||
new("SNOW", "a"),
|
new MiniYamlNode("SNOW", "a"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,10 +50,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
[FluentReference]
|
[FluentReference]
|
||||||
const string Gone = "label-client-state-disconnected";
|
const string Gone = "label-client-state-disconnected";
|
||||||
|
|
||||||
[FluentReference]
|
[TranslationReference]
|
||||||
const string KickTooltip = "button-kick-player";
|
const string KickTooltip = "button-kick-player";
|
||||||
|
|
||||||
[FluentReference("player")]
|
[TranslationReference("player")]
|
||||||
const string KickTitle = "dialog-kick.title";
|
const string KickTitle = "dialog-kick.title";
|
||||||
|
|
||||||
[FluentReference]
|
[FluentReference]
|
||||||
@@ -62,28 +62,28 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
[FluentReference]
|
[FluentReference]
|
||||||
const string KickAccept = "dialog-kick.confirm";
|
const string KickAccept = "dialog-kick.confirm";
|
||||||
|
|
||||||
[FluentReference]
|
[TranslationReference]
|
||||||
const string KickVoteTooltip = "button-vote-kick-player";
|
const string KickVoteTooltip = "button-vote-kick-player";
|
||||||
|
|
||||||
[FluentReference("player")]
|
[TranslationReference("player")]
|
||||||
const string VoteKickTitle = "dialog-vote-kick.title";
|
const string VoteKickTitle = "dialog-vote-kick.title";
|
||||||
|
|
||||||
[FluentReference]
|
[TranslationReference]
|
||||||
const string VoteKickPrompt = "dialog-vote-kick.prompt";
|
const string VoteKickPrompt = "dialog-vote-kick.prompt";
|
||||||
|
|
||||||
[FluentReference("bots")]
|
[TranslationReference("bots")]
|
||||||
const string VoteKickPromptBreakBots = "dialog-vote-kick.prompt-break-bots";
|
const string VoteKickPromptBreakBots = "dialog-vote-kick.prompt-break-bots";
|
||||||
|
|
||||||
[FluentReference]
|
[TranslationReference]
|
||||||
const string VoteKickVoteStart = "dialog-vote-kick.vote-start";
|
const string VoteKickVoteStart = "dialog-vote-kick.vote-start";
|
||||||
|
|
||||||
[FluentReference]
|
[TranslationReference]
|
||||||
const string VoteKickVoteFor = "dialog-vote-kick.vote-for";
|
const string VoteKickVoteFor = "dialog-vote-kick.vote-for";
|
||||||
|
|
||||||
[FluentReference]
|
[TranslationReference]
|
||||||
const string VoteKickVoteAgainst = "dialog-vote-kick.vote-against";
|
const string VoteKickVoteAgainst = "dialog-vote-kick.vote-against";
|
||||||
|
|
||||||
[FluentReference]
|
[TranslationReference]
|
||||||
const string VoteKickVoteCancel = "dialog-vote-kick.vote-cancel";
|
const string VoteKickVoteCancel = "dialog-vote-kick.vote-cancel";
|
||||||
|
|
||||||
[ObjectCreator.UseCtor]
|
[ObjectCreator.UseCtor]
|
||||||
@@ -133,10 +133,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
var teamTemplate = playerPanel.Get<ScrollItemWidget>("TEAM_TEMPLATE");
|
var teamTemplate = playerPanel.Get<ScrollItemWidget>("TEAM_TEMPLATE");
|
||||||
var playerTemplate = playerPanel.Get("PLAYER_TEMPLATE");
|
var playerTemplate = playerPanel.Get("PLAYER_TEMPLATE");
|
||||||
var spectatorTemplate = playerPanel.Get("SPECTATOR_TEMPLATE");
|
var spectatorTemplate = playerPanel.Get("SPECTATOR_TEMPLATE");
|
||||||
var unmuteTooltip = FluentProvider.GetMessage(Unmute);
|
var unmuteTooltip = TranslationProvider.GetString(Unmute);
|
||||||
var muteTooltip = FluentProvider.GetMessage(Mute);
|
var muteTooltip = TranslationProvider.GetString(Mute);
|
||||||
var kickTooltip = FluentProvider.GetMessage(KickTooltip);
|
var kickTooltip = TranslationProvider.GetString(KickTooltip);
|
||||||
var voteKickTooltip = FluentProvider.GetMessage(KickVoteTooltip);
|
var voteKickTooltip = TranslationProvider.GetString(KickVoteTooltip);
|
||||||
playerPanel.RemoveChildren();
|
playerPanel.RemoveChildren();
|
||||||
|
|
||||||
var teams = world.Players.Where(p => !p.NonCombatant && p.Playable)
|
var teams = world.Players.Where(p => !p.NonCombatant && p.Playable)
|
||||||
@@ -159,14 +159,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
{
|
{
|
||||||
ConfirmationDialogs.ButtonPrompt(modData,
|
ConfirmationDialogs.ButtonPrompt(modData,
|
||||||
title: VoteKickTitle,
|
title: VoteKickTitle,
|
||||||
|
titleArguments: Translation.Arguments("player", client.Name),
|
||||||
text: botsCount > 0 ? VoteKickPromptBreakBots : VoteKickPrompt,
|
text: botsCount > 0 ? VoteKickPromptBreakBots : VoteKickPrompt,
|
||||||
titleArguments: new object[] { "player", client.Name },
|
textArguments: Translation.Arguments("bots", botsCount),
|
||||||
textArguments: new object[] { "bots", botsCount },
|
|
||||||
onConfirm: () =>
|
onConfirm: () =>
|
||||||
{
|
{
|
||||||
orderManager.IssueOrder(Order.Command($"vote_kick {client.Index} {true}"));
|
orderManager.IssueOrder(Order.Command($"vote_kick {client.Index} {true}"));
|
||||||
hideMenu(false);
|
hideMenu(false);
|
||||||
closeMenu();
|
|
||||||
},
|
},
|
||||||
confirmText: VoteKickVoteStart,
|
confirmText: VoteKickVoteStart,
|
||||||
onCancel: () => hideMenu(false));
|
onCancel: () => hideMenu(false));
|
||||||
@@ -175,33 +174,31 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
|
|
||||||
ConfirmationDialogs.ButtonPrompt(modData,
|
ConfirmationDialogs.ButtonPrompt(modData,
|
||||||
title: VoteKickTitle,
|
title: VoteKickTitle,
|
||||||
|
titleArguments: Translation.Arguments("player", client.Name),
|
||||||
text: botsCount > 0 ? VoteKickPromptBreakBots : VoteKickPrompt,
|
text: botsCount > 0 ? VoteKickPromptBreakBots : VoteKickPrompt,
|
||||||
titleArguments: new object[] { "player", client.Name },
|
textArguments: Translation.Arguments("bots", botsCount),
|
||||||
textArguments: new object[] { "bots", botsCount },
|
|
||||||
onConfirm: () =>
|
onConfirm: () =>
|
||||||
{
|
{
|
||||||
orderManager.IssueOrder(Order.Command($"vote_kick {client.Index} {true}"));
|
orderManager.IssueOrder(Order.Command($"vote_kick {client.Index} {true}"));
|
||||||
hideMenu(false);
|
hideMenu(false);
|
||||||
closeMenu();
|
|
||||||
},
|
},
|
||||||
confirmText: VoteKickVoteFor,
|
confirmText: VoteKickVoteFor,
|
||||||
onCancel: () => hideMenu(false),
|
|
||||||
cancelText: VoteKickVoteCancel,
|
|
||||||
onOther: () =>
|
onOther: () =>
|
||||||
{
|
{
|
||||||
Ui.CloseWindow();
|
Ui.CloseWindow();
|
||||||
orderManager.IssueOrder(Order.Command($"vote_kick {client.Index} {false}"));
|
orderManager.IssueOrder(Order.Command($"vote_kick {client.Index} {false}"));
|
||||||
hideMenu(false);
|
hideMenu(false);
|
||||||
closeMenu();
|
|
||||||
},
|
},
|
||||||
otherText: VoteKickVoteAgainst);
|
otherText: VoteKickVoteAgainst,
|
||||||
|
onCancel: () => hideMenu(false),
|
||||||
|
cancelText: VoteKickVoteCancel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ConfirmationDialogs.ButtonPrompt(modData,
|
ConfirmationDialogs.ButtonPrompt(modData,
|
||||||
title: KickTitle,
|
title: KickTitle,
|
||||||
|
titleArguments: Translation.Arguments("player", client.Name),
|
||||||
text: KickPrompt,
|
text: KickPrompt,
|
||||||
titleArguments: new object[] { "player", client.Name },
|
|
||||||
onConfirm: () =>
|
onConfirm: () =>
|
||||||
{
|
{
|
||||||
orderManager.IssueOrder(Order.Command($"kick {client.Index} {false}"));
|
orderManager.IssueOrder(Order.Command($"kick {client.Index} {false}"));
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Metadata:
|
Metadata:
|
||||||
Title: All mods
|
Title: All mods
|
||||||
Version: release-20250330
|
Version: release-20231010
|
||||||
Hidden: true
|
Hidden: true
|
||||||
|
|
||||||
FileSystem: DefaultFileSystem
|
FileSystem: DefaultFileSystem
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Metadata:
|
Metadata:
|
||||||
Title: mod-title
|
Title: mod-title
|
||||||
Version: release-20250330
|
Version: {DEV_VERSION}
|
||||||
Hidden: true
|
Hidden: true
|
||||||
|
|
||||||
FileSystem: DefaultFileSystem
|
FileSystem: DefaultFileSystem
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Metadata:
|
Metadata:
|
||||||
Title: mod-title
|
Title: Tiberian Dawn
|
||||||
Version: release-20250330
|
Version: release-20231010
|
||||||
Website: https://www.openra.net
|
Website: https://www.openra.net
|
||||||
WebIcon32: https://www.openra.net/images/icons/cnc_32x32.png
|
WebIcon32: https://www.openra.net/images/icons/cnc_32x32.png
|
||||||
WindowTitle: mod-windowtitle
|
WindowTitle: mod-windowtitle
|
||||||
@@ -40,7 +40,7 @@ FileSystem: ContentInstallerFileSystem
|
|||||||
|
|
||||||
MapFolders:
|
MapFolders:
|
||||||
cnc|maps: System
|
cnc|maps: System
|
||||||
~^SupportDir|maps/cnc/release-20250330: User
|
~^SupportDir|maps/cnc/release-20231010: User
|
||||||
|
|
||||||
Rules:
|
Rules:
|
||||||
cnc|rules/misc.yaml
|
cnc|rules/misc.yaml
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Metadata:
|
Metadata:
|
||||||
Title: mod-title
|
Title: mod-title
|
||||||
Version: release-20250330
|
Version: {DEV_VERSION}
|
||||||
Hidden: true
|
Hidden: true
|
||||||
|
|
||||||
FileSystem: DefaultFileSystem
|
FileSystem: DefaultFileSystem
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Metadata:
|
Metadata:
|
||||||
Title: mod-title
|
Title: Dune 2000
|
||||||
Version: release-20250330
|
Version: release-20231010
|
||||||
Website: https://www.openra.net
|
Website: https://www.openra.net
|
||||||
WebIcon32: https://www.openra.net/images/icons/d2k_32x32.png
|
WebIcon32: https://www.openra.net/images/icons/d2k_32x32.png
|
||||||
WindowTitle: mod-windowtitle
|
WindowTitle: mod-windowtitle
|
||||||
@@ -37,7 +37,7 @@ FileSystem: ContentInstallerFileSystem
|
|||||||
|
|
||||||
MapFolders:
|
MapFolders:
|
||||||
d2k|maps: System
|
d2k|maps: System
|
||||||
~^SupportDir|maps/d2k/release-20250330: User
|
~^SupportDir|maps/d2k/release-20231010: User
|
||||||
|
|
||||||
Rules:
|
Rules:
|
||||||
d2k|rules/misc.yaml
|
d2k|rules/misc.yaml
|
||||||
|
|||||||
75
mods/modcontent/mod.yaml
Normal file
75
mods/modcontent/mod.yaml
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
Metadata:
|
||||||
|
Title: Mod Content Manager
|
||||||
|
Version: release-20231010
|
||||||
|
Hidden: true
|
||||||
|
|
||||||
|
Packages:
|
||||||
|
^EngineDir
|
||||||
|
^EngineDir|mods/modcontent: modcontent
|
||||||
|
^EngineDir|mods/common: common
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
modcontent|rules.yaml
|
||||||
|
|
||||||
|
Cursors:
|
||||||
|
modcontent|cursors.yaml
|
||||||
|
|
||||||
|
Chrome:
|
||||||
|
modcontent|chrome.yaml
|
||||||
|
|
||||||
|
Assemblies:
|
||||||
|
^BinDir|OpenRA.Mods.Common.dll
|
||||||
|
|
||||||
|
ChromeLayout:
|
||||||
|
modcontent|content.yaml
|
||||||
|
|
||||||
|
Notifications:
|
||||||
|
modcontent|notifications.yaml
|
||||||
|
|
||||||
|
LoadScreen: ModContentLoadScreen
|
||||||
|
Image: ^EngineDir|mods/modcontent/chrome.png
|
||||||
|
Image2x: ^EngineDir|mods/modcontent/chrome-2x.png
|
||||||
|
Image3x: ^EngineDir|mods/modcontent/chrome-3x.png
|
||||||
|
|
||||||
|
ChromeMetrics:
|
||||||
|
common|metrics.yaml
|
||||||
|
modcontent|metrics.yaml
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
common|languages/en.ftl
|
||||||
|
|
||||||
|
Fonts:
|
||||||
|
Tiny:
|
||||||
|
Font: common|FreeSans.ttf
|
||||||
|
Size: 10
|
||||||
|
Ascender: 8
|
||||||
|
TinyBold:
|
||||||
|
Font: common|FreeSansBold.ttf
|
||||||
|
Size: 10
|
||||||
|
Ascender: 8
|
||||||
|
Regular:
|
||||||
|
Font: common|FreeSans.ttf
|
||||||
|
Size: 14
|
||||||
|
Ascender: 11
|
||||||
|
Bold:
|
||||||
|
Font: common|FreeSansBold.ttf
|
||||||
|
Size: 14
|
||||||
|
Ascender: 11
|
||||||
|
MediumBold:
|
||||||
|
Font: common|FreeSansBold.ttf
|
||||||
|
Size: 18
|
||||||
|
Ascender: 14
|
||||||
|
BigBold:
|
||||||
|
Font: common|FreeSansBold.ttf
|
||||||
|
Size: 24
|
||||||
|
Ascender: 18
|
||||||
|
|
||||||
|
SoundFormats:
|
||||||
|
|
||||||
|
SpriteFormats: PngSheet
|
||||||
|
|
||||||
|
TerrainFormat: DefaultTerrain
|
||||||
|
|
||||||
|
SpriteSequenceFormat: DefaultSpriteSequence
|
||||||
|
|
||||||
|
ModelSequenceFormat: PlaceholderModelSequence
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
Metadata:
|
Metadata:
|
||||||
Title: mod-title
|
Title: mod-title
|
||||||
Version: release-20250330
|
Version: {DEV_VERSION}
|
||||||
Hidden: true
|
Hidden: true
|
||||||
|
|
||||||
FileSystem: DefaultFileSystem
|
FileSystem: DefaultFileSystem
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Metadata:
|
Metadata:
|
||||||
Title: mod-title
|
Title: Red Alert
|
||||||
Version: release-20250330
|
Version: release-20231010
|
||||||
Website: https://www.openra.net
|
Website: https://www.openra.net
|
||||||
WebIcon32: https://www.openra.net/images/icons/ra_32x32.png
|
WebIcon32: https://www.openra.net/images/icons/ra_32x32.png
|
||||||
WindowTitle: mod-windowtitle
|
WindowTitle: mod-windowtitle
|
||||||
@@ -68,7 +68,7 @@ FileSystem: ContentInstallerFileSystem
|
|||||||
|
|
||||||
MapFolders:
|
MapFolders:
|
||||||
ra|maps: System
|
ra|maps: System
|
||||||
~^SupportDir|maps/ra/release-20250330: User
|
~^SupportDir|maps/ra/release-20231010: User
|
||||||
|
|
||||||
Rules:
|
Rules:
|
||||||
ra|rules/misc.yaml
|
ra|rules/misc.yaml
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Metadata:
|
Metadata:
|
||||||
Title: mod-title
|
Title: mod-title
|
||||||
Version: release-20250330
|
Version: {DEV_VERSION}
|
||||||
Hidden: true
|
Hidden: true
|
||||||
|
|
||||||
FileSystem: DefaultFileSystem
|
FileSystem: DefaultFileSystem
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Metadata:
|
Metadata:
|
||||||
Title: mod-title
|
Title: Tiberian Sun
|
||||||
Version: release-20250330
|
Version: release-20231010
|
||||||
Website: https://www.openra.net
|
Website: https://www.openra.net
|
||||||
WebIcon32: https://www.openra.net/images/icons/ts_32x32.png
|
WebIcon32: https://www.openra.net/images/icons/ts_32x32.png
|
||||||
WindowTitle: mod-windowtitle
|
WindowTitle: mod-windowtitle
|
||||||
@@ -44,7 +44,7 @@ FileSystem: ContentInstallerFileSystem
|
|||||||
|
|
||||||
MapFolders:
|
MapFolders:
|
||||||
ts|maps: System
|
ts|maps: System
|
||||||
~^SupportDir|maps/ts/release-20250330: User
|
~^SupportDir|maps/ts/release-20231010: User
|
||||||
|
|
||||||
Rules:
|
Rules:
|
||||||
ts|rules/ai.yaml
|
ts|rules/ai.yaml
|
||||||
|
|||||||
Reference in New Issue
Block a user