Compare commits

..

3 Commits

Author SHA1 Message Date
zznty
cf5c00ce0e fixed steamcmd path does not follow TORCH_GAME_PATH env variable 2022-03-07 13:25:38 +07:00
zznty
9c185d5577 fixed mods not being properly cleared from bulk edit
fixed bulk edit crash if input format is invalid
2022-03-05 20:19:01 +07:00
LTP
8b6c401531 fixed plugin dependencies resolution 2022-03-03 22:30:55 +07:00
5 changed files with 116 additions and 32 deletions

View File

@@ -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,

View File

@@ -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);

View File

@@ -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)
{ {
AssemblyResolver = Resolver _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 = _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);
}
}
} }

View File

@@ -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));
} }

View File

@@ -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;
@@ -19,6 +20,43 @@ namespace Torch.Utils
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()
{ {