aboutsummaryrefslogtreecommitdiff
path: root/web/pw-server
diff options
context:
space:
mode:
authorIlion Beyst <ilion.beyst@gmail.com>2022-10-15 20:23:20 +0200
committerIlion Beyst <ilion.beyst@gmail.com>2022-10-15 23:28:36 +0200
commit8feccfeb234b69b1069d6b972f13b77ee2c0459f (patch)
treefce00b2e7eed89813f0932b4fba3ed1e4ff692da /web/pw-server
parentb51b7a331ddfd93675e93d88cf267494b9c1b083 (diff)
downloadplanetwars.dev-8feccfeb234b69b1069d6b972f13b77ee2c0459f.tar.xz
planetwars.dev-8feccfeb234b69b1069d6b972f13b77ee2c0459f.zip
show player logs on view match page
Diffstat (limited to 'web/pw-server')
-rw-r--r--web/pw-server/package.json4
-rw-r--r--web/pw-server/src/lib/components/OutputPane.svelte143
-rw-r--r--web/pw-server/src/lib/components/PlayerLog.svelte152
-rw-r--r--web/pw-server/src/lib/components/Visualizer.svelte13
-rw-r--r--web/pw-server/src/lib/constants.ts11
-rw-r--r--web/pw-server/src/routes/editor.svelte1
-rw-r--r--web/pw-server/src/routes/matches/[match_id].svelte42
-rw-r--r--web/pw-server/svelte.config.js8
8 files changed, 216 insertions, 158 deletions
diff --git a/web/pw-server/package.json b/web/pw-server/package.json
index 474f38c..604a820 100644
--- a/web/pw-server/package.json
+++ b/web/pw-server/package.json
@@ -26,7 +26,7 @@
"prettier": "^2.4.1",
"prettier-plugin-svelte": "^2.4.0",
"sass": "^1.49.7",
- "svelte": "^3.44.0",
+ "svelte": "^3.52.0",
"svelte-check": "^2.2.6",
"svelte-preprocess": "^4.9.4",
"tslib": "^2.3.1",
@@ -41,7 +41,7 @@
"dayjs": "^1.10.7",
"planetwars-rs": "file:../planetwars-rs/pkg",
"pw-visualizer": "file:../pw-visualizer",
- "svelte-select": "^4.4.7"
+ "svelte-select": "^5.0.0-beta.31"
},
"type": "module"
}
diff --git a/web/pw-server/src/lib/components/OutputPane.svelte b/web/pw-server/src/lib/components/OutputPane.svelte
index 91ffadc..68c5c3b 100644
--- a/web/pw-server/src/lib/components/OutputPane.svelte
+++ b/web/pw-server/src/lib/components/OutputPane.svelte
@@ -1,157 +1,22 @@
<script lang="ts">
- import { parsePlayerLog, PlayerLog } from "$lib/log_parser";
+ import PlayerLog from "./PlayerLog.svelte";
export let matchLog: string;
- let playerLog: PlayerLog;
-
- let showRawStderr = false;
-
- const PLURAL_MAP = {
- dispatch: "dispatches",
- ship: "ships",
- };
-
- function pluralize(num: number, word: string): string {
- if (num == 1) {
- return `1 ${word}`;
- } else {
- return `${num} ${PLURAL_MAP[word]}`;
- }
- }
-
- $: if (matchLog) {
- playerLog = parsePlayerLog(1, matchLog);
- } else {
- playerLog = [];
- }
</script>
-<div class="output">
+<div class="output-pane">
<h3 class="output-header">Player log</h3>
- {#if showRawStderr}
- <div class="output-text stderr-text">
- {playerLog.flatMap((turn) => turn.stderr).join("\n")}
- </div>
- {:else}
- <div class="output-text">
- {#each playerLog as logTurn, i}
- <div class="turn">
- <div class="turn-header">
- <span class="turn-header-text">Turn {i}</span>
- {#if logTurn.action?.type === "dispatches"}
- {pluralize(logTurn.action.dispatches.length, "dispatch")}
- {:else if logTurn.action?.type === "timeout"}
- <span class="turn-error">timeout</span>
- {:else if logTurn.action?.type === "bad_command"}
- <span class="turn-error">invalid command</span>
- {/if}
- </div>
- {#if logTurn.action?.type === "dispatches"}
- <div class="dispatches-container">
- {#each logTurn.action.dispatches as dispatch}
- <div class="dispatch">
- <div class="dispatch-text">
- {pluralize(dispatch.ship_count, "ship")} from {dispatch.origin} to {dispatch.destination}
- </div>
- {#if dispatch.error}
- <span class="dispatch-error">{dispatch.error}</span>
- {/if}
- </div>
- {/each}
- </div>
- {:else if logTurn.action?.type === "bad_command"}
- <div class="bad-command-container">
- <div class="bad-command-text">{logTurn.action.command}</div>
- <div class="bad-command-error">Parse error: {logTurn.action.error}</div>
- </div>
- {/if}
- {#if logTurn.stderr.length > 0}
- <div class="stderr-header">stderr</div>
- <div class="stderr-text-box">
- {#each logTurn.stderr as stdErrMsg}
- <div class="stderr-text">{stdErrMsg}</div>
- {/each}
- </div>
- {/if}
- </div>
- {/each}
- </div>
- {/if}
+ <PlayerLog {matchLog} playerId={1} />
</div>
<style lang="scss">
- .output {
+ .output-pane {
width: 100%;
overflow-y: scroll;
background-color: rgb(41, 41, 41);
padding: 15px;
}
- .turn {
- margin: 16px 4px;
- }
-
- .output-text {
- color: #ccc;
- }
-
- .turn-header {
- display: flex;
- justify-content: space-between;
- }
-
- .turn-header-text {
- color: #eee;
- font-size: 14px;
- font-weight: 600;
- text-transform: uppercase;
- }
-
- .turn-error {
- color: red;
- }
-
- .dispatch {
- display: flex;
- justify-content: space-between;
- }
-
- .dispatch-error {
- color: red;
- }
-
- .bad-command-container {
- border-left: 1px solid red;
- margin-left: 4px;
- padding-left: 8px;
- }
-
- .bad-command-text {
- font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace;
- padding-bottom: 4px;
- }
-
- .bad-command-error {
- color: whitesmoke;
- }
-
- .stderr-text {
- // font-family: monospace;
- font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace;
- white-space: pre-wrap;
- }
-
- .stderr-header {
- color: #eee;
- padding-top: 4px;
- }
-
- .stderr-text-box {
- border-left: 1px solid #ccc;
- margin-left: 4px;
- padding-left: 8px;
- }
-
.output-header {
color: #eee;
padding-bottom: 20px;
diff --git a/web/pw-server/src/lib/components/PlayerLog.svelte b/web/pw-server/src/lib/components/PlayerLog.svelte
new file mode 100644
index 0000000..52cae8e
--- /dev/null
+++ b/web/pw-server/src/lib/components/PlayerLog.svelte
@@ -0,0 +1,152 @@
+<script lang="ts">
+ import { parsePlayerLog, PlayerLog } from "$lib/log_parser";
+
+ export let matchLog: string;
+ export let playerId: number;
+
+ let playerLog: PlayerLog;
+
+ let showRawStderr = false;
+
+ const PLURAL_MAP = {
+ dispatch: "dispatches",
+ ship: "ships",
+ };
+
+ function pluralize(num: number, word: string): string {
+ if (num == 1) {
+ return `1 ${word}`;
+ } else {
+ return `${num} ${PLURAL_MAP[word]}`;
+ }
+ }
+
+ $: if (matchLog) {
+ playerLog = parsePlayerLog(playerId, matchLog);
+ } else {
+ playerLog = [];
+ }
+</script>
+
+<div class="output">
+ {#if showRawStderr}
+ <div class="output-text stderr-text">
+ {playerLog.flatMap((turn) => turn.stderr).join("\n")}
+ </div>
+ {:else}
+ <div class="output-text">
+ {#each playerLog as logTurn, i}
+ <div class="turn">
+ <div class="turn-header">
+ <span class="turn-header-text">Turn {i}</span>
+ {#if logTurn.action?.type === "dispatches"}
+ {pluralize(logTurn.action.dispatches.length, "dispatch")}
+ {:else if logTurn.action?.type === "timeout"}
+ <span class="turn-error">timeout</span>
+ {:else if logTurn.action?.type === "bad_command"}
+ <span class="turn-error">invalid command</span>
+ {/if}
+ </div>
+ {#if logTurn.action?.type === "dispatches"}
+ <div class="dispatches-container">
+ {#each logTurn.action.dispatches as dispatch}
+ <div class="dispatch">
+ <div class="dispatch-text">
+ {pluralize(dispatch.ship_count, "ship")} from {dispatch.origin} to {dispatch.destination}
+ </div>
+ {#if dispatch.error}
+ <span class="dispatch-error">{dispatch.error}</span>
+ {/if}
+ </div>
+ {/each}
+ </div>
+ {:else if logTurn.action?.type === "bad_command"}
+ <div class="bad-command-container">
+ <div class="bad-command-text">{logTurn.action.command}</div>
+ <div class="bad-command-error">Parse error: {logTurn.action.error}</div>
+ </div>
+ {/if}
+ {#if logTurn.stderr.length > 0}
+ <div class="stderr-header">stderr</div>
+ <div class="stderr-text-box">
+ {#each logTurn.stderr as stdErrMsg}
+ <div class="stderr-text">{stdErrMsg}</div>
+ {/each}
+ </div>
+ {/if}
+ </div>
+ {/each}
+ </div>
+ {/if}
+</div>
+
+<style lang="scss">
+ .output {
+ background-color: rgb(41, 41, 41);
+ }
+
+ .turn {
+ margin: 16px 4px;
+ }
+
+ .output-text {
+ color: #ccc;
+ }
+
+ .turn-header {
+ display: flex;
+ justify-content: space-between;
+ }
+
+ .turn-header-text {
+ color: #eee;
+ font-size: 14px;
+ font-weight: 600;
+ text-transform: uppercase;
+ }
+
+ .turn-error {
+ color: red;
+ }
+
+ .dispatch {
+ display: flex;
+ justify-content: space-between;
+ }
+
+ .dispatch-error {
+ color: red;
+ }
+
+ .bad-command-container {
+ border-left: 1px solid red;
+ margin-left: 4px;
+ padding-left: 8px;
+ }
+
+ .bad-command-text {
+ font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace;
+ padding-bottom: 4px;
+ }
+
+ .bad-command-error {
+ color: whitesmoke;
+ }
+
+ .stderr-text {
+ // font-family: monospace;
+ font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace;
+ white-space: pre-wrap;
+ }
+
+ .stderr-header {
+ color: #eee;
+ padding-top: 4px;
+ }
+
+ .stderr-text-box {
+ border-left: 1px solid #ccc;
+ margin-left: 4px;
+ padding-left: 8px;
+ }
+</style>
diff --git a/web/pw-server/src/lib/components/Visualizer.svelte b/web/pw-server/src/lib/components/Visualizer.svelte
index 8517a39..4fe8ab4 100644
--- a/web/pw-server/src/lib/components/Visualizer.svelte
+++ b/web/pw-server/src/lib/components/Visualizer.svelte
@@ -2,24 +2,13 @@
import { onDestroy, onMount } from "svelte";
import * as visualizer from "pw-visualizer";
import init_wasm_module from "planetwars-rs";
+ import { PLAYER_COLORS } from "$lib/constants";
export let matchLog = null;
export let matchData: object; // match object as returned by api
let initialized = false;
- const PLAYER_COLORS = [
- "#ff8000",
- "#0080ff",
- "#ff6693",
- "#3fcb55",
- "#cbc33f",
- "#cf40e9",
- "#ff3f0d",
- "#1beef0",
- "#0dc5ff",
- ];
-
onMount(async () => {
await init_wasm_module();
diff --git a/web/pw-server/src/lib/constants.ts b/web/pw-server/src/lib/constants.ts
new file mode 100644
index 0000000..208bf09
--- /dev/null
+++ b/web/pw-server/src/lib/constants.ts
@@ -0,0 +1,11 @@
+export const PLAYER_COLORS = [
+ "#ff8000",
+ "#0080ff",
+ "#ff6693",
+ "#3fcb55",
+ "#cbc33f",
+ "#cf40e9",
+ "#ff3f0d",
+ "#1beef0",
+ "#0dc5ff",
+];
diff --git a/web/pw-server/src/routes/editor.svelte b/web/pw-server/src/routes/editor.svelte
index ff8232c..ee4eef9 100644
--- a/web/pw-server/src/routes/editor.svelte
+++ b/web/pw-server/src/routes/editor.svelte
@@ -12,7 +12,6 @@
import { debounce } from "$lib/utils";
import SubmitPane from "$lib/components/SubmitPane.svelte";
import OutputPane from "$lib/components/OutputPane.svelte";
- import BotName from "./bots/[bot_name].svelte";
enum ViewMode {
Editor,
diff --git a/web/pw-server/src/routes/matches/[match_id].svelte b/web/pw-server/src/routes/matches/[match_id].svelte
index 11d6ee3..25438ad 100644
--- a/web/pw-server/src/routes/matches/[match_id].svelte
+++ b/web/pw-server/src/routes/matches/[match_id].svelte
@@ -22,6 +22,9 @@
<script lang="ts">
import { onMount } from "svelte";
import Visualizer from "$lib/components/Visualizer.svelte";
+ import PlayerLog from "$lib/components/PlayerLog.svelte";
+ import Select from "svelte-select";
+ import { PLAYER_COLORS } from "$lib/constants";
export let matchLog: string | undefined;
export let matchData: object;
@@ -30,13 +33,35 @@
const apiClient = new ApiClient();
matchLog = await apiClient.getText(`/api/matches/${matchData["id"]}/log`);
});
+
+ let selectedPlayer;
+
+ $: matchPlayerSelectItems = matchData["players"].map((player: any, index: number) => ({
+ color: PLAYER_COLORS[index],
+ value: index,
+ playerId: index + 1, // stoopid player number + 1
+ label: player["bot_name"],
+ }));
</script>
<div class="container">
<Visualizer {matchLog} {matchData} />
+ <div class="output-pane">
+ <div class="player-select">
+ <Select items={matchPlayerSelectItems} clearable={false} bind:value={selectedPlayer}>
+ <div slot="item" let:item>
+ <span style:color={item.color}>{item.label}</span>
+ </div>
+ </Select>
+ </div>
+ <div class="player-log">
+ <PlayerLog {matchLog} playerId={selectedPlayer?.playerId} />
+ </div>
+ </div>
</div>
<style lang="scss">
+ @use "src/styles/variables";
.container {
display: flex;
// these are needed for making the visualizer fill the screen.
@@ -44,4 +69,21 @@
flex-grow: 1;
overflow: hidden;
}
+
+ .player-select {
+ padding: 20px;
+ }
+
+ .player-log {
+ padding: 15px;
+ overflow-y: scroll;
+ }
+
+ .output-pane {
+ width: 600px;
+ // overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ background-color: variables.$bg-color;
+ }
</style>
diff --git a/web/pw-server/svelte.config.js b/web/pw-server/svelte.config.js
index fe396f9..02b4db9 100644
--- a/web/pw-server/svelte.config.js
+++ b/web/pw-server/svelte.config.js
@@ -12,13 +12,13 @@ const config = {
preprocess: [
sveltePreprocess(),
mdsvex({
- extensions: ['.md'],
+ extensions: [".md"],
layout: {
- docs: 'src/routes/docs/doc.svelte',
- }
+ docs: "src/routes/docs/doc.svelte",
+ },
}),
],
- extensions: ['.svelte', '.md'],
+ extensions: [".svelte", ".md"],
kit: {
adapter: adapter(),