player lists
This commit is contained in:
parent
b63db82a99
commit
6e582e11dc
@ -1,9 +1,9 @@
|
|||||||
import { VNode } from "preact";
|
import { FunctionComponent } from "preact";
|
||||||
|
|
||||||
export function Content(props: { children?: VNode | VNode[] }) {
|
export const Content: FunctionComponent = ({ children }) => {
|
||||||
return (
|
return (
|
||||||
<div class="bg-smoke-200 dark:bg-smoke-900 border-4 border-licorice-800 p-8 rounded-3xl">
|
<div class="bg-smoke-200 dark:bg-smoke-900 border-4 border-licorice-800 p-8 rounded-3xl">
|
||||||
{props.children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
@ -1,19 +1,23 @@
|
|||||||
import { VNode, toChildArray } from "preact";
|
import { FunctionComponent, toChildArray } from "preact";
|
||||||
|
|
||||||
export function OL(props: {children?: VNode | VNode[], color?: string;}) {
|
export const OL: FunctionComponent<{ color?: string }> = (props) => {
|
||||||
const childs = toChildArray(props.children);
|
const childs = toChildArray(props.children);
|
||||||
props.color = props.color || 'bg-sky';
|
props.color = props.color || "bg-sky";
|
||||||
return (
|
return (
|
||||||
<ol>
|
<ol>
|
||||||
{childs.map((c,i) => (
|
{childs.map((c, i) => (
|
||||||
<li class="flex gap-4 p-1 even:bg-black/10">
|
<li class="flex gap-4 p-1 even:bg-black/10">
|
||||||
<div class={`w-16 h-16 relative p-2 ${props.color} rounded-md text-white`}>
|
<div
|
||||||
<span class="text-6xl font-pixel absolute -bottom-1 right-0 text-smoke-800/30">{i+1}</span>
|
class={`w-16 h-16 relative p-2 ${props.color} rounded-md text-white`}
|
||||||
<span class="text-5xl font-pixel">{i+1}</span>
|
>
|
||||||
|
<span class="text-6xl font-pixel absolute -bottom-1 right-0 text-smoke-800/30">
|
||||||
|
{i + 1}
|
||||||
|
</span>
|
||||||
|
<span class="text-5xl font-pixel">{i + 1}</span>
|
||||||
</div>
|
</div>
|
||||||
{c}
|
{c}
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ol>
|
</ol>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
@ -3,8 +3,16 @@ import { StatusManager } from "./statusManager.tsx";
|
|||||||
import { IS_BROWSER } from "$fresh/runtime.ts";
|
import { IS_BROWSER } from "$fresh/runtime.ts";
|
||||||
import { PlayerData } from "../util/players.ts";
|
import { PlayerData } from "../util/players.ts";
|
||||||
import { Button } from "../components/Button.tsx";
|
import { Button } from "../components/Button.tsx";
|
||||||
|
import { JSX } from "preact/jsx-runtime";
|
||||||
|
import { FunctionComponent } from "preact";
|
||||||
|
|
||||||
export function ActivePlayerList() {
|
export function PlayerList(
|
||||||
|
{ whitelist, banlist, oplist }: {
|
||||||
|
whitelist: PlayerData[];
|
||||||
|
banlist: PlayerData[];
|
||||||
|
oplist: PlayerData[];
|
||||||
|
},
|
||||||
|
) {
|
||||||
const [players, setPlayers] = useState<PlayerData[]>([]);
|
const [players, setPlayers] = useState<PlayerData[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -29,27 +37,51 @@ export function ActivePlayerList() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div class="flex flex-col gap-8">
|
||||||
<StatusManager onAction={followStatusManager} />
|
<StatusManager onAction={followStatusManager} />
|
||||||
<div class="grid grid-cols-2 p-8">
|
<div class="grid grid-cols-2 p-8 bg-black/50 rounded-3xl">
|
||||||
<h2 class="col-span-2 font-pixel text-xl">Active Players</h2>
|
<h2 class="col-span-2 font-pixel text-xl">Active Players</h2>
|
||||||
{players.map((p) => <PlayerCard player={p} />)}
|
{players.map((p) => <PlayerCard player={p} />)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="grid grid-cols-3 gap-8 rounded-3xl">
|
||||||
);
|
<div class="flex flex-col gap-4 bg-smoke p-4 rounded-3xl">
|
||||||
}
|
<h2 className="font-pixel text-xl">Whitelisted Players</h2>
|
||||||
|
{whitelist.map((p) => <PlayerCard player={p} />)}
|
||||||
function PlayerCard({ player }: { player: PlayerData }) {
|
</div>
|
||||||
return (
|
<div class="flex flex-col gap-4 bg-smoke p-4 rounded-3xl">
|
||||||
<div class="flex gap-4">
|
<h2 className="font-pixel text-xl">Banned Players</h2>
|
||||||
<img class="w-16" src={player.avatar} alt={`${player.username}'s avatar`} />
|
{banlist.map((p) => (
|
||||||
<div>
|
<PlayerCard player={p}>
|
||||||
<h3>{player.username}</h3>
|
{!!p.banReason && <p>{p.banReason}</p>}
|
||||||
<small class="opacity-50">UUID: {player.id}</small>
|
</PlayerCard>
|
||||||
<div>
|
))}
|
||||||
Did you know that bats are the only mammal that can fly?
|
</div>
|
||||||
|
<div class="flex flex-col gap-4 bg-smoke p-4 rounded-3xl">
|
||||||
|
<h2 className="font-pixel text-xl">Ops</h2>
|
||||||
|
{oplist.map((p) => <PlayerCard player={p} />)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PlayerCard: FunctionComponent<{ player: PlayerData }> = (
|
||||||
|
{ player, children },
|
||||||
|
) => {
|
||||||
|
return (
|
||||||
|
<div class="flex gap-4">
|
||||||
|
<img
|
||||||
|
class="w-24 rounded-md"
|
||||||
|
src={player.avatar}
|
||||||
|
alt={`${player.username}'s avatar`}
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<h3>{player.username}</h3>
|
||||||
|
<small class="opacity-50">UUID: {player.id}</small>
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
@ -10,7 +10,6 @@ export function StatusManager(
|
|||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
const sendCommand = async (action: ManageAction) => {
|
const sendCommand = async (action: ManageAction) => {
|
||||||
console.log(action);
|
|
||||||
const res = await fetch("/api/manage", {
|
const res = await fetch("/api/manage", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: action,
|
body: action,
|
||||||
|
@ -23,7 +23,6 @@ export function Terminal(props: { channelId: string }) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
document.addEventListener('keyup', (e) => {
|
document.addEventListener('keyup', (e) => {
|
||||||
console.log(e.key)
|
|
||||||
switch (e.key) {
|
switch (e.key) {
|
||||||
case 'Up':
|
case 'Up':
|
||||||
case 'ArrowUp':
|
case 'ArrowUp':
|
||||||
|
@ -7,19 +7,15 @@ export const handler: Handlers = {
|
|||||||
let listener: (e: CustomEvent) => void;
|
let listener: (e: CustomEvent) => void;
|
||||||
const body = new ReadableStream({
|
const body = new ReadableStream({
|
||||||
async start(controller){
|
async start(controller){
|
||||||
console.log('did the thing')
|
|
||||||
if (SERVER_STATE.status !== 'running') return;
|
if (SERVER_STATE.status !== 'running') return;
|
||||||
const players = await getActivePlayers();
|
const players = await getActivePlayers();
|
||||||
|
|
||||||
const event = `event:players\ndata:${JSON.stringify(players)}\n\n`
|
const event = `event:players\ndata:${JSON.stringify(players)}\n\n`
|
||||||
|
|
||||||
controller.enqueue(event);
|
controller.enqueue(event);
|
||||||
console.log('sent the thing')
|
|
||||||
|
|
||||||
listener = async (e: CustomEvent<string>) => {
|
listener = async (e: CustomEvent<string>) => {
|
||||||
console.log('message received')
|
|
||||||
if (e.detail.includes('joined the game') || e.detail.includes('lost connection')) {
|
if (e.detail.includes('joined the game') || e.detail.includes('lost connection')) {
|
||||||
console.log('connection change')
|
|
||||||
const players = await getActivePlayers();
|
const players = await getActivePlayers();
|
||||||
const event = `event: players\ndata: ${JSON.stringify(players)}\n\n`
|
const event = `event: players\ndata: ${JSON.stringify(players)}\n\n`
|
||||||
|
|
||||||
@ -28,10 +24,8 @@ export const handler: Handlers = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
globalThis.addEventListener('stdoutmsg' as any, listener);
|
globalThis.addEventListener('stdoutmsg' as any, listener);
|
||||||
console.log('listened the thing')
|
|
||||||
},
|
},
|
||||||
cancel() {
|
cancel() {
|
||||||
console.log('cancelled')
|
|
||||||
globalThis.removeEventListener('stdoutmsg' as any, listener);
|
globalThis.removeEventListener('stdoutmsg' as any, listener);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1,12 +1,35 @@
|
|||||||
import { Content } from "../components/Content.tsx";
|
import { Content } from "../components/Content.tsx";
|
||||||
import { ActivePlayerList } from "../islands/players.tsx";
|
import { PlayerList } from "../islands/players.tsx";
|
||||||
|
import { getPlayerData, PlayerData } from "../util/players.ts";
|
||||||
|
|
||||||
export default function PlayerManger() {
|
export default async function PlayerManager() {
|
||||||
|
// TODO: change these to support instances
|
||||||
|
const whitelist = await Promise.all<PlayerData[]>(
|
||||||
|
JSON.parse(await Deno.readTextFile("./server/whitelist.json")).map(async (
|
||||||
|
p: { name: string },
|
||||||
|
) => await getPlayerData(p.name)),
|
||||||
|
);
|
||||||
|
const banlist = await Promise.all<PlayerData[]>(
|
||||||
|
JSON.parse(await Deno.readTextFile("./server/banned-players.json")).map(
|
||||||
|
async (
|
||||||
|
p: { name: string; reason: string },
|
||||||
|
) => ({ ...await getPlayerData(p.name), banReason: p.reason }),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
const oplist = await Promise.all<PlayerData[]>(
|
||||||
|
JSON.parse(await Deno.readTextFile("./server/ops.json")).map(async (
|
||||||
|
p: { name: string },
|
||||||
|
) => await getPlayerData(p.name)),
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<div className="container p-8">
|
<div className="container p-8">
|
||||||
<Content>
|
<Content>
|
||||||
<ActivePlayerList />
|
<PlayerList
|
||||||
|
whitelist={whitelist}
|
||||||
|
banlist={banlist}
|
||||||
|
oplist={oplist}
|
||||||
|
/>
|
||||||
</Content>
|
</Content>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
File diff suppressed because one or more lines are too long
@ -8,6 +8,5 @@ export const checkEULA = (instance = "server") =>
|
|||||||
export const acceptEULA = (instance = "server") => {
|
export const acceptEULA = (instance = "server") => {
|
||||||
const eula = Deno.readTextFileSync(`./${instance}/eula.txt`);
|
const eula = Deno.readTextFileSync(`./${instance}/eula.txt`);
|
||||||
const mod = eula.replace(eulaRegex, "eula=true");
|
const mod = eula.replace(eulaRegex, "eula=true");
|
||||||
console.log(mod);
|
|
||||||
!IS_BROWSER && Deno.writeTextFileSync(`./${instance}/eula.txt`, mod);
|
!IS_BROWSER && Deno.writeTextFileSync(`./${instance}/eula.txt`, mod);
|
||||||
};
|
};
|
||||||
|
@ -23,9 +23,10 @@ export type PlayerData = {
|
|||||||
username: string;
|
username: string;
|
||||||
id: string;
|
id: string;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
|
banReason?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPlayerData = async (username: string) => {
|
export const getPlayerData = async (username: string) => {
|
||||||
username = username.trim();
|
username = username.trim();
|
||||||
if (!username) return;
|
if (!username) return;
|
||||||
const cacheFile = 'players.cache.json'
|
const cacheFile = 'players.cache.json'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user