diff --git a/TestPlugin/Commands.cs b/TestPlugin/Commands.cs
deleted file mode 100644
index 6617b26..0000000
--- a/TestPlugin/Commands.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Sandbox;
-using Sandbox.Game.Entities;
-using Sandbox.Game.World;
-using Torch.Commands;
-using VRage.Game.Entity;
-using VRage.Game.ModAPI;
-
-namespace TestPlugin
-{
- public class Commands : CommandModule
- {
- [Command("Ban", "Bans a player from the game")]
- public void Ban()
- {
- Context.Torch.Multiplayer.SendMessage("Boop!");
- }
-
- [Command("Unban", "Unbans a player from the game")]
- public void Unban()
- {
- Context.Torch.Multiplayer.SendMessage("Beep!");
- }
- }
-}
diff --git a/TestPlugin/Plugin.cs b/TestPlugin/Plugin.cs
deleted file mode 100644
index 6017a95..0000000
--- a/TestPlugin/Plugin.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Torch;
-using Torch.API;
-using VRage.Plugins;
-
-namespace TestPlugin
-{
- [Plugin("Test Plugin", "1.3.3.7", "fed85d8d-8a29-4ab0-9869-4ad121f99d04")]
- public class Plugin : TorchPluginBase
- {
- ///
- public override void Init(ITorchBase torch)
- {
- base.Init(torch);
- //Torch.Log.Write($"Plugin init {Name}");
- }
-
- ///
- public override void Update()
- {
- //Torch.Log.Write($"Plugin update {Name}");
- }
-
- ///
- public override void Dispose()
- {
- //Torch.Log.Write($"Plugin unload {Name}");
- }
- }
-}
diff --git a/TestPlugin/Properties/AssemblyInfo.cs b/TestPlugin/Properties/AssemblyInfo.cs
deleted file mode 100644
index 95ea997..0000000
--- a/TestPlugin/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("TestPlugin")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("TestPlugin")]
-[assembly: AssemblyCopyright("Copyright © 2016")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("abd18a6c-f638-44e9-8e55-dedea321c600")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/TestPlugin/TestPlugin.csproj b/TestPlugin/TestPlugin.csproj
deleted file mode 100644
index 21772c3..0000000
--- a/TestPlugin/TestPlugin.csproj
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- {ABD18A6C-F638-44E9-8E55-DEDEA321C600}
- Library
- Properties
- TestPlugin
- TestPlugin
- v4.6.1
- 512
-
-
- true
- bin\x64\Debug\
- DEBUG;TRACE
- full
- x64
- prompt
- MinimumRecommendedRules.ruleset
-
-
- bin\x64\Release\
- TRACE
- true
- pdbonly
- x64
- prompt
- MinimumRecommendedRules.ruleset
-
-
-
- ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\SpaceEngineers\Bin64\Sandbox.Game.dll
-
-
-
-
-
-
-
-
-
-
- ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\SpaceEngineers\Bin64\VRage.dll
-
-
- False
- ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\SpaceEngineers\Bin64\VRage.Game.dll
-
-
-
-
-
-
-
-
-
-
- {FBA5D932-6254-4A1E-BAF4-E229FA94E3C2}
- Torch.API
-
-
- {7e01635c-3b67-472e-bcd6-c5539564f214}
- Torch
-
-
-
-
\ No newline at end of file
diff --git a/Torch.API/IPlayer.cs b/Torch.API/IPlayer.cs
new file mode 100644
index 0000000..db4d09e
--- /dev/null
+++ b/Torch.API/IPlayer.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using VRage.Game.ModAPI;
+
+namespace Torch.API
+{
+ public interface IPlayer
+ {
+ string Name { get; }
+ ulong SteamId { get; }
+ ConnectionState State { get; }
+ }
+}
diff --git a/Torch.API/ITorchBase.cs b/Torch.API/ITorchBase.cs
index 23a6313..e83aa63 100644
--- a/Torch.API/ITorchBase.cs
+++ b/Torch.API/ITorchBase.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using Torch.API.Managers;
using VRage.Game.ModAPI;
namespace Torch.API
@@ -14,7 +15,7 @@ namespace Torch.API
event Action SessionUnloading;
event Action SessionUnloaded;
ITorchConfig Config { get; }
- IMultiplayer Multiplayer { get; }
+ IMultiplayerManager Multiplayer { get; }
IPluginManager Plugins { get; }
Version TorchVersion { get; }
void Invoke(Action action);
@@ -25,6 +26,7 @@ namespace Torch.API
void Start();
void Stop();
void Init();
+ T GetManager() where T : class, IManager;
}
public interface ITorchServer : ITorchBase
diff --git a/Torch.API/Managers/IManager.cs b/Torch.API/Managers/IManager.cs
new file mode 100644
index 0000000..6274262
--- /dev/null
+++ b/Torch.API/Managers/IManager.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Torch.API.Managers
+{
+ public interface IManager
+ {
+ void Init();
+ }
+}
diff --git a/Torch.API/IMultiplayer.cs b/Torch.API/Managers/IMultiplayerManager.cs
similarity index 74%
rename from Torch.API/IMultiplayer.cs
rename to Torch.API/Managers/IMultiplayerManager.cs
index e873657..4a52844 100644
--- a/Torch.API/IMultiplayer.cs
+++ b/Torch.API/Managers/IMultiplayerManager.cs
@@ -4,20 +4,19 @@ using System.Collections.ObjectModel;
using VRage.Game;
using VRage.Game.ModAPI;
-namespace Torch.API
+namespace Torch.API.Managers
{
public delegate void MessageReceivedDel(IChatMessage message, ref bool sendToOthers);
- public interface IMultiplayer
+ public interface IMultiplayerManager : IManager
{
- event Action PlayerJoined;
- event Action PlayerLeft;
+ event Action PlayerJoined;
+ event Action PlayerLeft;
event MessageReceivedDel MessageReceived;
void SendMessage(string message, string author = "Server", long playerId = 0, string font = MyFontEnum.Blue);
void KickPlayer(ulong steamId);
void BanPlayer(ulong steamId, bool banned = true);
IMyPlayer GetPlayerBySteamId(ulong id);
IMyPlayer GetPlayerByName(string name);
- List ChatHistory { get; }
}
}
\ No newline at end of file
diff --git a/Torch.API/Managers/INetworkManager.cs b/Torch.API/Managers/INetworkManager.cs
new file mode 100644
index 0000000..dc14f60
--- /dev/null
+++ b/Torch.API/Managers/INetworkManager.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using VRage;
+using VRage.Library.Collections;
+using VRage.Network;
+
+namespace Torch.API.Managers
+{
+ public interface INetworkManager : IManager
+ {
+ void RegisterNetworkHandler(INetworkHandler handler);
+ }
+
+ public interface INetworkHandler
+ {
+ bool CanHandle(CallSite callSite);
+ bool Handle(ulong remoteUserId, CallSite site, BitStream stream, object obj, MyPacket packet);
+ }
+}
diff --git a/Torch.API/IPluginManager.cs b/Torch.API/Managers/IPluginManager.cs
similarity index 74%
rename from Torch.API/IPluginManager.cs
rename to Torch.API/Managers/IPluginManager.cs
index 9453977..7d685ba 100644
--- a/Torch.API/IPluginManager.cs
+++ b/Torch.API/Managers/IPluginManager.cs
@@ -4,14 +4,13 @@ using Torch.API.Plugins;
using VRage.Collections;
using VRage.Plugins;
-namespace Torch.API
+namespace Torch.API.Managers
{
- public interface IPluginManager : IEnumerable
+ public interface IPluginManager : IManager, IEnumerable
{
event Action> PluginsLoaded;
List Plugins { get; }
void UpdatePlugins();
- void Init();
void DisposePlugins();
}
}
\ No newline at end of file
diff --git a/Torch.API/Torch.API.csproj b/Torch.API/Torch.API.csproj
index 6a146de..3a737c3 100644
--- a/Torch.API/Torch.API.csproj
+++ b/Torch.API/Torch.API.csproj
@@ -35,6 +35,7 @@
False
..\GameBinaries\HavokWrapper.dll
+ False
..\packages\NLog.4.4.1\lib\net45\NLog.dll
@@ -45,30 +46,37 @@
False
..\GameBinaries\Sandbox.Common.dll
+ False
False
..\GameBinaries\Sandbox.Game.dll
+ False
False
..\GameBinaries\Sandbox.Graphics.dll
+ False
False
..\GameBinaries\SpaceEngineers.Game.dll
+ False
False
..\GameBinaries\SpaceEngineers.ObjectBuilders.dll
+ False
False
..\GameBinaries\SpaceEngineers.ObjectBuilders.XmlSerializers.dll
+ False
False
..\GameBinaries\SteamSDK.dll
+ False
@@ -85,59 +93,75 @@
..\GameBinaries\VRage.dll
+ False
False
..\GameBinaries\VRage.Audio.dll
+ False
..\GameBinaries\VRage.Dedicated.dll
+ False
False
..\GameBinaries\VRage.Game.dll
+ False
False
..\GameBinaries\VRage.Game.XmlSerializers.dll
+ False
False
..\GameBinaries\VRage.Input.dll
+ False
..\GameBinaries\VRage.Library.dll
+ False
False
..\GameBinaries\VRage.Math.dll
+ False
False
..\GameBinaries\VRage.Native.dll
+ False
False
..\GameBinaries\VRage.OpenVRWrapper.dll
+ False
False
..\GameBinaries\VRage.Render.dll
+ False
False
..\GameBinaries\VRage.Render11.dll
+ False
False
..\GameBinaries\VRage.Scripting.dll
+ False
-
-
+
+
+
+
+
diff --git a/Torch.Client/Properties/AssemblyInfo.cs b/Torch.Client/Properties/AssemblyInfo.cs
index cd9dab5..f623ac6 100644
--- a/Torch.Client/Properties/AssemblyInfo.cs
+++ b/Torch.Client/Properties/AssemblyInfo.cs
@@ -1,4 +1,4 @@
using System.Reflection;
-[assembly: AssemblyVersion("1.0.168.389")]
-[assembly: AssemblyFileVersion("1.0.168.389")]
\ No newline at end of file
+[assembly: AssemblyVersion("1.0.169.376")]
+[assembly: AssemblyFileVersion("1.0.169.376")]
\ No newline at end of file
diff --git a/Torch.Client/TorchMainMenuScreen.cs b/Torch.Client/TorchMainMenuScreen.cs
index 6ce982f..c0078e4 100644
--- a/Torch.Client/TorchMainMenuScreen.cs
+++ b/Torch.Client/TorchMainMenuScreen.cs
@@ -1,4 +1,5 @@
-using System;
+#pragma warning disable 618
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -19,6 +20,7 @@ namespace Torch.Client
public override void RecreateControls(bool constructor)
{
base.RecreateControls(constructor);
+
var buttonSize = MyGuiControlButton.GetVisualStyle(MyGuiControlButtonStyleEnum.Default).NormalTexture.MinSizeGui;
Vector2 leftButtonPositionOrigin = MyGuiManager.ComputeFullscreenGuiCoordinate(MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_BOTTOM) + new Vector2(buttonSize.X / 2f, 0f);
var btn = MakeButton(leftButtonPositionOrigin - 9 * MyGuiConstants.MENU_BUTTONS_POSITION_DELTA, MyStringId.GetOrCompute("Torch"), TorchButtonClicked);
diff --git a/Torch.Server/Managers/ConfigManager.cs b/Torch.Server/Managers/ConfigManager.cs
new file mode 100644
index 0000000..b655391
--- /dev/null
+++ b/Torch.Server/Managers/ConfigManager.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Sandbox.Engine.Utils;
+using Torch.API;
+using Torch.API.Managers;
+using Torch.Managers;
+using Torch.Server.ViewModels;
+using VRage.Game;
+
+namespace Torch.Server.Managers
+{
+ //TODO
+ public class ConfigManager : Manager
+ {
+ private const string CONFIG_NAME = "SpaceEngineers-Dedicated.cfg";
+ public ConfigDedicatedViewModel DedicatedConfig { get; set; }
+ public TorchConfig TorchConfig { get; set; }
+
+ public ConfigManager(ITorchBase torchInstance) : base(torchInstance)
+ {
+
+ }
+
+ ///
+ public override void Init()
+ {
+ LoadInstance(Torch.Config.InstancePath);
+ }
+
+ public void LoadInstance(string path)
+ {
+ if (!Directory.Exists(path))
+ throw new FileNotFoundException($"Instance directory not found at '{path}'");
+
+ var configPath = Path.Combine(path, CONFIG_NAME);
+ var config = new MyConfigDedicated(configPath);
+ config.Load();
+ DedicatedConfig = new ConfigDedicatedViewModel(config);
+ }
+
+ ///
+ /// Creates a skeleton of a DS instance folder at the given directory.
+ ///
+ ///
+ public void CreateInstance(string path)
+ {
+ if (Directory.Exists(path))
+ return;
+
+ Directory.CreateDirectory(path);
+ var savesPath = Path.Combine(path, "Saves");
+ Directory.CreateDirectory(savesPath);
+ var modsPath = Path.Combine(path, "Mods");
+ Directory.CreateDirectory(modsPath);
+ LoadInstance(path);
+ }
+ }
+}
diff --git a/Torch.Server/Managers/DSConfigManager.cs b/Torch.Server/Managers/DSConfigManager.cs
deleted file mode 100644
index ef75674..0000000
--- a/Torch.Server/Managers/DSConfigManager.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Sandbox.Engine.Utils;
-using Torch.Server.ViewModels;
-using VRage.Game;
-
-namespace Torch.Server.Managers
-{
- public class DSConfigManager
- {
- public ConfigDedicatedViewModel Config { get; set; }
- private ConfigDedicatedViewModel _viewModel;
-
- public DSConfigManager()
- {
- //Config.
- }
-
- ///
- /// Creates a skeleton of a DS instance folder at the given directory.
- ///
- ///
- public void CreateInstance(string path)
- {
- if (Directory.Exists(path))
- return;
-
- Directory.CreateDirectory(path);
- var saves = Path.Combine(path, "Saves");
- Directory.CreateDirectory(saves);
- var mods = Path.Combine(path, "Mods");
- Directory.CreateDirectory(mods);
- }
- }
-}
diff --git a/Torch.Server/Program.cs b/Torch.Server/Program.cs
index 90710ee..0d357cd 100644
--- a/Torch.Server/Program.cs
+++ b/Torch.Server/Program.cs
@@ -42,6 +42,9 @@ namespace Torch.Server
[STAThread]
public static void Main(string[] args)
{
+ //Ensures that all the files are downloaded in the Torch directory.
+ Directory.SetCurrentDirectory(new FileInfo(typeof(Program).Assembly.Location).Directory.ToString());
+
IsManualInstall = Directory.GetCurrentDirectory().Contains("DedicatedServer64");
if (!IsManualInstall)
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
@@ -72,7 +75,7 @@ namespace Torch.Server
if (!IsManualInstall)
{
- new DSConfigManager().CreateInstance("Instance");
+ new ConfigManager().CreateInstance("Instance");
options.InstancePath = Path.GetFullPath("Instance");
_log.Warn("Would you like to enable automatic updates? (Y/n):");
@@ -81,7 +84,10 @@ namespace Torch.Server
var autoUpdate = !input.Equals("n", StringComparison.InvariantCultureIgnoreCase);
options.AutomaticUpdates = autoUpdate;
if (autoUpdate)
- _log.Info("Automatic updates enabled.");
+ {
+ _log.Info("Automatic updates enabled, updating server.");
+ RunSteamCmd();
+ }
}
//var setupDialog = new FirstTimeSetup { DataContext = options };
@@ -267,11 +273,10 @@ quit";
{
try
{
- var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location) ?? AppDomain.CurrentDomain.BaseDirectory;
- string asmPath = Path.Combine(basePath, "DedicatedServer64", new AssemblyName(args.Name).Name + ".dll");
+ var basePath = Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), "DedicatedServer64");
+ string asmPath = Path.Combine(basePath, new AssemblyName(args.Name).Name + ".dll");
if (File.Exists(asmPath))
return Assembly.LoadFrom(asmPath);
-
}
catch
{
diff --git a/Torch.Server/Properties/AssemblyInfo.cs b/Torch.Server/Properties/AssemblyInfo.cs
index cd9dab5..f623ac6 100644
--- a/Torch.Server/Properties/AssemblyInfo.cs
+++ b/Torch.Server/Properties/AssemblyInfo.cs
@@ -1,4 +1,4 @@
using System.Reflection;
-[assembly: AssemblyVersion("1.0.168.389")]
-[assembly: AssemblyFileVersion("1.0.168.389")]
\ No newline at end of file
+[assembly: AssemblyVersion("1.0.169.376")]
+[assembly: AssemblyFileVersion("1.0.169.376")]
\ No newline at end of file
diff --git a/Torch.Server/Torch.Server.csproj b/Torch.Server/Torch.Server.csproj
index 8f574bb..2ea886a 100644
--- a/Torch.Server/Torch.Server.csproj
+++ b/Torch.Server/Torch.Server.csproj
@@ -51,10 +51,12 @@
False
..\GameBinaries\Microsoft.CodeAnalysis.dll
+ False
False
..\GameBinaries\Microsoft.CodeAnalysis.CSharp.dll
+ False
..\packages\NLog.4.4.1\lib\net45\NLog.dll
@@ -63,30 +65,37 @@
False
..\GameBinaries\Sandbox.Common.dll
+ False
False
..\GameBinaries\Sandbox.Game.dll
+ False
False
..\GameBinaries\Sandbox.Graphics.dll
+ False
False
..\GameBinaries\SpaceEngineers.Game.dll
+ False
False
..\GameBinaries\SpaceEngineers.ObjectBuilders.dll
+ False
False
..\GameBinaries\SpaceEngineers.ObjectBuilders.XmlSerializers.dll
+ False
False
..\GameBinaries\SteamSDK.dll
+ False
@@ -107,6 +116,7 @@
False
..\GameBinaries\VRage.dll
+ False
False
@@ -115,53 +125,64 @@
False
..\GameBinaries\VRage.Dedicated.dll
+ False
False
..\GameBinaries\VRage.Game.dll
+ False
False
..\GameBinaries\VRage.Game.XmlSerializers.dll
+ False
False
..\GameBinaries\VRage.Input.dll
+ False
False
..\GameBinaries\VRage.Library.dll
+ False
False
..\GameBinaries\VRage.Math.dll
+ False
False
..\GameBinaries\VRage.Native.dll
+ False
False
..\GameBinaries\VRage.OpenVRWrapper.dll
+ False
False
..\GameBinaries\VRage.Render.dll
+ False
False
..\GameBinaries\VRage.Render11.dll
+ False
False
..\GameBinaries\VRage.Scripting.dll
+ False
-
+
@@ -171,6 +192,7 @@
+
Component
@@ -187,6 +209,7 @@
+
diff --git a/Torch/TorchConfig.cs b/Torch.Server/TorchConfig.cs
similarity index 95%
rename from Torch/TorchConfig.cs
rename to Torch.Server/TorchConfig.cs
index d3408bf..43843b0 100644
--- a/Torch/TorchConfig.cs
+++ b/Torch.Server/TorchConfig.cs
@@ -1,15 +1,11 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using System.Windows;
using System.Xml.Serialization;
using NLog;
-using Sandbox.ModAPI.Ingame;
-namespace Torch
+namespace Torch.Server
{
public class TorchConfig : ITorchConfig
{
diff --git a/Torch.Server/TorchServer.cs b/Torch.Server/TorchServer.cs
index d62e0ec..6d39984 100644
--- a/Torch.Server/TorchServer.cs
+++ b/Torch.Server/TorchServer.cs
@@ -9,12 +9,10 @@ using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Principal;
-using System.Text;
using System.Threading;
-using Havok;
using Microsoft.Xml.Serialization.GeneratedAssembly;
-using Sandbox.Game.Entities.Cube;
using Sandbox.Game.Multiplayer;
+using Sandbox.ModAPI;
using SteamSDK;
using Torch.API;
using VRage.Dedicated;
@@ -25,8 +23,8 @@ using VRage.Game.SessionComponents;
using VRage.Library;
using VRage.ObjectBuilders;
using VRage.Plugins;
-using VRage.Trace;
using VRage.Utils;
+#pragma warning disable 618
namespace Torch.Server
{
@@ -44,6 +42,7 @@ namespace Torch.Server
private TimeSpan _elapsedPlayTime;
private float _simRatio;
private readonly AutoResetEvent _stopHandle = new AutoResetEvent(false);
+ private Timer _watchdog;
public TorchServer(TorchConfig config = null)
{
@@ -171,6 +170,27 @@ namespace Torch.Server
base.Update();
SimulationRatio = Sync.ServerSimulationRatio;
ElapsedPlayTime = MySession.Static?.ElapsedPlayTime ?? default(TimeSpan);
+
+ if (_watchdog == null)
+ {
+ Log.Info("Starting server watchdog.");
+ _watchdog = new Timer(CheckServerResponding, this, TimeSpan.Zero, TimeSpan.FromSeconds(30));
+ }
+ }
+
+ private static void CheckServerResponding(object state)
+ {
+ var mre = new ManualResetEvent(false);
+ ((TorchServer)state).Invoke(() => mre.Set());
+ if (!mre.WaitOne(TimeSpan.FromSeconds(30)))
+ {
+ var mainThread = MySandboxGame.Static.UpdateThread;
+ mainThread.Suspend();
+ var stackTrace = new StackTrace(mainThread, true);
+ throw new TimeoutException($"Server watchdog detected that the server was frozen for at least 30 seconds.\n{stackTrace}");
+ }
+
+ Log.Debug("Server watchdog responded");
}
///
diff --git a/Torch.Server/ViewModels/ConfigDedicatedViewModel.cs b/Torch.Server/ViewModels/ConfigDedicatedViewModel.cs
index 7890a64..0414e3b 100644
--- a/Torch.Server/ViewModels/ConfigDedicatedViewModel.cs
+++ b/Torch.Server/ViewModels/ConfigDedicatedViewModel.cs
@@ -4,6 +4,7 @@ using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using NLog;
using Sandbox.Engine.Utils;
using VRage.Game;
using VRage.Game.ModAPI;
@@ -12,6 +13,7 @@ namespace Torch.Server.ViewModels
{
public class ConfigDedicatedViewModel : ViewModel
{
+ private static readonly Logger Log = LogManager.GetLogger("Config");
private MyConfigDedicated _config;
public ConfigDedicatedViewModel() : this(new MyConfigDedicated(""))
@@ -42,7 +44,12 @@ namespace Torch.Server.ViewModels
_config.Mods.Clear();
foreach (var mod in Mods.Split(newline, StringSplitOptions.RemoveEmptyEntries))
- _config.Mods.Add(ulong.Parse(mod));
+ {
+ if (ulong.TryParse(mod, out ulong modId))
+ _config.Mods.Add(modId);
+ else
+ Log.Warn($"'{mod}' is not a valid mod ID.");
+ }
_config.Save(path);
}
diff --git a/Torch.Server/ViewModels/Entities/Blocks/BlockViewModel.cs b/Torch.Server/ViewModels/Entities/Blocks/BlockViewModel.cs
index 57f2cad..56aa4ed 100644
--- a/Torch.Server/ViewModels/Entities/Blocks/BlockViewModel.cs
+++ b/Torch.Server/ViewModels/Entities/Blocks/BlockViewModel.cs
@@ -47,6 +47,9 @@ namespace Torch.Server.ViewModels.Blocks
public BlockViewModel(IMyTerminalBlock block, EntityTreeViewModel tree) : base(block, tree)
{
Block = block;
+ if (Block == null)
+ return;
+
var propList = new List();
block.GetProperties(propList);
foreach (var prop in propList)
diff --git a/Torch.Server/ViewModels/Entities/GridViewModel.cs b/Torch.Server/ViewModels/Entities/GridViewModel.cs
index 1ed0e62..3dd5363 100644
--- a/Torch.Server/ViewModels/Entities/GridViewModel.cs
+++ b/Torch.Server/ViewModels/Entities/GridViewModel.cs
@@ -1,14 +1,16 @@
using System.Linq;
+using NLog;
using Sandbox.Game.Entities;
using Sandbox.ModAPI;
using Torch.Server.ViewModels.Blocks;
namespace Torch.Server.ViewModels.Entities
{
- public class GridViewModel : EntityViewModel
+ public class GridViewModel : EntityViewModel, ILazyLoad
{
private MyCubeGrid Grid => (MyCubeGrid)Entity;
public MTObservableCollection Blocks { get; } = new MTObservableCollection();
+ private static readonly Logger Log = LogManager.GetLogger(nameof(GridViewModel));
///
public string DescriptiveName => $"{Name} ({Grid.BlocksCount} blocks)";
@@ -17,17 +19,8 @@ namespace Torch.Server.ViewModels.Entities
public GridViewModel(MyCubeGrid grid, EntityTreeViewModel tree) : base(grid, tree)
{
- TorchBase.Instance.InvokeBlocking(() =>
- {
- foreach (var block in grid.GetFatBlocks().Where(b => b is IMyTerminalBlock))
- {
- Blocks.Add(new BlockViewModel((IMyTerminalBlock)block, tree));
- }
- });
- Blocks.Sort(b => b.Block.GetType().AssemblyQualifiedName);
-
- grid.OnBlockAdded += Grid_OnBlockAdded;
- grid.OnBlockRemoved += Grid_OnBlockRemoved;
+ Log.Debug($"Creating model {Grid.DisplayName}");
+ Blocks.Add(new BlockViewModel(null, Tree));
}
private void Grid_OnBlockRemoved(Sandbox.Game.Entities.Cube.MySlimBlock obj)
@@ -48,5 +41,27 @@ namespace Torch.Server.ViewModels.Entities
Blocks.Sort(b => b.Block.GetType().AssemblyQualifiedName);
OnPropertyChanged(nameof(Name));
}
+
+ private bool _load;
+ public void Load()
+ {
+ if (_load)
+ return;
+
+ Log.Debug($"Loading model {Grid.DisplayName}");
+ _load = true;
+ Blocks.Clear();
+ TorchBase.Instance.InvokeBlocking(() =>
+ {
+ foreach (var block in Grid.GetFatBlocks().Where(b => b is IMyTerminalBlock))
+ {
+ Blocks.Add(new BlockViewModel((IMyTerminalBlock)block, Tree));
+ }
+ });
+ Blocks.Sort(b => b.Block.GetType().AssemblyQualifiedName);
+
+ Grid.OnBlockAdded += Grid_OnBlockAdded;
+ Grid.OnBlockRemoved += Grid_OnBlockRemoved;
+ }
}
}
diff --git a/Torch.Server/ViewModels/Entities/VoxelMapViewModel.cs b/Torch.Server/ViewModels/Entities/VoxelMapViewModel.cs
index 9809214..e1f5384 100644
--- a/Torch.Server/ViewModels/Entities/VoxelMapViewModel.cs
+++ b/Torch.Server/ViewModels/Entities/VoxelMapViewModel.cs
@@ -3,7 +3,6 @@ using System.Linq;
using Sandbox.Game.Entities;
using VRage.Game.Entity;
using VRage.Game.ModAPI;
-using VRage.Library.Collections;
namespace Torch.Server.ViewModels.Entities
{
@@ -11,7 +10,7 @@ namespace Torch.Server.ViewModels.Entities
{
private MyVoxelBase Voxel => (MyVoxelBase)Entity;
- public override string Name => Voxel.StorageName;
+ public override string Name => string.IsNullOrEmpty(Voxel.StorageName) ? "Unnamed" : Voxel.StorageName;
public override bool CanStop => false;
@@ -19,6 +18,9 @@ namespace Torch.Server.ViewModels.Entities
public void UpdateAttachedGrids()
{
+ //TODO: fix
+ return;
+
AttachedGrids.Clear();
var box = Entity.WorldAABB;
var entities = new List();
diff --git a/Torch.Server/ViewModels/ILazyLoad.cs b/Torch.Server/ViewModels/ILazyLoad.cs
new file mode 100644
index 0000000..526b03d
--- /dev/null
+++ b/Torch.Server/ViewModels/ILazyLoad.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Torch.Server.ViewModels
+{
+ public interface ILazyLoad
+ {
+ void Load();
+ }
+}
diff --git a/Torch.Server/ViewModels/PluginManagerViewModel.cs b/Torch.Server/ViewModels/PluginManagerViewModel.cs
index 06196f0..d6e7aa1 100644
--- a/Torch.Server/ViewModels/PluginManagerViewModel.cs
+++ b/Torch.Server/ViewModels/PluginManagerViewModel.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Torch.API;
+using Torch.API.Managers;
using Torch.API.Plugins;
namespace Torch.Server.ViewModels
@@ -15,7 +16,7 @@ namespace Torch.Server.ViewModels
private PluginViewModel _selectedPlugin;
public PluginViewModel SelectedPlugin
{
- get { return _selectedPlugin; }
+ get => _selectedPlugin;
set { _selectedPlugin = value; OnPropertyChanged(); }
}
diff --git a/Torch.Server/ViewModels/SteamUserViewModel.cs b/Torch.Server/ViewModels/SteamUserViewModel.cs
index 2a9e1a3..87d4987 100644
--- a/Torch.Server/ViewModels/SteamUserViewModel.cs
+++ b/Torch.Server/ViewModels/SteamUserViewModel.cs
@@ -9,26 +9,13 @@ namespace Torch.Server.ViewModels
{
public class SteamUserViewModel : ViewModel
{
- private string _name;
- public string Name { get => _name; set { } }
-
- private ulong _id;
-
- public ulong SteamId
- {
- get => _id;
- set
- {
- _id = value;
- OnPropertyChanged();
- //TODO: resolve user name
- OnPropertyChanged(nameof(Name));
- }
- }
+ public string Name { get; }
+ public ulong SteamId { get; }
public SteamUserViewModel(ulong id)
{
SteamId = id;
+ Name = SteamAPI.Instance.Friends.GetPersonaName(id);
}
public SteamUserViewModel() : this(0) { }
diff --git a/Torch.Server/Views/ChatControl.xaml b/Torch.Server/Views/ChatControl.xaml
index c52cd67..a9186c4 100644
--- a/Torch.Server/Views/ChatControl.xaml
+++ b/Torch.Server/Views/ChatControl.xaml
@@ -10,7 +10,7 @@
-
+
diff --git a/Torch.Server/Views/ChatControl.xaml.cs b/Torch.Server/Views/ChatControl.xaml.cs
index fcc2eab..32c6755 100644
--- a/Torch.Server/Views/ChatControl.xaml.cs
+++ b/Torch.Server/Views/ChatControl.xaml.cs
@@ -19,6 +19,7 @@ using Sandbox.Engine.Multiplayer;
using Sandbox.Game.World;
using SteamSDK;
using Torch.API;
+using Torch.Managers;
namespace Torch.Server
{
@@ -27,7 +28,8 @@ namespace Torch.Server
///
public partial class ChatControl : UserControl
{
- private ITorchServer _server;
+ private TorchBase _server;
+ private MultiplayerManager _multiplayer;
public ChatControl()
{
@@ -36,17 +38,9 @@ namespace Torch.Server
public void BindServer(ITorchServer server)
{
- _server = server;
- server.Multiplayer.MessageReceived += Refresh;
- }
-
- private void Refresh(IChatMessage chatItem, ref bool sendToOthers)
- {
- Dispatcher.Invoke(() =>
- {
- ChatItems.ItemsSource = null;
- ChatItems.ItemsSource = _server.Multiplayer.ChatHistory;
- });
+ _server = (TorchBase)server;
+ _multiplayer = (MultiplayerManager)server.Multiplayer;
+ DataContext = _multiplayer;
}
private void SendButton_Click(object sender, RoutedEventArgs e)
@@ -64,11 +58,11 @@ namespace Torch.Server
{
//Can't use Message.Text directly because of object ownership in WPF.
var text = Message.Text;
- var commands = ((TorchBase)_server).Commands;
+ var commands = _server.Commands;
string response = null;
if (commands.IsCommand(text))
{
- _server.Multiplayer.ChatHistory.Add(new ChatMessage(DateTime.Now, 0, "Server", text));
+ _multiplayer.ChatHistory.Add(new ChatMessage(DateTime.Now, 0, "Server", text));
_server.InvokeBlocking(() =>
{
response = commands.HandleCommandFromServer(text);
@@ -79,10 +73,8 @@ namespace Torch.Server
_server.Multiplayer.SendMessage(text);
}
if (!string.IsNullOrEmpty(response))
- _server.Multiplayer.ChatHistory.Add(new ChatMessage(DateTime.Now, 0, "Server", response));
+ _multiplayer.ChatHistory.Add(new ChatMessage(DateTime.Now, 0, "Server", response));
Message.Text = "";
- var sto = false;
- Refresh(null, ref sto);
}
}
}
diff --git a/Torch.Server/Views/ConfigControl.xaml.cs b/Torch.Server/Views/ConfigControl.xaml.cs
index 7f705df..54f15e7 100644
--- a/Torch.Server/Views/ConfigControl.xaml.cs
+++ b/Torch.Server/Views/ConfigControl.xaml.cs
@@ -52,7 +52,13 @@ namespace Torch.Server.Views
Log.Info("Saved DS config.");
try
{
- var checkpoint = MyLocalCache.LoadCheckpoint(Config.LoadWorld, out _);
+ //var checkpoint = MyLocalCache.LoadCheckpoint(Config.LoadWorld, out _);
+ MyObjectBuilderSerializer.DeserializeXML(Path.Combine(Config.LoadWorld, "Sandbox.sbc"), out MyObjectBuilder_Checkpoint checkpoint, out ulong sizeInBytes);
+ if (checkpoint == null)
+ {
+ Log.Error($"Failed to load {Config.LoadWorld}, checkpoint null ({sizeInBytes} bytes, instance {TorchBase.Instance.Config.InstancePath})");
+ return;
+ }
checkpoint.Settings = Config.SessionSettings;
checkpoint.Mods.Clear();
foreach (var modId in Config.Mods)
@@ -75,6 +81,7 @@ namespace Torch.Server.Views
if (!File.Exists(path))
{
+ Log.Error($"Failed to load dedicated config at {path}");
DataContext = null;
return;
}
diff --git a/Torch.Server/Views/EntitiesControl.xaml b/Torch.Server/Views/EntitiesControl.xaml
index 6bff35f..2a78722 100644
--- a/Torch.Server/Views/EntitiesControl.xaml
+++ b/Torch.Server/Views/EntitiesControl.xaml
@@ -18,7 +18,7 @@
Margin="3" />
-
+
@@ -30,12 +30,12 @@
-
+
-
+
@@ -45,7 +45,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
diff --git a/Torch.Server/Views/EntitiesControl.xaml.cs b/Torch.Server/Views/EntitiesControl.xaml.cs
index e090007..7395747 100644
--- a/Torch.Server/Views/EntitiesControl.xaml.cs
+++ b/Torch.Server/Views/EntitiesControl.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.Server.ViewModels;
using Torch.Server.ViewModels.Blocks;
using Torch.Server.ViewModels.Entities;
@@ -64,5 +65,13 @@ namespace Torch.Server.Views
{
TorchBase.Instance.Invoke(() => Entities.CurrentEntity?.Entity.Physics?.ClearSpeed());
}
+
+ private void TreeViewItem_OnExpanded(object sender, RoutedEventArgs e)
+ {
+ LogManager.GetLogger("EntitiesControl").Debug(nameof(TreeViewItem_OnExpanded));
+ var item = (TreeViewItem)e.Source;
+ if (item.DataContext is ILazyLoad l)
+ l.Load();
+ }
}
}
diff --git a/Torch.Server/Views/FirstTimeSetup.xaml b/Torch.Server/Views/FirstTimeSetup.xaml
index 216170f..5defc52 100644
--- a/Torch.Server/Views/FirstTimeSetup.xaml
+++ b/Torch.Server/Views/FirstTimeSetup.xaml
@@ -5,10 +5,11 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Torch.Server.Views"
xmlns:torch="clr-namespace:Torch;assembly=Torch"
+ xmlns:server="clr-namespace:Torch.Server"
mc:Ignorable="d"
Title="Torch First Time Setup" Height="200" Width="500">
-
+
diff --git a/Torch.Server/Views/PlayerListControl.xaml b/Torch.Server/Views/PlayerListControl.xaml
index 26be1cd..86316f0 100644
--- a/Torch.Server/Views/PlayerListControl.xaml
+++ b/Torch.Server/Views/PlayerListControl.xaml
@@ -10,7 +10,7 @@
-
+
diff --git a/Torch.Server/Views/PlayerListControl.xaml.cs b/Torch.Server/Views/PlayerListControl.xaml.cs
index 1954836..c241aa5 100644
--- a/Torch.Server/Views/PlayerListControl.xaml.cs
+++ b/Torch.Server/Views/PlayerListControl.xaml.cs
@@ -17,8 +17,10 @@ using Sandbox;
using Sandbox.Engine.Multiplayer;
using Sandbox.Game.Multiplayer;
using Sandbox.Game.World;
+using Sandbox.ModAPI;
using SteamSDK;
using Torch.API;
+using Torch.Managers;
using VRage.Game.ModAPI;
namespace Torch.Server
@@ -38,18 +40,7 @@ namespace Torch.Server
public void BindServer(ITorchServer server)
{
_server = server;
- //server.Multiplayer.PlayerJoined += Refresh;
- //server.Multiplayer.PlayerLeft += Refresh;
- Refresh();
- }
-
- private void Refresh(IMyPlayer player = null)
- {
- Dispatcher.Invoke(() =>
- {
- PlayerList.ItemsSource = null;
- //PlayerList.ItemsSource = _server.Multiplayer.Players;
- });
+ DataContext = (MultiplayerManager)_server.Multiplayer;
}
private void KickButton_Click(object sender, RoutedEventArgs e)
diff --git a/Torch.sln b/Torch.sln
index f078b65..149cccd 100644
--- a/Torch.sln
+++ b/Torch.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
-VisualStudioVersion = 15.0.26127.3
+VisualStudioVersion = 15.0.26430.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Torch", "Torch\Torch.csproj", "{7E01635C-3B67-472E-BCD6-C5539564F214}"
EndProject
@@ -20,40 +20,28 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
- Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {7E01635C-3B67-472E-BCD6-C5539564F214}.Debug|Any CPU.ActiveCfg = Debug|x64
{7E01635C-3B67-472E-BCD6-C5539564F214}.Debug|x64.ActiveCfg = Debug|x64
{7E01635C-3B67-472E-BCD6-C5539564F214}.Debug|x64.Build.0 = Debug|x64
- {7E01635C-3B67-472E-BCD6-C5539564F214}.Release|Any CPU.ActiveCfg = Release|x64
{7E01635C-3B67-472E-BCD6-C5539564F214}.Release|x64.ActiveCfg = Release|x64
{7E01635C-3B67-472E-BCD6-C5539564F214}.Release|x64.Build.0 = Release|x64
- {FBA5D932-6254-4A1E-BAF4-E229FA94E3C2}.Debug|Any CPU.ActiveCfg = Debug|x64
{FBA5D932-6254-4A1E-BAF4-E229FA94E3C2}.Debug|x64.ActiveCfg = Debug|x64
{FBA5D932-6254-4A1E-BAF4-E229FA94E3C2}.Debug|x64.Build.0 = Debug|x64
- {FBA5D932-6254-4A1E-BAF4-E229FA94E3C2}.Release|Any CPU.ActiveCfg = Release|x64
{FBA5D932-6254-4A1E-BAF4-E229FA94E3C2}.Release|x64.ActiveCfg = Release|x64
{FBA5D932-6254-4A1E-BAF4-E229FA94E3C2}.Release|x64.Build.0 = Release|x64
- {E36DF745-260B-4956-A2E8-09F08B2E7161}.Debug|Any CPU.ActiveCfg = Debug|x64
{E36DF745-260B-4956-A2E8-09F08B2E7161}.Debug|x64.ActiveCfg = Debug|x64
{E36DF745-260B-4956-A2E8-09F08B2E7161}.Debug|x64.Build.0 = Debug|x64
- {E36DF745-260B-4956-A2E8-09F08B2E7161}.Release|Any CPU.ActiveCfg = Release|x64
{E36DF745-260B-4956-A2E8-09F08B2E7161}.Release|x64.ActiveCfg = Release|x64
{E36DF745-260B-4956-A2E8-09F08B2E7161}.Release|x64.Build.0 = Release|x64
- {CA50886B-7B22-4CD8-93A0-C06F38D4F77D}.Debug|Any CPU.ActiveCfg = Debug|x64
{CA50886B-7B22-4CD8-93A0-C06F38D4F77D}.Debug|x64.ActiveCfg = Debug|x64
{CA50886B-7B22-4CD8-93A0-C06F38D4F77D}.Debug|x64.Build.0 = Debug|x64
- {CA50886B-7B22-4CD8-93A0-C06F38D4F77D}.Release|Any CPU.ActiveCfg = Release|x64
{CA50886B-7B22-4CD8-93A0-C06F38D4F77D}.Release|x64.ActiveCfg = Release|x64
{CA50886B-7B22-4CD8-93A0-C06F38D4F77D}.Release|x64.Build.0 = Release|x64
- {19292801-5B9C-4EE0-961F-0FA37B3A6C3D}.Debug|Any CPU.ActiveCfg = Debug|x64
{19292801-5B9C-4EE0-961F-0FA37B3A6C3D}.Debug|x64.ActiveCfg = Debug|x64
{19292801-5B9C-4EE0-961F-0FA37B3A6C3D}.Debug|x64.Build.0 = Debug|x64
- {19292801-5B9C-4EE0-961F-0FA37B3A6C3D}.Release|Any CPU.ActiveCfg = Release|x64
{19292801-5B9C-4EE0-961F-0FA37B3A6C3D}.Release|x64.ActiveCfg = Release|x64
{19292801-5B9C-4EE0-961F-0FA37B3A6C3D}.Release|x64.Build.0 = Release|x64
EndGlobalSection
diff --git a/Torch/CommandLine.cs b/Torch/CommandLine.cs
index d747ddc..3085ae2 100644
--- a/Torch/CommandLine.cs
+++ b/Torch/CommandLine.cs
@@ -3,31 +3,31 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
-using System.Threading.Tasks;
namespace Torch
{
public class CommandLine
{
private readonly string _argPrefix;
+ private readonly Dictionary _args = new Dictionary();
public CommandLine(string argPrefix = "-")
{
_argPrefix = argPrefix;
- }
-
- public PropertyInfo[] GetArgs()
- {
- return GetType().GetProperties().Where(p => p.HasAttribute()).ToArray();
+ foreach (var prop in GetType().GetProperties())
+ {
+ if (prop.HasAttribute())
+ _args.Add(prop.GetCustomAttribute(), prop);
+ }
}
public string GetHelp()
{
var sb = new StringBuilder();
- foreach (var property in GetArgs())
+ foreach (var property in _args)
{
- var attr = property.GetCustomAttribute();
+ var attr = property.Key;
sb.AppendLine($"{_argPrefix}{attr.Name.PadRight(24)}{attr.Description}");
}
@@ -37,16 +37,16 @@ namespace Torch
public override string ToString()
{
var args = new List();
- foreach (var prop in GetArgs())
+ foreach (var prop in _args)
{
- var attr = prop.GetCustomAttribute();
- if (prop.PropertyType == typeof(bool) && (bool)prop.GetValue(this))
+ var attr = prop.Key;
+ if (prop.Value.PropertyType == typeof(bool) && (bool)prop.Value.GetValue(this))
{
args.Add($"{_argPrefix}{attr.Name}");
}
- else if (prop.PropertyType == typeof(string))
+ else if (prop.Value.PropertyType == typeof(string))
{
- var str = (string)prop.GetValue(this);
+ var str = (string)prop.Value.GetValue(this);
if (string.IsNullOrEmpty(str))
continue;
args.Add($"{_argPrefix}{attr.Name} \"{str}\"");
@@ -67,16 +67,14 @@ namespace Torch
return false;
}
- var properties = GetArgs();
-
for (var i = 0; i < args.Length; i++)
{
if (!args[i].StartsWith(_argPrefix))
continue;
- foreach (var property in properties)
+ foreach (var property in _args)
{
- var argName = property.GetCustomAttribute()?.Name;
+ var argName = property.Key.Name;
if (argName == null)
continue;
@@ -84,11 +82,11 @@ namespace Torch
{
if (string.Compare(argName, 0, args[i], 1, argName.Length, StringComparison.InvariantCultureIgnoreCase) == 0)
{
- if (property.PropertyType == typeof(bool))
- property.SetValue(this, true);
+ if (property.Value.PropertyType == typeof(bool))
+ property.Value.SetValue(this, true);
- if (property.PropertyType == typeof(string))
- property.SetValue(this, args[++i]);
+ if (property.Value.PropertyType == typeof(string))
+ property.Value.SetValue(this, args[++i]);
}
}
catch
diff --git a/Torch/Commands/CommandManager.cs b/Torch/Commands/CommandManager.cs
index 79c63e8..64c45ac 100644
--- a/Torch/Commands/CommandManager.cs
+++ b/Torch/Commands/CommandManager.cs
@@ -6,6 +6,7 @@ using System.Text.RegularExpressions;
using NLog;
using Sandbox.Game.World;
using Torch.API;
+using Torch.API.Managers;
using Torch.API.Plugins;
using Torch.Managers;
using VRage.Game.ModAPI;
@@ -13,20 +14,22 @@ using VRage.Network;
namespace Torch.Commands
{
- public class CommandManager
+ public class CommandManager : Manager
{
public char Prefix { get; set; }
public CommandTree Commands { get; set; } = new CommandTree();
private Logger _log = LogManager.GetLogger(nameof(CommandManager));
- private readonly ITorchBase _torch;
- public CommandManager(ITorchBase torch, char prefix = '/')
+ public CommandManager(ITorchBase torch, char prefix = '/') : base(torch)
{
- _torch = torch;
Prefix = prefix;
- ChatManager.Instance.MessageRecieved += HandleCommand;
+ }
+
+ public override void Init()
+ {
RegisterCommandModule(typeof(TorchCommands));
+ Torch.GetManager().MessageRecieved += HandleCommand;
}
public bool HasPermission(ulong steamId, Command command)
@@ -77,7 +80,7 @@ namespace Torch.Commands
var splitArgs = Regex.Matches(argText, "(\"[^\"]+\"|\\S+)").Cast().Select(x => x.ToString().Replace("\"", "")).ToList();
_log.Trace($"Invoking {cmdPath} for server.");
- var context = new CommandContext(_torch, command.Plugin, null, argText, splitArgs);
+ var context = new CommandContext(Torch, command.Plugin, null, argText, splitArgs);
if (command.TryInvoke(context))
_log.Info($"Server ran command '{message}'");
else
@@ -99,7 +102,7 @@ namespace Torch.Commands
sendToOthers = false;
- var player = _torch.Multiplayer.GetPlayerBySteamId(steamId);
+ var player = Torch.Multiplayer.GetPlayerBySteamId(steamId);
if (player == null)
{
_log.Error($"Command {message} invoked by nonexistant player");
@@ -116,14 +119,14 @@ namespace Torch.Commands
if (!HasPermission(steamId, command))
{
_log.Info($"{player.DisplayName} tried to use command {cmdPath} without permission");
- _torch.Multiplayer.SendMessage($"You need to be a {command.MinimumPromoteLevel} or higher to use that command.", playerId: player.IdentityId);
+ Torch.Multiplayer.SendMessage($"You need to be a {command.MinimumPromoteLevel} or higher to use that command.", playerId: player.IdentityId);
return;
}
var splitArgs = Regex.Matches(argText, "(\"[^\"]+\"|\\S+)").Cast().Select(x => x.ToString().Replace("\"", "")).ToList();
_log.Trace($"Invoking {cmdPath} for player {player.DisplayName}");
- var context = new CommandContext(_torch, command.Plugin, player, argText, splitArgs);
- _torch.Invoke(() =>
+ var context = new CommandContext(Torch, command.Plugin, player, argText, splitArgs);
+ Torch.Invoke(() =>
{
if (command.TryInvoke(context))
_log.Info($"Player {player.DisplayName} ran command '{message}'");
diff --git a/Torch/Commands/TorchCommands.cs b/Torch/Commands/TorchCommands.cs
index d986d4b..cac3e53 100644
--- a/Torch/Commands/TorchCommands.cs
+++ b/Torch/Commands/TorchCommands.cs
@@ -13,27 +13,6 @@ namespace Torch.Commands
{
public class TorchCommands : CommandModule
{
-#if DEBUG
- [Command("fixit")]
- public void Fixit()
- {
- Environment.Exit(0);
- }
-
- [Command("dbgcmd")]
- public void Dbgcmd()
- {
- var commandManager = ((PluginManager)Context.Torch.Plugins).Commands;
- Console.WriteLine(commandManager.Commands.GetTreeString());
- }
-#endif
- [Command("crash", "Causes the server to crash for testing purposes")]
- [Permission(MyPromoteLevel.Admin)]
- public void Crash()
- {
- throw new Exception("Crash triggered by Torch command");
- }
-
[Command("help", "Displays help for a command")]
public void Help()
{
diff --git a/Torch/Managers/ChatManager.cs b/Torch/Managers/ChatManager.cs
index fefe667..3468ba0 100644
--- a/Torch/Managers/ChatManager.cs
+++ b/Torch/Managers/ChatManager.cs
@@ -5,6 +5,8 @@ using System.Text;
using System.Threading.Tasks;
using NLog;
using Sandbox.Engine.Multiplayer;
+using Torch.API;
+using Torch.API.Managers;
using VRage;
using VRage.Library.Collections;
using VRage.Network;
@@ -13,9 +15,9 @@ using VRage.Utils;
namespace Torch.Managers
{
- public class ChatManager
+ [Manager]
+ public class ChatManager : Manager
{
- public static ChatManager Instance { get; } = new ChatManager();
private static Logger _log = LogManager.GetLogger(nameof(ChatManager));
public delegate void MessageRecievedDel(ChatMsg msg, ref bool sendToOthers);
@@ -25,11 +27,16 @@ namespace Torch.Managers
internal void RaiseMessageRecieved(ChatMsg msg, ref bool sendToOthers) =>
MessageRecieved?.Invoke(msg, ref sendToOthers);
- public void Init()
+ public ChatManager(ITorchBase torchInstance) : base(torchInstance)
+ {
+
+ }
+
+ public override void Init()
{
try
{
- NetworkManager.Instance.RegisterNetworkHandlers(new ChatIntercept());
+ Torch.GetManager().RegisterNetworkHandler(new ChatIntercept(this));
}
catch
{
@@ -45,43 +52,50 @@ namespace Torch.Managers
RaiseMessageRecieved(msg, ref sendToOthers);
}
- }
- internal class ChatIntercept : NetworkHandlerBase
- {
- private bool? _unitTestResult;
- public override bool CanHandle(CallSite site)
+ internal class ChatIntercept : NetworkHandlerBase, INetworkHandler
{
- if (site.MethodInfo.Name != "OnChatMessageRecieved")
- return false;
+ private ChatManager _chatManager;
+ private bool? _unitTestResult;
- if (_unitTestResult.HasValue)
- return _unitTestResult.Value;
-
- var parameters = site.MethodInfo.GetParameters();
- if (parameters.Length != 1)
+ public ChatIntercept(ChatManager chatManager)
{
- _unitTestResult = false;
- return false;
+ _chatManager = chatManager;
}
- if (parameters[0].ParameterType != typeof(ChatMsg))
- _unitTestResult = false;
+ public override bool CanHandle(CallSite site)
+ {
+ if (site.MethodInfo.Name != "OnChatMessageRecieved")
+ return false;
- _unitTestResult = true;
+ if (_unitTestResult.HasValue)
+ return _unitTestResult.Value;
- return _unitTestResult.Value;
- }
+ var parameters = site.MethodInfo.GetParameters();
+ if (parameters.Length != 1)
+ {
+ _unitTestResult = false;
+ return false;
+ }
- public override bool Handle(ulong remoteUserId, CallSite site, BitStream stream, object obj, MyPacket packet)
- {
- var msg = new ChatMsg();
- Serialize(site.MethodInfo, stream, ref msg);
+ if (parameters[0].ParameterType != typeof(ChatMsg))
+ _unitTestResult = false;
- bool sendToOthers = true;
- ChatManager.Instance.RaiseMessageRecieved(msg, ref sendToOthers);
+ _unitTestResult = true;
- return !sendToOthers;
+ return _unitTestResult.Value;
+ }
+
+ public override bool Handle(ulong remoteUserId, CallSite site, BitStream stream, object obj, MyPacket packet)
+ {
+ var msg = new ChatMsg();
+ Serialize(site.MethodInfo, stream, ref msg);
+
+ bool sendToOthers = true;
+ _chatManager.RaiseMessageRecieved(msg, ref sendToOthers);
+
+ return !sendToOthers;
+ }
}
}
}
diff --git a/Torch/Managers/EntityManager.cs b/Torch/Managers/EntityManager.cs
index 05478ac..c835028 100644
--- a/Torch/Managers/EntityManager.cs
+++ b/Torch/Managers/EntityManager.cs
@@ -17,6 +17,7 @@ using Sandbox.ModAPI;
using SpaceEngineers.Game.Entities.Blocks;
using SpaceEngineers.Game.ModAPI;
using Torch.API;
+using Torch.API.Managers;
using Torch.API.Plugins;
using VRage;
using VRage.Collections;
@@ -31,14 +32,13 @@ using VRageMath;
namespace Torch.Managers
{
- public class EntityManager
+ public class EntityManager : Manager
{
- private readonly ITorchBase _torch;
private static readonly Logger Log = LogManager.GetLogger(nameof(EntityManager));
- public EntityManager(ITorchBase torch)
+ public EntityManager(ITorchBase torch) : base(torch)
{
- _torch = torch;
+
}
public void ExportGrid(IMyCubeGrid grid, string path)
diff --git a/Torch/Managers/Manager.cs b/Torch/Managers/Manager.cs
new file mode 100644
index 0000000..255f93e
--- /dev/null
+++ b/Torch/Managers/Manager.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Torch.API;
+using Torch.API.Managers;
+
+namespace Torch.Managers
+{
+ [AttributeUsage(AttributeTargets.Class)]
+ public class ManagerAttribute : Attribute
+ {
+
+ }
+
+ public abstract class Manager : IManager
+ {
+ protected ITorchBase Torch { get; }
+
+ protected Manager(ITorchBase torchInstance)
+ {
+ Torch = torchInstance;
+ }
+
+ public virtual void Init()
+ {
+
+ }
+ }
+}
diff --git a/Torch/Managers/MultiplayerManager.cs b/Torch/Managers/MultiplayerManager.cs
index 364bc1c..2aa3f2a 100644
--- a/Torch/Managers/MultiplayerManager.cs
+++ b/Torch/Managers/MultiplayerManager.cs
@@ -19,8 +19,11 @@ using Sandbox.Engine.Multiplayer;
using Sandbox.Game.Multiplayer;
using Sandbox.Game.World;
using Sandbox.ModAPI;
+using SharpDX.Toolkit.Collections;
using SteamSDK;
using Torch.API;
+using Torch.API.Managers;
+using Torch.Commands;
using Torch.ViewModels;
using VRage.Game;
using VRage.Game.ModAPI;
@@ -33,39 +36,44 @@ namespace Torch.Managers
///
/// Provides a proxy to the game's multiplayer-related functions.
///
- public class MultiplayerManager : IMultiplayer
+ public class MultiplayerManager : Manager, IMultiplayerManager
{
- public event Action PlayerJoined;
- public event Action PlayerLeft;
+ public event Action PlayerJoined;
+ public event Action PlayerLeft;
public event MessageReceivedDel MessageReceived;
- public List ChatHistory { get; } = new List();
- public Dictionary Players { get; } = new Dictionary();
+ public MTObservableCollection ChatHistory { get; } = new MTObservableCollection();
+ public ObservableDictionary Players { get; } = new ObservableDictionary();
public IMyPlayer LocalPlayer => MySession.Static.LocalHumanPlayer;
- private readonly ITorchBase _torch;
- private static Logger _log = LogManager.GetLogger(nameof(MultiplayerManager));
- private static Logger _chatLog = LogManager.GetLogger("Chat");
+ private static readonly Logger _log = LogManager.GetLogger(nameof(MultiplayerManager));
+ private static readonly Logger _chatLog = LogManager.GetLogger("Chat");
private Dictionary _onlinePlayers;
- internal MultiplayerManager(ITorchBase torch)
+ internal MultiplayerManager(ITorchBase torch) : base(torch)
{
- _torch = torch;
- _torch.SessionLoaded += OnSessionLoaded;
- ChatManager.Instance.MessageRecieved += Instance_MessageRecieved;
+
+ }
+
+ ///
+ public override void Init()
+ {
+ Torch.SessionLoaded += OnSessionLoaded;
+ Torch.GetManager().MessageRecieved += Instance_MessageRecieved;
}
private void Instance_MessageRecieved(ChatMsg msg, ref bool sendToOthers)
{
var message = ChatMessage.FromChatMsg(msg);
ChatHistory.Add(message);
+ _chatLog.Info($"{message.Name}: {message.Message}");
MessageReceived?.Invoke(message, ref sendToOthers);
}
- public void KickPlayer(ulong steamId) => _torch.Invoke(() => MyMultiplayer.Static.KickClient(steamId));
+ public void KickPlayer(ulong steamId) => Torch.Invoke(() => MyMultiplayer.Static.KickClient(steamId));
public void BanPlayer(ulong steamId, bool banned = true)
{
- _torch.Invoke(() =>
+ Torch.Invoke(() =>
{
MyMultiplayer.Static.BanClient(steamId, banned);
if (_gameOwnerIds.ContainsKey(steamId))
@@ -94,9 +102,18 @@ namespace Torch.Managers
///
public void SendMessage(string message, string author = "Server", long playerId = 0, string font = MyFontEnum.Red)
{
- var msg = new ScriptedChatMsg {Author = author, Font = font, Target = playerId, Text = message};
- MyMultiplayerBase.SendScriptedChatMessage(ref msg);
- ChatHistory.Add(new ChatMessage(DateTime.Now, 0, author, message));
+ ChatHistory.Add(new ChatMessage(DateTime.Now, 0, "Server", message));
+ var commands = Torch.GetManager();
+ if (commands.IsCommand(message))
+ {
+ var response = commands.HandleCommandFromServer(message);
+ ChatHistory.Add(new ChatMessage(DateTime.Now, 0, "Server", response));
+ }
+ else
+ {
+ var msg = new ScriptedChatMsg { Author = author, Font = font, Target = playerId, Text = message };
+ MyMultiplayerBase.SendScriptedChatMessage(ref msg);
+ }
}
private void OnSessionLoaded()
@@ -122,7 +139,9 @@ namespace Torch.Managers
private void OnClientLeft(ulong steamId, ChatMemberStateChangeEnum stateChange)
{
_log.Info($"{GetSteamUsername(steamId)} disconnected ({(ConnectionState)stateChange}).");
- PlayerLeft?.Invoke(steamId, (ConnectionState)stateChange);
+ Players.TryGetValue(steamId, out PlayerViewModel vm);
+ PlayerLeft?.Invoke(vm ?? new PlayerViewModel(steamId));
+ Players.Remove(steamId);
}
//TODO: Split the following into a new file?
@@ -130,7 +149,7 @@ namespace Torch.Managers
//This lets us have a server set to private (admins only) or friends (friends of all listed admins)
private List _members;
private HashSet _waitingForGroup;
- private HashSet _waitingForFriends;
+ //private HashSet _waitingForFriends;
private Dictionary _gameOwnerIds = new Dictionary();
//private IMultiplayer _multiplayerImplementation;
@@ -272,7 +291,9 @@ namespace Torch.Managers
private void UserAccepted(ulong steamId)
{
typeof(MyDedicatedServerBase).GetMethod("UserAccepted", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(MyMultiplayer.Static, new object[] {steamId});
- PlayerJoined?.Invoke(steamId);
+ var vm = new PlayerViewModel(steamId);
+ Players.Add(steamId, vm);
+ PlayerJoined?.Invoke(vm);
}
private void UserRejected(ulong steamId, JoinResult reason)
diff --git a/Torch/Managers/NetworkManager/NetworkManager.cs b/Torch/Managers/NetworkManager/NetworkManager.cs
index 5817c43..bed7f31 100644
--- a/Torch/Managers/NetworkManager/NetworkManager.cs
+++ b/Torch/Managers/NetworkManager/NetworkManager.cs
@@ -7,25 +7,31 @@ using System.Threading.Tasks;
using NLog;
using Sandbox.Engine.Multiplayer;
using Sandbox.Game.Multiplayer;
+using Torch.API;
+using Torch.API.Managers;
using VRage;
using VRage.Library.Collections;
using VRage.Network;
namespace Torch.Managers
{
- public class NetworkManager
+ public class NetworkManager : Manager, INetworkManager
{
private static Logger _log = LogManager.GetLogger(nameof(NetworkManager));
- public static NetworkManager Instance { get; } = new NetworkManager();
private const string MyTransportLayerField = "TransportLayer";
private const string TypeTableField = "m_typeTable";
private const string TransportHandlersField = "m_handlers";
private MyTypeTable m_typeTable = new MyTypeTable();
- private HashSet _networkHandlers = new HashSet();
+ private HashSet _networkHandlers = new HashSet();
private bool _init;
- private bool ReflectionUnitTest(bool suppress = false)
+ public NetworkManager(ITorchBase torchInstance) : base(torchInstance)
+ {
+
+ }
+
+ private static bool ReflectionUnitTest(bool suppress = false)
{
try
{
@@ -57,7 +63,7 @@ namespace Torch.Managers
///
/// Loads the network intercept system
///
- public void Init()
+ public override void Init()
{
if (_init)
return;
@@ -196,10 +202,10 @@ namespace Torch.Managers
}
}
- private void RegisterNetworkHandler(NetworkHandlerBase handler)
+ public void RegisterNetworkHandler(INetworkHandler handler)
{
var handlerType = handler.GetType().FullName;
- var toRemove = new List();
+ var toRemove = new List();
foreach (var item in _networkHandlers)
{
if (item.GetType().FullName == handlerType)
@@ -216,7 +222,7 @@ namespace Torch.Managers
_networkHandlers.Add(handler);
}
- public void RegisterNetworkHandlers(params NetworkHandlerBase[] handlers)
+ public void RegisterNetworkHandlers(params INetworkHandler[] handlers)
{
foreach (var handler in handlers)
RegisterNetworkHandler(handler);
diff --git a/Torch/Managers/PluginManager.cs b/Torch/Managers/PluginManager.cs
index 6d99dc5..0fbaf1b 100644
--- a/Torch/Managers/PluginManager.cs
+++ b/Torch/Managers/PluginManager.cs
@@ -13,6 +13,7 @@ using NLog;
using Sandbox;
using Sandbox.ModAPI;
using Torch.API;
+using Torch.API.Managers;
using Torch.API.Plugins;
using Torch.Commands;
using Torch.Managers;
diff --git a/Torch/Managers/UpdateManager.cs b/Torch/Managers/UpdateManager.cs
new file mode 100644
index 0000000..e4784d7
--- /dev/null
+++ b/Torch/Managers/UpdateManager.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using SteamSDK;
+
+namespace Torch.Managers
+{
+ ///
+ /// Handles updating of the DS and Torch plugins.
+ ///
+ public class UpdateManager
+ {
+ private Timer _updatePollTimer;
+
+ public UpdateManager()
+ {
+ _updatePollTimer = new Timer(CheckForUpdates, this, TimeSpan.Zero, TimeSpan.FromMinutes(5));
+ }
+
+ private void CheckForUpdates(object state)
+ {
+
+ }
+ }
+}
diff --git a/Torch/Persistent.cs b/Torch/Persistent.cs
index 2bbc208..527955f 100644
--- a/Torch/Persistent.cs
+++ b/Torch/Persistent.cs
@@ -9,12 +9,11 @@ using Newtonsoft.Json;
namespace Torch
{
///
- /// Class that manages saving to disk using JSON serialization.
+ /// Simple class that manages saving to disk using JSON serialization.
///
/// Data class
public class Persistent : IDisposable where T : new()
{
- [JsonIgnore]
public string Path { get; set; }
public T Data { get; private set; }
@@ -64,7 +63,14 @@ namespace Torch
public void Dispose()
{
- Save();
+ try
+ {
+ Save();
+ }
+ catch
+ {
+ // ignored
+ }
}
}
diff --git a/Torch/Torch.csproj b/Torch/Torch.csproj
index c766800..442a8c9 100644
--- a/Torch/Torch.csproj
+++ b/Torch/Torch.csproj
@@ -35,6 +35,7 @@
False
..\GameBinaries\HavokWrapper.dll
+ False
False
@@ -51,24 +52,31 @@
..\GameBinaries\Sandbox.Common.dll
+ False
..\GameBinaries\Sandbox.Game.dll
+ False
..\GameBinaries\Sandbox.Graphics.dll
+ False
..\GameBinaries\SpaceEngineers.Game.dll
+ False
..\GameBinaries\SpaceEngineers.ObjectBuilders.dll
+ False
..\GameBinaries\SpaceEngineers.ObjectBuilders.XmlSerializers.dll
+ False
..\GameBinaries\SteamSDK.dll
+ False
@@ -81,42 +89,55 @@
..\GameBinaries\VRage.dll
+ False
..\GameBinaries\VRage.Audio.dll
+ False
..\GameBinaries\VRage.Dedicated.dll
+ False
..\GameBinaries\VRage.Game.dll
+ False
..\GameBinaries\VRage.Game.XmlSerializers.dll
+ False
..\GameBinaries\VRage.Input.dll
+ False
..\GameBinaries\VRage.Library.dll
+ False
..\GameBinaries\VRage.Math.dll
+ False
..\GameBinaries\VRage.Native.dll
+ False
..\GameBinaries\VRage.OpenVRWrapper.dll
+ False
..\GameBinaries\VRage.Render.dll
+ False
..\GameBinaries\VRage.Render11.dll
+ False
..\GameBinaries\VRage.Scripting.dll
+ False
@@ -137,11 +158,12 @@
+
+
-
@@ -154,6 +176,7 @@
+
diff --git a/Torch/TorchBase.cs b/Torch/TorchBase.cs
index db8f890..3e2acaf 100644
--- a/Torch/TorchBase.cs
+++ b/Torch/TorchBase.cs
@@ -17,8 +17,10 @@ using Sandbox.Game.World;
using Sandbox.ModAPI;
using SpaceEngineers.Game;
using Torch.API;
+using Torch.API.Managers;
using Torch.Commands;
using Torch.Managers;
+using VRage.Collections;
using VRage.FileSystem;
using VRage.Game.ObjectBuilder;
using VRage.ObjectBuilders;
@@ -41,14 +43,15 @@ namespace Torch
public Version GameVersion { get; private set; }
public string[] RunArgs { get; set; }
public IPluginManager Plugins { get; protected set; }
- public IMultiplayer Multiplayer { get; protected set; }
+ public IMultiplayerManager Multiplayer { get; protected set; }
public EntityManager Entities { get; protected set; }
- public NetworkManager Network { get; protected set; }
+ public INetworkManager Network { get; protected set; }
public CommandManager Commands { get; protected set; }
public event Action SessionLoading;
public event Action SessionLoaded;
public event Action SessionUnloading;
public event Action SessionUnloaded;
+ private HashSet _managers;
private bool _init;
@@ -61,11 +64,40 @@ namespace Torch
TorchVersion = Assembly.GetExecutingAssembly().GetName().Version;
RunArgs = new string[0];
+
Plugins = new PluginManager(this);
Multiplayer = new MultiplayerManager(this);
Entities = new EntityManager(this);
- Network = NetworkManager.Instance;
+ Network = new NetworkManager(this);
Commands = new CommandManager(this);
+
+ _managers = new HashSet
+ {
+ Plugins,
+ Multiplayer,
+ Entities,
+ Network,
+ Commands
+ };
+ }
+
+ public HashSetReader GetManagers()
+ {
+ return new HashSetReader(_managers);
+ }
+
+ public T GetManager() where T : class, IManager
+ {
+ return _managers.FirstOrDefault(m => m is T) as T;
+ }
+
+ public bool AddManager(T manager) where T : class, IManager
+ {
+ if (_managers.Any(x => x is T))
+ return false;
+
+ _managers.Add(manager);
+ return true;
}
public bool IsOnGameThread()
@@ -91,9 +123,9 @@ namespace Torch
if (!e.WaitOne(60000))
{
Log.Error("Save failed!");
- Multiplayer.SendMessage("Save timed out!", author: "Error");
+ Multiplayer.SendMessage("Save timed out!", "Error");
}
- });
+ }).ConfigureAwait(false);
}
}
else
@@ -233,8 +265,8 @@ namespace Torch
///
public virtual void Init(object gameInstance)
{
- Network.Init();
- ChatManager.Instance.Init();
+ foreach (var manager in _managers)
+ manager.Init();
}
///
diff --git a/Torch/Updater/PluginUpdater.cs b/Torch/Updater/PluginUpdater.cs
index 7ec0ca6..355bfd3 100644
--- a/Torch/Updater/PluginUpdater.cs
+++ b/Torch/Updater/PluginUpdater.cs
@@ -37,7 +37,7 @@ namespace Torch.Updater
}
var gitClient = new GitHubClient(new ProductHeaderValue("Torch"));
- var releases = await gitClient.Repository.Release.GetAll(split[0], split[1]);
+ var releases = await gitClient.Repository.Release.GetAll(split[0], split[1]).ConfigureAwait(false);
if (releases.Count == 0)
{
@@ -62,14 +62,14 @@ namespace Torch.Updater
if (force || latestVersion > currentVersion)
{
var webClient = new WebClient();
- var assets = await gitClient.Repository.Release.GetAllAssets(split[0], split[1], releases[0].Id);
+ var assets = await gitClient.Repository.Release.GetAllAssets(split[0], split[1], releases[0].Id).ConfigureAwait(false);
foreach (var asset in assets)
{
if (asset.Name.EndsWith(".zip"))
{
Log.Debug(asset.BrowserDownloadUrl);
var localPath = Path.Combine(Path.GetTempPath(), asset.Name);
- await webClient.DownloadFileTaskAsync(new Uri(asset.BrowserDownloadUrl), localPath);
+ await webClient.DownloadFileTaskAsync(new Uri(asset.BrowserDownloadUrl), localPath).ConfigureAwait(false);
UnzipPlugin(localPath);
Log.Info($"Downloaded update for {manifest.Repository}");
return;
diff --git a/Torch/ViewModels/PlayerViewModel.cs b/Torch/ViewModels/PlayerViewModel.cs
new file mode 100644
index 0000000..3c29c8a
--- /dev/null
+++ b/Torch/ViewModels/PlayerViewModel.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using SteamSDK;
+using Torch.API;
+
+namespace Torch.ViewModels
+{
+ public class PlayerViewModel : ViewModel, IPlayer
+ {
+ public ulong SteamId { get; }
+ public string Name { get; }
+ private ConnectionState _state;
+ public ConnectionState State { get => _state; set { _state = value; OnPropertyChanged(); } }
+
+ public PlayerViewModel(ulong steamId, string name = null)
+ {
+ SteamId = steamId;
+ Name = name ?? SteamAPI.Instance?.Friends?.GetPersonaName(steamId) ?? "???";
+ }
+ }
+}