Fix NetworkManager, add more entity management, default command permission level to "Admin"

This commit is contained in:
John Gross
2017-06-02 19:40:52 -07:00
parent 8ad9ecf2bb
commit c40b17ac30
37 changed files with 489 additions and 114 deletions

View File

@@ -1,4 +1,4 @@
using System.Reflection; using System.Reflection;
[assembly: AssemblyVersion("1.0.135.374")] [assembly: AssemblyVersion("1.0.153.575")]
[assembly: AssemblyFileVersion("1.0.135.374")] [assembly: AssemblyFileVersion("1.0.153.575")]

View File

@@ -1,4 +1,4 @@
using System.Reflection; using System.Reflection;
[assembly: AssemblyVersion("1.0.135.374")] [assembly: AssemblyVersion("1.0.153.575")]
[assembly: AssemblyFileVersion("1.0.135.374")] [assembly: AssemblyFileVersion("1.0.153.575")]

View File

@@ -175,14 +175,14 @@
<Compile Include="TorchServiceInstaller.cs"> <Compile Include="TorchServiceInstaller.cs">
<SubType>Component</SubType> <SubType>Component</SubType>
</Compile> </Compile>
<Compile Include="ViewModels\Blocks\BlockViewModel.cs" /> <Compile Include="ViewModels\Entities\Blocks\BlockViewModel.cs" />
<Compile Include="ViewModels\Blocks\BlockViewModelGenerator.cs" /> <Compile Include="ViewModels\Entities\Blocks\BlockViewModelGenerator.cs" />
<Compile Include="ViewModels\Blocks\PropertyViewModel.cs" /> <Compile Include="ViewModels\Entities\Blocks\PropertyViewModel.cs" />
<Compile Include="ViewModels\Entities\CharacterViewModel.cs" /> <Compile Include="ViewModels\Entities\CharacterViewModel.cs" />
<Compile Include="ViewModels\ConfigDedicatedViewModel.cs" /> <Compile Include="ViewModels\ConfigDedicatedViewModel.cs" />
<Compile Include="ViewModels\EntityTreeViewModel.cs" /> <Compile Include="ViewModels\EntityTreeViewModel.cs" />
<Compile Include="ViewModels\Entities\EntityViewModel.cs" /> <Compile Include="ViewModels\Entities\EntityViewModel.cs" />
<Compile Include="ViewModels\FloatingObjectViewModel.cs" /> <Compile Include="ViewModels\Entities\FloatingObjectViewModel.cs" />
<Compile Include="ViewModels\Entities\GridViewModel.cs" /> <Compile Include="ViewModels\Entities\GridViewModel.cs" />
<Compile Include="ViewModels\PluginManagerViewModel.cs" /> <Compile Include="ViewModels\PluginManagerViewModel.cs" />
<Compile Include="ViewModels\PluginViewModel.cs" /> <Compile Include="ViewModels\PluginViewModel.cs" />
@@ -191,10 +191,11 @@
<Compile Include="Views\AddWorkshopItemsDialog.xaml.cs"> <Compile Include="Views\AddWorkshopItemsDialog.xaml.cs">
<DependentUpon>AddWorkshopItemsDialog.xaml</DependentUpon> <DependentUpon>AddWorkshopItemsDialog.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\Blocks\BlockView.xaml.cs"> <Compile Include="Views\Converters\Vector3DConverter.cs" />
<Compile Include="Views\Entities\Blocks\BlockView.xaml.cs">
<DependentUpon>BlockView.xaml</DependentUpon> <DependentUpon>BlockView.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\Blocks\PropertyView.xaml.cs"> <Compile Include="Views\Entities\Blocks\PropertyView.xaml.cs">
<DependentUpon>PropertyView.xaml</DependentUpon> <DependentUpon>PropertyView.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\ChatControl.xaml.cs"> <Compile Include="Views\ChatControl.xaml.cs">
@@ -206,6 +207,14 @@
<Compile Include="Views\EntitiesControl.xaml.cs"> <Compile Include="Views\EntitiesControl.xaml.cs">
<DependentUpon>EntitiesControl.xaml</DependentUpon> <DependentUpon>EntitiesControl.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\Converters\StringBuilderConverter.cs" />
<Compile Include="Views\Converters\StringIdConverter.cs" />
<Compile Include="Views\Entities\GridView.xaml.cs">
<DependentUpon>GridView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\Entities\VoxelMapView.xaml.cs">
<DependentUpon>VoxelMapView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ModsControl.xaml.cs"> <Compile Include="Views\ModsControl.xaml.cs">
<DependentUpon>ModsControl.xaml</DependentUpon> <DependentUpon>ModsControl.xaml</DependentUpon>
</Compile> </Compile>
@@ -260,11 +269,11 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Views\Blocks\BlockView.xaml"> <Page Include="Views\Entities\Blocks\BlockView.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Views\Blocks\PropertyView.xaml"> <Page Include="Views\Entities\Blocks\PropertyView.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
@@ -280,6 +289,14 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Views\Entities\GridView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\Entities\VoxelMapView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ModsControl.xaml"> <Page Include="Views\ModsControl.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

View File

@@ -1,8 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing.Text;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Sandbox.Game.Entities.Cube;
using Sandbox.ModAPI; using Sandbox.ModAPI;
using Sandbox.ModAPI.Interfaces; using Sandbox.ModAPI.Interfaces;
using Torch.Server.ViewModels.Entities; using Torch.Server.ViewModels.Entities;
@@ -26,9 +29,22 @@ namespace Torch.Server.ViewModels.Blocks
} }
} }
/// <inheritdoc />
public override string Position { get => base.Position; set { } }
public long BuiltBy
{
get => ((MySlimBlock)Block.SlimBlock).BuiltBy;
set
{
TorchBase.Instance.InvokeBlocking(() => ((MySlimBlock)Block.SlimBlock).TransferAuthorship(value));
OnPropertyChanged();
}
}
public override bool CanStop => false; public override bool CanStop => false;
public BlockViewModel(IMyTerminalBlock block) : base(block) public BlockViewModel(IMyTerminalBlock block, EntityTreeViewModel tree) : base(block, tree)
{ {
Block = block; Block = block;
var propList = new List<ITerminalProperty>(); var propList = new List<ITerminalProperty>();

View File

@@ -4,7 +4,7 @@ namespace Torch.Server.ViewModels.Entities
{ {
public class CharacterViewModel : EntityViewModel public class CharacterViewModel : EntityViewModel
{ {
public CharacterViewModel(MyCharacter character) : base(character) public CharacterViewModel(MyCharacter character, EntityTreeViewModel tree) : base(character, tree)
{ {
} }

View File

@@ -6,6 +6,7 @@ namespace Torch.Server.ViewModels.Entities
{ {
public class EntityViewModel : ViewModel public class EntityViewModel : ViewModel
{ {
protected EntityTreeViewModel Tree { get; }
public IMyEntity Entity { get; } public IMyEntity Entity { get; }
public long Id => Entity.EntityId; public long Id => Entity.EntityId;
@@ -36,7 +37,7 @@ namespace Torch.Server.ViewModels.Entities
public virtual bool CanDelete => !(Entity is IMyCharacter); public virtual bool CanDelete => !(Entity is IMyCharacter);
public EntityViewModel(IMyEntity entity) public EntityViewModel(IMyEntity entity, EntityTreeViewModel tree)
{ {
Entity = entity; Entity = entity;
} }

View File

@@ -9,6 +9,6 @@ namespace Torch.Server.ViewModels
public override string Name => $"{base.Name} ({Floating.Amount})"; public override string Name => $"{base.Name} ({Floating.Amount})";
public FloatingObjectViewModel(MyFloatingObject floating) : base(floating) { } public FloatingObjectViewModel(MyFloatingObject floating, EntityTreeViewModel tree) : base(floating, tree) { }
} }
} }

View File

@@ -11,15 +11,17 @@ namespace Torch.Server.ViewModels.Entities
public MTObservableCollection<BlockViewModel> Blocks { get; } = new MTObservableCollection<BlockViewModel>(); public MTObservableCollection<BlockViewModel> Blocks { get; } = new MTObservableCollection<BlockViewModel>();
/// <inheritdoc /> /// <inheritdoc />
public override string Name => $"{base.Name} ({Grid.BlocksCount} blocks)"; public string DescriptiveName => $"{Name} ({Grid.BlocksCount} blocks)";
public GridViewModel(MyCubeGrid grid) : base(grid) public GridViewModel() { }
public GridViewModel(MyCubeGrid grid, EntityTreeViewModel tree) : base(grid, tree)
{ {
TorchBase.Instance.InvokeBlocking(() => TorchBase.Instance.InvokeBlocking(() =>
{ {
foreach (var block in grid.GetFatBlocks().Where(b => b is IMyTerminalBlock)) foreach (var block in grid.GetFatBlocks().Where(b => b is IMyTerminalBlock))
{ {
Blocks.Add(new BlockViewModel((IMyTerminalBlock)block)); Blocks.Add(new BlockViewModel((IMyTerminalBlock)block, tree));
} }
}); });
Blocks.Sort(b => b.Block.GetType().AssemblyQualifiedName); Blocks.Sort(b => b.Block.GetType().AssemblyQualifiedName);
@@ -39,8 +41,9 @@ namespace Torch.Server.ViewModels.Entities
private void Grid_OnBlockAdded(Sandbox.Game.Entities.Cube.MySlimBlock obj) private void Grid_OnBlockAdded(Sandbox.Game.Entities.Cube.MySlimBlock obj)
{ {
if (obj.FatBlock != null) var block = obj.FatBlock as IMyTerminalBlock;
Blocks.Add(new BlockViewModel((IMyTerminalBlock)obj.FatBlock)); if (block != null)
Blocks.Add(new BlockViewModel(block, Tree));
Blocks.Sort(b => b.Block.GetType().AssemblyQualifiedName); Blocks.Sort(b => b.Block.GetType().AssemblyQualifiedName);
OnPropertyChanged(nameof(Name)); OnPropertyChanged(nameof(Name));

View File

@@ -1,4 +1,9 @@
using Sandbox.Game.Entities; using System.Collections.Generic;
using System.Linq;
using Sandbox.Game.Entities;
using VRage.Game.Entity;
using VRage.Game.ModAPI;
using VRage.Library.Collections;
namespace Torch.Server.ViewModels.Entities namespace Torch.Server.ViewModels.Entities
{ {
@@ -10,6 +15,35 @@ namespace Torch.Server.ViewModels.Entities
public override bool CanStop => false; public override bool CanStop => false;
public VoxelMapViewModel(MyVoxelBase e) : base(e) { } public MTObservableCollection<GridViewModel> AttachedGrids { get; } = new MTObservableCollection<GridViewModel>();
public void UpdateAttachedGrids()
{
AttachedGrids.Clear();
var box = Entity.WorldAABB;
var entities = new List<MyEntity>();
MyGamePruningStructure.GetTopMostEntitiesInBox(ref box, entities, MyEntityQueryType.Static);
foreach (var entity in entities.Where(e => e is IMyCubeGrid))
{
var gridModel = Tree.Grids.FirstOrDefault(g => g.Entity.EntityId == entity.EntityId);
if (gridModel == null)
{
gridModel = new GridViewModel((MyCubeGrid)entity, Tree);
Tree.Grids.Add(gridModel);
}
AttachedGrids.Add(gridModel);
}
}
public VoxelMapViewModel(MyVoxelBase e, EntityTreeViewModel tree) : base(e, tree)
{
}
public VoxelMapViewModel()
{
}
} }
} }

View File

@@ -53,20 +53,23 @@ namespace Torch.Server.ViewModels
private void MyEntities_OnEntityAdd(VRage.Game.Entity.MyEntity obj) private void MyEntities_OnEntityAdd(VRage.Game.Entity.MyEntity obj)
{ {
//TODO: make view models
switch (obj) switch (obj)
{ {
case MyCubeGrid grid: case MyCubeGrid grid:
Grids.Add(new GridViewModel(grid)); if (Grids.All(g => g.Entity.EntityId != obj.EntityId))
Grids.Add(new GridViewModel(grid, this));
break; break;
case MyCharacter character: case MyCharacter character:
Characters.Add(new CharacterViewModel(character)); if (Characters.All(g => g.Entity.EntityId != obj.EntityId))
Characters.Add(new CharacterViewModel(character, this));
break; break;
case MyFloatingObject floating: case MyFloatingObject floating:
FloatingObjects.Add(new FloatingObjectViewModel(floating)); if (FloatingObjects.All(g => g.Entity.EntityId != obj.EntityId))
FloatingObjects.Add(new FloatingObjectViewModel(floating, this));
break; break;
case MyVoxelBase voxel: case MyVoxelBase voxel:
VoxelMaps.Add(new VoxelMapViewModel(voxel)); if (VoxelMaps.All(g => g.Entity.EntityId != obj.EntityId))
VoxelMaps.Add(new VoxelMapViewModel(voxel, this));
break; break;
} }
} }

View File

@@ -16,7 +16,7 @@
<ComboBox Text="{Binding LoadWorld}" ItemsSource="{Binding WorldPaths}" IsEditable="True" Margin="3" /> <ComboBox Text="{Binding LoadWorld}" ItemsSource="{Binding WorldPaths}" IsEditable="True" Margin="3" />
</DockPanel> </DockPanel>
<DockPanel DockPanel.Dock="Bottom"> <DockPanel DockPanel.Dock="Bottom">
<StackPanel> <StackPanel DockPanel.Dock="Left">
<ScrollViewer IsEnabled="True"> <ScrollViewer IsEnabled="True">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<StackPanel Margin="3" DockPanel.Dock="Left"> <StackPanel Margin="3" DockPanel.Dock="Left">
@@ -48,7 +48,7 @@
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>
</ScrollViewer> </ScrollViewer>
<Button Content="Save Config" Margin="3" Click="Save_OnClick"></Button> <Button Content="Save Config" Margin="3" Click="Save_OnClick" />
</StackPanel> </StackPanel>
<ScrollViewer Margin="3" DockPanel.Dock="Right" IsEnabled="True"> <ScrollViewer Margin="3" DockPanel.Dock="Right" IsEnabled="True">
<StackPanel DataContext="{Binding SessionSettings}"> <StackPanel DataContext="{Binding SessionSettings}">

View File

@@ -0,0 +1,22 @@
using System;
using System.Globalization;
using System.Text;
using System.Windows.Data;
namespace Torch.Server.Views.Converters
{
public class StringBuilderConverter : IValueConverter
{
/// <inheritdoc />
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((StringBuilder)value).ToString();
}
/// <inheritdoc />
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return new StringBuilder((string)value);
}
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Globalization;
using System.Windows.Data;
using VRage.Utils;
namespace Torch.Server.Views.Converters
{
public class StringIdConverter : IValueConverter
{
/// <inheritdoc />
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return MyStringId.GetOrCompute((string)value);
}
/// <inheritdoc />
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new InvalidOperationException();
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using VRageMath;
namespace Torch.Server.Views.Converters
{
public class Vector3DConverter : IValueConverter
{
/// <inheritdoc />
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((Vector3D)value).ToString();
}
/// <inheritdoc />
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (Vector3D.TryParse((string)value, out Vector3D vec))
return vec;
throw new ArgumentException();
}
}
}

View File

@@ -10,7 +10,14 @@
<blocks:BlockViewModel /> <blocks:BlockViewModel />
</UserControl.DataContext> </UserControl.DataContext>
<DockPanel x:Name="Stack" Margin="3"> <DockPanel x:Name="Stack" Margin="3">
<Label Content="{Binding FullName}" FontSize="16" DockPanel.Dock="Top" /> <StackPanel DockPanel.Dock="Top">
<Label Content="{Binding FullName}" FontSize="16" />
<StackPanel Orientation="Horizontal">
<Label Content="Built By: "/>
<TextBox Text="{Binding BuiltBy}" HorizontalAlignment="Stretch" Margin="3"/>
</StackPanel>
<Label Content="Properties"/>
</StackPanel>
<ListView ItemsSource="{Binding Properties}" Margin="3" IsEnabled="True" DockPanel.Dock="Bottom"> <ListView ItemsSource="{Binding Properties}" Margin="3" IsEnabled="True" DockPanel.Dock="Bottom">
<ListView.ItemTemplate> <ListView.ItemTemplate>
<DataTemplate> <DataTemplate>

View File

@@ -5,9 +5,10 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Torch.Server.Views.Blocks" xmlns:local="clr-namespace:Torch.Server.Views.Blocks"
xmlns:blocks="clr-namespace:Torch.Server.ViewModels.Blocks" xmlns:blocks="clr-namespace:Torch.Server.ViewModels.Blocks"
xmlns:converters="clr-namespace:Torch.Server.Views.Converters"
mc:Ignorable="d"> mc:Ignorable="d">
<UserControl.Resources> <UserControl.Resources>
<local:StringIdConverter x:Key="StringIdConverter"/> <converters:StringIdConverter x:Key="StringIdConverter"/>
</UserControl.Resources> </UserControl.Resources>
<DockPanel x:Name="Dock"> <DockPanel x:Name="Dock">
<Label x:Name="Label" Width="150" VerticalAlignment="Center" DockPanel.Dock="Left"> <Label x:Name="Label" Width="150" VerticalAlignment="Center" DockPanel.Dock="Left">

View File

@@ -1,6 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -15,7 +13,7 @@ using System.Windows.Media.Imaging;
using System.Windows.Navigation; using System.Windows.Navigation;
using System.Windows.Shapes; using System.Windows.Shapes;
using Torch.Server.ViewModels.Blocks; using Torch.Server.ViewModels.Blocks;
using VRage.Utils; using Torch.Server.Views.Converters;
namespace Torch.Server.Views.Blocks namespace Torch.Server.Views.Blocks
{ {
@@ -71,34 +69,4 @@ namespace Torch.Server.Views.Blocks
Frame.Content = textBox; Frame.Content = textBox;
} }
} }
public class StringBuilderConverter : IValueConverter
{
/// <inheritdoc />
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((StringBuilder)value).ToString();
}
/// <inheritdoc />
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return new StringBuilder((string)value);
}
}
public class StringIdConverter : IValueConverter
{
/// <inheritdoc />
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return MyStringId.GetOrCompute((string)value);
}
/// <inheritdoc />
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new InvalidOperationException();
}
}
} }

View File

@@ -0,0 +1,22 @@
<UserControl x:Class="Torch.Server.Views.Entities.GridView"
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.Entities"
xmlns:entities="clr-namespace:Torch.Server.ViewModels.Entities"
mc:Ignorable="d">
<UserControl.DataContext>
<entities:GridViewModel />
</UserControl.DataContext>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="Name" Width="100"/>
<TextBox Text="{Binding Name}" Margin="3"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="Position" Width="100"/>
<TextBox Text="{Binding Position}" Margin="3" />
</StackPanel>
</StackPanel>
</UserControl>

View 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.Entities
{
/// <summary>
/// Interaction logic for GridView.xaml
/// </summary>
public partial class GridView : UserControl
{
public GridView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,22 @@
<UserControl x:Class="Torch.Server.Views.Entities.VoxelMapView"
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.Entities"
xmlns:entities="clr-namespace:Torch.Server.ViewModels.Entities"
mc:Ignorable="d">
<UserControl.DataContext>
<entities:VoxelMapViewModel/>
</UserControl.DataContext>
<StackPanel>
<Label Content="Attached Grids"></Label>
<ListView ItemsSource="{Binding AttachedGrids}" Margin="3">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</UserControl>

View File

@@ -0,0 +1,35 @@
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;
using Torch.Server.ViewModels.Entities;
namespace Torch.Server.Views.Entities
{
/// <summary>
/// Interaction logic for VoxelMapView.xaml
/// </summary>
public partial class VoxelMapView : UserControl
{
public VoxelMapView()
{
InitializeComponent();
DataContextChanged += VoxelMapView_DataContextChanged;
}
private void VoxelMapView_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
((VoxelMapViewModel)e.NewValue).UpdateAttachedGrids();
}
}
}

View File

@@ -5,9 +5,8 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Torch.Server.Views" xmlns:local="clr-namespace:Torch.Server.Views"
xmlns:viewModels="clr-namespace:Torch.Server.ViewModels" xmlns:viewModels="clr-namespace:Torch.Server.ViewModels"
xmlns:blocks="clr-namespace:Torch.Server.Views.Blocks"
xmlns:entities="clr-namespace:Torch.Server.ViewModels.Entities" xmlns:entities="clr-namespace:Torch.Server.ViewModels.Entities"
xmlns:blocks1="clr-namespace:Torch.Server.ViewModels.Blocks" xmlns:blocks="clr-namespace:Torch.Server.ViewModels.Blocks"
mc:Ignorable="d"> mc:Ignorable="d">
<UserControl.DataContext> <UserControl.DataContext>
<viewModels:EntityTreeViewModel /> <viewModels:EntityTreeViewModel />
@@ -22,11 +21,14 @@
<TreeView Width="300" Margin="3" DockPanel.Dock="Top" SelectedItemChanged="TreeView_OnSelectedItemChanged"> <TreeView Width="300" Margin="3" DockPanel.Dock="Top" SelectedItemChanged="TreeView_OnSelectedItemChanged">
<TreeView.Resources> <TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type entities:GridViewModel}" ItemsSource="{Binding Blocks}"> <HierarchicalDataTemplate DataType="{x:Type entities:GridViewModel}" ItemsSource="{Binding Blocks}">
<TextBlock Text="{Binding Name}" /> <TextBlock Text="{Binding DescriptiveName}" />
</HierarchicalDataTemplate> </HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type blocks1:BlockViewModel}"> <DataTemplate DataType="{x:Type blocks:BlockViewModel}">
<TextBlock Text="{Binding Path=Name}" /> <TextBlock Text="{Binding Path=Name}" />
</DataTemplate> </DataTemplate>
<HierarchicalDataTemplate DataType="{x:Type entities:VoxelMapViewModel}" ItemsSource="{Binding AttachedGrids}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
</TreeView.Resources> </TreeView.Resources>
<TreeViewItem ItemsSource="{Binding Grids}" IsExpanded="true"> <TreeViewItem ItemsSource="{Binding Grids}" IsExpanded="true">
<TreeViewItem.Header> <TreeViewItem.Header>

View File

@@ -16,6 +16,7 @@ using Torch.Server.ViewModels;
using Torch.Server.ViewModels.Blocks; using Torch.Server.ViewModels.Blocks;
using Torch.Server.ViewModels.Entities; using Torch.Server.ViewModels.Entities;
using Torch.Server.Views.Blocks; using Torch.Server.Views.Blocks;
using Torch.Server.Views.Entities;
using VRage.Game.ModAPI; using VRage.Game.ModAPI;
namespace Torch.Server.Views namespace Torch.Server.Views
@@ -38,11 +39,18 @@ namespace Torch.Server.Views
if (e.NewValue is EntityViewModel vm) if (e.NewValue is EntityViewModel vm)
{ {
Entities.CurrentEntity = vm; Entities.CurrentEntity = vm;
if (e.NewValue is GridViewModel 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)
EditorFrame.Content = new VoxelMapView {DataContext = vvm};
} }
else else
{
Entities.CurrentEntity = null; Entities.CurrentEntity = null;
EditorFrame.Content = null;
}
} }
private void Delete_OnClick(object sender, RoutedEventArgs e) private void Delete_OnClick(object sender, RoutedEventArgs e)

View File

@@ -6,7 +6,7 @@
xmlns:local="clr-namespace:Torch.Server" xmlns:local="clr-namespace:Torch.Server"
xmlns:views="clr-namespace:Torch.Server.Views" xmlns:views="clr-namespace:Torch.Server.Views"
mc:Ignorable="d" mc:Ignorable="d"
Title="Torch" Height="560" Width="700"> Title="Torch">
<DockPanel> <DockPanel>
<StackPanel DockPanel.Dock="Top" Margin="5,5,5,5" Orientation="Horizontal"> <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"/> <Button x:Name="BtnStart" Content="Start" Height="24" Width="75" Margin="5,0,5,0" HorizontalAlignment="Left" Click="BtnStart_Click" IsDefault="True"/>

View File

@@ -19,6 +19,7 @@ using System.Windows.Navigation;
using System.Windows.Shapes; using System.Windows.Shapes;
using Sandbox; using Sandbox;
using Torch.API; using Torch.API;
using VRageMath;
using Timer = System.Timers.Timer; using Timer = System.Timers.Timer;
namespace Torch.Server namespace Torch.Server
@@ -45,6 +46,11 @@ namespace Torch.Server
_startTime = DateTime.Now; _startTime = DateTime.Now;
_uiUpdate.Elapsed += UiUpdate_Elapsed; _uiUpdate.Elapsed += UiUpdate_Elapsed;
Left = _config.WindowPosition.X;
Top = _config.WindowPosition.Y;
Width = _config.WindowSize.X;
Height = _config.WindowSize.Y;
Chat.BindServer(server); Chat.BindServer(server);
PlayerList.BindServer(server); PlayerList.BindServer(server);
Plugins.BindServer(server); Plugins.BindServer(server);
@@ -101,6 +107,12 @@ namespace Torch.Server
protected override void OnClosing(CancelEventArgs e) protected override void OnClosing(CancelEventArgs e)
{ {
var newSize = new Vector2I((int)Width, (int)Height);
_config.WindowSize = newSize;
var newPos = new Vector2I((int)Left, (int)Top);
_config.WindowPosition = newPos;
_config.Save();
if (_server?.State == ServerState.Running) if (_server?.State == ServerState.Running)
_server.Stop(); _server.Stop();
} }

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Collections.Specialized; using System.Collections.Specialized;
@@ -33,6 +34,22 @@ namespace Torch
} }
} }
public void Insert<TKey>(T item, Func<T, TKey> selector, IComparer<TKey> comparer)
{
var key = selector(item);
for (var i = 0; i < Count; i++)
{
var key2 = selector(Items[i]);
if (comparer.Compare(key, key2) < 1)
continue;
Insert(i + 1, item);
return;
}
Add(item);
}
public void Sort<TKey>(Func<T, TKey> selector, IComparer<TKey> comparer = null) public void Sort<TKey>(Func<T, TKey> selector, IComparer<TKey> comparer = null)
{ {
List<T> sortedItems; List<T> sortedItems;

View File

@@ -10,13 +10,19 @@ namespace Torch.Commands
{ {
public List<string> Path { get; } public List<string> Path { get; }
/// <summary> [Obsolete("Use the other CategoryAttribute constructor.")]
/// Specifies where to add the class's commands in the command tree.
/// </summary>
/// <param name="path">Command path, e.g. "/admin config" -> "admin, config"</param>
public CategoryAttribute(params string[] path) public CategoryAttribute(params string[] path)
{ {
Path = path.Select(i => i.ToLower()).ToList(); Path = path.Select(i => i.ToLower()).ToList();
} }
/// <summary>
/// Provides information about where to place commands in the command tree. Supports space-delimited hierarchy.
/// </summary>
/// <param name="category"></param>
public CategoryAttribute(string category)
{
Path = category.Split(' ').ToList();
}
} }
} }

View File

@@ -36,7 +36,7 @@ namespace Torch.Commands
throw new TypeLoadException($"Method does not have a {nameof(CommandAttribute)}"); throw new TypeLoadException($"Method does not have a {nameof(CommandAttribute)}");
var permissionAttribute = commandMethod.GetCustomAttribute<PermissionAttribute>(); var permissionAttribute = commandMethod.GetCustomAttribute<PermissionAttribute>();
MinimumPromoteLevel = permissionAttribute?.PromoteLevel ?? MyPromoteLevel.None; MinimumPromoteLevel = permissionAttribute?.PromoteLevel ?? MyPromoteLevel.Admin;
if (!commandMethod.DeclaringType.IsSubclassOf(typeof(CommandModule))) if (!commandMethod.DeclaringType.IsSubclassOf(typeof(CommandModule)))
throw new TypeLoadException($"Command {commandMethod.Name}'s declaring type {commandMethod.DeclaringType.FullName} is not a subclass of {nameof(CommandModule)}"); throw new TypeLoadException($"Command {commandMethod.Name}'s declaring type {commandMethod.DeclaringType.FullName} is not a subclass of {nameof(CommandModule)}");

View File

@@ -11,6 +11,7 @@ namespace Torch.Commands
public string HelpText { get; } public string HelpText { get; }
public List<string> Path { get; } = new List<string>(); public List<string> Path { get; } = new List<string>();
[Obsolete("Use the other CommandAttribute constructor.")]
public CommandAttribute(string name, string description = "", string helpText = null, params string[] path) public CommandAttribute(string name, string description = "", string helpText = null, params string[] path)
{ {
Name = name; Name = name;
@@ -20,5 +21,18 @@ namespace Torch.Commands
Path.AddRange(path.Select(x => x.ToLower())); Path.AddRange(path.Select(x => x.ToLower()));
Path.Add(name.ToLower()); Path.Add(name.ToLower());
} }
/// <summary>
/// Provides information about the command. Supports space-delimited hierarchy.
/// </summary>
public CommandAttribute(string command, string description = "", string helpText = null)
{
var split = command.Split(' ');
Name = split.Last();
Description = description;
HelpText = helpText ?? description;
Path.AddRange(split);
}
} }
} }

View File

@@ -187,7 +187,7 @@ namespace Torch.Managers
{ {
UserRejected(steamID, JoinResult.ServerFull); UserRejected(steamID, JoinResult.ServerFull);
} }
else if (MySandboxGame.ConfigDedicated.Administrators.Contains(steamID.ToString()) || MySandboxGame.ConfigDedicated.Administrators.Contains(MyDedicatedServerBase.ConvertSteamIDFrom64(steamID))) else if (MySandboxGame.ConfigDedicated.Administrators.Contains(steamID.ToString()) /*|| MySandboxGame.ConfigDedicated.Administrators.Contains(MyDedicatedServerBase.ConvertSteamIDFrom64(steamID))*/)
{ {
UserAccepted(steamID); UserAccepted(steamID);
} }

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@@ -70,12 +71,24 @@ namespace Torch.Managers
//don't bother with nullchecks here, it was all handled in ReflectionUnitTest //don't bother with nullchecks here, it was all handled in ReflectionUnitTest
var transportType = typeof(MySyncLayer).GetField(MyTransportLayerField, BindingFlags.NonPublic | BindingFlags.Instance).FieldType; var transportType = typeof(MySyncLayer).GetField(MyTransportLayerField, BindingFlags.NonPublic | BindingFlags.Instance).FieldType;
var transportInstance = typeof(MySyncLayer).GetField(MyTransportLayerField, BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(MyMultiplayer.Static.SyncLayer); var transportInstance = typeof(MySyncLayer).GetField(MyTransportLayerField, BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(MyMultiplayer.Static.SyncLayer);
var handlers = (Dictionary<MyMessageId, Action<MyPacket>>)transportType.GetField(TransportHandlersField, BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(transportInstance); var handlers = (IDictionary)transportType.GetField(TransportHandlersField, BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(transportInstance);
var handlerTypeField = handlers.GetType().GenericTypeArguments[0].GetField("messageId"); //Should be MyTransportLayer.HandlerId
object id = null;
foreach (var key in handlers.Keys)
{
if ((MyMessageId)handlerTypeField.GetValue(key) != MyMessageId.RPC)
continue;
id = key;
break;
}
if (id == null)
throw new InvalidOperationException("RPC handler not found.");
//remove Keen's network listener //remove Keen's network listener
handlers.Remove(MyMessageId.RPC); handlers.Remove(id);
//replace it with our own //replace it with our own
handlers.Add(MyMessageId.RPC, ProcessEvent); handlers.Add(id, new Action<MyPacket>(OnEvent));
//PrintDebug(); //PrintDebug();
@@ -91,14 +104,14 @@ namespace Torch.Managers
/// DO NOT modify this method unless you're absolutely sure of what you're doing. This can very easily destabilize the game! /// DO NOT modify this method unless you're absolutely sure of what you're doing. This can very easily destabilize the game!
/// </summary> /// </summary>
/// <param name="packet"></param> /// <param name="packet"></param>
private void ProcessEvent(MyPacket packet) private void OnEvent(MyPacket packet)
{ {
if (_networkHandlers.Count == 0) if (_networkHandlers.Count == 0)
{ {
//pass the message back to the game server //pass the message back to the game server
try try
{ {
((MyReplicationLayer)MyMultiplayer.ReplicationLayer).ProcessEvent(packet); ((MyReplicationLayer)MyMultiplayer.ReplicationLayer).OnEvent(packet);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -156,7 +169,7 @@ namespace Torch.Managers
try try
{ {
if (handler.CanHandle(site)) if (handler.CanHandle(site))
discard |= handler.Handle(packet.Sender.Value, site, stream, obj, packet); discard |= handler.Handle(packet.Sender.Id.Value, site, stream, obj, packet);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -172,7 +185,7 @@ namespace Torch.Managers
//pass the message back to the game server //pass the message back to the game server
try try
{ {
((MyReplicationLayer)MyMultiplayer.ReplicationLayer).ProcessEvent(packet); ((MyReplicationLayer)MyMultiplayer.ReplicationLayer).OnEvent(packet);
} }
catch (Exception ex) catch (Exception ex)
{ {

65
Torch/Persistent.cs Normal file
View File

@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace Torch
{
/// <summary>
/// Class that manages saving <see cref="T"/> to disk using JSON serialization.
/// </summary>
/// <typeparam name="T">Data class</typeparam>
public class Persistent<T> : IDisposable where T : new()
{
[JsonIgnore]
public string Path { get; set; }
public T Data { get; private set; } = new T();
~Persistent()
{
Dispose();
}
public void Save(string path = null)
{
if (path == null)
path = Path;
using (var f = File.Create(path))
{
var writer = new StreamWriter(f);
writer.Write(JsonConvert.SerializeObject(Data, Formatting.Indented));
writer.Flush();
}
}
public static Persistent<T> Load(string path, bool saveIfNew = true)
{
var config = new Persistent<T> { Path = path };
if (File.Exists(path))
{
using (var f = File.OpenRead(path))
{
var reader = new StreamReader(f);
config.Data = JsonConvert.DeserializeObject<T>(reader.ReadToEnd());
}
}
else if (saveIfNew)
{
config.Save(path);
}
return config;
}
public void Dispose()
{
Save();
}
}
}

View File

@@ -36,6 +36,10 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\GameBinaries\HavokWrapper.dll</HintPath> <HintPath>..\GameBinaries\HavokWrapper.dll</HintPath>
</Reference> </Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\GameBinaries\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.4.1\lib\net45\NLog.dll</HintPath> <HintPath>..\packages\NLog.4.4.1\lib\net45\NLog.dll</HintPath>
<Private>True</Private> <Private>True</Private>
@@ -135,6 +139,7 @@
<Compile Include="Managers\NetworkManager\NetworkHandlerBase.cs" /> <Compile Include="Managers\NetworkManager\NetworkHandlerBase.cs" />
<Compile Include="Managers\NetworkManager\NetworkManager.cs" /> <Compile Include="Managers\NetworkManager\NetworkManager.cs" />
<Compile Include="Managers\MultiplayerManager.cs" /> <Compile Include="Managers\MultiplayerManager.cs" />
<Compile Include="Persistent.cs" />
<Compile Include="TorchConfig.cs" /> <Compile Include="TorchConfig.cs" />
<Compile Include="Updater\PluginManifest.cs" /> <Compile Include="Updater\PluginManifest.cs" />
<Compile Include="Reflection.cs" /> <Compile Include="Reflection.cs" />

View File

@@ -7,6 +7,7 @@ using System.Threading.Tasks;
using System.Xml.Serialization; using System.Xml.Serialization;
using NLog; using NLog;
using Sandbox.ModAPI.Ingame; using Sandbox.ModAPI.Ingame;
using VRageMath;
namespace Torch namespace Torch
{ {
@@ -22,6 +23,8 @@ namespace Torch
public bool EnableAutomaticUpdates { get; set; } = true; public bool EnableAutomaticUpdates { get; set; } = true;
public bool RedownloadPlugins { get; set; } public bool RedownloadPlugins { get; set; }
public List<string> Plugins { get; set; } = new List<string>(); public List<string> Plugins { get; set; } = new List<string>();
public Vector2I WindowSize { get; set; } = new Vector2I(800, 600);
public Vector2I WindowPosition { get; set; } = new Vector2I();
[NonSerialized] [NonSerialized]
private string _path; private string _path;