Added: Dedicated server support
Added: The ability to not render anything when using the client as a dedicated server Added: The basic server extension (NullServerExtension) Exposed: Made some fields public, so that the server extension can access it
This commit is contained in:
@@ -245,6 +245,28 @@ namespace OpenRA
|
||||
|
||||
modData = new ModData( mods );
|
||||
|
||||
// when this client is running in dedicated mode ...
|
||||
if (Settings.Server.IsDedicated)
|
||||
{
|
||||
// it may specify a yaml extension file (to add non synced traits)
|
||||
if (!string.IsNullOrEmpty(Settings.Server.ExtensionYaml))
|
||||
{
|
||||
var r = modData.Manifest.LocalRules.ToList();
|
||||
r.Add(Settings.Server.ExtensionYaml);
|
||||
modData.Manifest.LocalRules = r.ToArray();
|
||||
}
|
||||
// and a dll to the assemblies (to add those non synced traits)
|
||||
if (!string.IsNullOrEmpty(Settings.Server.ExtensionDll))
|
||||
{
|
||||
var r = modData.Manifest.LocalAssemblies.ToList();
|
||||
r.Add(Settings.Server.ExtensionDll);
|
||||
modData.Manifest.LocalAssemblies = r.ToArray();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Settings.Server.ExtensionClass))
|
||||
Settings.Server.Extension = modData.ObjectCreator.CreateObject<IServerExtension>(Settings.Server.ExtensionClass);
|
||||
}
|
||||
|
||||
Sound.Initialize();
|
||||
PerfHistory.items["render"].hasNormalTick = false;
|
||||
PerfHistory.items["batches"].hasNormalTick = false;
|
||||
@@ -252,38 +274,108 @@ namespace OpenRA
|
||||
PerfHistory.items["cursor"].hasNormalTick = false;
|
||||
|
||||
|
||||
JoinLocal();
|
||||
StartGame(modData.Manifest.ShellmapUid);
|
||||
|
||||
Game.ConnectionStateChanged += orderManager =>
|
||||
if (!Settings.Graphics.UseNullRenderer)
|
||||
{
|
||||
Widget.CloseWindow();
|
||||
switch( orderManager.Connection.ConnectionState )
|
||||
{
|
||||
case ConnectionState.PreConnecting:
|
||||
Widget.OpenWindow("MAINMENU_BG");
|
||||
break;
|
||||
case ConnectionState.Connecting:
|
||||
Widget.OpenWindow( "CONNECTING_BG",
|
||||
new Dictionary<string, object> { { "host", orderManager.Host }, { "port", orderManager.Port } } );
|
||||
break;
|
||||
case ConnectionState.NotConnected:
|
||||
Widget.OpenWindow( "CONNECTION_FAILED_BG",
|
||||
new Dictionary<string, object> { { "host", orderManager.Host }, { "port", orderManager.Port } } );
|
||||
break;
|
||||
case ConnectionState.Connected:
|
||||
var lobby = Widget.OpenWindow( "SERVER_LOBBY", new Dictionary<string, object> { { "orderManager", orderManager } } );
|
||||
lobby.GetWidget<ChatDisplayWidget>("CHAT_DISPLAY").ClearChat();
|
||||
lobby.GetWidget("CHANGEMAP_BUTTON").Visible = true;
|
||||
lobby.GetWidget("LOCKTEAMS_CHECKBOX").Visible = true;
|
||||
lobby.GetWidget("DISCONNECT_BUTTON").Visible = true;
|
||||
//r.GetWidget("INGAME_ROOT").GetWidget<ChatDisplayWidget>("CHAT_DISPLAY").ClearChat();
|
||||
break;
|
||||
}
|
||||
};
|
||||
JoinLocal();
|
||||
StartGame(modData.Manifest.ShellmapUid);
|
||||
|
||||
modData.WidgetLoader.LoadWidget( new Dictionary<string,object>(), Widget.RootWidget, "PERF_BG" );
|
||||
Widget.OpenWindow("MAINMENU_BG");
|
||||
Game.ConnectionStateChanged += om =>
|
||||
{
|
||||
Widget.CloseWindow();
|
||||
switch (om.Connection.ConnectionState)
|
||||
{
|
||||
case ConnectionState.PreConnecting:
|
||||
Widget.OpenWindow("MAINMENU_BG");
|
||||
break;
|
||||
case ConnectionState.Connecting:
|
||||
Widget.OpenWindow("CONNECTING_BG",
|
||||
new Dictionary<string, object>
|
||||
{{"host", om.Host}, {"port", om.Port}});
|
||||
break;
|
||||
case ConnectionState.NotConnected:
|
||||
Widget.OpenWindow("CONNECTION_FAILED_BG",
|
||||
new Dictionary<string, object>
|
||||
{{"host", om.Host}, {"port", om.Port}});
|
||||
break;
|
||||
case ConnectionState.Connected:
|
||||
var lobby = Widget.OpenWindow("SERVER_LOBBY",
|
||||
new Dictionary<string, object>
|
||||
{{"orderManager", om}});
|
||||
lobby.GetWidget<ChatDisplayWidget>("CHAT_DISPLAY").ClearChat();
|
||||
lobby.GetWidget("CHANGEMAP_BUTTON").Visible = true;
|
||||
lobby.GetWidget("LOCKTEAMS_CHECKBOX").Visible = true;
|
||||
lobby.GetWidget("DISCONNECT_BUTTON").Visible = true;
|
||||
|
||||
// Inform whoever is willing to hear it that the player is connected to the lobby
|
||||
if (ConnectedToLobby != null)
|
||||
ConnectedToLobby();
|
||||
|
||||
if (Settings.Server.IsDedicated)
|
||||
{
|
||||
// Force spectator as a default
|
||||
Game.orderManager.IssueOrder(Order.Command("spectator"));
|
||||
}
|
||||
|
||||
if (Game.Settings.Server.Extension != null)
|
||||
Game.Settings.Server.Extension.OnLobbyUp();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
modData.WidgetLoader.LoadWidget(new Dictionary<string, object>(), Widget.RootWidget, "PERF_BG");
|
||||
Widget.OpenWindow("MAINMENU_BG");
|
||||
}else
|
||||
{
|
||||
JoinLocal();
|
||||
StartGame(modData.Manifest.ShellmapUid);
|
||||
|
||||
Game.ConnectionStateChanged += om =>
|
||||
{
|
||||
Widget.CloseWindow();
|
||||
switch (om.Connection.ConnectionState)
|
||||
{
|
||||
case ConnectionState.PreConnecting:
|
||||
Widget.OpenWindow("MAINMENU_BG");
|
||||
break;
|
||||
case ConnectionState.Connecting:
|
||||
Widget.OpenWindow("CONNECTING_BG",
|
||||
new Dictionary<string, object> { { "host", om.Host }, { "port", om.Port } });
|
||||
break;
|
||||
case ConnectionState.NotConnected:
|
||||
Widget.OpenWindow("CONNECTION_FAILED_BG",
|
||||
new Dictionary<string, object> { { "host", om.Host }, { "port", om.Port } });
|
||||
break;
|
||||
case ConnectionState.Connected:
|
||||
var lobby = Widget.OpenWindow("SERVER_LOBBY",
|
||||
new Dictionary<string, object> { { "orderManager", om } });
|
||||
|
||||
// Inform whoever is willing to hear it that the player is connected to the lobby
|
||||
if (ConnectedToLobby != null)
|
||||
ConnectedToLobby();
|
||||
|
||||
if (Settings.Server.IsDedicated)
|
||||
{
|
||||
// Force spectator as a default
|
||||
Game.orderManager.IssueOrder(Order.Command("spectator"));
|
||||
}
|
||||
|
||||
if (Game.Settings.Server.Extension != null)
|
||||
Game.Settings.Server.Extension.OnLobbyUp();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
modData.WidgetLoader.LoadWidget(new Dictionary<string, object>(), Widget.RootWidget, "PERF_BG");
|
||||
Widget.OpenWindow("MAINMENU_BG");
|
||||
}
|
||||
|
||||
if (Settings.Server.IsDedicated)
|
||||
{
|
||||
// Auto-host
|
||||
var map = Game.modData.AvailableMaps.FirstOrDefault(m => m.Value.Selectable).Key;
|
||||
Server.Server.ServerMain(Game.modData, Settings, map);
|
||||
Game.JoinServer(IPAddress.Loopback.ToString(), Settings.Server.ListenPort);
|
||||
}
|
||||
|
||||
Game.orderManager.LastTickTime = Environment.TickCount;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,13 @@ namespace OpenRA.GameRules
|
||||
public bool AdvertiseOnline = true;
|
||||
public string MasterServer = "http://master.open-ra.org/";
|
||||
public bool AllowCheats = false;
|
||||
public string ExtensionDll = "";
|
||||
public string ExtensionClass = "";
|
||||
|
||||
/* not storeable */
|
||||
public IServerExtension Extension { get; set; }
|
||||
public string ExtensionYaml { get; set; }
|
||||
public bool IsDedicated { get; set; }
|
||||
}
|
||||
|
||||
public class DebugSettings
|
||||
@@ -38,9 +45,12 @@ namespace OpenRA.GameRules
|
||||
public class GraphicSettings
|
||||
{
|
||||
public WindowMode Mode = WindowMode.PseudoFullscreen;
|
||||
public int2 FullscreenSize = new int2(Screen.PrimaryScreen.Bounds.Width,Screen.PrimaryScreen.Bounds.Height);
|
||||
public int2 WindowedSize = new int2(1024,768);
|
||||
public int2 FullscreenSize = new int2(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
|
||||
public int2 WindowedSize = new int2(1024, 768);
|
||||
public readonly int2 MinResolution = new int2(800, 600);
|
||||
public readonly string RenderEngine = "OpenRA.Gl.dll";
|
||||
public readonly string NullRenderEngine = "OpenRA.Renderer.Null.dll";
|
||||
public bool UseNullRenderer { get; set; }
|
||||
}
|
||||
|
||||
public class SoundSettings
|
||||
@@ -103,6 +113,11 @@ namespace OpenRA.GameRules
|
||||
{"Debug", Debug}
|
||||
};
|
||||
|
||||
// Should we run in dedicated mode (use the server extension)
|
||||
Server.IsDedicated = args.GetValue("Server.IsDedicated", false);
|
||||
if (Server.IsDedicated)
|
||||
Graphics.UseNullRenderer = args.GetValue("Graphics.UseNullRenderer", false);
|
||||
|
||||
// Override fieldloader to ignore invalid entries
|
||||
var err1 = FieldLoader.UnknownFieldAction;
|
||||
var err2 = FieldLoader.InvalidValueAction;
|
||||
|
||||
@@ -135,7 +135,11 @@ namespace OpenRA.Graphics
|
||||
internal static void Initialize( OpenRA.FileFormats.Graphics.WindowMode windowMode )
|
||||
{
|
||||
var resolution = GetResolution( windowMode );
|
||||
device = CreateDevice( Assembly.LoadFile( Path.GetFullPath( "OpenRA.Gl.dll" ) ), resolution.Width, resolution.Height, windowMode, false );
|
||||
|
||||
if (Game.Settings.Graphics.UseNullRenderer)
|
||||
device = CreateDevice(Assembly.LoadFile(Path.GetFullPath(Game.Settings.Graphics.NullRenderEngine)), resolution.Width, resolution.Height, windowMode, false);
|
||||
else
|
||||
device = CreateDevice( Assembly.LoadFile( Path.GetFullPath( Game.Settings.Graphics.RenderEngine ) ), resolution.Width, resolution.Height, windowMode, false );
|
||||
}
|
||||
|
||||
static Size GetResolution(WindowMode windowmode)
|
||||
|
||||
176
OpenRA.Game/Misc.cs
Normal file
176
OpenRA.Game/Misc.cs
Normal file
@@ -0,0 +1,176 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRA.Network;
|
||||
using OpenRA.Server;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
public interface IServerExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// Return true to use the build-in handling
|
||||
/// </summary>
|
||||
bool OnReadyUp(Connection conn, Session.Client client);
|
||||
void OnStartGame();
|
||||
/// <summary>
|
||||
/// Return true to use the build-in handling
|
||||
/// </summary>
|
||||
bool OnNickChange(Connection conn, Session.Client client, string newName);
|
||||
|
||||
/// <summary>
|
||||
/// Return true to use the build-in handling
|
||||
/// </summary>
|
||||
bool OnRaceChange(Connection conn, Session.Client client, string newRace);
|
||||
|
||||
/// <summary>
|
||||
/// Return true to use the build-in handling
|
||||
/// </summary>
|
||||
bool OnSlotChange(Connection conn, Session.Client client, Session.Slot slot, Map map);
|
||||
|
||||
/// <summary>
|
||||
/// Return true to use the build-in handling
|
||||
/// </summary>
|
||||
bool OnTeamChange(Connection conn, Session.Client getClient, int team);
|
||||
|
||||
/// <summary>
|
||||
/// Return true to use the build-in handling
|
||||
/// </summary>
|
||||
bool OnSpawnpointChange(Connection conn, Session.Client getClient, int spawnPoint);
|
||||
|
||||
/// <summary>
|
||||
/// Return true to use the build-in handling
|
||||
/// </summary>
|
||||
bool OnColorChange(Connection conn, Session.Client getClient, Color fromArgb, Color color);
|
||||
|
||||
/// <summary>
|
||||
/// Return true to use the build-in handling
|
||||
/// </summary>
|
||||
bool OnChat(Connection conn, string message, bool teamChat);
|
||||
|
||||
void OnServerStart();
|
||||
void OnServerStop(bool forced);
|
||||
void OnLoadMap(Map map);
|
||||
|
||||
/// <summary>
|
||||
/// Return false to drop the connection
|
||||
/// </summary>
|
||||
bool OnValidateConnection(bool gameStarted, Connection newConn);
|
||||
|
||||
void OnLobbySync(Session lobbyInfo, bool gameStarted);
|
||||
/// <summary>
|
||||
/// Return true to use the build-in handling
|
||||
/// </summary>
|
||||
bool OnPingMasterServer(Session lobbyInfo, bool gameStarted);
|
||||
|
||||
/// <summary>
|
||||
/// Return true to use the build-in handling
|
||||
/// </summary>
|
||||
bool OnIngameChat(Session.Client client, string message, bool teamChat);
|
||||
|
||||
void OnIngameSetStance(Player player, Player stanceForPlayer, Stance newStance);
|
||||
|
||||
void OnLobbyUp();
|
||||
void OnRejoinLobby(World world);
|
||||
}
|
||||
|
||||
public class NullServerExtension : IServerExtension
|
||||
{
|
||||
public virtual bool OnReadyUp(Connection conn, Session.Client client)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void OnStartGame()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual bool OnNickChange(Connection conn, Session.Client client, string newName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool OnRaceChange(Connection conn, Session.Client client, string newRace)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool OnSlotChange(Connection conn, Session.Client client, Session.Slot slot, Map map)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool OnTeamChange(Connection conn, Session.Client getClient, int team)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool OnSpawnpointChange(Connection conn, Session.Client getClient, int spawnPoint)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool OnColorChange(Connection conn, Session.Client getClient, Color fromArgb, Color color)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool OnChat(Connection conn, string message, bool teamChat)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void OnServerStart()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnServerStop(bool forced)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void OnLoadMap(Map map)
|
||||
{
|
||||
// Good spot to manipulate amount of spectators! ie set Server.MaxSpectators
|
||||
}
|
||||
|
||||
public virtual bool OnValidateConnection(bool gameStarted, Connection newConn)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void OnLobbySync(Session lobbyInfo, bool gameStarted)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual bool OnPingMasterServer(Session lobbyInfo, bool gameStarted)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool OnIngameChat(Session.Client client, string message, bool teamChat)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void OnIngameSetStance(Player player, Player stanceForPlayer, Stance newStance)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void OnLobbyUp()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void OnRejoinLobby(World world)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,10 @@ namespace OpenRA.Network
|
||||
case "Chat":
|
||||
{
|
||||
var client = orderManager.LobbyInfo.ClientWithIndex( clientId );
|
||||
|
||||
if (Game.IsHost && Game.Settings.Server.Extension != null && !Game.Settings.Server.Extension.OnIngameChat(client, order.TargetString, false))
|
||||
break;
|
||||
|
||||
if (client != null)
|
||||
{
|
||||
var player = world != null ? world.FindPlayerByClient(client) : null;
|
||||
@@ -52,6 +56,10 @@ namespace OpenRA.Network
|
||||
case "TeamChat":
|
||||
{
|
||||
var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
|
||||
|
||||
if (Game.IsHost && Game.Settings.Server.Extension != null && !Game.Settings.Server.Extension.OnIngameChat(client, order.TargetString, true))
|
||||
break;
|
||||
|
||||
if (client != null)
|
||||
{
|
||||
if (world == null)
|
||||
@@ -98,9 +106,14 @@ namespace OpenRA.Network
|
||||
}
|
||||
case "SetStance":
|
||||
{
|
||||
|
||||
var targetPlayer = order.Player.World.players[order.TargetLocation.X];
|
||||
var newStance = (Stance)order.TargetLocation.Y;
|
||||
|
||||
if (Game.IsHost && Game.Settings.Server.Extension != null)
|
||||
Game.Settings.Server.Extension.OnIngameSetStance(order.Player, targetPlayer, newStance);
|
||||
|
||||
|
||||
SetPlayerStance(world, order.Player, targetPlayer, newStance);
|
||||
|
||||
// automatically declare war reciprocally
|
||||
|
||||
@@ -213,6 +213,7 @@
|
||||
</ProjectReference>
|
||||
<Compile Include="ActorInitializer.cs" />
|
||||
<Compile Include="ActorReference.cs" />
|
||||
<Compile Include="Misc.cs" />
|
||||
<Compile Include="ModData.cs" />
|
||||
<Compile Include="Map.cs" />
|
||||
<Compile Include="Network\FrameData.cs" />
|
||||
|
||||
@@ -15,20 +15,20 @@ using System.Net.Sockets;
|
||||
|
||||
namespace OpenRA.Server
|
||||
{
|
||||
class Connection
|
||||
public class Connection
|
||||
{
|
||||
public Socket socket;
|
||||
public List<byte> data = new List<byte>();
|
||||
public ReceiveState State = ReceiveState.Header;
|
||||
public int ExpectLength = 8;
|
||||
public int Frame = 0;
|
||||
internal Socket socket;
|
||||
internal List<byte> data = new List<byte>();
|
||||
internal ReceiveState State = ReceiveState.Header;
|
||||
internal int ExpectLength = 8;
|
||||
internal int Frame = 0;
|
||||
|
||||
public int MostRecentFrame = 0;
|
||||
internal int MostRecentFrame = 0;
|
||||
|
||||
/* client data */
|
||||
public int PlayerIndex;
|
||||
public int PlayerIndex { get; internal set; }
|
||||
|
||||
public byte[] PopBytes(int n)
|
||||
internal byte[] PopBytes(int n)
|
||||
{
|
||||
var result = data.GetRange(0, n);
|
||||
data.RemoveRange(0, n);
|
||||
@@ -65,7 +65,7 @@ namespace OpenRA.Server
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ReadData()
|
||||
internal void ReadData()
|
||||
{
|
||||
if (ReadDataInner())
|
||||
while (data.Count >= ExpectLength)
|
||||
|
||||
@@ -25,12 +25,17 @@ namespace OpenRA.Server
|
||||
{
|
||||
static class Server
|
||||
{
|
||||
public static Connection[] Connections
|
||||
{
|
||||
get { return conns.ToArray(); }
|
||||
}
|
||||
|
||||
static List<Connection> conns = new List<Connection>();
|
||||
static TcpListener listener = null;
|
||||
static Dictionary<int, List<Connection>> inFlightFrames
|
||||
= new Dictionary<int, List<Connection>>();
|
||||
static Session lobbyInfo;
|
||||
static bool GameStarted = false;
|
||||
internal static bool GameStarted = false;
|
||||
static string Name;
|
||||
static int ExternalPort;
|
||||
static int randomSeed;
|
||||
@@ -61,6 +66,9 @@ namespace OpenRA.Server
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
if (Game.Settings.Server.Extension != null)
|
||||
Game.Settings.Server.Extension.OnServerStop(true);
|
||||
}
|
||||
public static void ServerMain(ModData modData, Settings settings, string map)
|
||||
{
|
||||
@@ -69,6 +77,7 @@ namespace OpenRA.Server
|
||||
isInitialPing = true;
|
||||
Server.masterServerUrl = settings.Server.MasterServer;
|
||||
isInternetServer = settings.Server.AdvertiseOnline;
|
||||
|
||||
listener = new TcpListener(IPAddress.Any, settings.Server.ListenPort);
|
||||
Name = settings.Server.Name;
|
||||
ExternalPort = settings.Server.ExternalPort;
|
||||
@@ -98,6 +107,9 @@ namespace OpenRA.Server
|
||||
throw new InvalidOperationException( "Unable to start server: port is already in use" );
|
||||
}
|
||||
|
||||
if (Game.Settings.Server.Extension != null)
|
||||
Game.Settings.Server.Extension.OnServerStart();
|
||||
|
||||
new Thread( _ =>
|
||||
{
|
||||
for( ; ; )
|
||||
@@ -123,6 +135,9 @@ namespace OpenRA.Server
|
||||
{
|
||||
listener.Stop();
|
||||
GameStarted = false;
|
||||
|
||||
if (Game.Settings.Server.Extension != null)
|
||||
Game.Settings.Server.Extension.OnServerStop(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -151,6 +166,9 @@ namespace OpenRA.Server
|
||||
.Select((s, i) => { s.Index = i; return s; })
|
||||
.ToList();
|
||||
|
||||
if (Game.Settings.Server.Extension != null)
|
||||
Game.Settings.Server.Extension.OnLoadMap(Map);
|
||||
|
||||
// Generate slots for spectators
|
||||
for (int i = 0; i < MaxSpectators; i++)
|
||||
{
|
||||
@@ -302,7 +320,7 @@ namespace OpenRA.Server
|
||||
catch (NotImplementedException) { }
|
||||
}
|
||||
|
||||
static void SyncClientToPlayerReference(Session.Client c, PlayerReference pr)
|
||||
public static void SyncClientToPlayerReference(Session.Client c, PlayerReference pr)
|
||||
{
|
||||
if (pr == null)
|
||||
return;
|
||||
@@ -315,7 +333,7 @@ namespace OpenRA.Server
|
||||
c.Country = pr.Race;
|
||||
}
|
||||
|
||||
static bool InterpretCommand(Connection conn, string cmd)
|
||||
public static bool InterpretCommand(Connection conn, string cmd)
|
||||
{
|
||||
var dict = new Dictionary<string, Func<string, bool>>
|
||||
{
|
||||
@@ -335,8 +353,11 @@ namespace OpenRA.Server
|
||||
|
||||
SyncLobbyInfo();
|
||||
|
||||
if (conns.Count > 0 && conns.All(c => GetClient(c).State == Session.ClientState.Ready))
|
||||
InterpretCommand(conn, "startgame");
|
||||
if (Game.Settings.Server.Extension== null || Game.Settings.Server.Extension.OnReadyUp(conn, client))
|
||||
{
|
||||
if (conns.Count > 0 && conns.All(c => GetClient(c).State == Session.ClientState.Ready))
|
||||
InterpretCommand(conn, "startgame");
|
||||
}
|
||||
|
||||
return true;
|
||||
}},
|
||||
@@ -351,6 +372,8 @@ namespace OpenRA.Server
|
||||
DispatchOrders(null, 0,
|
||||
new ServerOrder("StartGame", "").Serialize());
|
||||
|
||||
if (Game.Settings.Server.Extension != null) Game.Settings.Server.Extension.OnStartGame();
|
||||
|
||||
PingMasterServer();
|
||||
return true;
|
||||
}},
|
||||
@@ -358,7 +381,11 @@ namespace OpenRA.Server
|
||||
s =>
|
||||
{
|
||||
Log.Write("server", "Player@{0} is now known as {1}", conn.socket.RemoteEndPoint, s);
|
||||
GetClient(conn).Name = s;
|
||||
|
||||
if (Game.Settings.Server.Extension == null || Game.Settings.Server.Extension.OnNickChange(conn, GetClient(conn), s))
|
||||
GetClient(conn).Name = s;
|
||||
|
||||
|
||||
SyncLobbyInfo();
|
||||
return true;
|
||||
}},
|
||||
@@ -377,6 +404,7 @@ namespace OpenRA.Server
|
||||
{ "race",
|
||||
s =>
|
||||
{
|
||||
if (Game.Settings.Server.Extension == null || Game.Settings.Server.Extension.OnRaceChange(conn, GetClient(conn), s))
|
||||
GetClient(conn).Country = s;
|
||||
|
||||
SyncLobbyInfo();
|
||||
@@ -391,9 +419,12 @@ namespace OpenRA.Server
|
||||
|
||||
var cl = GetClient(conn);
|
||||
|
||||
if (Game.Settings.Server.Extension == null || Game.Settings.Server.Extension.OnSlotChange(conn, cl, slotData, Map))
|
||||
{
|
||||
cl.Slot = slotData.Index;
|
||||
|
||||
SyncClientToPlayerReference(cl, slotData.MapPlayer != null ? Map.Players[slotData.MapPlayer] : null);
|
||||
}
|
||||
|
||||
SyncLobbyInfo();
|
||||
return true;
|
||||
@@ -403,8 +434,10 @@ namespace OpenRA.Server
|
||||
{
|
||||
int team;
|
||||
if (!int.TryParse(s, out team)) { Log.Write("server", "Invalid team: {0}", s ); return false; }
|
||||
|
||||
GetClient(conn).Team = team;
|
||||
if (Game.Settings.Server.Extension == null || Game.Settings.Server.Extension.OnTeamChange(conn, GetClient(conn), team))
|
||||
{
|
||||
GetClient(conn).Team = team;
|
||||
}
|
||||
SyncLobbyInfo();
|
||||
return true;
|
||||
}},
|
||||
@@ -423,8 +456,10 @@ namespace OpenRA.Server
|
||||
SendChatTo( conn, "You can't be at the same spawn point as another player" );
|
||||
return true;
|
||||
}
|
||||
|
||||
GetClient(conn).SpawnPoint = spawnPoint;
|
||||
if (Game.Settings.Server.Extension == null || Game.Settings.Server.Extension.OnSpawnpointChange(conn, GetClient(conn), spawnPoint))
|
||||
{
|
||||
GetClient(conn).SpawnPoint = spawnPoint;
|
||||
}
|
||||
SyncLobbyInfo();
|
||||
return true;
|
||||
}},
|
||||
@@ -432,8 +467,12 @@ namespace OpenRA.Server
|
||||
s =>
|
||||
{
|
||||
var c = s.Split(',').Select(cc => int.Parse(cc)).ToArray();
|
||||
GetClient(conn).Color1 = Color.FromArgb(c[0],c[1],c[2]);
|
||||
GetClient(conn).Color2 = Color.FromArgb(c[3],c[4],c[5]);
|
||||
|
||||
if (Game.Settings.Server.Extension == null || Game.Settings.Server.Extension.OnColorChange(conn, GetClient(conn), Color.FromArgb(c[0], c[1], c[2]), Color.FromArgb(c[3], c[4], c[5])))
|
||||
{
|
||||
GetClient(conn).Color1 = Color.FromArgb(c[0], c[1], c[2]);
|
||||
GetClient(conn).Color2 = Color.FromArgb(c[3], c[4], c[5]);
|
||||
}
|
||||
SyncLobbyInfo();
|
||||
return true;
|
||||
}},
|
||||
@@ -449,9 +488,13 @@ namespace OpenRA.Server
|
||||
return false;
|
||||
|
||||
var cl = GetClient(conn);
|
||||
cl.Slot = slot;
|
||||
|
||||
SyncClientToPlayerReference(cl, slotData.MapPlayer != null ? Map.Players[slotData.MapPlayer] : null);
|
||||
if (Game.Settings.Server.Extension == null || Game.Settings.Server.Extension.OnSlotChange(conn, cl, slotData, Map))
|
||||
{
|
||||
cl.Slot = slot;
|
||||
|
||||
SyncClientToPlayerReference(cl, slotData.MapPlayer != null ? Map.Players[slotData.MapPlayer] : null);
|
||||
}
|
||||
|
||||
SyncLobbyInfo();
|
||||
return true;
|
||||
@@ -628,6 +671,7 @@ namespace OpenRA.Server
|
||||
|
||||
case "Chat":
|
||||
case "TeamChat":
|
||||
if (Game.Settings.Server.Extension == null || Game.Settings.Server.Extension.OnChat(conn, so.Data, so.Name == "TeamChat"))
|
||||
foreach (var c in conns.Except(conn).ToArray())
|
||||
DispatchOrdersToClient(c, GetClient(conn).Index, 0, so.Serialize());
|
||||
break;
|
||||
@@ -654,6 +698,9 @@ namespace OpenRA.Server
|
||||
|
||||
static void SyncLobbyInfo()
|
||||
{
|
||||
if (Game.Settings.Server.Extension != null)
|
||||
Game.Settings.Server.Extension.OnLobbySync(lobbyInfo, GameStarted);
|
||||
|
||||
if (!GameStarted) /* don't do this while the game is running, it breaks things. */
|
||||
DispatchOrders(null, 0,
|
||||
new ServerOrder("SyncInfo", lobbyInfo.Serialize()).Serialize());
|
||||
@@ -667,6 +714,9 @@ namespace OpenRA.Server
|
||||
{
|
||||
if (isBusy || !isInternetServer) return;
|
||||
|
||||
if (Game.Settings.Server.Extension != null && !Game.Settings.Server.Extension.OnPingMasterServer(lobbyInfo, GameStarted))
|
||||
return;
|
||||
|
||||
lastPing = Environment.TickCount;
|
||||
isBusy = true;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user