Excise previous server extensions code
This commit is contained in:
@@ -21,8 +21,6 @@ namespace OpenRA.FileFormats
|
|||||||
Mods, Folders, Packages, Rules,
|
Mods, Folders, Packages, Rules,
|
||||||
Sequences, Cursors, Chrome, Assemblies, ChromeLayout,
|
Sequences, Cursors, Chrome, Assemblies, ChromeLayout,
|
||||||
Weapons, Voices, Music, Movies, TileSets;
|
Weapons, Voices, Music, Movies, TileSets;
|
||||||
public string[] LocalRules = new string[0];
|
|
||||||
public string[] LocalAssemblies = new string[0];
|
|
||||||
public readonly string ShellmapUid, LoadScreen;
|
public readonly string ShellmapUid, LoadScreen;
|
||||||
public readonly int TileSize = 24;
|
public readonly int TileSize = 24;
|
||||||
|
|
||||||
|
|||||||
@@ -220,29 +220,6 @@ namespace OpenRA
|
|||||||
Console.WriteLine("Loading mods: {0}",string.Join(",",mods));
|
Console.WriteLine("Loading mods: {0}",string.Join(",",mods));
|
||||||
|
|
||||||
modData = new ModData( mods );
|
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();
|
Sound.Initialize();
|
||||||
PerfHistory.items["render"].hasNormalTick = false;
|
PerfHistory.items["render"].hasNormalTick = false;
|
||||||
PerfHistory.items["batches"].hasNormalTick = false;
|
PerfHistory.items["batches"].hasNormalTick = false;
|
||||||
@@ -250,108 +227,38 @@ namespace OpenRA
|
|||||||
PerfHistory.items["cursor"].hasNormalTick = false;
|
PerfHistory.items["cursor"].hasNormalTick = false;
|
||||||
|
|
||||||
|
|
||||||
if (!Settings.Graphics.UseNullRenderer)
|
|
||||||
{
|
|
||||||
JoinLocal();
|
JoinLocal();
|
||||||
StartGame(modData.Manifest.ShellmapUid);
|
StartGame(modData.Manifest.ShellmapUid);
|
||||||
|
|
||||||
Game.ConnectionStateChanged += om =>
|
Game.ConnectionStateChanged += orderManager =>
|
||||||
{
|
{
|
||||||
Widget.CloseWindow();
|
Widget.CloseWindow();
|
||||||
switch (om.Connection.ConnectionState)
|
switch( orderManager.Connection.ConnectionState )
|
||||||
{
|
{
|
||||||
case ConnectionState.PreConnecting:
|
case ConnectionState.PreConnecting:
|
||||||
Widget.OpenWindow("MAINMENU_BG");
|
Widget.OpenWindow("MAINMENU_BG");
|
||||||
break;
|
break;
|
||||||
case ConnectionState.Connecting:
|
case ConnectionState.Connecting:
|
||||||
Widget.OpenWindow( "CONNECTING_BG",
|
Widget.OpenWindow( "CONNECTING_BG",
|
||||||
new Dictionary<string, object>
|
new Dictionary<string, object> { { "host", orderManager.Host }, { "port", orderManager.Port } } );
|
||||||
{{"host", om.Host}, {"port", om.Port}});
|
|
||||||
break;
|
break;
|
||||||
case ConnectionState.NotConnected:
|
case ConnectionState.NotConnected:
|
||||||
Widget.OpenWindow( "CONNECTION_FAILED_BG",
|
Widget.OpenWindow( "CONNECTION_FAILED_BG",
|
||||||
new Dictionary<string, object>
|
new Dictionary<string, object> { { "host", orderManager.Host }, { "port", orderManager.Port } } );
|
||||||
{{"host", om.Host}, {"port", om.Port}});
|
|
||||||
break;
|
break;
|
||||||
case ConnectionState.Connected:
|
case ConnectionState.Connected:
|
||||||
var lobby = Widget.OpenWindow("SERVER_LOBBY",
|
var lobby = Widget.OpenWindow( "SERVER_LOBBY", new Dictionary<string, object> { { "orderManager", orderManager } } );
|
||||||
new Dictionary<string, object>
|
|
||||||
{{"orderManager", om}});
|
|
||||||
lobby.GetWidget<ChatDisplayWidget>("CHAT_DISPLAY").ClearChat();
|
lobby.GetWidget<ChatDisplayWidget>("CHAT_DISPLAY").ClearChat();
|
||||||
lobby.GetWidget("CHANGEMAP_BUTTON").Visible = true;
|
lobby.GetWidget("CHANGEMAP_BUTTON").Visible = true;
|
||||||
lobby.GetWidget("LOCKTEAMS_CHECKBOX").Visible = true;
|
lobby.GetWidget("LOCKTEAMS_CHECKBOX").Visible = true;
|
||||||
lobby.GetWidget("DISCONNECT_BUTTON").Visible = true;
|
lobby.GetWidget("DISCONNECT_BUTTON").Visible = true;
|
||||||
|
//r.GetWidget("INGAME_ROOT").GetWidget<ChatDisplayWidget>("CHAT_DISPLAY").ClearChat();
|
||||||
// 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;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
modData.WidgetLoader.LoadWidget( new Dictionary<string,object>(), Widget.RootWidget, "PERF_BG" );
|
modData.WidgetLoader.LoadWidget( new Dictionary<string,object>(), Widget.RootWidget, "PERF_BG" );
|
||||||
Widget.OpenWindow("MAINMENU_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;
|
Game.orderManager.LastTickTime = Environment.TickCount;
|
||||||
}
|
}
|
||||||
@@ -415,9 +322,6 @@ namespace OpenRA
|
|||||||
|
|
||||||
public static void RejoinLobby(World world)
|
public static void RejoinLobby(World world)
|
||||||
{
|
{
|
||||||
if (Game.IsHost && Game.Settings.Server.Extension != null)
|
|
||||||
Game.Settings.Server.Extension.OnRejoinLobby(world);
|
|
||||||
|
|
||||||
var map = orderManager.LobbyInfo.GlobalSettings.Map;
|
var map = orderManager.LobbyInfo.GlobalSettings.Map;
|
||||||
var host = orderManager.Host;
|
var host = orderManager.Host;
|
||||||
var port = orderManager.Port;
|
var port = orderManager.Port;
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ namespace OpenRA
|
|||||||
public static void LoadRules(Manifest m, Map map)
|
public static void LoadRules(Manifest m, Map map)
|
||||||
{
|
{
|
||||||
// Added support to extend the list of rules (add it to m.LocalRules)
|
// Added support to extend the list of rules (add it to m.LocalRules)
|
||||||
// Should only be used to add ITraitNoSync traits! (otherwise BOOM)
|
Info = LoadYamlRules(m.Rules, map.Rules, (k, y) => new ActorInfo(k.Key.ToLowerInvariant(), k.Value, y));
|
||||||
Info = LoadYamlRules(m.Rules.Concat(m.LocalRules).ToArray(), map.Rules, (k, y) => new ActorInfo(k.Key.ToLowerInvariant(), k.Value, y));
|
|
||||||
Weapons = LoadYamlRules(m.Weapons, new List<MiniYamlNode>(), (k, _) => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value));
|
Weapons = LoadYamlRules(m.Weapons, new List<MiniYamlNode>(), (k, _) => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value));
|
||||||
Voices = LoadYamlRules(m.Voices, new List<MiniYamlNode>(), (k, _) => new VoiceInfo(k.Value));
|
Voices = LoadYamlRules(m.Voices, new List<MiniYamlNode>(), (k, _) => new VoiceInfo(k.Value));
|
||||||
Music = LoadYamlRules(m.Music, new List<MiniYamlNode>(), (k, _) => new MusicInfo(k.Key, k.Value));
|
Music = LoadYamlRules(m.Music, new List<MiniYamlNode>(), (k, _) => new MusicInfo(k.Key, k.Value));
|
||||||
|
|||||||
@@ -27,13 +27,6 @@ namespace OpenRA.GameRules
|
|||||||
public bool AdvertiseOnline = true;
|
public bool AdvertiseOnline = true;
|
||||||
public string MasterServer = "http://master.open-ra.org/";
|
public string MasterServer = "http://master.open-ra.org/";
|
||||||
public bool AllowCheats = false;
|
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
|
public class DebugSettings
|
||||||
@@ -50,9 +43,6 @@ namespace OpenRA.GameRules
|
|||||||
public int2 FullscreenSize = new int2(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
|
public int2 FullscreenSize = new int2(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
|
||||||
public int2 WindowedSize = new int2(1024, 768);
|
public int2 WindowedSize = new int2(1024, 768);
|
||||||
public readonly int2 MinResolution = new int2(800, 600);
|
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
|
public class SoundSettings
|
||||||
@@ -115,11 +105,6 @@ namespace OpenRA.GameRules
|
|||||||
{"Debug", Debug}
|
{"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
|
// Override fieldloader to ignore invalid entries
|
||||||
var err1 = FieldLoader.UnknownFieldAction;
|
var err1 = FieldLoader.UnknownFieldAction;
|
||||||
var err2 = FieldLoader.InvalidValueAction;
|
var err2 = FieldLoader.InvalidValueAction;
|
||||||
|
|||||||
@@ -133,11 +133,7 @@ namespace OpenRA.Graphics
|
|||||||
internal static void Initialize( OpenRA.FileFormats.Graphics.WindowMode windowMode )
|
internal static void Initialize( OpenRA.FileFormats.Graphics.WindowMode windowMode )
|
||||||
{
|
{
|
||||||
var resolution = GetResolution( 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)
|
static Size GetResolution(WindowMode windowmode)
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ namespace OpenRA.Network
|
|||||||
report.Traits.Clear();
|
report.Traits.Clear();
|
||||||
foreach (var a in orderManager.world.Queries.WithTraitMultiple<object>())
|
foreach (var a in orderManager.world.Queries.WithTraitMultiple<object>())
|
||||||
{
|
{
|
||||||
if (a.Trait is ITraitNotSynced ) continue;
|
|
||||||
var sync = Sync.CalculateSyncHash(a.Trait);
|
var sync = Sync.CalculateSyncHash(a.Trait);
|
||||||
if (sync != 0)
|
if (sync != 0)
|
||||||
report.Traits.Add(new TraitReport()
|
report.Traits.Add(new TraitReport()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#region Copyright & License Information
|
#region Copyright & License Information
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||||
* This file is part of OpenRA, which is free software. It is made
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
@@ -39,11 +39,6 @@ namespace OpenRA.Network
|
|||||||
case "Chat":
|
case "Chat":
|
||||||
{
|
{
|
||||||
var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
|
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)
|
if (client != null)
|
||||||
{
|
{
|
||||||
var player = world != null ? world.FindPlayerByClient(client) : null;
|
var player = world != null ? world.FindPlayerByClient(client) : null;
|
||||||
@@ -54,7 +49,6 @@ namespace OpenRA.Network
|
|||||||
Game.AddChatLine(Color.White, "(player {0})".F(clientId), order.TargetString);
|
Game.AddChatLine(Color.White, "(player {0})".F(clientId), order.TargetString);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "Disconnected": /* reports that the target player disconnected */
|
case "Disconnected": /* reports that the target player disconnected */
|
||||||
{
|
{
|
||||||
var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
|
var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
|
||||||
@@ -68,9 +62,6 @@ namespace OpenRA.Network
|
|||||||
{
|
{
|
||||||
var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
|
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 (client != null)
|
||||||
{
|
{
|
||||||
if (world == null)
|
if (world == null)
|
||||||
@@ -125,10 +116,6 @@ namespace OpenRA.Network
|
|||||||
var targetPlayer = order.Player.World.players[order.TargetLocation.X];
|
var targetPlayer = order.Player.World.players[order.TargetLocation.X];
|
||||||
var newStance = (Stance)order.TargetLocation.Y;
|
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);
|
SetPlayerStance(world, order.Player, targetPlayer, newStance);
|
||||||
|
|
||||||
// automatically declare war reciprocally
|
// automatically declare war reciprocally
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace OpenRA
|
|||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// Namespaces from each mod assembly
|
// Namespaces from each mod assembly
|
||||||
foreach (var a in manifest.Assemblies.Concat(manifest.LocalAssemblies))
|
foreach (var a in manifest.Assemblies)
|
||||||
{
|
{
|
||||||
var asm = Assembly.LoadFile(Path.GetFullPath(a));
|
var asm = Assembly.LoadFile(Path.GetFullPath(a));
|
||||||
asms.AddRange(asm.GetNamespaces().Select(ns => Pair.New(asm, ns)));
|
asms.AddRange(asm.GetNamespaces().Select(ns => Pair.New(asm, ns)));
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
@@ -208,8 +208,6 @@
|
|||||||
<Compile Include="Network\Session.cs" />
|
<Compile Include="Network\Session.cs" />
|
||||||
<Compile Include="ObjectCreator.cs" />
|
<Compile Include="ObjectCreator.cs" />
|
||||||
<Compile Include="Network\SyncReport.cs" />
|
<Compile Include="Network\SyncReport.cs" />
|
||||||
<Compile Include="Server\IServerExtension.cs" />
|
|
||||||
<Compile Include="Server\NullServerExtension.cs" />
|
|
||||||
<Compile Include="Traits\BaseBuilding.cs" />
|
<Compile Include="Traits\BaseBuilding.cs" />
|
||||||
<Compile Include="Traits\EditorAppearance.cs" />
|
<Compile Include="Traits\EditorAppearance.cs" />
|
||||||
<Compile Include="Traits\ValidateOrder.cs" />
|
<Compile Include="Traits\ValidateOrder.cs" />
|
||||||
|
|||||||
@@ -15,20 +15,20 @@ using System.Net.Sockets;
|
|||||||
|
|
||||||
namespace OpenRA.Server
|
namespace OpenRA.Server
|
||||||
{
|
{
|
||||||
public class Connection
|
class Connection
|
||||||
{
|
{
|
||||||
internal Socket socket;
|
public Socket socket;
|
||||||
internal List<byte> data = new List<byte>();
|
public List<byte> data = new List<byte>();
|
||||||
internal ReceiveState State = ReceiveState.Header;
|
public ReceiveState State = ReceiveState.Header;
|
||||||
internal int ExpectLength = 8;
|
public int ExpectLength = 8;
|
||||||
internal int Frame = 0;
|
public int Frame = 0;
|
||||||
|
|
||||||
internal int MostRecentFrame = 0;
|
public int MostRecentFrame = 0;
|
||||||
|
|
||||||
/* client data */
|
/* client data */
|
||||||
public int PlayerIndex { get; internal set; }
|
public int PlayerIndex;
|
||||||
|
|
||||||
internal byte[] PopBytes(int n)
|
public byte[] PopBytes(int n)
|
||||||
{
|
{
|
||||||
var result = data.GetRange(0, n);
|
var result = data.GetRange(0, n);
|
||||||
data.RemoveRange(0, n);
|
data.RemoveRange(0, n);
|
||||||
@@ -65,7 +65,7 @@ namespace OpenRA.Server
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ReadData()
|
public void ReadData()
|
||||||
{
|
{
|
||||||
if (ReadDataInner())
|
if (ReadDataInner())
|
||||||
while (data.Count >= ExpectLength)
|
while (data.Count >= ExpectLength)
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
#region Copyright & License Information
|
|
||||||
/*
|
|
||||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
|
||||||
* This file is part of OpenRA, which is free software. It is made
|
|
||||||
* available to you under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation. For more information,
|
|
||||||
* see LICENSE.
|
|
||||||
*/
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
using System.Drawing;
|
|
||||||
using OpenRA.Network;
|
|
||||||
using OpenRA.Traits;
|
|
||||||
|
|
||||||
namespace OpenRA.Server
|
|
||||||
{
|
|
||||||
public interface IServerExtension
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Return true to use the built-in handling
|
|
||||||
/// </summary>
|
|
||||||
bool OnReadyUp(Connection conn, Session.Client client);
|
|
||||||
void OnStartGame();
|
|
||||||
/// <summary>
|
|
||||||
/// Return true to use the built-in handling
|
|
||||||
/// </summary>
|
|
||||||
bool OnNickChange(Connection conn, Session.Client client, string newName);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Return true to use the built-in handling
|
|
||||||
/// </summary>
|
|
||||||
bool OnRaceChange(Connection conn, Session.Client client, string newRace);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Return true to use the built-in handling
|
|
||||||
/// </summary>
|
|
||||||
bool OnSlotChange(Connection conn, Session.Client client, Session.Slot slot, Map map);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Return true to use the built-in handling
|
|
||||||
/// </summary>
|
|
||||||
bool OnTeamChange(Connection conn, Session.Client getClient, int team);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Return true to use the built-in handling
|
|
||||||
/// </summary>
|
|
||||||
bool OnSpawnpointChange(Connection conn, Session.Client getClient, int spawnPoint);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Return true to use the built-in handling
|
|
||||||
/// </summary>
|
|
||||||
bool OnColorChange(Connection conn, Session.Client getClient, Color fromArgb, Color color);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Return true to use the built-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 built-in handling
|
|
||||||
/// </summary>
|
|
||||||
bool OnPingMasterServer(Session lobbyInfo, bool gameStarted);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Return true to use the built-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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
#region Copyright & License Information
|
|
||||||
/*
|
|
||||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
|
||||||
* This file is part of OpenRA, which is free software. It is made
|
|
||||||
* available to you under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation. For more information,
|
|
||||||
* see LICENSE.
|
|
||||||
*/
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
using System.Drawing;
|
|
||||||
using OpenRA.Network;
|
|
||||||
using OpenRA.Traits;
|
|
||||||
|
|
||||||
namespace OpenRA.Server
|
|
||||||
{
|
|
||||||
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) { }
|
|
||||||
// Good spot to manipulate number of spectators! ie set Server.MaxSpectators
|
|
||||||
public virtual void OnLoadMap(Map map) { }
|
|
||||||
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) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -25,17 +25,12 @@ namespace OpenRA.Server
|
|||||||
{
|
{
|
||||||
static class Server
|
static class Server
|
||||||
{
|
{
|
||||||
public static Connection[] Connections
|
|
||||||
{
|
|
||||||
get { return conns.ToArray(); }
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<Connection> conns = new List<Connection>();
|
static List<Connection> conns = new List<Connection>();
|
||||||
static TcpListener listener = null;
|
static TcpListener listener = null;
|
||||||
static Dictionary<int, List<Connection>> inFlightFrames
|
static Dictionary<int, List<Connection>> inFlightFrames
|
||||||
= new Dictionary<int, List<Connection>>();
|
= new Dictionary<int, List<Connection>>();
|
||||||
static Session lobbyInfo;
|
static Session lobbyInfo;
|
||||||
internal static bool GameStarted = false;
|
static bool GameStarted = false;
|
||||||
static string Name;
|
static string Name;
|
||||||
static int ExternalPort;
|
static int ExternalPort;
|
||||||
static int randomSeed;
|
static int randomSeed;
|
||||||
@@ -62,20 +57,7 @@ namespace OpenRA.Server
|
|||||||
try { listener.Stop(); }
|
try { listener.Stop(); }
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
E(e => e.OnServerStop(true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void E(Action<IServerExtension> f)
|
|
||||||
{
|
|
||||||
E(g => { f(g); return true; });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool E(Func<IServerExtension, bool> f)
|
|
||||||
{
|
|
||||||
return Game.Settings.Server.Extension == null ||
|
|
||||||
f(Game.Settings.Server.Extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ServerMain(ModData modData, Settings settings, string map)
|
public static void ServerMain(ModData modData, Settings settings, string map)
|
||||||
{
|
{
|
||||||
Log.AddChannel("server", "server.log");
|
Log.AddChannel("server", "server.log");
|
||||||
@@ -83,7 +65,6 @@ namespace OpenRA.Server
|
|||||||
isInitialPing = true;
|
isInitialPing = true;
|
||||||
Server.masterServerUrl = settings.Server.MasterServer;
|
Server.masterServerUrl = settings.Server.MasterServer;
|
||||||
isInternetServer = settings.Server.AdvertiseOnline;
|
isInternetServer = settings.Server.AdvertiseOnline;
|
||||||
|
|
||||||
listener = new TcpListener(IPAddress.Any, settings.Server.ListenPort);
|
listener = new TcpListener(IPAddress.Any, settings.Server.ListenPort);
|
||||||
Name = settings.Server.Name;
|
Name = settings.Server.Name;
|
||||||
ExternalPort = settings.Server.ExternalPort;
|
ExternalPort = settings.Server.ExternalPort;
|
||||||
@@ -113,8 +94,6 @@ namespace OpenRA.Server
|
|||||||
throw new InvalidOperationException( "Unable to start server: port is already in use" );
|
throw new InvalidOperationException( "Unable to start server: port is already in use" );
|
||||||
}
|
}
|
||||||
|
|
||||||
E(e => e.OnServerStart());
|
|
||||||
|
|
||||||
new Thread( _ =>
|
new Thread( _ =>
|
||||||
{
|
{
|
||||||
for( ; ; )
|
for( ; ; )
|
||||||
@@ -140,7 +119,6 @@ namespace OpenRA.Server
|
|||||||
{
|
{
|
||||||
listener.Stop();
|
listener.Stop();
|
||||||
GameStarted = false;
|
GameStarted = false;
|
||||||
E(e => e.OnServerStop(false));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,8 +147,6 @@ namespace OpenRA.Server
|
|||||||
.Select((s, i) => { s.Index = i; return s; })
|
.Select((s, i) => { s.Index = i; return s; })
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
E(e => e.OnLoadMap(Map));
|
|
||||||
|
|
||||||
// Generate slots for spectators
|
// Generate slots for spectators
|
||||||
for (int i = 0; i < MaxSpectators; i++)
|
for (int i = 0; i < MaxSpectators; i++)
|
||||||
lobbyInfo.Slots.Add(new Session.Slot
|
lobbyInfo.Slots.Add(new Session.Slot
|
||||||
@@ -217,17 +193,7 @@ namespace OpenRA.Server
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var newConn = new Connection { socket = newSocket };
|
var newConn = new Connection { socket = newSocket };
|
||||||
|
|
||||||
|
|
||||||
if (!E(e => e.OnValidateConnection(GameStarted, newConn)))
|
|
||||||
{
|
|
||||||
DropClient(newConn, new Exception() );
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (GameStarted)
|
if (GameStarted)
|
||||||
@@ -338,7 +304,7 @@ namespace OpenRA.Server
|
|||||||
catch (NotImplementedException) { }
|
catch (NotImplementedException) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SyncClientToPlayerReference(Session.Client c, PlayerReference pr)
|
static void SyncClientToPlayerReference(Session.Client c, PlayerReference pr)
|
||||||
{
|
{
|
||||||
if (pr == null)
|
if (pr == null)
|
||||||
return;
|
return;
|
||||||
@@ -351,7 +317,7 @@ namespace OpenRA.Server
|
|||||||
c.Country = pr.Race;
|
c.Country = pr.Race;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool InterpretCommand(Connection conn, string cmd)
|
static bool InterpretCommand(Connection conn, string cmd)
|
||||||
{
|
{
|
||||||
var dict = new Dictionary<string, Func<string, bool>>
|
var dict = new Dictionary<string, Func<string, bool>>
|
||||||
{
|
{
|
||||||
@@ -371,11 +337,8 @@ namespace OpenRA.Server
|
|||||||
|
|
||||||
SyncLobbyInfo();
|
SyncLobbyInfo();
|
||||||
|
|
||||||
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))
|
if (conns.Count > 0 && conns.All(c => GetClient(c).State == Session.ClientState.Ready))
|
||||||
InterpretCommand(conn, "startgame");
|
InterpretCommand(conn, "startgame");
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}},
|
}},
|
||||||
@@ -390,8 +353,6 @@ namespace OpenRA.Server
|
|||||||
DispatchOrders(null, 0,
|
DispatchOrders(null, 0,
|
||||||
new ServerOrder("StartGame", "").Serialize());
|
new ServerOrder("StartGame", "").Serialize());
|
||||||
|
|
||||||
E(e => e.OnStartGame());
|
|
||||||
|
|
||||||
PingMasterServer();
|
PingMasterServer();
|
||||||
return true;
|
return true;
|
||||||
}},
|
}},
|
||||||
@@ -399,10 +360,7 @@ namespace OpenRA.Server
|
|||||||
s =>
|
s =>
|
||||||
{
|
{
|
||||||
Log.Write("server", "Player@{0} is now known as {1}", conn.socket.RemoteEndPoint, s);
|
Log.Write("server", "Player@{0} is now known as {1}", conn.socket.RemoteEndPoint, s);
|
||||||
|
|
||||||
if (E(e => e.OnNickChange(conn, GetClient(conn), s)))
|
|
||||||
GetClient(conn).Name = s;
|
GetClient(conn).Name = s;
|
||||||
|
|
||||||
SyncLobbyInfo();
|
SyncLobbyInfo();
|
||||||
return true;
|
return true;
|
||||||
}},
|
}},
|
||||||
@@ -421,7 +379,6 @@ namespace OpenRA.Server
|
|||||||
{ "race",
|
{ "race",
|
||||||
s =>
|
s =>
|
||||||
{
|
{
|
||||||
if (E(e => e.OnRaceChange(conn, GetClient(conn), s)))
|
|
||||||
GetClient(conn).Country = s;
|
GetClient(conn).Country = s;
|
||||||
|
|
||||||
SyncLobbyInfo();
|
SyncLobbyInfo();
|
||||||
@@ -436,12 +393,9 @@ namespace OpenRA.Server
|
|||||||
|
|
||||||
var cl = GetClient(conn);
|
var cl = GetClient(conn);
|
||||||
|
|
||||||
if (E(e => e.OnSlotChange(conn, cl, slotData, Map)))
|
|
||||||
{
|
|
||||||
cl.Slot = slotData.Index;
|
cl.Slot = slotData.Index;
|
||||||
SyncClientToPlayerReference(cl, slotData.MapPlayer != null
|
|
||||||
? Map.Players[slotData.MapPlayer] : null);
|
SyncClientToPlayerReference(cl, slotData.MapPlayer != null ? Map.Players[slotData.MapPlayer] : null);
|
||||||
}
|
|
||||||
|
|
||||||
SyncLobbyInfo();
|
SyncLobbyInfo();
|
||||||
return true;
|
return true;
|
||||||
@@ -451,10 +405,8 @@ namespace OpenRA.Server
|
|||||||
{
|
{
|
||||||
int team;
|
int team;
|
||||||
if (!int.TryParse(s, out team)) { Log.Write("server", "Invalid team: {0}", s ); return false; }
|
if (!int.TryParse(s, out team)) { Log.Write("server", "Invalid team: {0}", s ); return false; }
|
||||||
if (E(e => e.OnTeamChange(conn, GetClient(conn), team)))
|
|
||||||
{
|
|
||||||
GetClient(conn).Team = team;
|
GetClient(conn).Team = team;
|
||||||
}
|
|
||||||
SyncLobbyInfo();
|
SyncLobbyInfo();
|
||||||
return true;
|
return true;
|
||||||
}},
|
}},
|
||||||
@@ -473,10 +425,8 @@ namespace OpenRA.Server
|
|||||||
SendChatTo( conn, "You can't be at the same spawn point as another player" );
|
SendChatTo( conn, "You can't be at the same spawn point as another player" );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (E(e => e.OnSpawnpointChange(conn, GetClient(conn), spawnPoint)))
|
|
||||||
{
|
|
||||||
GetClient(conn).SpawnPoint = spawnPoint;
|
GetClient(conn).SpawnPoint = spawnPoint;
|
||||||
}
|
|
||||||
SyncLobbyInfo();
|
SyncLobbyInfo();
|
||||||
return true;
|
return true;
|
||||||
}},
|
}},
|
||||||
@@ -484,14 +434,8 @@ namespace OpenRA.Server
|
|||||||
s =>
|
s =>
|
||||||
{
|
{
|
||||||
var c = s.Split(',').Select(cc => int.Parse(cc)).ToArray();
|
var c = s.Split(',').Select(cc => int.Parse(cc)).ToArray();
|
||||||
var c1 = Color.FromArgb(c[0], c[1], c[2]);
|
GetClient(conn).Color1 = Color.FromArgb(c[0],c[1],c[2]);
|
||||||
var c2 = Color.FromArgb(c[3], c[4], c[5]);
|
GetClient(conn).Color2 = Color.FromArgb(c[3],c[4],c[5]);
|
||||||
|
|
||||||
if (E(e => e.OnColorChange(conn, GetClient(conn), c1, c2)))
|
|
||||||
{
|
|
||||||
GetClient(conn).Color1 = c1;
|
|
||||||
GetClient(conn).Color2 = c2;
|
|
||||||
}
|
|
||||||
SyncLobbyInfo();
|
SyncLobbyInfo();
|
||||||
return true;
|
return true;
|
||||||
}},
|
}},
|
||||||
@@ -507,13 +451,9 @@ namespace OpenRA.Server
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
var cl = GetClient(conn);
|
var cl = GetClient(conn);
|
||||||
|
|
||||||
if (E(e => e.OnSlotChange(conn, cl, slotData, Map)))
|
|
||||||
{
|
|
||||||
cl.Slot = slot;
|
cl.Slot = slot;
|
||||||
SyncClientToPlayerReference(cl, slotData.MapPlayer != null
|
|
||||||
? Map.Players[slotData.MapPlayer] : null);
|
SyncClientToPlayerReference(cl, slotData.MapPlayer != null ? Map.Players[slotData.MapPlayer] : null);
|
||||||
}
|
|
||||||
|
|
||||||
SyncLobbyInfo();
|
SyncLobbyInfo();
|
||||||
return true;
|
return true;
|
||||||
@@ -673,7 +613,7 @@ namespace OpenRA.Server
|
|||||||
case "Command":
|
case "Command":
|
||||||
{
|
{
|
||||||
if (GameStarted)
|
if (GameStarted)
|
||||||
SendChatTo(conn, "Cannot change state when game started.");
|
SendChatTo(conn, "Cannot change state when game started. ({0})".F(so.Data));
|
||||||
else if (GetClient(conn).State == Session.ClientState.Ready && !(so.Data == "ready" || so.Data == "startgame"))
|
else if (GetClient(conn).State == Session.ClientState.Ready && !(so.Data == "ready" || so.Data == "startgame"))
|
||||||
SendChatTo(conn, "Cannot change state when marked as ready.");
|
SendChatTo(conn, "Cannot change state when marked as ready.");
|
||||||
else if (!InterpretCommand(conn, so.Data))
|
else if (!InterpretCommand(conn, so.Data))
|
||||||
@@ -686,8 +626,6 @@ namespace OpenRA.Server
|
|||||||
|
|
||||||
case "Chat":
|
case "Chat":
|
||||||
case "TeamChat":
|
case "TeamChat":
|
||||||
case "Disconnected":
|
|
||||||
if (E(e => e.OnChat(conn, so.Data, so.Name == "TeamChat")))
|
|
||||||
foreach (var c in conns.Except(conn).ToArray())
|
foreach (var c in conns.Except(conn).ToArray())
|
||||||
DispatchOrdersToClient(c, GetClient(conn).Index, 0, so.Serialize());
|
DispatchOrdersToClient(c, GetClient(conn).Index, 0, so.Serialize());
|
||||||
break;
|
break;
|
||||||
@@ -717,8 +655,6 @@ namespace OpenRA.Server
|
|||||||
|
|
||||||
static void SyncLobbyInfo()
|
static void SyncLobbyInfo()
|
||||||
{
|
{
|
||||||
E(e => e.OnLobbySync(lobbyInfo, GameStarted));
|
|
||||||
|
|
||||||
if (!GameStarted) /* don't do this while the game is running, it breaks things. */
|
if (!GameStarted) /* don't do this while the game is running, it breaks things. */
|
||||||
DispatchOrders(null, 0,
|
DispatchOrders(null, 0,
|
||||||
new ServerOrder("SyncInfo", lobbyInfo.Serialize()).Serialize());
|
new ServerOrder("SyncInfo", lobbyInfo.Serialize()).Serialize());
|
||||||
@@ -732,9 +668,6 @@ namespace OpenRA.Server
|
|||||||
{
|
{
|
||||||
if (isBusy || !isInternetServer) return;
|
if (isBusy || !isInternetServer) return;
|
||||||
|
|
||||||
if (!E(e => e.OnPingMasterServer(lobbyInfo, GameStarted)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
lastPing = Environment.TickCount;
|
lastPing = Environment.TickCount;
|
||||||
isBusy = true;
|
isBusy = true;
|
||||||
|
|
||||||
|
|||||||
@@ -210,8 +210,6 @@ namespace OpenRA.Traits
|
|||||||
public interface IPostRenderSelection { void RenderAfterWorld(WorldRenderer wr, Actor self); }
|
public interface IPostRenderSelection { void RenderAfterWorld(WorldRenderer wr, Actor self); }
|
||||||
public interface IPreRenderSelection { void RenderBeforeWorld(WorldRenderer wr, Actor self); }
|
public interface IPreRenderSelection { void RenderBeforeWorld(WorldRenderer wr, Actor self); }
|
||||||
|
|
||||||
public interface ITraitNotSynced{} // Traits marked with NotSynced arent sync-checked
|
|
||||||
|
|
||||||
public struct Target // a target: either an actor, or a fixed location.
|
public struct Target // a target: either an actor, or a fixed location.
|
||||||
{
|
{
|
||||||
Actor actor;
|
Actor actor;
|
||||||
|
|||||||
@@ -199,11 +199,7 @@ namespace OpenRA
|
|||||||
|
|
||||||
// hash all the traits that tick
|
// hash all the traits that tick
|
||||||
foreach (var x in traitDict.ActorsWithTraitMultiple<object>(this))
|
foreach (var x in traitDict.ActorsWithTraitMultiple<object>(this))
|
||||||
{
|
|
||||||
if (x.Trait is ITraitNotSynced) continue;
|
|
||||||
|
|
||||||
ret += n++*(int) x.Actor.ActorID*Sync.CalculateSyncHash(x.Trait);
|
ret += n++*(int) x.Actor.ActorID*Sync.CalculateSyncHash(x.Trait);
|
||||||
}
|
|
||||||
|
|
||||||
// Hash the shared rng
|
// Hash the shared rng
|
||||||
ret += SharedRandom.Last;
|
ret += SharedRandom.Last;
|
||||||
|
|||||||
Reference in New Issue
Block a user