Compare commits

...

9 Commits

Author SHA1 Message Date
Pieter-Jan Briers
b205a14f69 Exception tolerance for NetManager.OnDisconnect 2021-01-20 21:07:02 +01:00
Pieter-Jan Briers
d5f3292e0a Unregister OnSessionOnPlayerStatusChanged on bound user interfaces.
I am frankly flabbergasted this is only a problem now.
2021-01-20 21:00:24 +01:00
Pieter-Jan Briers
561e4b330e Fix ALL components memory leaking.
:irrational:
2021-01-20 20:45:02 +01:00
Paul
36a5d102ff prevent one error from killing the entire namegenerator from running 2021-01-17 17:17:02 +01:00
Pieter-Jan Briers
b9c39e0953 Fix reconnecting. 2021-01-17 16:08:48 +01:00
Pieter-Jan Briers
ad4c8be132 Add system for preserving Map UIDs across edits. 2021-01-17 15:51:32 +01:00
kira-er
988cbf9a87 VV Enum (#1503) 2021-01-17 01:50:26 +01:00
Acruid
e26512001a Completely removed MsgSetTickRate, the NetConfigurationManager replaces the functionality. This builds on top of the previous commit.
Fixes bug where server was not sending the entire set of replicated cvars.
2021-01-16 15:33:44 -08:00
Pieter-Jan Briers
8e97982f1e Fix net.tickrate not being replicated correctly to clients. 2021-01-16 21:46:10 +01:00
15 changed files with 219 additions and 118 deletions

View File

@@ -153,7 +153,7 @@ namespace {nameSpace}
DiagnosticSeverity.Error,
true),
typeSymbol.Locations[0]));
return;
continue;
}
var txt = relevantXamlFile.GetText()?.ToString();
@@ -169,7 +169,7 @@ namespace {nameSpace}
DiagnosticSeverity.Error,
true),
Location.Create(xamlFileName, new TextSpan(0,0), new LinePositionSpan(new LinePosition(0,0),new LinePosition(0,0)))));
return;
continue;
}
try
@@ -189,7 +189,7 @@ namespace {nameSpace}
DiagnosticSeverity.Error,
true),
typeSymbol.Locations[0]));
return;
continue;
}
}
}

View File

@@ -15,7 +15,6 @@ using Robust.Shared.Interfaces.Timing;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Network;
using Robust.Shared.Network.Messages;
using Robust.Shared.Utility;
namespace Robust.Client
@@ -50,16 +49,28 @@ namespace Robust.Client
/// <inheritdoc />
public void Initialize()
{
_net.RegisterNetMessage<MsgSetTickRate>(MsgSetTickRate.NAME, HandleSetTickRate);
_net.Connected += OnConnected;
_net.ConnectFailed += OnConnectFailed;
_net.Disconnect += OnNetDisconnect;
_configManager.OnValueChanged(CVars.NetTickrate, TickRateChanged);
_playMan.Initialize();
_debugDrawMan.Initialize();
Reset();
}
private void TickRateChanged(int tickrate)
{
if (GameInfo != null)
{
GameInfo.TickRate = (byte) tickrate;
}
_timing.TickRate = (byte) tickrate;
Logger.InfoS("client", $"Tickrate changed to: {tickrate} on tick {_timing.CurTick}");
}
/// <inheritdoc />
public void ConnectToServer(DnsEndPoint endPoint)
{
@@ -119,11 +130,6 @@ namespace Robust.Client
var maxPlayers = _configManager.GetCVar<int>("game.maxplayers");
info.ServerMaxPlayers = maxPlayers;
var tickrate = _configManager.GetCVar<int>("net.tickrate");
info.TickRate = (byte) tickrate;
_timing.TickRate = (byte) tickrate;
Logger.InfoS("client", $"Tickrate changed to: {tickrate}");
var userName = _net.ServerChannel!.UserName;
var userId = _net.ServerChannel.UserId;
_discord.Update(info.ServerName, userName, info.ServerMaxPlayers.ToString());
@@ -168,6 +174,7 @@ namespace Robust.Client
private void Reset()
{
_configManager.ClearReceivedInitialNwVars();
OnRunLevelChanged(ClientRunLevel.Initialize);
}
@@ -194,12 +201,6 @@ namespace Robust.Client
Reset();
}
private void HandleSetTickRate(MsgSetTickRate message)
{
_timing.TickRate = message.NewTickRate;
Logger.InfoS("client", $"Tickrate changed to: {message.NewTickRate} on tick {_timing.CurTick}");
}
private void OnLocalStatusChanged(object? obj, StatusEventArgs eventArgs)
{
// player finished fully connecting to the server.

View File

@@ -1,10 +1,12 @@
using System;
using System.Globalization;
using System.Linq.Expressions;
using System.Reflection;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
namespace Robust.Client.ViewVariables.Editors
{
@@ -13,48 +15,31 @@ namespace Robust.Client.ViewVariables.Editors
protected override Control MakeUI(object? value)
{
DebugTools.Assert(value!.GetType().IsEnum);
var enumVal = (Enum)value;
var enumType = value.GetType();
var enumStorageType = enumType.GetEnumUnderlyingType();
var enumList = Enum.GetValues(enumType);
var hBox = new HBoxContainer
var optionButton = new OptionButton();
foreach (var val in enumList)
{
CustomMinimumSize = new Vector2(200, 0)
};
var label = val?.ToString();
if (label == null)
continue;
optionButton.AddItem(label, (int?)val);
}
var lineEdit = new LineEdit
{
Text = enumVal.ToString(),
Editable = !ReadOnly,
SizeFlagsHorizontal = Control.SizeFlags.FillExpand
};
optionButton.SelectId((int)value);
optionButton.Disabled = ReadOnly;
if (!ReadOnly)
{
lineEdit.OnTextEntered += e =>
optionButton.OnItemSelected += e =>
{
var parseSig = new []{typeof(string), typeof(NumberStyles), typeof(CultureInfo), enumStorageType.MakeByRefType()};
var parseMethod = enumStorageType.GetMethod("TryParse", parseSig);
DebugTools.AssertNotNull(parseMethod);
var parameters = new object?[] {e.Text, NumberStyles.Integer, CultureInfo.InvariantCulture, null};
var parseWorked = (bool)parseMethod!.Invoke(null, parameters)!;
if (parseWorked) // textbox was the underlying type
{
DebugTools.AssertNotNull(parameters[3]);
ValueChanged(parameters[3]);
}
else if(Enum.TryParse(enumType, e.Text, true, out var enumValue))
{
var underlyingVal = Convert.ChangeType(enumValue, enumStorageType);
ValueChanged(underlyingVal);
}
optionButton.SelectId(e.Id);
ValueChanged(e.Id);
};
}
hBox.AddChild(lineEdit);
return hBox;
return optionButton;
}
}
}

View File

@@ -238,7 +238,6 @@ namespace Robust.Server
{
netMan.Initialize(true);
netMan.StartServer();
netMan.RegisterNetMessage<MsgSetTickRate>(MsgSetTickRate.NAME);
}
catch (Exception e)
{
@@ -468,7 +467,6 @@ namespace Robust.Server
_time.TickRate = b;
Logger.InfoS("game", $"Tickrate changed to: {b} on tick {_time.CurTick}");
SendTickRateUpdateToClients(b);
});
_time.TickRate = (byte) _config.GetCVar(CVars.NetTickrate);
@@ -478,14 +476,6 @@ namespace Robust.Server
Logger.InfoS("srv", $"Max players: {MaxPlayers}");
}
private void SendTickRateUpdateToClients(byte newTickRate)
{
var msg = _network.CreateNetMessage<MsgSetTickRate>();
msg.NewTickRate = newTickRate;
_network.ServerSendToAll(msg);
}
// called right before main loop returns, do all saving/cleanup in here
private void Cleanup()
{

View File

@@ -5,6 +5,7 @@ using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Maps;
using Robust.Server.Interfaces.Player;
using Robust.Server.Interfaces.Timing;
using Robust.Server.Maps;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
@@ -111,7 +112,7 @@ namespace Robust.Server.Console.Commands
{
public string Command => "loadbp";
public string Description => "Loads a blueprint from disk into the game.";
public string Help => "loadbp <MapID> <Path>";
public string Help => "loadbp <MapID> <Path> [storeUids]";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
@@ -141,8 +142,14 @@ namespace Robust.Server.Console.Commands
return;
}
var loadOptions = new MapLoadOptions();
if (args.Length > 2)
{
loadOptions.StoreMapUids = bool.Parse(args[2]);
}
var mapLoader = IoCManager.Resolve<IMapLoader>();
mapLoader.LoadBlueprint(mapId, args[1]);
mapLoader.LoadBlueprint(mapId, args[1], loadOptions);
}
}

View File

@@ -162,7 +162,7 @@ namespace Robust.Server.GameObjects.Components.UserInterface
_stateDirty = true;
}
/// <summary>
/// Switches between closed and open for a specific client.
/// </summary>
@@ -183,8 +183,8 @@ namespace Robust.Server.GameObjects.Components.UserInterface
}
}
/// <summary>
/// Opens this interface for a specific client.
/// </summary>
@@ -263,6 +263,7 @@ namespace Robust.Server.GameObjects.Components.UserInterface
OnClosed?.Invoke(session);
_subscribedSessions.Remove(session);
_playerStateOverrides.Remove(session);
session.PlayerStatusChanged -= OnSessionOnPlayerStatusChanged;
if (_subscribedSessions.Count == 0)
{

View File

@@ -0,0 +1,18 @@
using Robust.Shared.GameObjects;
namespace Robust.Server.GameObjects
{
/// <summary>
/// Metadata component used to keep consistent UIDs inside map files cross saving.
/// </summary>
/// <remarks>
/// This component stores the previous map UID of entities from map load.
/// This can then be used to re-serialize the entity with the same UID for the merge driver to recognize.
/// </remarks>
public sealed class MapSaveIdComponent : Component
{
public override string Name => "MapSaveId";
public int Uid { get; set; }
}
}

View File

@@ -73,6 +73,8 @@ namespace Robust.Server.GameObjects
Register<DebugExceptionInitializeComponent>();
Register<DebugExceptionStartupComponent>();
#endif
Register<MapSaveIdComponent>();
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using Robust.Server.Maps;
using Robust.Shared.Map;
using YamlDotNet.RepresentationModel;
@@ -7,9 +8,11 @@ namespace Robust.Server.Interfaces.Maps
public interface IMapLoader
{
IMapGrid? LoadBlueprint(MapId mapId, string path);
IMapGrid? LoadBlueprint(MapId mapId, string path, MapLoadOptions options);
void SaveBlueprint(GridId gridId, string yamlPath);
void LoadMap(MapId mapId, string path);
void LoadMap(MapId mapId, string path, MapLoadOptions options);
void SaveMap(MapId mapId, string yamlPath);
event Action<YamlStream, string> LoadedMapData;

View File

@@ -0,0 +1,11 @@
namespace Robust.Server.Maps
{
public sealed class MapLoadOptions
{
/// <summary>
/// If true, UID components will be created for loaded entities
/// to maintain consistency upon subsequent savings.
/// </summary>
public bool StoreMapUids { get; set; }
}
}

View File

@@ -16,6 +16,7 @@ using Robust.Shared.GameObjects;
using System.Globalization;
using Robust.Shared.Interfaces.GameObjects;
using System.Linq;
using Robust.Server.GameObjects;
using Robust.Server.Interfaces.Timing;
using Robust.Shared.GameObjects.Components.Map;
using Robust.Shared.Interfaces.Serialization;
@@ -29,6 +30,8 @@ namespace Robust.Server.Maps
/// </summary>
public class MapLoader : IMapLoader
{
private static readonly MapLoadOptions DefaultLoadOptions = new();
private const int MapFormatVersion = 2;
[Dependency] private readonly IResourceManager _resMan = default!;
@@ -46,7 +49,8 @@ namespace Robust.Server.Maps
{
var grid = _mapManager.GetGrid(gridId);
var context = new MapContext(_mapManager, _tileDefinitionManager, _serverEntityManager, _pauseManager, _componentManager, _prototypeManager);
var context = new MapContext(_mapManager, _tileDefinitionManager, _serverEntityManager, _pauseManager,
_componentManager, _prototypeManager);
context.RegisterGrid(grid);
var root = context.Serialize();
var document = new YamlDocument(root);
@@ -68,6 +72,11 @@ namespace Robust.Server.Maps
/// <inheritdoc />
public IMapGrid? LoadBlueprint(MapId mapId, string path)
{
return LoadBlueprint(mapId, path, DefaultLoadOptions);
}
public IMapGrid? LoadBlueprint(MapId mapId, string path, MapLoadOptions options)
{
TextReader reader;
var resPath = new ResourcePath(path).ToRootedPath();
@@ -108,7 +117,8 @@ namespace Robust.Server.Maps
throw new InvalidDataException("Cannot instance map with multiple grids as blueprint.");
}
var context = new MapContext(_mapManager, _tileDefinitionManager, _serverEntityManager, _pauseManager, _componentManager, _prototypeManager, (YamlMappingNode)data.RootNode, mapId);
var context = new MapContext(_mapManager, _tileDefinitionManager, _serverEntityManager, _pauseManager,
_componentManager, _prototypeManager, (YamlMappingNode) data.RootNode, mapId, options);
context.Deserialize();
grid = context.Grids[0];
@@ -128,7 +138,8 @@ namespace Robust.Server.Maps
public void SaveMap(MapId mapId, string yamlPath)
{
Logger.InfoS("map", $"Saving map {mapId} to {yamlPath}");
var context = new MapContext(_mapManager, _tileDefinitionManager, _serverEntityManager, _pauseManager, _componentManager, _prototypeManager);
var context = new MapContext(_mapManager, _tileDefinitionManager, _serverEntityManager, _pauseManager,
_componentManager, _prototypeManager);
foreach (var grid in _mapManager.GetAllMapGrids(mapId))
{
context.RegisterGrid(grid);
@@ -149,11 +160,16 @@ namespace Robust.Server.Maps
stream.Save(new YamlMappingFix(new Emitter(writer)), false);
}
}
Logger.InfoS("map", "Save completed!");
}
/// <inheritdoc />
public void LoadMap(MapId mapId, string path)
{
LoadMap(mapId, path, DefaultLoadOptions);
}
public void LoadMap(MapId mapId, string path, MapLoadOptions options)
{
TextReader reader;
var resPath = new ResourcePath(path).ToRootedPath();
@@ -188,7 +204,8 @@ namespace Robust.Server.Maps
LoadedMapData?.Invoke(data.Stream, resPath.ToString());
var context = new MapContext(_mapManager, _tileDefinitionManager, _serverEntityManager, _pauseManager, _componentManager, _prototypeManager, (YamlMappingNode)data.RootNode, mapId);
var context = new MapContext(_mapManager, _tileDefinitionManager, _serverEntityManager, _pauseManager,
_componentManager, _prototypeManager, (YamlMappingNode) data.RootNode, mapId, options);
context.Deserialize();
if (!context.MapIsPostInit && _pauseManager.IsMapInitialized(mapId))
@@ -213,6 +230,7 @@ namespace Robust.Server.Maps
private readonly IComponentManager _componentManager;
private readonly IPrototypeManager _prototypeManager;
private readonly MapLoadOptions? _loadOptions;
private readonly Dictionary<GridId, int> GridIDMap = new();
public readonly List<IMapGrid> Grids = new();
@@ -225,8 +243,6 @@ namespace Robust.Server.Maps
private bool IsBlueprintMode => GridIDMap.Count == 1;
private int uidCounter;
private readonly YamlMappingNode RootNode;
private readonly MapId TargetMap;
@@ -239,7 +255,9 @@ namespace Robust.Server.Maps
public bool MapIsPostInit { get; private set; }
public MapContext(IMapManagerInternal maps, ITileDefinitionManager tileDefs, IServerEntityManagerInternal entities, IPauseManager pauseManager, IComponentManager componentManager, IPrototypeManager prototypeManager)
public MapContext(IMapManagerInternal maps, ITileDefinitionManager tileDefs,
IServerEntityManagerInternal entities, IPauseManager pauseManager, IComponentManager componentManager,
IPrototypeManager prototypeManager)
{
_mapManager = maps;
_tileDefinitionManager = tileDefs;
@@ -251,14 +269,17 @@ namespace Robust.Server.Maps
RootNode = new YamlMappingNode();
}
public MapContext(IMapManagerInternal maps, ITileDefinitionManager tileDefs, IServerEntityManagerInternal entities,
IPauseManager pauseManager, IComponentManager componentManager, IPrototypeManager prototypeManager, YamlMappingNode node, MapId targetMapId)
public MapContext(IMapManagerInternal maps, ITileDefinitionManager tileDefs,
IServerEntityManagerInternal entities,
IPauseManager pauseManager, IComponentManager componentManager, IPrototypeManager prototypeManager,
YamlMappingNode node, MapId targetMapId, MapLoadOptions options)
{
_mapManager = maps;
_tileDefinitionManager = tileDefs;
_serverEntityManager = entities;
_pauseManager = pauseManager;
_componentManager = componentManager;
_loadOptions = options;
RootNode = node;
TargetMap = targetMapId;
@@ -438,8 +459,8 @@ namespace Robust.Server.Maps
var newId = new GridId?();
YamlGridSerializer.DeserializeGrid(
_mapManager, TargetMap, ref newId,
(YamlMappingNode)grid["settings"],
(YamlSequenceNode)grid["chunks"],
(YamlMappingNode) grid["settings"],
(YamlSequenceNode) grid["chunks"],
_tileMap!,
_tileDefinitionManager
);
@@ -489,6 +510,12 @@ namespace Robust.Server.Maps
Entities.Add(entity);
UidEntityMap.Add(uid, entity.Uid);
_entitiesToDeserialize.Add((entity, entityDef));
if (_loadOptions!.StoreMapUids)
{
var comp = entity.AddComponent<MapSaveIdComponent>();
comp.Uid = uid;
}
}
}
@@ -501,7 +528,7 @@ namespace Robust.Server.Maps
{
foreach (var compData in componentList)
{
CurrentReadingEntityComponents[compData["type"].AsString()] = (YamlMappingNode)compData;
CurrentReadingEntityComponents[compData["type"].AsString()] = (YamlMappingNode) compData;
}
}
@@ -605,15 +632,55 @@ namespace Robust.Server.Maps
private void PopulateEntityList()
{
var withUid = new List<MapSaveIdComponent>();
var withoutUid = new List<IEntity>();
var takenIds = new HashSet<int>();
foreach (var entity in _serverEntityManager.GetEntities())
{
if (IsMapSavable(entity))
{
var uid = uidCounter++;
EntityUidMap.Add(entity.Uid, uid);
Entities.Add(entity);
if (entity.TryGetComponent(out MapSaveIdComponent? mapSaveId))
{
withUid.Add(mapSaveId);
}
else
{
withoutUid.Add(entity);
}
}
}
// Go over entities with a MapSaveIdComponent and assign those.
foreach (var mapIdComp in withUid)
{
var uid = mapIdComp.Uid;
if (takenIds.Contains(uid))
{
// Duplicate ID. Just pretend it doesn't have an ID and use the without path.
withoutUid.Add(mapIdComp.Owner);
}
else
{
EntityUidMap.Add(mapIdComp.Owner.Uid, uid);
takenIds.Add(uid);
}
}
var uidCounter = 0;
foreach (var entity in withoutUid)
{
while (takenIds.Contains(uidCounter))
{
// Find next available UID.
uidCounter += 1;
}
EntityUidMap.Add(entity.Uid, uidCounter);
takenIds.Add(uidCounter);
}
}
private void WriteEntitySection()
@@ -621,7 +688,7 @@ namespace Robust.Server.Maps
var entities = new YamlSequenceNode();
RootNode.Add("entities", entities);
foreach (var entity in Entities)
foreach (var entity in Entities.OrderBy(e => EntityUidMap[e.Uid]))
{
CurrentWritingEntity = entity;
var mapping = new YamlMappingNode
@@ -638,6 +705,9 @@ namespace Robust.Server.Maps
// See engine#636 for why the Distinct() call.
foreach (var component in entity.GetAllComponents())
{
if (component is MapSaveIdComponent)
continue;
var compMapping = new YamlMappingNode();
CurrentWritingComponent = component.Name;
var compSerializer = YamlObjectSerializer.NewWriter(compMapping, this);
@@ -683,6 +753,7 @@ namespace Robust.Server.Maps
return true;
}
}
if (type == typeof(EntityUid))
{
if (node.AsString() == "null")
@@ -694,7 +765,8 @@ namespace Robust.Server.Maps
var val = node.AsInt();
if (val >= Entities.Count)
{
Logger.ErrorS("map", "Error in map file: found local entity UID '{0}' which does not exist.", val);
Logger.ErrorS("map", "Error in map file: found local entity UID '{0}' which does not exist.",
val);
}
else
{
@@ -702,12 +774,14 @@ namespace Robust.Server.Maps
return true;
}
}
if (typeof(IEntity).IsAssignableFrom(type))
{
var val = node.AsInt();
if (val >= Entities.Count)
{
Logger.ErrorS("map", "Error in map file: found local entity UID '{0}' which does not exist.", val);
Logger.ErrorS("map", "Error in map file: found local entity UID '{0}' which does not exist.",
val);
}
else
{
@@ -715,6 +789,7 @@ namespace Robust.Server.Maps
return true;
}
}
obj = null;
return false;
}
@@ -766,6 +841,7 @@ namespace Robust.Server.Maps
return true;
}
}
node = null;
return false;
}
@@ -878,7 +954,7 @@ namespace Robust.Server.Maps
}
Stream = stream;
GridCount = ((YamlSequenceNode)RootNode["grids"]).Children.Count;
GridCount = ((YamlSequenceNode) RootNode["grids"]).Children.Count;
}
}
}

View File

@@ -54,6 +54,12 @@ namespace Robust.Shared.Configuration
/// </summary>
void FlushMessages();
/// <summary>
/// Clears internal flag for <see cref="ReceivedInitialNwVars"/>.
/// Must be called upon disconnect.
/// </summary>
void ClearReceivedInitialNwVars();
public event EventHandler ReceivedInitialNwVars;
}
@@ -77,7 +83,7 @@ namespace Robust.Shared.Configuration
_netManager.Connected += PeerConnected;
_netManager.Disconnect += PeerDisconnected;
}
_netManager.RegisterNetMessage<MsgConVars>(MsgConVars.NAME, HandleNetVarMessage);
}
@@ -94,10 +100,16 @@ namespace Robust.Shared.Configuration
private void HandleNetVarMessage(MsgConVars message)
{
if(!_receivedInitialNwVars)
ReceivedInitialNwVars?.Invoke(this, EventArgs.Empty);
{
_receivedInitialNwVars = true;
_receivedInitialNwVars = true;
_netVarsMessages.Add(message);
// apply the initial set immediately, so that they are available to
// for the rest of connection building
ApplyNetVarChange(message.MsgChannel, message.NetworkedVars);
ReceivedInitialNwVars?.Invoke(this, EventArgs.Empty);
}
else
_netVarsMessages.Add(message);
}
/// <inheritdoc />
@@ -135,7 +147,7 @@ namespace Robust.Shared.Configuration
_netVarsMessages.Clear();
}
private void ApplyNetVarChange(INetChannel msgChannel, List<(string name, object value)> networkedVars)
{
Logger.DebugS("cfg", "Handling replicated cvars...");
@@ -285,6 +297,11 @@ namespace Robust.Shared.Configuration
_netManager.ClientSendMessage(msg);
}
public void ClearReceivedInitialNwVars()
{
_receivedInitialNwVars = false;
}
private List<(string name, object value)> GetReplicatedVars()
{
var nwVars = new List<(string name, object value)>();
@@ -292,7 +309,7 @@ namespace Robust.Shared.Configuration
foreach (var cVar in _configVars.Values)
{
if (!cVar.Registered)
return nwVars;
continue;
if ((cVar.Flags & CVar.REPLICATED) == 0)
continue;

View File

@@ -206,8 +206,6 @@ namespace Robust.Shared.GameObjects
/// <inheritdoc />
public void RemoveComponents(EntityUid uid)
{
_entCompIndex.Remove(uid);
foreach (var comp in InSafeOrder(_entCompIndex[uid]))
{
RemoveComponentDeferred(comp, uid, false);
@@ -221,6 +219,10 @@ namespace Robust.Shared.GameObjects
{
RemoveComponentDeferred(comp, uid, true);
}
// DisposeComponents means the entity is getting deleted.
// Safe to wipe the entity out of the index.
_entCompIndex.Remove(uid);
}
private void RemoveComponentDeferred(Component component, EntityUid uid, bool removeProtected)
@@ -306,6 +308,7 @@ namespace Robust.Shared.GameObjects
var netId = component.NetID.Value;
_entNetIdDict[netId].Remove(entityUid);
_entCompIndex.Remove(entityUid, component);
// mark the owning entity as dirty for networking
component.Owner.Dirty();

View File

@@ -1,28 +0,0 @@
using Lidgren.Network;
using Robust.Shared.Interfaces.Network;
#nullable disable
namespace Robust.Shared.Network.Messages
{
public class MsgSetTickRate : NetMessage
{
#region REQUIRED
public static readonly MsgGroups GROUP = MsgGroups.Core;
public static readonly string NAME = nameof(MsgSetTickRate);
public MsgSetTickRate(INetChannel channel) : base(NAME, GROUP) { }
#endregion
public byte NewTickRate { get; set; }
public override void ReadFromBuffer(NetIncomingMessage buffer)
{
NewTickRate = buffer.ReadByte();
}
public override void WriteToBuffer(NetOutgoingMessage buffer)
{
buffer.Write(NewTickRate);
}
}
}

View File

@@ -685,7 +685,21 @@ namespace Robust.Shared.Network
_assignedUsernames.Remove(channel.UserName);
_assignedUserIds.Remove(channel.UserId);
OnDisconnected(channel, reason);
#if EXCEPTION_TOLERANCE
try
{
#endif
OnDisconnected(channel, reason);
#if EXCEPTION_TOLERANCE
}
catch (Exception e)
{
// A throw aborting in the middle of this method would be *really* bad
// and cause fun bugs like ghost clients sticking around.
// I say "would" as if it hasn't already happened...
Logger.ErrorS("net", "Caught exception in OnDisconnected handler:\n{0}", e);
}
#endif
_channels.Remove(connection);
peer.RemoveChannel(channel);
@@ -1004,6 +1018,7 @@ namespace Robust.Shared.Network
{
await conn(args);
}
return args;
}