Compare commits
8 Commits
v1.0.40-ma
...
v1.0.46-ma
Author | SHA1 | Date | |
---|---|---|---|
![]() |
cf5c00ce0e | ||
![]() |
9c185d5577 | ||
![]() |
8b6c401531 | ||
![]() |
92db8994ef | ||
![]() |
aee36661fd | ||
![]() |
feda84fac8 | ||
![]() |
2503cd6372 | ||
![]() |
f321034eeb |
@@ -1,4 +1,3 @@
|
|||||||
[](https://discord.gg/trK6sYdcNE)
|
|
||||||
[](https://ci.appveyor.com/project/zznty/torch/branch/master)
|
[](https://ci.appveyor.com/project/zznty/torch/branch/master)
|
||||||
|
|
||||||
# What is Torch?
|
# What is Torch?
|
||||||
@@ -17,6 +16,10 @@ Torch is the successor to SE Server Extender and gives server admins the tools t
|
|||||||
* .NET 6.0 runtime
|
* .NET 6.0 runtime
|
||||||
* Additional options & features
|
* Additional options & features
|
||||||
|
|
||||||
|
### Discord
|
||||||
|
|
||||||
|
If you have any questions or issues please join our [discord](https://discord.gg/UyYFSe3TyQ)
|
||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
|
|
||||||
* Unzip the Torch release into its own directory and run the executable. It will automatically download the SE DS and generate the other necessary files.
|
* Unzip the Torch release into its own directory and run the executable. It will automatically download the SE DS and generate the other necessary files.
|
||||||
|
@@ -29,12 +29,7 @@ namespace Torch.Server
|
|||||||
private const string STEAMCMD_DIR = "steamcmd";
|
private const string STEAMCMD_DIR = "steamcmd";
|
||||||
private const string STEAMCMD_ZIP = "temp.zip";
|
private const string STEAMCMD_ZIP = "temp.zip";
|
||||||
private static readonly string STEAMCMD_EXE = "steamcmd.exe";
|
private static readonly string STEAMCMD_EXE = "steamcmd.exe";
|
||||||
private static readonly string RUNSCRIPT_FILE = "runscript.txt";
|
private const string STEAMCMD_ARGS = "+force_install_dir \"{0}\" +login anonymous +app_update 298740 +quit";
|
||||||
|
|
||||||
private const string RUNSCRIPT = @"force_install_dir ../
|
|
||||||
login anonymous
|
|
||||||
app_update 298740
|
|
||||||
quit";
|
|
||||||
private TorchServer _server;
|
private TorchServer _server;
|
||||||
|
|
||||||
internal Persistent<TorchConfig> ConfigPersistent { get; }
|
internal Persistent<TorchConfig> ConfigPersistent { get; }
|
||||||
@@ -140,10 +135,6 @@ quit";
|
|||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
var runScriptPath = Path.Combine(path, RUNSCRIPT_FILE);
|
|
||||||
if (!File.Exists(runScriptPath))
|
|
||||||
File.WriteAllText(runScriptPath, RUNSCRIPT);
|
|
||||||
|
|
||||||
var steamCmdExePath = Path.Combine(path, STEAMCMD_EXE);
|
var steamCmdExePath = Path.Combine(path, STEAMCMD_EXE);
|
||||||
if (!File.Exists(steamCmdExePath))
|
if (!File.Exists(steamCmdExePath))
|
||||||
{
|
{
|
||||||
@@ -166,8 +157,9 @@ quit";
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Checking for DS updates.");
|
log.Info("Checking for DS updates.");
|
||||||
var steamCmdProc = new ProcessStartInfo(steamCmdExePath, "+runscript runscript.txt")
|
var steamCmdProc = new ProcessStartInfo(steamCmdExePath)
|
||||||
{
|
{
|
||||||
|
Arguments = string.Format(STEAMCMD_ARGS, Environment.GetEnvironmentVariable("TORCH_GAME_PATH") ?? "../"),
|
||||||
WorkingDirectory = path,
|
WorkingDirectory = path,
|
||||||
UseShellExecute = false,
|
UseShellExecute = false,
|
||||||
RedirectStandardOutput = true,
|
RedirectStandardOutput = true,
|
||||||
|
@@ -140,12 +140,6 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Update="TorchService.cs">
|
|
||||||
<SubType>Component</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Update="TorchServiceInstaller.cs">
|
|
||||||
<SubType>Component</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Remove="ServerManager.cs" />
|
<Compile Remove="ServerManager.cs" />
|
||||||
<Compile Remove="ViewModels\SessionSettingsViewModel1.cs" />
|
<Compile Remove="ViewModels\SessionSettingsViewModel1.cs" />
|
||||||
<Compile Remove="Views\WorldSelectControl.xaml.cs" />
|
<Compile Remove="Views\WorldSelectControl.xaml.cs" />
|
||||||
|
@@ -144,22 +144,17 @@ namespace Torch.Server.Views
|
|||||||
{
|
{
|
||||||
//var w = new RoleEditor(_instanceManager.DedicatedConfig.SelectedWorld);
|
//var w = new RoleEditor(_instanceManager.DedicatedConfig.SelectedWorld);
|
||||||
//w.Show();
|
//w.Show();
|
||||||
var d = new RoleEditor();
|
|
||||||
var w = _instanceManager.DedicatedConfig.SelectedWorld;
|
var w = _instanceManager.DedicatedConfig.SelectedWorld;
|
||||||
|
|
||||||
if(w.Checkpoint.PromotedUsers == null) {
|
if (w is null)
|
||||||
w.Checkpoint.PromotedUsers = new VRage.Serialization.SerializableDictionary<ulong, MyPromoteLevel>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (w == null)
|
|
||||||
{
|
{
|
||||||
MessageBox.Show("A world is not selected.");
|
MessageBox.Show("A world is not selected.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w.Checkpoint.PromotedUsers == null)
|
w.Checkpoint.PromotedUsers ??= new();
|
||||||
w.Checkpoint.PromotedUsers = new SerializableDictionary<ulong, MyPromoteLevel>();
|
|
||||||
d.Edit(w.Checkpoint.PromotedUsers.Dictionary);
|
new RoleEditor().Edit(w.Checkpoint.PromotedUsers.Dictionary);
|
||||||
_instanceManager.DedicatedConfig.Administrators = w.Checkpoint.PromotedUsers.Dictionary.Where(k => k.Value >= MyPromoteLevel.Admin).Select(k => k.Key.ToString()).ToList();
|
_instanceManager.DedicatedConfig.Administrators = w.Checkpoint.PromotedUsers.Dictionary.Where(k => k.Value >= MyPromoteLevel.Admin).Select(k => k.Key.ToString()).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -130,17 +130,17 @@ namespace Torch.Server.Views
|
|||||||
//blocking
|
//blocking
|
||||||
editor.Edit<string>(idList, "Mods");
|
editor.Edit<string>(idList, "Mods");
|
||||||
|
|
||||||
modList.RemoveAll(m =>
|
modList.Clear();
|
||||||
{
|
|
||||||
var mod = m.ToString();
|
|
||||||
return idList.Any(mod.Equals);
|
|
||||||
});
|
|
||||||
modList.AddRange(idList.Select(id =>
|
modList.AddRange(idList.Select(id =>
|
||||||
{
|
{
|
||||||
var info = new ModItemInfo(ModItemUtils.Create(id));
|
if (!ModItemUtils.TryParse(id, out var item))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var info = new ModItemInfo(item);
|
||||||
tasks.Add(Task.Run(info.UpdateModInfoAsync));
|
tasks.Add(Task.Run(info.UpdateModInfoAsync));
|
||||||
return info;
|
return info;
|
||||||
}));
|
}).Where(b => b is not null));
|
||||||
|
|
||||||
_instanceManager.DedicatedConfig.Mods.Clear();
|
_instanceManager.DedicatedConfig.Mods.Clear();
|
||||||
foreach (var mod in modList)
|
foreach (var mod in modList)
|
||||||
_instanceManager.DedicatedConfig.Mods.Add(mod);
|
_instanceManager.DedicatedConfig.Mods.Add(mod);
|
||||||
|
@@ -103,27 +103,27 @@ namespace Torch.Patches
|
|||||||
private static bool PrefixWriteLine(MyLog __instance, string msg)
|
private static bool PrefixWriteLine(MyLog __instance, string msg)
|
||||||
{
|
{
|
||||||
if (__instance.LogEnabled && _log.IsDebugEnabled)
|
if (__instance.LogEnabled && _log.IsDebugEnabled)
|
||||||
_log.Debug($"{" ".PadRight(3 * GetIndentByCurrentThread())}{msg}");
|
_log.Debug($"{string.Empty.PadRight(3 * GetIndentByCurrentThread(), ' ')}{msg}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool PrefixWriteLineConsole(MyLog __instance, string msg)
|
private static bool PrefixWriteLineConsole(MyLog __instance, string msg)
|
||||||
{
|
{
|
||||||
if (__instance.LogEnabled && _log.IsInfoEnabled)
|
if (__instance.LogEnabled && _log.IsInfoEnabled)
|
||||||
_log.Info($"{" ".PadRight(3 * GetIndentByCurrentThread())}{msg}");
|
_log.Info($"{string.Empty.PadRight(3 * GetIndentByCurrentThread(), ' ')}{msg}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool PrefixAppendToClosedLog(MyLog __instance, string text)
|
private static bool PrefixAppendToClosedLog(MyLog __instance, string text)
|
||||||
{
|
{
|
||||||
if (__instance.LogEnabled && _log.IsDebugEnabled)
|
if (__instance.LogEnabled && _log.IsDebugEnabled)
|
||||||
_log.Debug($"{" ".PadRight(3 * GetIndentByCurrentThread())}{text}");
|
_log.Debug($"{string.Empty.PadRight(3 * GetIndentByCurrentThread(), ' ')}{text}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
private static bool PrefixWriteLineOptions(MyLog __instance, string message, LoggingOptions option)
|
private static bool PrefixWriteLineOptions(MyLog __instance, string message, LoggingOptions option)
|
||||||
{
|
{
|
||||||
if (__instance.LogEnabled && __instance.LogFlag(option) && _log.IsDebugEnabled)
|
if (__instance.LogEnabled && __instance.LogFlag(option) && _log.IsDebugEnabled)
|
||||||
_log.Info($"{" ".PadRight(3 * GetIndentByCurrentThread())}{message}");
|
_log.Info($"{string.Empty.PadRight(3 * GetIndentByCurrentThread(), ' ')}{message}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ namespace Torch.Patches
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// ReSharper disable once TemplateIsNotCompileTimeConstantProblem
|
// ReSharper disable once TemplateIsNotCompileTimeConstantProblem
|
||||||
_log.Log(new(LogLevelFor(severity), _log.Name, $"{" ".PadRight(3 * GetIndentByCurrentThread())}{string.Format(format, args)}"));
|
_log.Log(new(LogLevelFor(severity), _log.Name, $"{string.Empty.PadRight(3 * GetIndentByCurrentThread(), ' ')}{string.Format(format, args)}"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
@@ -12,7 +11,6 @@ using System.Reflection.Emit;
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using ProtoBuf;
|
|
||||||
using Torch.Managers.PatchManager;
|
using Torch.Managers.PatchManager;
|
||||||
using Torch.Managers.PatchManager.MSIL;
|
using Torch.Managers.PatchManager.MSIL;
|
||||||
using Torch.Utils;
|
using Torch.Utils;
|
||||||
@@ -42,10 +40,14 @@ namespace Torch.Patches
|
|||||||
context.GetPattern(Register2Method).AddTranspiler(nameof(RegisterTranspiler));
|
context.GetPattern(Register2Method).AddTranspiler(nameof(RegisterTranspiler));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WhitelistCtorPrefix(MyScriptCompiler scriptCompiler)
|
private static void WhitelistCtorPrefix(MyScriptCompiler scriptCompiler, MyScriptWhitelist __instance)
|
||||||
{
|
{
|
||||||
|
var basePath = new FileInfo(typeof(object).Assembly.Location).DirectoryName!;
|
||||||
|
|
||||||
scriptCompiler.AddReferencedAssemblies(
|
scriptCompiler.AddReferencedAssemblies(
|
||||||
typeof(ValueType).Assembly.Location,
|
Path.Combine(basePath, "netstandard.dll"),
|
||||||
|
Path.Combine(basePath, "mscorlib.dll"),
|
||||||
|
Path.Combine(basePath, "System.Runtime.dll"),
|
||||||
typeof(LinkedList<>).Assembly.Location,
|
typeof(LinkedList<>).Assembly.Location,
|
||||||
typeof(Regex).Assembly.Location,
|
typeof(Regex).Assembly.Location,
|
||||||
typeof(Enumerable).Assembly.Location,
|
typeof(Enumerable).Assembly.Location,
|
||||||
@@ -55,6 +57,7 @@ namespace Torch.Patches
|
|||||||
typeof(TypeConverter).Assembly.Location,
|
typeof(TypeConverter).Assembly.Location,
|
||||||
typeof(System.Diagnostics.TraceSource).Assembly.Location,
|
typeof(System.Diagnostics.TraceSource).Assembly.Location,
|
||||||
typeof(ProtoBuf.Meta.RuntimeTypeModel).Assembly.Location,
|
typeof(ProtoBuf.Meta.RuntimeTypeModel).Assembly.Location,
|
||||||
|
typeof(ProtoBuf.ProtoMemberAttribute).Assembly.Location,
|
||||||
Path.Combine(MyFileSystem.ExePath, "Sandbox.Game.dll"),
|
Path.Combine(MyFileSystem.ExePath, "Sandbox.Game.dll"),
|
||||||
Path.Combine(MyFileSystem.ExePath, "Sandbox.Common.dll"),
|
Path.Combine(MyFileSystem.ExePath, "Sandbox.Common.dll"),
|
||||||
Path.Combine(MyFileSystem.ExePath, "Sandbox.Graphics.dll"),
|
Path.Combine(MyFileSystem.ExePath, "Sandbox.Graphics.dll"),
|
||||||
@@ -73,6 +76,9 @@ namespace Torch.Patches
|
|||||||
MyModWatchdog.Init(updateThread);
|
MyModWatchdog.Init(updateThread);
|
||||||
MyScriptCompiler.Static.AddImplicitIngameNamespacesFromTypes(referencedTypes);
|
MyScriptCompiler.Static.AddImplicitIngameNamespacesFromTypes(referencedTypes);
|
||||||
MyScriptCompiler.Static.AddConditionalCompilationSymbols(symbols);
|
MyScriptCompiler.Static.AddConditionalCompilationSymbols(symbols);
|
||||||
|
using var batch = MyScriptCompiler.Static.Whitelist.OpenBatch();
|
||||||
|
// Dict and queue in different assemblies, microsoft being microsoft
|
||||||
|
batch.AllowNamespaceOfTypes(MyWhitelistTarget.ModApi, typeof(ConcurrentQueue<>));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,34 +1,52 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
using NLog;
|
|
||||||
|
|
||||||
namespace Torch.Plugins;
|
namespace Torch.Plugins;
|
||||||
|
|
||||||
internal static class AssemblyRewriter
|
internal static class AssemblyRewriter
|
||||||
{
|
{
|
||||||
private static readonly ILogger Log = LogManager.GetCurrentClassLogger();
|
private static readonly ZipResolver _zipResolver;
|
||||||
|
private static readonly DefaultAssemblyResolver _defaultResolver;
|
||||||
private static readonly IAssemblyResolver Resolver;
|
|
||||||
|
|
||||||
static AssemblyRewriter()
|
static AssemblyRewriter()
|
||||||
{
|
{
|
||||||
var resolver = new DefaultAssemblyResolver();
|
_defaultResolver = new();
|
||||||
Resolver = resolver;
|
_zipResolver = new(_defaultResolver);
|
||||||
resolver.AddSearchDirectory(Directory.GetCurrentDirectory());
|
_defaultResolver.AddSearchDirectory(Directory.GetCurrentDirectory());
|
||||||
resolver.AddSearchDirectory(Path.Combine(Directory.GetCurrentDirectory(), "DedicatedServer64"));
|
_defaultResolver.AddSearchDirectory(Path.Combine(Directory.GetCurrentDirectory(), "DedicatedServer64"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Assembly ProcessWeavers(this Stream stream)
|
public static Assembly ProcessWeavers(this Stream stream, ZipArchive archive)
|
||||||
{
|
{
|
||||||
|
_zipResolver.Archive = archive;
|
||||||
using var assStream = new MemoryStream();
|
using var assStream = new MemoryStream();
|
||||||
stream.CopyTo(assStream);
|
stream.CopyTo(assStream);
|
||||||
assStream.Position = 0;
|
assStream.Position = 0;
|
||||||
using var module = ModuleDefinition.ReadModule(assStream, new()
|
var ass = ProcessInternal(assStream, _zipResolver);
|
||||||
|
_zipResolver.Archive = null;
|
||||||
|
return ass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Assembly ProcessWeavers(this Stream stream, string path)
|
||||||
|
{
|
||||||
|
_defaultResolver.AddSearchDirectory(path);
|
||||||
|
using var assStream = new MemoryStream();
|
||||||
|
stream.CopyTo(assStream);
|
||||||
|
assStream.Position = 0;
|
||||||
|
var ass = ProcessInternal(assStream, _defaultResolver);
|
||||||
|
_defaultResolver.RemoveSearchDirectory(path);
|
||||||
|
return ass;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Assembly ProcessInternal(Stream inputStream, IAssemblyResolver resolver)
|
||||||
|
{
|
||||||
|
using var module = ModuleDefinition.ReadModule(inputStream, new()
|
||||||
{
|
{
|
||||||
AssemblyResolver = Resolver
|
AssemblyResolver = _zipResolver
|
||||||
});
|
});
|
||||||
foreach (var fieldDefinition in FindAllToRewrite(module))
|
foreach (var fieldDefinition in FindAllToRewrite(module))
|
||||||
{
|
{
|
||||||
@@ -47,4 +65,40 @@ internal static class AssemblyRewriter
|
|||||||
|
|
||||||
private static bool HasValidAttributes(FieldDefinition definition) =>
|
private static bool HasValidAttributes(FieldDefinition definition) =>
|
||||||
definition.CustomAttributes.Any(b => b.AttributeType.Name.Contains("Reflected") || b.AttributeType.Name == "DependencyAttribute");
|
definition.CustomAttributes.Any(b => b.AttributeType.Name.Contains("Reflected") || b.AttributeType.Name == "DependencyAttribute");
|
||||||
|
|
||||||
|
private class ZipResolver : IAssemblyResolver
|
||||||
|
{
|
||||||
|
private readonly IAssemblyResolver _fallbackResolver;
|
||||||
|
public ZipArchive Archive { get; set; }
|
||||||
|
|
||||||
|
public ZipResolver(IAssemblyResolver fallbackResolver)
|
||||||
|
{
|
||||||
|
_fallbackResolver = fallbackResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_fallbackResolver.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AssemblyDefinition Resolve(AssemblyNameReference name)
|
||||||
|
{
|
||||||
|
return Resolve(name, new());
|
||||||
|
}
|
||||||
|
|
||||||
|
public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
|
||||||
|
{
|
||||||
|
var fileName = $"{name.Name}.dll";
|
||||||
|
|
||||||
|
if (Archive.Entries.FirstOrDefault(entry => entry.Name == fileName) is not { } archiveEntry)
|
||||||
|
return _fallbackResolver.Resolve(name, parameters);
|
||||||
|
|
||||||
|
using var stream = archiveEntry.Open();
|
||||||
|
using var memStream = new MemoryStream();
|
||||||
|
stream.CopyTo(memStream);
|
||||||
|
memStream.Position = 0;
|
||||||
|
|
||||||
|
return AssemblyDefinition.ReadAssembly(memStream, parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -360,7 +360,7 @@ namespace Torch.Managers
|
|||||||
|
|
||||||
|
|
||||||
using var stream = entry.Open();
|
using var stream = entry.Open();
|
||||||
assemblies.Add(stream.ProcessWeavers());
|
assemblies.Add(stream.ProcessWeavers(zipFile));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -378,7 +378,7 @@ namespace Torch.Managers
|
|||||||
// continue;
|
// continue;
|
||||||
|
|
||||||
using var stream = File.OpenRead(file);
|
using var stream = File.OpenRead(file);
|
||||||
assemblies.Add(stream.ProcessWeavers());
|
assemblies.Add(stream.ProcessWeavers(item.Path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -122,31 +122,6 @@
|
|||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<Compile Update="Views\CollectionEditor.xaml.cs">
|
|
||||||
<DependentUpon>CollectionEditor.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Update="Views\DictionaryEditor.xaml.cs">
|
|
||||||
<DependentUpon>DictionaryEditor.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Update="Views\EmbeddedCollectionEditor.xaml.cs">
|
|
||||||
<DependentUpon>EmbeddedCollectionEditor.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Update="Views\FlagsEditor.xaml.cs">
|
|
||||||
<DependentUpon>FlagsEditor.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Update="Views\ObjectCollectionEditor.xaml.cs">
|
|
||||||
<DependentUpon>ObjectCollectionEditor.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Update="Views\ObjectEditor.xaml.cs">
|
|
||||||
<DependentUpon>ObjectEditor.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Update="Views\PropertyGrid.xaml.cs">
|
|
||||||
<DependentUpon>PropertyGrid.xaml</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\Versioning\AssemblyVersion.cs" Link="Properties/AssemblyVersion.cs" />
|
|
||||||
<Compile Remove="Commands\Permissions\PermissionManager.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Torch.API\Torch.API.csproj" />
|
<ProjectReference Include="..\Torch.API\Torch.API.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Sandbox.Engine.Networking;
|
using Sandbox.Engine.Networking;
|
||||||
using Torch.API;
|
using Torch.API;
|
||||||
@@ -18,6 +19,43 @@ namespace Torch.Utils
|
|||||||
var arr = str.Split('-');
|
var arr = str.Split('-');
|
||||||
return new MyObjectBuilder_Checkpoint.ModItem(ulong.Parse(arr[0]), arr[1]);
|
return new MyObjectBuilder_Checkpoint.ModItem(ulong.Parse(arr[0]), arr[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool TryParse(string str, out MyObjectBuilder_Checkpoint.ModItem item)
|
||||||
|
{
|
||||||
|
item = default;
|
||||||
|
|
||||||
|
var arr = str.Split('-');
|
||||||
|
|
||||||
|
if (arr.Length is 0 or > 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!ulong.TryParse(arr[0], out var id))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (arr.Length == 1 || !TryParseServiceName(arr[1], out var serviceName))
|
||||||
|
serviceName = GetDefaultServiceName();
|
||||||
|
|
||||||
|
item = new(id, serviceName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryParseServiceName(string str, out string serviceName)
|
||||||
|
{
|
||||||
|
if (str.Equals("steam", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
serviceName = "Steam";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (str.Equals("mod.io", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
str.Equals("eos", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
serviceName = "mod.io";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceName = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//because KEEEN!
|
//because KEEEN!
|
||||||
public static string GetDefaultServiceName()
|
public static string GetDefaultServiceName()
|
||||||
|
Reference in New Issue
Block a user