Add support for mod thumbnails
This commit is contained in:
@@ -1,12 +1,15 @@
|
|||||||
using System.Collections.Immutable;
|
using CringePlugins.Abstractions;
|
||||||
using System.Net.Http.Json;
|
using CringePlugins.Services;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text.Json;
|
|
||||||
using CringePlugins.Abstractions;
|
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Plugin.ClientModLoader.Utils;
|
using Plugin.ClientModLoader.Utils;
|
||||||
|
using Sandbox;
|
||||||
using Steamworks;
|
using Steamworks;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using System.Text.Json;
|
||||||
using VRage;
|
using VRage;
|
||||||
|
using VRage.FileSystem;
|
||||||
using static ImGuiNET.ImGui;
|
using static ImGuiNET.ImGui;
|
||||||
|
|
||||||
namespace Plugin.ClientModLoader;
|
namespace Plugin.ClientModLoader;
|
||||||
@@ -15,6 +18,7 @@ public class ModListComponent : IRenderComponent
|
|||||||
{
|
{
|
||||||
private readonly string _configPath;
|
private readonly string _configPath;
|
||||||
private readonly JsonSerializerOptions _options = new(JsonSerializerDefaults.Web);
|
private readonly JsonSerializerOptions _options = new(JsonSerializerDefaults.Web);
|
||||||
|
private readonly IImGuiImageService _imageService = MySandboxGame.Services.GetRequiredService<IImGuiImageService>();
|
||||||
|
|
||||||
private bool _visible;
|
private bool _visible;
|
||||||
private string _searchQuery = string.Empty;
|
private string _searchQuery = string.Empty;
|
||||||
@@ -167,6 +171,25 @@ public class ModListComponent : IRenderComponent
|
|||||||
{
|
{
|
||||||
Text(_selected.Name);
|
Text(_selected.Name);
|
||||||
Separator();
|
Separator();
|
||||||
|
|
||||||
|
if (_selected.ThubmnailTask.IsCompletedSuccessfully && _selected.ThubmnailTask.Result is { } thumbnail)
|
||||||
|
{
|
||||||
|
var img = _imageService.GetFromPath(thumbnail);
|
||||||
|
|
||||||
|
var size = img.Size;
|
||||||
|
|
||||||
|
if (size.X > 256 || size.Y > 256)
|
||||||
|
{
|
||||||
|
//scale down to fit
|
||||||
|
var scale = Math.Min(256f / size.X, 256f / size.Y);
|
||||||
|
size = new(size.X * scale, size.Y * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
Image(img, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (BeginTabBar("##ModViewTabs"))
|
if (BeginTabBar("##ModViewTabs"))
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(_selected.Description) && BeginTabItem("Description"))
|
if (!string.IsNullOrEmpty(_selected.Description) && BeginTabItem("Description"))
|
||||||
@@ -277,7 +300,7 @@ public class ModListComponent : IRenderComponent
|
|||||||
: item.Tooltip,
|
: item.Tooltip,
|
||||||
item.Description,
|
item.Description,
|
||||||
description, $"https://steamcommunity.com/sharedfiles/filedetails/?id={details.m_nPublishedFileId.m_PublishedFileId}",
|
description, $"https://steamcommunity.com/sharedfiles/filedetails/?id={details.m_nPublishedFileId.m_PublishedFileId}",
|
||||||
details.m_rtimeCreated, details.m_rtimeUpdated, item.Author));
|
details.m_rtimeCreated, details.m_rtimeUpdated, item.Author, GetThumbnailImageAsync(details.m_hPreviewFile)));
|
||||||
}
|
}
|
||||||
|
|
||||||
_modList = list;
|
_modList = list;
|
||||||
@@ -288,6 +311,36 @@ public class ModListComponent : IRenderComponent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task<string?> GetThumbnailImageAsync(UGCHandle_t handle)
|
||||||
|
{
|
||||||
|
var dir = MyFileSystem.WorkshopBrowserPath;
|
||||||
|
|
||||||
|
if (!Directory.Exists(dir))
|
||||||
|
Directory.CreateDirectory(dir);
|
||||||
|
|
||||||
|
var path = Path.Join(dir, $"{handle.m_UGCHandle}.png");
|
||||||
|
|
||||||
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
if (File.GetLastWriteTimeUtc(path) + TimeSpan.FromMinutes(10) < DateTime.UtcNow)
|
||||||
|
File.Delete(path);
|
||||||
|
else
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
var call = SteamRemoteStorage.UGCDownloadToLocation(handle, path, 0);
|
||||||
|
|
||||||
|
var result = await CallResultAsync<RemoteStorageDownloadUGCResult_t>.Create(call);
|
||||||
|
|
||||||
|
if (result.m_eResult != EResult.k_EResultOK || result.m_hFile != handle || !File.Exists(path))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
File.SetLastWriteTimeUtc(path, DateTime.UtcNow);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
private static string MapLanguage(MyLanguagesEnum lang) =>
|
private static string MapLanguage(MyLanguagesEnum lang) =>
|
||||||
lang switch
|
lang switch
|
||||||
{
|
{
|
||||||
@@ -314,7 +367,7 @@ public class ModListComponent : IRenderComponent
|
|||||||
_ => "english",
|
_ => "english",
|
||||||
};
|
};
|
||||||
|
|
||||||
private record ModItem(ulong Id, string Name, string Summary, string? Description, string ModDescription, string Url, long Created, long Updated, string Author);
|
private record ModItem(ulong Id, string Name, string Summary, string? Description, string ModDescription, string Url, long Created, long Updated, string Author, Task<string?> ThubmnailTask);
|
||||||
|
|
||||||
private record WhitelistItem(string Id, string? Tooltip, string Author, string? Description);
|
private record WhitelistItem(string Id, string? Tooltip, string Author, string? Description);
|
||||||
|
|
||||||
|
@@ -20,11 +20,21 @@
|
|||||||
<PackageProjectUrl>https://git.zznty.ru/PvE/ClientModLoader</PackageProjectUrl>
|
<PackageProjectUrl>https://git.zznty.ru/PvE/ClientModLoader</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://git.zznty.ru/PvE/ClientModLoader</RepositoryUrl>
|
<RepositoryUrl>https://git.zznty.ru/PvE/ClientModLoader</RepositoryUrl>
|
||||||
<RepositoryType>git</RepositoryType>
|
<RepositoryType>git</RepositoryType>
|
||||||
|
<LangVersion>preview</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CringePlugins" Version="*" ExcludeAssets="runtime; native"/>
|
<PackageReference Include="CringePlugins" Version="*" ExcludeAssets="runtime; native"/>
|
||||||
<PackageReference Include="Steamworks.NET" Version="[20.1.0]" ExcludeAssets="runtime; native" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="CopyFiles" AfterTargets="PostBuildEvent">
|
||||||
|
<PropertyGroup>
|
||||||
|
<AppdataPath>$([System.Environment]::GetFolderPath(SpecialFolder.ApplicationData))</AppdataPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<OutputFiles Include="$(OutputPath)\*" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Copy SourceFiles="@(OutputFiles)" DestinationFolder="$(AppdataPath)\CringeLauncher\plugins\$(ProjectName)" OverwriteReadOnlyFiles="true" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@@ -5,34 +5,36 @@
|
|||||||
"CringePlugins": {
|
"CringePlugins": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[*, )",
|
"requested": "[*, )",
|
||||||
"resolved": "0.1.57",
|
"resolved": "0.1.82",
|
||||||
"contentHash": "PR3GGF1qvBMdre3f7CgPBKoHk0/Y8MXFz/Kp9SkAzmJmTzARct0MxFEz+nhUYfoNAma02L5KXuko5QYv3lWmQA==",
|
"contentHash": "PKsCEgA2OoUYElkVUu36ZQ63+ttDXcQmts6r6Im5m/EgbzvRuMVV/n+ew2ZUdJbA3jCFs9wgWDKGTmbfArpddA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ImGui.NET.DirectX": "1.91.0.1",
|
"ImGui.NET.DirectX": "1.91.0.1",
|
||||||
|
"JsonSchema.Net.Generation": "5.0.2",
|
||||||
"Lib.Harmony.Thin": "2.3.4-torch",
|
"Lib.Harmony.Thin": "2.3.4-torch",
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.5",
|
||||||
"NLog": "5.4.0",
|
"NLog": "5.4.0",
|
||||||
"NuGet": "0.1.57",
|
"NuGet": "0.1.82",
|
||||||
"SharedCringe": "0.1.57",
|
"SharedCringe": "0.1.82",
|
||||||
"SpaceEngineersDedicated.ReferenceAssemblies": "1.206.30",
|
"SpaceEngineersDedicated.ReferenceAssemblies": "1.206.32",
|
||||||
|
"Steamworks.NET": "[20.1.0]",
|
||||||
"dnlib": "4.4.0"
|
"dnlib": "4.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Steamworks.NET": {
|
|
||||||
"type": "Direct",
|
|
||||||
"requested": "[20.1.0, 20.1.0]",
|
|
||||||
"resolved": "20.1.0",
|
|
||||||
"contentHash": "+GntwnyJ5tCNvUIaQxv2+ehDvZJzGUqlSB5xRBk1hTj1qqBJ6s4vK/OfGD/jae7aTmXiGSm8wpJORosNtQevJQ=="
|
|
||||||
},
|
|
||||||
"CringeBootstrap.Abstractions": {
|
"CringeBootstrap.Abstractions": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "0.1.57",
|
"resolved": "0.1.82",
|
||||||
"contentHash": "0Otka7VBWH8xhkmJ7OsBe0zoZyT8N9W6Bl1ZasymLW5rVkcEwspJt7iZ75mPQOe4qo9UuvnZJdV/fMIYXK2yEg=="
|
"contentHash": "9cN/QbZhF46mdqlUfJgKFE0WIU72kndzAaOfarqmCZ5LOvPRjGLTyEOWmDub9vKvqOKII4txOxIURj7GnPk/0g=="
|
||||||
},
|
},
|
||||||
"dnlib": {
|
"dnlib": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.4.0",
|
"resolved": "4.4.0",
|
||||||
"contentHash": "cKHI720q+zfEEvzklWVGt6B0TH3AibAyJbpUJl4U6KvTP13tycfnqJpkGHRZ/oQ45BTIoIxIwltHIJVDN+iCqQ=="
|
"contentHash": "cKHI720q+zfEEvzklWVGt6B0TH3AibAyJbpUJl4U6KvTP13tycfnqJpkGHRZ/oQ45BTIoIxIwltHIJVDN+iCqQ=="
|
||||||
},
|
},
|
||||||
|
"Humanizer.Core": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "2.14.1",
|
||||||
|
"contentHash": "lQKvtaTDOXnoVJ20ibTuSIOf2i0uO0MPbDhd1jm238I+U/2ZnRENj0cktKZhtchBMtCUSRQ5v4xBCUbKNmyVMw=="
|
||||||
|
},
|
||||||
"ImGui.NET.DirectX": {
|
"ImGui.NET.DirectX": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "1.91.0.1",
|
"resolved": "1.91.0.1",
|
||||||
@@ -43,6 +45,37 @@
|
|||||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Json.More.Net": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "2.1.1",
|
||||||
|
"contentHash": "ZXAKl2VsdnIZeUo1PFII3Oi1m1L4YQjEyDjygHfHln5vgsjgIo749X6xWkv7qFYp8RROES+vOEfDcvvoVgs8kA=="
|
||||||
|
},
|
||||||
|
"JsonPointer.Net": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "5.3.1",
|
||||||
|
"contentHash": "3e2OJjU0OaE26XC/klgxbJuXvteFWTDJIJv0ITYWcJEoskq7jzUwPSC1s0iz4wPPQnfN7vwwFmg2gJfwRAPwgw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Humanizer.Core": "2.14.1",
|
||||||
|
"Json.More.Net": "2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"JsonSchema.Net": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "7.3.4",
|
||||||
|
"contentHash": "7GggWrdzKrtGWETRn3dcMnmuLSyWaDkBK94TK80LEHQEVz4bmsQc7FYO7qL40RDdZU2YPz5d98aT9lW5OYExuA==",
|
||||||
|
"dependencies": {
|
||||||
|
"JsonPointer.Net": "5.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"JsonSchema.Net.Generation": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "5.0.2",
|
||||||
|
"contentHash": "+khIPgLqOyFOWjgHSzXMjJijwbQb85/cFRf4NwTaV6QBoGM9IT8LeLCnmwazruwKsx16HB1UFX3mslUujfjVpg==",
|
||||||
|
"dependencies": {
|
||||||
|
"Humanizer.Core": "2.14.1",
|
||||||
|
"JsonSchema.Net": "7.3.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Lib.Harmony.Thin": {
|
"Lib.Harmony.Thin": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "2.3.4-torch",
|
"resolved": "2.3.4-torch",
|
||||||
@@ -57,6 +90,11 @@
|
|||||||
"resolved": "6.0.0",
|
"resolved": "6.0.0",
|
||||||
"contentHash": "UcSjPsst+DfAdJGVDsu346FX0ci0ah+lw3WRtn18NUwEqRt70HaOQ7lI72vy3+1LxtqI3T5GWwV39rQSrCzAeg=="
|
"contentHash": "UcSjPsst+DfAdJGVDsu346FX0ci0ah+lw3WRtn18NUwEqRt70HaOQ7lI72vy3+1LxtqI3T5GWwV39rQSrCzAeg=="
|
||||||
},
|
},
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "9.0.5",
|
||||||
|
"contentHash": "cjnRtsEAzU73aN6W7vkWy8Phj5t3Xm78HSqgrbh/O4Q9SK/yN73wZVa21QQY6amSLQRQ/M8N+koGnY6PuvKQsw=="
|
||||||
|
},
|
||||||
"Mono.Cecil": {
|
"Mono.Cecil": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "0.11.5",
|
"resolved": "0.11.5",
|
||||||
@@ -103,8 +141,8 @@
|
|||||||
},
|
},
|
||||||
"NuGet": {
|
"NuGet": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "0.1.57",
|
"resolved": "0.1.82",
|
||||||
"contentHash": "7e395oq1nXq61w3G/3dpMZo3XieMynWjgUBZl9B4jbo+08XCu0bPfkAsF793/9GKdVvfflXT0eHVfNziAfnbKg==",
|
"contentHash": "BjixWsaCI+xKpBlUmA8qIsGXQpy9owCC3C93qviKsNCZPjQ5ej+m/DBw5Rarr0InybyBSTHHNVLwDIUtMI5+Aw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"NuGet.Frameworks": "6.13.2",
|
"NuGet.Frameworks": "6.13.2",
|
||||||
"NuGet.Versioning": "6.13.2",
|
"NuGet.Versioning": "6.13.2",
|
||||||
@@ -128,12 +166,12 @@
|
|||||||
},
|
},
|
||||||
"SharedCringe": {
|
"SharedCringe": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "0.1.57",
|
"resolved": "0.1.82",
|
||||||
"contentHash": "Vc6JmpW8R7nVIFz56ItR2uo3kfdc3DQh+ctTw7dqrQgzwUiC0s6j7OOXwSq2nvXBtXtym5E/3Gc3vKsUdhvKPw==",
|
"contentHash": "0t1izvWzkadqvbNJ8/ahmItcgW9ZeNkE+hMQrxYcrUNj7pEd2ZIOdOXdIrsKfDIB/H2Mkw2Zs/rEbIZKc6rvtw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"CringeBootstrap.Abstractions": "0.1.57",
|
"CringeBootstrap.Abstractions": "0.1.82",
|
||||||
"NLog": "5.4.0",
|
"NLog": "5.4.0",
|
||||||
"SpaceEngineersDedicated.ReferenceAssemblies": "1.206.30"
|
"SpaceEngineersDedicated.ReferenceAssemblies": "1.206.32"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"SharpDX": {
|
"SharpDX": {
|
||||||
@@ -143,13 +181,18 @@
|
|||||||
},
|
},
|
||||||
"SpaceEngineersDedicated.ReferenceAssemblies": {
|
"SpaceEngineersDedicated.ReferenceAssemblies": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "1.206.30",
|
"resolved": "1.206.32",
|
||||||
"contentHash": "xk/EgMhbG7oT4fPzW1DcFT8tYkxJFPK3+j+t4vms9a/wz8cCmszbilA2Y+JWIpmauUDcfovX8eqAOKlgz3dpcg==",
|
"contentHash": "uFhkUUxmumct/turcfMeM2f+jJHxuiB6jAE4JMGa/AOFKCsWIr+ZWTX9hW2muEoJpUNKrzCbGrxH8ssaJUZpig==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"SharpDX": "4.2.0-keen-cringe",
|
"SharpDX": "4.2.0-keen-cringe",
|
||||||
"protobuf-net": "1.0.0"
|
"protobuf-net": "1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Steamworks.NET": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "20.1.0",
|
||||||
|
"contentHash": "+GntwnyJ5tCNvUIaQxv2+ehDvZJzGUqlSB5xRBk1hTj1qqBJ6s4vK/OfGD/jae7aTmXiGSm8wpJORosNtQevJQ=="
|
||||||
|
},
|
||||||
"System.Buffers": {
|
"System.Buffers": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.5.1",
|
"resolved": "4.5.1",
|
||||||
@@ -180,12 +223,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"net9.0-windows7.0/win-x64": {
|
"net9.0-windows7.0/win-x64": {
|
||||||
"Steamworks.NET": {
|
|
||||||
"type": "Direct",
|
|
||||||
"requested": "[20.1.0, 20.1.0]",
|
|
||||||
"resolved": "20.1.0",
|
|
||||||
"contentHash": "+GntwnyJ5tCNvUIaQxv2+ehDvZJzGUqlSB5xRBk1hTj1qqBJ6s4vK/OfGD/jae7aTmXiGSm8wpJORosNtQevJQ=="
|
|
||||||
},
|
|
||||||
"ImGui.NET.DirectX": {
|
"ImGui.NET.DirectX": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "1.91.0.1",
|
"resolved": "1.91.0.1",
|
||||||
@@ -195,6 +232,11 @@
|
|||||||
"System.Numerics.Vectors": "4.5.0",
|
"System.Numerics.Vectors": "4.5.0",
|
||||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"Steamworks.NET": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "20.1.0",
|
||||||
|
"contentHash": "+GntwnyJ5tCNvUIaQxv2+ehDvZJzGUqlSB5xRBk1hTj1qqBJ6s4vK/OfGD/jae7aTmXiGSm8wpJORosNtQevJQ=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"sdk": {
|
"sdk": {
|
||||||
"version": "9.0.0",
|
"version": "10.0.0",
|
||||||
"rollForward": "latestFeature",
|
"rollForward": "latestFeature",
|
||||||
"allowPrerelease": false
|
"allowPrerelease": true
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user