feat(bridge): every NPC an event places needs RunicNPC (runicnpc stage 9, D310) #27
@@ -86,6 +86,7 @@ requires_plugins = ["Kits", "ZoneManager"]
|
|||||||
# two equal. The release copies it into manifest.json, and the installer's
|
# two equal. The release copies it into manifest.json, and the installer's
|
||||||
# bundle carries the latest RunicNPC release that answers at least it (D224).
|
# bundle carries the latest RunicNPC release that answers at least it (D224).
|
||||||
#
|
#
|
||||||
# RunicNPC is optional to the bridge until its stage 9: without it every npc.*
|
# RunicNPC is required since its stage 9 (D310): without it, or with one older
|
||||||
# command answers `runicnpc-missing`, and events place Rust's own scientists.
|
# than this, every npc.* command and every NPC an event places, Rust's own
|
||||||
|
# scientists included, is refused as `runicnpc-missing` or `runicnpc-old`.
|
||||||
runicnpc_api = 6
|
runicnpc_api = 6
|
||||||
|
|||||||
@@ -9067,6 +9067,11 @@ namespace Oxide.Plugins
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RunicNPC stage 9 (D310): Rust's own scientists need RunicNPC too, so a module that
|
||||||
|
// missed the hello cannot place NPCs on a server the site would call incomplete.
|
||||||
|
if (prefab.Kind == WorldKindNpc && !RunicNpcForWorld(reqId))
|
||||||
|
return;
|
||||||
|
|
||||||
int count = IntField(cmd, "count");
|
int count = IntField(cmd, "count");
|
||||||
int max = prefab.Kind == WorldKindNpc
|
int max = prefab.Kind == WorldKindNpc
|
||||||
? (_config != null ? _config.EventsMaxNpcs : WorldHardMaxNpcs)
|
? (_config != null ? _config.EventsMaxNpcs : WorldHardMaxNpcs)
|
||||||
@@ -10365,8 +10370,8 @@ namespace Oxide.Plugins
|
|||||||
// RunicNPC is Runic Gateway's own NPC plugin. The bridge is its only link to the site
|
// RunicNPC is Runic Gateway's own NPC plugin. The bridge is its only link to the site
|
||||||
// (runicnpc PLAN.md §4): it calls RunicNPC's API for the site's commands and turns its hooks
|
// (runicnpc PLAN.md §4): it calls RunicNPC's API for the site's commands and turns its hooks
|
||||||
// into frames. RunicNPC never talks to the sidecar, so "the sidecar is a dumb forwarder"
|
// into frames. RunicNPC never talks to the sidecar, so "the sidecar is a dumb forwarder"
|
||||||
// stays true. It is optional until RunicNPC's stage 9; without it every `npc.*` command
|
// stays true. It is required since RunicNPC's stage 9 (D310): without it every `npc.*` command
|
||||||
// answers `runicnpc-missing`, and events keep Rust's own scientists (D243).
|
// answers `runicnpc-missing`, and so does every NPC an event places, Rust's own included.
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The RunicNPC API these commands call: 3 added placements from a website (D249), 4 the
|
/// The RunicNPC API these commands call: 3 added placements from a website (D249), 4 the
|
||||||
@@ -10443,6 +10448,33 @@ namespace Oxide.Plugins
|
|||||||
return npc;
|
return npc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Main thread. Whether an event may place NPCs here (stage 9, D310): RunicNPC loaded and
|
||||||
|
/// answering the API this bridge needs, for a profile and for Rust's own scientists alike.
|
||||||
|
/// Answers <c>world.error</c> with the reason when not.
|
||||||
|
/// </summary>
|
||||||
|
private bool RunicNpcForWorld(string reqId)
|
||||||
|
{
|
||||||
|
Plugin npc = RunicNpcPlugin();
|
||||||
|
|
||||||
|
if (npc == null)
|
||||||
|
{
|
||||||
|
EmitWorldError(reqId, "runicnpc-missing", "this server needs RunicNPC to place NPCs, and it is not loaded");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int api = RunicNpcApi();
|
||||||
|
|
||||||
|
if (api < RunicNpcApiNeeded)
|
||||||
|
{
|
||||||
|
EmitWorldError(reqId, "runicnpc-old",
|
||||||
|
$"this server needs RunicNPC to place NPCs: RunicNPC {npc.Version} answers API {api}, and this bridge needs {RunicNpcApiNeeded}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Main thread. <c>npc.profiles</c>: the server's profile set as RunicNPC holds it — whether
|
/// Main thread. <c>npc.profiles</c>: the server's profile set as RunicNPC holds it — whether
|
||||||
/// a site manages it, every profile, and those refused and why. The site reads this before
|
/// a site manages it, every profile, and those refused and why. The site reads this before
|
||||||
@@ -10919,14 +10951,10 @@ namespace Oxide.Plugins
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void HandleWorldPlaceProfile(Dictionary<string, object> cmd, string reqId, string key, string runId, string profile)
|
private void HandleWorldPlaceProfile(Dictionary<string, object> cmd, string reqId, string key, string runId, string profile)
|
||||||
{
|
{
|
||||||
Plugin npc = RunicNpcPlugin();
|
if (!RunicNpcForWorld(reqId))
|
||||||
|
|
||||||
if (npc == null)
|
|
||||||
{
|
|
||||||
EmitWorldError(reqId, "runicnpc-missing", $"RunicNPC is not loaded, so there is no profile '{profile}' here");
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
|
Plugin npc = RunicNpcPlugin();
|
||||||
var profiles = npc.Call("RunicNpc_Profiles") as Newtonsoft.Json.Linq.JObject;
|
var profiles = npc.Call("RunicNpc_Profiles") as Newtonsoft.Json.Linq.JObject;
|
||||||
Newtonsoft.Json.Linq.JToken known = profiles != null ? profiles["profiles"]?[profile] : null;
|
Newtonsoft.Json.Linq.JToken known = profiles != null ? profiles["profiles"]?[profile] : null;
|
||||||
|
|
||||||
@@ -11228,7 +11256,7 @@ namespace Oxide.Plugins
|
|||||||
|
|
||||||
Plugin npc = RunicNpcPlugin();
|
Plugin npc = RunicNpcPlugin();
|
||||||
arg.ReplyWith(npc == null
|
arg.ReplyWith(npc == null
|
||||||
? "RunicNPC: not loaded. npc.* commands answer runicnpc-missing; events place Rust's own scientists."
|
? "RunicNPC: not loaded. npc.* commands and every NPC an event places answer runicnpc-missing (it is required)."
|
||||||
: $"RunicNPC {npc.Version}, API {RunicNpcApi()} (this bridge needs {RunicNpcApiNeeded}). last: {_lastNpcSummary ?? "none yet"}");
|
: $"RunicNPC {npc.Version}, API {RunicNpcApi()} (this bridge needs {RunicNpcApiNeeded}). last: {_lastNpcSummary ?? "none yet"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user