Richer player profiles, launcher command guide, integration docs

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DjMbLQujBHunCCu5GpsHaT
This commit is contained in:
Claude committed 2026-09-30 18:29:07 +00:00
1 parent 745c2178ee
commit 9dc7f12fb0
13 files changed
+655 -13

No files matched your search

+142
View File
@@ -0,0 +1,142 @@
<script lang="ts">
import { Terminal, Search, Copy, Check } from '@lucide/svelte';
type Cmd = { usage: string; does: string; perm: string; aliases?: string[] };
type Group = { title: string; blurb: string; cmds: Cmd[] };
const groups: Group[] = [
{ title: 'Getting around', blurb: 'Teleports, homes and warps.', cmds: [
{ usage: '/spawn', does: 'Teleport to the server spawn.', perm: 'scopenet.command.spawn', aliases: ['hub', 'lobby'] },
{ usage: '/home [name]', does: 'Teleport to a home, or open the homes menu.', perm: 'scopenet.command.home', aliases: ['homes'] },
{ usage: '/sethome [name]', does: 'Save your current spot as a home.', perm: 'scopenet.command.sethome' },
{ usage: '/delhome <name>', does: 'Delete one of your homes.', perm: 'scopenet.command.delhome', aliases: ['rmhome'] },
{ usage: '/back', does: 'Return to where you were, or where you died.', perm: 'scopenet.command.back', aliases: ['return'] },
{ usage: '/warp [name]', does: 'Go to a server warp, or open the warps menu.', perm: 'scopenet.command.warp', aliases: ['warps'] },
{ usage: '/rtp', does: 'Jump to a random safe spot in the wild.', perm: 'scopenet.command.rtp', aliases: ['wild', 'randomtp'] },
{ usage: '/tpa <player>', does: 'Ask to teleport to another player.', perm: 'scopenet.command.tpa' },
{ usage: '/tpaccept', does: 'Accept a teleport request.', perm: 'scopenet.command.tpaccept', aliases: ['tpyes'] },
{ usage: '/tpdeny', does: 'Decline a teleport request.', perm: 'scopenet.command.tpdeny', aliases: ['tpno'] },
] },
{ title: 'Money & trading', blurb: 'Your balance, the shop, the market and player trades.', cmds: [
{ usage: '/balance', does: 'Check your balance.', perm: 'scopenet.command.balance', aliases: ['bal', 'money'] },
{ usage: '/pay <player> <amount>', does: 'Send money to a player.', perm: 'scopenet.command.pay' },
{ usage: '/baltop', does: 'See the richest players.', perm: 'scopenet.command.baltop', aliases: ['richest'] },
{ usage: '/shop', does: 'Open the server shop.', perm: 'scopenet.command.shop' },
{ usage: '/sell hand', does: 'Sell the item in your hand to the shop.', perm: 'scopenet.command.sell.hand' },
{ usage: '/sell', does: 'Open the selling menu.', perm: 'scopenet.command.sell' },
{ usage: '/market', does: 'Browse and buy from the player market.', perm: 'scopenet.command.market', aliases: ['ah', 'auction'] },
{ usage: '/market sell <price>', does: 'List the item in your hand on the market.', perm: 'scopenet.command.market.sell' },
{ usage: '/orders', does: 'View your active market orders.', perm: 'scopenet.command.orders' },
{ usage: '/trade <player>', does: 'Start a secure trade with another player.', perm: 'scopenet.command.trade' },
{ usage: '/transactions', does: 'See your recent money movements.', perm: 'scopenet.command.transactions' },
] },
{ title: 'Guilds & land', blurb: 'Team up, claim land and protect it.', cmds: [
{ usage: '/guild', does: 'Open your guild dashboard.', perm: 'scopenet.command.guild', aliases: ['g', 'clan'] },
{ usage: '/guild create <name> <tag>', does: 'Found a new guild.', perm: 'scopenet.command.guild.create' },
{ usage: '/guild leave', does: 'Leave your guild.', perm: 'scopenet.command.guild.leave' },
{ usage: '/guild members', does: 'List your guild members.', perm: 'scopenet.command.guild.members' },
{ usage: '/guild chat <message>', does: 'Talk to your guild only.', perm: 'scopenet.command.guild.chat', aliases: ['/guild c'] },
{ usage: '/guild sethome · /guild home', does: 'Set or visit the guild home.', perm: 'scopenet.command.guild.sethome' },
{ usage: '/guild map', does: 'Show nearby claims on a map.', perm: 'scopenet.command.guild.map' },
{ usage: '/claim', does: 'Claim the chunk you stand in for your guild.', perm: 'scopenet.command.claim' },
{ usage: '/unclaim', does: 'Give up the chunk you stand in.', perm: 'scopenet.command.unclaim' },
] },
{ title: 'Guild bank', blurb: 'Shared guild money. Officers and leaders can spend it.', cmds: [
{ usage: '/guild bank', does: 'Show the bank balance and recent activity.', perm: 'scopenet.command.guild.bank' },
{ usage: '/guild bank deposit <amount>', does: 'Put your own money into the bank.', perm: 'scopenet.command.guild.bank.deposit' },
{ usage: '/guild bank withdraw <amount>', does: 'Take money out (officers and leaders).', perm: 'scopenet.command.guild.bank.withdraw' },
{ usage: '/guild sell hand', does: 'Sell your held item and pay the bank.', perm: 'scopenet.command.guild.sell' },
{ usage: '/guild market', does: 'Buy and sell on the market as your guild.', perm: 'scopenet.command.guild.market' },
{ usage: '/guild pay <tag> <amount>', does: 'Pay another guild from your bank.', perm: 'scopenet.command.guild.pay' },
] },
{ title: 'Info & admin', blurb: 'Status and help.', cmds: [
{ usage: '/playtime', does: 'Check your total and session playtime.', perm: 'scopenet.command.playtime', aliases: ['ontime'] },
{ usage: '/scopenet help', does: 'List SCOPENET commands.', perm: 'scopenet.command.scopenet.help', aliases: ['sn'] },
{ usage: '/scopenet status', does: 'Panel connection, features and plugin integrations (admins).', perm: 'scopenet.command.scopenet.status' },
{ usage: '/scopenet reload', does: 'Reload the plugin config (admins).', perm: 'scopenet.command.scopenet.reload' },
] },
];
const tips = [
'Placeholders: use %scopenet_level%, %scopenet_guild%, %scopenet_balance% and more in scoreboards, tab and chat.',
'Some commands may be switched off or limited by the server. If one says you lack permission, ask an admin.',
'Everything here also works through your rank: servers using LuckPerms can grant each permission node to any group.',
];
let query = $state('');
let copied = $state('');
const q = $derived(query.trim().toLowerCase());
const shown = $derived(
groups
.map((g) => ({ ...g, cmds: g.cmds.filter((c) => !q || `${c.usage} ${c.does} ${c.perm} ${(c.aliases ?? []).join(' ')}`.toLowerCase().includes(q)) }))
.filter((g) => g.cmds.length)
);
async function copy(c: Cmd) {
const text = c.usage.split(' · ')[0];
try { await navigator.clipboard.writeText(text); } catch { /* clipboard may be unavailable */ }
copied = c.usage;
setTimeout(() => (copied = ''), 1200);
}
</script>
<div class="page">
<div class="head">
<div>
<h1><Terminal size={26} class="ic" /> Command guide</h1>
<p class="lead">Everything you can type in-game on SCOPENET servers. Click a command to copy it.</p>
</div>
<label class="search"><Search size={15} /><input bind:value={query} placeholder="Search commands" aria-label="Search commands" /></label>
</div>
{#each shown as g (g.title)}
<section class="group">
<div class="gh"><h2>{g.title}</h2><span class="muted tiny">{g.blurb}</span></div>
<div class="list">
{#each g.cmds as c (c.usage)}
<button class="cmd glass" onclick={() => copy(c)} title="Copy command">
<code class="usage">{c.usage}</code>
<span class="does">{c.does}</span>
<span class="meta">
{#each c.aliases ?? [] as a}<span class="alias">/{a.replace(/^\//, '')}</span>{/each}
<span class="perm" title="LuckPerms permission node">{c.perm}</span>
</span>
<span class="copy">{#if copied === c.usage}<Check size={14} />{:else}<Copy size={14} />{/if}</span>
</button>
{/each}
</div>
</section>
{:else}
<p class="muted">No commands match “{query}”.</p>
{/each}
<section class="tips glass">
<h2>Good to know</h2>
<ul>{#each tips as t}<li>{t}</li>{/each}</ul>
</section>
</div>
<style>
.page { flex: 1; display: flex; flex-direction: column; overflow-y: auto; padding: 1.6rem 2.2rem 2.5rem; gap: 1.2rem; }
.head { display: flex; justify-content: space-between; align-items: flex-end; gap: 1rem; flex-wrap: wrap; border-bottom: 1px solid var(--line); padding-bottom: 1rem; }
h1 { font-size: 1.5rem; font-weight: 700; display: flex; align-items: center; gap: 0.6rem; margin: 0; }
:global(.ic) { color: var(--accent); }
.lead { color: var(--muted); font-size: 0.88rem; margin: 0.2rem 0 0; }
.search { display: flex; align-items: center; gap: 0.5rem; padding: 0.4rem 0.75rem; border-radius: var(--radius-sm); border: 1px solid var(--line); background: color-mix(in srgb, var(--surface) 80%, transparent); min-width: 14rem; }
.search input { background: transparent; border: none; outline: none; color: var(--text); flex: 1; font-size: 0.85rem; }
.group { display: flex; flex-direction: column; gap: 0.6rem; }
.gh { display: flex; align-items: baseline; gap: 0.7rem; flex-wrap: wrap; }
.gh h2 { font-size: 1.05rem; margin: 0; }
.list { display: grid; grid-template-columns: repeat(auto-fill, minmax(21rem, 1fr)); gap: 0.6rem; }
.cmd { position: relative; display: flex; flex-direction: column; gap: 0.3rem; text-align: left; padding: 0.75rem 2.2rem 0.75rem 0.9rem; border-radius: var(--radius-sm); border: 1px solid var(--line); transition: border-color 0.15s, transform 0.15s; }
.cmd:hover { border-color: var(--accent); transform: translateY(-1px); }
.usage { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.88rem; font-weight: 650; color: var(--accent); }
.does { font-size: 0.83rem; color: var(--text); line-height: 1.35; }
.meta { display: flex; flex-wrap: wrap; gap: 0.35rem; align-items: center; }
.alias { font-size: 0.68rem; padding: 0.05rem 0.45rem; border-radius: 99rem; background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--muted); }
.perm { font-family: ui-monospace, monospace; font-size: 0.66rem; color: var(--muted); opacity: 0.85; }
.copy { position: absolute; top: 0.7rem; right: 0.75rem; color: var(--muted); }
.tips { padding: 1rem 1.2rem; border-radius: var(--radius-sm); border: 1px solid var(--line); }
.tips h2 { font-size: 0.95rem; margin: 0 0 0.4rem; }
.tips ul { margin: 0; padding-left: 1.1rem; display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.83rem; color: var(--muted); }
</style>