Merge branch 'Patron' of https://github.com/TorchAPI/Torch into survival
This commit is contained in:
@@ -10,6 +10,8 @@ using Torch.Collections;
|
||||
using Torch.Server.Managers;
|
||||
using VRage.Game;
|
||||
using VRage.Game.ModAPI;
|
||||
using Torch.Utils.SteamWorkshopTools;
|
||||
using Torch.Collections;
|
||||
|
||||
namespace Torch.Server.ViewModels
|
||||
{
|
||||
@@ -29,6 +31,7 @@ namespace Torch.Server.ViewModels
|
||||
_config = configDedicated;
|
||||
_config.IgnoreLastSession = true;
|
||||
SessionSettings = new SessionSettingsViewModel(_config.SessionSettings);
|
||||
Task.Run(() => UpdateAllModInfosAsync());
|
||||
}
|
||||
|
||||
public void Save(string path = null)
|
||||
@@ -73,14 +76,61 @@ namespace Torch.Server.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UpdateAllModInfosAsync(Action<string> messageHandler = null)
|
||||
{
|
||||
if (Mods.Count() == 0)
|
||||
return;
|
||||
|
||||
var ids = Mods.Select(m => m.PublishedFileId);
|
||||
var workshopService = WebAPI.Instance;
|
||||
Dictionary<ulong, PublishedItemDetails> modInfos = null;
|
||||
|
||||
try
|
||||
{
|
||||
modInfos = (await workshopService.GetPublishedFileDetails(ids.ToArray()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Info($"Mods Info successfully retrieved!");
|
||||
|
||||
foreach (var mod in Mods)
|
||||
{
|
||||
if (!modInfos.ContainsKey(mod.PublishedFileId) || modInfos[mod.PublishedFileId] == null)
|
||||
{
|
||||
Log.Error($"Failed to retrieve info for mod with workshop id '{mod.PublishedFileId}'!");
|
||||
}
|
||||
//else if (!modInfo.Tags.Contains(""))
|
||||
else
|
||||
{
|
||||
mod.FriendlyName = modInfos[mod.PublishedFileId].Title;
|
||||
mod.Description = modInfos[mod.PublishedFileId].Description;
|
||||
//mod.Name = modInfos[mod.PublishedFileId].FileName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<string> Administrators { get => _config.Administrators; set => SetValue(x => _config.Administrators = x, value); }
|
||||
|
||||
public List<ulong> Banned { get => _config.Banned; set => SetValue(x => _config.Banned = x, value); }
|
||||
|
||||
private MtObservableList<ModItemInfo> _mods = new MtObservableList<ModItemInfo>();
|
||||
public MtObservableList<ModItemInfo> Mods
|
||||
{
|
||||
get => _mods;
|
||||
set
|
||||
{
|
||||
SetValue(x => _mods = x, value);
|
||||
Task.Run(() => UpdateAllModInfosAsync());
|
||||
}
|
||||
}
|
||||
|
||||
public List<ulong> Reserved { get => _config.Reserved; set => SetValue(x => _config.Reserved = x, value); }
|
||||
|
||||
private List<ulong> _mods = new List<ulong>();
|
||||
public List<ulong> Mods { get => _mods; set => SetValue(x => _mods = x, value); }
|
||||
|
||||
public int AsteroidAmount { get => _config.AsteroidAmount; set => SetValue(x => _config.AsteroidAmount = x, value); }
|
||||
|
||||
|
@@ -1,8 +1,14 @@
|
||||
using System.Windows.Controls;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Controls;
|
||||
using NLog;
|
||||
using Sandbox.Game.Entities;
|
||||
using Sandbox.Game.World;
|
||||
using Torch.API.Managers;
|
||||
using Torch.Collections;
|
||||
using Torch.Server.Managers;
|
||||
using Torch.Utils;
|
||||
using VRage.Game.Entity;
|
||||
using VRage.Game.ModAPI;
|
||||
using VRage.ModAPI;
|
||||
@@ -14,6 +20,8 @@ namespace Torch.Server.ViewModels.Entities
|
||||
{
|
||||
protected EntityTreeViewModel Tree { get; }
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private IMyEntity _backing;
|
||||
public IMyEntity Entity
|
||||
{
|
||||
@@ -43,6 +51,75 @@ namespace Torch.Server.ViewModels.Entities
|
||||
}
|
||||
}
|
||||
|
||||
private string _descriptiveName;
|
||||
public string DescriptiveName
|
||||
{
|
||||
get => _descriptiveName ?? (_descriptiveName = GetSortedName(EntityTreeViewModel.SortEnum.Name));
|
||||
set => _descriptiveName = value;
|
||||
}
|
||||
|
||||
public virtual string GetSortedName(EntityTreeViewModel.SortEnum sort)
|
||||
{
|
||||
switch (sort)
|
||||
{
|
||||
case EntityTreeViewModel.SortEnum.Name:
|
||||
return Name;
|
||||
case EntityTreeViewModel.SortEnum.Size:
|
||||
return $"{Name} ({Entity.WorldVolume.Radius * 2:N}m)";
|
||||
case EntityTreeViewModel.SortEnum.Speed:
|
||||
return $"{Name} ({Entity.Physics?.LinearVelocity.Length() ?? 0:N}m/s)";
|
||||
case EntityTreeViewModel.SortEnum.BlockCount:
|
||||
if (Entity is MyCubeGrid grid)
|
||||
return $"{Name} ({grid.BlocksCount} blocks)";
|
||||
return Name;
|
||||
case EntityTreeViewModel.SortEnum.DistFromCenter:
|
||||
return $"{Name} ({Entity.GetPosition().Length():N}m)";
|
||||
case EntityTreeViewModel.SortEnum.Owner:
|
||||
if (Entity is MyCubeGrid g)
|
||||
return $"{Name} ({g.GetGridOwnerName()})";
|
||||
return Name;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(sort), sort, null);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int CompareToSort(EntityViewModel other, EntityTreeViewModel.SortEnum sort)
|
||||
{
|
||||
switch (sort)
|
||||
{
|
||||
case EntityTreeViewModel.SortEnum.Name:
|
||||
return string.Compare(Name, other.Name, StringComparison.InvariantCultureIgnoreCase);
|
||||
case EntityTreeViewModel.SortEnum.Size:
|
||||
return Entity.WorldVolume.Radius.CompareTo(other.Entity.WorldVolume.Radius);
|
||||
case EntityTreeViewModel.SortEnum.Speed:
|
||||
if (Entity.Physics == null)
|
||||
{
|
||||
if (other.Entity.Physics == null)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
if (other.Entity.Physics == null)
|
||||
return 1;
|
||||
return Entity.Physics.LinearVelocity.LengthSquared().CompareTo(other.Entity.Physics.LinearVelocity.LengthSquared());
|
||||
case EntityTreeViewModel.SortEnum.BlockCount:
|
||||
{
|
||||
if (Entity is MyCubeGrid ga && other.Entity is MyCubeGrid gb)
|
||||
return ga.BlocksCount.CompareTo(gb.BlocksCount);
|
||||
goto case EntityTreeViewModel.SortEnum.Name;
|
||||
}
|
||||
case EntityTreeViewModel.SortEnum.DistFromCenter:
|
||||
return Entity.GetPosition().LengthSquared().CompareTo(other.Entity.GetPosition().LengthSquared());
|
||||
case EntityTreeViewModel.SortEnum.Owner:
|
||||
{
|
||||
if (Entity is MyCubeGrid ga && other.Entity is MyCubeGrid gb)
|
||||
return string.Compare(ga.GetGridOwnerName(), gb.GetGridOwnerName(), StringComparison.InvariantCultureIgnoreCase);
|
||||
goto case EntityTreeViewModel.SortEnum.Name;
|
||||
}
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(sort), sort, null);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual string Position
|
||||
{
|
||||
get => Entity?.GetPosition().ToString();
|
||||
@@ -76,5 +153,20 @@ namespace Torch.Server.ViewModels.Entities
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class Comparer : IComparer<EntityViewModel>
|
||||
{
|
||||
private EntityTreeViewModel.SortEnum _sort;
|
||||
|
||||
public Comparer(EntityTreeViewModel.SortEnum sort)
|
||||
{
|
||||
_sort = sort;
|
||||
}
|
||||
|
||||
public int Compare(EntityViewModel x, EntityViewModel y)
|
||||
{
|
||||
return x.CompareToSort(y, _sort);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -50,17 +50,14 @@ namespace Torch.Server.ViewModels.Entities
|
||||
Blocks { get; } =
|
||||
new MtObservableSortedDictionary<MyCubeBlockDefinition, MtObservableSortedDictionary<long, BlockViewModel>>(
|
||||
CubeBlockDefinitionComparer.Default);
|
||||
|
||||
/// <inheritdoc />
|
||||
public string DescriptiveName { get; }
|
||||
|
||||
|
||||
public GridViewModel()
|
||||
{
|
||||
}
|
||||
|
||||
public GridViewModel(MyCubeGrid grid, EntityTreeViewModel tree) : base(grid, tree)
|
||||
{
|
||||
DescriptiveName = $"{grid.DisplayName} ({grid.BlocksCount} blocks)";
|
||||
//DescriptiveName = $"{grid.DisplayName} ({grid.BlocksCount} blocks)";
|
||||
Blocks.Add(_fillerDefinition, new MtObservableSortedDictionary<long, BlockViewModel>());
|
||||
}
|
||||
|
||||
|
@@ -12,11 +12,21 @@ using VRage.ModAPI;
|
||||
using System.Windows.Threading;
|
||||
using NLog;
|
||||
using Torch.Collections;
|
||||
using Torch.Server.Views.Entities;
|
||||
|
||||
namespace Torch.Server.ViewModels
|
||||
{
|
||||
public class EntityTreeViewModel : ViewModel
|
||||
{
|
||||
public enum SortEnum
|
||||
{
|
||||
Name,
|
||||
Size,
|
||||
Speed,
|
||||
Owner,
|
||||
BlockCount,
|
||||
DistFromCenter,
|
||||
}
|
||||
private static readonly Logger _log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
//TODO: these should be sorted sets for speed
|
||||
@@ -26,7 +36,13 @@ namespace Torch.Server.ViewModels
|
||||
public MtObservableSortedDictionary<long, VoxelMapViewModel> VoxelMaps { get; set; } = new MtObservableSortedDictionary<long, VoxelMapViewModel>();
|
||||
public Dispatcher ControlDispatcher => _control.Dispatcher;
|
||||
|
||||
public SortedView<GridViewModel> SortedGrids { get; }
|
||||
public SortedView<CharacterViewModel> SortedCharacters { get; }
|
||||
public SortedView<EntityViewModel> SortedFloatingObjects { get; }
|
||||
public SortedView<VoxelMapViewModel> SortedVoxelMaps { get; }
|
||||
|
||||
private EntityViewModel _currentEntity;
|
||||
private SortEnum _currentSort;
|
||||
private UserControl _control;
|
||||
|
||||
public EntityViewModel CurrentEntity
|
||||
@@ -35,6 +51,12 @@ namespace Torch.Server.ViewModels
|
||||
set { _currentEntity = value; OnPropertyChanged(nameof(CurrentEntity)); }
|
||||
}
|
||||
|
||||
public SortEnum CurrentSort
|
||||
{
|
||||
get => _currentSort;
|
||||
set => SetValue(ref _currentSort, value);
|
||||
}
|
||||
|
||||
// I hate you today WPF
|
||||
public EntityTreeViewModel() : this(null)
|
||||
{
|
||||
@@ -43,6 +65,11 @@ namespace Torch.Server.ViewModels
|
||||
public EntityTreeViewModel(UserControl control)
|
||||
{
|
||||
_control = control;
|
||||
var comparer = new EntityViewModel.Comparer(_currentSort);
|
||||
SortedGrids = new SortedView<GridViewModel>(Grids.Values, comparer);
|
||||
SortedCharacters = new SortedView<CharacterViewModel>(Characters.Values, comparer);
|
||||
SortedFloatingObjects = new SortedView<EntityViewModel>(FloatingObjects.Values, comparer);
|
||||
SortedVoxelMaps = new SortedView<VoxelMapViewModel>(VoxelMaps.Values, comparer);
|
||||
}
|
||||
|
||||
public void Init()
|
||||
@@ -85,16 +112,16 @@ namespace Torch.Server.ViewModels
|
||||
switch (obj)
|
||||
{
|
||||
case MyCubeGrid grid:
|
||||
Grids.Add(obj.EntityId, new GridViewModel(grid, this));
|
||||
Grids.Add(grid.EntityId, new GridViewModel(grid, this));
|
||||
break;
|
||||
case MyCharacter character:
|
||||
Characters.Add(obj.EntityId, new CharacterViewModel(character, this));
|
||||
Characters.Add(character.EntityId, new CharacterViewModel(character, this));
|
||||
break;
|
||||
case MyFloatingObject floating:
|
||||
FloatingObjects.Add(obj.EntityId, new FloatingObjectViewModel(floating, this));
|
||||
FloatingObjects.Add(floating.EntityId, new FloatingObjectViewModel(floating, this));
|
||||
break;
|
||||
case MyVoxelBase voxel:
|
||||
VoxelMaps.Add(obj.EntityId, new VoxelMapViewModel(voxel, this));
|
||||
VoxelMaps.Add(voxel.EntityId, new VoxelMapViewModel(voxel, this));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
131
Torch.Server/ViewModels/ModItemInfo.cs
Normal file
131
Torch.Server/ViewModels/ModItemInfo.cs
Normal file
@@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Threading;
|
||||
using System.Runtime.CompilerServices;
|
||||
using NLog;
|
||||
using VRage.Game;
|
||||
using Torch.Server.Annotations;
|
||||
using Torch.Utils.SteamWorkshopTools;
|
||||
|
||||
namespace Torch.Server.ViewModels
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper around VRage.Game.Objectbuilder_Checkpoint.ModItem
|
||||
/// that holds additional meta information
|
||||
/// (e.g. workshop description)
|
||||
/// </summary>
|
||||
public class ModItemInfo : ViewModel
|
||||
{
|
||||
MyObjectBuilder_Checkpoint.ModItem _modItem;
|
||||
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// Human friendly name of the mod
|
||||
/// </summary>
|
||||
public string FriendlyName
|
||||
{
|
||||
get { return _modItem.FriendlyName; }
|
||||
set {
|
||||
SetValue(ref _modItem.FriendlyName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Workshop ID of the mod
|
||||
/// </summary>
|
||||
public ulong PublishedFileId
|
||||
{
|
||||
get { return _modItem.PublishedFileId; }
|
||||
set
|
||||
{
|
||||
SetValue(ref _modItem.PublishedFileId, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Local filename of the mod
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get { return _modItem.Name; }
|
||||
set
|
||||
{
|
||||
SetValue(ref _modItem.FriendlyName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the mod was added
|
||||
/// because another mod depends on it
|
||||
/// </summary>
|
||||
public bool IsDependency
|
||||
{
|
||||
get { return _modItem.IsDependency; }
|
||||
set
|
||||
{
|
||||
SetValue(ref _modItem.IsDependency, value);
|
||||
}
|
||||
}
|
||||
|
||||
private string _description;
|
||||
/// <summary>
|
||||
/// Workshop description of the mod
|
||||
/// </summary>
|
||||
public string Description
|
||||
{
|
||||
get { return _description; }
|
||||
set
|
||||
{
|
||||
SetValue(ref _description, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor, returns a new ModItemInfo instance
|
||||
/// </summary>
|
||||
/// <param name="mod">The wrapped mod</param>
|
||||
public ModItemInfo(MyObjectBuilder_Checkpoint.ModItem mod)
|
||||
{
|
||||
_modItem = mod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve information about the
|
||||
/// wrapped mod from the workhop asynchronously
|
||||
/// via the Steam web API.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> UpdateModInfoAsync()
|
||||
{
|
||||
var msg = "";
|
||||
var workshopService = WebAPI.Instance;
|
||||
PublishedItemDetails modInfo = null;
|
||||
try
|
||||
{
|
||||
modInfo = (await workshopService.GetPublishedFileDetails(new ulong[] { PublishedFileId }))?[PublishedFileId];
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Log.Error(e.Message);
|
||||
}
|
||||
if (modInfo == null)
|
||||
{
|
||||
Log.Error($"Failed to retrieve mod with workshop id '{PublishedFileId}'!");
|
||||
return false;
|
||||
}
|
||||
//else if (!modInfo.Tags.Contains(""))
|
||||
else
|
||||
{
|
||||
Log.Info($"Mod Info successfully retrieved!");
|
||||
FriendlyName = modInfo.Title;
|
||||
Description = modInfo.Description;
|
||||
//Name = modInfo.FileName;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user