diff --git a/README.md b/README.md index 2a65cad..12533ec 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,10 @@ kept when the event ends: Guarded Crate has no way to end one event alone. Witho is refused, because the crate would land unguarded; and, as for Dangerous Treasures, a framework with `consolePlugins=False` cannot place one. +nivex's `ZLevels Remastered` is optional, and the bridge only says whether it is loaded. Its levels are +never read or sent. Its XP boosts are its own permissions (`zlevelsremastered.vip1` to `vip3`), so an +event lends one as it lends any other permission, and it takes effect at once. + Rust's own world events need no plugin at all. The patrol helicopter, Bradley, the cargo ship, the Chinook, airdrops, locked crates, the Travelling Vendor, the satellite and the Deep Sea reach the site's feed and its event triggers on every server, and an event can call one of them (`world.call`). diff --git a/overlay/oxide/plugins/RunicGateway.cs b/overlay/oxide/plugins/RunicGateway.cs index ab2210f..e40a715 100644 --- a/overlay/oxide/plugins/RunicGateway.cs +++ b/overlay/oxide/plugins/RunicGateway.cs @@ -77,7 +77,8 @@ namespace Oxide.Plugins /// integrations.dangerousTreasures; and Guarded Crate (§20.9, PLAN_REDESIGNS.md /// §14.3.5): gc.started, gc.ended and gc.failed, gc.place, /// map.live's guarded rows, the tally's guardedWon and - /// integrations.guardedCrate with NpcSpawn beside it. + /// integrations.guardedCrate with NpcSpawn beside it; and ZLevels Remastered + /// (§20.10, PLAN_REDESIGNS.md §14.3.6): integrations.zLevels, and nothing more. /// /// private const int ProtocolVersion = 14; @@ -5214,8 +5215,9 @@ namespace Oxide.Plugins // Economics too: hello carries its starting balance, which the richest column needs; // and Backpacks, whose sizes are what a Bigger backpack step offers; and TruePVE, which a // zone step's PvP rules are refused without (§14.3.2); and Dynamic PVP (§14.3.3). - // Guarded Crate and NpcSpawn too: a placement is refused without either (D364). - if (IsZonePlugin(plugin) || IsRunicNpc(plugin) || IsEconomics(plugin) || IsBackpacks(plugin) || IsTruePve(plugin) || IsDynamicPvp(plugin) || IsDangerousTreasures(plugin) || IsGuardedCrate(plugin)) + // Guarded Crate and NpcSpawn too: a placement is refused without either (D364). And + // ZLevels, which the servers page names (§14.3.6). + if (IsZonePlugin(plugin) || IsRunicNpc(plugin) || IsEconomics(plugin) || IsBackpacks(plugin) || IsTruePve(plugin) || IsDynamicPvp(plugin) || IsDangerousTreasures(plugin) || IsGuardedCrate(plugin) || IsZLevels(plugin)) NextTick(ResendHello); // Dynamic PVP raises its creates as it opens its zones, which at a load are its @@ -5258,7 +5260,7 @@ namespace Oxide.Plugins if (plugin != null && plugin.Name == "BetterChat") _titlesRegistered = false; - if (IsZonePlugin(plugin) || IsRunicNpc(plugin) || IsEconomics(plugin) || IsBackpacks(plugin) || IsTruePve(plugin) || IsDynamicPvp(plugin) || IsDangerousTreasures(plugin) || IsGuardedCrate(plugin)) + if (IsZonePlugin(plugin) || IsRunicNpc(plugin) || IsEconomics(plugin) || IsBackpacks(plugin) || IsTruePve(plugin) || IsDynamicPvp(plugin) || IsDangerousTreasures(plugin) || IsGuardedCrate(plugin) || IsZLevels(plugin)) NextTick(ResendHello); // Guarded Crate's Unload ended every event WITHOUT a hook. @@ -10098,6 +10100,22 @@ namespace Oxide.Plugins EmitFrame(frame); } + // ---- ZLevels Remastered (PLAN_REDESIGNS §14.3.6, D369, D374) ---- + // + // Hello says whether it is loaded, and that is all. No level is read or sent: the + // leaderboard does not change for it (D374). Its XP boosts are permissions, so an event + // lends one through `perm.lend` with no code of ours (§12). + + private Plugin ZLevelsPlugin() + { + return plugins.Find("ZLevelsRemastered"); + } + + private bool IsZLevels(Plugin plugin) + { + return plugin != null && plugin != this && plugin.Name == "ZLevelsRemastered"; + } + // ---- the zone's messages (D193) ---- // // ZoneManager can say a zone's enter and leave messages itself, but only to chat unless its @@ -11408,6 +11426,7 @@ namespace Oxide.Plugins $"dangerousTreasures={(DangerousTreasuresPlugin() != null)} treasures={_treasures.Count} dtStarts={_dtStarts.Count} dtWarmingUp={DtWarmingUp()} " + $"guardedCrate={(GuardedCratePlugin() != null)} npcSpawn={(NpcSpawnPlugin() != null)} guarded={_guardedCrates.Count} gcPlaces={_gcPlacements.Count} " + $"gcEvents={(GuardedCrateEventNames() != null ? string.Join("|", GuardedCrateEventNames().ToArray()) : "none")} gcCommand={GuardedCrateCommand()} gcListReadable={_gcListReadable} " + + $"zLevels={(ZLevelsPlugin() != null ? ZLevelsPlugin().Version.ToString() : "absent")} " + $"wipeId={(_wipeId ?? "none")} calls={_worldCalls.Count} consolePlugins={_consolePlugins} " + $"credits={_vehicleCredit.Count} chinookCrates={_chinookCrates.Count} said={_worldEventsSaid} " + $"worldEvents={(WorldEventsLive() ? "live" : $"quiet (ready={_worldReady} quitting={Rust.Application.isQuitting} loadingSave={Rust.Application.isLoadingSave})")}" + Environment.NewLine + @@ -15022,7 +15041,9 @@ namespace Oxide.Plugins // Protocol 14 (§14.3.4): whether a step may open a Dangerous Treasures event here. { "dangerousTreasures", IntegrationBody(DangerousTreasuresPlugin()) }, // Protocol 14 (§14.3.5): whether a step may place a guarded crate here, and which. - { "guardedCrate", GuardedCrateBody() } + { "guardedCrate", GuardedCrateBody() }, + // Protocol 14 (§14.3.6): whether its XP boosts are here for a step to lend. + { "zLevels", IntegrationBody(ZLevelsPlugin()) } }; }