fix(examples): a Kits reload owed for the example kits survives an interrupted load (D329) #17
@@ -4121,8 +4121,16 @@ namespace Oxide.Plugins
|
||||
{
|
||||
/// <summary>D284: set on the first load that wrote them, and never cleared.</summary>
|
||||
[JsonProperty("examplesWritten")] public bool ExamplesWritten;
|
||||
|
||||
/// <summary>D329: the example kits written that Kits has not loaded yet. The reload is owed until it has.</summary>
|
||||
[JsonProperty("kitsReloadOwed")] public List<string> KitsReloadOwed = new List<string>();
|
||||
|
||||
/// <summary>D329: the loads that have asked for that reload. At most three, so a kit Kits never takes cannot loop.</summary>
|
||||
[JsonProperty("kitsReloadTries")] public int KitsReloadTries;
|
||||
}
|
||||
|
||||
private const int KitsReloadTriesMax = 3;
|
||||
|
||||
/// <summary>Placements wait while Kits reloads with the example kits (D283 reloads RunicNPC with it).</summary>
|
||||
private bool _holdForKits;
|
||||
|
||||
@@ -4206,8 +4214,8 @@ namespace Oxide.Plugins
|
||||
/// <summary>
|
||||
/// D284: on the first load only, the four example kits go into Kits' own data file (Kits has no
|
||||
/// API that creates one, D280) and the four profiles into ours, each only where its name is free.
|
||||
/// The flag is set before anything is written, so this runs once whatever happens. Kits is then
|
||||
/// reloaded, which reloads RunicNPC too (D283); placements wait for it.
|
||||
/// The flag is set before anything is written, so this runs once whatever happens. The kits it wrote
|
||||
/// are then owed a Kits reload (D329), which SettleKitsReload asks for; it reloads RunicNPC too (D283).
|
||||
/// </summary>
|
||||
private void WriteExamplesOnce()
|
||||
{
|
||||
@@ -4286,11 +4294,43 @@ namespace Oxide.Plugins
|
||||
if (addedKits.Count == 0)
|
||||
return;
|
||||
|
||||
// Kits reads its file only when it loads (stage 6 spike, finding 5). The reload takes RunicNPC down and
|
||||
// back with it (D283); if this framework does not, OnPluginLoaded("Kits") picks the profiles up.
|
||||
// Kits reads its file only when it loads (stage 6 spike, finding 5), so a reload is owed; SettleKitsReload asks for it.
|
||||
state.KitsReloadOwed = addedKits;
|
||||
state.KitsReloadTries = 0;
|
||||
Interface.Oxide.DataFileSystem.WriteObject(DataState, state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// D329: asks Kits to reload while the example kits written are still owed, and clears the debt once Kits
|
||||
/// knows them all. The reload runs on a timer, which dies with RunicNPC: in the 9d session a second load of
|
||||
/// RunicNPC within that second lost it, and the examples stayed refused until Kits was reloaded by hand.
|
||||
/// Owing it in the state file lets any later load (or Kits coming back) finish the job.
|
||||
/// </summary>
|
||||
private void SettleKitsReload()
|
||||
{
|
||||
StateFile state = ReadData<StateFile>(DataState);
|
||||
if (state.KitsReloadOwed == null || state.KitsReloadOwed.Count == 0)
|
||||
return;
|
||||
|
||||
string command = Framework() == "carbon" ? "c.reload" : "oxide.reload";
|
||||
if (state.KitsReloadOwed.All(KitExists) || state.KitsReloadTries >= KitsReloadTriesMax)
|
||||
{
|
||||
if (state.KitsReloadTries >= KitsReloadTriesMax && !state.KitsReloadOwed.All(KitExists))
|
||||
PrintWarning($"Kits has still not loaded the example kits ({string.Join(", ", state.KitsReloadOwed.ToArray())}) after " +
|
||||
$"{KitsReloadTriesMax} reloads. Run `{command} Kits` once.");
|
||||
state.KitsReloadOwed = new List<string>();
|
||||
state.KitsReloadTries = 0;
|
||||
Interface.Oxide.DataFileSystem.WriteObject(DataState, state);
|
||||
return;
|
||||
}
|
||||
|
||||
state.KitsReloadTries++;
|
||||
Interface.Oxide.DataFileSystem.WriteObject(DataState, state);
|
||||
|
||||
// The reload takes RunicNPC down and back with it (D283); if this framework does not, OnPluginLoaded("Kits")
|
||||
// picks the profiles up. Placements wait for it.
|
||||
_holdForKits = true;
|
||||
timer.Once(60f, () => _holdForKits = false);
|
||||
string command = Framework() == "carbon" ? "c.reload" : "oxide.reload";
|
||||
timer.Once(1f, () => ConsoleSystem.Run(ConsoleSystem.Option.Server, command, "Kits"));
|
||||
}
|
||||
|
||||
@@ -4475,6 +4515,7 @@ namespace Oxide.Plugins
|
||||
ResolveFields();
|
||||
LoadData();
|
||||
WriteExamplesOnce();
|
||||
SettleKitsReload();
|
||||
RevalidateProfiles();
|
||||
RebuildPlacements();
|
||||
TrackWorld();
|
||||
@@ -4526,6 +4567,7 @@ namespace Oxide.Plugins
|
||||
if (plugin == null || plugin.Name != "Kits" || !_ready)
|
||||
return;
|
||||
_holdForKits = false;
|
||||
SettleKitsReload();
|
||||
RevalidateProfiles();
|
||||
TickPlacements();
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace Oxide.Plugins
|
||||
/// a made-up user id (11400000001 and up), so <c>IsNpc</c> is false. They take no damage.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[Info("RunicNpcTest", "Runic Gateway", "0.7.2")]
|
||||
[Info("RunicNpcTest", "Runic Gateway", "0.7.3")]
|
||||
[Description("RunicNPC stage 2 to 7 tests, the stage 6 spike and stage 9's cost check. A developer tool: never ship it.")]
|
||||
internal class RunicNpcTest : RustPlugin
|
||||
{
|
||||
@@ -2422,6 +2422,9 @@ namespace Oxide.Plugins
|
||||
"each needs kits.runicnpc, which nobody is granted");
|
||||
JObject state = Interface.Oxide.DataFileSystem.ReadObject<JObject>("RunicNPC/state");
|
||||
Check("s6.examples.once", state?["examplesWritten"]?.Type == JTokenType.Boolean && (bool)state["examplesWritten"], "state.json: " + state?.ToString(Formatting.None));
|
||||
// D329: once Kits knows the examples, no reload is owed (a state from before D329 has no list at all).
|
||||
JArray owed = state?["kitsReloadOwed"] as JArray;
|
||||
Check("s6.examples.reloadSettled", owed == null || owed.Count == 0, "kitsReloadOwed: " + (owed?.ToString(Formatting.None) ?? "absent"));
|
||||
JObject items = kitFile?["_kits"]?["rnpc_juggernaut"] as JObject;
|
||||
int itemCount = items == null ? 0 : ((JArray)items["MainItems"]).Count + ((JArray)items["WearItems"]).Count + ((JArray)items["BeltItems"]).Count;
|
||||
Check("s6.examples.items", itemCount == 6, $"rnpc_juggernaut carries {itemCount} of its 6 items (a short name this Rust lacks would be left out)");
|
||||
|
||||
Reference in New Issue
Block a user