Add support for WPF controls in plugins and method parameters in plugin commands
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Torch.API.Plugins;
|
||||
using VRage.Collections;
|
||||
using VRage.Plugins;
|
||||
|
||||
@@ -7,6 +8,8 @@ namespace Torch.API
|
||||
{
|
||||
public interface IPluginManager : IEnumerable<ITorchPlugin>
|
||||
{
|
||||
event Action<List<ITorchPlugin>> PluginsLoaded;
|
||||
List<ITorchPlugin> Plugins { get; }
|
||||
void UpdatePlugins();
|
||||
void Init();
|
||||
void DisposePlugins();
|
||||
|
@@ -5,7 +5,7 @@ using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Torch.API
|
||||
namespace Torch.API.Plugins
|
||||
{
|
||||
public interface ITorchPlugin : IDisposable
|
||||
{
|
18
Torch.API/Plugins/IWpfPlugin.cs
Normal file
18
Torch.API/Plugins/IWpfPlugin.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Torch.API.Plugins
|
||||
{
|
||||
public interface IWpfPlugin : ITorchPlugin
|
||||
{
|
||||
/// <summary>
|
||||
/// Used by the server's WPF interface to load custom plugin controls.
|
||||
/// Do not instantiate your plugin control outside of this method! It will throw an exception.
|
||||
/// </summary>
|
||||
UserControl GetControl();
|
||||
}
|
||||
}
|
@@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Torch.API
|
||||
namespace Torch.API.Plugins
|
||||
{
|
||||
public class PluginAttribute : Attribute
|
||||
{
|
@@ -114,12 +114,13 @@
|
||||
<Compile Include="IChatMessage.cs" />
|
||||
<Compile Include="IMultiplayer.cs" />
|
||||
<Compile Include="IPluginManager.cs" />
|
||||
<Compile Include="ITorchPlugin.cs" />
|
||||
<Compile Include="Plugins\ITorchPlugin.cs" />
|
||||
<Compile Include="IServerControls.cs" />
|
||||
<Compile Include="ITorchBase.cs" />
|
||||
<Compile Include="Plugins\IWpfPlugin.cs" />
|
||||
<Compile Include="ModAPI\Ingame\GridExtensions.cs" />
|
||||
<Compile Include="ModAPI\TorchAPI.cs" />
|
||||
<Compile Include="PluginAttribute.cs" />
|
||||
<Compile Include="Plugins\PluginAttribute.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@@ -12,5 +12,5 @@ using System.Runtime.InteropServices;
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.89.507")]
|
||||
[assembly: AssemblyFileVersion("1.0.89.507")]
|
||||
[assembly: AssemblyVersion("1.0.89.540")]
|
||||
[assembly: AssemblyFileVersion("1.0.89.540")]
|
@@ -165,7 +165,13 @@
|
||||
<Compile Include="TorchServiceInstaller.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ViewModels\CharacterViewModel.cs" />
|
||||
<Compile Include="ViewModels\ConfigDedicatedViewModel.cs" />
|
||||
<Compile Include="ViewModels\EntityTreeViewModel.cs" />
|
||||
<Compile Include="ViewModels\EntityViewModel.cs" />
|
||||
<Compile Include="ViewModels\GridViewModel.cs" />
|
||||
<Compile Include="ViewModels\PluginManagerViewModel.cs" />
|
||||
<Compile Include="ViewModels\PluginViewModel.cs" />
|
||||
<Compile Include="ViewModels\SessionSettingsViewModel.cs" />
|
||||
<Compile Include="Views\AddWorkshopItemsDialog.xaml.cs">
|
||||
<DependentUpon>AddWorkshopItemsDialog.xaml</DependentUpon>
|
||||
@@ -179,9 +185,15 @@
|
||||
<Compile Include="Views\ConfigControl.xaml.cs">
|
||||
<DependentUpon>ConfigControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\EntitiesControl.xaml.cs">
|
||||
<DependentUpon>EntitiesControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\ModsControl.xaml.cs">
|
||||
<DependentUpon>ModsControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\PluginsControl.xaml.cs">
|
||||
<DependentUpon>PluginsControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\TorchUI.xaml.cs">
|
||||
<DependentUpon>TorchUI.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@@ -242,10 +254,18 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\EntitiesControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\ModsControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\PluginsControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\TorchUI.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
|
@@ -25,7 +25,7 @@ namespace Torch.Server
|
||||
public TorchConfig(string instanceName = "Torch", string instancePath = null, int autosaveInterval = 5, bool autoRestart = false)
|
||||
{
|
||||
InstanceName = instanceName;
|
||||
InstancePath = instancePath ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Torch", InstanceName);
|
||||
InstancePath = instancePath ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "SpaceEngineersDedicated", InstanceName);
|
||||
Autosave = autosaveInterval;
|
||||
AutoRestart = autoRestart;
|
||||
}
|
||||
|
13
Torch.Server/ViewModels/CharacterViewModel.cs
Normal file
13
Torch.Server/ViewModels/CharacterViewModel.cs
Normal file
@@ -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 class CharacterViewModel : EntityViewModel
|
||||
{
|
||||
}*/
|
||||
}
|
20
Torch.Server/ViewModels/EntityTreeViewModel.cs
Normal file
20
Torch.Server/ViewModels/EntityTreeViewModel.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Torch.Server.ViewModels
|
||||
{
|
||||
/*
|
||||
public class EntityTreeViewModel : ViewModel
|
||||
{
|
||||
public string GridsHeader => null;
|
||||
public MTObservableCollection<>
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
|
||||
}
|
||||
}*/
|
||||
}
|
31
Torch.Server/ViewModels/EntityViewModel.cs
Normal file
31
Torch.Server/ViewModels/EntityViewModel.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using VRage.ModAPI;
|
||||
using VRageMath;
|
||||
|
||||
namespace Torch.Server.ViewModels
|
||||
{
|
||||
/*
|
||||
public class EntityViewModel : ViewModel
|
||||
{
|
||||
public IMyEntity Entity { get; }
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return Entity.DisplayName; }
|
||||
set { TorchBase.Instance.i}
|
||||
}
|
||||
|
||||
public string Position { get; }
|
||||
|
||||
public EntityViewModel(IMyEntity entity)
|
||||
{
|
||||
Entity = entity;
|
||||
Name = entity.DisplayName;
|
||||
Position
|
||||
}
|
||||
}*/
|
||||
}
|
13
Torch.Server/ViewModels/GridViewModel.cs
Normal file
13
Torch.Server/ViewModels/GridViewModel.cs
Normal file
@@ -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 class GridViewModel : EntityViewModel
|
||||
{
|
||||
}*/
|
||||
}
|
38
Torch.Server/ViewModels/PluginManagerViewModel.cs
Normal file
38
Torch.Server/ViewModels/PluginManagerViewModel.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Torch.API;
|
||||
using Torch.API.Plugins;
|
||||
|
||||
namespace Torch.Server.ViewModels
|
||||
{
|
||||
public class PluginManagerViewModel : ViewModel
|
||||
{
|
||||
public MTObservableCollection<PluginViewModel> Plugins { get; } = new MTObservableCollection<PluginViewModel>();
|
||||
|
||||
private PluginViewModel _selectedPlugin;
|
||||
public PluginViewModel SelectedPlugin
|
||||
{
|
||||
get { return _selectedPlugin; }
|
||||
set { _selectedPlugin = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
public PluginManagerViewModel() { }
|
||||
|
||||
public PluginManagerViewModel(IPluginManager pluginManager)
|
||||
{
|
||||
pluginManager.PluginsLoaded += PluginManager_PluginsLoaded;
|
||||
}
|
||||
|
||||
private void PluginManager_PluginsLoaded(List<ITorchPlugin> obj)
|
||||
{
|
||||
Plugins.Clear();
|
||||
foreach (var plugin in obj)
|
||||
{
|
||||
Plugins.Add(new PluginViewModel(plugin));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
34
Torch.Server/ViewModels/PluginViewModel.cs
Normal file
34
Torch.Server/ViewModels/PluginViewModel.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using Torch.API;
|
||||
using Torch.API.Plugins;
|
||||
|
||||
namespace Torch.Server.ViewModels
|
||||
{
|
||||
public class PluginViewModel
|
||||
{
|
||||
public UserControl Control
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Plugin is IWpfPlugin p)
|
||||
return p.GetControl();
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public ITorchPlugin Plugin { get; }
|
||||
|
||||
public PluginViewModel(ITorchPlugin plugin)
|
||||
{
|
||||
Plugin = plugin;
|
||||
Name = $"{plugin.Name} ({plugin.Version})";
|
||||
}
|
||||
}
|
||||
}
|
@@ -14,9 +14,9 @@
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<WrapPanel>
|
||||
<TextBlock Text="{Binding Time}"/>
|
||||
<TextBlock Text="{Binding Timestamp}"/>
|
||||
<TextBlock Text=" "/>
|
||||
<TextBlock Text="{Binding Player.Name}" FontWeight="Bold"/>
|
||||
<TextBlock Text="{Binding Name}" FontWeight="Bold"/>
|
||||
<TextBlock Text=": "/>
|
||||
<TextBlock Text="{Binding Message}"/>
|
||||
</WrapPanel>
|
||||
|
22
Torch.Server/Views/EntitiesControl.xaml
Normal file
22
Torch.Server/Views/EntitiesControl.xaml
Normal file
@@ -0,0 +1,22 @@
|
||||
<UserControl x:Class="Torch.Server.Views.EntitiesControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Torch.Server.Views"
|
||||
mc:Ignorable="d">
|
||||
<DockPanel>
|
||||
<DockPanel DockPanel.Dock="Left">
|
||||
<StackPanel DockPanel.Dock="Bottom">
|
||||
<Button Content="Refresh" Margin="3"></Button>
|
||||
<Button Content="Delete Selected" Margin="3"></Button>
|
||||
</StackPanel>
|
||||
<TreeView Width="300" Margin="3" DockPanel.Dock="Top">
|
||||
<TreeViewItem Header="Grids"/>
|
||||
<TreeViewItem Header="Characters"/>
|
||||
<TreeViewItem Header="Floating Objects"/>
|
||||
</TreeView>
|
||||
</DockPanel>
|
||||
<Frame Margin="3"></Frame>
|
||||
</DockPanel>
|
||||
</UserControl>
|
28
Torch.Server/Views/EntitiesControl.xaml.cs
Normal file
28
Torch.Server/Views/EntitiesControl.xaml.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Torch.Server.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for EntitiesControl.xaml
|
||||
/// </summary>
|
||||
public partial class EntitiesControl : UserControl
|
||||
{
|
||||
public EntitiesControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
27
Torch.Server/Views/PluginsControl.xaml
Normal file
27
Torch.Server/Views/PluginsControl.xaml
Normal file
@@ -0,0 +1,27 @@
|
||||
<UserControl x:Class="Torch.Server.Views.PluginsControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Torch.Server.Views"
|
||||
xmlns:viewModels="clr-namespace:Torch.Server.ViewModels"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<UserControl.DataContext>
|
||||
<viewModels:PluginManagerViewModel/>
|
||||
</UserControl.DataContext>
|
||||
<DockPanel>
|
||||
<ListView Width="150" ItemsSource="{Binding Plugins}" SelectedItem="{Binding SelectedPlugin}" Margin="3">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Name}"/>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
<StackPanel Margin="3">
|
||||
<Label Content="{Binding SelectedPlugin.Name}" FontSize="16"/>
|
||||
<Frame Content="{Binding SelectedPlugin.Control}"/>
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
</UserControl>
|
||||
|
38
Torch.Server/Views/PluginsControl.xaml.cs
Normal file
38
Torch.Server/Views/PluginsControl.xaml.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using NLog;
|
||||
using Torch.API;
|
||||
using Torch.Server.ViewModels;
|
||||
|
||||
namespace Torch.Server.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for PluginsControl.xaml
|
||||
/// </summary>
|
||||
public partial class PluginsControl : UserControl
|
||||
{
|
||||
public PluginsControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void BindServer(ITorchServer server)
|
||||
{
|
||||
var pluginManager = new PluginManagerViewModel(server.Plugins);
|
||||
DataContext = pluginManager;
|
||||
}
|
||||
}
|
||||
}
|
@@ -6,7 +6,7 @@
|
||||
xmlns:local="clr-namespace:Torch.Server"
|
||||
xmlns:views="clr-namespace:Torch.Server.Views"
|
||||
mc:Ignorable="d"
|
||||
Title="Torch" Height="900" Width="600">
|
||||
Title="Torch" Height="600" Width="800">
|
||||
<DockPanel>
|
||||
<StackPanel DockPanel.Dock="Top" Margin="5,5,5,5" Orientation="Horizontal">
|
||||
<Button x:Name="BtnStart" Content="Start" Height="24" Width="75" Margin="5,0,5,0" HorizontalAlignment="Left" Click="BtnStart_Click" IsDefault="True"/>
|
||||
@@ -32,8 +32,10 @@
|
||||
</DockPanel>
|
||||
</TabItem>
|
||||
<TabItem Header="Entity Manager">
|
||||
<views:EntitiesControl/>
|
||||
</TabItem>
|
||||
<TabItem Header="Plugins">
|
||||
<views:PluginsControl x:Name="Plugins"/>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</DockPanel>
|
||||
|
@@ -38,6 +38,7 @@ namespace Torch.Server
|
||||
|
||||
public TorchUI(TorchServer server)
|
||||
{
|
||||
_config = new TorchConfig();
|
||||
_server = server;
|
||||
InitializeComponent();
|
||||
_startTime = DateTime.Now;
|
||||
@@ -45,6 +46,7 @@ namespace Torch.Server
|
||||
|
||||
Chat.BindServer(server);
|
||||
PlayerList.BindServer(server);
|
||||
Plugins.BindServer(server);
|
||||
}
|
||||
|
||||
public void LoadConfig(TorchConfig config)
|
||||
|
@@ -1,8 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using NLog;
|
||||
using Torch.API;
|
||||
using Torch.API.Plugins;
|
||||
using Torch.Commands.Permissions;
|
||||
using VRage.Game.ModAPI;
|
||||
|
||||
@@ -18,6 +22,9 @@ namespace Torch.Commands
|
||||
public List<string> Path { get; } = new List<string>();
|
||||
public ITorchPlugin Plugin { get; }
|
||||
private readonly MethodInfo _method;
|
||||
private ParameterInfo[] _parameters;
|
||||
private int? _requiredParamCount;
|
||||
public string SyntaxHelp { get; }
|
||||
|
||||
public Command(ITorchPlugin plugin, MethodInfo commandMethod)
|
||||
{
|
||||
@@ -47,6 +54,60 @@ namespace Torch.Commands
|
||||
Name = commandAttribute.Name;
|
||||
Description = commandAttribute.Description;
|
||||
HelpText = commandAttribute.HelpText;
|
||||
|
||||
//parameters
|
||||
_parameters = commandMethod.GetParameters();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.Append($"/{string.Join(" ", Path)} ");
|
||||
for (var i = 0; i < _parameters.Length; i++)
|
||||
{
|
||||
var param = _parameters[i];
|
||||
|
||||
if (param.HasDefaultValue)
|
||||
{
|
||||
_requiredParamCount = _requiredParamCount ?? i;
|
||||
|
||||
sb.Append($"[{param.ParameterType.Name} {param.Name}] ");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append($"<{param.ParameterType.Name} {param.Name}> ");
|
||||
}
|
||||
}
|
||||
|
||||
_requiredParamCount = _requiredParamCount ?? 0;
|
||||
LogManager.GetLogger(nameof(Command)).Debug($"Params: {_parameters.Length} ({_requiredParamCount} required)");
|
||||
SyntaxHelp = sb.ToString();
|
||||
}
|
||||
|
||||
public bool TryInvoke(CommandContext context)
|
||||
{
|
||||
var parameters = new object[_parameters.Length];
|
||||
|
||||
if (context.Args.Count < _requiredParamCount)
|
||||
return false;
|
||||
|
||||
//Convert args from string
|
||||
for (var i = 0; i < _parameters.Length && i < context.Args.Count; i++)
|
||||
{
|
||||
if (context.Args[i].TryConvert(_parameters[i].ParameterType, out object obj))
|
||||
parameters[i] = obj;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//Fill omitted default parameters
|
||||
for (var i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
if (parameters[i] == null)
|
||||
parameters[i] = _parameters[i].DefaultValue;
|
||||
}
|
||||
|
||||
var moduleInstance = (CommandModule)Activator.CreateInstance(Module);
|
||||
moduleInstance.Context = context;
|
||||
_method.Invoke(moduleInstance, parameters);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Invoke(CommandContext context)
|
||||
@@ -56,4 +117,38 @@ namespace Torch.Commands
|
||||
_method.Invoke(moduleInstance, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
public static bool TryConvert(this string str, Type toType, out object val)
|
||||
{
|
||||
try
|
||||
{
|
||||
var converter = TypeDescriptor.GetConverter(toType);
|
||||
val = converter.ConvertFromString(str);
|
||||
return true;
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
val = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryConvert<T>(this string str, out T val)
|
||||
{
|
||||
try
|
||||
{
|
||||
var converter = TypeDescriptor.GetConverter(typeof(T));
|
||||
val = (T)converter.ConvertFromString(str);
|
||||
return true;
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
val = default(T);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Torch.API;
|
||||
using Torch.API.Plugins;
|
||||
using VRage.Game;
|
||||
using VRage.Game.ModAPI;
|
||||
|
||||
|
@@ -6,6 +6,7 @@ using System.Text.RegularExpressions;
|
||||
using NLog;
|
||||
using Sandbox.Game.World;
|
||||
using Torch.API;
|
||||
using Torch.API.Plugins;
|
||||
using Torch.Managers;
|
||||
using VRage.Game.ModAPI;
|
||||
using VRage.Network;
|
||||
@@ -99,8 +100,11 @@ namespace Torch.Commands
|
||||
var splitArgs = Regex.Matches(argText, "(\"[^\"]+\"|\\S+)").Cast<Match>().Select(x => x.ToString().Replace("\"", "")).ToList();
|
||||
_log.Trace($"Invoking {cmdPath} for player {player.DisplayName}");
|
||||
var context = new CommandContext(_torch, command.Plugin, player, argText, splitArgs);
|
||||
command.Invoke(context);
|
||||
_log.Info($"Player {player.DisplayName} ran command '{msg.Text}'");
|
||||
//command.Invoke(context);
|
||||
if (command.TryInvoke(context))
|
||||
_log.Info($"Player {player.DisplayName} ran command '{msg.Text}'");
|
||||
else
|
||||
context.Respond($"Invalid Syntax: {command.SyntaxHelp}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Sandbox.ModAPI;
|
||||
using Torch.Commands.Permissions;
|
||||
using Torch.Managers;
|
||||
using VRage.Game.ModAPI;
|
||||
@@ -39,7 +40,10 @@ namespace Torch.Commands
|
||||
var sb = new StringBuilder();
|
||||
|
||||
if (command != null)
|
||||
{
|
||||
sb.AppendLine($"Syntax: {command.SyntaxHelp}");
|
||||
sb.AppendLine(command.HelpText);
|
||||
}
|
||||
|
||||
sb.AppendLine($"Subcommands: {string.Join(", ", children)}");
|
||||
|
||||
|
@@ -129,6 +129,12 @@ namespace Torch.Managers
|
||||
});
|
||||
}
|
||||
|
||||
public void RevealAll()
|
||||
{
|
||||
for (var i = _concealGroups.Count - 1; i >= 0; i--)
|
||||
RevealGroup(_concealGroups[i]);
|
||||
}
|
||||
|
||||
private void ConcealTimerElapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
if (_concealInProgress)
|
||||
@@ -164,6 +170,8 @@ namespace Torch.Managers
|
||||
void UnregisterRecursive(IMyEntity e)
|
||||
{
|
||||
MyEntities.UnregisterForUpdate((MyEntity)e);
|
||||
if (e.Hierarchy == null)
|
||||
return;
|
||||
foreach (var child in e.Hierarchy.Children)
|
||||
UnregisterRecursive(child.Entity);
|
||||
}
|
||||
@@ -181,6 +189,8 @@ namespace Torch.Managers
|
||||
void RegisterRecursive(IMyEntity e)
|
||||
{
|
||||
MyEntities.RegisterForUpdate((MyEntity)e);
|
||||
if (e.Hierarchy == null)
|
||||
return;
|
||||
foreach (var child in e.Hierarchy.Children)
|
||||
RegisterRecursive(child.Entity);
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@ using NLog;
|
||||
using Sandbox;
|
||||
using Sandbox.ModAPI;
|
||||
using Torch.API;
|
||||
using Torch.API.Plugins;
|
||||
using Torch.Commands;
|
||||
using Torch.Managers;
|
||||
using VRage.Plugins;
|
||||
@@ -27,12 +28,14 @@ namespace Torch.Managers
|
||||
private static Logger _log = LogManager.GetLogger(nameof(PluginManager));
|
||||
public const string PluginDir = "Plugins";
|
||||
|
||||
private readonly List<ITorchPlugin> _plugins = new List<ITorchPlugin>();
|
||||
public List<ITorchPlugin> Plugins { get; } = new List<ITorchPlugin>();
|
||||
public CommandManager Commands { get; private set; }
|
||||
|
||||
public float LastUpdateMs => _lastUpdateMs;
|
||||
private volatile float _lastUpdateMs;
|
||||
|
||||
public event Action<List<ITorchPlugin>> PluginsLoaded;
|
||||
|
||||
public PluginManager(ITorchBase torch)
|
||||
{
|
||||
_torch = torch;
|
||||
@@ -62,7 +65,7 @@ namespace Torch.Managers
|
||||
public void UpdatePlugins()
|
||||
{
|
||||
var s = Stopwatch.StartNew();
|
||||
Parallel.ForEach(_plugins, p => p.Update());
|
||||
Parallel.ForEach(Plugins, p => p.Update());
|
||||
s.Stop();
|
||||
_lastUpdateMs = (float)s.Elapsed.TotalMilliseconds;
|
||||
}
|
||||
@@ -72,10 +75,10 @@ namespace Torch.Managers
|
||||
/// </summary>
|
||||
public void DisposePlugins()
|
||||
{
|
||||
foreach (var plugin in _plugins)
|
||||
foreach (var plugin in Plugins)
|
||||
plugin.Dispose();
|
||||
|
||||
_plugins.Clear();
|
||||
Plugins.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -105,7 +108,7 @@ namespace Torch.Managers
|
||||
throw new TypeLoadException($"Plugin '{type.FullName}' is missing a {nameof(PluginAttribute)}");
|
||||
|
||||
_log.Info($"Loading plugin {plugin.Name} ({plugin.Version})");
|
||||
_plugins.Add(plugin);
|
||||
Plugins.Add(plugin);
|
||||
|
||||
Commands.RegisterPluginCommands(plugin);
|
||||
}
|
||||
@@ -119,12 +122,13 @@ namespace Torch.Managers
|
||||
}
|
||||
}
|
||||
|
||||
_plugins.ForEach(p => p.Init(_torch));
|
||||
Plugins.ForEach(p => p.Init(_torch));
|
||||
PluginsLoaded?.Invoke(Plugins);
|
||||
}
|
||||
|
||||
public IEnumerator<ITorchPlugin> GetEnumerator()
|
||||
{
|
||||
return _plugins.GetEnumerator();
|
||||
return Plugins.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
|
21
Torch/PluginOptions.cs
Normal file
21
Torch/PluginOptions.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Torch
|
||||
{
|
||||
public class PluginOptions
|
||||
{
|
||||
public virtual string Save()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void Load(string data)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SteamSDK;
|
||||
using Sandbox;
|
||||
|
||||
namespace Torch
|
||||
|
@@ -162,6 +162,7 @@
|
||||
<Compile Include="Managers\NetworkManager\NetworkHandlerBase.cs" />
|
||||
<Compile Include="Managers\NetworkManager\NetworkManager.cs" />
|
||||
<Compile Include="Managers\MultiplayerManager.cs" />
|
||||
<Compile Include="PluginOptions.cs" />
|
||||
<Compile Include="Reflection.cs" />
|
||||
<Compile Include="Managers\ScriptingManager.cs" />
|
||||
<Compile Include="TorchBase.cs" />
|
||||
|
@@ -6,6 +6,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
using NLog;
|
||||
using Sandbox.ModAPI.Ingame;
|
||||
|
||||
namespace Torch
|
||||
{
|
||||
|
@@ -9,6 +9,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using Torch.API;
|
||||
using Torch.API.Plugins;
|
||||
|
||||
namespace Torch
|
||||
{
|
||||
|
Reference in New Issue
Block a user