Skip to content

Commit af72acb

Browse files
committed
fix modrow patches
better steam ts update logic
1 parent d717f3b commit af72acb

6 files changed

Lines changed: 88 additions & 23 deletions

File tree

Source/ModSwitch/ModSwitch.cs

Lines changed: 82 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Concurrent;
4+
using System.Collections.Generic;
25
using System.Linq;
36
using System.Reflection;
4-
7+
using System.Threading;
58
using HarmonyLib;
69
using RimWorld;
710
using UnityEngine;
@@ -13,6 +16,9 @@ internal class ModSwitch : Mod {
1316

1417
public static bool IsRestartDefered;
1518

19+
public volatile static IDictionary<string, uint> TSUpdateCache = new ConcurrentDictionary<string, uint>();
20+
21+
1622
static ModSwitch() {
1723
fiModLister_mods = AccessTools.Field(typeof(ModLister), "mods");
1824
}
@@ -30,14 +36,16 @@ public ModSwitch(ModContentPack content) : base(content) {
3036

3137
CustomSettings = GetSettings<Settings>();
3238

33-
if (ModsConfigUI.Helpers.PreInitTSUpdateCache.Count != null) {
34-
var entries = ModsConfigUI.Helpers.PreInitTSUpdateCache.ToArray();
35-
ModsConfigUI.Helpers.PreInitTSUpdateCache.Clear();
36-
Log.Message($"ModSwitch - copying cached steam TS values.");
3739

38-
foreach (KeyValuePair<string, uint> cachedTSValue in entries) {
40+
var cachedValues = Interlocked.Exchange(ref TSUpdateCache, new SteamUpdateAdapter(CustomSettings));
41+
if (cachedValues.Count != 0) {
42+
// yes, there may *still* be a race condition where we overwrite a later, but previously written, update timestamp with a cached, but earlier timestamp... not going to block threads here
43+
44+
Log.Message($"ModSwitch - copying cached steam TS values.");
45+
foreach (KeyValuePair<string, uint> cachedTSValue in cachedValues) {
3946
CustomSettings.Attributes[cachedTSValue.Key].LastUpdateTS = cachedTSValue.Value;
4047
}
48+
4149
}
4250
}
4351

@@ -57,5 +65,72 @@ public override void DoSettingsWindowContents(Rect inRect) {
5765
public override string SettingsCategory() {
5866
return LanguageKeys.keyed.ModSwitch.Translate();
5967
}
68+
69+
/// <summary>
70+
/// <em>Severely</em> restricted dictionary adapter for writing steam TS updates to ModSwitch settings.
71+
/// <em>ONLY</em> the index setter <seealso cref="SteamUpdateAdapter.this"/> is actually implemented.
72+
/// All other calls will fail.
73+
/// </summary>
74+
private class SteamUpdateAdapter : IDictionary<string, uint> {
75+
private readonly Settings _owner;
76+
77+
public SteamUpdateAdapter(Settings owner) {
78+
_owner = owner;
79+
}
80+
81+
public IEnumerator<KeyValuePair<string, uint>> GetEnumerator() {
82+
throw new NotImplementedException();
83+
}
84+
85+
IEnumerator IEnumerable.GetEnumerator() {
86+
return GetEnumerator();
87+
}
88+
89+
public void Add(KeyValuePair<string, uint> item) {
90+
throw new NotImplementedException();
91+
}
92+
93+
public void Clear() {
94+
throw new NotImplementedException();
95+
}
96+
97+
public bool Contains(KeyValuePair<string, uint> item) {
98+
throw new NotImplementedException();
99+
}
100+
101+
public void CopyTo(KeyValuePair<string, uint>[] array, int arrayIndex) {
102+
throw new NotImplementedException();
103+
}
104+
105+
public bool Remove(KeyValuePair<string, uint> item) {
106+
throw new NotImplementedException();
107+
}
108+
109+
public int Count { get; }
110+
public bool IsReadOnly { get; }
111+
public bool ContainsKey(string key) {
112+
throw new NotImplementedException();
113+
}
114+
115+
public void Add(string key, uint value) {
116+
throw new NotImplementedException();
117+
}
118+
119+
public bool Remove(string key) {
120+
throw new NotImplementedException();
121+
}
122+
123+
public bool TryGetValue(string key, out uint value) {
124+
throw new NotImplementedException();
125+
}
126+
127+
public uint this[string key] {
128+
get => throw new NotImplementedException();
129+
set => _owner.Attributes[key].LastUpdateTS = value;
130+
}
131+
132+
public ICollection<string> Keys => throw new NotImplementedException();
133+
public ICollection<uint> Values => throw new NotImplementedException();
134+
}
60135
}
61136
}

Source/ModSwitch/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@
1212
[assembly: System.Reflection.AssemblyCopyright("Copyright © DoctorVanGogh 2017")]
1313
[assembly: System.Runtime.InteropServices.ComVisible(false)]
1414
[assembly: System.Runtime.InteropServices.Guid("ab2e8e89-3d1d-4e36-a0ae-489b6ebc84a6")]
15-
[assembly: System.Reflection.AssemblyVersion("2.0.3.299")]
15+
[assembly: System.Reflection.AssemblyVersion("2.1.0.302")]
1616

1717

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.0.3.299
1+
2.1.0.302

Source/ModSwitch/[Patches]/Patches.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,14 @@ public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructio
7777

7878

7979
public class Page_ModsConfig_DoModRow {
80-
[HarmonyPatch(typeof(Page_ModsConfig), "DoModRow", new[] {typeof(Listing_Standard), typeof(ModMetaData), typeof(int), typeof(int)})]
80+
[HarmonyPatch(typeof(Page_ModsConfig), "DoModRow")]
8181
public class SupressNonMatchingFilteredRows {
8282
public static bool Prefix(ModMetaData mod) {
8383
return ModsConfigUI.Search.MatchCriteria(mod?.Name) || true == mod?.SupportedVersionsReadOnly.Any(s => ModsConfigUI.Search.MatchCriteria(s.ToString()));
8484
}
8585
}
8686

87-
[HarmonyPatch(typeof(Page_ModsConfig), "DoModRow", new[] {typeof(Listing_Standard), typeof(ModMetaData), typeof(int), typeof(int)})]
87+
[HarmonyPatch(typeof(Page_ModsConfig), "DoModRow")]
8888
public class InjectRightClickMenu {
8989
// inject right click menu on mod rows
9090
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator ilGen) {
@@ -177,7 +177,7 @@ public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructio
177177
}
178178
}
179179

180-
[HarmonyPatch(typeof(Page_ModsConfig), "DoModRow", new[] {typeof(Listing_Standard), typeof(ModMetaData), typeof(int), typeof(int)})]
180+
[HarmonyPatch(typeof(Page_ModsConfig), "DoModRow")]
181181
public class InjectCustomContentSourceDraw {
182182
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instr) {
183183
List<CodeInstruction> instructions = new List<CodeInstruction>(instr);

Source/ModSwitch/[UI]/ModsConfigUI.cs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,6 @@ private static void UpdateSteamAttributes(string name, ModMetaData original, Str
381381

382382
public static class Helpers {
383383

384-
public static IDictionary<string, uint> PreInitTSUpdateCache = new ConcurrentDictionary<string, uint>();
385384

386385
public static string ExplainError(string label, string error) {
387386
return $"{label} *{error}*";
@@ -408,16 +407,7 @@ public static Color SetGUIColorMod(ModMetaData mod) {
408407
}
409408

410409
public static void UpdateSteamTS(PublishedFileId_t pfid, uint ts) {
411-
var modModSwitch = LoadedModManager.GetMod<ModSwitch>();
412-
413-
if (modModSwitch != null) {
414-
modModSwitch.CustomSettings.Attributes[pfid.ToString()].LastUpdateTS = ts;
415-
} else {
416-
if (PreInitTSUpdateCache.Count == 0) {
417-
Log.Message("ModSwitch: Mod yet loaded, but already getting steam update values - caching until mod initialization.");
418-
}
419-
PreInitTSUpdateCache[pfid.ToString()] = ts;
420-
}
410+
ModSwitch.TSUpdateCache[pfid.ToString()] = ts;
421411
}
422412

423413
public static string WrapTimestamp(long? timestamp) {

v1.1/Assemblies/ModSwitch.dll

512 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)