Skip to content

Commit f5131f0

Browse files
committed
chore(release): merge dev into main for v0.4.35
2 parents d401003 + 12f5731 commit f5131f0

38 files changed

Lines changed: 3058 additions & 106 deletions

Compat/ContentModLoadOrderInventory.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ private static IReadOnlyList<ContentModInventoryEntry> BuildRelevantInventory(
5959
entry.Version,
6060
entry.DisplayName,
6161
entry.Source.ToString(),
62+
entry.WorkshopItemId,
6263
entry.IsEnabled,
6364
entry.AffectsGameplay,
6465
relevantDependencyIds.Contains(entry.Id)))
@@ -230,6 +231,7 @@ internal static bool IsDependencyLibraryId(string id)
230231
version,
231232
displayName,
232233
mod.modSource,
234+
Sts2ModManagerCompat.TryGetWorkshopItemId(mod),
233235
isEnabled,
234236
manifest?.affectsGameplay ?? true,
235237
ReadDependencyIds(manifest),
@@ -268,6 +270,7 @@ internal sealed record CurrentModEntry(
268270
string Version,
269271
string DisplayName,
270272
ModSource Source,
273+
ulong? WorkshopItemId,
271274
bool IsEnabled,
272275
bool AffectsGameplay,
273276
IReadOnlyList<string> Dependencies,
@@ -291,6 +294,7 @@ internal sealed record ContentModInventoryEntry(
291294
string Version,
292295
string Name,
293296
string Source,
297+
ulong? WorkshopItemId,
294298
bool IsEnabled,
295299
bool AffectsGameplay,
296300
bool IsDependency);

Compat/RitsuModManager.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,15 @@ public enum RitsuModLoadState
156156
public sealed record RitsuModInfo(
157157
string Id,
158158
string Name,
159+
string? Author,
159160
string? Version,
160161
RitsuModLoadState State,
161162
RitsuModSource Source,
162163
bool AffectsGameplay,
163164
string? AssemblyName,
164165
string? AssemblyVersion,
165-
IReadOnlyList<LocString> Errors)
166+
IReadOnlyList<LocString> Errors,
167+
ulong? WorkshopItemId = null)
166168
{
167169
/// <summary>
168170
/// True when the mod is either pending load or already loaded in this session.

Compat/Sts2ModManagerCompat.cs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Reflection;
22
using MegaCrit.Sts2.Core.Localization;
33
using MegaCrit.Sts2.Core.Modding;
4+
using STS2RitsuLib.Platform.Steam;
45

56
namespace STS2RitsuLib.Compat
67
{
@@ -19,6 +20,7 @@ internal static class Sts2ModManagerCompat
1920
private static readonly Func<Mod, Assembly?> ReadAssembly = CreateModAssemblyAccessor();
2021
private static readonly Func<Mod, IReadOnlyList<LocString>> ReadErrors = CreateModErrorsAccessor();
2122
private static readonly Func<Mod, string> ReadSource = CreateModSourceAccessor();
23+
private static readonly Func<Mod, string?> ReadPath = CreateModPathAccessor();
2224
private static readonly Func<Mod, int, string> ReadLoadState = CreateLoadStateAccessor();
2325

2426
private static readonly Func<ModManifest, string?> ReadManifestId =
@@ -27,6 +29,9 @@ internal static class Sts2ModManagerCompat
2729
private static readonly Func<ModManifest, string?> ReadManifestName =
2830
CreateManifestStringAccessor("name", static manifest => manifest.name);
2931

32+
private static readonly Func<ModManifest, string?> ReadManifestAuthor =
33+
CreateManifestStringAccessor("author", static manifest => manifest.author);
34+
3035
private static readonly Func<ModManifest, string?> ReadManifestVersion =
3136
CreateManifestStringAccessor("version", static manifest => manifest.version);
3237

@@ -134,6 +139,28 @@ internal static IReadOnlyList<RitsuModInfo> BuildModInfos(string? modId = null,
134139
.ToArray();
135140
}
136141

142+
internal static ulong? TryGetWorkshopItemId(Mod mod)
143+
{
144+
ArgumentNullException.ThrowIfNull(mod);
145+
try
146+
{
147+
if (SteamWorkshopInstallSource.TryGetWorkshopItemIdFromPath(ReadPath(mod), out var pathItemId))
148+
return pathItemId;
149+
150+
var assembly = ReadAssembly(mod);
151+
if (assembly != null &&
152+
SteamWorkshopInstallSource.TryGetWorkshopItemIdFromAssembly(assembly, out var assemblyItemId))
153+
return assemblyItemId;
154+
}
155+
catch (Exception ex)
156+
{
157+
RitsuLibFramework.Logger.Warn(
158+
$"[Compat] Failed to inspect Workshop item id for a registered mod: {ex.Message}");
159+
}
160+
161+
return null;
162+
}
163+
137164
internal static bool TryGetBestModInfo(string modId, RitsuModSource? source, out RitsuModInfo? info)
138165
{
139166
info = BuildModInfos(modId, source).FirstOrDefault();
@@ -211,13 +238,15 @@ internal static bool TryGetBestModInfo(string modId, RitsuModSource? source, out
211238
return new(
212239
id,
213240
name,
241+
manifest == null ? null : ReadManifestAuthor(manifest),
214242
manifest == null ? null : ReadManifestVersion(manifest),
215243
ParseLoadState(ReadLoadState(mod, errors.Count)),
216244
ParseSource(ReadSource(mod)),
217245
manifest == null || ReadManifestAffectsGameplay(manifest),
218246
assemblyName?.Name,
219247
assemblyName?.Version?.ToString(),
220-
errors);
248+
errors,
249+
TryGetWorkshopItemId(mod));
221250
}
222251
catch (Exception ex)
223252
{
@@ -318,6 +347,15 @@ private static Func<Mod, string> CreateModSourceAccessor()
318347
return mod => getter?.Invoke(mod)?.ToString() ?? "None";
319348
}
320349

350+
private static Func<Mod, string?> CreateModPathAccessor()
351+
{
352+
if (typeof(Mod).GetField("path", InstanceMemberFlags) != null)
353+
return static mod => mod.path;
354+
355+
var getter = CreateUntypedMemberGetter(typeof(Mod), "path");
356+
return mod => getter?.Invoke(mod) as string;
357+
}
358+
321359
private static Func<Mod, int, string> CreateLoadStateAccessor()
322360
{
323361
if (typeof(Mod).GetField("state", InstanceMemberFlags) != null)

Const.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,20 @@ public static class Const
2222
/// Assembly / manifest version string.
2323
/// 程序集/清单版本字符串。
2424
/// </summary>
25-
public const string Version = "0.4.34";
25+
public const string Version = "0.4.35";
2626

2727
/// <summary>
2828
/// Steam Workshop item id for the official RitsuLib release.
2929
/// 官方 RitsuLib 发布使用的 Steam Workshop item id。
3030
/// </summary>
3131
public const ulong SteamWorkshopItemId = 3747602295;
3232

33+
/// <summary>
34+
/// Steam app id for Slay the Spire 2.
35+
/// Slay the Spire 2 的 Steam app id。
36+
/// </summary>
37+
public const uint Sts2SteamAppId = 2868840;
38+
3339
/// <summary>
3440
/// Root key for RitsuLib JSON settings under the mod’s user folder.
3541
/// mod 用户文件夹下 RitsuLib JSON 设置的根键。

Content/ContentCatalogEntry.cs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,37 @@
11
namespace STS2RitsuLib.Content
22
{
33
/// <summary>
4-
/// <para xml:lang="en">One mod content catalog: global type set or act-scoped registrations, warm hooks, and merge mode.</para>
5-
/// <para xml:lang="zh-CN">一条 mod 内容目录:全局类型集或 act 作用域注册、预热钩子与合并模式。</para>
4+
/// <para xml:lang="en">
5+
/// One mod content catalog: global type set or act-scoped registrations, warm hooks, and merge
6+
/// mode.
7+
/// </para>
8+
/// <para xml:lang="zh-CN">一条 mod 内容目录:全局类型集或 act 作用域注册、预热钩子与合并模式。</para>
69
/// </summary>
710
internal sealed class ContentCatalogEntry
811
{
912
internal required ContentCatalogId Id { get; init; }
1013

1114
/// <summary>
12-
/// <para xml:lang="en">Registered types for global getters.</para>
13-
/// <para xml:lang="zh-CN">全局 getter 的已注册类型。</para>
15+
/// <para xml:lang="en">Registered types for global getters.</para>
16+
/// <para xml:lang="zh-CN">全局 getter 的已注册类型。</para>
1417
/// </summary>
1518
internal Func<IEnumerable<Type>>? GlobalTypes { get; init; }
1619

1720
/// <summary>
18-
/// <para xml:lang="en">Act type to registered model types.</para>
19-
/// <para xml:lang="zh-CN">Act 类型到已注册模型类型的映射。</para>
21+
/// <para xml:lang="en">Act type to registered model types.</para>
22+
/// <para xml:lang="zh-CN">Act 类型到已注册模型类型的映射。</para>
2023
/// </summary>
2124
internal Func<Dictionary<Type, HashSet<Type>>>? ScopedRegistry { get; init; }
2225

2326
/// <summary>
24-
/// <para xml:lang="en">Warm hook: global types to resolved model array.</para>
25-
/// <para xml:lang="zh-CN">预热钩子:全局类型到已解析模型数组。</para>
27+
/// <para xml:lang="en">Warm hook: global types to resolved model array.</para>
28+
/// <para xml:lang="zh-CN">预热钩子:全局类型到已解析模型数组。</para>
2629
/// </summary>
2730
internal Func<IEnumerable<Type>, object>? WarmGlobal { get; init; }
2831

2932
/// <summary>
30-
/// <para xml:lang="en">Warm hook: scoped registry to per-act arrays.</para>
31-
/// <para xml:lang="zh-CN">预热钩子:作用域注册表到各 act 数组。</para>
33+
/// <para xml:lang="en">Warm hook: scoped registry to per-act arrays.</para>
34+
/// <para xml:lang="zh-CN">预热钩子:作用域注册表到各 act 数组。</para>
3235
/// </summary>
3336
internal Func<Dictionary<Type, HashSet<Type>>, Dictionary<Type, object>>? WarmScoped { get; init; }
3437

Content/ContentCatalogId.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
namespace STS2RitsuLib.Content
22
{
33
/// <summary>
4-
/// <para xml:lang="en">Keys for <see cref="ContentCatalogEntry" /> rows wired into patched <see cref="MegaCrit.Sts2.Core.Models.ModelDb" /> getters.</para>
5-
/// <para xml:lang="zh-CN">接入 patched <see cref="MegaCrit.Sts2.Core.Models.ModelDb" /> getter 的 <see cref="ContentCatalogEntry" /> 行键。</para>
4+
/// <para xml:lang="en">
5+
/// Keys for <see cref="ContentCatalogEntry" /> rows wired into patched
6+
/// <see cref="MegaCrit.Sts2.Core.Models.ModelDb" /> getters.
7+
/// </para>
8+
/// <para xml:lang="zh-CN">
9+
/// 接入 patched <see cref="MegaCrit.Sts2.Core.Models.ModelDb" /> getter 的
10+
/// <see cref="ContentCatalogEntry" /> 行键。
11+
/// </para>
612
/// </summary>
713
internal enum ContentCatalogId
814
{

Content/ContentMergeMode.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
namespace STS2RitsuLib.Content
22
{
33
/// <summary>
4-
/// <para xml:lang="en">How patched <see cref="MegaCrit.Sts2.Core.Models.ModelDb" /> getter postfixes merge vanilla output with mod models.</para>
5-
/// <para xml:lang="zh-CN">patched <see cref="MegaCrit.Sts2.Core.Models.ModelDb" /> getter postfix 如何合并原版输出与 mod 模型。</para>
4+
/// <para xml:lang="en">
5+
/// How patched <see cref="MegaCrit.Sts2.Core.Models.ModelDb" /> getter postfixes merge vanilla
6+
/// output with mod models.
7+
/// </para>
8+
/// <para xml:lang="zh-CN">patched <see cref="MegaCrit.Sts2.Core.Models.ModelDb" /> getter postfix 如何合并原版输出与 mod 模型。</para>
69
/// </summary>
710
internal enum ContentMergeMode
811
{
912
/// <summary>
10-
/// <para xml:lang="en">Vanilla first, then mod; first <see cref="MegaCrit.Sts2.Core.Models.AbstractModel.Id" /> wins; materialize as array.</para>
11-
/// <para xml:lang="zh-CN">原版在前、mod 在后;首个 <see cref="MegaCrit.Sts2.Core.Models.AbstractModel.Id" /> 胜出;物化为数组。</para>
13+
/// <para xml:lang="en">
14+
/// Vanilla first, then mod; first <see cref="MegaCrit.Sts2.Core.Models.AbstractModel.Id" /> wins;
15+
/// materialize as array.
16+
/// </para>
17+
/// <para xml:lang="zh-CN">原版在前、mod 在后;首个 <see cref="MegaCrit.Sts2.Core.Models.AbstractModel.Id" /> 胜出;物化为数组。</para>
1218
/// </summary>
1319
AppendDistinctById = 0,
1420

1521
/// <summary>
16-
/// <para xml:lang="en">Skip materialization when mod is empty; otherwise union by id into a list.</para>
17-
/// <para xml:lang="zh-CN">mod 为空时不物化 vanilla;否则按 id 合并为列表。</para>
22+
/// <para xml:lang="en">Skip materialization when mod is empty; otherwise union by id into a list.</para>
23+
/// <para xml:lang="zh-CN">mod 为空时不物化 vanilla;否则按 id 合并为列表。</para>
1824
/// </summary>
1925
MergeDistinctById = 1,
2026
}

Content/ModContentRegistry.ContentMerging.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@ namespace STS2RitsuLib.Content
55
public sealed partial class ModContentRegistry
66
{
77
/// <summary>
8-
/// <para xml:lang="en">Merges vanilla getter output with a global catalog row via <see cref="ResolvedModelCache" /> and <see cref="ContentMergeStrategies" />.</para>
9-
/// <para xml:lang="zh-CN">通过 <see cref="ResolvedModelCache" /> 与 <see cref="ContentMergeStrategies" /> 将原版 getter 输出与全局 catalog 行合并。</para>
8+
/// <para xml:lang="en">
9+
/// Merges vanilla getter output with a global catalog row via <see cref="ResolvedModelCache" />
10+
/// and <see cref="ContentMergeStrategies" />.
11+
/// </para>
12+
/// <para xml:lang="zh-CN">
13+
/// 通过 <see cref="ResolvedModelCache" /> 与 <see cref="ContentMergeStrategies" /> 将原版 getter
14+
/// 输出与全局 catalog 行合并。
15+
/// </para>
1016
/// </summary>
1117
internal static IEnumerable<TModel> MergeGlobalCatalog<TModel>(
1218
ContentCatalogId catalogId,
@@ -19,8 +25,8 @@ internal static IEnumerable<TModel> MergeGlobalCatalog<TModel>(
1925
}
2026

2127
/// <summary>
22-
/// <para xml:lang="en">Merges vanilla getter output with an act-scoped catalog row.</para>
23-
/// <para xml:lang="zh-CN">将原版 getter 输出与 act 作用域 catalog 行合并。</para>
28+
/// <para xml:lang="en">Merges vanilla getter output with an act-scoped catalog row.</para>
29+
/// <para xml:lang="zh-CN">将原版 getter 输出与 act 作用域 catalog 行合并。</para>
2430
/// </summary>
2531
internal static IEnumerable<TModel> MergeScopedCatalog<TModel>(
2632
ContentCatalogId catalogId,
@@ -34,8 +40,8 @@ internal static IEnumerable<TModel> MergeScopedCatalog<TModel>(
3440
}
3541

3642
/// <summary>
37-
/// <para xml:lang="en">Merges a read-only list getter with a global catalog row.</para>
38-
/// <para xml:lang="zh-CN">将只读列表 getter 与全局 catalog 行合并。</para>
43+
/// <para xml:lang="en">Merges a read-only list getter with a global catalog row.</para>
44+
/// <para xml:lang="zh-CN">将只读列表 getter 与全局 catalog 行合并。</para>
3945
/// </summary>
4046
internal static IReadOnlyList<TModel> MergeGlobalCatalogList<TModel>(
4147
ContentCatalogId catalogId,

Content/ModifierContentMerge.cs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,23 @@
33
namespace STS2RitsuLib.Content
44
{
55
/// <summary>
6-
/// <para xml:lang="en">Merges RitsuLib-registered run modifiers and exclusivity groups into <see cref="ModelDb" /> lists.</para>
7-
/// <para xml:lang="zh-CN">将 RitsuLib 注册的运行修饰符与互斥组合并到 <see cref="ModelDb" /> 列表中。</para>
6+
/// <para xml:lang="en">
7+
/// Merges RitsuLib-registered run modifiers and exclusivity groups into <see cref="ModelDb" />
8+
/// lists.
9+
/// </para>
10+
/// <para xml:lang="zh-CN">将 RitsuLib 注册的运行修饰符与互斥组合并到 <see cref="ModelDb" /> 列表中。</para>
811
/// </summary>
912
internal static class ModifierContentMerge
1013
{
1114
/// <summary>
12-
/// <para xml:lang="en">Inserts registered modifiers before or after <paramref name="source" /> using <see cref="ModifierRegistration.ModifierListSortOrder" />.</para>
13-
/// <para xml:lang="zh-CN">按 <see cref="ModifierRegistration.ModifierListSortOrder" /> 在 <paramref name="source" /> 前后插入已注册修饰符。</para>
15+
/// <para xml:lang="en">
16+
/// Inserts registered modifiers before or after <paramref name="source" /> using
17+
/// <see cref="ModifierRegistration.ModifierListSortOrder" />.
18+
/// </para>
19+
/// <para xml:lang="zh-CN">
20+
/// 按 <see cref="ModifierRegistration.ModifierListSortOrder" /> 在 <paramref name="source" />
21+
/// 前后插入已注册修饰符。
22+
/// </para>
1423
/// </summary>
1524
public static IReadOnlyList<ModifierModel> InsertModifiers(
1625
IReadOnlyList<ModifierModel> source,
@@ -28,8 +37,11 @@ public static IReadOnlyList<ModifierModel> InsertModifiers(
2837
}
2938

3039
/// <summary>
31-
/// <para xml:lang="en">Merges registered exclusivity groups into <paramref name="source" />, combining overlapping sets.</para>
32-
/// <para xml:lang="zh-CN">将已注册互斥组合并到 <paramref name="source" />,并合并存在交集的集合。</para>
40+
/// <para xml:lang="en">
41+
/// Merges registered exclusivity groups into <paramref name="source" />, combining overlapping
42+
/// sets.
43+
/// </para>
44+
/// <para xml:lang="zh-CN">将已注册互斥组合并到 <paramref name="source" />,并合并存在交集的集合。</para>
3345
/// </summary>
3446
public static IReadOnlyList<IReadOnlySet<ModifierModel>> MergeMutuallyExclusiveModifiers(
3547
IReadOnlyList<IReadOnlySet<ModifierModel>> source,
@@ -113,16 +125,16 @@ private static List<ModifierModel> ConcatDistinctByModelId(
113125
}
114126

115127
/// <summary>
116-
/// <para xml:lang="en">Registration metadata for a mod run modifier list entry.</para>
117-
/// <para xml:lang="zh-CN">mod 运行修饰符列表条目的注册元数据。</para>
128+
/// <para xml:lang="en">Registration metadata for a mod run modifier list entry.</para>
129+
/// <para xml:lang="zh-CN">mod 运行修饰符列表条目的注册元数据。</para>
118130
/// </summary>
119131
/// <param name="ModifierType">
120-
/// <para xml:lang="en">Concrete <see cref="ModifierModel" /> type.</para>
121-
/// <para xml:lang="zh-CN">具体 <see cref="ModifierModel" /> 类型。</para>
132+
/// <para xml:lang="en">Concrete <see cref="ModifierModel" /> type.</para>
133+
/// <para xml:lang="zh-CN">具体 <see cref="ModifierModel" /> 类型。</para>
122134
/// </param>
123135
/// <param name="ModifierListSortOrder">
124-
/// <para xml:lang="en">Negative values insert before the current list segment; non-negative values insert after.</para>
125-
/// <para xml:lang="zh-CN">负值插入当前列表段之前;非负值插入之后。</para>
136+
/// <para xml:lang="en">Negative values insert before the current list segment; non-negative values insert after.</para>
137+
/// <para xml:lang="zh-CN">负值插入当前列表段之前;非负值插入之后。</para>
126138
/// </param>
127139
internal readonly record struct ModifierRegistration(Type ModifierType, int ModifierListSortOrder);
128140
}

0 commit comments

Comments
 (0)