From b7fa57c9b7ae8dcac1b644b3d924283173331282 Mon Sep 17 00:00:00 2001 From: Westin Miller Date: Sun, 29 Oct 2017 09:53:20 -0700 Subject: [PATCH] Non-indexed remove causes a full reset (@Xero's issue) Removed ignore last session option. Implicitly true now. Asteroid generation options (fixes #151) --- Torch.API/Managers/IChatManagerClient.cs | 38 +++++++++++---- .../ViewModels/ConfigDedicatedViewModel.cs | 9 ++-- .../ViewModels/SessionSettingsViewModel.cs | 15 +++++- Torch.Server/Views/ChatControl.xaml.cs | 4 +- Torch.Server/Views/ConfigControl.xaml | 9 +++- Torch.Server/Views/PlayerListControl.xaml.cs | 21 +++++++- Torch/Collections/MTObservableCollection.cs | 15 +++--- Torch/Collections/MtObservableDictionary.cs | 48 +++++++++---------- Torch/Collections/MtObservableList.cs | 18 ++++--- .../Managers/ChatManager/ChatManagerClient.cs | 25 ++-------- .../Managers/ChatManager/ChatManagerServer.cs | 9 ++-- 11 files changed, 120 insertions(+), 91 deletions(-) diff --git a/Torch.API/Managers/IChatManagerClient.cs b/Torch.API/Managers/IChatManagerClient.cs index d9a0bba..2be2fc8 100644 --- a/Torch.API/Managers/IChatManagerClient.cs +++ b/Torch.API/Managers/IChatManagerClient.cs @@ -5,7 +5,9 @@ using System.Text; using System.Threading.Tasks; using Sandbox.Engine.Multiplayer; using Sandbox.Game.Multiplayer; +using VRage.Game; using VRage.Network; +using VRage.Replication; namespace Torch.API.Managers { @@ -19,13 +21,30 @@ namespace Torch.API.Managers /// /// Author's name /// Message - public TorchChatMessage(string author, string message) + /// Font + public TorchChatMessage(string author, string message, string font = MyFontEnum.Blue) { Timestamp = DateTime.Now; AuthorSteamId = null; Author = author; Message = message; - Font = "Blue"; + Font = font; + } + + /// + /// Creates a new torch chat message with the given author and message. + /// + /// Author's name + /// Author's steam ID + /// Message + /// Font + public TorchChatMessage(string author, ulong authorSteamId, string message, string font = MyFontEnum.Blue) + { + Timestamp = DateTime.Now; + AuthorSteamId = authorSteamId; + Author = author; + Message = message; + Font = font; } /// @@ -33,35 +52,36 @@ namespace Torch.API.Managers /// /// Author's steam ID /// Message - public TorchChatMessage(ulong authorSteamId, string message) + /// Font + public TorchChatMessage(ulong authorSteamId, string message, string font = MyFontEnum.Blue) { Timestamp = DateTime.Now; AuthorSteamId = authorSteamId; Author = MyMultiplayer.Static?.GetMemberName(authorSteamId) ?? "Player"; Message = message; - Font = "Blue"; + Font = font; } /// /// This message's timestamp. /// - public DateTime Timestamp; + public readonly DateTime Timestamp; /// /// The author's steam ID, if available. Else, null. /// - public ulong? AuthorSteamId; + public readonly ulong? AuthorSteamId; /// /// The author's name, if available. Else, null. /// - public string Author; + public readonly string Author; /// /// The message contents. /// - public string Message; + public readonly string Message; /// /// The font, or null if default. /// - public string Font; + public readonly string Font; } /// diff --git a/Torch.Server/ViewModels/ConfigDedicatedViewModel.cs b/Torch.Server/ViewModels/ConfigDedicatedViewModel.cs index 091fd16..5a6498e 100644 --- a/Torch.Server/ViewModels/ConfigDedicatedViewModel.cs +++ b/Torch.Server/ViewModels/ConfigDedicatedViewModel.cs @@ -26,6 +26,7 @@ namespace Torch.Server.ViewModels public ConfigDedicatedViewModel(MyConfigDedicated configDedicated) { _config = configDedicated; + _config.IgnoreLastSession = true; SessionSettings = new SessionSettingsViewModel(_config.SessionSettings); Administrators = string.Join(Environment.NewLine, _config.Administrators); Banned = string.Join(Environment.NewLine, _config.Banned); @@ -53,6 +54,8 @@ namespace Torch.Server.ViewModels Log.Warn($"'{mod}' is not a valid mod ID."); } + // Never ever + _config.IgnoreLastSession = true; _config.Save(path); } @@ -79,12 +82,6 @@ namespace Torch.Server.ViewModels set { _config.GroupID = value; OnPropertyChanged(); } } - public bool IgnoreLastSession - { - get { return _config.IgnoreLastSession; } - set { _config.IgnoreLastSession = value; OnPropertyChanged(); } - } - public string IP { get { return _config.IP; } diff --git a/Torch.Server/ViewModels/SessionSettingsViewModel.cs b/Torch.Server/ViewModels/SessionSettingsViewModel.cs index 35d569d..f045c2f 100644 --- a/Torch.Server/ViewModels/SessionSettingsViewModel.cs +++ b/Torch.Server/ViewModels/SessionSettingsViewModel.cs @@ -23,7 +23,7 @@ namespace Torch.Server.ViewModels /// public SessionSettingsViewModel() : this(new MyObjectBuilder_SessionSettings()) { - + } /// @@ -363,6 +363,19 @@ namespace Torch.Server.ViewModels get => _settings.WorldSizeKm; set { _settings.WorldSizeKm = value; OnPropertyChanged(); } } + /// + public float ProceduralDensity + { + get => _settings.ProceduralDensity; set { _settings.ProceduralDensity = value; OnPropertyChanged(); } + } + + /// + public int ProceduralSeed + { + get => _settings.ProceduralSeed; + set { _settings.ProceduralSeed = value; OnPropertyChanged(); } + } + /// public static implicit operator MyObjectBuilder_SessionSettings(SessionSettingsViewModel viewModel) { diff --git a/Torch.Server/Views/ChatControl.xaml.cs b/Torch.Server/Views/ChatControl.xaml.cs index 59334b2..6c966cc 100644 --- a/Torch.Server/Views/ChatControl.xaml.cs +++ b/Torch.Server/Views/ChatControl.xaml.cs @@ -136,12 +136,12 @@ namespace Torch.Server var commands = _server.CurrentSession?.Managers.GetManager(); if (commands != null && commands.IsCommand(text)) { - InsertMessage(new TorchChatMessage("Server", text) { Font = MyFontEnum.DarkBlue }); + InsertMessage(new TorchChatMessage("Server", text, MyFontEnum.DarkBlue)); _server.Invoke(() => { string response = commands.HandleCommandFromServer(text); if (!string.IsNullOrWhiteSpace(response)) - InsertMessage(new TorchChatMessage("Server", response) { Font = MyFontEnum.Blue }); + InsertMessage(new TorchChatMessage("Server", response, MyFontEnum.Blue)); }); } else diff --git a/Torch.Server/Views/ConfigControl.xaml b/Torch.Server/Views/ConfigControl.xaml index d8b8327..12b07f7 100644 --- a/Torch.Server/Views/ConfigControl.xaml +++ b/Torch.Server/Views/ConfigControl.xaml @@ -45,7 +45,6 @@ public partial class PlayerListControl : UserControl { + private static readonly Logger _log = LogManager.GetCurrentClassLogger(); + private ITorchServer _server; public PlayerListControl() @@ -65,13 +68,27 @@ namespace Torch.Server private void KickButton_Click(object sender, RoutedEventArgs e) { var player = (KeyValuePair)PlayerList.SelectedItem; - _server.CurrentSession?.Managers.GetManager()?.KickPlayer(player.Key); + try + { + _server.CurrentSession.Managers.GetManager().KickPlayer(player.Key); + } + catch (Exception ex) + { + _log.Warn(ex); + } } private void BanButton_Click(object sender, RoutedEventArgs e) { var player = (KeyValuePair)PlayerList.SelectedItem; - _server.CurrentSession?.Managers.GetManager()?.BanPlayer(player.Key); + try + { + _server.CurrentSession.Managers.GetManager().BanPlayer(player.Key); + } + catch (Exception ex) + { + _log.Warn(ex); + } } } } diff --git a/Torch/Collections/MTObservableCollection.cs b/Torch/Collections/MTObservableCollection.cs index 05a8fd3..6cc3d38 100644 --- a/Torch/Collections/MTObservableCollection.cs +++ b/Torch/Collections/MTObservableCollection.cs @@ -40,7 +40,7 @@ namespace Torch.Collections /// /// Collection to clear and reuse, or null if none /// The snapshot - protected abstract TC Snapshot(TC old); + protected abstract List Snapshot(List old); /// /// Marks all snapshots taken of this collection as dirty. @@ -104,7 +104,7 @@ namespace Torch.Collections OnPropertyChanged(nameof(Count)); OnCollectionChanged(oldIndex.HasValue ? new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, oldIndex.Value) - : new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item)); + : new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); return true; } } @@ -204,7 +204,6 @@ namespace Torch.Collections for (int i = invokeList.Length - 1; i >= 0; i--) { var wrapper = (DispatcherDelegate)invokeList[i].Target; - Debug.Assert(wrapper._dispatcher == CurrentDispatcher, "Adding and removing should be done from the same dispatcher"); if (wrapper._delegate.Equals(evt)) { _event -= wrapper.Invoke; @@ -215,7 +214,7 @@ namespace Torch.Collections private struct DispatcherDelegate { - internal readonly Dispatcher _dispatcher; + private readonly Dispatcher _dispatcher; internal readonly TEvtHandle _delegate; internal DispatcherDelegate(TEvtHandle del) @@ -244,7 +243,7 @@ namespace Torch.Collections private sealed class ThreadView { private readonly MtObservableCollection _owner; - private readonly WeakReference _snapshot; + private readonly WeakReference> _snapshot; /// /// The of the /// @@ -257,17 +256,17 @@ namespace Torch.Collections internal ThreadView(MtObservableCollection owner) { _owner = owner; - _snapshot = new WeakReference(null); + _snapshot = new WeakReference>(null); _snapshotVersion = 0; _snapshotRefCount = 0; } - private TC GetSnapshot() + private List GetSnapshot() { // reading the version number + snapshots using (_owner.Lock.ReadUsing()) { - if (!_snapshot.TryGetTarget(out TC currentSnapshot) || _snapshotVersion != _owner._version) + if (!_snapshot.TryGetTarget(out List currentSnapshot) || _snapshotVersion != _owner._version) { // Update the snapshot, using the old one if it isn't referenced. currentSnapshot = _owner.Snapshot(_snapshotRefCount == 0 ? currentSnapshot : null); diff --git a/Torch/Collections/MtObservableDictionary.cs b/Torch/Collections/MtObservableDictionary.cs index 3aea46a..feeda30 100644 --- a/Torch/Collections/MtObservableDictionary.cs +++ b/Torch/Collections/MtObservableDictionary.cs @@ -2,9 +2,6 @@ using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Torch.Utils; namespace Torch.Collections @@ -21,17 +18,16 @@ namespace Torch.Collections /// public MtObservableDictionary() : base(new Dictionary()) { - Keys = new ProxyCollection(this, Backing.Keys, (x) => x.Key); - Values = new ProxyCollection(this, Backing.Values, (x) => x.Value); + ObservableKeys = new ProxyCollection(this, Backing.Keys, (x) => x.Key); + ObservableValues = new ProxyCollection(this, Backing.Values, (x) => x.Value); } - protected override IDictionary Snapshot(IDictionary old) + protected override List> Snapshot(List> old) { if (old == null) - return new Dictionary(Backing); + return new List>(Backing); old.Clear(); - foreach (KeyValuePair k in Backing) - old.Add(k); + old.AddRange(Backing); return old; } @@ -83,10 +79,17 @@ namespace Torch.Collections } /// - public ICollection Keys { get; } + public ICollection Keys => ObservableKeys; /// - public ICollection Values { get; } + public ICollection Values => ObservableValues; + + // TODO when we rewrite this to use a sorted dictionary. + /// + private ProxyCollection ObservableKeys { get; } + + /// + private ProxyCollection ObservableValues { get; } internal void RaiseFullReset() { @@ -94,7 +97,11 @@ namespace Torch.Collections OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } - private class ProxyCollection : ICollection + /// + /// Proxy collection capable of raising notifications when the parent collection changes. + /// + /// Entry type + public class ProxyCollection : ICollection { private readonly MtObservableDictionary _owner; private readonly ICollection _backing; @@ -116,17 +123,13 @@ namespace Torch.Collections /// public void Add(TP item) { - using (_owner.Lock.WriteUsing()) - { - _backing.Add(item); - _owner.RaiseFullReset(); - } + throw new NotSupportedException(); } /// public void Clear() { - _owner.Clear(); + throw new NotSupportedException(); } /// @@ -146,13 +149,7 @@ namespace Torch.Collections /// public bool Remove(TP item) { - using (_owner.Lock.WriteUsing()) - { - if (!_backing.Remove(item)) - return false; - _owner.RaiseFullReset(); - return true; - } + throw new NotSupportedException(); } /// @@ -165,6 +162,7 @@ namespace Torch.Collections } } + /// public bool IsReadOnly => _backing.IsReadOnly; } } diff --git a/Torch/Collections/MtObservableList.cs b/Torch/Collections/MtObservableList.cs index 76d2075..ec64c64 100644 --- a/Torch/Collections/MtObservableList.cs +++ b/Torch/Collections/MtObservableList.cs @@ -29,7 +29,7 @@ namespace Torch.Collections { } - protected override IList Snapshot(IList old) + protected override List Snapshot(List old) { if (old == null) { @@ -37,11 +37,7 @@ namespace Torch.Collections return list; } old.Clear(); - if (old is List tmp) - tmp.AddRange(Backing); - else - foreach (T k in Backing) - old.Add(k); + old.AddRange(Backing); return old; } @@ -55,7 +51,7 @@ namespace Torch.Collections /// public void Insert(int index, T item) { - using(Lock.WriteUsing()) + using (Lock.WriteUsing()) { Backing.Insert(index, item); MarkSnapshotsDirty(); @@ -82,12 +78,13 @@ namespace Torch.Collections { get { - using(Lock.ReadUsing()) + using (Lock.ReadUsing()) return Backing[index]; } set { - using(Lock.ReadUsing()) { + using (Lock.ReadUsing()) + { T old = Backing[index]; Backing[index] = value; MarkSnapshotsDirty(); @@ -109,7 +106,8 @@ namespace Torch.Collections /// public void Sort(Func selector, IComparer comparer = null) { - using (Lock.ReadUsing()) { + using (Lock.ReadUsing()) + { comparer = comparer ?? Comparer.Default; if (Backing is List lst) lst.Sort(new TransformComparer(selector, comparer)); diff --git a/Torch/Managers/ChatManager/ChatManagerClient.cs b/Torch/Managers/ChatManager/ChatManagerClient.cs index f18a494..f435b77 100644 --- a/Torch/Managers/ChatManager/ChatManagerClient.cs +++ b/Torch/Managers/ChatManager/ChatManagerClient.cs @@ -113,12 +113,7 @@ namespace Torch.Managers.ChatManager { if (!sendToOthers) return; - var torchMsg = new TorchChatMessage() - { - AuthorSteamId = Sync.MyId, - Author = MySession.Static.LocalHumanPlayer?.DisplayName ?? "Player", - Message = messageText - }; + var torchMsg = new TorchChatMessage(MySession.Static.LocalHumanPlayer?.DisplayName ?? "Player", Sync.MyId, messageText); var consumed = false; MessageRecieved?.Invoke(torchMsg, ref consumed); if (!consumed) @@ -138,14 +133,8 @@ namespace Torch.Managers.ChatManager private void Multiplayer_ChatMessageReceived(ulong steamUserId, string message) { - var torchMsg = new TorchChatMessage() - { - AuthorSteamId = steamUserId, - Author = Torch.CurrentSession.Managers.GetManager() - ?.GetSteamUsername(steamUserId), - Font = (steamUserId == MyGameService.UserId) ? "DarkBlue" : "Blue", - Message = message - }; + var torchMsg = new TorchChatMessage(steamUserId, message, + (steamUserId == MyGameService.UserId) ? MyFontEnum.DarkBlue : MyFontEnum.Blue); var consumed = false; MessageRecieved?.Invoke(torchMsg, ref consumed); if (!consumed && HasHud) @@ -154,13 +143,7 @@ namespace Torch.Managers.ChatManager private void Multiplayer_ScriptedChatMessageReceived(string message, string author, string font) { - var torchMsg = new TorchChatMessage() - { - AuthorSteamId = null, - Author = author, - Font = font, - Message = message - }; + var torchMsg = new TorchChatMessage(author, message, font); var consumed = false; MessageRecieved?.Invoke(torchMsg, ref consumed); if (!consumed && HasHud) diff --git a/Torch/Managers/ChatManager/ChatManagerServer.cs b/Torch/Managers/ChatManager/ChatManagerServer.cs index f71900c..096e489 100644 --- a/Torch/Managers/ChatManager/ChatManagerServer.cs +++ b/Torch/Managers/ChatManager/ChatManagerServer.cs @@ -147,12 +147,9 @@ namespace Torch.Managers.ChatManager internal void RaiseMessageRecieved(ChatMsg message, ref bool consumed) { - var torchMsg = new TorchChatMessage() - { - AuthorSteamId = message.Author, - Author = MyMultiplayer.Static?.GetMemberName(message.Author) ?? $"user_{message.Author}", - Message = message.Text - }; + var torchMsg = + new TorchChatMessage(MyMultiplayer.Static?.GetMemberName(message.Author) ?? $"user_{message.Author}", + message.Author, message.Text); MessageProcessing?.Invoke(torchMsg, ref consumed); }