Compare commits
2 Commits
1.0.180.47
...
1.0.182.32
Author | SHA1 | Date | |
---|---|---|---|
![]() |
79fe6a08ab | ||
![]() |
5e0f69e0e6 |
10
NLog.config
10
NLog.config
@@ -3,13 +3,13 @@
|
|||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
|
||||||
<targets>
|
<targets>
|
||||||
<target name="logfile" layout="${longdate} [${level:uppercase=true}] ${logger}: ${message}" xsi:type="File" fileName="Torch.log" deleteOldFileOnStartup="true"/>
|
<target xsi:type="File" name="main" layout="${time} [${level:uppercase=true}] ${logger}: ${message}" fileName="Logs\Torch-${shortdate}.log" />
|
||||||
<target name="console" layout="${longdate} [${level:uppercase=true}] ${logger}: ${message}" xsi:type="ColoredConsole" />
|
<target xsi:type="File" name="chat" layout="${longdate} ${message}" fileName="Logs\Chat.log" />
|
||||||
|
<target xsi:type="ColoredConsole" name="console" layout="${time} [${level:uppercase=true}] ${logger}: ${message}" />
|
||||||
</targets>
|
</targets>
|
||||||
|
|
||||||
<rules>
|
<rules>
|
||||||
<logger name="*" minlevel="Info" writeTo="logfile" />
|
<logger name="*" minlevel="Info" writeTo="main, console" />
|
||||||
<logger name="*" minlevel="Info" writeTo="console" />
|
<logger name="Chat" minlevel="Info" writeTo="chat" />
|
||||||
</rules>
|
</rules>
|
||||||
|
|
||||||
</nlog>
|
</nlog>
|
@@ -7,6 +7,7 @@
|
|||||||
bool RedownloadPlugins { get; set; }
|
bool RedownloadPlugins { get; set; }
|
||||||
bool AutomaticUpdates { get; set; }
|
bool AutomaticUpdates { get; set; }
|
||||||
bool RestartOnCrash { get; set; }
|
bool RestartOnCrash { get; set; }
|
||||||
|
int TickTimeout { get; set; }
|
||||||
|
|
||||||
bool Save(string path = null);
|
bool Save(string path = null);
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
[assembly: AssemblyVersion("1.0.169.376")]
|
[assembly: AssemblyVersion("1.0.182.329")]
|
||||||
[assembly: AssemblyFileVersion("1.0.169.376")]
|
[assembly: AssemblyFileVersion("1.0.182.329")]
|
@@ -291,6 +291,8 @@ quit";
|
|||||||
{
|
{
|
||||||
var ex = (Exception)e.ExceptionObject;
|
var ex = (Exception)e.ExceptionObject;
|
||||||
_log.Fatal(ex);
|
_log.Fatal(ex);
|
||||||
|
Console.WriteLine("Exiting in 5 seconds.");
|
||||||
|
Thread.Sleep(5000);
|
||||||
if (_restartOnCrash)
|
if (_restartOnCrash)
|
||||||
{
|
{
|
||||||
/* Throws an exception somehow and I'm too lazy to debug it.
|
/* Throws an exception somehow and I'm too lazy to debug it.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
[assembly: AssemblyVersion("1.0.169.376")]
|
[assembly: AssemblyVersion("1.0.182.329")]
|
||||||
[assembly: AssemblyFileVersion("1.0.169.376")]
|
[assembly: AssemblyFileVersion("1.0.182.329")]
|
@@ -15,15 +15,19 @@ namespace Torch.Server
|
|||||||
public string InstanceName { get; set; }
|
public string InstanceName { get; set; }
|
||||||
#warning World Path not implemented
|
#warning World Path not implemented
|
||||||
public string WorldPath { get; set; }
|
public string WorldPath { get; set; }
|
||||||
//public int Autosave { get; set; }
|
|
||||||
//public bool AutoRestart { get; set; }
|
|
||||||
//public bool LogChat { get; set; }
|
|
||||||
public bool AutomaticUpdates { get; set; } = true;
|
public bool AutomaticUpdates { get; set; } = true;
|
||||||
public bool RedownloadPlugins { get; set; }
|
public bool RedownloadPlugins { get; set; }
|
||||||
public bool RestartOnCrash { get; set; }
|
public bool RestartOnCrash { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// How long in seconds to wait before automatically resetting a frozen server.
|
||||||
|
/// </summary>
|
||||||
|
public int TickTimeout { get; set; } = 60;
|
||||||
|
/// <summary>
|
||||||
|
/// A list of plugins to install or update. TODO
|
||||||
|
/// </summary>
|
||||||
public List<string> Plugins { get; set; } = new List<string>();
|
public List<string> Plugins { get; set; } = new List<string>();
|
||||||
public Point WindowSize { get; set; } = new Point(800, 600);
|
internal Point WindowSize { get; set; } = new Point(800, 600);
|
||||||
public Point WindowPosition { get; set; } = new Point();
|
internal Point WindowPosition { get; set; } = new Point();
|
||||||
[NonSerialized]
|
[NonSerialized]
|
||||||
private string _path;
|
private string _path;
|
||||||
|
|
||||||
|
@@ -11,6 +11,7 @@ using System.Runtime.CompilerServices;
|
|||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Microsoft.Xml.Serialization.GeneratedAssembly;
|
using Microsoft.Xml.Serialization.GeneratedAssembly;
|
||||||
|
using Sandbox.Engine.Analytics;
|
||||||
using Sandbox.Game.Multiplayer;
|
using Sandbox.Game.Multiplayer;
|
||||||
using Sandbox.ModAPI;
|
using Sandbox.ModAPI;
|
||||||
using SteamSDK;
|
using SteamSDK;
|
||||||
@@ -35,9 +36,11 @@ namespace Torch.Server
|
|||||||
public TimeSpan ElapsedPlayTime { get => _elapsedPlayTime; set { _elapsedPlayTime = value; OnPropertyChanged(); } }
|
public TimeSpan ElapsedPlayTime { get => _elapsedPlayTime; set { _elapsedPlayTime = value; OnPropertyChanged(); } }
|
||||||
public Thread GameThread { get; private set; }
|
public Thread GameThread { get; private set; }
|
||||||
public ServerState State { get => _state; private set { _state = value; OnPropertyChanged(); } }
|
public ServerState State { get => _state; private set { _state = value; OnPropertyChanged(); } }
|
||||||
|
public bool IsRunning { get => _isRunning; set { _isRunning = value; OnPropertyChanged(); } }
|
||||||
public string InstanceName => Config?.InstanceName;
|
public string InstanceName => Config?.InstanceName;
|
||||||
public string InstancePath => Config?.InstancePath;
|
public string InstancePath => Config?.InstancePath;
|
||||||
|
|
||||||
|
private bool _isRunning;
|
||||||
private ServerState _state;
|
private ServerState _state;
|
||||||
private TimeSpan _elapsedPlayTime;
|
private TimeSpan _elapsedPlayTime;
|
||||||
private float _simRatio;
|
private float _simRatio;
|
||||||
@@ -47,6 +50,7 @@ namespace Torch.Server
|
|||||||
public TorchServer(TorchConfig config = null)
|
public TorchServer(TorchConfig config = null)
|
||||||
{
|
{
|
||||||
Config = config ?? new TorchConfig();
|
Config = config ?? new TorchConfig();
|
||||||
|
MyFakes.ENABLE_INFINARIO = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Init()
|
public override void Init()
|
||||||
@@ -55,7 +59,6 @@ namespace Torch.Server
|
|||||||
|
|
||||||
Log.Info($"Init server '{Config.InstanceName}' at '{Config.InstancePath}'");
|
Log.Info($"Init server '{Config.InstanceName}' at '{Config.InstancePath}'");
|
||||||
|
|
||||||
MyFakes.ENABLE_INFINARIO = false;
|
|
||||||
MyPerGameSettings.SendLogToKeen = false;
|
MyPerGameSettings.SendLogToKeen = false;
|
||||||
MyPerServerSettings.GameName = MyPerGameSettings.GameName;
|
MyPerServerSettings.GameName = MyPerGameSettings.GameName;
|
||||||
MyPerServerSettings.GameNameSafe = MyPerGameSettings.GameNameSafe;
|
MyPerServerSettings.GameNameSafe = MyPerGameSettings.GameNameSafe;
|
||||||
@@ -171,10 +174,10 @@ namespace Torch.Server
|
|||||||
SimulationRatio = Sync.ServerSimulationRatio;
|
SimulationRatio = Sync.ServerSimulationRatio;
|
||||||
ElapsedPlayTime = MySession.Static?.ElapsedPlayTime ?? default(TimeSpan);
|
ElapsedPlayTime = MySession.Static?.ElapsedPlayTime ?? default(TimeSpan);
|
||||||
|
|
||||||
if (_watchdog == null)
|
if (_watchdog == null && Instance.Config.TickTimeout > 0)
|
||||||
{
|
{
|
||||||
Log.Info("Starting server watchdog.");
|
Log.Info("Starting server watchdog.");
|
||||||
_watchdog = new Timer(CheckServerResponding, this, TimeSpan.Zero, TimeSpan.FromSeconds(30));
|
_watchdog = new Timer(CheckServerResponding, this, TimeSpan.Zero, TimeSpan.FromSeconds(Instance.Config.TickTimeout));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,12 +185,12 @@ namespace Torch.Server
|
|||||||
{
|
{
|
||||||
var mre = new ManualResetEvent(false);
|
var mre = new ManualResetEvent(false);
|
||||||
((TorchServer)state).Invoke(() => mre.Set());
|
((TorchServer)state).Invoke(() => mre.Set());
|
||||||
if (!mre.WaitOne(TimeSpan.FromSeconds(30)))
|
if (!mre.WaitOne(TimeSpan.FromSeconds(Instance.Config.TickTimeout)))
|
||||||
{
|
{
|
||||||
var mainThread = MySandboxGame.Static.UpdateThread;
|
var mainThread = MySandboxGame.Static.UpdateThread;
|
||||||
mainThread.Suspend();
|
mainThread.Suspend();
|
||||||
var stackTrace = new StackTrace(mainThread, true);
|
var stackTrace = new StackTrace(mainThread, true);
|
||||||
throw new TimeoutException($"Server watchdog detected that the server was frozen for at least 30 seconds.\n{stackTrace}");
|
throw new TimeoutException($"Server watchdog detected that the server was frozen for at least {Instance.Config.TickTimeout} seconds.\n{stackTrace}");
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Debug("Server watchdog responded");
|
Log.Debug("Server watchdog responded");
|
||||||
|
@@ -41,7 +41,7 @@ namespace Torch.Server.Views
|
|||||||
{
|
{
|
||||||
Entities.CurrentEntity = vm;
|
Entities.CurrentEntity = vm;
|
||||||
if (e.NewValue is GridViewModel gvm)
|
if (e.NewValue is GridViewModel gvm)
|
||||||
EditorFrame.Content = new Entities.GridView { DataContext = gvm};
|
EditorFrame.Content = new Entities.GridView {DataContext = gvm};
|
||||||
if (e.NewValue is BlockViewModel bvm)
|
if (e.NewValue is BlockViewModel bvm)
|
||||||
EditorFrame.Content = new BlockView {DataContext = bvm};
|
EditorFrame.Content = new BlockView {DataContext = bvm};
|
||||||
if (e.NewValue is VoxelMapViewModel vvm)
|
if (e.NewValue is VoxelMapViewModel vvm)
|
||||||
|
@@ -14,9 +14,9 @@
|
|||||||
<ListView.ItemTemplate>
|
<ListView.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<WrapPanel>
|
<WrapPanel>
|
||||||
<TextBlock Text="{Binding Name}" FontWeight="Bold"/>
|
<TextBlock Text="{Binding Value.Name}" FontWeight="Bold"/>
|
||||||
<TextBlock Text=" ("/>
|
<TextBlock Text=" ("/>
|
||||||
<TextBlock Text="{Binding State}"/>
|
<TextBlock Text="{Binding Value.State}"/>
|
||||||
<TextBlock Text=")"/>
|
<TextBlock Text=")"/>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
@@ -21,6 +21,7 @@ using Sandbox.ModAPI;
|
|||||||
using SteamSDK;
|
using SteamSDK;
|
||||||
using Torch.API;
|
using Torch.API;
|
||||||
using Torch.Managers;
|
using Torch.Managers;
|
||||||
|
using Torch.ViewModels;
|
||||||
using VRage.Game.ModAPI;
|
using VRage.Game.ModAPI;
|
||||||
|
|
||||||
namespace Torch.Server
|
namespace Torch.Server
|
||||||
@@ -45,20 +46,14 @@ namespace Torch.Server
|
|||||||
|
|
||||||
private void KickButton_Click(object sender, RoutedEventArgs e)
|
private void KickButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var player = PlayerList.SelectedItem as IMyPlayer;
|
var player = (KeyValuePair<ulong, PlayerViewModel>)PlayerList.SelectedItem;
|
||||||
if (player != null)
|
_server.Multiplayer.KickPlayer(player.Key);
|
||||||
{
|
|
||||||
_server.Multiplayer.KickPlayer(player.SteamUserId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BanButton_Click(object sender, RoutedEventArgs e)
|
private void BanButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var player = PlayerList.SelectedItem as IMyPlayer;
|
var player = (KeyValuePair<ulong, PlayerViewModel>) PlayerList.SelectedItem;
|
||||||
if (player != null)
|
_server.Multiplayer.BanPlayer(player.Key);
|
||||||
{
|
|
||||||
_server.Multiplayer.BanPlayer(player.SteamUserId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -42,8 +42,8 @@
|
|||||||
</TabItem>
|
</TabItem>
|
||||||
<TabItem Header="Chat/Players">
|
<TabItem Header="Chat/Players">
|
||||||
<DockPanel>
|
<DockPanel>
|
||||||
<local:PlayerListControl x:Name="PlayerList" DockPanel.Dock="Right" Width="250" IsEnabled="False" />
|
<local:PlayerListControl x:Name="PlayerList" DockPanel.Dock="Right" Width="250" />
|
||||||
<local:ChatControl x:Name="Chat" IsEnabled="False" />
|
<local:ChatControl x:Name="Chat" />
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
<TabItem Header="Entity Manager">
|
<TabItem Header="Entity Manager">
|
||||||
|
@@ -65,8 +65,6 @@ namespace Torch.Server
|
|||||||
private void BtnStart_Click(object sender, RoutedEventArgs e)
|
private void BtnStart_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
_config.Save();
|
_config.Save();
|
||||||
Chat.IsEnabled = true;
|
|
||||||
PlayerList.IsEnabled = true;
|
|
||||||
((Button) sender).IsEnabled = false;
|
((Button) sender).IsEnabled = false;
|
||||||
BtnStop.IsEnabled = true;
|
BtnStop.IsEnabled = true;
|
||||||
ConfigControl.SaveConfig();
|
ConfigControl.SaveConfig();
|
||||||
@@ -76,8 +74,6 @@ namespace Torch.Server
|
|||||||
private void BtnStop_Click(object sender, RoutedEventArgs e)
|
private void BtnStop_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
_config.Save();
|
_config.Save();
|
||||||
Chat.IsEnabled = false;
|
|
||||||
PlayerList.IsEnabled = false;
|
|
||||||
((Button) sender).IsEnabled = false;
|
((Button) sender).IsEnabled = false;
|
||||||
//HACK: Uncomment when restarting is possible.
|
//HACK: Uncomment when restarting is possible.
|
||||||
//BtnStart.IsEnabled = true;
|
//BtnStart.IsEnabled = true;
|
||||||
|
62
Torch/Collections/ObservableDictionary.cs
Normal file
62
Torch/Collections/ObservableDictionary.cs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Threading;
|
||||||
|
|
||||||
|
namespace Torch.Collections
|
||||||
|
{
|
||||||
|
public class ObservableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, INotifyCollectionChanged, INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public new void Add(TKey key, TValue value)
|
||||||
|
{
|
||||||
|
base.Add(key, value);
|
||||||
|
var kv = new KeyValuePair<TKey, TValue>(key, value);
|
||||||
|
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, kv));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public new bool Remove(TKey key)
|
||||||
|
{
|
||||||
|
if (!ContainsKey(key))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var kv = new KeyValuePair<TKey, TValue>(key, this[key]);
|
||||||
|
base.Remove(key);
|
||||||
|
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, kv));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
NotifyCollectionChangedEventHandler collectionChanged = CollectionChanged;
|
||||||
|
if (collectionChanged != null)
|
||||||
|
foreach (NotifyCollectionChangedEventHandler nh in collectionChanged.GetInvocationList())
|
||||||
|
{
|
||||||
|
var dispObj = nh.Target as DispatcherObject;
|
||||||
|
|
||||||
|
var dispatcher = dispObj?.Dispatcher;
|
||||||
|
if (dispatcher != null && !dispatcher.CheckAccess())
|
||||||
|
{
|
||||||
|
dispatcher.BeginInvoke(
|
||||||
|
(Action)(() => nh.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))),
|
||||||
|
DispatcherPriority.DataBind);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
nh.Invoke(this, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
}
|
||||||
|
}
|
@@ -76,6 +76,8 @@ namespace Torch.Commands
|
|||||||
{
|
{
|
||||||
var cmdText = new string(message.Skip(1).ToArray());
|
var cmdText = new string(message.Skip(1).ToArray());
|
||||||
var command = Commands.GetCommand(cmdText, out string argText);
|
var command = Commands.GetCommand(cmdText, out string argText);
|
||||||
|
if (command == null)
|
||||||
|
return null;
|
||||||
var cmdPath = string.Join(".", command.Path);
|
var cmdPath = string.Join(".", command.Path);
|
||||||
|
|
||||||
var splitArgs = Regex.Matches(argText, "(\"[^\"]+\"|\\S+)").Cast<Match>().Select(x => x.ToString().Replace("\"", "")).ToList();
|
var splitArgs = Regex.Matches(argText, "(\"[^\"]+\"|\\S+)").Cast<Match>().Select(x => x.ToString().Replace("\"", "")).ToList();
|
||||||
|
@@ -14,6 +14,7 @@ namespace Torch.Commands
|
|||||||
public class TorchCommands : CommandModule
|
public class TorchCommands : CommandModule
|
||||||
{
|
{
|
||||||
[Command("help", "Displays help for a command")]
|
[Command("help", "Displays help for a command")]
|
||||||
|
[Permission(MyPromoteLevel.None)]
|
||||||
public void Help()
|
public void Help()
|
||||||
{
|
{
|
||||||
var commandManager = ((TorchBase)Context.Torch).Commands;
|
var commandManager = ((TorchBase)Context.Torch).Commands;
|
||||||
@@ -45,6 +46,7 @@ namespace Torch.Commands
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Command("ver", "Shows the running Torch version.")]
|
[Command("ver", "Shows the running Torch version.")]
|
||||||
|
[Permission(MyPromoteLevel.None)]
|
||||||
public void Version()
|
public void Version()
|
||||||
{
|
{
|
||||||
var ver = Context.Torch.TorchVersion;
|
var ver = Context.Torch.TorchVersion;
|
||||||
@@ -52,6 +54,7 @@ namespace Torch.Commands
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Command("plugins", "Lists the currently loaded plugins.")]
|
[Command("plugins", "Lists the currently loaded plugins.")]
|
||||||
|
[Permission(MyPromoteLevel.None)]
|
||||||
public void Plugins()
|
public void Plugins()
|
||||||
{
|
{
|
||||||
var plugins = Context.Torch.Plugins.Select(p => p.Name);
|
var plugins = Context.Torch.Plugins.Select(p => p.Name);
|
||||||
@@ -59,7 +62,6 @@ namespace Torch.Commands
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Command("stop", "Stops the server.")]
|
[Command("stop", "Stops the server.")]
|
||||||
[Permission(MyPromoteLevel.Admin)]
|
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
Context.Respond("Stopping server.");
|
Context.Respond("Stopping server.");
|
||||||
|
@@ -19,10 +19,10 @@ using Sandbox.Engine.Multiplayer;
|
|||||||
using Sandbox.Game.Multiplayer;
|
using Sandbox.Game.Multiplayer;
|
||||||
using Sandbox.Game.World;
|
using Sandbox.Game.World;
|
||||||
using Sandbox.ModAPI;
|
using Sandbox.ModAPI;
|
||||||
using SharpDX.Toolkit.Collections;
|
|
||||||
using SteamSDK;
|
using SteamSDK;
|
||||||
using Torch.API;
|
using Torch.API;
|
||||||
using Torch.API.Managers;
|
using Torch.API.Managers;
|
||||||
|
using Torch.Collections;
|
||||||
using Torch.Commands;
|
using Torch.Commands;
|
||||||
using Torch.ViewModels;
|
using Torch.ViewModels;
|
||||||
using VRage.Game;
|
using VRage.Game;
|
||||||
@@ -126,6 +126,7 @@ namespace Torch.Managers
|
|||||||
|
|
||||||
private void OnSessionLoaded()
|
private void OnSessionLoaded()
|
||||||
{
|
{
|
||||||
|
_log.Info("Initializing Steam auth");
|
||||||
MyMultiplayer.Static.ClientKicked += OnClientKicked;
|
MyMultiplayer.Static.ClientKicked += OnClientKicked;
|
||||||
MyMultiplayer.Static.ClientLeft += OnClientLeft;
|
MyMultiplayer.Static.ClientLeft += OnClientLeft;
|
||||||
|
|
||||||
@@ -137,6 +138,7 @@ namespace Torch.Managers
|
|||||||
SteamServerAPI.Instance.GameServer.UserGroupStatus += UserGroupStatus;
|
SteamServerAPI.Instance.GameServer.UserGroupStatus += UserGroupStatus;
|
||||||
_members = (List<ulong>)typeof(MyDedicatedServerBase).GetField("m_members", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(MyMultiplayer.Static);
|
_members = (List<ulong>)typeof(MyDedicatedServerBase).GetField("m_members", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(MyMultiplayer.Static);
|
||||||
_waitingForGroup = (HashSet<ulong>)typeof(MyDedicatedServerBase).GetField("m_waitingForGroup", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(MyMultiplayer.Static);
|
_waitingForGroup = (HashSet<ulong>)typeof(MyDedicatedServerBase).GetField("m_waitingForGroup", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(MyMultiplayer.Static);
|
||||||
|
_log.Info("Steam auth initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClientKicked(ulong steamId)
|
private void OnClientKicked(ulong steamId)
|
||||||
@@ -146,9 +148,11 @@ namespace Torch.Managers
|
|||||||
|
|
||||||
private void OnClientLeft(ulong steamId, ChatMemberStateChangeEnum stateChange)
|
private void OnClientLeft(ulong steamId, ChatMemberStateChangeEnum stateChange)
|
||||||
{
|
{
|
||||||
_log.Info($"{GetSteamUsername(steamId)} disconnected ({(ConnectionState)stateChange}).");
|
|
||||||
Players.TryGetValue(steamId, out PlayerViewModel vm);
|
Players.TryGetValue(steamId, out PlayerViewModel vm);
|
||||||
PlayerLeft?.Invoke(vm ?? new PlayerViewModel(steamId));
|
if (vm == null)
|
||||||
|
vm = new PlayerViewModel(steamId);
|
||||||
|
_log.Info($"{vm.Name} ({vm.SteamId}) {(ConnectionState)stateChange}.");
|
||||||
|
PlayerLeft?.Invoke(vm);
|
||||||
Players.Remove(steamId);
|
Players.Remove(steamId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,6 +178,7 @@ namespace Torch.Managers
|
|||||||
if (handle.Method.Name == "GameServer_ValidateAuthTicketResponse")
|
if (handle.Method.Name == "GameServer_ValidateAuthTicketResponse")
|
||||||
{
|
{
|
||||||
SteamServerAPI.Instance.GameServer.ValidateAuthTicketResponse -= handle as ValidateAuthTicketResponse;
|
SteamServerAPI.Instance.GameServer.ValidateAuthTicketResponse -= handle as ValidateAuthTicketResponse;
|
||||||
|
_log.Debug("Removed GameServer_ValidateAuthTicketResponse");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -186,6 +191,7 @@ namespace Torch.Managers
|
|||||||
if (handle.Method.Name == "GameServer_UserGroupStatus")
|
if (handle.Method.Name == "GameServer_UserGroupStatus")
|
||||||
{
|
{
|
||||||
SteamServerAPI.Instance.GameServer.UserGroupStatus -= handle as UserGroupStatus;
|
SteamServerAPI.Instance.GameServer.UserGroupStatus -= handle as UserGroupStatus;
|
||||||
|
_log.Debug("Removed GameServer_UserGroupStatus");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -299,7 +305,8 @@ namespace Torch.Managers
|
|||||||
private void UserAccepted(ulong steamId)
|
private void UserAccepted(ulong steamId)
|
||||||
{
|
{
|
||||||
typeof(MyDedicatedServerBase).GetMethod("UserAccepted", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(MyMultiplayer.Static, new object[] {steamId});
|
typeof(MyDedicatedServerBase).GetMethod("UserAccepted", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(MyMultiplayer.Static, new object[] {steamId});
|
||||||
var vm = new PlayerViewModel(steamId);
|
var vm = new PlayerViewModel(steamId) {State = ConnectionState.Connected};
|
||||||
|
_log.Info($"Player {vm.Name} joined ({vm.SteamId})");
|
||||||
Players.Add(steamId, vm);
|
Players.Add(steamId, vm);
|
||||||
PlayerJoined?.Invoke(vm);
|
PlayerJoined?.Invoke(vm);
|
||||||
}
|
}
|
||||||
|
@@ -129,7 +129,7 @@ namespace Torch.Managers
|
|||||||
throw new TypeLoadException($"Plugin '{type.FullName}' is missing a {nameof(PluginAttribute)}");
|
throw new TypeLoadException($"Plugin '{type.FullName}' is missing a {nameof(PluginAttribute)}");
|
||||||
|
|
||||||
_log.Info($"Loading plugin {plugin.Name} ({plugin.Version})");
|
_log.Info($"Loading plugin {plugin.Name} ({plugin.Version})");
|
||||||
plugin.StoragePath = new FileInfo(asm.Location).Directory.FullName;
|
plugin.StoragePath = _torch.Config.InstancePath;
|
||||||
Plugins.Add(plugin);
|
Plugins.Add(plugin);
|
||||||
|
|
||||||
commands.RegisterPluginCommands(plugin);
|
commands.RegisterPluginCommands(plugin);
|
||||||
|
@@ -145,6 +145,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="ChatMessage.cs" />
|
<Compile Include="ChatMessage.cs" />
|
||||||
<Compile Include="Collections\KeyTree.cs" />
|
<Compile Include="Collections\KeyTree.cs" />
|
||||||
|
<Compile Include="Collections\ObservableDictionary.cs" />
|
||||||
<Compile Include="Collections\RollingAverage.cs" />
|
<Compile Include="Collections\RollingAverage.cs" />
|
||||||
<Compile Include="CommandLine.cs" />
|
<Compile Include="CommandLine.cs" />
|
||||||
<Compile Include="Commands\CategoryAttribute.cs" />
|
<Compile Include="Commands\CategoryAttribute.cs" />
|
||||||
|
@@ -231,15 +231,41 @@ namespace Torch
|
|||||||
Log.Info($"Executing assembly: {Assembly.GetEntryAssembly().FullName}");
|
Log.Info($"Executing assembly: {Assembly.GetEntryAssembly().FullName}");
|
||||||
Log.Info($"Executing directory: {AppDomain.CurrentDomain.BaseDirectory}");
|
Log.Info($"Executing directory: {AppDomain.CurrentDomain.BaseDirectory}");
|
||||||
|
|
||||||
MySession.OnLoading += () => SessionLoading?.Invoke();
|
MySession.OnLoading += OnSessionLoading;
|
||||||
MySession.AfterLoading += () => SessionLoaded?.Invoke();
|
MySession.AfterLoading += OnSessionLoaded;
|
||||||
MySession.OnUnloading += () => SessionUnloading?.Invoke();
|
MySession.OnUnloading += OnSessionUnloading;
|
||||||
MySession.OnUnloaded += () => SessionUnloaded?.Invoke();
|
MySession.OnUnloaded += OnSessionUnloaded;
|
||||||
RegisterVRagePlugin();
|
RegisterVRagePlugin();
|
||||||
|
|
||||||
_init = true;
|
_init = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnSessionLoading()
|
||||||
|
{
|
||||||
|
Log.Debug("Session loading");
|
||||||
|
foreach (var manager in _managers)
|
||||||
|
manager.Init();
|
||||||
|
SessionLoading?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSessionLoaded()
|
||||||
|
{
|
||||||
|
Log.Debug("Session loaded");
|
||||||
|
SessionLoaded?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSessionUnloading()
|
||||||
|
{
|
||||||
|
Log.Debug("Session unloading");
|
||||||
|
SessionUnloading?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSessionUnloaded()
|
||||||
|
{
|
||||||
|
Log.Debug("Session unloaded");
|
||||||
|
SessionUnloaded?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hook into the VRage plugin system for updates.
|
/// Hook into the VRage plugin system for updates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -269,8 +295,7 @@ namespace Torch
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public virtual void Init(object gameInstance)
|
public virtual void Init(object gameInstance)
|
||||||
{
|
{
|
||||||
foreach (var manager in _managers)
|
|
||||||
manager.Init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@@ -3,8 +3,10 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Sandbox.Engine.Multiplayer;
|
||||||
using SteamSDK;
|
using SteamSDK;
|
||||||
using Torch.API;
|
using Torch.API;
|
||||||
|
using VRage.Replication;
|
||||||
|
|
||||||
namespace Torch.ViewModels
|
namespace Torch.ViewModels
|
||||||
{
|
{
|
||||||
@@ -18,7 +20,7 @@ namespace Torch.ViewModels
|
|||||||
public PlayerViewModel(ulong steamId, string name = null)
|
public PlayerViewModel(ulong steamId, string name = null)
|
||||||
{
|
{
|
||||||
SteamId = steamId;
|
SteamId = steamId;
|
||||||
Name = name ?? SteamAPI.Instance?.Friends?.GetPersonaName(steamId) ?? "???";
|
Name = name ?? ((MyDedicatedServerBase)MyMultiplayerMinimalBase.Instance).GetMemberName(steamId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,7 @@ namespace Torch
|
|||||||
{
|
{
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
protected void OnPropertyChanged([CallerMemberName] string propName = "")
|
protected virtual void OnPropertyChanged([CallerMemberName] string propName = "")
|
||||||
{
|
{
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user