Kick clients who don't have the map when the host force-starts.

This commit is contained in:
Paul Chote
2014-03-13 17:07:41 +13:00
parent f5f84244eb
commit fcb3d7347a
6 changed files with 41 additions and 18 deletions

View File

@@ -81,7 +81,7 @@ namespace OpenRA.Network
get { return Clients.Count(c => c.Bot == null) == 1; } get { return Clients.Count(c => c.Bot == null) == 1; }
} }
public enum ClientState { NotReady, Ready, Disconnected = 1000 } public enum ClientState { NotReady, Invalid, Ready, Disconnected = 1000 }
public class Client public class Client
{ {
@@ -93,13 +93,14 @@ namespace OpenRA.Network
public int SpawnPoint; public int SpawnPoint;
public string Name; public string Name;
public string IpAddress; public string IpAddress;
public ClientState State; public ClientState State = ClientState.Invalid;
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 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 IsInvalid { get { return State == ClientState.Invalid; } }
public bool IsObserver { get { return Slot == null; } } public bool IsObserver { get { return Slot == null; } }
public int Latency = -1; public int Latency = -1;
public int LatencyJitter = -1; public int LatencyJitter = -1;

View File

@@ -130,7 +130,7 @@ namespace OpenRA.Network
Country = "random", Country = "random",
SpawnPoint = 0, SpawnPoint = 0,
Team = 0, Team = 0,
State = Session.ClientState.NotReady State = Session.ClientState.Invalid
}; };
var response = new HandshakeResponse() var response = new HandshakeResponse()

View File

@@ -272,7 +272,7 @@ namespace OpenRA.Server
Country = "random", Country = "random",
SpawnPoint = 0, SpawnPoint = 0,
Team = 0, Team = 0,
State = Session.ClientState.NotReady, State = Session.ClientState.Invalid,
IsAdmin = !LobbyInfo.Clients.Any(c1 => c1.IsAdmin) IsAdmin = !LobbyInfo.Clients.Any(c1 => c1.IsAdmin)
}; };
@@ -572,19 +572,31 @@ namespace OpenRA.Server
public void StartGame() public void StartGame()
{ {
State = ServerState.GameStarted;
listener.Stop(); listener.Stop();
Console.WriteLine("Game started"); Console.WriteLine("Game started");
foreach (var c in Conns)
foreach (var d in Conns)
DispatchOrdersToClient(c, d.PlayerIndex, 0x7FFFFFFF, new byte[] { 0xBF });
// Drop any unvalidated clients // Drop any unvalidated clients
foreach (var c in PreConns.ToArray()) foreach (var c in PreConns.ToArray())
DropClient(c); DropClient(c);
// Drop any players who are not ready
foreach (var c in Conns.ToArray())
{
if (GetClient(c).IsInvalid)
{
SendOrderTo(c, "ServerError", "You have been kicked from the server");
DropClient(c);
}
}
SyncLobbyInfo();
State = ServerState.GameStarted;
foreach (var c in Conns)
foreach (var d in Conns)
DispatchOrdersToClient(c, d.PlayerIndex, 0x7FFFFFFF, new byte[] { 0xBF });
DispatchOrders(null, 0, DispatchOrders(null, 0,
new ServerOrder("StartGame", "").Serialize()); new ServerOrder("StartGame", "").Serialize());

View File

@@ -44,7 +44,7 @@ namespace OpenRA.Mods.RA.Server
server.SendOrderTo(conn, "Message", "Cannot change state when game started. ({0})".F(cmd)); server.SendOrderTo(conn, "Message", "Cannot change state when game started. ({0})".F(cmd));
return false; return false;
} }
else if (client.State == Session.ClientState.Ready && !(cmd == "ready" || cmd == "startgame")) else if (client.State == Session.ClientState.Ready && !(cmd.StartsWith("state") || cmd == "startgame"))
{ {
server.SendOrderTo(conn, "Message", "Cannot change state when marked as ready."); server.SendOrderTo(conn, "Message", "Cannot change state when marked as ready.");
return false; return false;
@@ -75,14 +75,17 @@ namespace OpenRA.Mods.RA.Server
var dict = new Dictionary<string, Func<string, bool>> var dict = new Dictionary<string, Func<string, bool>>
{ {
{ "ready", { "state",
s => s =>
{ {
// if we're downloading, we can't ready up. var state = Session.ClientState.Invalid;
if (client.State == Session.ClientState.NotReady) if (!Enum<Session.ClientState>.TryParse(s, false, out state))
client.State = Session.ClientState.Ready; {
else if (client.State == Session.ClientState.Ready) server.SendOrderTo(conn, "Message", "Malformed state command");
client.State = Session.ClientState.NotReady; return true;
}
client.State = state;
Log.Write("server", "Player @{0} is {1}", Log.Write("server", "Player @{0} is {1}",
conn.socket.RemoteEndPoint, client.State); conn.socket.RemoteEndPoint, client.State);
@@ -290,6 +293,10 @@ namespace OpenRA.Mods.RA.Server
LoadMap(server); LoadMap(server);
SetDefaultDifficulty(server); SetDefaultDifficulty(server);
// Reset client states
foreach (var c in server.LobbyInfo.Clients)
c.State = Session.ClientState.Invalid;
// Reassign players into new slots based on their old slots: // Reassign players into new slots based on their old slots:
// - Observers remain as observers // - Observers remain as observers
// - Players who now lack a slot are made observers // - Players who now lack a slot are made observers
@@ -303,7 +310,6 @@ namespace OpenRA.Mods.RA.Server
continue; continue;
c.SpawnPoint = 0; c.SpawnPoint = 0;
c.State = Session.ClientState.NotReady;
c.Slot = i < slots.Length ? slots[i++] : null; c.Slot = i < slots.Length ? slots[i++] : null;
if (c.Slot != null) if (c.Slot != null)
{ {

View File

@@ -530,6 +530,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic
if (Map.Status == MapStatus.Available) if (Map.Status == MapStatus.Available)
{ {
// Tell the server that we have the map
orderManager.IssueOrder(Order.Command("state {0}".F(Session.ClientState.NotReady)));
// Restore default starting cash if the last map set it to something invalid // Restore default starting cash if the last map set it to something invalid
var pri = Rules.Info["player"].Traits.Get<PlayerResourcesInfo>(); var pri = Rules.Info["player"].Traits.Get<PlayerResourcesInfo>();
if (!Map.Map.Options.StartingCash.HasValue && !pri.SelectableCash.Contains(orderManager.LobbyInfo.GlobalSettings.StartingCash)) if (!Map.Map.Options.StartingCash.HasValue && !pri.SelectableCash.Contains(orderManager.LobbyInfo.GlobalSettings.StartingCash))

View File

@@ -383,7 +383,8 @@ namespace OpenRA.Mods.RA.Widgets.Logic
status.IsVisible = () => true; status.IsVisible = () => true;
status.IsDisabled = () => c.Bot != null || map.Status != MapStatus.Available; status.IsDisabled = () => c.Bot != null || map.Status != MapStatus.Available;
status.OnClick = () => orderManager.IssueOrder(Order.Command("ready")); var state = orderManager.LocalClient.IsReady ? Session.ClientState.NotReady : Session.ClientState.Ready;
status.OnClick = () => orderManager.IssueOrder(Order.Command("state {0}".F(state)));
} }
public static void SetupReadyWidget(Widget parent, Session.Slot s, Session.Client c) public static void SetupReadyWidget(Widget parent, Session.Slot s, Session.Client c)