aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock17
-rw-r--r--Cargo.toml1
-rw-r--r--locale/en.ini173
-rw-r--r--locale/tools/Cargo.toml9
-rw-r--r--locale/tools/src/main.rs161
5 files changed, 357 insertions, 4 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4e2094c1..918e2e48 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -366,9 +366,9 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.5.15"
+version = "4.5.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11d8838454fda655dafd3accb2b6e2bea645b9e4078abe84a22ceb947235c5cc"
+checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019"
dependencies = [
"clap_builder",
"clap_derive",
@@ -1020,6 +1020,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
+name = "localetool"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "clap",
+ "serde_json",
+]
+
+[[package]]
name = "lock_api"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1710,9 +1719,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.122"
+version = "1.0.127"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da"
+checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad"
dependencies = [
"itoa",
"memchr",
diff --git a/Cargo.toml b/Cargo.toml
index f125b8a3..14915aa0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,5 +7,6 @@ members = [
"server/replaytool",
"pixel-client",
"pixel-client/tools",
+ "locale/tools",
]
resolver = "2"
diff --git a/locale/en.ini b/locale/en.ini
new file mode 100644
index 00000000..f6446807
--- /dev/null
+++ b/locale/en.ini
@@ -0,0 +1,173 @@
+[hurrycurry]
+c.controls.boost=Boost movement
+c.controls.camera_down=Rotate camera downwards
+c.controls.camera_left=Rotate camera to the left
+c.controls.camera_reset=Reset camera view
+c.controls.camera_right=Rotate camera to the right
+c.controls.camera_up=Rotate camera upwards
+c.controls.chat=Toggle chat
+c.controls.fullscreen=Toggle fullscreen
+c.controls.interact=Interact
+c.controls.move_backward=Move backwards
+c.controls.move_forward=Move forwards
+c.controls.move_left=Move left
+c.controls.move_right=Move right
+c.controls.zoom_in_discrete=Zoom in (discrete)
+c.controls.zoom_in=Zoom in
+c.controls.zoom_out_discrete=Zoom out (discrete)
+c.controls.zoom_out=Zoom out
+c.credits.developed_by=developed by
+c.credits.thanks=Thank You For Playing
+c.credits.title=Hurry Curry! - a game about cooking
+c.error.cannot_cancel_no_game=Cannot cancel game since no game is running.
+c.error.must_join_to_cancel=You must join in order to be able to cancel the current game.
+c.error.placeholder=This should be the error message.
+c.error.websocket=WebSocket closed with code: %d, reason %s. Clean: %s
+c.error=Error
+c.hint.boost=Press %s to boost
+c.hint.framerate_low=Your framerate seems to be low. You can lower your graphics settings in the settings menu.
+c.hint.interact=Press %s to pick up items and hold %s to interact with toolsDrücke %s, um Gegenstände aufzuheben und halte %s gedrückt= um mit Utensilien zu interagieren
+c.hint.movement=Use %s to move
+c.hint.reset_camera=Press %s to reset the camera view
+c.hint.zoom_camera=Use %s to zoom in/out
+c.hint=Hint
+c.lobby.botenable=Enable bots
+c.lobby.mapname=Map name
+c.lobby.players=Players
+c.lobby.start=Start game
+c.map.difficulty.0=Easy
+c.map.difficulty.1=Hard
+c.map.difficulty.2=Moderate
+c.map.difficulty.3=Unplayable
+c.map.difficulty.4=Very hard
+c.map.difficulty=Difficulty
+c.map.players_recommended=%d players recommended
+c.menu.back=Back
+c.menu.credits=Credits
+c.menu.ingame.cancel=Cancel game
+c.menu.ingame.join=Join game
+c.menu.ingame.join2=Join Game
+c.menu.ingame.leave=Leave game
+c.menu.ingame.leave2=Leave Game
+c.menu.ingame.main_menu=Main menu
+c.menu.ingame.mainmenu=Main Menu
+c.menu.ingame.quit=Quit game
+c.menu.ingame.reconnect=Reconnect
+c.menu.ingame.resume=Resume
+c.menu.ingame.spectate=Spectate
+c.menu.my_chef=My Chef
+c.menu.play.connect=Connect
+c.menu.play.quick_connect=Quick Connect
+c.menu.play.server=Server
+c.menu.play=Play
+c.menu.quit=Quit
+c.menu.settings=Settings
+c.score.acceptable=Acceptable service
+c.score.completed=Completed
+c.score.excellent=Excellent service
+c.score.failed=Failed
+c.score.good=Good service
+c.score.points_par=You collected %s points
+c.score.points=Points
+c.score.poor=Poor service
+c.settings.apply=Save & Apply
+c.settings.audio.master_volume=Master Volume
+c.settings.audio.music_volume=Music Volume
+c.settings.audio.sfx_volume=SFX Volume
+c.settings.audio=Audio
+c.settings.controls.add=Add new
+c.settings.controls.joypad_axis=Joypad axis %s
+c.settings.controls.joypad=%s (Joypad)
+c.settings.controls.keyboard=%s (Keyboard)
+c.settings.controls.mouse_button=Mouse button %s
+c.settings.controls.other_event=Other event
+c.settings.controls.press_any_key=Press any key...
+c.settings.controls=Controls
+c.settings.debug_info=Display debug info (Framerate, etc.)
+c.settings.fullscreen.always=Always
+c.settings.fullscreen.keep=Keep
+c.settings.fullscreen.never=Never
+c.settings.fullscreen=Fullscreen
+c.settings.gameplay.extend_boost=Always extend boost to maximum duration
+c.settings.gameplay=Gameplay
+c.settings.gi.sdfgi=SDFGI
+c.settings.gi.voxelgi=Voxel GI
+c.settings.gi=Global illumination
+c.settings.glow=Enable glow
+c.settings.graphics.aa=Anti-aliasing
+c.settings.graphics.ao=Ambient occlusion
+c.settings.graphics.taa=Temporal Anti-Aliasing
+c.settings.graphics=Graphics
+c.settings.grass_amount=3D grass amount per grass tile
+c.settings.language.system=System default
+c.settings.language=Language
+c.settings.low_poly_trees=Low-poly trees
+c.settings.other=Other
+c.settings.preset_high=High
+c.settings.preset_low=Low
+c.settings.preset_medium=Medium
+c.settings.server_data=Server data directory (leave empty to auto-detect)
+c.settings.server_path.placeholder=Enter path
+c.settings.server_path=Server binary (leave empty to search PATH)
+c.settings.shadows=Enable shadows
+c.settings.smooth_camera=Smooth camera rotation
+c.settings.ui_blur=Enable UI blur
+c.settings.ui.scale_factor=UI scale factor
+c.settings.ui.scale_mode.resize=Resize
+c.settings.ui.scale_mode=UI scale mode
+c.settings.ui.touch_controls=Enable touch screen controls
+c.settings.ui=User interface
+c.settings.username=Username
+c.setup.contract_title=EMPLOYMENT CONTRACT
+c.setup.par00=This is a binding contract between you (the employee) and Musterfoods Ltd. (the employer) for working as a chef or waiter.
+c.setup.par01=1. [b]Name of the Employee[/b]
+c.setup.par02=Other players can see your name when playing on a server
+c.setup.par03=2. [b]Employment Position[/b]
+c.setup.par04=Chef / Waiting Staff
+c.setup.par05=3. [b]Working Uniform.[/b] You must always have one of the following hairstyles.
+c.setup.par06=4. [b]Duties.[/b] It is your duty to serve customers the meal or item that they request.\n
+c.setup.par08=6. [b]Compensation.[/b] You will be compensated monthly for your work.
+c.setup.par09=The salary is
+c.setup.par10=$ 0.00
+c.setup.par11=per month
+c.setup.par12=5. [b]Additional Terms.[/b] You shall not duplicate plates. (That is [u]NOT[/u] possible!)\n
+c.setup.par13=F.Miller
+c.setup.sign=Click to sign
+s.bot.chef=Simple chef
+s.bot.waiter=Waiter
+unknown298=Signature of the Employer:\nMusterfoods Ltd.\nFrank Miller, Head of HR
+unknown312=Signature of the Employee:\n\n\n
+unknown33=Automatic
+unknown336=Return to Main Menu
+unknown37=Enabled
+unknown41=Disabled
+unknown460=+
+unknown464=-
+unknown476=SHIFT
+unknown484=left stick
+unknown488=SPACE
+unknown49=Invert camera movement
+unknown494=Press %s to pick up items and hold %s to interact with tools
+unknown506=PageUp/PageDown
+unknown510=Use %s to rotate the camera view
+unknown514=arrow keys
+unknown518=right stick
+unknown524=Username tags can be enabled/disabled in the settings
+unknown53=Show username tags
+unknown530=Press %s and click "Join" to join the game while it is running
+unknown534=ESCAPE
+unknown538=Menu button
+unknown551=unavailable
+unknown564=Server and client versions do not match. Server: %d.%d, Client: %d.%d.\nAre you sure the game is up to date?
+unknown568=Hairstyle %d
+unknown572=Models
+unknown576=Sounds
+unknown59=Initial setup complete. (Uncheck and restart to reenter)
+unknown598=[/table]\n\n\n
+unknown622=You must fill out all requested fields.
+unknown626=Accept
+unknown63=Tutorial started
+unknown732=Previous
+unknown736=Next
+unknown740=Join / Spectate
+unknown752=Scroll down
diff --git a/locale/tools/Cargo.toml b/locale/tools/Cargo.toml
new file mode 100644
index 00000000..e8084b23
--- /dev/null
+++ b/locale/tools/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "localetool"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+clap = { version = "4.5.16", features = ["derive"] }
+anyhow = "1.0.86"
+serde_json = "1.0.127"
diff --git a/locale/tools/src/main.rs b/locale/tools/src/main.rs
new file mode 100644
index 00000000..017d9d74
--- /dev/null
+++ b/locale/tools/src/main.rs
@@ -0,0 +1,161 @@
+#![feature(iterator_try_collect)]
+use anyhow::{anyhow, Context, Result};
+use clap::Parser;
+use std::{
+ collections::BTreeMap,
+ fs::{read_to_string, File},
+ io::Write,
+ path::PathBuf,
+};
+
+#[derive(Parser)]
+enum Args {
+ ImportOldPot {
+ input: PathBuf,
+ output: PathBuf,
+ },
+ ImportOldPo {
+ reference: PathBuf,
+ input: PathBuf,
+ output: PathBuf,
+ },
+}
+
+fn main() -> Result<()> {
+ let args = Args::parse();
+ match args {
+ Args::ImportOldPo {
+ reference,
+ input,
+ output,
+ } => {
+ let reference = read_to_string(reference)?;
+ let input = read_to_string(input)?;
+
+ let id_reverse = reference
+ .lines()
+ .skip(1)
+ .map(|l| {
+ l.split_once("=")
+ .map(|(k, v)| (v, k))
+ .ok_or(anyhow!("invalid ini"))
+ })
+ .try_collect::<BTreeMap<&str, &str>>()?;
+
+ let mut outmap = BTreeMap::new();
+ let mut mode = 0;
+ let mut msgid = String::new();
+ let mut msgstr = String::new();
+ for (i, mut line) in input.lines().enumerate() {
+ if line.starts_with("#") {
+ continue;
+ }
+ if line.is_empty() {
+ continue;
+ }
+ if let Some(rest) = line.strip_prefix("msgid ") {
+ if !msgid.is_empty() {
+ if let Some(id) = id_reverse.get(&msgid.as_str()) {
+ outmap.insert(id.to_owned(), msgstr.clone());
+ } else {
+ eprintln!("warning: message id {msgid:?} is unknown")
+ }
+ }
+ line = rest;
+ msgid = String::new();
+ mode = 1;
+ } else if let Some(rest) = line.strip_prefix("msgstr ") {
+ line = rest;
+ msgstr = String::new();
+ mode = 2;
+ } else if let Some(_) = line.strip_prefix("msgctxt ") {
+ mode = 0;
+ eprintln!("warning: msgctxt not implemented (line {})", i + 1);
+ continue;
+ }
+ let frag =
+ serde_json::from_str::<String>(line).context(anyhow!("line {}", i + 1))?;
+ match mode {
+ 0 => (),
+ 1 => msgid.push_str(&frag),
+ 2 => msgstr.push_str(&frag),
+ _ => unreachable!(),
+ };
+ }
+
+ File::create(output)?.write_all(
+ format!(
+ "[hurrycurry]\n{}",
+ outmap
+ .into_iter()
+ .map(|(k, v)| format!("{k}={v}\n"))
+ .collect::<String>()
+ )
+ .as_bytes(),
+ )?;
+
+ Ok(())
+ }
+ Args::ImportOldPot { input, output } => {
+ let output_raw = read_to_string(&output).unwrap_or("".to_owned());
+ let input = read_to_string(input)?;
+
+ let mut output_flip = output_raw
+ .lines()
+ .skip(1)
+ .map(|l| {
+ l.split_once("=")
+ .map(|(k, v)| (v.to_owned(), k.to_owned()))
+ .ok_or(anyhow!("invalid ini"))
+ })
+ .try_collect::<BTreeMap<String, String>>()?;
+
+ let mut id = false;
+ let mut msgid = String::new();
+ for (i, mut line) in input.lines().enumerate() {
+ if line.starts_with("#") {
+ continue;
+ }
+ if line.is_empty() {
+ continue;
+ }
+ if let Some(rest) = line.strip_prefix("msgid ") {
+ if !msgid.is_empty() {
+ if !output_flip.contains_key(&msgid) {
+ output_flip.insert(msgid.replace("\n", "\\n"), format!("unknown{i}"));
+ }
+ }
+ line = rest;
+ id = true;
+ msgid = String::new();
+ } else if line.starts_with("msgctxt ") || line.starts_with("msgstr ") {
+ id = false;
+ continue;
+ }
+ if id {
+ let frag =
+ serde_json::from_str::<String>(line).context(anyhow!("line {}", i + 1))?;
+ msgid.push_str(frag.as_str());
+ }
+ }
+
+ let output_unflip = output_flip
+ .into_iter()
+ .map(|(v, k)| (k, v))
+ .collect::<BTreeMap<_, _>>();
+
+ File::create(output)?.write_all(
+ format!(
+ "[hurrycurry]\n{}",
+ output_unflip
+ .into_iter()
+ .map(|(k, v)| format!("{k}={v}\n"))
+ .collect::<String>()
+ )
+ .as_bytes(),
+ )?;
+
+ Ok(())
+ }
+ }
+}