fix: Adds command help, webpage, and fixes issues with other commands (#1669)
### Summary - Fixes `[AdvancedSearch` being accessible by players 😱 - Adds `[GenCommands` to generate the same commands html page on https://muo.gg/commands. - Fixes `[helpinfo` so all commands properly show up! > [!WARNING] > ### Developer Warning: > Commands must now be registered in the `Configure` bootup phase. > If a command is not registered early enough, it may not be available to systems like [helpinfo > that cache their information. > [!NOTE] > ### Developer Note: > Various commands related to generating content have been changed to _Developer_ and above access level. ### Screenshots <img width="673" alt="image" src="https://github.com/modernuo/ModernUO/assets/3953314/b105b5c9-5eb4-4ace-93ff-1bfb31e7132f"> <img width="547" alt="image" src="https://github.com/modernuo/ModernUO/assets/3953314/e97487e8-47a5-4aa7-89cc-9fe3deda584d">
This commit is contained in:
parent
3244704ea2
commit
fffda53263
88 changed files with 1163 additions and 557 deletions
531
Distribution/Data/commands.html
Normal file
531
Distribution/Data/commands.html
Normal file
|
|
@ -0,0 +1,531 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="description" content="In-game commands for the Ultima Online Server Emulator ModernUO">
|
||||
<meta name="author" content="Kamron Batman">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" href="https://modernuo.com/branding/favicon.png">
|
||||
<title>ModernUO Commands</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;500;700&display=swap" rel="stylesheet">
|
||||
<script src="https://cdn.tailwindcss.com/3.4.1?plugins=typography@0.5.10"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
colors: {
|
||||
inherit: "inherit",
|
||||
current: "currentColor",
|
||||
transparent: "transparent",
|
||||
black: "#000",
|
||||
white: "#fff",
|
||||
counselor: "rgb(80, 80, 200)",
|
||||
gamemaster: "rgb(200, 128, 112)",
|
||||
seer: "rgb(128, 168, 128)",
|
||||
administrator: "rgb(0, 152, 136)",
|
||||
developer: "rgb(112, 88, 160)",
|
||||
owner: "rgb(208, 144, 0)",
|
||||
"modern-black": "#212121",
|
||||
"modern-black-hover": "#2F2F2F",
|
||||
"modern-dark-black": "#1A1A1A",
|
||||
gold: {
|
||||
50: "#fbf3ee",
|
||||
100: "#f8e9dd",
|
||||
200: "#f0d9bd",
|
||||
300: "#e8cea1",
|
||||
400: "#dfc688",
|
||||
500: "#d5bf74",
|
||||
600: "#cab664",
|
||||
700: "#bdab58",
|
||||
800: "#b09f4f",
|
||||
900: "#a29147",
|
||||
},
|
||||
slate: {
|
||||
50: "#f8fafc",
|
||||
100: "#f1f5f9",
|
||||
200: "#e2e8f0",
|
||||
300: "#cbd5e1",
|
||||
400: "#94a3b8",
|
||||
500: "#64748b",
|
||||
600: "#475569",
|
||||
700: "#334155",
|
||||
800: "#1e293b",
|
||||
900: "#0f172a",
|
||||
950: "#020617"
|
||||
},
|
||||
gray: {
|
||||
50: "#f9fafb",
|
||||
100: "#f3f4f6",
|
||||
200: "#e5e7eb",
|
||||
300: "#d1d5db",
|
||||
400: "#9ca3af",
|
||||
500: "#6b7280",
|
||||
600: "#4b5563",
|
||||
700: "#374151",
|
||||
800: "#1f2937",
|
||||
900: "#111827",
|
||||
950: "#030712"
|
||||
},
|
||||
zinc: {
|
||||
50: "#fafafa",
|
||||
100: "#f4f4f5",
|
||||
200: "#e4e4e7",
|
||||
300: "#d4d4d8",
|
||||
400: "#a1a1aa",
|
||||
500: "#71717a",
|
||||
600: "#52525b",
|
||||
700: "#3f3f46",
|
||||
800: "#27272a",
|
||||
900: "#18181b",
|
||||
950: "#09090b"
|
||||
},
|
||||
neutral: {
|
||||
50: "#fafafa",
|
||||
100: "#f5f5f5",
|
||||
200: "#e5e5e5",
|
||||
300: "#d4d4d4",
|
||||
400: "#a3a3a3",
|
||||
500: "#737373",
|
||||
600: "#525252",
|
||||
700: "#404040",
|
||||
800: "#262626",
|
||||
900: "#171717",
|
||||
950: "#0a0a0a"
|
||||
},
|
||||
stone: {
|
||||
50: "#fafaf9",
|
||||
100: "#f5f5f4",
|
||||
200: "#e7e5e4",
|
||||
300: "#d6d3d1",
|
||||
400: "#a8a29e",
|
||||
500: "#78716c",
|
||||
600: "#57534e",
|
||||
700: "#44403c",
|
||||
800: "#292524",
|
||||
900: "#1c1917",
|
||||
950: "#0c0a09"
|
||||
},
|
||||
red: {
|
||||
50: "#fef2f2",
|
||||
100: "#fee2e2",
|
||||
200: "#fecaca",
|
||||
300: "#fca5a5",
|
||||
400: "#f87171",
|
||||
500: "#ef4444",
|
||||
600: "#dc2626",
|
||||
700: "#b91c1c",
|
||||
800: "#991b1b",
|
||||
900: "#7f1d1d",
|
||||
950: "#450a0a"
|
||||
},
|
||||
orange: {
|
||||
50: "#fff7ed",
|
||||
100: "#ffedd5",
|
||||
200: "#fed7aa",
|
||||
300: "#fdba74",
|
||||
400: "#fb923c",
|
||||
500: "#f97316",
|
||||
600: "#ea580c",
|
||||
700: "#c2410c",
|
||||
800: "#9a3412",
|
||||
900: "#7c2d12",
|
||||
950: "#431407"
|
||||
},
|
||||
amber: {
|
||||
50: "#fffbeb",
|
||||
100: "#fef3c7",
|
||||
200: "#fde68a",
|
||||
300: "#fcd34d",
|
||||
400: "#fbbf24",
|
||||
500: "#f59e0b",
|
||||
600: "#d97706",
|
||||
700: "#b45309",
|
||||
800: "#92400e",
|
||||
900: "#78350f",
|
||||
950: "#451a03"
|
||||
},
|
||||
yellow: {
|
||||
50: "#fefce8",
|
||||
100: "#fef9c3",
|
||||
200: "#fef08a",
|
||||
300: "#fde047",
|
||||
400: "#facc15",
|
||||
500: "#eab308",
|
||||
600: "#ca8a04",
|
||||
700: "#a16207",
|
||||
800: "#854d0e",
|
||||
900: "#713f12",
|
||||
950: "#422006"
|
||||
},
|
||||
lime: {
|
||||
50: "#f7fee7",
|
||||
100: "#ecfccb",
|
||||
200: "#d9f99d",
|
||||
300: "#bef264",
|
||||
400: "#a3e635",
|
||||
500: "#84cc16",
|
||||
600: "#65a30d",
|
||||
700: "#4d7c0f",
|
||||
800: "#3f6212",
|
||||
900: "#365314",
|
||||
950: "#1a2e05"
|
||||
},
|
||||
green: {
|
||||
50: "#f0fdf4",
|
||||
100: "#dcfce7",
|
||||
200: "#bbf7d0",
|
||||
300: "#86efac",
|
||||
400: "#4ade80",
|
||||
500: "#22c55e",
|
||||
600: "#16a34a",
|
||||
700: "#15803d",
|
||||
800: "#166534",
|
||||
900: "#14532d",
|
||||
950: "#052e16"
|
||||
},
|
||||
emerald: {
|
||||
50: "#ecfdf5",
|
||||
100: "#d1fae5",
|
||||
200: "#a7f3d0",
|
||||
300: "#6ee7b7",
|
||||
400: "#34d399",
|
||||
500: "#10b981",
|
||||
600: "#059669",
|
||||
700: "#047857",
|
||||
800: "#065f46",
|
||||
900: "#064e3b",
|
||||
950: "#022c22"
|
||||
},
|
||||
teal: {
|
||||
50: "#f0fdfa",
|
||||
100: "#ccfbf1",
|
||||
200: "#99f6e4",
|
||||
300: "#5eead4",
|
||||
400: "#2dd4bf",
|
||||
500: "#14b8a6",
|
||||
600: "#0d9488",
|
||||
700: "#0f766e",
|
||||
800: "#115e59",
|
||||
900: "#134e4a",
|
||||
950: "#042f2e"
|
||||
},
|
||||
cyan: {
|
||||
50: "#ecfeff",
|
||||
100: "#cffafe",
|
||||
200: "#a5f3fc",
|
||||
300: "#67e8f9",
|
||||
400: "#22d3ee",
|
||||
500: "#06b6d4",
|
||||
600: "#0891b2",
|
||||
700: "#0e7490",
|
||||
800: "#155e75",
|
||||
900: "#164e63",
|
||||
950: "#083344"
|
||||
},
|
||||
sky: {
|
||||
50: "#f0f9ff",
|
||||
100: "#e0f2fe",
|
||||
200: "#bae6fd",
|
||||
300: "#7dd3fc",
|
||||
400: "#38bdf8",
|
||||
500: "#0ea5e9",
|
||||
600: "#0284c7",
|
||||
700: "#0369a1",
|
||||
800: "#075985",
|
||||
900: "#0c4a6e",
|
||||
950: "#082f49"
|
||||
},
|
||||
blue: {
|
||||
50: "#eff6ff",
|
||||
100: "#dbeafe",
|
||||
200: "#bfdbfe",
|
||||
300: "#93c5fd",
|
||||
400: "#60a5fa",
|
||||
500: "#3b82f6",
|
||||
600: "#2563eb",
|
||||
700: "#1d4ed8",
|
||||
800: "#1e40af",
|
||||
900: "#1e3a8a",
|
||||
950: "#172554"
|
||||
},
|
||||
indigo: {
|
||||
50: "#eef2ff",
|
||||
100: "#e0e7ff",
|
||||
200: "#c7d2fe",
|
||||
300: "#a5b4fc",
|
||||
400: "#818cf8",
|
||||
500: "#6366f1",
|
||||
600: "#4f46e5",
|
||||
700: "#4338ca",
|
||||
800: "#3730a3",
|
||||
900: "#312e81",
|
||||
950: "#1e1b4b"
|
||||
},
|
||||
violet: {
|
||||
50: "#f5f3ff",
|
||||
100: "#ede9fe",
|
||||
200: "#ddd6fe",
|
||||
300: "#c4b5fd",
|
||||
400: "#a78bfa",
|
||||
500: "#8b5cf6",
|
||||
600: "#7c3aed",
|
||||
700: "#6d28d9",
|
||||
800: "#5b21b6",
|
||||
900: "#4c1d95",
|
||||
950: "#2e1065"
|
||||
},
|
||||
purple: {
|
||||
50: "#faf5ff",
|
||||
100: "#f3e8ff",
|
||||
200: "#e9d5ff",
|
||||
300: "#d8b4fe",
|
||||
400: "#c084fc",
|
||||
500: "#a855f7",
|
||||
600: "#9333ea",
|
||||
700: "#7e22ce",
|
||||
800: "#6b21a8",
|
||||
900: "#581c87",
|
||||
950: "#3b0764"
|
||||
},
|
||||
fuchsia: {
|
||||
50: "#fdf4ff",
|
||||
100: "#fae8ff",
|
||||
200: "#f5d0fe",
|
||||
300: "#f0abfc",
|
||||
400: "#e879f9",
|
||||
500: "#d946ef",
|
||||
600: "#c026d3",
|
||||
700: "#a21caf",
|
||||
800: "#86198f",
|
||||
900: "#701a75",
|
||||
950: "#4a044e"
|
||||
},
|
||||
pink: {
|
||||
50: "#fdf2f8",
|
||||
100: "#fce7f3",
|
||||
200: "#fbcfe8",
|
||||
300: "#f9a8d4",
|
||||
400: "#f472b6",
|
||||
500: "#ec4899",
|
||||
600: "#db2777",
|
||||
700: "#be185d",
|
||||
800: "#9d174d",
|
||||
900: "#831843",
|
||||
950: "#500724"
|
||||
},
|
||||
rose: {
|
||||
50: "#fff1f2",
|
||||
100: "#ffe4e6",
|
||||
200: "#fecdd3",
|
||||
300: "#fda4af",
|
||||
400: "#fb7185",
|
||||
500: "#f43f5e",
|
||||
600: "#e11d48",
|
||||
700: "#be123c",
|
||||
800: "#9f1239",
|
||||
900: "#881337",
|
||||
950: "#4c0519"
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body class="bg-modern-dark-black text-gold-300 max-w-4xl">
|
||||
<div id="app" class="min-h-screen p-2">
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<div class="bg-modern-black p-6 rounded-lg shadow-lg">
|
||||
<!-- Logo -->
|
||||
<div class="flex justify-center">
|
||||
<img src="https://modernuo.com/branding/logo.svg" class="h-24 w-24">
|
||||
</div>
|
||||
<!-- Title -->
|
||||
<h1 class="text-center text-white text-3xl opacity-70 p-2 pb-12 font-light">ModernUO Commands</h1>
|
||||
<!-- Tabs -->
|
||||
<ul id="tabs" class="flex mb-0 list-none flex-wrap pt-3 pb-4 flex-row place-content-center">
|
||||
<!-- JavaScript will populate tabs here -->
|
||||
</ul>
|
||||
<!-- Tab Content -->
|
||||
<div id="tabContent" class="p-4 border-t border-gold-500">
|
||||
<!-- JavaScript will populate tab content here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Toolip -->
|
||||
<div id="tooltip" class="absolute p-2 bg-modern-black text-white rounded-md shadow-lg max-w-lg hidden"></div>
|
||||
<span id="commands" style="display:none; visibility: hidden">
|
||||
<!-- COMMANDS -->
|
||||
</span>
|
||||
<span id="modifiers" style="display:none; visibility: hidden">
|
||||
<!-- MODIFIERS -->
|
||||
</span>
|
||||
<script>
|
||||
/*
|
||||
Modifiers Structure:
|
||||
{
|
||||
"modifier": {
|
||||
name: "Modifier",
|
||||
usage: "[modifier <command> [condition]",
|
||||
description: "long description. Optional condition arguments can further restrict the set of objects."
|
||||
}
|
||||
}
|
||||
*/
|
||||
let allModifiers = {};
|
||||
|
||||
try {
|
||||
allModifiers = JSON.parse(document.querySelectorAll('#modifiers')[0].innerText.trim() || {});
|
||||
} catch {}
|
||||
|
||||
/*
|
||||
Commands Structure:
|
||||
{
|
||||
"AccessLevel": [
|
||||
{
|
||||
command: "CommandName",
|
||||
aliases: ["cn"],
|
||||
usage: "CommandName <options>",
|
||||
modifiers: ["Global", "Online", "Region", "Multi", "Area", "Self"],
|
||||
description: "Long Description"
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
let commands = {};
|
||||
|
||||
try {
|
||||
commands = JSON.parse(document.querySelectorAll('#commands')[0].innerText.trim() || {});
|
||||
} catch {}
|
||||
|
||||
function createTab(name, selected) {
|
||||
const tab = document.createElement("li");
|
||||
tab.className = "mr-2 last:mr-0 flex-auto text-center";
|
||||
const tabLink = document.createElement("a");
|
||||
tabLink.href = "#";
|
||||
tabLink.className = "text-xs font-bold uppercase px-5 py-3 rounded block leading-normal text-white bg-modern-black hover:bg-modern-black-hover hover:bg-opacity-70 transition-background-color ease-in-out duration-700";
|
||||
|
||||
tabLink.innerText = name;
|
||||
tabLink.onclick = function (e) {
|
||||
e.preventDefault();
|
||||
document.querySelectorAll("#tabs a").forEach(tab => {
|
||||
tab.classList.remove("bg-gold-500", "text-modern-black");
|
||||
tab.classList.add("bg-modern-black", "text-white", "hover:bg-modern-black-hover", "hover:bg-opacity-70");
|
||||
});
|
||||
tabLink.classList.remove("bg-gold-900", "text-white", "hover:bg-modern-black-hover", "hover:bg-opacity-70");
|
||||
tabLink.classList.add("bg-gold-500", "text-modern-black");
|
||||
loadTabContent(name);
|
||||
};
|
||||
|
||||
if (selected) {
|
||||
tabLink.classList.remove("bg-gold-900", "text-white", "hover:bg-modern-black-hover", "hover:bg-opacity-70");
|
||||
tabLink.classList.add("bg-gold-500", "text-modern-black");
|
||||
}
|
||||
tab.appendChild(tabLink);
|
||||
return tab;
|
||||
}
|
||||
|
||||
function createTable(tabData) {
|
||||
let table = `<table class="min-w-full border-collapse table-fixed"><tbody>`;
|
||||
tabData.forEach(item => {
|
||||
table += `
|
||||
<tr class="border-b">
|
||||
<td class="px-4 py-4 text-sm font-medium text-gold-500 w-1/4 "><p>${item.name}</p></td>
|
||||
<td class="text-sm text-gold-900 px-6 py-4">
|
||||
`;
|
||||
|
||||
const usageParts = (item.usage || item.name).split(" ");
|
||||
const usage = `${usageParts[0]} <span class='text-gold-700 font-light'>${usageParts.slice(1).join(" ")}</span>`;
|
||||
|
||||
table += `<div class="text-white">Usage: <span class="font-bold text-gold-500">${usage}</span></div>`;
|
||||
|
||||
if (item.aliases && item.aliases.length > 0) {
|
||||
table += `<div class="text-white">Aliases: <span class="text-gold-500">${item.aliases.join(", ")}</span></div>`;
|
||||
}
|
||||
|
||||
if (item.modifiers && item.modifiers.length > 0) {
|
||||
table += "<div>";
|
||||
item.modifiers.forEach((mod, index) => {
|
||||
table += `<span class="modifier cursor-pointer italic text-gold-300"
|
||||
data-modifier="${mod}"
|
||||
data-command="${item.name}">${mod}</span>${index !== item.modifiers.length - 1 ? ", " : ""}`;
|
||||
});
|
||||
table += "</div>";
|
||||
}
|
||||
|
||||
if (item.description) {
|
||||
table += `<div class="text-white pt-2">${item.description}</div>`;
|
||||
}
|
||||
table += "</td></tr>";
|
||||
});
|
||||
table += "</tbody></table>";
|
||||
return table;
|
||||
}
|
||||
|
||||
function loadTabContent(tabName) {
|
||||
const tabContent = document.getElementById("tabContent");
|
||||
tabContent.innerHTML = createTable(commands[tabName]);
|
||||
|
||||
// Add event listeners to modifiers
|
||||
const modifiers = document.querySelectorAll(".modifier");
|
||||
modifiers.forEach(modNode => {
|
||||
modNode.addEventListener("mouseenter", (event) => {
|
||||
const mod = allModifiers[modNode.dataset.modifier];
|
||||
const command = modNode.dataset.command.toLowerCase()
|
||||
|
||||
let aliases = "";
|
||||
if (mod.accessors.length > 1) {
|
||||
aliases = `<p class="text-white">Aliases: <span class="text-gold-500">${mod.accessors.slice(1).join(", ")}</span></p>`;
|
||||
}
|
||||
|
||||
const usageParts = (mod.usage || mod.accessors[0]).split(" ");
|
||||
const usage = `${usageParts[0]} <span class='text-gold-700 font-light'>${usageParts.slice(1).join(" ")}</span>`
|
||||
.replace("<command>", command);
|
||||
|
||||
const content = `
|
||||
<p class="font-bold text-gold-500">${mod.accessors[0]}</p>
|
||||
<p class="text-white">Access Level: <span class="text-${mod.accessLevel.toLowerCase()}">${mod.accessLevel}</span></p>
|
||||
${aliases}
|
||||
<p class="text-white">Usage: <span class="font-bold text-gold-500">${usage}</span></p>
|
||||
<p class="italic text-white pt-2">${mod.description}</p>
|
||||
`;
|
||||
showTooltip(event, content);
|
||||
});
|
||||
|
||||
modNode.addEventListener("mouseleave", hideTooltip);
|
||||
});
|
||||
}
|
||||
|
||||
function initTabs() {
|
||||
const tabsContainer = document.getElementById("tabs");
|
||||
Object.keys(commands).forEach((tabName, index) => {
|
||||
const tab = createTab(tabName, index === 0);
|
||||
tabsContainer.appendChild(tab);
|
||||
if (index === 0) { // Load first tab content by default
|
||||
loadTabContent(tabName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Function to show the tooltip
|
||||
function showTooltip(event, content) {
|
||||
const tooltip = document.getElementById("tooltip");
|
||||
tooltip.innerHTML = content;
|
||||
tooltip.style.left = `${event.pageX + 15}px`;
|
||||
tooltip.style.top = `${event.pageY + 15}px`;
|
||||
tooltip.classList.remove("hidden");
|
||||
}
|
||||
|
||||
// Function to hide the tooltip
|
||||
function hideTooltip() {
|
||||
const tooltip = document.getElementById("tooltip");
|
||||
tooltip.classList.add("hidden");
|
||||
}
|
||||
|
||||
const escapeHtml = (unsafe) => {
|
||||
return unsafe.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll("'", "'");
|
||||
}
|
||||
|
||||
initTabs();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue