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 @@
-
@@ -174,6 +173,14 @@
DockPanel.Dock="Left" />
+
+
+
+
+
+
+
+
diff --git a/Torch.Server/Views/PlayerListControl.xaml.cs b/Torch.Server/Views/PlayerListControl.xaml.cs
index c9e9676..a920eb3 100644
--- a/Torch.Server/Views/PlayerListControl.xaml.cs
+++ b/Torch.Server/Views/PlayerListControl.xaml.cs
@@ -12,6 +12,7 @@ using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
+using NLog;
using Torch;
using Sandbox;
using Sandbox.Engine.Multiplayer;
@@ -34,6 +35,8 @@ namespace Torch.Server
///
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);
}