diff options
author | metamuffin <metamuffin@disroot.org> | 2024-09-17 21:33:08 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-09-17 21:33:08 +0200 |
commit | 976e2fc3e25bfd08c755aa222a45c42a53b0b8e0 (patch) | |
tree | e73b304827d149770a94b533569b08aa35ac4cad /test-client | |
parent | 666adbf669afc06d87aa28f1a8ca120c5612d3a4 (diff) | |
download | hurrycurry-976e2fc3e25bfd08c755aa222a45c42a53b0b8e0.tar hurrycurry-976e2fc3e25bfd08c755aa222a45c42a53b0b8e0.tar.bz2 hurrycurry-976e2fc3e25bfd08c755aa222a45c42a53b0b8e0.tar.zst |
tc: localization
Diffstat (limited to 'test-client')
-rw-r--r-- | test-client/.gitignore | 2 | ||||
-rw-r--r-- | test-client/locale.ts | 14 | ||||
-rw-r--r-- | test-client/main.ts | 4 | ||||
-rw-r--r-- | test-client/makefile | 13 | ||||
-rw-r--r-- | test-client/protocol.ts | 1 | ||||
-rw-r--r-- | test-client/visual.ts | 30 |
6 files changed, 58 insertions, 6 deletions
diff --git a/test-client/.gitignore b/test-client/.gitignore new file mode 100644 index 00000000..27b9b44d --- /dev/null +++ b/test-client/.gitignore @@ -0,0 +1,2 @@ +/locale +/*.js diff --git a/test-client/locale.ts b/test-client/locale.ts new file mode 100644 index 00000000..61d083b4 --- /dev/null +++ b/test-client/locale.ts @@ -0,0 +1,14 @@ + +let TR: { [key: string]: string } = {} +export async function init_locale(lang: string) { + const res = await fetch(`/locale/${encodeURIComponent(lang)}.json`, { headers: { "Accept": "application/json" } }) + if (!res.ok) throw new Error("language pack download failed"); + TR = await res.json() +} + +export function tr(key: string, ...args: string[]): string { + let s = TR[key] ?? key; + if (args.length) + s = s.replace(/%(s|i)/ig, () => args.shift() ?? "[not provided]") + return s +} diff --git a/test-client/main.ts b/test-client/main.ts index 875e420d..f48aef17 100644 --- a/test-client/main.ts +++ b/test-client/main.ts @@ -17,6 +17,7 @@ */ /// <reference lib="dom" /> +import { init_locale } from "./locale.ts"; import { MovementBase, collide_player_player, update_movement } from "./movement.ts"; import { Gamedata, ItemIndex, ItemLocation, Message, MessageTimeout, PacketC, PacketS, PlayerID, TileIndex } from "./protocol.ts"; import { V2, lerp_exp_v2_mut, normalize, lerp_exp } from "./util.ts"; @@ -35,7 +36,8 @@ const HANDLED_KEYS = [KEY_BOOST, KEY_CHAT, KEY_CLOSE, KEY_DOWN, KEY_UP, KEY_LEFT export let ctx: CanvasRenderingContext2D; export let canvas: HTMLCanvasElement; let ws: WebSocket; -document.addEventListener("DOMContentLoaded", () => { +document.addEventListener("DOMContentLoaded", async () => { + await init_locale(navigator.language.split("-")[0] ?? "en") const ws_uri = window.location.protocol.endsWith("s:") ? `wss://${window.location.host}/` : `ws://${window.location.hostname}:27032/` diff --git a/test-client/makefile b/test-client/makefile index 2a83f5d0..72a04791 100644 --- a/test-client/makefile +++ b/test-client/makefile @@ -14,9 +14,20 @@ # along with this program. If not, see <https://www.gnu.org/licenses/>. # .PHONY: all clean -all: main.js +all: main.js locales +locales: $(patsubst ../locale/%.ini,locale/%.json,$(wildcard ../locale/*.ini)) clean: rm main.js + rm -rf locale main.js: main.ts $(wildcard *.ts) esbuild $< --bundle --outfile=$@ --target=esnext --format=esm + +LT = ../target/release/localetool + +$(LT): $(shell find ../locale/tools -type f) + { cd ..; cargo build --release --bin localetool; } + +locale/%.json: ../locale/%.ini $(LT) ../locale/en.ini + @mkdir -p locale + $(LT) export-json $< $@ --fallback ../locale/en.ini diff --git a/test-client/protocol.ts b/test-client/protocol.ts index d0f5f997..4d243702 100644 --- a/test-client/protocol.ts +++ b/test-client/protocol.ts @@ -90,6 +90,7 @@ export type Message = { item: number } | { text: string } | { effect: string } + | { translation: { id: string, params: Message[] } } export type ItemLocation = { player: PlayerID } diff --git a/test-client/visual.ts b/test-client/visual.ts index 09b6ec85..863fea41 100644 --- a/test-client/visual.ts +++ b/test-client/visual.ts @@ -15,6 +15,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ +import { tr } from "./locale.ts"; import { ItemData, MessageData, PlayerData, TileData, camera, camera_scale, canvas, ctx, data, demands_completed, demands_failed, get_interact_target, global_message, interact_active_anim, interact_possible_anim, interact_target_anim, items_removed, keys_down, my_id, nametag_scale_anim, players, points, server_hints, tiles, time_remaining } from "./main.ts"; import { PLAYER_SIZE } from "./movement.ts"; import { draw_item_sprite, draw_tile_sprite, ItemName, TileName } from "./tiles.ts"; @@ -91,12 +92,12 @@ export function draw_ingame() { ctx.textBaseline = "bottom" ctx.font = "20px sans-serif" if (time_remaining != undefined) - ctx.fillText(`Time remaining: ${time_remaining?.toFixed(2)}`, 10, canvas.height - 90) + ctx.fillText(`${tr("c.score.time_remaining")}: ${time_remaining?.toFixed(2)}`, 10, canvas.height - 90) ctx.font = "30px sans-serif" - ctx.fillText(`Points: ${points}`, 10, canvas.height - 60) + ctx.fillText(`${tr("c.score.points")}: ${points}`, 10, canvas.height - 60) ctx.font = "20px sans-serif" - ctx.fillText(`Completed: ${demands_completed}`, 10, canvas.height - 30) - ctx.fillText(`Failed: ${demands_failed}`, 10, canvas.height - 10) + ctx.fillText(`${tr("c.score.completed")}: ${demands_completed}`, 10, canvas.height - 30) + ctx.fillText(`${tr("c.score.failed")}: ${demands_failed}`, 10, canvas.height - 10) if (keys_down.has("KeyP")) { draw_debug() @@ -258,6 +259,27 @@ function draw_message(m: MessageData) { ctx.translate(0, 1) } + if ("translation" in m.inner) { + ctx.translate(0, -1) + + ctx.textAlign = "center" + ctx.font = "15px sans-serif" + ctx.scale(2 / camera_scale, 2 / camera_scale) + + const text = tr(m.inner.translation.id, ...m.inner.translation.params.map(p => "text" in p ? p.text : "[not text]")); + const w = ctx.measureText(text).width + 30 + + ctx.fillStyle = "#fffa" + ctx.beginPath() + ctx.roundRect(-w / 2, -15, w, 30, 5) + ctx.fill() + + ctx.fillStyle = "black" + ctx.textBaseline = "middle" + ctx.fillText(text, 0, 0) + + ctx.translate(0, 1) + } ctx.restore() } |