Compare commits

...

30 Commits

Author SHA1 Message Date
zznty
850b313269 fix updates again 2023-01-12 23:29:37 +07:00
zznty
fe985e1a9c fix restart again 2023-01-12 23:20:44 +07:00
zznty
aeea192860 exit on restart 2023-01-09 22:02:54 +07:00
zznty
b8be5b2dce fix auto-updates 2023-01-05 00:48:11 +07:00
zznty
ea08d60d58 update protobuf 2023-01-05 00:41:49 +07:00
zznty
6493a305f7 remove retarded assembly version checks 2023-01-04 23:59:33 +07:00
zznty
bc0a2b89b8 fix entity updates and steam errors on game exit 2022-12-14 19:57:14 +07:00
zznty
846c2aa42e remove cache from ci 2022-12-12 13:29:40 +03:00
zznty
ac1ec431fd use lock files 2022-12-12 17:27:21 +07:00
zznty
3acaf25376 fix plugins ui crashes 2022-12-12 17:25:03 +07:00
zznty
e8928b6b3b fix PropertyGrid readonly is not copyable (#516)
(cherry picked from commit 09ddad495988beed896077f879998bf62cd0c8a8)
2022-12-02 15:45:59 +07:00
zznty
8478ee3752 cleanup for webapi things 2022-12-02 15:44:38 +07:00
zznty
ead8e3a4fc update 2022-12-02 15:23:11 +07:00
zznty
f73b9df924 net7 things 2022-11-20 23:13:16 +07:00
zznty
d524651da9 im a true retard 2022-11-06 21:07:18 +06:00
zznty
2743e5b42d okay 2022-11-06 21:02:41 +06:00
zznty
02bd9df059 fix because retarded exmaples 2022-11-06 21:00:24 +06:00
zznty
a5cc132151 add version string normalization 2022-11-06 20:57:56 +06:00
zznty
92dea1986c linux ci v5 2022-11-06 20:49:18 +06:00
zznty
c03eb79f81 linux ci v4 2022-11-06 20:46:54 +06:00
zznty
0ee9c5f97c test linux ci v3 2022-11-06 20:44:17 +06:00
zznty
c283059106 test linux ci v2 2022-11-06 20:41:26 +06:00
zznty
422963517f test building linux 2022-11-06 17:36:29 +03:00
zznty
d2ac0e44be correct whitelist for compiler 2022-10-16 02:09:44 +07:00
zznty
c5acf61f7c add auto-updates from github 2022-10-15 15:33:57 +07:00
zznty
197d04a661 fix steamcmd default directory 2022-10-15 15:33:09 +07:00
zznty
99ab7d0eea Merge remote-tracking branch 'pve/master' 2022-10-15 02:19:05 +07:00
zznty
17f97af52f add gslt login option (#515)
(cherry picked from commit c81f139fe6b5de0c9f7a005dc2cbe576f4ca8f67)
2022-10-15 02:09:09 +07:00
zznty
ed7c897bd2 Update README.md 2022-10-14 21:59:18 +03:00
zznty
e4d3c3987f fix ci changelog building 2022-10-14 21:48:43 +03:00
41 changed files with 1427 additions and 363 deletions

View File

@@ -8,9 +8,9 @@ on:
jobs:
build:
name: Build
runs-on: windows-latest
runs-on: ubuntu-latest
env:
VERSION: ${{ github.ref_name }}
TORCH_VERSION: ${{ github.ref_name }}
BUILD_CONFIGURATION: Release
DOTNET_NOLOGO: true
DOTNET_CLI_TELEMETRY_OPTOUT: true
@@ -20,21 +20,15 @@ jobs:
- uses: actions/setup-dotnet@v3
name: Setup dotnet
with:
dotnet-version: '6.0.x'
- uses: actions/cache@v1
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
restore-keys: |
${{ runner.os }}-nuget-
dotnet-version: '7.0.x'
- name: Add Gh Packages Nuget Source
run: dotnet nuget add source "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" --username ${{ github.actor }} --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github
- name: Restore dependencies
run: dotnet restore Torch.Server/Torch.Server.csproj --use-lock-file
run: dotnet restore Torch.Server/Torch.Server.csproj --locked-mode
- name: Build
run: dotnet build Torch.Server/Torch.Server.csproj --no-restore -c $env:BUILD_CONFIGURATION /p:AssemblyVersion=$env:VERSION /p:Version=$env:VERSION
run: dotnet build Torch.Server/Torch.Server.csproj --no-restore -c ${{ env.BUILD_CONFIGURATION }} /p:AssemblyVersion=${{ env.TORCH_VERSION }} /p:Version=${{ env.TORCH_VERSION }}
- name: Publish
run: dotnet publish Torch.Server/Torch.Server.csproj --no-build -r win-x64 --sc -c $env:BUILD_CONFIGURATION -o ./publish
run: dotnet publish Torch.Server/Torch.Server.csproj --no-build -r win-x64 --sc -c ${{ env.BUILD_CONFIGURATION }} -o ./publish
- uses: vimtor/action-zip@v1
name: Zip Release
with:
@@ -45,14 +39,16 @@ jobs:
uses: mikepenz/release-changelog-builder-action@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
commitMode: true
- name: Create release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ env.VERSION }}
release_name: Release v${{ env.VERSION }}
tag_name: ${{ env.TORCH_VERSION }}
release_name: Release v${{ env.TORCH_VERSION }}
body: ${{ steps.github_release.outputs.changelog }}
draft: true
prerelease: false

View File

@@ -12,7 +12,10 @@ Torch is the successor to SE Server Extender and gives server admins the tools t
### Fork Difference
* .NET 6.0 runtime
* Additional options & features
* Optimized in-game scripts (also newer compiler & language versions)
* Better configuration via cli arguments, environment variables or xml config
* Designed to run multiple instance from same install directory without having you to waste disk space
* Mostly compatible with original torch's plugins
### Discord
@@ -21,10 +24,13 @@ If you have any questions or issues please join our [discord](https://discord.gg
### 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.
- If you already have a DS installed you can unzip the Torch files into the folder that contains the DedicatedServer64 folder.
- If you already have a DS installed you can:
* Unzip the Torch files into the folder that contains the DedicatedServer64 folder.
* Pass path to game files using config parameter `gamePath`
# Building
To build Torch you must first have a complete SE Dedicated installation somewhere. Before you open the solution, run the Setup batch file and enter the path of that installation's DedicatedServer64 folder. The script will make a symlink to that folder so the Torch solution can find the DLL references it needs.
As a regular dotnet project with cli by running `dotnet build Torch.Server/Torch.Server.csproj`, with VS 2022 or higher, with JB Rider or Fleet.
If you have a more enjoyable server experience because of Torch, please consider supporting us on Patreon. (https://www.patreon.com/TorchSE)

View File

@@ -31,6 +31,23 @@ namespace Torch
int FontSize { get; set; }
UGCServiceType UgcServiceType { get; set; }
bool EntityManagerEnabled { get; set; }
string LoginToken { get; set; }
UpdateSource UpdateSource { get; set; }
void Save(string path = null);
}
public class UpdateSource
{
public UpdateSourceType SourceType { get; set; }
public string Url { get; set; }
public string Repository { get; set; }
public string Branch { get; set; }
}
public enum UpdateSourceType
{
Github,
Jenkins
}
}

View File

@@ -1,16 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6-windows</TargetFramework>
<LangVersion>10</LangVersion>
<TargetFramework>net7-windows</TargetFramework>
<AssemblyTitle>Torch API</AssemblyTitle>
<Product>Torch</Product>
<Copyright>Copyright © Torch API 2017</Copyright>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<OutputPath>..\bin\$(Platform)\$(Configuration)\</OutputPath>
<UseWpf>True</UseWpf>
<PlatformTarget>x64</PlatformTarget>
<Configurations>Debug;Release</Configurations>
<Platforms>AnyCPU</Platforms>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>
<PropertyGroup Condition="$(Configuration) == 'Release'">
@@ -18,7 +16,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NLog" Version="5.0.4" />
<PackageReference Include="JorgeSerrano.Json.JsonSnakeCaseNamingPolicy" Version="0.9.0" />
<PackageReference Include="NLog" Version="5.1.0" />
<PackageReference Include="SemanticVersioning" Version="2.0.2" />
<PackageReference Include="SpaceEngineersDedicated.ReferenceAssemblies" Version="1.201.13">
<PrivateAssets>all</PrivateAssets>

View File

@@ -1,88 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using NLog;
using Torch.API.Utils;
using Version = SemanticVersioning.Version;
namespace Torch.API.WebAPI
{
public class JenkinsQuery
{
private const string BRANCH_QUERY = "http://136.243.80.164:2690/job/Torch/job/{0}/" + API_PATH;
private const string ARTIFACT_PATH = "artifact/bin/torch-server.zip";
private const string API_PATH = "api/json";
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
private static JenkinsQuery _instance;
public static JenkinsQuery Instance => _instance ??= new JenkinsQuery();
private HttpClient _client;
private JenkinsQuery()
{
_client = new HttpClient();
}
public async Task<Job> GetLatestVersion(string branch)
{
var h = await _client.GetAsync(string.Format(BRANCH_QUERY, branch));
if (!h.IsSuccessStatusCode)
{
Log.Error($"'{branch}' Branch query failed with code {h.StatusCode}");
if(h.StatusCode == HttpStatusCode.NotFound)
Log.Error("This likely means you're trying to update a branch that is not public on Jenkins. Sorry :(");
return null;
}
var branchResponse = await h.Content.ReadFromJsonAsync<BranchResponse>();
if (branchResponse is null)
{
Log.Error("Error reading branch response");
return null;
}
h = await _client.GetAsync($"{branchResponse.LastStableBuild.Url}{API_PATH}");
if (h.IsSuccessStatusCode)
return await h.Content.ReadFromJsonAsync<Job>();
Log.Error($"Job query failed with code {h.StatusCode}");
return null;
}
public async Task<bool> DownloadRelease(Job job, string path)
{
var h = await _client.GetAsync(job.Url + ARTIFACT_PATH);
if (!h.IsSuccessStatusCode)
{
Log.Error($"Job download failed with code {h.StatusCode}");
return false;
}
var s = await h.Content.ReadAsStreamAsync();
#if !NETFRAMEWORK
await using var fs = new FileStream(path, FileMode.Create);
#else
using var fs = new FileStream(path, FileMode.Create);
#endif
await s.CopyToAsync(fs);
return true;
}
}
public record BranchResponse(string Name, string Url, Build LastBuild, Build LastStableBuild);
public record Build(int Number, string Url);
public record Job(int Number, bool Building, string Description, string Result, string Url,
[property: JsonConverter(typeof(SemanticVersionConverter))] Version Version);
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Threading.Tasks;
namespace Torch.API.WebAPI.Plugin;
public interface IPluginQuery
{
Task<PluginsResponse> QueryAll();
Task<PluginItem> QueryOne(Guid guid);
Task<bool> DownloadPlugin(Guid guid, string path = null);
Task<bool> DownloadPlugin(PluginItem item, string path = null);
}

View File

@@ -0,0 +1,81 @@
using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading;
using System.Threading.Tasks;
using NLog;
namespace Torch.API.WebAPI.Plugin;
public class LegacyPluginQuery : IPluginQuery
{
private const string BASE_URL = "https://torchapi.com/";
private readonly HttpClient _client;
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
private LegacyPluginQuery()
{
_client = new()
{
BaseAddress = new(BASE_URL)
};
}
public static LegacyPluginQuery Instance { get; } = new();
public async Task<PluginsResponse> QueryAll()
{
return await _client.GetFromJsonAsync<PluginsResponse>("/api/plugins/", CancellationToken.None);
}
public async Task<PluginItem> QueryOne(Guid guid)
{
using var res = await _client.GetAsync($"/api/plugins/search/{guid}");
if (!res.IsSuccessStatusCode)
return null;
return await res.Content.ReadFromJsonAsync<PluginItem>();
}
public async Task<bool> DownloadPlugin(Guid guid, string path = null)
{
var item = await QueryOne(guid);
if (item is null) return false;
return await DownloadPlugin(item, path);
}
public async Task<bool> DownloadPlugin(PluginItem item, string path = null)
{
try
{
path ??= Path.Combine(AppContext.BaseDirectory, "Plugins", $"{item.Name}.zip");
if (item.Versions.Length == 0)
{
Log.Error($"Selected plugin {item.Name} does not have any versions to download!");
return false;
}
var version = item.Versions.FirstOrDefault(v => v.Version == item.LatestVersion);
if (version is null)
{
Log.Error($"Could not find latest version for selected plugin {item.Name}");
return false;
}
var s = await _client.GetStreamAsync(version.Url);
if(File.Exists(path))
File.Delete(path);
await using var f = File.Create(path);
await s.CopyToAsync(f);
}
catch (Exception ex)
{
Log.Error(ex, "Failed to download plugin!");
return false;
}
return true;
}
}

View File

@@ -0,0 +1,11 @@
using System;
using System.Text.Json.Serialization;
namespace Torch.API.WebAPI.Plugin;
public record PluginItem(Guid Id, string Name, string Author, string Description, string LatestVersion,
VersionItem[] Versions)
{
[JsonIgnore]
public bool Installed { get; set; }
}

View File

@@ -0,0 +1,3 @@
namespace Torch.API.WebAPI.Plugin;
public record PluginsResponse(PluginItem[] Plugins);

View File

@@ -0,0 +1,6 @@
using System.Text.Json.Serialization;
namespace Torch.API.WebAPI.Plugin;
public record VersionItem(string Version, string Note, [property: JsonPropertyName("is_beta")] bool IsBeta,
string Url);

View File

@@ -1,104 +0,0 @@
using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using NLog;
namespace Torch.API.WebAPI
{
public class PluginQuery
{
private const string ALL_QUERY = "https://torchapi.com/api/plugins/";
private const string PLUGIN_QUERY = "https://torchapi.com/api/plugins/search/{0}";
private readonly HttpClient _client;
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
private static PluginQuery _instance;
public static PluginQuery Instance => _instance ??= new();
private PluginQuery()
{
_client = new();
}
public async Task<PluginsResponse> QueryAll()
{
return (PluginsResponse) await _client.GetFromJsonAsync(ALL_QUERY, typeof(PluginsResponse), CancellationToken.None);
}
public Task<PluginItem> QueryOne(Guid guid)
{
return QueryOne(guid.ToString());
}
public async Task<PluginItem> QueryOne(string guid)
{
using var res = await _client.GetAsync(string.Format(PLUGIN_QUERY, guid));
if (!res.IsSuccessStatusCode)
return null;
return await res.Content.ReadFromJsonAsync<PluginItem>();
}
public Task<bool> DownloadPlugin(Guid guid, string path = null)
{
return DownloadPlugin(guid.ToString(), path);
}
public async Task<bool> DownloadPlugin(string guid, string path = null)
{
var item = await QueryOne(guid);
if (item is null) return false;
return await DownloadPlugin(item, path);
}
public async Task<bool> DownloadPlugin(PluginItem item, string path = null)
{
try
{
path ??= Path.Combine(AppContext.BaseDirectory, "Plugins", $"{item.Name}.zip");
if (item.Versions.Length == 0)
{
Log.Error($"Selected plugin {item.Name} does not have any versions to download!");
return false;
}
var version = item.Versions.FirstOrDefault(v => v.Version == item.LatestVersion);
if (version is null)
{
Log.Error($"Could not find latest version for selected plugin {item.Name}");
return false;
}
var s = await _client.GetStreamAsync(version.Url);
if(File.Exists(path))
File.Delete(path);
await using var f = File.Create(path);
await s.CopyToAsync(f);
}
catch (Exception ex)
{
Log.Error(ex, "Failed to download plugin!");
}
return true;
}
}
public record PluginsResponse(PluginItem[] Plugins);
public record PluginItem(Guid Id, string Name, string Author, string Description, string LatestVersion,
VersionItem[] Versions)
{
[JsonIgnore]
public bool Installed { get; set; }
}
public record VersionItem(string Version, string Note, [property: JsonPropertyName("is_beta")] bool IsBeta,
string Url);
}

View File

@@ -0,0 +1,128 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Threading.Tasks;
using JorgeSerrano.Json;
using Version = SemanticVersioning.Version;
namespace Torch.API.WebAPI.Update;
public class GithubQuery : IUpdateQuery
{
private readonly HttpClient _client;
public GithubQuery(string url)
{
if (url == null) throw new ArgumentNullException(nameof(url));
_client = new()
{
BaseAddress = new(url),
DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher,
DefaultRequestHeaders =
{
{"User-Agent", "TorchAPI"}
}
};
}
public void Dispose()
{
_client?.Dispose();
}
public async Task<UpdateRelease> GetLatestReleaseAsync(string repository, string branch = null)
{
var response = await _client.GetFromJsonAsync<Release>($"/repos/{repository}/releases/latest", new JsonSerializerOptions(JsonSerializerDefaults.Web)
{
PropertyNamingPolicy = new JsonSnakeCaseNamingPolicy()
});
if (response is null)
throw new($"Unable to get latest release for {repository}");
return new(Version.Parse(response.TagName), response.Assets.First(b => b.Name == "torch-server.zip").BrowserDownloadUrl);
}
private record Asset(
string Url,
int Id,
string NodeId,
string Name,
string Label,
Uploader Uploader,
string ContentType,
string State,
int Size,
int DownloadCount,
DateTime CreatedAt,
DateTime UpdatedAt,
string BrowserDownloadUrl
);
private record Author(
string Login,
int Id,
string NodeId,
string AvatarUrl,
string GravatarId,
string Url,
string HtmlUrl,
string FollowersUrl,
string FollowingUrl,
string GistsUrl,
string StarredUrl,
string SubscriptionsUrl,
string OrganizationsUrl,
string ReposUrl,
string EventsUrl,
string ReceivedEventsUrl,
string Type,
bool SiteAdmin
);
private record Release(
string Url,
string AssetsUrl,
string UploadUrl,
string HtmlUrl,
int Id,
Author Author,
string NodeId,
string TagName,
string TargetCommitish,
string Name,
bool Draft,
bool Prerelease,
DateTime CreatedAt,
DateTime PublishedAt,
IReadOnlyList<Asset> Assets,
string TarballUrl,
string ZipballUrl,
string Body
);
private record Uploader(
string Login,
int Id,
string NodeId,
string AvatarUrl,
string GravatarId,
string Url,
string HtmlUrl,
string FollowersUrl,
string FollowingUrl,
string GistsUrl,
string StarredUrl,
string SubscriptionsUrl,
string OrganizationsUrl,
string ReposUrl,
string EventsUrl,
string ReceivedEventsUrl,
string Type,
bool SiteAdmin
);
}

View File

@@ -0,0 +1,9 @@
using System;
using System.Threading.Tasks;
namespace Torch.API.WebAPI.Update;
public interface IUpdateQuery : IDisposable
{
Task<UpdateRelease> GetLatestReleaseAsync(string repository, string branch = null);
}

View File

@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Torch.API.Utils;
using Version = SemanticVersioning.Version;
namespace Torch.API.WebAPI.Update
{
public class JenkinsQuery : IUpdateQuery
{
private const string ApiPath = "api/json";
private readonly HttpClient _client;
public JenkinsQuery(string url)
{
if (url == null) throw new ArgumentNullException(nameof(url));
_client = new()
{
BaseAddress = new(url)
};
}
public async Task<UpdateRelease> GetLatestReleaseAsync(string repository, string branch = null)
{
branch ??= "master";
var response = await _client.GetFromJsonAsync<BranchResponse>($"/job/{repository}/job/{branch}/{ApiPath}");
if (response is null)
throw new($"Unable to get latest release for {repository}");
var job = await _client.GetFromJsonAsync<Job>(
$"/job/{repository}/job/{branch}/{response.LastBuild.Number}/{ApiPath}");
if (job is null)
throw new($"Unable to get latest release for job {repository}/{response.LastBuild.Number}");
return new(job.Version, job.Url + job.Artifacts.First(b => b.FileName == "torch-server.zip").RelativePath);
}
public void Dispose()
{
_client?.Dispose();
}
}
public record BranchResponse(string Name, string Url, Build LastBuild, Build LastStableBuild);
public record Build(int Number, string Url);
public record Job(int Number, bool Building, string Description, string Result, string Url,
[property: JsonConverter(typeof(SemanticVersionConverter))] Version Version,
IReadOnlyList<Artifact> Artifacts);
public record Artifact(
string DisplayPath,
string FileName,
string RelativePath
);
}

View File

@@ -0,0 +1,5 @@
using SemanticVersioning;
namespace Torch.API.WebAPI.Update;
public record UpdateRelease(Version Version, string ArtifactUrl);

View File

@@ -0,0 +1,39 @@
{
"version": 1,
"dependencies": {
"net7.0-windows7.0": {
"JorgeSerrano.Json.JsonSnakeCaseNamingPolicy": {
"type": "Direct",
"requested": "[0.9.0, )",
"resolved": "0.9.0",
"contentHash": "xCqODS+wzpUXNtg4bMMvXG5PLbP0iTwRzRn2R+zWHKm83E6tbV2bCagawXp1EnZeNpd5OXpMxehulZWns8efzQ=="
},
"NLog": {
"type": "Direct",
"requested": "[5.1.0, )",
"resolved": "5.1.0",
"contentHash": "oW7ekrkRG9okpDMUcEglunWj8Qf2RY8qkgl+/chJoavzg3dbT13y32t19R54FKkmq80fKzw4ZekZkCrRGanKgQ=="
},
"SemanticVersioning": {
"type": "Direct",
"requested": "[2.0.2, )",
"resolved": "2.0.2",
"contentHash": "4EQgYdNZ92SyaO7YFk6olVnebF5V+jrHyMUjvPq89tLeMo8NSfgDF+6Zwq/lgh9j/0yfQp9Lkm0ZA0rUATCZFA=="
},
"SpaceEngineersDedicated.ReferenceAssemblies": {
"type": "Direct",
"requested": "[1.201.13, )",
"resolved": "1.201.13",
"contentHash": "FRXuNLENsz5jGQvL0QkogAGsxEJyUQlXhvWHBWfZiHCnCrAWMD60nEis6yt0xCQpazszfMtHonbxz72XMxnFoQ==",
"dependencies": {
"protobuf-net": "1.0.0"
}
},
"protobuf-net": {
"type": "Transitive",
"resolved": "1.0.0",
"contentHash": "kTGOK0E87473sOImOjgZOnz3kTC2aMLffoRWQLYNuBLJnwNNmjanF9IkevZ9Q7yYLeABQfcF3BpeepuMntMVNw=="
}
}
}
}

View File

@@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6-windows</TargetFramework>
<LangVersion>10</LangVersion>
<TargetFramework>net7-windows</TargetFramework>
<NoWarn>1591,0649</NoWarn>
<AssemblyTitle>Torch Server Tests</AssemblyTitle>
<Product>Torch</Product>
@@ -18,8 +17,8 @@
</PropertyGroup>
<!-- <Import Project="$(SolutionDir)\TransformOnBuild.targets" /> -->
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="NLog" Version="5.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
<PackageReference Include="NLog" Version="5.1.0" />
<PackageReference Include="xunit" Version="2.4.2" />
</ItemGroup>
<ItemGroup>

View File

@@ -57,7 +57,7 @@ namespace Torch.Server
#endif
if (!configuration.GetValue("noupdate", false))
RunSteamCmd();
RunSteamCmd(configuration);
var processPid = configuration.GetValue<int>("waitForPid");
if (processPid != 0)
@@ -124,11 +124,12 @@ namespace Torch.Server
}
}
public static void RunSteamCmd()
public static void RunSteamCmd(IConfiguration configuration)
{
var log = LogManager.GetLogger("SteamCMD");
var path = Environment.GetEnvironmentVariable("TORCH_STEAMCMD") ?? Path.GetFullPath(STEAMCMD_DIR);
var path = configuration.GetValue<string>("steamCmdPath") ?? ApplicationContext.Current.TorchDirectory
.CreateSubdirectory(STEAMCMD_DIR).FullName;
if (!Directory.Exists(path))
{
@@ -143,7 +144,8 @@ namespace Torch.Server
log.Info("Downloading SteamCMD.");
using (var client = new HttpClient())
using (var file = File.Create(STEAMCMD_ZIP))
client.GetStreamAsync("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip").Result.CopyTo(file);
using (var stream = client.GetStreamAsync("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip").Result)
stream.CopyTo(file);
ZipFile.ExtractToDirectory(STEAMCMD_ZIP, path);
File.Delete(STEAMCMD_ZIP);
@@ -159,7 +161,7 @@ namespace Torch.Server
log.Info("Checking for DS updates.");
var steamCmdProc = new ProcessStartInfo(steamCmdExePath)
{
Arguments = string.Format(STEAMCMD_ARGS, Environment.GetEnvironmentVariable("TORCH_GAME_PATH") ?? "../"),
Arguments = string.Format(STEAMCMD_ARGS, configuration.GetValue("gamePath", "../")),
WorkingDirectory = path,
UseShellExecute = false,
RedirectStandardOutput = true,

View File

@@ -90,8 +90,7 @@ namespace Torch.Server.Managers
}
catch (Exception ex)
{
Log.Error("Failed to load world at path: " + f);
continue;
Log.Error(ex, "Failed to load world at path: " + f);
}
}
@@ -137,7 +136,7 @@ namespace Torch.Server.Managers
}
catch (Exception ex)
{
Log.Error("Failed to load world at path: " + worldPath);
Log.Error(ex, "Failed to load world at path: " + worldPath);
DedicatedConfig.LoadWorld = null;
return;
}

View File

@@ -0,0 +1,35 @@
using System.Reflection;
using NLog;
using Steamworks;
using Torch.Managers.PatchManager;
using Torch.Utils;
namespace Torch.Patches;
[PatchShim]
public static class SteamLoginPatch
{
private static readonly ILogger Log = LogManager.GetCurrentClassLogger();
[ReflectedMethodInfo(null, "LogOnAnonymous", TypeName = "VRage.Steam.MySteamGameServer, VRage.Steam")]
private static MethodInfo LoginMethod = null!;
public static void Patch(PatchContext context)
{
context.GetPattern(LoginMethod).AddPrefix();
}
private static bool Prefix()
{
#pragma warning disable CS0618
var token = TorchBase.Instance.Config.LoginToken;
#pragma warning restore CS0618
if (string.IsNullOrEmpty(token))
return true;
Log.Info("Logging in to Steam with GSLT");
SteamGameServer.LogOn(token);
return false;
}
}

View File

@@ -1,21 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6-windows</TargetFramework>
<TargetFramework>net7-windows</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<LangVersion>10</LangVersion>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<PublishUrl>publish\</PublishUrl>
<UseApplicationTrust>false</UseApplicationTrust>
<AssemblyTitle>Torch Server</AssemblyTitle>
<Product>Torch</Product>
<Copyright>Copyright © Torch API 2017</Copyright>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<OutputPath>..\bin\$(Platform)\$(Configuration)\</OutputPath>
<UseWPF>true</UseWPF>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
<NeutralLanguage>en</NeutralLanguage>
<PlatformTarget>x64</PlatformTarget>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
<TieredPGO>true</TieredPGO>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>
<PropertyGroup>
@@ -35,18 +34,22 @@
<ItemGroup>
<PackageReference Include="AutoCompleteTextBox" Version="1.6.0" />
<PackageReference Include="Ben.Demystifier" Version="0.4.1" />
<PackageReference Include="ControlzEx" Version="5.0.1" />
<PackageReference Include="ControlzEx" Version="5.0.2" />
<PackageReference Include="MahApps.Metro" Version="2.4.9" />
<PackageReference Include="MdXaml" Version="1.16.0" />
<PackageReference Include="Microsoft.Diagnostics.Runtime" Version="2.2.332302" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Xml" Version="6.0.0" />
<PackageReference Include="NLog" Version="5.0.4" />
<PackageReference Include="MdXaml" Version="1.16.2" />
<PackageReference Include="Microsoft.Diagnostics.Runtime" Version="2.2.343001" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Xml" Version="7.0.0" />
<PackageReference Include="NLog" Version="5.1.0" />
<PackageReference Include="PropertyChanged.Fody" Version="4.0.3" PrivateAssets="all" />
<PackageReference Include="Steamworks.NET" Version="20.1.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>compile</IncludeAssets>
</PackageReference>
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Management" Version="6.0.0" />
<PackageReference Include="System.Management" Version="7.0.0" />
<PackageReference Include="nulastudio.NetCoreBeauty" Version="1.2.9.3" />
<PackageReference Include="SpaceEngineersDedicated.ReferenceAssemblies" Version="1.201.13">
<PrivateAssets>all</PrivateAssets>

View File

@@ -109,6 +109,16 @@ public class TorchConfig : ViewModel, ITorchConfig
GroupName = "Server")]
public bool EntityManagerEnabled { get; set; } = true;
[Display(Name = "Login Token", Description = "Steam GSLT (can be used if you have dynamic ip)", GroupName = "Server")]
public string LoginToken { get; set; }
public UpdateSource UpdateSource { get; set; } = new()
{
Repository = "PveTeam/Torch",
Url = "https://api.github.com",
SourceType = UpdateSourceType.Github
};
// for backward compatibility
public void Save(string path = null) => Initializer.Instance?.ConfigPersistent?.Save(path);
}

View File

@@ -3,11 +3,10 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Diagnostics.Runtime;
using NLog;
using PropertyChanged;
@@ -21,8 +20,6 @@ using Torch.API.Session;
using Torch.Commands;
using Torch.Managers.PatchManager;
using Torch.Mod;
using Torch.Mod.Messages;
using Torch.Patches;
using Torch.Server.Commands;
using Torch.Server.Managers;
using Torch.Utils;
@@ -211,7 +208,7 @@ namespace Torch.Server
Environment.Exit(0);
#endif
var exe = Assembly.GetExecutingAssembly().Location.Replace("dll", "exe");
var exe = Path.Combine(AppContext.BaseDirectory, "Torch.Server.exe");
var args = Environment.GetCommandLineArgs();
@@ -229,6 +226,8 @@ namespace Torch.Server
}
Process.Start(exe, $"--waitForPid {Environment.ProcessId} --tempAutostart true {string.Join(" ", args)}");
Environment.Exit(0);
})
{
Name = "Restart thread"

View File

@@ -22,6 +22,8 @@ using Torch.Collections;
using Torch.Server.Annotations;
using Torch.Managers;
using Torch.API.Managers;
using Torch.API.Plugins;
using Torch.API.WebAPI.Plugin;
namespace Torch.Server.Views
{
@@ -55,39 +57,38 @@ namespace Torch.Server.Views
InitializeComponent();
var installedPlugins = pluginManager.Plugins;
BindingOperations.EnableCollectionSynchronization(Plugins, _syncLock);
Task.Run(async () =>
{
try
{
var res = await PluginQuery.Instance.QueryAll();
foreach (var item in res.Plugins.OrderBy(i => i.Name)) {
lock (_syncLock)
{
var pluginItem = item with
{
Description = item.Description.Replace("&lt;", "<").Replace("&gt;", ">"),
Installed = installedPlugins.Keys.Contains(item.Id)
};
Plugins.Add(pluginItem);
PluginsSource.Add(pluginItem);
}
}
Dispatcher.Invoke(() => PluginsList.SelectedIndex = 0);
CurrentDescription = "Please select a plugin...";
}
catch (Exception e)
{
MessageBox.Show(e.ToString(), "An Error Occurred", MessageBoxButton.OK, MessageBoxImage.Error);
Close();
throw;
}
});
LoadAsync(installedPlugins);
MarkdownFlow.CommandBindings.Add(new CommandBinding(NavigationCommands.GoToPage, (sender, e) => OpenUri((string)e.Parameter)));
}
private async void LoadAsync(IReadOnlyDictionary<Guid, ITorchPlugin> installedPlugins)
{
try
{
var res = await LegacyPluginQuery.Instance.QueryAll();
foreach (var item in res.Plugins.OrderBy(i => i.Name))
{
var pluginItem = item with
{
Description = item.Description?.Replace("&lt;", "<").Replace("&gt;", ">") ?? string.Empty,
Installed = installedPlugins.Keys.Contains(item.Id)
};
Plugins.Add(pluginItem);
PluginsSource.Add(pluginItem);
}
PluginsList.SelectedIndex = 0;
CurrentDescription = "Please select a plugin...";
}
catch (Exception e)
{
MessageBox.Show(e.ToString(), "An Error Occurred", MessageBoxButton.OK, MessageBoxImage.Error);
Close();
throw;
}
}
public static bool IsValidUri(string uri)
{
if (!Uri.IsWellFormedUriString(uri, UriKind.Absolute))

View File

@@ -14,6 +14,7 @@ using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;
using Torch.API.WebAPI.Plugin;
namespace Torch.Server.Views
{
@@ -50,7 +51,7 @@ namespace Torch.Server.Views
var PercentChangeOnDownload = 100 / PluginsToDownload.Count;
foreach (PluginItem PluginItem in PluginsToDownload) {
if (!PluginQuery.Instance.DownloadPlugin(PluginItem.Id).Result) {
if (!LegacyPluginQuery.Instance.DownloadPlugin(PluginItem.Id).Result) {
failedDownloads++;
DownloadProgress += PercentChangeOnDownload;
(sender as BackgroundWorker).ReportProgress(DownloadProgress);

View File

@@ -71,7 +71,7 @@ namespace Torch.Server.Views
private void OpenFolder_OnClick(object sender, RoutedEventArgs e)
{
if (_plugins?.PluginDir != null)
Process.Start(_plugins.PluginDir);
Process.Start("explorer", _plugins.PluginDir);
}
private void BrowsPlugins_OnClick(object sender, RoutedEventArgs e)

View File

@@ -0,0 +1,538 @@
{
"version": 1,
"dependencies": {
"net7.0-windows7.0": {
"AutoCompleteTextBox": {
"type": "Direct",
"requested": "[1.6.0, )",
"resolved": "1.6.0",
"contentHash": "xTQB0o3yZzBqKqWTZYlu22wTpIeXAsBU3+wswQ44D6rTMMTBXqr3AjxqrvjFcnoZXtLZgjPNRIUwnfsFSsH46g=="
},
"Ben.Demystifier": {
"type": "Direct",
"requested": "[0.4.1, )",
"resolved": "0.4.1",
"contentHash": "axFeEMfmEORy3ipAzOXG/lE+KcNptRbei3F0C4kQCdeiQtW+qJW90K5iIovITGrdLt8AjhNCwk5qLSX9/rFpoA==",
"dependencies": {
"System.Reflection.Metadata": "5.0.0"
}
},
"ControlzEx": {
"type": "Direct",
"requested": "[5.0.2, )",
"resolved": "5.0.2",
"contentHash": "f724LoDJ36LxaLR62G4ek9ZAJI8BiiYRJJ04furC/qjXSeIwU0qmHFIe19xB1/FwxyZjevdFguEr9ZUjf3dZgw==",
"dependencies": {
"Microsoft.Xaml.Behaviors.Wpf": "1.1.31",
"System.Text.Json": "5.0.1"
}
},
"MahApps.Metro": {
"type": "Direct",
"requested": "[2.4.9, )",
"resolved": "2.4.9",
"contentHash": "eMTkg6TBnCwHzszw7CP+pxsBeB4ZMsJFiTJJoifUVBysRyEenzzR+TKQJuMvvKK6KzvLxwHmJsFhi9o5p4vxhQ==",
"dependencies": {
"ControlzEx": "[4.4.0, 6.0.0)"
}
},
"MdXaml": {
"type": "Direct",
"requested": "[1.16.2, )",
"resolved": "1.16.2",
"contentHash": "UxYWJaXugQ+v4txS7K8sw26bxS6xvjSW+f79U/oMBtm+cVvZSmBGRZkB77rzaoXAyrbixX0Vk0U+1f22TT2uWg==",
"dependencies": {
"AvalonEdit": "6.0.0",
"MdXaml.Plugins": "1.16.2"
}
},
"Microsoft.Diagnostics.Runtime": {
"type": "Direct",
"requested": "[2.2.343001, )",
"resolved": "2.2.343001",
"contentHash": "nVwXLEJiXbnnNkQPcWy64DMWNBvMg9XKWpfBBNMVs1gbEJ9HUVTcAA862mOjgyKryAtvGVKkeQ/9cW6pK8YAiA==",
"dependencies": {
"Microsoft.Diagnostics.NETCore.Client": "0.2.251802",
"System.Collections.Immutable": "5.0.0",
"System.Runtime.CompilerServices.Unsafe": "5.0.0"
}
},
"Microsoft.Extensions.Configuration.Binder": {
"type": "Direct",
"requested": "[7.0.0, )",
"resolved": "7.0.0",
"contentHash": "tgU4u7bZsoS9MKVRiotVMAwHtbREHr5/5zSEV+JPhg46+ox47Au84E3D2IacAaB0bk5ePNaNieTlPrfjbbRJkg==",
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "7.0.0"
}
},
"Microsoft.Extensions.Configuration.CommandLine": {
"type": "Direct",
"requested": "[7.0.0, )",
"resolved": "7.0.0",
"contentHash": "a8Iq8SCw5m8W5pZJcPCgBpBO4E89+NaObPng+ApIhrGSv9X4JPrcFAaGM4sDgR0X83uhLgsNJq8VnGP/wqhr8A==",
"dependencies": {
"Microsoft.Extensions.Configuration": "7.0.0",
"Microsoft.Extensions.Configuration.Abstractions": "7.0.0"
}
},
"Microsoft.Extensions.Configuration.EnvironmentVariables": {
"type": "Direct",
"requested": "[7.0.0, )",
"resolved": "7.0.0",
"contentHash": "RIkfqCkvrAogirjsqSrG1E1FxgrLsOZU2nhRbl07lrajnxzSU2isj2lwQah0CtCbLWo/pOIukQzM1GfneBUnxA==",
"dependencies": {
"Microsoft.Extensions.Configuration": "7.0.0",
"Microsoft.Extensions.Configuration.Abstractions": "7.0.0"
}
},
"Microsoft.Extensions.Configuration.Xml": {
"type": "Direct",
"requested": "[7.0.0, )",
"resolved": "7.0.0",
"contentHash": "KXmN/llitPZydHbW3cac7MQHGPUXPi4783tYxsBqSAFJgcaYTdLmsboFL7Ss4TsnelF0+v4ZMpEkKTtCtpysiA==",
"dependencies": {
"Microsoft.Extensions.Configuration": "7.0.0",
"Microsoft.Extensions.Configuration.Abstractions": "7.0.0",
"Microsoft.Extensions.Configuration.FileExtensions": "7.0.0",
"Microsoft.Extensions.FileProviders.Abstractions": "7.0.0",
"System.Security.Cryptography.Xml": "7.0.0"
}
},
"NLog": {
"type": "Direct",
"requested": "[5.1.0, )",
"resolved": "5.1.0",
"contentHash": "oW7ekrkRG9okpDMUcEglunWj8Qf2RY8qkgl+/chJoavzg3dbT13y32t19R54FKkmq80fKzw4ZekZkCrRGanKgQ=="
},
"nulastudio.NetCoreBeauty": {
"type": "Direct",
"requested": "[1.2.9.3, )",
"resolved": "1.2.9.3",
"contentHash": "ToUOoX/sNCg6oeMcSrHYBBRPjKp1gDS7I5WNnY+59t7iNFPcAojpc2lYmgCm3hxwXW/xCxyQIV4k5agegqc3fg=="
},
"PropertyChanged.Fody": {
"type": "Direct",
"requested": "[4.0.3, )",
"resolved": "4.0.3",
"contentHash": "vRxEDydahhcetswKaoUug7mQywgpZpHoeHZWa7Opb+H+eWPUQo+f+v37Jy+rrG1RVOCkyziTgCkNetXzNlUXJw==",
"dependencies": {
"Fody": "6.6.3"
}
},
"SpaceEngineersDedicated.ReferenceAssemblies": {
"type": "Direct",
"requested": "[1.201.13, )",
"resolved": "1.201.13",
"contentHash": "FRXuNLENsz5jGQvL0QkogAGsxEJyUQlXhvWHBWfZiHCnCrAWMD60nEis6yt0xCQpazszfMtHonbxz72XMxnFoQ==",
"dependencies": {
"protobuf-net": "1.0.0"
}
},
"Steamworks.NET": {
"type": "Direct",
"requested": "[20.1.0, )",
"resolved": "20.1.0",
"contentHash": "+GntwnyJ5tCNvUIaQxv2+ehDvZJzGUqlSB5xRBk1hTj1qqBJ6s4vK/OfGD/jae7aTmXiGSm8wpJORosNtQevJQ=="
},
"System.ComponentModel.Annotations": {
"type": "Direct",
"requested": "[5.0.0, )",
"resolved": "5.0.0",
"contentHash": "dMkqfy2el8A8/I76n2Hi1oBFEbG1SfxD2l5nhwXV3XjlnOmwxJlQbYpJH4W51odnU9sARCSAgv7S3CyAFMkpYg=="
},
"System.Management": {
"type": "Direct",
"requested": "[7.0.0, )",
"resolved": "7.0.0",
"contentHash": "A4jed4QUviDOm7fJNKAJObEAEkEUXmkGL/w0iyCYTzrl1rezTj8LGFHfsVst4Vb9JwFcTpboiDrvdST48avBpw==",
"dependencies": {
"System.CodeDom": "7.0.0"
}
},
"AvalonEdit": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "QMbyJrlhOuWzLRPqvW724ly9XbSEkp8Xg2mQY7tvsh1se1pDEJnmDjS6c6OuqDe2Q37uCnXwKdV8tJUx2iLUnw=="
},
"Fody": {
"type": "Transitive",
"resolved": "6.6.3",
"contentHash": "X1WKKgSNYVtLzdO8dK3YWmfmljA4L0soePcWNouq9X6WbVF4bmivuJdlhTZx/2L3ml6tMvhFe8skIbVQ24PAYA=="
},
"HarmonyX": {
"type": "Transitive",
"resolved": "2.10.2-prerelease.1",
"contentHash": "5hbH0ENhQ+JV7tk63fQ2ab7MtplRHKJYH1JfIjG39rlltHNXxAcGJh05an+SQbVRV4EoP/+Qm9w9BrLc3RwRMA==",
"dependencies": {
"MonoModReorg.RuntimeDetour": "22.11.21-prerelease.2",
"System.Reflection.Emit": "4.7.0",
"System.Reflection.Emit.Lightweight": "4.7.0"
}
},
"JorgeSerrano.Json.JsonSnakeCaseNamingPolicy": {
"type": "Transitive",
"resolved": "0.9.0",
"contentHash": "xCqODS+wzpUXNtg4bMMvXG5PLbP0iTwRzRn2R+zWHKm83E6tbV2bCagawXp1EnZeNpd5OXpMxehulZWns8efzQ=="
},
"MdXaml.Plugins": {
"type": "Transitive",
"resolved": "1.16.2",
"contentHash": "EOMENHbLkpRk7+UItuutDuETiJpSCZgBATBRk7WSuxO16NUfzrS39ja4RhIQ0Ax8u0RH1wCAS0VINYPZqxfJeg=="
},
"Microsoft.Bcl.AsyncInterfaces": {
"type": "Transitive",
"resolved": "1.1.0",
"contentHash": "1Am6l4Vpn3/K32daEqZI+FFr96OlZkgwK2LcT3pZ2zWubR5zTPW3/FkO1Rat9kb7oQOa4rxgl9LJHc5tspCWfg=="
},
"Microsoft.CodeAnalysis.Analyzers": {
"type": "Transitive",
"resolved": "3.3.3",
"contentHash": "j/rOZtLMVJjrfLRlAMckJLPW/1rze9MT1yfWqSIbUPGRu1m1P0fuo9PmqapwsmePfGB5PJrudQLvmUOAMF0DqQ=="
},
"Microsoft.CodeAnalysis.Common": {
"type": "Transitive",
"resolved": "4.4.0",
"contentHash": "JfHupS/B7Jb5MZoYkFFABn3mux0wQgxi2D8F/rJYZeRBK2ZOyk7TjQ2Kq9rh6W/DCh0KNbbSbn5qoFar+ueHqw==",
"dependencies": {
"Microsoft.CodeAnalysis.Analyzers": "3.3.3",
"System.Collections.Immutable": "6.0.0",
"System.Memory": "4.5.5",
"System.Reflection.Metadata": "5.0.0",
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
"System.Text.Encoding.CodePages": "6.0.0",
"System.Threading.Tasks.Extensions": "4.5.4"
}
},
"Microsoft.CodeAnalysis.CSharp": {
"type": "Transitive",
"resolved": "4.4.0",
"contentHash": "eD2w0xHRoaqK07hjlOKGR9eLNy3nimiGNeCClNax1NDgS/+DBtBqCjXelOa+TNy99kIB3nHhUqDmr46nDXy/RQ==",
"dependencies": {
"Microsoft.CodeAnalysis.Common": "[4.4.0]"
}
},
"Microsoft.Diagnostics.NETCore.Client": {
"type": "Transitive",
"resolved": "0.2.251802",
"contentHash": "bqnYl6AdSeboeN4v25hSukK6Odm6/54E3Y2B8rBvgqvAW0mF8fo7XNRVE2DMOG7Rk0fiuA079QIH28+V+W1Zdg==",
"dependencies": {
"Microsoft.Bcl.AsyncInterfaces": "1.1.0",
"Microsoft.Extensions.Logging": "2.1.1"
}
},
"Microsoft.Extensions.Configuration": {
"type": "Transitive",
"resolved": "7.0.0",
"contentHash": "tldQUBWt/xeH2K7/hMPPo5g8zuLc3Ro9I5d4o/XrxvxOCA2EZBtW7bCHHTc49fcBtvB8tLAb/Qsmfrq+2SJ4vA==",
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "7.0.0",
"Microsoft.Extensions.Primitives": "7.0.0"
}
},
"Microsoft.Extensions.Configuration.Abstractions": {
"type": "Transitive",
"resolved": "7.0.0",
"contentHash": "f34u2eaqIjNO9YLHBz8rozVZ+TcFiFs0F3r7nUJd7FRkVSxk8u4OpoK226mi49MwexHOR2ibP9MFvRUaLilcQQ==",
"dependencies": {
"Microsoft.Extensions.Primitives": "7.0.0"
}
},
"Microsoft.Extensions.Configuration.FileExtensions": {
"type": "Transitive",
"resolved": "7.0.0",
"contentHash": "xk2lRJ1RDuqe57BmgvRPyCt6zyePKUmvT6iuXqiHR+/OIIgWVR8Ff5k2p6DwmqY8a17hx/OnrekEhziEIeQP6Q==",
"dependencies": {
"Microsoft.Extensions.Configuration": "7.0.0",
"Microsoft.Extensions.Configuration.Abstractions": "7.0.0",
"Microsoft.Extensions.FileProviders.Abstractions": "7.0.0",
"Microsoft.Extensions.FileProviders.Physical": "7.0.0",
"Microsoft.Extensions.Primitives": "7.0.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.1.1",
"contentHash": "MgYpU5cwZohUMKKg3sbPhvGG+eAZ/59E9UwPwlrUkyXU+PGzqwZg9yyQNjhxuAWmoNoFReoemeCku50prYSGzA=="
},
"Microsoft.Extensions.FileProviders.Abstractions": {
"type": "Transitive",
"resolved": "7.0.0",
"contentHash": "NyawiW9ZT/liQb34k9YqBSNPLuuPkrjMgQZ24Y/xXX1RoiBkLUdPMaQTmxhZ5TYu8ZKZ9qayzil75JX95vGQUg==",
"dependencies": {
"Microsoft.Extensions.Primitives": "7.0.0"
}
},
"Microsoft.Extensions.FileProviders.Physical": {
"type": "Transitive",
"resolved": "7.0.0",
"contentHash": "K8D2MTR+EtzkbZ8z80LrG7Ur64R7ZZdRLt1J5cgpc/pUWl0C6IkAUapPuK28oionHueCPELUqq0oYEvZfalNdg==",
"dependencies": {
"Microsoft.Extensions.FileProviders.Abstractions": "7.0.0",
"Microsoft.Extensions.FileSystemGlobbing": "7.0.0",
"Microsoft.Extensions.Primitives": "7.0.0"
}
},
"Microsoft.Extensions.FileSystemGlobbing": {
"type": "Transitive",
"resolved": "7.0.0",
"contentHash": "2jONjKHiF+E92ynz2ZFcr9OvxIw+rTGMPEH+UZGeHTEComVav93jQUWGkso8yWwVBcEJGcNcZAaqY01FFJcj7w=="
},
"Microsoft.Extensions.Logging": {
"type": "Transitive",
"resolved": "2.1.1",
"contentHash": "hh+mkOAQDTp6XH80xJt3+wwYVzkbwYQl9XZRCz4Um0JjP/o7N9vHM3rZ6wwwtr+BBe/L6iBO2sz0px6OWBzqZQ==",
"dependencies": {
"Microsoft.Extensions.Configuration.Binder": "2.1.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.1",
"Microsoft.Extensions.Logging.Abstractions": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1"
}
},
"Microsoft.Extensions.Logging.Abstractions": {
"type": "Transitive",
"resolved": "2.1.1",
"contentHash": "XRzK7ZF+O6FzdfWrlFTi1Rgj2080ZDsd46vzOjadHUB0Cz5kOvDG8vI7caa5YFrsHQpcfn0DxtjS4E46N4FZsA=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.1.1",
"contentHash": "V7lXCU78lAbzaulCGFKojcCyG8RTJicEbiBkPJjFqiqXwndEBBIehdXRMWEVU3UtzQ1yDvphiWUL9th6/4gJ7w==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.1",
"Microsoft.Extensions.Primitives": "2.1.1"
}
},
"Microsoft.Extensions.Primitives": {
"type": "Transitive",
"resolved": "7.0.0",
"contentHash": "um1KU5kxcRp3CNuI8o/GrZtD4AIOXDk+RLsytjZ9QPok3ttLUelLKpilVPuaFT3TFjOhSibUAso0odbOaCDj3Q=="
},
"Microsoft.Xaml.Behaviors.Wpf": {
"type": "Transitive",
"resolved": "1.1.31",
"contentHash": "LZpuf82ACZWldmfMuv3CTUMDh3o0xo0uHUaybR5HgqVLDBJJ9RZLykplQ/bTJd0/VDt3EhD4iDgUgbdIUAM+Kg=="
},
"Mono.Cecil": {
"type": "Transitive",
"resolved": "0.11.4",
"contentHash": "IC1h5g0NeJGHIUgzM1P82ld57knhP0IcQfrYITDPXlNpMYGUrsG5TxuaWTjaeqDNQMBDNZkB8L0rBnwsY6JHuQ=="
},
"MonoModReorg.Backports": {
"type": "Transitive",
"resolved": "22.11.21-prerelease.2",
"contentHash": "69T6jjA5nx29jLkdqtfXKlJ8sMqIlc6czNDTomy0rbM68W0xo2JRJBgsu2mroBuqx7nvUdX+zIU6k1edS/pPbw==",
"dependencies": {
"MonoModReorg.ILHelpers": "22.11.21-prerelease.2"
}
},
"MonoModReorg.Core": {
"type": "Transitive",
"resolved": "22.11.21-prerelease.2",
"contentHash": "gDoxu4aAF6TeOo8rsrj5prq2X36i12ch6NeRHu/Ct0H3qoPDHuEQ6JMJN/Eiy45YrLNEN7C5+Ku4BrNX4nwVQg==",
"dependencies": {
"Mono.Cecil": "0.11.4",
"MonoModReorg.Backports": "22.11.21-prerelease.2",
"MonoModReorg.ILHelpers": "22.11.21-prerelease.2",
"MonoModReorg.Utils": "22.11.21-prerelease.2"
}
},
"MonoModReorg.ILHelpers": {
"type": "Transitive",
"resolved": "22.11.21-prerelease.2",
"contentHash": "JtOKHJR4DEyq3HxmdEVXIxhqNQnu1KmjGFXuEQrNHoPbzi8Yr9465VKVXdsoAF0Lm8StdyJHQ03efjv3+OlonA=="
},
"MonoModReorg.RuntimeDetour": {
"type": "Transitive",
"resolved": "22.11.21-prerelease.2",
"contentHash": "Qv1h4rW03LrHwxwVuw5R6hbL8X78l8Lfnxe5tMlyVAe+AK0HnwsRzjsTwzFF57wxWUwq12NbLflkzV6T+hIhJw==",
"dependencies": {
"Mono.Cecil": "0.11.4",
"MonoModReorg.Backports": "22.11.21-prerelease.2",
"MonoModReorg.Core": "22.11.21-prerelease.2",
"MonoModReorg.ILHelpers": "22.11.21-prerelease.2",
"MonoModReorg.Utils": "22.11.21-prerelease.2"
}
},
"MonoModReorg.Utils": {
"type": "Transitive",
"resolved": "22.11.21-prerelease.2",
"contentHash": "TX+vlgg2/x8rzEOqwiAy2qv61FjlJsr4u10WGTekCkulZVmmC+xxDmK+4Do9noXF/4RlgFN6sR3m9/W8KvJq3g==",
"dependencies": {
"Mono.Cecil": "0.11.4",
"MonoModReorg.Backports": "22.11.21-prerelease.2",
"MonoModReorg.ILHelpers": "22.11.21-prerelease.2"
}
},
"protobuf-net": {
"type": "Transitive",
"resolved": "3.1.26",
"contentHash": "iy+VROYtWZEqDvkUjS6FfzKZNpWRoVGc5h0cupGQT/37Ox0LxPblRKLnw6V0RT1MPclLo8nZp7E2M0f7PNn/Tw==",
"dependencies": {
"protobuf-net.Core": "3.1.26"
}
},
"protobuf-net.Core": {
"type": "Transitive",
"resolved": "3.1.26",
"contentHash": "fuKoDWgAf5ju+ixbJoasVFhnUaT0oWUgrWh1AZ5D0Y5keKHpA93vQB5g6aQNtB4zgeQ4hGEeh0MY9bIbAUPgEw=="
},
"SemanticVersioning": {
"type": "Transitive",
"resolved": "2.0.2",
"contentHash": "4EQgYdNZ92SyaO7YFk6olVnebF5V+jrHyMUjvPq89tLeMo8NSfgDF+6Zwq/lgh9j/0yfQp9Lkm0ZA0rUATCZFA=="
},
"SixLabors.Core": {
"type": "Transitive",
"resolved": "1.0.0-beta0007",
"contentHash": "s9aPl6yxwcvoKRD0u0zjkCISZCCifbUi9/XVFjdvlx5Pt7vRYmGV0anq1EEftUjIEHbEu5aNBipbUSBIV2CE7w==",
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
}
},
"System.CodeDom": {
"type": "Transitive",
"resolved": "7.0.0",
"contentHash": "GLltyqEsE5/3IE+zYRP5sNa1l44qKl9v+bfdMcwg+M9qnQf47wK3H0SUR/T+3N4JEQXF3vV4CSuuo0rsg+nq2A=="
},
"System.Collections.Immutable": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "l4zZJ1WU2hqpQQHXz1rvC3etVZN+2DLmQMO79FhOTZHMn8tDRr+WU287sbomD0BETlmKDn0ygUgVy9k5xkkJdA==",
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
},
"System.Formats.Asn1": {
"type": "Transitive",
"resolved": "7.0.0",
"contentHash": "+nfpV0afLmvJW8+pLlHxRjz3oZJw4fkyU9MMEaMhCsHi/SN9bGF9q79ROubDiwTiCHezmK0uCWkPP7tGFP/4yg=="
},
"System.Memory": {
"type": "Transitive",
"resolved": "4.5.5",
"contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw=="
},
"System.Reflection.Emit": {
"type": "Transitive",
"resolved": "4.7.0",
"contentHash": "VR4kk8XLKebQ4MZuKuIni/7oh+QGFmZW3qORd1GvBq/8026OpW501SzT/oypwiQl4TvT8ErnReh/NzY9u+C6wQ=="
},
"System.Reflection.Emit.Lightweight": {
"type": "Transitive",
"resolved": "4.7.0",
"contentHash": "a4OLB4IITxAXJeV74MDx49Oq2+PsF6Sml54XAFv+2RyWwtDBcabzoxiiJRhdhx+gaohLh4hEGCLQyBozXoQPqA=="
},
"System.Reflection.Metadata": {
"type": "Transitive",
"resolved": "5.0.0",
"contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ=="
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
},
"System.Security.Cryptography.Pkcs": {
"type": "Transitive",
"resolved": "7.0.0",
"contentHash": "mjUbEXkR6DYRef6dnEYKdfec9otcAkibExL+1f9hmbGlWIUyaCnS3Y3oGZEet38waXmuY1ORE8vgv4sgD5nMYg==",
"dependencies": {
"System.Formats.Asn1": "7.0.0"
}
},
"System.Security.Cryptography.Xml": {
"type": "Transitive",
"resolved": "7.0.0",
"contentHash": "LHc5PUypYGAMNf/2DzCxOXREKamwCtdUtxb/WpCnHngORVYZbUdSMnm1PcKvEvzKUTKSC0CL6aVAywzbEEeNQg==",
"dependencies": {
"System.Security.Cryptography.Pkcs": "7.0.0"
}
},
"System.Text.Encoding.CodePages": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "ZFCILZuOvtKPauZ/j/swhvw68ZRi9ATCfvGbk1QfydmcXBkIWecWKn/250UH7rahZ5OoDBaiAudJtPvLwzw85A==",
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
},
"System.Text.Json": {
"type": "Transitive",
"resolved": "5.0.1",
"contentHash": "/UM3UK1dXKl8Ybysg/21gM4S8DJgkR+yLU8JwqCVbuNqQNImelntgYFAN5QxR8sJJ1kMx//hOUdf0lltosi8cQ=="
},
"System.Threading.Tasks.Extensions": {
"type": "Transitive",
"resolved": "4.5.4",
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg=="
},
"Torch.SixLabors.ImageSharp": {
"type": "Transitive",
"resolved": "1.0.0-beta6",
"contentHash": "WJ7ocT79HgmuKi0+ltpvXTiMI80UcI3DeS8XSfYwJtTB1tcQws6zLPGuUwra6qe6qRrFfpABeDP3xvHV1rJgfg==",
"dependencies": {
"SixLabors.Core": "1.0.0-beta0007",
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
}
},
"torch": {
"type": "Project",
"dependencies": {
"ControlzEx": "[5.0.2, )",
"HarmonyX": "[2.10.2-prerelease.1, )",
"MahApps.Metro": "[2.4.9, )",
"Microsoft.CodeAnalysis.CSharp": "[4.4.0, )",
"Microsoft.CodeAnalysis.Common": "[4.4.0, )",
"MonoModReorg.RuntimeDetour": "[22.11.21-prerelease.2, )",
"NLog": "[5.1.0, )",
"System.ComponentModel.Annotations": "[5.0.0, )",
"Torch.API": "[1.0.0, )",
"Torch.SixLabors.ImageSharp": "[1.0.0-beta6, )",
"protobuf-net": "[3.1.26, )"
}
},
"torch.api": {
"type": "Project",
"dependencies": {
"JorgeSerrano.Json.JsonSnakeCaseNamingPolicy": "[0.9.0, )",
"NLog": "[5.1.0, )",
"SemanticVersioning": "[2.0.2, )"
}
}
},
"net7.0-windows7.0/win-x64": {
"Steamworks.NET": {
"type": "Direct",
"requested": "[20.1.0, )",
"resolved": "20.1.0",
"contentHash": "+GntwnyJ5tCNvUIaQxv2+ehDvZJzGUqlSB5xRBk1hTj1qqBJ6s4vK/OfGD/jae7aTmXiGSm8wpJORosNtQevJQ=="
},
"System.Management": {
"type": "Direct",
"requested": "[7.0.0, )",
"resolved": "7.0.0",
"contentHash": "A4jed4QUviDOm7fJNKAJObEAEkEUXmkGL/w0iyCYTzrl1rezTj8LGFHfsVst4Vb9JwFcTpboiDrvdST48avBpw==",
"dependencies": {
"System.CodeDom": "7.0.0"
}
},
"System.Security.Cryptography.Pkcs": {
"type": "Transitive",
"resolved": "7.0.0",
"contentHash": "mjUbEXkR6DYRef6dnEYKdfec9otcAkibExL+1f9hmbGlWIUyaCnS3Y3oGZEet38waXmuY1ORE8vgv4sgD5nMYg==",
"dependencies": {
"System.Formats.Asn1": "7.0.0"
}
},
"System.Text.Encoding.CodePages": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "ZFCILZuOvtKPauZ/j/swhvw68ZRi9ATCfvGbk1QfydmcXBkIWecWKn/250UH7rahZ5OoDBaiAudJtPvLwzw85A==",
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
}
}
}
}

View File

@@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6-windows</TargetFramework>
<LangVersion>10</LangVersion>
<TargetFramework>net7-windows</TargetFramework>
<NoWarn>1591,0649</NoWarn>
<AssemblyTitle>Torch Tests</AssemblyTitle>
<Product>Torch</Product>
@@ -18,8 +17,8 @@
</PropertyGroup>
<!-- <Import Project="$(SolutionDir)\TransformOnBuild.targets" /> -->
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="NLog" Version="5.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
<PackageReference Include="NLog" Version="5.1.0" />
<PackageReference Include="xunit" Version="2.4.2" />
</ItemGroup>
<ItemGroup>

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using NLog;
@@ -9,7 +10,7 @@ using Torch.API;
namespace Torch.Managers
{
public class FilesystemManager : Manager
public partial class FilesystemManager : Manager
{
private static readonly Logger _log = LogManager.GetCurrentClassLogger();
/// <summary>
@@ -51,19 +52,27 @@ namespace Torch.Managers
}
}
/// <summary>
/// Move the given file (if it exists) to a temporary directory that will be cleared the next time the application starts.
/// </summary>
public void SoftDelete(string path, string file)
{
string source = Path.Combine(path, file);
var source = Path.Combine(path, file);
if (!File.Exists(source))
return;
var rand = Path.GetRandomFileName();
var dest = Path.Combine(TempDirectory, rand);
File.Move(source, rand);
string rsource = Path.Combine(path, rand);
File.Move(rsource, dest);
var tempFilePath = Path.Combine(path, file + ".old");
if (File.Exists(tempFilePath))
File.Delete(tempFilePath);
var errorCode = Rename(source, tempFilePath);
if (Marshal.GetExceptionForHR(errorCode) is { } exception)
throw exception;
}
[LibraryImport("msvcrt", SetLastError = true, EntryPoint = "rename")]
[UnmanagedCallConv(CallConvs = new[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })]
private static partial int Rename(
[MarshalAs(UnmanagedType.LPWStr)]
string oldpath,
[MarshalAs(UnmanagedType.LPWStr)]
string newpath);
}
}

View File

@@ -21,8 +21,6 @@ namespace Torch.Managers.PatchManager
{
internal class DecoratedMethod : MethodRewritePattern
{
private static Action<ILHook, bool> IsAppliedSetter;
[ReflectedMethodInfo(typeof(MethodBase), nameof(MethodBase.GetMethodFromHandle), Parameters = new[] {typeof(RuntimeMethodHandle)})]
private static MethodInfo _getMethodFromHandle = null!;
@@ -37,10 +35,6 @@ namespace Torch.Managers.PatchManager
internal DecoratedMethod(MethodBase method) : base(null)
{
_method = method;
if (IsAppliedSetter == null)
{
IsAppliedSetter = typeof(ILHook).GetProperty(nameof(ILHook.IsApplied)).CreateSetter<ILHook, bool>();
}
}
internal bool HasChanged()
@@ -62,16 +56,14 @@ namespace Torch.Managers.PatchManager
_log.Log(PrintMode != 0 ? LogLevel.Info : LogLevel.Debug,
$"Begin patching {_method.DeclaringType?.FullName}#{_method.Name}({string.Join(", ", _method.GetParameters().Select(x => x.ParameterType.Name))})");
if (_hook == null)
_hook = new ILHook(_method, Manipulator, new ILHookConfig {ManualApply = true});
IsAppliedSetter(_hook, false);
_hook ??= new ILHook(_method, Manipulator, false);
try
{
_hook.Apply();
}
catch (InvalidProgramException e)
{
IsAppliedSetter(_hook, false);
_hook.Undo();
PrintMode = PrintModeEnum.Emitted | PrintModeEnum.Original;
try
{

View File

@@ -215,7 +215,7 @@ public class ScriptCompilationManager : Manager
}
private readonly CSharpCompilationOptions _compilationOptions = new(OutputKind.DynamicallyLinkedLibrary);
private readonly CSharpParseOptions _parseOptions = new(LanguageVersion.CSharp10, DocumentationMode.None);
private readonly CSharpParseOptions _parseOptions = new(LanguageVersion.CSharp11, DocumentationMode.None);
private CSharpCompilation CreateCompilation(string assemblyFileName, IEnumerable<Script> scripts)
{

View File

@@ -5,6 +5,7 @@ using System.IO.Compression;
using System.IO.Packaging;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
@@ -12,6 +13,7 @@ using System.Threading.Tasks;
using NLog;
using Torch.API;
using Torch.API.WebAPI;
using Torch.API.WebAPI.Update;
namespace Torch.Managers
{
@@ -21,8 +23,9 @@ namespace Torch.Managers
public class UpdateManager : Manager
{
private readonly Timer _updatePollTimer;
private string _torchDir = new FileInfo(typeof(UpdateManager).Assembly.Location).DirectoryName;
private Logger _log = LogManager.GetCurrentClassLogger();
private readonly string _torchDir = ApplicationContext.Current.TorchDirectory.FullName;
private readonly Logger _log = LogManager.GetCurrentClassLogger();
[Dependency]
private FilesystemManager _fsManager = null!;
@@ -50,26 +53,22 @@ namespace Torch.Managers
try
{
var job = await JenkinsQuery.Instance.GetLatestVersion(Torch.TorchVersion.Build);
if (job == null)
{
_log.Info("Failed to fetch latest version.");
return;
}
var updateSource = Torch.Config.UpdateSource;
if (job.Version > Torch.TorchVersion)
IUpdateQuery source = updateSource.SourceType switch
{
_log.Warn($"Updating Torch from version {Torch.TorchVersion} to version {job.Version}");
var updateName = Path.Combine(_fsManager.TempDirectory, "torchupdate.zip");
//new WebClient().DownloadFile(new Uri(releaseInfo.Item2), updateName);
if (!await JenkinsQuery.Instance.DownloadRelease(job, updateName))
{
_log.Warn("Failed to download new release!");
return;
}
UpdateFromZip(updateName, _torchDir);
File.Delete(updateName);
_log.Warn($"Torch version {job.Version} has been installed, please restart Torch to finish the process.");
UpdateSourceType.Github => new GithubQuery(updateSource.Url),
UpdateSourceType.Jenkins => new JenkinsQuery(updateSource.Url),
_ => throw new ArgumentOutOfRangeException()
};
var release = await source.GetLatestReleaseAsync(updateSource.Repository, updateSource.Branch);
if (release.Version > Torch.TorchVersion)
{
_log.Warn($"Updating Torch from version {Torch.TorchVersion} to version {release.Version}");
await UpdateAsync(release, _torchDir);
_log.Warn($"Torch version {release.Version} has been installed, please restart Torch to finish the process.");
}
else
{
@@ -83,23 +82,38 @@ namespace Torch.Managers
}
}
private void UpdateFromZip(string zipFile, string extractPath)
private async Task UpdateAsync(UpdateRelease release, string extractPath)
{
using (var zip = ZipFile.OpenRead(zipFile))
{
foreach (var file in zip.Entries)
{
if(file.Name == "NLog-user.config" && File.Exists(Path.Combine(extractPath, file.FullName)))
continue;
using var client = new HttpClient();
await using var stream = await client.GetStreamAsync(release.ArtifactUrl);
UpdateFromZip(stream, extractPath);
}
_log.Debug($"Unzipping {file.FullName}");
var targetFile = Path.Combine(extractPath, file.FullName);
private void UpdateFromZip(Stream zipStream, string extractPath)
{
using var zip = new ZipArchive(zipStream, ZipArchiveMode.Read, true);
foreach (var file in zip.Entries)
{
if(file.Name == "NLog-user.config" && File.Exists(Path.Combine(extractPath, file.FullName)))
continue;
_log.Debug($"Unzipping {file.FullName}");
var targetFile = Path.Combine(extractPath, file.FullName);
// if its a directory
if (Path.GetFileName(targetFile).Length == 0)
{
Directory.CreateDirectory(targetFile);
}
else
{
_fsManager.SoftDelete(extractPath, file.FullName);
file.ExtractToFile(targetFile, true);
}
//zip.ExtractToDirectory(extractPath); //throws exceptions sometimes?
}
//zip.ExtractToDirectory(extractPath); //throws exceptions sometimes?
}
/// <inheritdoc />

View File

@@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Sandbox;
using Sandbox.Game.Entities;
using Torch.Utils;
@@ -69,6 +66,8 @@ namespace Torch.Patches
}
}
MyEntities.Orchestrator = new MyParallelEntityUpdateOrchestrator();
// static MyObjectPoolManager()
// Render, so should be fine.
}

View File

@@ -12,6 +12,7 @@ using System.Reflection.Emit;
using System.Text.RegularExpressions;
using System.Threading;
using Microsoft.CodeAnalysis;
using ParallelTasks;
using ProtoBuf;
using Torch.Managers.PatchManager;
using Torch.Managers.PatchManager.MSIL;
@@ -82,6 +83,14 @@ namespace Torch.Patches
using var batch = MyScriptCompiler.Static.Whitelist.OpenBatch();
batch.AllowTypes(MyWhitelistTarget.ModApi, typeof(ConcurrentQueue<>));
batch.AllowNamespaceOfTypes(MyWhitelistTarget.Both, typeof(ImmutableArray), typeof(ArrayExtensions));
batch.AllowTypes(MyWhitelistTarget.ModApi, typeof(ProtoContractAttribute).Assembly.GetExportedTypes()
.Where(b => b.Namespace == "ProtoBuf" && b.Name.Contains("Attribute"))
.Concat(new[]
{
typeof(DataFormat), typeof(MemberSerializationOptions), typeof(ImplicitFields)
}).ToArray());
batch.AllowTypes(MyWhitelistTarget.ModApi, typeof(WorkData));
return false;
}
@@ -103,7 +112,7 @@ namespace Torch.Patches
do
{
ins[i] = new(OpCodes.Nop);
} while (ins[--i].OpCode.OperandType != OperandType.ShortInlineBrTarget);
} while (ins[--i].OpCode.FlowControl != FlowControl.Cond_Branch);
ins[index] = new(OpCodes.Ret);
}

View File

@@ -62,7 +62,7 @@ internal static class AssemblyRewriter
{
using var module = ModuleDefinition.ReadModule(inputStream, new()
{
AssemblyResolver = _zipResolver
AssemblyResolver = resolver
});
foreach (var fieldDefinition in FindAllToRewrite(module))
{

View File

@@ -16,6 +16,7 @@ using Torch.API.Managers;
using Torch.API.Plugins;
using Torch.API.Session;
using Torch.API.WebAPI;
using Torch.API.WebAPI.Plugin;
using Torch.Collections;
using Torch.Commands;
using Torch.Plugins;
@@ -306,7 +307,7 @@ namespace Torch.Managers
return;
}
item.Manifest.Version.TryExtractVersion(out Version currentVersion);
var latest = await PluginQuery.Instance.QueryOne(item.Manifest.Guid);
var latest = await LegacyPluginQuery.Instance.QueryOne(item.Manifest.Guid);
if (latest?.LatestVersion == null)
{
@@ -329,7 +330,7 @@ namespace Torch.Managers
}
_log.Info($"Updating plugin '{item.Manifest.Name}' from {currentVersion} to {newVersion}.");
await PluginQuery.Instance.DownloadPlugin(latest, item.Path);
await LegacyPluginQuery.Instance.DownloadPlugin(latest, item.Path);
Interlocked.Increment(ref count);
}
catch (Exception e)
@@ -428,7 +429,7 @@ namespace Torch.Managers
if (a.Version is null || b.Version is null)
return a.Name == b.Name;
return a.Name == b.Name && a.Version.Major == b.Version.Major && a.Version.Minor == b.Version.Minor;
return a.Name == b.Name && b.Version >= a.Version;
}
private void InstantiatePlugin(PluginManifest manifest, IEnumerable<Assembly> assemblies)

View File

@@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6-windows</TargetFramework>
<LangVersion>10</LangVersion>
<TargetFramework>net7-windows</TargetFramework>
<AssemblyTitle>Torch</AssemblyTitle>
<Product>Torch</Product>
<Copyright>Copyright © Torch API 2017</Copyright>
@@ -12,6 +11,8 @@
<PlatformTarget>x64</PlatformTarget>
<Configurations>Debug;Release</Configurations>
<Platforms>AnyCPU</Platforms>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>
<PropertyGroup Condition="$(Configuration) == 'Release'">
@@ -21,16 +22,16 @@
<Import Project="..\Torch.Mod\Torch.Mod.projitems" Label="Shared" />
<ItemGroup>
<PackageReference Include="ControlzEx" Version="5.0.1" />
<PackageReference Include="HarmonyX" Version="2.10.0" />
<PackageReference Include="ControlzEx" Version="5.0.2" />
<PackageReference Include="HarmonyX" Version="2.10.2-prerelease.1" />
<PackageReference Include="InfoOf.Fody" Version="2.1.1" PrivateAssets="all" />
<PackageReference Include="MahApps.Metro" Version="2.4.9" />
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.3.1" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.1" />
<PackageReference Include="MonoMod.RuntimeDetour" Version="22.5.1.1" />
<PackageReference Include="NLog" Version="5.0.4" />
<PackageReference Include="PropertyChanged.Fody" Version="4.0.3" PrivateAssets="all" />
<PackageReference Include="protobuf-net" Version="2.4.7" />
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.4.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.4.0" />
<PackageReference Include="MonoModReorg.RuntimeDetour" Version="22.11.21-prerelease.2" />
<PackageReference Include="NLog" Version="5.1.0" />
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0" PrivateAssets="all" />
<PackageReference Include="protobuf-net" Version="3.1.26" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="Torch.SixLabors.ImageSharp" Version="1.0.0-beta6" />
<PackageReference Include="SpaceEngineersDedicated.ReferenceAssemblies" Version="1.201.13">

View File

@@ -104,14 +104,8 @@ namespace Torch
#pragma warning restore CS0618
Config = config;
var versionString = GetType().Assembly
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()!
.InformationalVersion;
if (!SemanticVersioning.Version.TryParse(versionString, out var version))
throw new TypeLoadException("Unable to parse the Torch version from the assembly.");
TorchVersion = version;
var assemblyVersion = GetType().Assembly.GetName().Version ?? new Version();
TorchVersion = new(assemblyVersion.Major, assemblyVersion.Minor, assemblyVersion.Build);
RunArgs = Array.Empty<string>();
@@ -129,7 +123,7 @@ namespace Torch
Managers.AddManager(sessionManager);
Managers.AddManager(new PatchManager(this));
Managers.AddManager(new FilesystemManager(this));
// Managers.AddManager(new UpdateManager(this));
Managers.AddManager(new UpdateManager(this));
Managers.AddManager(new EventManager(this));
#pragma warning disable CS0618
Managers.AddManager(Plugins);

View File

@@ -240,6 +240,7 @@ namespace Torch
_log.Info("Services initialized");
MySandboxGame.InitMultithreading();
MyVRage.Platform.System.OnThreadpoolInitialized();
// MyInitializer.InitCheckSum();
@@ -309,6 +310,7 @@ namespace Torch
_getVRagePluginList().Remove(_torch);
MyInitializer.InvokeAfterRun();
MyVRage.Done();
}
private void DoStart()

View File

@@ -151,7 +151,7 @@ namespace Torch.Views
valueControl = (FrameworkElement)Activator.CreateInstance(descriptor.EditorType);
valueControl.SetBinding(FrameworkElement.DataContextProperty, property.Name);
}
else if (property.GetSetMethod() == null && !(propertyType.IsGenericType && typeof(ICollection).IsAssignableFrom(propertyType.GetGenericTypeDefinition()))|| descriptor?.ReadOnly == true)
else if (property.GetSetMethod() == null && !(propertyType.IsGenericType && typeof(ICollection).IsAssignableFrom(propertyType.GetGenericTypeDefinition())))
{
valueControl = new TextBlock();
var binding = new Binding(property.Name)
@@ -234,7 +234,10 @@ namespace Torch.Views
}
else if (propertyType.IsPrimitive)
{
valueControl = new TextBox();
valueControl = new TextBox
{
IsReadOnly = descriptor?.ReadOnly == true
};
valueControl.SetBinding(TextBox.TextProperty, property.Name);
}
else if (propertyType == typeof(string))
@@ -244,6 +247,7 @@ namespace Torch.Views
tb.AcceptsReturn = true;
tb.AcceptsTab = true;
tb.SpellCheck.IsEnabled = true;
tb.IsReadOnly = descriptor?.ReadOnly == true;
tb.SetBinding(TextBox.TextProperty, property.Name);
valueControl = tb;
}

268
Torch/packages.lock.json Normal file
View File

@@ -0,0 +1,268 @@
{
"version": 1,
"dependencies": {
"net7.0-windows7.0": {
"ControlzEx": {
"type": "Direct",
"requested": "[5.0.2, )",
"resolved": "5.0.2",
"contentHash": "f724LoDJ36LxaLR62G4ek9ZAJI8BiiYRJJ04furC/qjXSeIwU0qmHFIe19xB1/FwxyZjevdFguEr9ZUjf3dZgw==",
"dependencies": {
"Microsoft.Xaml.Behaviors.Wpf": "1.1.31",
"System.Text.Json": "5.0.1"
}
},
"HarmonyX": {
"type": "Direct",
"requested": "[2.10.2-prerelease.1, )",
"resolved": "2.10.2-prerelease.1",
"contentHash": "5hbH0ENhQ+JV7tk63fQ2ab7MtplRHKJYH1JfIjG39rlltHNXxAcGJh05an+SQbVRV4EoP/+Qm9w9BrLc3RwRMA==",
"dependencies": {
"MonoModReorg.RuntimeDetour": "22.11.21-prerelease.2",
"System.Reflection.Emit": "4.7.0",
"System.Reflection.Emit.Lightweight": "4.7.0"
}
},
"InfoOf.Fody": {
"type": "Direct",
"requested": "[2.1.1, )",
"resolved": "2.1.1",
"contentHash": "o87i6Aab7fVKbiEbRySH/IY14BytH/I63Yv0G3KK4xcAsQa759RrFyLB9JhpJMilN99ioJHvYqybZNvpN6FGDQ==",
"dependencies": {
"Fody": "6.6.0"
}
},
"MahApps.Metro": {
"type": "Direct",
"requested": "[2.4.9, )",
"resolved": "2.4.9",
"contentHash": "eMTkg6TBnCwHzszw7CP+pxsBeB4ZMsJFiTJJoifUVBysRyEenzzR+TKQJuMvvKK6KzvLxwHmJsFhi9o5p4vxhQ==",
"dependencies": {
"ControlzEx": "[4.4.0, 6.0.0)"
}
},
"Microsoft.CodeAnalysis.Common": {
"type": "Direct",
"requested": "[4.4.0, )",
"resolved": "4.4.0",
"contentHash": "JfHupS/B7Jb5MZoYkFFABn3mux0wQgxi2D8F/rJYZeRBK2ZOyk7TjQ2Kq9rh6W/DCh0KNbbSbn5qoFar+ueHqw==",
"dependencies": {
"Microsoft.CodeAnalysis.Analyzers": "3.3.3",
"System.Collections.Immutable": "6.0.0",
"System.Memory": "4.5.5",
"System.Reflection.Metadata": "5.0.0",
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
"System.Text.Encoding.CodePages": "6.0.0",
"System.Threading.Tasks.Extensions": "4.5.4"
}
},
"Microsoft.CodeAnalysis.CSharp": {
"type": "Direct",
"requested": "[4.4.0, )",
"resolved": "4.4.0",
"contentHash": "eD2w0xHRoaqK07hjlOKGR9eLNy3nimiGNeCClNax1NDgS/+DBtBqCjXelOa+TNy99kIB3nHhUqDmr46nDXy/RQ==",
"dependencies": {
"Microsoft.CodeAnalysis.Common": "[4.4.0]"
}
},
"MonoModReorg.RuntimeDetour": {
"type": "Direct",
"requested": "[22.11.21-prerelease.2, )",
"resolved": "22.11.21-prerelease.2",
"contentHash": "Qv1h4rW03LrHwxwVuw5R6hbL8X78l8Lfnxe5tMlyVAe+AK0HnwsRzjsTwzFF57wxWUwq12NbLflkzV6T+hIhJw==",
"dependencies": {
"Mono.Cecil": "0.11.4",
"MonoModReorg.Backports": "22.11.21-prerelease.2",
"MonoModReorg.Core": "22.11.21-prerelease.2",
"MonoModReorg.ILHelpers": "22.11.21-prerelease.2",
"MonoModReorg.Utils": "22.11.21-prerelease.2"
}
},
"NLog": {
"type": "Direct",
"requested": "[5.1.0, )",
"resolved": "5.1.0",
"contentHash": "oW7ekrkRG9okpDMUcEglunWj8Qf2RY8qkgl+/chJoavzg3dbT13y32t19R54FKkmq80fKzw4ZekZkCrRGanKgQ=="
},
"PropertyChanged.Fody": {
"type": "Direct",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "6v+f9cI8YjnZH2WBHuOqWEAo8DFFNGFIdU8xD3AsL6fhV6Y8oAmVWd7XKk49t8DpeUBwhR/X+97+6Epvek0Y3A==",
"dependencies": {
"Fody": "6.6.4"
}
},
"protobuf-net": {
"type": "Direct",
"requested": "[3.1.26, )",
"resolved": "3.1.26",
"contentHash": "iy+VROYtWZEqDvkUjS6FfzKZNpWRoVGc5h0cupGQT/37Ox0LxPblRKLnw6V0RT1MPclLo8nZp7E2M0f7PNn/Tw==",
"dependencies": {
"protobuf-net.Core": "3.1.26"
}
},
"SpaceEngineersDedicated.ReferenceAssemblies": {
"type": "Direct",
"requested": "[1.201.13, )",
"resolved": "1.201.13",
"contentHash": "FRXuNLENsz5jGQvL0QkogAGsxEJyUQlXhvWHBWfZiHCnCrAWMD60nEis6yt0xCQpazszfMtHonbxz72XMxnFoQ==",
"dependencies": {
"protobuf-net": "1.0.0"
}
},
"System.ComponentModel.Annotations": {
"type": "Direct",
"requested": "[5.0.0, )",
"resolved": "5.0.0",
"contentHash": "dMkqfy2el8A8/I76n2Hi1oBFEbG1SfxD2l5nhwXV3XjlnOmwxJlQbYpJH4W51odnU9sARCSAgv7S3CyAFMkpYg=="
},
"Torch.SixLabors.ImageSharp": {
"type": "Direct",
"requested": "[1.0.0-beta6, )",
"resolved": "1.0.0-beta6",
"contentHash": "WJ7ocT79HgmuKi0+ltpvXTiMI80UcI3DeS8XSfYwJtTB1tcQws6zLPGuUwra6qe6qRrFfpABeDP3xvHV1rJgfg==",
"dependencies": {
"SixLabors.Core": "1.0.0-beta0007",
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
}
},
"Fody": {
"type": "Transitive",
"resolved": "6.6.4",
"contentHash": "vLZS+oa+ndUHYPlx/8n9bBTT3dHkCF0riml4paKq4D663+cZd47x1uagQo32D/gKFZ/sfmV1oqKaLmH0elxq4A=="
},
"JorgeSerrano.Json.JsonSnakeCaseNamingPolicy": {
"type": "Transitive",
"resolved": "0.9.0",
"contentHash": "xCqODS+wzpUXNtg4bMMvXG5PLbP0iTwRzRn2R+zWHKm83E6tbV2bCagawXp1EnZeNpd5OXpMxehulZWns8efzQ=="
},
"Microsoft.CodeAnalysis.Analyzers": {
"type": "Transitive",
"resolved": "3.3.3",
"contentHash": "j/rOZtLMVJjrfLRlAMckJLPW/1rze9MT1yfWqSIbUPGRu1m1P0fuo9PmqapwsmePfGB5PJrudQLvmUOAMF0DqQ=="
},
"Microsoft.Xaml.Behaviors.Wpf": {
"type": "Transitive",
"resolved": "1.1.31",
"contentHash": "LZpuf82ACZWldmfMuv3CTUMDh3o0xo0uHUaybR5HgqVLDBJJ9RZLykplQ/bTJd0/VDt3EhD4iDgUgbdIUAM+Kg=="
},
"Mono.Cecil": {
"type": "Transitive",
"resolved": "0.11.4",
"contentHash": "IC1h5g0NeJGHIUgzM1P82ld57knhP0IcQfrYITDPXlNpMYGUrsG5TxuaWTjaeqDNQMBDNZkB8L0rBnwsY6JHuQ=="
},
"MonoModReorg.Backports": {
"type": "Transitive",
"resolved": "22.11.21-prerelease.2",
"contentHash": "69T6jjA5nx29jLkdqtfXKlJ8sMqIlc6czNDTomy0rbM68W0xo2JRJBgsu2mroBuqx7nvUdX+zIU6k1edS/pPbw==",
"dependencies": {
"MonoModReorg.ILHelpers": "22.11.21-prerelease.2"
}
},
"MonoModReorg.Core": {
"type": "Transitive",
"resolved": "22.11.21-prerelease.2",
"contentHash": "gDoxu4aAF6TeOo8rsrj5prq2X36i12ch6NeRHu/Ct0H3qoPDHuEQ6JMJN/Eiy45YrLNEN7C5+Ku4BrNX4nwVQg==",
"dependencies": {
"Mono.Cecil": "0.11.4",
"MonoModReorg.Backports": "22.11.21-prerelease.2",
"MonoModReorg.ILHelpers": "22.11.21-prerelease.2",
"MonoModReorg.Utils": "22.11.21-prerelease.2"
}
},
"MonoModReorg.ILHelpers": {
"type": "Transitive",
"resolved": "22.11.21-prerelease.2",
"contentHash": "JtOKHJR4DEyq3HxmdEVXIxhqNQnu1KmjGFXuEQrNHoPbzi8Yr9465VKVXdsoAF0Lm8StdyJHQ03efjv3+OlonA=="
},
"MonoModReorg.Utils": {
"type": "Transitive",
"resolved": "22.11.21-prerelease.2",
"contentHash": "TX+vlgg2/x8rzEOqwiAy2qv61FjlJsr4u10WGTekCkulZVmmC+xxDmK+4Do9noXF/4RlgFN6sR3m9/W8KvJq3g==",
"dependencies": {
"Mono.Cecil": "0.11.4",
"MonoModReorg.Backports": "22.11.21-prerelease.2",
"MonoModReorg.ILHelpers": "22.11.21-prerelease.2"
}
},
"protobuf-net.Core": {
"type": "Transitive",
"resolved": "3.1.26",
"contentHash": "fuKoDWgAf5ju+ixbJoasVFhnUaT0oWUgrWh1AZ5D0Y5keKHpA93vQB5g6aQNtB4zgeQ4hGEeh0MY9bIbAUPgEw=="
},
"SemanticVersioning": {
"type": "Transitive",
"resolved": "2.0.2",
"contentHash": "4EQgYdNZ92SyaO7YFk6olVnebF5V+jrHyMUjvPq89tLeMo8NSfgDF+6Zwq/lgh9j/0yfQp9Lkm0ZA0rUATCZFA=="
},
"SixLabors.Core": {
"type": "Transitive",
"resolved": "1.0.0-beta0007",
"contentHash": "s9aPl6yxwcvoKRD0u0zjkCISZCCifbUi9/XVFjdvlx5Pt7vRYmGV0anq1EEftUjIEHbEu5aNBipbUSBIV2CE7w==",
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
}
},
"System.Collections.Immutable": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "l4zZJ1WU2hqpQQHXz1rvC3etVZN+2DLmQMO79FhOTZHMn8tDRr+WU287sbomD0BETlmKDn0ygUgVy9k5xkkJdA==",
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
},
"System.Memory": {
"type": "Transitive",
"resolved": "4.5.5",
"contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw=="
},
"System.Reflection.Emit": {
"type": "Transitive",
"resolved": "4.7.0",
"contentHash": "VR4kk8XLKebQ4MZuKuIni/7oh+QGFmZW3qORd1GvBq/8026OpW501SzT/oypwiQl4TvT8ErnReh/NzY9u+C6wQ=="
},
"System.Reflection.Emit.Lightweight": {
"type": "Transitive",
"resolved": "4.7.0",
"contentHash": "a4OLB4IITxAXJeV74MDx49Oq2+PsF6Sml54XAFv+2RyWwtDBcabzoxiiJRhdhx+gaohLh4hEGCLQyBozXoQPqA=="
},
"System.Reflection.Metadata": {
"type": "Transitive",
"resolved": "5.0.0",
"contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ=="
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
},
"System.Text.Encoding.CodePages": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "ZFCILZuOvtKPauZ/j/swhvw68ZRi9ATCfvGbk1QfydmcXBkIWecWKn/250UH7rahZ5OoDBaiAudJtPvLwzw85A==",
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
},
"System.Text.Json": {
"type": "Transitive",
"resolved": "5.0.1",
"contentHash": "/UM3UK1dXKl8Ybysg/21gM4S8DJgkR+yLU8JwqCVbuNqQNImelntgYFAN5QxR8sJJ1kMx//hOUdf0lltosi8cQ=="
},
"System.Threading.Tasks.Extensions": {
"type": "Transitive",
"resolved": "4.5.4",
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg=="
},
"torch.api": {
"type": "Project",
"dependencies": {
"JorgeSerrano.Json.JsonSnakeCaseNamingPolicy": "[0.9.0, )",
"NLog": "[5.1.0, )",
"SemanticVersioning": "[2.0.2, )"
}
}
}
}
}