Kick clients who don't have the map when the host force-starts.
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user