Locale stuff

This commit is contained in:
IQuant 2024-06-08 14:25:57 +03:00
parent a7d8f5244e
commit dc8048b59d
7 changed files with 395 additions and 10 deletions

249
noita-proxy/Cargo.lock generated
View file

@ -128,6 +128,12 @@ dependencies = [
"x11rb",
]
[[package]]
name = "arc-swap"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
[[package]]
name = "arrayref"
version = "0.3.7"
@ -273,6 +279,16 @@ dependencies = [
"objc2 0.5.1",
]
[[package]]
name = "bstr"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706"
dependencies = [
"memchr",
"serde",
]
[[package]]
name = "bumpalo"
version = "3.16.0"
@ -1052,6 +1068,97 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
[[package]]
name = "fluent"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb74634707bebd0ce645a981148e8fb8c7bccd4c33c652aeffd28bf2f96d555a"
dependencies = [
"fluent-bundle",
"unic-langid",
]
[[package]]
name = "fluent-bundle"
version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe0a21ee80050c678013f82edf4b705fe2f26f1f9877593d13198612503f493"
dependencies = [
"fluent-langneg",
"fluent-syntax",
"intl-memoizer",
"intl_pluralrules",
"rustc-hash",
"self_cell 0.10.3",
"smallvec",
"unic-langid",
]
[[package]]
name = "fluent-langneg"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94"
dependencies = [
"unic-langid",
]
[[package]]
name = "fluent-syntax"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a530c4694a6a8d528794ee9bbd8ba0122e779629ac908d15ad5a7ae7763a33d"
dependencies = [
"thiserror",
]
[[package]]
name = "fluent-template-macros"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77d2bcae1f3ec390c50161fcf130d3228750e9ecf965618584e046d884199b83"
dependencies = [
"flume",
"ignore",
"once_cell",
"proc-macro2",
"quote",
"syn",
"unic-langid",
]
[[package]]
name = "fluent-templates"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "197feb1e37209c6b3d29f0754b11fc070890efb2b1d761caac4e5287a200e9db"
dependencies = [
"arc-swap",
"fluent",
"fluent-bundle",
"fluent-langneg",
"fluent-syntax",
"fluent-template-macros",
"flume",
"heck",
"ignore",
"intl-memoizer",
"log",
"once_cell",
"serde_json",
"thiserror",
"unic-langid",
]
[[package]]
name = "flume"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
dependencies = [
"spin",
]
[[package]]
name = "fnv"
version = "1.0.7"
@ -1207,6 +1314,19 @@ dependencies = [
"xml-rs",
]
[[package]]
name = "globset"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1"
dependencies = [
"aho-corasick",
"bstr",
"log",
"regex-automata 0.4.6",
"regex-syntax 0.8.3",
]
[[package]]
name = "glow"
version = "0.13.1"
@ -1309,6 +1429,12 @@ version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.3.9"
@ -1450,6 +1576,22 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "ignore"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1"
dependencies = [
"crossbeam-deque",
"globset",
"log",
"memchr",
"regex-automata 0.4.6",
"same-file",
"walkdir",
"winapi-util",
]
[[package]]
name = "image"
version = "0.24.9"
@ -1509,6 +1651,25 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "intl-memoizer"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe22e020fce238ae18a6d5d8c502ee76a52a6e880d99477657e6acc30ec57bda"
dependencies = [
"type-map",
"unic-langid",
]
[[package]]
name = "intl_pluralrules"
version = "7.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972"
dependencies = [
"unic-langid",
]
[[package]]
name = "ipnet"
version = "2.9.0"
@ -1815,6 +1976,7 @@ dependencies = [
"eframe",
"egui-file-dialog",
"egui_extras",
"fluent-templates",
"image 0.25.1",
"lz4_flex",
"poll-promise",
@ -1831,6 +1993,7 @@ dependencies = [
"tracing",
"tracing-subscriber",
"tungstenite",
"unic-langid",
"zip",
]
@ -2230,6 +2393,12 @@ dependencies = [
"toml_edit",
]
[[package]]
name = "proc-macro-hack"
version = "0.5.20+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
[[package]]
name = "proc-macro2"
version = "1.0.81"
@ -2622,6 +2791,21 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "self_cell"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d"
dependencies = [
"self_cell 1.0.4",
]
[[package]]
name = "self_cell"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a"
[[package]]
name = "serde"
version = "1.0.199"
@ -2790,6 +2974,9 @@ name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]]
name = "static_assertions"
@ -3013,6 +3200,15 @@ dependencies = [
"strict-num",
]
[[package]]
name = "tinystr"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
dependencies = [
"displaydoc",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
@ -3205,12 +3401,65 @@ dependencies = [
"utf-8",
]
[[package]]
name = "type-map"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "deb68604048ff8fa93347f02441e4487594adc20bb8a084f9e564d2b827a0a9f"
dependencies = [
"rustc-hash",
]
[[package]]
name = "typenum"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "unic-langid"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23dd9d1e72a73b25e07123a80776aae3e7b0ec461ef94f9151eed6ec88005a44"
dependencies = [
"unic-langid-impl",
"unic-langid-macros",
]
[[package]]
name = "unic-langid-impl"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a5422c1f65949306c99240b81de9f3f15929f5a8bfe05bb44b034cc8bf593e5"
dependencies = [
"serde",
"tinystr",
]
[[package]]
name = "unic-langid-macros"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0da1cd2c042d3c7569a1008806b02039e7a4a2bdf8f8e96bd3c792434a0e275e"
dependencies = [
"proc-macro-hack",
"tinystr",
"unic-langid-impl",
"unic-langid-macros-impl",
]
[[package]]
name = "unic-langid-macros-impl"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b"
dependencies = [
"proc-macro-hack",
"quote",
"syn",
"unic-langid-impl",
]
[[package]]
name = "unicase"
version = "2.7.0"

View file

@ -34,6 +34,8 @@ egui_extras = { version = "*", features = ["all_loaders"] }
bytemuck = { version = "1.16.0", features = ["derive"] }
bincode = "1.3.3"
rustc-hash = "1.1.0"
fluent-templates = "0.9.4"
unic-langid = { version = "0.9.5", features = ["serde"] }
[profile.dev]
opt-level = 1

View file

@ -0,0 +1,15 @@
connect_steam = Connect using steam
connect_steam_create = Create lobby
connect_steam_connect = Connect to lobby in clipboard
connect_ip = Connect using ip
connect_settings = Game settings
connect_settings_debug = Debug settings
connect_settings_debug_en = Debug/cheat mode
connect_settings_debug_fixed_seed = Use fixed seed
connect_settings_wsv = World sync version to use:
lang_picker = Choose a language
button_confirm = Confirm

View file

@ -0,0 +1,15 @@
connect_steam = Подключение по Steam
connect_steam_create = Создать лобби
connect_steam_connect = Подключиться к лобби в буфере обмена
connect_ip = Подключение по IP
connect_settings = Настройки игры
connect_settings_debug = Настройки разработчика
connect_settings_debug_en = Подрубить читы
connect_settings_debug_fixed_seed = Фиксированный сид мира
connect_settings_wsv = Версия синхронизатора мира:
lang_picker = Выберите язык
button_confirm = Подтвердить

51
noita-proxy/src/lang.rs Normal file
View file

@ -0,0 +1,51 @@
use std::sync::RwLock;
use fluent_templates::{LanguageIdentifier, Loader};
use unic_langid::langid;
fluent_templates::static_loader! {
// Declare our `StaticLoader` named `LOCALES`.
static LOCALES = {
// The directory of localisations and fluent resources.
locales: "./assets/lang",
// The language to falback on if something is not present.
fallback_language: "en-US",
};
}
// static LANG: LanguageIdentifier = langid!("en-US");
static LANG: RwLock<LanguageIdentifier> = RwLock::new(langid!("ru-RU"));
pub struct LangDesc {
name: &'static str,
id: LanguageIdentifier,
}
impl LangDesc {
const fn new(name: &'static str, id: LanguageIdentifier) -> Self {
Self { name, id }
}
pub fn name(&self) -> &'static str {
self.name
}
pub fn id(&self) -> LanguageIdentifier {
self.id.clone()
}
}
pub static LANGS: [LangDesc; 2] = [
LangDesc::new("English", langid!("en-US")),
LangDesc::new("Русский", langid!("ru-RU")),
];
pub fn set_current_locale(lang_id: LanguageIdentifier) {
*LANG.write().unwrap() = lang_id;
}
pub fn tr(text_id: &str) -> String {
LOCALES
.try_lookup(&LANG.read().unwrap(), text_id)
.unwrap_or_else(|| text_id.to_string())
}

View file

@ -8,6 +8,7 @@ use std::{
use bitcode::{Decode, Encode};
use clipboard::{ClipboardContext, ClipboardProvider};
use eframe::egui::{self, Align2, Color32, InnerResponse, Margin, RichText, TextureOptions, Ui};
use lang::{set_current_locale, tr, LANGS};
use mod_manager::{Modmanager, ModmanagerSettings};
use net::{omni::PeerVariant, NetManagerInit};
use self_update::SelfUpdateManager;
@ -15,7 +16,9 @@ use serde::{Deserialize, Serialize};
use steamworks::{LobbyId, SteamAPIInitError};
use tangled::Peer;
use tracing::info;
use unic_langid::LanguageIdentifier;
pub mod lang;
pub mod messages;
mod mod_manager;
pub mod net;
@ -36,6 +39,7 @@ enum AppState {
Netman { netman: Arc<net::NetManager> },
Error { message: String },
SelfUpdate,
LangPick,
}
#[derive(Debug, Serialize, Deserialize)]
@ -46,6 +50,7 @@ struct AppSavedState {
nickname: Option<String>,
times_started: u32,
world_sync_version: u32,
lang_id: Option<LanguageIdentifier>,
}
impl Default for AppSavedState {
@ -57,6 +62,7 @@ impl Default for AppSavedState {
nickname: None,
times_started: 0,
world_sync_version: 1,
lang_id: None,
}
}
}
@ -102,10 +108,18 @@ impl App {
.and_then(|storage| eframe::get_value(storage, MODMANAGER))
.unwrap_or_default();
saved_state.times_started += 1;
let state = if let Some(lang_id) = &saved_state.lang_id {
set_current_locale(lang_id.clone());
AppState::ModManager
} else {
AppState::LangPick
};
egui_extras::install_image_loaders(&cc.egui_ctx);
info!("Creating the app...");
Self {
state: AppState::ModManager,
state,
modmanager: Modmanager::default(),
steam_state: steam_helper::SteamState::new(),
saved_state,
@ -196,20 +210,39 @@ impl App {
let item_spacing = ui.spacing().item_spacing.x;
let rect = ui.max_rect();
let (rect, right_b_panel) =
rect.split_left_right_at_x(rect.right() - (50.0 + item_spacing));
let (settings_rect, right) = rect.split_left_right_at_fraction(0.5);
let (steam_connect_rect, ip_connect_rect) = right.split_top_bottom_at_fraction(0.5);
ui.allocate_ui_at_rect(right_b_panel.shrink(item_spacing), |ui| {
filled_group(ui, |ui| {
ui.set_min_size(ui.available_size());
if ui.button("EN").clicked() {
self.state = AppState::LangPick;
}
})
});
ui.allocate_ui_at_rect(settings_rect.shrink(item_spacing), |ui| {
filled_group(ui, |ui| {
ui.set_min_size(ui.available_size());
heading_with_underline(ui, "Game settings");
heading_with_underline(ui, tr("connect_settings"));
ui.label("Debug settings");
ui.checkbox(&mut self.saved_state.debug_mode, "Debug/cheat mode");
ui.checkbox(&mut self.saved_state.use_constant_seed, "Use fixed seed");
ui.label(tr("connect_settings_debug"));
ui.checkbox(
&mut self.saved_state.debug_mode,
tr("connect_settings_debug_en"),
);
ui.checkbox(
&mut self.saved_state.use_constant_seed,
tr("connect_settings_debug_fixed_seed"),
);
ui.add_space(20.0);
ui.label("World sync version to use:");
ui.label(tr("connect_settings_wsv"));
ui.horizontal(|ui| {
ui.radio_value(&mut self.saved_state.world_sync_version, 1, "v1");
ui.radio_value(
@ -224,14 +257,14 @@ impl App {
filled_group(ui, |ui| {
ui.set_min_size(ui.available_size());
heading_with_underline(ui, "Connect using steam");
heading_with_underline(ui, tr("connect_steam"));
match &self.steam_state {
Ok(_) => {
if ui.button("Create lobby").clicked() {
if ui.button(tr("connect_steam_create")).clicked() {
self.start_steam_host();
}
if ui.button("Connect to lobby in clipboard").clicked() {
if ui.button(tr("connect_steam_connect")).clicked() {
let id = ClipboardProvider::new()
.and_then(|mut ctx: ClipboardContext| ctx.get_contents());
match id {
@ -256,7 +289,7 @@ impl App {
filled_group(ui, |ui| {
ui.set_min_size(ui.available_size());
heading_with_underline(ui, "Connect by ip");
heading_with_underline(ui, tr("connect_ip"));
ui.label("Note: steam networking is more reliable. Use it, if possible.");
if ui.button("Host").clicked() {
@ -387,6 +420,25 @@ impl eframe::App for App {
self.self_update.self_update(ui);
});
}
AppState::LangPick => {
egui::Window::new(tr("lang_picker"))
.auto_sized()
.anchor(Align2::CENTER_CENTER, [0.0, 0.0])
.show(ctx, |ui| {
for lang in &LANGS {
ui.set_max_width(200.0);
ui.vertical_centered_justified(|ui| {
if ui.button(lang.name()).clicked() {
self.saved_state.lang_id = Some(lang.id());
set_current_locale(lang.id())
}
});
}
if ui.button(tr("button_confirm")).clicked() {
self.state = AppState::ModManager;
}
});
}
};
}

View file

@ -15,6 +15,7 @@ fn main() -> Result<(), eframe::Error> {
)
.finish();
tracing::subscriber::set_global_default(my_subscriber).expect("setting tracing default failed");
let icon = image::load_from_memory(include_bytes!("../assets/icon.png"))
.unwrap()
.to_rgba8();