Merge pull request #2957 from Mailaender/dedicated-bot-order-exploits

Don't misinterpret AI orders as an exploit on dedicated servers anymore.
This commit is contained in:
Chris Forbes
2013-04-05 18:48:17 -07:00
6 changed files with 35 additions and 16 deletions

View File

@@ -57,6 +57,7 @@ namespace OpenRA.Network
public int Team; public int Team;
public string Slot; // slot ID, or null for observer public string Slot; // slot ID, or null for observer
public string Bot; // Bot type, null for real clients public string Bot; // Bot type, null for real clients
public int BotControllerClientIndex; // who added the bot to the slot
public bool IsAdmin; public bool IsAdmin;
public bool IsReady { get { return State == ClientState.Ready; } } public bool IsReady { get { return State == ClientState.Ready; } }
public bool IsObserver { get { return Slot == null; } } public bool IsObserver { get { return Slot == null; } }

View File

@@ -528,9 +528,11 @@ namespace OpenRA.Server
SendDisconnected(toDrop); /* Report disconnection */ SendDisconnected(toDrop); /* Report disconnection */
lobbyInfo.Clients.RemoveAll(c => c.Index == toDrop.PlayerIndex); lobbyInfo.Clients.RemoveAll(c => c.Index == toDrop.PlayerIndex);
// remove the bots he added
lobbyInfo.Clients.RemoveAll(c => c.BotControllerClientIndex == toDrop.PlayerIndex);
// reassign admin if necessary // reassign admin if necessary
if ( lobbyInfo.GlobalSettings.Dedicated && dropClient.IsAdmin && State == ServerState.WaitingPlayers) if (lobbyInfo.GlobalSettings.Dedicated && dropClient.IsAdmin && State == ServerState.WaitingPlayers)
{ {
if (lobbyInfo.Clients.Where(c1 => c1.Bot == null).Count() > 0) if (lobbyInfo.Clients.Where(c1 => c1.Bot == null).Count() > 0)
{ {
@@ -545,7 +547,7 @@ namespace OpenRA.Server
if (conns.Count != 0 || lobbyInfo.GlobalSettings.Dedicated) if (conns.Count != 0 || lobbyInfo.GlobalSettings.Dedicated)
SyncLobbyInfo(); SyncLobbyInfo();
if ( !lobbyInfo.GlobalSettings.Dedicated && dropClient.IsAdmin ) if (!lobbyInfo.GlobalSettings.Dedicated && dropClient.IsAdmin)
Shutdown(); Shutdown();
} }

View File

@@ -31,8 +31,7 @@ namespace OpenRA.Traits
return false; return false;
} }
// Hack: Assumes bots always run on clientId 0. var isBotOrder = subjectClient.Bot != null && clientId == subjectClient.BotControllerClientIndex;
var isBotOrder = subjectClient.Bot != null && clientId == 0;
// Drop exploiting orders // Drop exploiting orders
if (subjectClientId != clientId && !isBotOrder) if (subjectClientId != clientId && !isBotOrder)

View File

@@ -104,7 +104,11 @@ namespace OpenRA.Mods.RA.Server
s => s =>
{ {
int lag; int lag;
if (!int.TryParse(s, out lag)) { Log.Write("server", "Invalid order lag: {0}", s); return false; } if (!int.TryParse(s, out lag))
{
Log.Write("server", "Invalid order lag: {0}", s);
return false;
}
Log.Write("server", "Order lag is now {0} frames.", lag); Log.Write("server", "Order lag is now {0} frames.", lag);
@@ -190,23 +194,29 @@ namespace OpenRA.Mods.RA.Server
{ {
var parts = s.Split(' '); var parts = s.Split(' ');
if (parts.Length < 2) if (parts.Length < 3)
{ {
server.SendChatTo( conn, "Malformed slot_bot command" ); server.SendChatTo(conn, "Malformed slot_bot command");
return true; return true;
} }
if (!ValidateSlotCommand( server, conn, client, parts[0], true )) if (!ValidateSlotCommand(server, conn, client, parts[0], true))
return false; return false;
var slot = server.lobbyInfo.Slots[parts[0]]; var slot = server.lobbyInfo.Slots[parts[0]];
var bot = server.lobbyInfo.ClientInSlot(parts[0]); var bot = server.lobbyInfo.ClientInSlot(parts[0]);
var botType = parts.Skip(1).JoinWith(" "); int controllerClientIndex;
if (!int.TryParse(parts[1], out controllerClientIndex))
{
Log.Write("server", "Invalid bot controller client index: {0}", parts[1]);
return false;
}
var botType = parts.Skip(2).JoinWith(" ");
// Invalid slot // Invalid slot
if (bot != null && bot.Bot == null) if (bot != null && bot.Bot == null)
{ {
server.SendChatTo( conn, "Can't add bots to a slot with another client" ); server.SendChatTo(conn, "Can't add bots to a slot with another client");
return true; return true;
} }
@@ -223,7 +233,8 @@ namespace OpenRA.Mods.RA.Server
Country = "random", Country = "random",
SpawnPoint = 0, SpawnPoint = 0,
Team = 0, Team = 0,
State = Session.ClientState.NotReady State = Session.ClientState.NotReady,
BotControllerClientIndex = controllerClientIndex
}; };
// pick a random color for the bot // pick a random color for the bot
@@ -410,7 +421,7 @@ namespace OpenRA.Mods.RA.Server
} }
int clientID; int clientID;
int.TryParse( s, out clientID ); int.TryParse(s, out clientID);
var connToKick = server.conns.SingleOrDefault( c => server.GetClient(c) != null && server.GetClient(c).Index == clientID); var connToKick = server.conns.SingleOrDefault( c => server.GetClient(c) != null && server.GetClient(c).Index == clientID);
if (connToKick == null) if (connToKick == null)
@@ -465,7 +476,11 @@ namespace OpenRA.Mods.RA.Server
return true; return true;
int team; int team;
if (!int.TryParse(parts[1], out team)) { Log.Write("server", "Invalid team: {0}", s ); return false; } if (!int.TryParse(parts[1], out team))
{
Log.Write("server", "Invalid team: {0}", s );
return false;
}
targetClient.Team = team; targetClient.Team = team;
server.SyncLobbyInfo(); server.SyncLobbyInfo();
@@ -546,7 +561,7 @@ namespace OpenRA.Mods.RA.Server
static Session.Slot MakeSlotFromPlayerReference(PlayerReference pr) static Session.Slot MakeSlotFromPlayerReference(PlayerReference pr)
{ {
if (!pr.Playable) return null; if (!pr.Playable) return null;
if (Game.Settings.Server.LockBots || Game.Settings.Server.Dedicated) if (Game.Settings.Server.LockBots)
pr.AllowBots = false; pr.AllowBots = false;
return new Session.Slot return new Session.Slot
{ {

View File

@@ -287,8 +287,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic
{ {
var slot = orderManager.LobbyInfo.FirstEmptySlot(); var slot = orderManager.LobbyInfo.FirstEmptySlot();
var bot = Rules.Info["player"].Traits.WithInterface<IBotInfo>().Select(t => t.Name).FirstOrDefault(); var bot = Rules.Info["player"].Traits.WithInterface<IBotInfo>().Select(t => t.Name).FirstOrDefault();
var botController = orderManager.LobbyInfo.Clients.Where(c => c.IsAdmin).FirstOrDefault();
if (slot != null && bot != null) if (slot != null && bot != null)
orderManager.IssueOrder(Order.Command("slot_bot {0} {1}".F(slot, bot))); orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot, botController.Index, bot)));
}); });
} }

View File

@@ -71,8 +71,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic
foreach (var b in Rules.Info["player"].Traits.WithInterface<IBotInfo>().Select(t => t.Name)) foreach (var b in Rules.Info["player"].Traits.WithInterface<IBotInfo>().Select(t => t.Name))
{ {
var bot = b; var bot = b;
var botController = orderManager.LobbyInfo.Clients.Where(c => c.IsAdmin).FirstOrDefault();
options.Add(new SlotDropDownOption("Bot: {0}".F(bot), options.Add(new SlotDropDownOption("Bot: {0}".F(bot),
"slot_bot {0} {1}".F(slot.PlayerReference, bot), "slot_bot {0} {1} {2}".F(slot.PlayerReference, botController.Index, bot),
() => client != null && client.Bot == bot)); () => client != null && client.Bot == bot));
} }