feat(sidecar): protocol 13, the egg with RunicNPC and the banner, edge → main (runicnpc 9e step 3, merge 2 of 3) #23

Merged
whitlocktech merged 11 commits from edge into main 2026-10-09 07:21:03 +00:00
Showing only changes of commit 4eee1fbe17 - Show all commits

View File

@@ -88,6 +88,69 @@ if [ $WORLD_SEED == "0" ]; then
fi
## ── The Runic Gateway bridge ─────────────────────────────────────────────────
# PopupNotifications' recommended look (docs/runicnpc/PLAN.md D327): a banner
# across the top of the screen. PopupNotifications is optional and the operator
# installs it (D141), so its config is theirs: the banner goes in only where the
# file is missing or is still exactly the plugin's own defaults, every setting
# equal and the Version aside (D328). Anything else is kept whole. The Version
# is written too: PopupNotifications resets a config without one to defaults.
rg_popup() { # <the framework's config directory>
local file="$1/PopupNotifications.json"
local banner='{
"Notification duration (in seconds)": 8,
"Maximum notifications shown at any time": 6,
"UI Positioning": {
"Position of the left side of notification (0.0 - 1.0)": 0.15,
"Position of the bottom of noticiation (0.0 - 1.0)": 0.87,
"Width (0.0 - 1.0)": 0.7,
"Height (0.0 - 1.0)": 0.07,
"Space between notification (0.0 - 1.0)": 0.005
},
"UI Options": {
"Show close button": false,
"Panel color (hex)": "#2b2b2b",
"Panel transparency (0.0 - 1.0)": 0.8,
"Close button color (hex)": "#d85540",
"Close button transparency (0.0 - 1.0)": 0.5,
"Font": "robotocondensed-bold.ttf",
"Font size": 18
},
"Version": { "Major": 0, "Minor": 2, "Patch": 1 }
}'
# PopupNotifications 0.2.1's GetBaseConfig(): a small grey box at the right.
local defaults='{
"Notification duration (in seconds)": 8,
"Maximum notifications shown at any time": 6,
"UI Positioning": {
"Position of the left side of notification (0.0 - 1.0)": 0.8,
"Position of the bottom of noticiation (0.0 - 1.0)": 0.78,
"Width (0.0 - 1.0)": 0.19,
"Height (0.0 - 1.0)": 0.1,
"Space between notification (0.0 - 1.0)": 0.01
},
"UI Options": {
"Show close button": true,
"Panel color (hex)": "#2b2b2b",
"Panel transparency (0.0 - 1.0)": 0.5,
"Close button color (hex)": "#d85540",
"Close button transparency (0.0 - 1.0)": 0.5,
"Font": "droidsansmono.ttf",
"Font size": 12
}
}'
if [ ! -e "${file}" ]; then
mkdir -p "$1" || return 1
jq -n "${banner}" > "${file}" || return 1
echo "Runic Gateway: wrote the recommended PopupNotifications banner to ${file}"
elif jq -e --argjson d "${defaults}" 'type == "object" and del(.Version) == $d' "${file}" >/dev/null 2>&1; then
jq --argjson b "${banner}" '$b + { Version: (.Version // $b.Version) }' "${file}" > "${file}.rg" \
&& mv "${file}.rg" "${file}" || { rm -f "${file}.rg"; return 1; }
echo "Runic Gateway: ${file} was PopupNotifications' defaults; wrote the recommended banner"
else
echo "Runic Gateway: kept ${file} (not PopupNotifications' defaults)"
fi
}
# After the wipe, so REMOVE_FILES can never delete the plugin this just placed.
rg_install() {
set -euo pipefail
@@ -95,10 +158,10 @@ rg_install() {
# just the variables an egg declares, and this one is not declared.
local api="${RUNICGATEWAY_BUNDLE_API:-https://gitea.whitlocktech.com/api/v1/repos/RunicGateway/installer/contents/v2/rust}"
local work=/tmp/runicgateway
local plugins
local plugins config
case "${FRAMEWORK:-vanilla}" in
oxide) plugins=/mnt/server/oxide/plugins ;;
carbon) plugins=/mnt/server/carbon/plugins ;;
oxide) plugins=/mnt/server/oxide/plugins; config=/mnt/server/oxide/config ;;
carbon) plugins=/mnt/server/carbon/plugins; config=/mnt/server/carbon/configs ;;
*)
# Not a failure (§34.4): failing would leave the operator without a game
# server over a bridge they may not want yet. The startup skips the
@@ -188,6 +251,10 @@ rg_install() {
for file in $(jq -r '.files | keys[]' "${manifest}"); do
install -m 644 "${work}/runicgateway-rust-plugin/${file}" "${plugins}/${file}"
done
# A look, not the bridge: if it cannot be written, say so and finish the install.
if ! rg_popup "${config}"; then
echo "Runic Gateway: could not write the PopupNotifications banner to ${config}; the bridge is installed regardless"
fi
# What is installed, readable from the panel's file manager.
jq --arg framework "${FRAMEWORK}" --arg installed "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
'{ bundle, protocol, framework: $framework, installed: $installed,