Add a 'Shutting down' state to the gameserver.
Tell the masterserver about it, so it can quickly remove games from the list when they are finished, rather than waiting for the 5 minute TTL to expire.
This commit is contained in:
committed by
Chris Forbes
parent
3a77082c66
commit
0c104cfc3a
@@ -313,7 +313,8 @@ namespace OpenRA
|
||||
{
|
||||
System.Threading.Thread.Sleep(100);
|
||||
|
||||
if((server.GameStarted)&&(server.conns.Count<=1))
|
||||
if((server.State == Server.ServerState.GameStarted)
|
||||
&& (server.conns.Count<=1))
|
||||
{
|
||||
Console.WriteLine("No one is playing, shutting down...");
|
||||
server.Shutdown();
|
||||
|
||||
@@ -26,6 +26,13 @@ using XTimer = System.Timers.Timer;
|
||||
|
||||
namespace OpenRA.Server
|
||||
{
|
||||
public enum ServerState : int
|
||||
{
|
||||
WaitingPlayers = 1,
|
||||
GameStarted = 2,
|
||||
ShuttingDown = 3
|
||||
}
|
||||
|
||||
public class Server
|
||||
{
|
||||
// Valid player connections
|
||||
@@ -40,7 +47,7 @@ namespace OpenRA.Server
|
||||
|
||||
TypeDictionary ServerTraits = new TypeDictionary();
|
||||
public Session lobbyInfo;
|
||||
public bool GameStarted = false;
|
||||
|
||||
public readonly IPAddress Ip;
|
||||
public readonly int Port;
|
||||
int randomSeed;
|
||||
@@ -51,16 +58,31 @@ namespace OpenRA.Server
|
||||
public Map Map;
|
||||
XTimer gameTimeout;
|
||||
|
||||
volatile bool shutdown = false;
|
||||
protected volatile ServerState pState = new ServerState();
|
||||
public ServerState State
|
||||
{
|
||||
get { return pState; }
|
||||
protected set { pState = value; }
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
{
|
||||
shutdown = true;
|
||||
State = ServerState.ShuttingDown;
|
||||
}
|
||||
|
||||
public void EndGame()
|
||||
{
|
||||
foreach (var t in ServerTraits.WithInterface<IEndGame>())
|
||||
t.GameEnded(this);
|
||||
if (Settings.AllowUPnP)
|
||||
RemovePortforward();
|
||||
}
|
||||
|
||||
public Server(IPEndPoint endpoint, string[] mods, ServerSettings settings, ModData modData)
|
||||
{
|
||||
Log.AddChannel("server", "server.log");
|
||||
|
||||
pState = ServerState.WaitingPlayers;
|
||||
listener = new TcpListener(endpoint);
|
||||
listener.Start();
|
||||
var localEndpoint = (IPEndPoint)listener.LocalEndpoint;
|
||||
@@ -140,10 +162,9 @@ namespace OpenRA.Server
|
||||
foreach( var c in preConns ) checkRead.Add( c.socket );
|
||||
|
||||
Socket.Select( checkRead, null, null, timeout );
|
||||
if (shutdown)
|
||||
if (State == ServerState.ShuttingDown)
|
||||
{
|
||||
if (Settings.AllowUPnP)
|
||||
RemovePortforward();
|
||||
EndGame();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -159,15 +180,13 @@ namespace OpenRA.Server
|
||||
foreach (var t in ServerTraits.WithInterface<ITick>())
|
||||
t.Tick(this);
|
||||
|
||||
if (shutdown)
|
||||
if (State == ServerState.ShuttingDown)
|
||||
{
|
||||
if (Settings.AllowUPnP)
|
||||
RemovePortforward();
|
||||
EndGame();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GameStarted = false;
|
||||
foreach (var t in ServerTraits.WithInterface<INotifyServerShutdown>())
|
||||
t.ServerShutdown(this);
|
||||
|
||||
@@ -245,7 +264,7 @@ namespace OpenRA.Server
|
||||
{
|
||||
try
|
||||
{
|
||||
if (GameStarted)
|
||||
if (State == ServerState.GameStarted)
|
||||
{
|
||||
Log.Write("server", "Rejected connection from {0}; game is already started.",
|
||||
newConn.socket.RemoteEndPoint);
|
||||
@@ -498,13 +517,13 @@ namespace OpenRA.Server
|
||||
|
||||
OpenRA.Network.Session.Client dropClient = lobbyInfo.Clients.Where(c1 => c1.Index == toDrop.PlayerIndex).Single();
|
||||
|
||||
if (GameStarted)
|
||||
if (State == ServerState.GameStarted)
|
||||
SendDisconnected(toDrop); /* Report disconnection */
|
||||
|
||||
lobbyInfo.Clients.RemoveAll(c => c.Index == toDrop.PlayerIndex);
|
||||
|
||||
// reassign admin if necessary
|
||||
if ( lobbyInfo.GlobalSettings.Dedicated && dropClient.IsAdmin && !GameStarted)
|
||||
if ( lobbyInfo.GlobalSettings.Dedicated && dropClient.IsAdmin && State == ServerState.WaitingPlayers)
|
||||
{
|
||||
if (lobbyInfo.Clients.Where(c1 => c1.Bot == null).Count() > 0)
|
||||
{
|
||||
@@ -530,7 +549,7 @@ namespace OpenRA.Server
|
||||
|
||||
public void SyncLobbyInfo()
|
||||
{
|
||||
if (!GameStarted) /* don't do this while the game is running, it breaks things. */
|
||||
if (State != ServerState.GameStarted) /* don't do this while the game is running, it breaks things. */
|
||||
DispatchOrders(null, 0,
|
||||
new ServerOrder("SyncInfo", lobbyInfo.Serialize()).Serialize());
|
||||
|
||||
@@ -540,7 +559,7 @@ namespace OpenRA.Server
|
||||
|
||||
public void StartGame()
|
||||
{
|
||||
GameStarted = true;
|
||||
State = ServerState.GameStarted;
|
||||
listener.Stop();
|
||||
|
||||
Console.WriteLine("Game started");
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace OpenRA.Server
|
||||
public interface INotifyServerShutdown { void ServerShutdown(Server server); }
|
||||
public interface IStartGame { void GameStarted(Server server); }
|
||||
public interface IClientJoined { void ClientJoined(Server server, Connection conn); }
|
||||
public interface IEndGame { void GameEnded(Server server); }
|
||||
public interface ITick
|
||||
{
|
||||
void Tick(Server server);
|
||||
@@ -28,7 +29,7 @@ namespace OpenRA.Server
|
||||
|
||||
public abstract class ServerTrait {}
|
||||
|
||||
public class DebugServerTrait : ServerTrait, IInterpretCommand, IStartGame, INotifySyncLobbyInfo, INotifyServerStart, INotifyServerShutdown
|
||||
public class DebugServerTrait : ServerTrait, IInterpretCommand, IStartGame, INotifySyncLobbyInfo, INotifyServerStart, INotifyServerShutdown, IEndGame
|
||||
{
|
||||
public bool InterpretCommand(Server server, Connection conn, Session.Client client, string cmd)
|
||||
{
|
||||
@@ -55,5 +56,10 @@ namespace OpenRA.Server
|
||||
{
|
||||
Console.WriteLine("ServerShutdown()");
|
||||
}
|
||||
|
||||
public void GameEnded(Server server)
|
||||
{
|
||||
Console.WriteLine("GameEnded()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.RA.Server
|
||||
|
||||
public static bool ValidateCommand(S server, Connection conn, Session.Client client, string cmd)
|
||||
{
|
||||
if (server.GameStarted)
|
||||
if (server.State == ServerState.GameStarted)
|
||||
{
|
||||
server.SendChatTo(conn, "Cannot change state when game started. ({0})".F(cmd));
|
||||
return false;
|
||||
|
||||
@@ -17,7 +17,7 @@ using S = OpenRA.Server.Server;
|
||||
|
||||
namespace OpenRA.Mods.RA.Server
|
||||
{
|
||||
public class MasterServerPinger : ServerTrait, ITick, INotifySyncLobbyInfo, IStartGame
|
||||
public class MasterServerPinger : ServerTrait, ITick, INotifySyncLobbyInfo, IStartGame, IEndGame
|
||||
{
|
||||
const int MasterPingInterval = 60 * 3; // 3 minutes. server has a 5 minute TTL for games, so give ourselves a bit
|
||||
// of leeway.
|
||||
@@ -36,6 +36,7 @@ namespace OpenRA.Mods.RA.Server
|
||||
|
||||
public void LobbyInfoSynced(S server) { PingMasterServer(server); }
|
||||
public void GameStarted(S server) { PingMasterServer(server); }
|
||||
public void GameEnded(S server) { PingMasterServer(server); }
|
||||
|
||||
int lastPing = 0;
|
||||
bool isInitialPing = true;
|
||||
@@ -60,10 +61,11 @@ namespace OpenRA.Mods.RA.Server
|
||||
using (var wc = new WebClient())
|
||||
{
|
||||
wc.Proxy = null;
|
||||
|
||||
wc.DownloadData(
|
||||
server.Settings.MasterServer + url.F(
|
||||
server.Settings.ExternalPort, Uri.EscapeUriString(server.Settings.Name),
|
||||
server.GameStarted ? 2 : 1, // todo: post-game states, etc.
|
||||
(int) server.State,
|
||||
server.lobbyInfo.Clients.Count,
|
||||
Game.CurrentMods.Select(f => "{0}@{1}".F(f.Key, f.Value.Version)).JoinWith(","),
|
||||
server.lobbyInfo.GlobalSettings.Map,
|
||||
|
||||
Reference in New Issue
Block a user