chore: parse translations at compile time

not finished but its much safer and nicer now
This commit is contained in:
Alexander Medvedev 2026-02-08 13:22:36 +01:00
parent abe01f3019
commit e45ab613f4
47 changed files with 339 additions and 193 deletions

79
Cargo.lock generated
View File

@ -401,7 +401,7 @@ version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34"
dependencies = [ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -501,6 +501,12 @@ dependencies = [
"url", "url",
] ]
[[package]]
name = "cpubits"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ef0c543070d296ea414df2dd7625d1b24866ce206709d8a4a424f28377f5861"
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.17" version = "0.2.17"
@ -651,10 +657,11 @@ dependencies = [
[[package]] [[package]]
name = "crypto-bigint" name = "crypto-bigint"
version = "0.7.0-rc.22" version = "0.7.0-rc.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053c3561863ce55e3226ecc48b08679f4b66cb1b92b9afb42c2c402dfe8b9b51" checksum = "cba9eeeb213f7fd29353032f71f7c173e5f6d95d85151cb3a47197b0ea7e8be7"
dependencies = [ dependencies = [
"cpubits",
"ctutils", "ctutils",
"num-traits", "num-traits",
"rand_core 0.10.0", "rand_core 0.10.0",
@ -674,9 +681,9 @@ dependencies = [
[[package]] [[package]]
name = "crypto-common" name = "crypto-common"
version = "0.2.0-rc.13" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7722afd27468475c9b6063dc03a57ef2ca833816981619f8ebe64d38d207eef" checksum = "211f05e03c7d03754740fd9e585de910a095d6b99f8bcfffdef8319fa02a8331"
dependencies = [ dependencies = [
"hybrid-array", "hybrid-array",
] ]
@ -687,7 +694,7 @@ version = "0.7.0-pre.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "334a79c97c0b7fa536716dc132fd417d0afbf471440a41fc25a5d9f66d8771cd" checksum = "334a79c97c0b7fa536716dc132fd417d0afbf471440a41fc25a5d9f66d8771cd"
dependencies = [ dependencies = [
"crypto-bigint 0.7.0-rc.22", "crypto-bigint 0.7.0-rc.25",
"libm", "libm",
"rand_core 0.10.0", "rand_core 0.10.0",
] ]
@ -760,13 +767,13 @@ dependencies = [
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.11.0-rc.9" version = "0.11.0-rc.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bff8de092798697546237a3a701e4174fe021579faec9b854379af9bf1e31962" checksum = "02b42f1d9edf5207c137646b568a0168ca0ec25b7f9eaf7f9961da51a3d91cea"
dependencies = [ dependencies = [
"block-buffer 0.11.0", "block-buffer 0.11.0",
"const-oid 0.10.2", "const-oid 0.10.2",
"crypto-common 0.2.0-rc.13", "crypto-common 0.2.0",
"subtle", "subtle",
] ]
@ -885,7 +892,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys 0.52.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -1202,11 +1209,11 @@ dependencies = [
[[package]] [[package]]
name = "hmac" name = "hmac"
version = "0.13.0-rc.4" version = "0.13.0-rc.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9956e202a691c5c86c60303a421f66f93f44b29433407b7c43cf2bebadc750e" checksum = "ef451d73f36d8a3f93ad32c332ea01146c9650e1ec821a9b0e46c01277d544f8"
dependencies = [ dependencies = [
"digest 0.11.0-rc.9", "digest 0.11.0-rc.11",
] ]
[[package]] [[package]]
@ -1271,9 +1278,9 @@ checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424"
[[package]] [[package]]
name = "hybrid-array" name = "hybrid-array"
version = "0.4.6" version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b41fb3dc24fe72c2e3a4685eed55917c2fb228851257f4a8f2d985da9443c3e5" checksum = "e1b229d73f5803b562cc26e4da0396c8610a4ee209f4fac8fa4f8d709166dc45"
dependencies = [ dependencies = [
"typenum", "typenum",
] ]
@ -1718,7 +1725,7 @@ version = "0.50.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
dependencies = [ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -2134,7 +2141,7 @@ dependencies = [
"crossbeam", "crossbeam",
"flate2", "flate2",
"futures", "futures",
"hmac 0.13.0-rc.4", "hmac 0.13.0-rc.5",
"libloading", "libloading",
"log", "log",
"num-bigint", "num-bigint",
@ -2154,7 +2161,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"sha1", "sha1",
"sha2 0.11.0-rc.4", "sha2 0.11.0-rc.5",
"tempfile", "tempfile",
"thiserror", "thiserror",
"time", "time",
@ -2319,7 +2326,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"serde_json5", "serde_json5",
"sha2 0.11.0-rc.4", "sha2 0.11.0-rc.5",
"slotmap", "slotmap",
"temp-dir", "temp-dir",
"thiserror", "thiserror",
@ -2462,19 +2469,19 @@ dependencies = [
[[package]] [[package]]
name = "rsa" name = "rsa"
version = "0.10.0-rc.14" version = "0.10.0-rc.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ef381dd6f207f81aff2ee3a8264eddd68ba475bbfcdb44ca445e5906bce381b" checksum = "1b342b99544549f37509ed7fd42b0cea04bfd9ce07c16ca56094cf0fbeefbbcd"
dependencies = [ dependencies = [
"const-oid 0.10.2", "const-oid 0.10.2",
"crypto-bigint 0.7.0-rc.22", "crypto-bigint 0.7.0-rc.25",
"crypto-primes", "crypto-primes",
"digest 0.11.0-rc.9", "digest 0.11.0-rc.11",
"pkcs1", "pkcs1",
"pkcs8 0.11.0-rc.10", "pkcs8 0.11.0-rc.10",
"rand_core 0.10.0", "rand_core 0.10.0",
"sha1", "sha1",
"signature 3.0.0-rc.9", "signature 3.0.0-rc.10",
"spki 0.8.0-rc.4", "spki 0.8.0-rc.4",
"zeroize", "zeroize",
] ]
@ -2495,7 +2502,7 @@ dependencies = [
"errno", "errno",
"libc", "libc",
"linux-raw-sys", "linux-raw-sys",
"windows-sys 0.52.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -2680,13 +2687,13 @@ dependencies = [
[[package]] [[package]]
name = "sha1" name = "sha1"
version = "0.11.0-rc.4" version = "0.11.0-rc.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c777f0a122a53fddb0beb6e706771197000b8eb5c9f42b5b850f450ef48c788" checksum = "3b167252f3c126be0d8926639c4c4706950f01445900c4b3db0fd7e89fcb750a"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures",
"digest 0.11.0-rc.9", "digest 0.11.0-rc.11",
] ]
[[package]] [[package]]
@ -2702,13 +2709,13 @@ dependencies = [
[[package]] [[package]]
name = "sha2" name = "sha2"
version = "0.11.0-rc.4" version = "0.11.0-rc.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7535f94fa3339fe9e5e9be6260a909e62af97f6e14b32345ccf79b92b8b81233" checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures",
"digest 0.11.0-rc.9", "digest 0.11.0-rc.11",
] ]
[[package]] [[package]]
@ -2748,11 +2755,11 @@ dependencies = [
[[package]] [[package]]
name = "signature" name = "signature"
version = "3.0.0-rc.9" version = "3.0.0-rc.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ad0ce3b3f8efd7406f22e2ca5d02be21cdf3b3d1d53ab141f784de8965c7c7e" checksum = "7f1880df446116126965eeec169136b2e0251dba37c6223bcc819569550edea3"
dependencies = [ dependencies = [
"digest 0.11.0-rc.9", "digest 0.11.0-rc.11",
"rand_core 0.10.0", "rand_core 0.10.0",
] ]
@ -2892,7 +2899,7 @@ dependencies = [
"fastrand", "fastrand",
"once_cell", "once_cell",
"rustix", "rustix",
"windows-sys 0.52.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -3504,7 +3511,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]

View File

@ -125,7 +125,7 @@ enum_dispatch = "0.3.13"
env_logger = "0.11.8" env_logger = "0.11.8"
flate2 = "1.1.9" flate2 = "1.1.9"
heck = "0.5" heck = "0.5"
hmac = "=0.13.0-rc.4" hmac = "=0.13.0-rc.5"
indexmap = "2.13" indexmap = "2.13"
itertools = "0.14.0" itertools = "0.14.0"
libloading = "0.9" libloading = "0.9"
@ -150,13 +150,13 @@ pumpkin-util = { path = "pumpkin-util" }
pumpkin-world = { path = "pumpkin-world" } pumpkin-world = { path = "pumpkin-world" }
quote = "1.0" quote = "1.0"
rand = { git = "https://github.com/rust-random/rand"} rand = { git = "https://github.com/rust-random/rand"}
rsa = "=0.10.0-rc.14" rsa = "=0.10.0-rc.15"
rustc-hash = "2.1.1" rustc-hash = "2.1.1"
rustyline = "17.0.2" rustyline = "17.0.2"
ruzstd = "0.8.2" ruzstd = "0.8.2"
serde_json5 = "0.2.1" serde_json5 = "0.2.1"
sha1 = "=0.11.0-rc.4" sha1 = "=0.11.0-rc.5"
sha2 = "=0.11.0-rc.4" sha2 = "=0.11.0-rc.5"
signature = "2.2.0" signature = "2.2.0"
tracing = "0.1.44" tracing = "0.1.44"
tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt", "time"] } tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt", "time"] }

View File

@ -51,6 +51,7 @@ mod spawn_egg;
mod structures; mod structures;
mod tag; mod tag;
mod tracked_data; mod tracked_data;
mod translations;
mod world_event; mod world_event;
pub const OUT_DIR: &str = "src/generated"; pub const OUT_DIR: &str = "src/generated";
@ -72,6 +73,7 @@ pub fn main() {
(game_rules::build, "game_rules.rs"), (game_rules::build, "game_rules.rs"),
(registry::build, "registry.rs"), (registry::build, "registry.rs"),
(dimension::build, "dimension.rs"), (dimension::build, "dimension.rs"),
(translations::build, "translation.rs"),
(jukebox_song::build, "jukebox_song.rs"), (jukebox_song::build, "jukebox_song.rs"),
(sound_category::build, "sound_category.rs"), (sound_category::build, "sound_category.rs"),
(entity_pose::build, "entity_pose.rs"), (entity_pose::build, "entity_pose.rs"),

View File

@ -0,0 +1,34 @@
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use std::{collections::BTreeMap, fs};
pub(crate) fn build() -> TokenStream {
println!("cargo:rerun-if-changed=../assets/en_us.json");
let en_us: BTreeMap<String, String> = serde_json::from_str(
&fs::read_to_string("../assets/en_us.json").expect("en_us is missing"),
)
.unwrap();
let mut constants = TokenStream::new();
for (name, value) in &en_us {
let clean_name = name.to_uppercase().replace(['.', '-'], "_");
let ident = format_ident!("{}", clean_name);
if !value.is_empty() {
constants.extend(quote! {
#[doc = #value]
pub const #ident: &str = #name;
});
} else {
constants.extend(quote! {
pub const #ident: &str = #name;
});
}
}
quote! {
#constants
}
}

View File

@ -12,6 +12,10 @@ pub mod packet;
#[path = "generated/jukebox_song.rs"] #[path = "generated/jukebox_song.rs"]
pub mod jukebox_song; pub mod jukebox_song;
#[rustfmt::skip]
#[path = "generated/translation.rs"]
pub mod translation;
#[rustfmt::skip] #[rustfmt::skip]
#[path = "generated/registry.rs"] #[path = "generated/registry.rs"]
pub mod registry; pub mod registry;

View File

@ -141,7 +141,7 @@ fn is_start_chunk_concentric_rings(
_salt: u32, _salt: u32,
) -> bool { ) -> bool {
// TODO: Implement proper concentric rings logic // TODO: Implement proper concentric rings logic
rand::random_bool(1.0 / 100.0) rand::random_bool(1.0 / 1000.0)
} }
#[cfg(test)] #[cfg(test)]

View File

@ -7,6 +7,7 @@ use crate::block::{
}; };
use pumpkin_data::block_properties::{BarrelLikeProperties, BlockProperties}; use pumpkin_data::block_properties::{BarrelLikeProperties, BlockProperties};
use pumpkin_data::translation;
use pumpkin_inventory::generic_container_screen_handler::create_generic_9x3; use pumpkin_inventory::generic_container_screen_handler::create_generic_9x3;
use pumpkin_inventory::player::player_inventory::PlayerInventory; use pumpkin_inventory::player::player_inventory::PlayerInventory;
use pumpkin_inventory::screen_handler::{ use pumpkin_inventory::screen_handler::{
@ -37,7 +38,7 @@ impl ScreenHandlerFactory for BarrelScreenFactory {
} }
fn get_display_name(&self) -> TextComponent { fn get_display_name(&self) -> TextComponent {
TextComponent::translate("container.barrel", &[]) TextComponent::translate(translation::CONTAINER_BARREL, &[])
} }
} }

View File

@ -5,6 +5,7 @@ use pumpkin_data::block_properties::BedPart;
use pumpkin_data::block_properties::BlockProperties; use pumpkin_data::block_properties::BlockProperties;
use pumpkin_data::dimension::Dimension; use pumpkin_data::dimension::Dimension;
use pumpkin_data::entity::EntityType; use pumpkin_data::entity::EntityType;
use pumpkin_data::translation;
use pumpkin_macros::pumpkin_block_from_tag; use pumpkin_macros::pumpkin_block_from_tag;
use pumpkin_util::GameMode; use pumpkin_util::GameMode;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
@ -243,7 +244,7 @@ impl BlockBehaviour for BedBlock {
{ {
args.player args.player
.send_system_message_raw( .send_system_message_raw(
&TextComponent::translate("block.minecraft.bed.obstructed", []), &TextComponent::translate(translation::BLOCK_MINECRAFT_BED_OBSTRUCTED, []),
true, true,
) )
.await; .await;
@ -256,7 +257,7 @@ impl BlockBehaviour for BedBlock {
args.player args.player
.send_system_message_raw( .send_system_message_raw(
&TextComponent::translate("block.minecraft.bed.occupied", []), &TextComponent::translate(translation::BLOCK_MINECRAFT_BED_OCCUPIED, []),
true, true,
) )
.await; .await;
@ -275,7 +276,10 @@ impl BlockBehaviour for BedBlock {
{ {
args.player args.player
.send_system_message_raw( .send_system_message_raw(
&TextComponent::translate("block.minecraft.bed.too_far_away", []), &TextComponent::translate(
translation::BLOCK_MINECRAFT_BED_TOO_FAR_AWAY,
[],
),
true, true,
) )
.await; .await;
@ -294,7 +298,10 @@ impl BlockBehaviour for BedBlock {
.await .await
{ {
args.player args.player
.send_system_message(&TextComponent::translate("block.minecraft.set_spawn", [])) .send_system_message(&TextComponent::translate(
translation::BLOCK_MINECRAFT_SET_SPAWN,
[],
))
.await; .await;
} }
@ -302,7 +309,7 @@ impl BlockBehaviour for BedBlock {
if !can_sleep(args.world).await { if !can_sleep(args.world).await {
args.player args.player
.send_system_message_raw( .send_system_message_raw(
&TextComponent::translate("block.minecraft.bed.no_sleep", []), &TextComponent::translate(translation::BLOCK_MINECRAFT_BED_NO_SLEEP, []),
true, true,
) )
.await; .await;
@ -321,7 +328,10 @@ impl BlockBehaviour for BedBlock {
{ {
args.player args.player
.send_system_message_raw( .send_system_message_raw(
&TextComponent::translate("block.minecraft.bed.not_safe", []), &TextComponent::translate(
translation::BLOCK_MINECRAFT_BED_NOT_SAFE,
[],
),
true, true,
) )
.await; .await;

View File

@ -3,6 +3,7 @@ use std::sync::Arc;
use pumpkin_data::{ use pumpkin_data::{
block_properties::{BlockProperties, FurnaceLikeProperties}, block_properties::{BlockProperties, FurnaceLikeProperties},
screen::WindowType, screen::WindowType,
translation,
}; };
use pumpkin_inventory::{ use pumpkin_inventory::{
furnace_like::furnace_like_screen_handler::FurnaceLikeScreenHandler, furnace_like::furnace_like_screen_handler::FurnaceLikeScreenHandler,
@ -74,7 +75,7 @@ impl ScreenHandlerFactory for BlastingFurnaceScreenFactory {
} }
fn get_display_name(&self) -> pumpkin_util::text::TextComponent { fn get_display_name(&self) -> pumpkin_util::text::TextComponent {
TextComponent::translate("container.blast_furnace", &[]) TextComponent::translate(translation::CONTAINER_BLAST_FURNACE, &[])
} }
} }

View File

@ -5,7 +5,7 @@ use pumpkin_data::block_properties::{
BlockProperties, ChestLikeProperties, ChestType, HorizontalFacing, BlockProperties, ChestLikeProperties, ChestType, HorizontalFacing,
}; };
use pumpkin_data::entity::EntityPose; use pumpkin_data::entity::EntityPose;
use pumpkin_data::{Block, BlockDirection}; use pumpkin_data::{Block, BlockDirection, translation};
use pumpkin_inventory::double::DoubleInventory; use pumpkin_inventory::double::DoubleInventory;
use pumpkin_inventory::generic_container_screen_handler::{create_generic_9x3, create_generic_9x6}; use pumpkin_inventory::generic_container_screen_handler::{create_generic_9x3, create_generic_9x6};
use pumpkin_inventory::player::player_inventory::PlayerInventory; use pumpkin_inventory::player::player_inventory::PlayerInventory;
@ -57,9 +57,9 @@ impl ScreenHandlerFactory for ChestScreenFactory {
fn get_display_name(&self) -> TextComponent { fn get_display_name(&self) -> TextComponent {
if self.0.size() > 27 { if self.0.size() > 27 {
TextComponent::translate("container.chestDouble", &[]) TextComponent::translate(translation::CONTAINER_CHESTDOUBLE, &[])
} else { } else {
TextComponent::translate("container.chest", &[]) TextComponent::translate(translation::CONTAINER_CHEST, &[])
} }
} }
} }

View File

@ -1,6 +1,7 @@
use crate::block::registry::BlockActionResult; use crate::block::registry::BlockActionResult;
use crate::block::{BlockBehaviour, BlockFuture, NormalUseArgs}; use crate::block::{BlockBehaviour, BlockFuture, NormalUseArgs};
use pumpkin_data::translation;
use pumpkin_inventory::crafting::crafting_screen_handler::CraftingTableScreenHandler; use pumpkin_inventory::crafting::crafting_screen_handler::CraftingTableScreenHandler;
use pumpkin_inventory::player::player_inventory::PlayerInventory; use pumpkin_inventory::player::player_inventory::PlayerInventory;
use pumpkin_inventory::screen_handler::{ use pumpkin_inventory::screen_handler::{
@ -44,6 +45,6 @@ impl ScreenHandlerFactory for CraftingTableScreenFactory {
} }
fn get_display_name(&self) -> TextComponent { fn get_display_name(&self) -> TextComponent {
TextComponent::translate("container.crafting", &[]) TextComponent::translate(translation::CONTAINER_CRAFTING, &[])
} }
} }

View File

@ -6,6 +6,7 @@ use crate::block::{
}; };
use crate::world::World; use crate::world::World;
use pumpkin_data::block_properties::{BlockProperties, LadderLikeProperties}; use pumpkin_data::block_properties::{BlockProperties, LadderLikeProperties};
use pumpkin_data::translation;
use pumpkin_inventory::{ use pumpkin_inventory::{
generic_container_screen_handler::create_generic_9x3, generic_container_screen_handler::create_generic_9x3,
player::player_inventory::PlayerInventory, player::player_inventory::PlayerInventory,
@ -37,7 +38,7 @@ impl ScreenHandlerFactory for EnderChestScreenFactory {
} }
fn get_display_name(&self) -> TextComponent { fn get_display_name(&self) -> TextComponent {
TextComponent::translate("container.enderchest", &[]) TextComponent::translate(translation::CONTAINER_ENDERCHEST, &[])
} }
} }

View File

@ -3,6 +3,7 @@ use std::sync::Arc;
use pumpkin_data::{ use pumpkin_data::{
block_properties::{BlockProperties, FurnaceLikeProperties}, block_properties::{BlockProperties, FurnaceLikeProperties},
screen::WindowType, screen::WindowType,
translation,
}; };
use pumpkin_inventory::{ use pumpkin_inventory::{
furnace_like::furnace_like_screen_handler::FurnaceLikeScreenHandler, furnace_like::furnace_like_screen_handler::FurnaceLikeScreenHandler,
@ -74,7 +75,7 @@ impl ScreenHandlerFactory for FurnaceScreenFactory {
} }
fn get_display_name(&self) -> pumpkin_util::text::TextComponent { fn get_display_name(&self) -> pumpkin_util::text::TextComponent {
TextComponent::translate("container.furnace", &[]) TextComponent::translate(translation::CONTAINER_FURNACE, &[])
} }
} }

View File

@ -9,7 +9,7 @@ use crate::block::{
use crate::world::World; use crate::world::World;
use pumpkin_data::block_properties::{BlockProperties, HopperFacing}; use pumpkin_data::block_properties::{BlockProperties, HopperFacing};
use pumpkin_data::{Block, BlockDirection}; use pumpkin_data::{Block, BlockDirection, translation};
use pumpkin_inventory::generic_container_screen_handler::create_hopper; use pumpkin_inventory::generic_container_screen_handler::create_hopper;
use pumpkin_inventory::player::player_inventory::PlayerInventory; use pumpkin_inventory::player::player_inventory::PlayerInventory;
use pumpkin_inventory::screen_handler::{ use pumpkin_inventory::screen_handler::{
@ -43,7 +43,7 @@ impl ScreenHandlerFactory for HopperBlockScreenFactory {
} }
fn get_display_name(&self) -> TextComponent { fn get_display_name(&self) -> TextComponent {
TextComponent::translate("container.hopper", &[]) TextComponent::translate(translation::CONTAINER_HOPPER, &[])
} }
} }

View File

@ -92,7 +92,6 @@ impl BlockBehaviour for CactusBlock {
} }
fn on_entity_collision<'a>(&'a self, args: OnEntityCollisionArgs<'a>) -> BlockFuture<'a, ()> { fn on_entity_collision<'a>(&'a self, args: OnEntityCollisionArgs<'a>) -> BlockFuture<'a, ()> {
log::warn!("CactusBlock::on_entity_collision");
Box::pin(async move { Box::pin(async move {
args.entity args.entity
.damage(args.entity, 1.0, DamageType::CACTUS) .damage(args.entity, 1.0, DamageType::CACTUS)

View File

@ -7,10 +7,10 @@ use crate::block::{
use crate::entity::Entity; use crate::entity::Entity;
use crate::entity::item::ItemEntity; use crate::entity::item::ItemEntity;
use pumpkin_data::FacingExt;
use pumpkin_data::block_properties::{BlockProperties, Facing}; use pumpkin_data::block_properties::{BlockProperties, Facing};
use pumpkin_data::entity::EntityType; use pumpkin_data::entity::EntityType;
use pumpkin_data::world::WorldEvent; use pumpkin_data::world::WorldEvent;
use pumpkin_data::{FacingExt, translation};
use pumpkin_inventory::generic_container_screen_handler::create_generic_3x3; use pumpkin_inventory::generic_container_screen_handler::create_generic_3x3;
use pumpkin_inventory::player::player_inventory::PlayerInventory; use pumpkin_inventory::player::player_inventory::PlayerInventory;
use pumpkin_inventory::screen_handler::{ use pumpkin_inventory::screen_handler::{
@ -47,7 +47,7 @@ impl ScreenHandlerFactory for DropperScreenFactory {
} }
fn get_display_name(&self) -> TextComponent { fn get_display_name(&self) -> TextComponent {
TextComponent::translate("container.dropper", &[]) TextComponent::translate(translation::CONTAINER_DROPPER, &[])
} }
} }

View File

@ -8,6 +8,7 @@ use crate::block::{
use pumpkin_data::block_properties::BlockProperties; use pumpkin_data::block_properties::BlockProperties;
use pumpkin_data::tag::{self}; use pumpkin_data::tag::{self};
use pumpkin_data::translation;
use pumpkin_inventory::generic_container_screen_handler::create_generic_9x3; use pumpkin_inventory::generic_container_screen_handler::create_generic_9x3;
use pumpkin_inventory::player::player_inventory::PlayerInventory; use pumpkin_inventory::player::player_inventory::PlayerInventory;
use pumpkin_inventory::screen_handler::{ use pumpkin_inventory::screen_handler::{
@ -37,7 +38,7 @@ impl ScreenHandlerFactory for ShulkerBoxScreenFactory {
} }
fn get_display_name(&self) -> TextComponent { fn get_display_name(&self) -> TextComponent {
TextComponent::translate("container.shulkerBox", &[]) TextComponent::translate(translation::CONTAINER_SHULKERBOX, &[])
} }
} }

View File

@ -3,6 +3,7 @@ use std::sync::Arc;
use pumpkin_data::{ use pumpkin_data::{
block_properties::{BlockProperties, FurnaceLikeProperties}, block_properties::{BlockProperties, FurnaceLikeProperties},
screen::WindowType, screen::WindowType,
translation,
}; };
use pumpkin_inventory::{ use pumpkin_inventory::{
furnace_like::furnace_like_screen_handler::FurnaceLikeScreenHandler, furnace_like::furnace_like_screen_handler::FurnaceLikeScreenHandler,
@ -73,7 +74,7 @@ impl ScreenHandlerFactory for SmokerScreenFactory {
} }
fn get_display_name(&self) -> pumpkin_util::text::TextComponent { fn get_display_name(&self) -> pumpkin_util::text::TextComponent {
TextComponent::translate("container.smoker", &[]) TextComponent::translate(translation::CONTAINER_SMOKER, &[])
} }
} }
#[pumpkin_block("minecraft:smoker")] #[pumpkin_block("minecraft:smoker")]

View File

@ -1,5 +1,5 @@
use pumpkin_data::Block;
use pumpkin_data::tag::{RegistryKey, get_tag_ids}; use pumpkin_data::tag::{RegistryKey, get_tag_ids};
use pumpkin_data::{Block, translation};
use pumpkin_protocol::java::client::play::{ArgumentType, SuggestionProviders}; use pumpkin_protocol::java::client::play::{ArgumentType, SuggestionProviders};
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
@ -56,12 +56,12 @@ impl<'a> FindArg<'a> for BlockArgumentConsumer {
|| { || {
if name.starts_with("minecraft:") { if name.starts_with("minecraft:") {
Err(CommandError::CommandFailed(TextComponent::translate( Err(CommandError::CommandFailed(TextComponent::translate(
"argument.block.id.invalid", translation::ARGUMENT_BLOCK_ID_INVALID,
[TextComponent::text((*name).to_string())], [TextComponent::text((*name).to_string())],
))) )))
} else { } else {
Err(CommandError::CommandFailed(TextComponent::translate( Err(CommandError::CommandFailed(TextComponent::translate(
"argument.block.id.invalid", translation::ARGUMENT_BLOCK_ID_INVALID,
[TextComponent::text("minecraft:".to_string() + *name)], [TextComponent::text("minecraft:".to_string() + *name)],
))) )))
} }
@ -122,12 +122,12 @@ impl<'a> FindArg<'a> for BlockPredicateArgumentConsumer {
|| { || {
if name.starts_with("minecraft:") { if name.starts_with("minecraft:") {
Err(CommandError::CommandFailed(TextComponent::translate( Err(CommandError::CommandFailed(TextComponent::translate(
"argument.block.id.invalid", translation::ARGUMENT_BLOCK_ID_INVALID,
[TextComponent::text((*name).to_string())], [TextComponent::text((*name).to_string())],
))) )))
} else { } else {
Err(CommandError::CommandFailed(TextComponent::translate( Err(CommandError::CommandFailed(TextComponent::translate(
"argument.block.id.invalid", translation::ARGUMENT_BLOCK_ID_INVALID,
[TextComponent::text("minecraft:".to_string() + *name)], [TextComponent::text("minecraft:".to_string() + *name)],
))) )))
} }
@ -139,7 +139,7 @@ impl<'a> FindArg<'a> for BlockPredicateArgumentConsumer {
get_tag_ids(RegistryKey::Block, tag).map_or_else( get_tag_ids(RegistryKey::Block, tag).map_or_else(
|| { || {
Err(CommandError::CommandFailed(TextComponent::translate( Err(CommandError::CommandFailed(TextComponent::translate(
"arguments.block.tag.unknown", translation::ARGUMENTS_BLOCK_TAG_UNKNOWN,
[TextComponent::text((*tag).to_string())], [TextComponent::text((*tag).to_string())],
))) )))
}, },

View File

@ -13,6 +13,7 @@ use crate::{
net::DisconnectReason, net::DisconnectReason,
}; };
use CommandError::InvalidConsumption; use CommandError::InvalidConsumption;
use pumpkin_data::translation;
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
const NAMES: [&str; 1] = ["ban"]; const NAMES: [&str; 1] = ["ban"];
@ -79,7 +80,7 @@ async fn ban_players(
if count == 0 { if count == 0 {
Err(CommandError::CommandFailed(TextComponent::translate( Err(CommandError::CommandFailed(TextComponent::translate(
"commands.ban.failed", translation::COMMANDS_BAN_FAILED,
[], [],
))) )))
} else { } else {
@ -116,7 +117,7 @@ async fn ban_player(
// Send messages // Send messages
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.ban.success", translation::COMMANDS_BAN_SUCCESS,
[player.get_display_name().await, TextComponent::text(reason)], [player.get_display_name().await, TextComponent::text(reason)],
)) ))
.await; .await;
@ -124,7 +125,7 @@ async fn ban_player(
player player
.kick( .kick(
DisconnectReason::Kicked, DisconnectReason::Kicked,
TextComponent::translate("multiplayer.disconnect.banned", []), TextComponent::translate(translation::MULTIPLAYER_DISCONNECT_BANNED, []),
) )
.await; .await;

View File

@ -11,6 +11,7 @@ use crate::{
server::Server, server::Server,
}; };
use CommandError::InvalidConsumption; use CommandError::InvalidConsumption;
use pumpkin_data::translation;
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
const NAMES: [&str; 1] = ["ban-ip"]; const NAMES: [&str; 1] = ["ban-ip"];
@ -83,7 +84,7 @@ async fn ban_ip(
let Some(target_ip) = parse_ip(target, server).await else { let Some(target_ip) = parse_ip(target, server).await else {
return Err(CommandError::CommandFailed(TextComponent::translate( return Err(CommandError::CommandFailed(TextComponent::translate(
"commands.banip.invalid", translation::COMMANDS_BANIP_INVALID,
[], [],
))); )));
}; };
@ -92,7 +93,7 @@ async fn ban_ip(
if banned_ips.get_entry(&target_ip).is_some() { if banned_ips.get_entry(&target_ip).is_some() {
return Err(CommandError::CommandFailed(TextComponent::translate( return Err(CommandError::CommandFailed(TextComponent::translate(
"commands.banip.failed", translation::COMMANDS_BANIP_FAILED,
[], [],
))); )));
} }
@ -117,7 +118,7 @@ async fn ban_ip(
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.banip.success", translation::COMMANDS_BANIP_SUCCESS,
[ [
TextComponent::text(target_ip.to_string()), TextComponent::text(target_ip.to_string()),
TextComponent::text(reason), TextComponent::text(reason),
@ -127,7 +128,7 @@ async fn ban_ip(
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.banip.info", translation::COMMANDS_BANIP_INFO,
[ [
TextComponent::text(affected.len().to_string()), TextComponent::text(affected.len().to_string()),
TextComponent::text(names), TextComponent::text(names),
@ -140,7 +141,7 @@ async fn ban_ip(
target target
.kick( .kick(
DisconnectReason::Kicked, DisconnectReason::Kicked,
TextComponent::translate("multiplayer.disconnect.ip_banned", []), TextComponent::translate(translation::MULTIPLAYER_DISCONNECT_IP_BANNED, []),
) )
.await; .await;
} }

View File

@ -4,6 +4,7 @@ use crate::command::{
tree::{CommandTree, builder::argument}, tree::{CommandTree, builder::argument},
}; };
use CommandError::InvalidConsumption; use CommandError::InvalidConsumption;
use pumpkin_data::translation;
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
const NAMES: [&str; 1] = ["banlist"]; const NAMES: [&str; 1] = ["banlist"];
@ -59,7 +60,7 @@ impl CommandExecutor for ListExecutor {
handle_banlist(entries, sender).await handle_banlist(entries, sender).await
} }
_ => Err(CommandError::CommandFailed(TextComponent::translate( _ => Err(CommandError::CommandFailed(TextComponent::translate(
"command.unknown.argument", translation::COMMAND_UNKNOWN_ARGUMENT,
[], [],
))), ))),
} }
@ -106,14 +107,14 @@ async fn handle_banlist(
) -> Result<i32, CommandError> { ) -> Result<i32, CommandError> {
if list.is_empty() { if list.is_empty() {
return Result::Err(CommandError::CommandFailed(TextComponent::translate( return Result::Err(CommandError::CommandFailed(TextComponent::translate(
"commands.banlist.none", translation::COMMANDS_BANLIST_NONE,
[], [],
))); )));
} }
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.banlist.list", translation::COMMANDS_BANLIST_LIST,
[TextComponent::text(list.len().to_string())], [TextComponent::text(list.len().to_string())],
)) ))
.await; .await;
@ -123,7 +124,7 @@ async fn handle_banlist(
for (name, source, reason) in list { for (name, source, reason) in list {
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.banlist.entry", translation::COMMANDS_BANLIST_ENTRY,
[ [
TextComponent::text(name), TextComponent::text(name),
TextComponent::text(source), TextComponent::text(source),

View File

@ -14,6 +14,7 @@ use crate::command::tree::builder::{argument, argument_default_name, literal};
use crate::command::{CommandExecutor, CommandResult, CommandSender}; use crate::command::{CommandExecutor, CommandResult, CommandSender};
use crate::world::bossbar::Bossbar; use crate::world::bossbar::Bossbar;
use crate::world::custom_bossbar::BossbarUpdateError; use crate::world::custom_bossbar::BossbarUpdateError;
use pumpkin_data::translation;
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
use pumpkin_util::text::hover::HoverEvent; use pumpkin_util::text::hover::HoverEvent;
use std::fmt::Write as _; use std::fmt::Write as _;
@ -634,9 +635,12 @@ fn bossbar_prefix(title: TextComponent, namespace: String) -> TextComponent {
fn handle_bossbar_error(error: BossbarUpdateError) -> CommandError { fn handle_bossbar_error(error: BossbarUpdateError) -> CommandError {
match error { match error {
BossbarUpdateError::InvalidResourceLocation(location) => CommandError::CommandFailed( BossbarUpdateError::InvalidResourceLocation(location) => {
TextComponent::translate("commands.bossbar.unknown", [TextComponent::text(location)]), CommandError::CommandFailed(TextComponent::translate(
), translation::COMMANDS_BOSSBAR_UNKNOWN,
[TextComponent::text(location)],
))
}
BossbarUpdateError::NoChanges(value, variation) => { BossbarUpdateError::NoChanges(value, variation) => {
let mut key = "commands.bossbar.set.".to_string(); let mut key = "commands.bossbar.set.".to_string();
key.push_str(value); key.push_str(value);

View File

@ -1,5 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use pumpkin_data::translation;
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
use pumpkin_world::item::ItemStack; use pumpkin_world::item::ItemStack;
use tokio::sync::Mutex; use tokio::sync::Mutex;
@ -143,36 +144,36 @@ async fn clear_command_text_output(
) -> Result<TextComponent, TextComponent> { ) -> Result<TextComponent, TextComponent> {
match (targets, item_count == 0, max_count == 0) { match (targets, item_count == 0, max_count == 0) {
([target], true, _) => Err(TextComponent::translate( ([target], true, _) => Err(TextComponent::translate(
"clear.failed.single", translation::CLEAR_FAILED_SINGLE,
[target.get_display_name().await], [target.get_display_name().await],
)), )),
(targets, true, _) => Err(TextComponent::translate( (targets, true, _) => Err(TextComponent::translate(
"clear.failed.multiple", translation::CLEAR_FAILED_MULTIPLE,
[TextComponent::text(targets.len().to_string())], [TextComponent::text(targets.len().to_string())],
)), )),
([target], false, false) => Ok(TextComponent::translate( ([target], false, false) => Ok(TextComponent::translate(
"commands.clear.success.single", translation::COMMANDS_CLEAR_SUCCESS_SINGLE,
[ [
TextComponent::text(item_count.to_string()), TextComponent::text(item_count.to_string()),
target.get_display_name().await, target.get_display_name().await,
], ],
)), )),
(targets, false, false) => Ok(TextComponent::translate( (targets, false, false) => Ok(TextComponent::translate(
"commands.clear.success.multiple", translation::COMMANDS_CLEAR_SUCCESS_MULTIPLE,
[ [
TextComponent::text(item_count.to_string()), TextComponent::text(item_count.to_string()),
TextComponent::text(targets.len().to_string()), TextComponent::text(targets.len().to_string()),
], ],
)), )),
([target], false, true) => Ok(TextComponent::translate( ([target], false, true) => Ok(TextComponent::translate(
"commands.clear.test.single", translation::COMMANDS_CLEAR_TEST_SINGLE,
[ [
TextComponent::text(item_count.to_string()), TextComponent::text(item_count.to_string()),
target.get_display_name().await, target.get_display_name().await,
], ],
)), )),
(targets, false, true) => Ok(TextComponent::translate( (targets, false, true) => Ok(TextComponent::translate(
"commands.clear.test.multiple", translation::COMMANDS_CLEAR_TEST_MULTIPLE,
[ [
TextComponent::text(item_count.to_string()), TextComponent::text(item_count.to_string()),
TextComponent::text(targets.len().to_string()), TextComponent::text(targets.len().to_string()),
@ -273,7 +274,7 @@ impl CommandExecutor for ItemCountExecutor {
let item = ItemPredicateArgumentConsumer::find_arg(args, ARG_ITEM)?; let item = ItemPredicateArgumentConsumer::find_arg(args, ARG_ITEM)?;
let Ok(max) = count_consumer().find_arg_default_name(args)? else { let Ok(max) = count_consumer().find_arg_default_name(args)? else {
return Err(CommandError::CommandFailed(TextComponent::translate( return Err(CommandError::CommandFailed(TextComponent::translate(
"parsing.int.invalid", translation::PARSING_INT_INVALID,
[TextComponent::text(i32::MAX.to_string())], [TextComponent::text(i32::MAX.to_string())],
))); )));
}; };

View File

@ -1,4 +1,4 @@
use pumpkin_data::damage::DamageType; use pumpkin_data::{damage::DamageType, translation};
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
use crate::command::{ use crate::command::{
@ -40,14 +40,14 @@ async fn send_damage_result(
) -> Result<i32, CommandError> { ) -> Result<i32, CommandError> {
if !success { if !success {
return Err(CommandError::CommandFailed(TextComponent::translate( return Err(CommandError::CommandFailed(TextComponent::translate(
"commands.damage.invulnerable", translation::COMMANDS_DAMAGE_INVULNERABLE,
[], [],
))); )));
} }
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.damage.success", translation::COMMANDS_DAMAGE_SUCCESS,
[TextComponent::text(amount.to_string()), target_name], [TextComponent::text(amount.to_string()), target_name],
)) ))
.await; .await;

View File

@ -8,6 +8,7 @@ use crate::command::{
}; };
use crate::entity::NBTStorage; use crate::entity::NBTStorage;
use CommandError::InvalidConsumption; use CommandError::InvalidConsumption;
use pumpkin_data::translation;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_nbt::tag::NbtTag; use pumpkin_nbt::tag::NbtTag;
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
@ -232,7 +233,7 @@ async fn display_data(
.map_err(|string| CommandError::CommandFailed(TextComponent::text(string)))?; .map_err(|string| CommandError::CommandFailed(TextComponent::text(string)))?;
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.data.entity.query", translation::COMMANDS_DATA_ENTITY_QUERY,
[target_name, display], [target_name, display],
)) ))
.await; .await;
@ -243,7 +244,7 @@ async fn display_data(
fn get_i32_result(tag: &NbtTag) -> Result<i32, CommandError> { fn get_i32_result(tag: &NbtTag) -> Result<i32, CommandError> {
match tag { match tag {
NbtTag::End => Err(CommandError::CommandFailed(TextComponent::translate( NbtTag::End => Err(CommandError::CommandFailed(TextComponent::translate(
"commands.data.get.unknown", translation::COMMANDS_DATA_GET_UNKNOWN,
[], [],
))), ))),

View File

@ -1,3 +1,4 @@
use pumpkin_data::translation;
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
use crate::command::args::bounded_num::{BoundedNumArgumentConsumer, NotInBounds}; use crate::command::args::bounded_num::{BoundedNumArgumentConsumer, NotInBounds};
@ -119,12 +120,12 @@ impl CommandExecutor for Executor {
} }
} }
if success == 0 { if success == 0 {
let msg = TextComponent::translate("commands.enchant.failed", []); let msg = TextComponent::translate(translation::COMMANDS_ENCHANT_FAILED, []);
return Err(CommandError::CommandFailed(msg)); return Err(CommandError::CommandFailed(msg));
} }
if only_one { if only_one {
let msg = TextComponent::translate( let msg = TextComponent::translate(
"commands.enchant.success.single", translation::COMMANDS_ENCHANT_SUCCESS_SINGLE,
[ [
enchantment.get_fullname(level), enchantment.get_fullname(level),
targets[0].get_display_name().await, targets[0].get_display_name().await,
@ -133,7 +134,7 @@ impl CommandExecutor for Executor {
sender.send_message(msg).await; sender.send_message(msg).await;
} else { } else {
let msg = TextComponent::translate( let msg = TextComponent::translate(
"commands.enchant.success.multiple", translation::COMMANDS_ENCHANT_SUCCESS_MULTIPLE,
[ [
enchantment.get_fullname(level), enchantment.get_fullname(level),
TextComponent::text(targets.len().to_string()), TextComponent::text(targets.len().to_string()),

View File

@ -1,3 +1,4 @@
use pumpkin_data::translation;
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
use pumpkin_util::text::color::NamedColor; use pumpkin_util::text::color::NamedColor;
@ -35,7 +36,7 @@ impl CommandExecutor for Executor {
let reason = match args.get(&ARG_REASON) { let reason = match args.get(&ARG_REASON) {
Some(Arg::Msg(r)) => TextComponent::text(r.clone()), Some(Arg::Msg(r)) => TextComponent::text(r.clone()),
_ => TextComponent::translate("multiplayer.disconnect.kicked", []), _ => TextComponent::translate(translation::MULTIPLAYER_DISCONNECT_KICKED, []),
}; };
for target in targets { for target in targets {

View File

@ -1,6 +1,7 @@
use std::sync::Arc; use std::sync::Arc;
use pumpkin_data::sound::SoundCategory; use pumpkin_data::sound::SoundCategory;
use pumpkin_data::translation;
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
use rand::{RngExt, rng}; use rand::{RngExt, rng};
@ -149,7 +150,7 @@ impl CommandExecutor for Executor {
if players_who_heard == 1 { if players_who_heard == 1 {
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.playsound.success.single", translation::COMMANDS_PLAYSOUND_SUCCESS_SINGLE,
[ [
TextComponent::text(sound_name), TextComponent::text(sound_name),
targets[0].get_display_name().await, targets[0].get_display_name().await,
@ -159,7 +160,7 @@ impl CommandExecutor for Executor {
} else { } else {
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.playsound.success.multiple", translation::COMMANDS_PLAYSOUND_SUCCESS_MULTIPLE,
[ [
TextComponent::text(sound_name), TextComponent::text(sound_name),
TextComponent::text(players_who_heard.to_string()), TextComponent::text(players_who_heard.to_string()),

View File

@ -1,3 +1,4 @@
use pumpkin_data::translation;
use pumpkin_util::math::vector3::Vector3; use pumpkin_util::math::vector3::Vector3;
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
@ -89,7 +90,7 @@ async fn send_success_message(sender: &CommandSender, target: &dyn crate::entity
let target_name = target.get_display_name().await; let target_name = target.get_display_name().await;
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.rotate.success", translation::COMMANDS_ROTATE_SUCCESS,
[target_name], [target_name],
)) ))
.await; .await;

View File

@ -13,6 +13,7 @@ use crate::command::{
}; };
use crate::server::Server; use crate::server::Server;
use pumpkin_data::dimension::Dimension; use pumpkin_data::dimension::Dimension;
use pumpkin_data::translation;
use pumpkin_util::{math::position::BlockPos, text::TextComponent}; use pumpkin_util::{math::position::BlockPos, text::TextComponent};
const NAMES: [&str; 1] = ["setworldspawn"]; const NAMES: [&str; 1] = ["setworldspawn"];
@ -107,7 +108,7 @@ async fn setworldspawn(
}; };
if world.dimension != Dimension::OVERWORLD && world.dimension != Dimension::OVERWORLD_CAVES { if world.dimension != Dimension::OVERWORLD && world.dimension != Dimension::OVERWORLD_CAVES {
return Err(CommandError::CommandFailed(TextComponent::translate( return Err(CommandError::CommandFailed(TextComponent::translate(
"commands.setworldspawn.failure.not_overworld", translation::COMMANDS_SETWORLDSPAWN_FAILURE_NOT_OVERWORLD,
[], [],
))); )));
} }
@ -126,7 +127,7 @@ async fn setworldspawn(
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.setworldspawn.success", translation::COMMANDS_SETWORLDSPAWN_SUCCESS,
[ [
TextComponent::text(block_pos.0.x.to_string()), TextComponent::text(block_pos.0.x.to_string()),
TextComponent::text(block_pos.0.y.to_string()), TextComponent::text(block_pos.0.y.to_string()),

View File

@ -1,5 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use pumpkin_data::translation;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
@ -131,7 +132,7 @@ async fn set_spawnpoint(sender: &CommandSender, target: &Arc<Player>, pos: Block
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.spawnpoint.success.single", translation::COMMANDS_SPAWNPOINT_SUCCESS_SINGLE,
[ [
TextComponent::text(pos.0.x.to_string()), TextComponent::text(pos.0.x.to_string()),
TextComponent::text(pos.0.y.to_string()), TextComponent::text(pos.0.y.to_string()),

View File

@ -1,3 +1,4 @@
use pumpkin_data::translation;
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
use pumpkin_util::text::color::NamedColor; use pumpkin_util::text::color::NamedColor;
@ -22,7 +23,7 @@ impl CommandExecutor for Executor {
Box::pin(async move { Box::pin(async move {
sender sender
.send_message( .send_message(
TextComponent::translate("commands.stop.stopping", []) TextComponent::translate(translation::COMMANDS_STOP_STOPPING, [])
.color_named(NamedColor::Red), .color_named(NamedColor::Red),
) )
.await; .await;

View File

@ -6,6 +6,7 @@ use crate::command::{
}, },
tree::{CommandTree, builder::argument}, tree::{CommandTree, builder::argument},
}; };
use pumpkin_data::translation;
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
const NAMES: [&str; 1] = ["stopsound"]; const NAMES: [&str; 1] = ["stopsound"];
@ -45,23 +46,24 @@ impl CommandExecutor for Executor {
let text = match (category, sound) { let text = match (category, sound) {
(Ok(c), Ok(s)) => TextComponent::translate( (Ok(c), Ok(s)) => TextComponent::translate(
"commands.stopsound.success.source.sound", translation::COMMANDS_STOPSOUND_SUCCESS_SOURCE_SOUND,
[ [
TextComponent::text(s.to_name()), TextComponent::text(s.to_name()),
TextComponent::text(c.to_name()), TextComponent::text(c.to_name()),
], ],
), ),
(Ok(c), Err(_)) => TextComponent::translate( (Ok(c), Err(_)) => TextComponent::translate(
"commands.stopsound.success.source.any", translation::COMMANDS_STOPSOUND_SUCCESS_SOURCE_ANY,
[TextComponent::text(c.to_name())], [TextComponent::text(c.to_name())],
), ),
(Err(_), Ok(s)) => TextComponent::translate( (Err(_), Ok(s)) => TextComponent::translate(
"commands.stopsound.success.sourceless.sound", translation::COMMANDS_STOPSOUND_SUCCESS_SOURCELESS_SOUND,
[TextComponent::text(s.to_name())], [TextComponent::text(s.to_name())],
), ),
(Err(_), Err(_)) => { (Err(_), Err(_)) => TextComponent::translate(
TextComponent::translate("commands.stopsound.success.sourceless.any", []) translation::COMMANDS_STOPSOUND_SUCCESS_SOURCELESS_ANY,
} [],
),
}; };
sender.send_message(text).await; sender.send_message(text).await;

View File

@ -1,3 +1,4 @@
use pumpkin_data::translation;
use pumpkin_util::{math::vector3::Vector3, text::TextComponent}; use pumpkin_util::{math::vector3::Vector3, text::TextComponent};
use uuid::Uuid; use uuid::Uuid;
@ -65,7 +66,10 @@ impl CommandExecutor for Executor {
let name = entity.get_display_name().await; let name = entity.get_display_name().await;
world.spawn_entity(entity).await; world.spawn_entity(entity).await;
sender sender
.send_message(TextComponent::translate("commands.summon.success", [name])) .send_message(TextComponent::translate(
translation::COMMANDS_SUMMON_SUCCESS,
[name],
))
.await; .await;
Ok(1) Ok(1)

View File

@ -1,3 +1,4 @@
use pumpkin_data::translation;
use pumpkin_util::text::{ use pumpkin_util::text::{
TextComponent, TextComponent,
color::{Color, NamedColor}, color::{Color, NamedColor},
@ -64,13 +65,13 @@ impl TickExecutor {
if manager.is_sprinting() { if manager.is_sprinting() {
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.tick.status.sprinting", translation::COMMANDS_TICK_STATUS_SPRINTING,
[], [],
)) ))
.await; .await;
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.tick.query.rate.sprinting", translation::COMMANDS_TICK_QUERY_RATE_SPRINTING,
[ [
TextComponent::text(format!("{tickrate:.1}")), TextComponent::text(format!("{tickrate:.1}")),
TextComponent::text(avg_mspt_str), TextComponent::text(avg_mspt_str),
@ -83,7 +84,7 @@ impl TickExecutor {
let target_mspt_str = nanos_to_millis_string(manager.nanoseconds_per_tick()); let target_mspt_str = nanos_to_millis_string(manager.nanoseconds_per_tick());
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.tick.query.rate.running", translation::COMMANDS_TICK_QUERY_RATE_RUNNING,
[ [
TextComponent::text(format!("{tickrate:.1}")), TextComponent::text(format!("{tickrate:.1}")),
TextComponent::text(avg_mspt_str), TextComponent::text(avg_mspt_str),
@ -103,15 +104,24 @@ impl TickExecutor {
) { ) {
if manager.is_frozen() { if manager.is_frozen() {
sender sender
.send_message(TextComponent::translate("commands.tick.status.frozen", [])) .send_message(TextComponent::translate(
translation::COMMANDS_TICK_STATUS_FROZEN,
[],
))
.await; .await;
} else if avg_tick_nanos > manager.nanoseconds_per_tick() { } else if avg_tick_nanos > manager.nanoseconds_per_tick() {
sender sender
.send_message(TextComponent::translate("commands.tick.status.lagging", [])) .send_message(TextComponent::translate(
translation::COMMANDS_TICK_STATUS_LAGGING,
[],
))
.await; .await;
} else { } else {
sender sender
.send_message(TextComponent::translate("commands.tick.status.running", [])) .send_message(TextComponent::translate(
translation::COMMANDS_TICK_STATUS_RUNNING,
[],
))
.await; .await;
} }
} }
@ -131,7 +141,7 @@ impl TickExecutor {
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.tick.query.percentiles", translation::COMMANDS_TICK_QUERY_PERCENTILES,
[ [
TextComponent::text(nanos_to_millis_string(p50_nanos)), TextComponent::text(nanos_to_millis_string(p50_nanos)),
TextComponent::text(nanos_to_millis_string(p95_nanos)), TextComponent::text(nanos_to_millis_string(p95_nanos)),
@ -151,14 +161,14 @@ impl TickExecutor {
if manager.step_game_if_paused(server, ticks).await { if manager.step_game_if_paused(server, ticks).await {
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.tick.step.success", translation::COMMANDS_TICK_STEP_SUCCESS,
[TextComponent::text(ticks.to_string())], [TextComponent::text(ticks.to_string())],
)) ))
.await; .await;
} else { } else {
sender sender
.send_message( .send_message(
TextComponent::translate("commands.tick.step.fail", []) TextComponent::translate(translation::COMMANDS_TICK_STEP_FAIL, [])
.color_named(NamedColor::Red), .color_named(NamedColor::Red),
) )
.await; .await;
@ -176,14 +186,14 @@ impl TickExecutor {
{ {
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.tick.sprint.stop.success", translation::COMMANDS_TICK_SPRINT_STOP_SUCCESS,
[], [],
)) ))
.await; .await;
} }
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.tick.status.sprinting", translation::COMMANDS_TICK_STATUS_SPRINTING,
[], [],
)) ))
.await; .await;
@ -198,7 +208,7 @@ impl TickExecutor {
manager.set_tick_rate(server, rate).await; manager.set_tick_rate(server, rate).await;
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.tick.rate.success", translation::COMMANDS_TICK_RATE_SUCCESS,
[TextComponent::text(format!("{rate:.1}"))], [TextComponent::text(format!("{rate:.1}"))],
)) ))
.await; .await;
@ -253,7 +263,7 @@ impl CommandExecutor for TickExecutor {
if manager.stop_stepping(server).await { if manager.stop_stepping(server).await {
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.tick.step.stop.success", translation::COMMANDS_TICK_SPRINT_STOP_SUCCESS,
[], [],
)) ))
.await; .await;
@ -262,7 +272,7 @@ impl CommandExecutor for TickExecutor {
// TODO: send feedback as error without Err // TODO: send feedback as error without Err
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.tick.step.stop.fail", translation::COMMANDS_TICK_SPRINT_STOP_FAIL,
[], [],
)) ))
.await; .await;
@ -287,7 +297,7 @@ impl CommandExecutor for TickExecutor {
if manager.stop_sprinting(server).await { if manager.stop_sprinting(server).await {
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.tick.sprint.stop.success", translation::COMMANDS_TICK_SPRINT_STOP_SUCCESS,
[], [],
)) ))
.await; .await;
@ -296,8 +306,11 @@ impl CommandExecutor for TickExecutor {
// TODO: send feedback as error without Err // TODO: send feedback as error without Err
sender sender
.send_message( .send_message(
TextComponent::translate("commands.tick.sprint.stop.fail", []) TextComponent::translate(
.color(Color::Named(NamedColor::Red)), translation::COMMANDS_TICK_SPRINT_STOP_FAIL,
[],
)
.color(Color::Named(NamedColor::Red)),
) )
.await; .await;
Ok(0) Ok(0)

View File

@ -1,3 +1,4 @@
use pumpkin_data::translation;
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
use crate::command::CommandResult; use crate::command::CommandResult;
@ -67,7 +68,7 @@ impl CommandExecutor for QueryExecutor {
}; };
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.time.query", translation::COMMANDS_TIME_QUERY,
[TextComponent::text(curr_time.to_string())], [TextComponent::text(curr_time.to_string())],
)) ))
.await; .await;
@ -112,7 +113,7 @@ impl CommandExecutor for ChangeExecutor {
let curr_time = level_time.query_daytime(); let curr_time = level_time.query_daytime();
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.time.set", translation::COMMANDS_TIME_SET,
[TextComponent::text(curr_time.to_string())], [TextComponent::text(curr_time.to_string())],
)) ))
.await; .await;
@ -124,7 +125,7 @@ impl CommandExecutor for ChangeExecutor {
level_time.send_time(world).await; level_time.send_time(world).await;
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.time.set", translation::COMMANDS_TIME_SET,
[TextComponent::text(time_count.to_string())], [TextComponent::text(time_count.to_string())],
)) ))
.await; .await;

View File

@ -1,3 +1,4 @@
use pumpkin_data::translation;
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
use crate::command::{ use crate::command::{
@ -51,7 +52,10 @@ impl CommandExecutor for Executor {
.set_weather_parameters(&world, processed_duration, 0, false, false) .set_weather_parameters(&world, processed_duration, 0, false, false)
.await; .await;
sender sender
.send_message(TextComponent::translate("commands.weather.set.clear", [])) .send_message(TextComponent::translate(
translation::COMMANDS_WEATHER_SET_CLEAR,
[],
))
.await; .await;
} }
WeatherMode::Rain => { WeatherMode::Rain => {
@ -62,7 +66,10 @@ impl CommandExecutor for Executor {
.set_weather_parameters(&world, 0, processed_duration, true, false) .set_weather_parameters(&world, 0, processed_duration, true, false)
.await; .await;
sender sender
.send_message(TextComponent::translate("commands.weather.set.rain", [])) .send_message(TextComponent::translate(
translation::COMMANDS_WEATHER_SET_RAIN,
[],
))
.await; .await;
} }
WeatherMode::Thunder => { WeatherMode::Thunder => {
@ -73,7 +80,10 @@ impl CommandExecutor for Executor {
.set_weather_parameters(&world, 0, processed_duration, true, true) .set_weather_parameters(&world, 0, processed_duration, true, true)
.await; .await;
sender sender
.send_message(TextComponent::translate("commands.weather.set.thunder", [])) .send_message(TextComponent::translate(
translation::COMMANDS_WEATHER_SET_THUNDER,
[],
))
.await; .await;
} }
} }

View File

@ -1,6 +1,7 @@
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use pumpkin_config::whitelist::WhitelistEntry; use pumpkin_config::whitelist::WhitelistEntry;
use pumpkin_data::translation;
use pumpkin_util::text::TextComponent; use pumpkin_util::text::TextComponent;
use crate::command::CommandResult; use crate::command::CommandResult;
@ -34,7 +35,10 @@ async fn kick_non_whitelisted_players(server: &Server) {
player player
.kick( .kick(
DisconnectReason::Kicked, DisconnectReason::Kicked,
TextComponent::translate("multiplayer.disconnect.not_whitelisted", &[]), TextComponent::translate(
translation::MULTIPLAYER_DISCONNECT_NOT_WHITELISTED,
&[],
),
) )
.await; .await;
} }
@ -54,13 +58,16 @@ impl CommandExecutor for OnExecutor {
let previous = server.white_list.swap(true, Ordering::Relaxed); let previous = server.white_list.swap(true, Ordering::Relaxed);
if previous { if previous {
Err(CommandError::CommandFailed(TextComponent::translate( Err(CommandError::CommandFailed(TextComponent::translate(
"commands.whitelist.alreadyOn", translation::COMMANDS_WHITELIST_ALREADYON,
&[], &[],
))) )))
} else { } else {
kick_non_whitelisted_players(server).await; kick_non_whitelisted_players(server).await;
sender sender
.send_message(TextComponent::translate("commands.whitelist.enabled", &[])) .send_message(TextComponent::translate(
translation::COMMANDS_WHITELIST_ENABLED,
&[],
))
.await; .await;
Ok(1) Ok(1)
} }
@ -81,12 +88,15 @@ impl CommandExecutor for OffExecutor {
let previous = server.white_list.swap(false, Ordering::Relaxed); let previous = server.white_list.swap(false, Ordering::Relaxed);
if previous { if previous {
sender sender
.send_message(TextComponent::translate("commands.whitelist.disabled", &[])) .send_message(TextComponent::translate(
translation::COMMANDS_WHITELIST_DISABLED,
&[],
))
.await; .await;
Ok(1) Ok(1)
} else { } else {
Err(CommandError::CommandFailed(TextComponent::translate( Err(CommandError::CommandFailed(TextComponent::translate(
"commands.whitelist.alreadyOff", translation::COMMANDS_WHITELIST_ALREADYOFF,
&[], &[],
))) )))
} }
@ -107,7 +117,10 @@ impl CommandExecutor for ListExecutor {
let whitelist = &server.data.whitelist_config.read().await.whitelist; let whitelist = &server.data.whitelist_config.read().await.whitelist;
if whitelist.is_empty() { if whitelist.is_empty() {
sender sender
.send_message(TextComponent::translate("commands.whitelist.none", [])) .send_message(TextComponent::translate(
translation::COMMANDS_WHITELIST_NONE,
[],
))
.await; .await;
return Ok(0); return Ok(0);
} }
@ -122,7 +135,7 @@ impl CommandExecutor for ListExecutor {
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.whitelist.list", translation::COMMANDS_WHITELIST_LIST,
[ [
TextComponent::text(whitelist.len().to_string()), TextComponent::text(whitelist.len().to_string()),
TextComponent::text(names), TextComponent::text(names),
@ -148,7 +161,10 @@ impl CommandExecutor for ReloadExecutor {
*server.data.whitelist_config.write().await = WhitelistConfig::load(); *server.data.whitelist_config.write().await = WhitelistConfig::load();
kick_non_whitelisted_players(server).await; kick_non_whitelisted_players(server).await;
sender sender
.send_message(TextComponent::translate("commands.whitelist.reloaded", &[])) .send_message(TextComponent::translate(
translation::COMMANDS_WHITELIST_RELOADED,
&[],
))
.await; .await;
Ok(1) Ok(1)
}) })
@ -181,7 +197,7 @@ impl CommandExecutor for AddExecutor {
.push(WhitelistEntry::new(profile.id, profile.name.clone())); .push(WhitelistEntry::new(profile.id, profile.name.clone()));
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.whitelist.add.success", translation::COMMANDS_WHITELIST_ADD_SUCCESS,
[TextComponent::text(profile.name.clone())], [TextComponent::text(profile.name.clone())],
)) ))
.await; .await;
@ -192,7 +208,7 @@ impl CommandExecutor for AddExecutor {
if successes == 0 { if successes == 0 {
Err(CommandError::CommandFailed(TextComponent::translate( Err(CommandError::CommandFailed(TextComponent::translate(
"commands.whitelist.add.failed", translation::COMMANDS_WHITELIST_ADD_FAILED,
&[], &[],
))) )))
} else { } else {
@ -228,7 +244,7 @@ impl CommandExecutor for RemoveExecutor {
whitelist.whitelist.remove(i); whitelist.whitelist.remove(i);
sender sender
.send_message(TextComponent::translate( .send_message(TextComponent::translate(
"commands.whitelist.remove.success", translation::COMMANDS_WHITELIST_REMOVE_SUCCESS,
[player.get_display_name().await], [player.get_display_name().await],
)) ))
.await; .await;
@ -243,7 +259,7 @@ impl CommandExecutor for RemoveExecutor {
if successes == 0 { if successes == 0 {
Err(CommandError::CommandFailed(TextComponent::translate( Err(CommandError::CommandFailed(TextComponent::translate(
"commands.whitelist.remove.failed", translation::COMMANDS_WHITELIST_REMOVE_FAILED,
&[], &[],
))) )))
} else { } else {

View File

@ -23,12 +23,12 @@ use crate::entity::{EntityBaseFuture, NbtFuture};
use crate::server::Server; use crate::server::Server;
use crate::world::loot::{LootContextParameters, LootTableExt}; use crate::world::loot::{LootContextParameters, LootTableExt};
use crossbeam::atomic::AtomicCell; use crossbeam::atomic::AtomicCell;
use pumpkin_data::Block;
use pumpkin_data::damage::DeathMessageType; use pumpkin_data::damage::DeathMessageType;
use pumpkin_data::data_component_impl::{DeathProtectionImpl, EquipmentSlot, FoodImpl}; use pumpkin_data::data_component_impl::{DeathProtectionImpl, EquipmentSlot, FoodImpl};
use pumpkin_data::effect::StatusEffect; use pumpkin_data::effect::StatusEffect;
use pumpkin_data::entity::{EntityPose, EntityStatus, EntityType}; use pumpkin_data::entity::{EntityPose, EntityStatus, EntityType};
use pumpkin_data::sound::SoundCategory; use pumpkin_data::sound::SoundCategory;
use pumpkin_data::{Block, translation};
use pumpkin_data::{damage::DamageType, sound::Sound}; use pumpkin_data::{damage::DamageType, sound::Sound};
use pumpkin_inventory::entity_equipment::EntityEquipment; use pumpkin_inventory::entity_equipment::EntityEquipment;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
@ -888,7 +888,7 @@ impl LivingEntity {
DeathMessageType::FallVariants => { DeathMessageType::FallVariants => {
//TODO //TODO
TextComponent::translate( TextComponent::translate(
"death.fell.accident.generic", translation::DEATH_FELL_ACCIDENT_GENERIC,
[dyn_self.get_display_name().await], [dyn_self.get_display_name().await],
) )
} }

View File

@ -38,7 +38,7 @@ use pumpkin_data::entity::{EntityPose, EntityStatus, EntityType};
use pumpkin_data::particle::Particle; use pumpkin_data::particle::Particle;
use pumpkin_data::sound::{Sound, SoundCategory}; use pumpkin_data::sound::{Sound, SoundCategory};
use pumpkin_data::tag::Taggable; use pumpkin_data::tag::Taggable;
use pumpkin_data::{Block, BlockState, Enchantment, tag}; use pumpkin_data::{Block, BlockState, Enchantment, tag, translation};
use pumpkin_inventory::player::{ use pumpkin_inventory::player::{
player_inventory::PlayerInventory, player_screen_handler::PlayerScreenHandler, player_inventory::PlayerInventory, player_screen_handler::PlayerScreenHandler,
}; };
@ -1378,7 +1378,7 @@ impl Player {
if idle_duration >= Duration::from_secs(idle_timeout_minutes as u64 * 60) { if idle_duration >= Duration::from_secs(idle_timeout_minutes as u64 * 60) {
self.kick( self.kick(
DisconnectReason::KickedForIdle, DisconnectReason::KickedForIdle,
TextComponent::translate("multiplayer.disconnect.idling", []), TextComponent::translate(translation::MULTIPLAYER_DISCONNECT_IDLING, []),
) )
.await; .await;
return; return;
@ -1394,7 +1394,7 @@ impl Player {
if self.wait_for_keep_alive.load(Ordering::Relaxed) { if self.wait_for_keep_alive.load(Ordering::Relaxed) {
self.kick( self.kick(
DisconnectReason::Timeout, DisconnectReason::Timeout,
TextComponent::translate("disconnect.timeout", []), TextComponent::translate(translation::DISCONNECT_TIMEOUT, []),
) )
.await; .await;
return; return;

View File

@ -1,4 +1,4 @@
use pumpkin_data::packet::CURRENT_MC_PROTOCOL; use pumpkin_data::{packet::CURRENT_MC_PROTOCOL, translation};
use pumpkin_protocol::{ConnectionState, java::server::handshake::SHandShake}; use pumpkin_protocol::{ConnectionState, java::server::handshake::SHandShake};
use pumpkin_util::{text::TextComponent, version::MinecraftVersion}; use pumpkin_util::{text::TextComponent, version::MinecraftVersion};
@ -18,13 +18,13 @@ impl JavaClient {
let protocol = version; let protocol = version;
if protocol < LOWEST_SUPPRORTED_PROTOCOL_VERSION { if protocol < LOWEST_SUPPRORTED_PROTOCOL_VERSION {
self.kick(TextComponent::translate( self.kick(TextComponent::translate(
"multiplayer.disconnect.outdated_client", translation::MULTIPLAYER_DISCONNECT_OUTDATED_CLIENT,
[TextComponent::text(CURRENT_MC_VERSION.to_string())], [TextComponent::text(CURRENT_MC_VERSION.to_string())],
)) ))
.await; .await;
} else if protocol > CURRENT_MC_PROTOCOL { } else if protocol > CURRENT_MC_PROTOCOL {
self.kick(TextComponent::translate( self.kick(TextComponent::translate(
"multiplayer.disconnect.incompatible", translation::MULTIPLAYER_DISCONNECT_OUTDATED_SERVER,
[TextComponent::text(CURRENT_MC_VERSION.to_string())], [TextComponent::text(CURRENT_MC_VERSION.to_string())],
)) ))
.await; .await;

View File

@ -1,3 +1,4 @@
use pumpkin_data::translation;
use pumpkin_protocol::{ use pumpkin_protocol::{
ConnectionState, KnownPack, Label, Link, LinkType, ConnectionState, KnownPack, Label, Link, LinkType,
java::client::{ java::client::{
@ -33,7 +34,7 @@ impl JavaClient {
let max_players = server.basic_config.max_players; let max_players = server.basic_config.max_players;
if max_players > 0 && server.get_player_count() >= max_players as usize { if max_players > 0 && server.get_player_count() >= max_players as usize {
self.kick(TextComponent::translate( self.kick(TextComponent::translate(
"multiplayer.disconnect.server_full", translation::MULTIPLAYER_DISCONNECT_SERVER_FULL,
[], [],
)) ))
.await; .await;
@ -135,11 +136,12 @@ impl JavaClient {
Ok(new_profile) => *profile = new_profile, Ok(new_profile) => *profile = new_profile,
Err(error) => { Err(error) => {
self.kick(match error { self.kick(match error {
AuthError::FailedResponse => { AuthError::FailedResponse => TextComponent::translate(
TextComponent::translate("multiplayer.disconnect.authservers_down", []) translation::MULTIPLAYER_DISCONNECT_AUTHSERVERS_DOWN,
} [],
),
AuthError::UnverifiedUsername => TextComponent::translate( AuthError::UnverifiedUsername => TextComponent::translate(
"multiplayer.disconnect.unverified_username", translation::MULTIPLAYER_DISCONNECT_UNVERIFIED_USERNAME,
[], [],
), ),
e => TextComponent::text(e.to_string()), e => TextComponent::text(e.to_string()),
@ -159,7 +161,7 @@ impl JavaClient {
&online_player.gameprofile.name &online_player.gameprofile.name
); );
self.kick(TextComponent::translate( self.kick(TextComponent::translate(
"multiplayer.disconnect.duplicate_login", translation::MULTIPLAYER_DISCONNECT_DUPLICATE_LOGIN,
[], [],
)) ))
.await; .await;
@ -176,7 +178,7 @@ impl JavaClient {
&online_player.gameprofile.name &online_player.gameprofile.name
); );
self.kick(TextComponent::translate( self.kick(TextComponent::translate(
"multiplayer.disconnect.duplicate_login", translation::MULTIPLAYER_DISCONNECT_DUPLICATE_LOGIN,
[], [],
)) ))
.await; .await;

View File

@ -30,7 +30,7 @@ use pumpkin_data::block_properties::{
use pumpkin_data::data_component_impl::{ConsumableImpl, EquipmentSlot, EquippableImpl, FoodImpl}; use pumpkin_data::data_component_impl::{ConsumableImpl, EquipmentSlot, EquippableImpl, FoodImpl};
use pumpkin_data::item::Item; use pumpkin_data::item::Item;
use pumpkin_data::sound::{Sound, SoundCategory}; use pumpkin_data::sound::{Sound, SoundCategory};
use pumpkin_data::{Block, BlockDirection, BlockState}; use pumpkin_data::{Block, BlockDirection, BlockState, translation};
use pumpkin_inventory::InventoryError; use pumpkin_inventory::InventoryError;
use pumpkin_inventory::player::player_inventory::PlayerInventory; use pumpkin_inventory::player::player_inventory::PlayerInventory;
use pumpkin_inventory::screen_handler::{InventoryPlayer, ScreenHandler}; use pumpkin_inventory::screen_handler::{InventoryPlayer, ScreenHandler};
@ -136,30 +136,47 @@ impl PumpkinError for ChatError {
match self { match self {
Self::OversizedMessage => Some("Chat message too long".into()), Self::OversizedMessage => Some("Chat message too long".into()),
Self::IllegalCharacters => Some( Self::IllegalCharacters => Some(
TextComponent::translate("multiplayer.disconnect.illegal_characters", []) TextComponent::translate(
.get_text(), translation::MULTIPLAYER_DISCONNECT_ILLEGAL_CHARACTERS,
[],
)
.get_text(),
), ),
Self::UnsignedChat => Some( Self::UnsignedChat => Some(
TextComponent::translate("multiplayer.disconnect.unsigned_chat", []).get_text(), TextComponent::translate(translation::MULTIPLAYER_DISCONNECT_UNSIGNED_CHAT, [])
.get_text(),
), ),
Self::TooManyPendingChats => Some( Self::TooManyPendingChats => Some(
TextComponent::translate("multiplayer.disconnect.too_many_pending_chats", []) TextComponent::translate(
.get_text(), translation::MULTIPLAYER_DISCONNECT_TOO_MANY_PENDING_CHATS,
[],
)
.get_text(),
), ),
Self::ChatValidationFailed => Some( Self::ChatValidationFailed => Some(
TextComponent::translate("multiplayer.disconnect.chat_validation_failed", []) TextComponent::translate(
.get_text(), translation::MULTIPLAYER_DISCONNECT_CHAT_VALIDATION_FAILED,
[],
)
.get_text(),
), ),
Self::OutOfOrderChat => Some( Self::OutOfOrderChat => Some(
TextComponent::translate("multiplayer.disconnect.out_of_order_chat", []).get_text(), TextComponent::translate(translation::MULTIPLAYER_DISCONNECT_OUT_OF_ORDER_CHAT, [])
.get_text(),
), ),
Self::ExpiredPublicKey => Some( Self::ExpiredPublicKey => Some(
TextComponent::translate("multiplayer.disconnect.expired_public_key", []) TextComponent::translate(
.get_text(), translation::MULTIPLAYER_DISCONNECT_EXPIRED_PUBLIC_KEY,
[],
)
.get_text(),
), ),
Self::InvalidPublicKey => Some( Self::InvalidPublicKey => Some(
TextComponent::translate("multiplayer.disconnect.invalid_public_key_signature", []) TextComponent::translate(
.get_text(), translation::MULTIPLAYER_DISCONNECT_INVALID_PUBLIC_KEY_SIGNATURE,
[],
)
.get_text(),
), ),
} }
} }
@ -206,7 +223,7 @@ impl JavaClient {
); );
player player
.send_system_message(&TextComponent::translate( .send_system_message(&TextComponent::translate(
"commands.gamemode.success.self", translation::COMMANDS_GAMEMODE_SUCCESS_SELF,
[TextComponent::translate(gamemode_string, [])], [TextComponent::translate(gamemode_string, [])],
)) ))
.await; .await;
@ -274,7 +291,7 @@ impl JavaClient {
let position = packet.position; let position = packet.position;
if position.x.is_nan() || position.y.is_nan() || position.z.is_nan() { if position.x.is_nan() || position.y.is_nan() || position.z.is_nan() {
self.kick(TextComponent::translate( self.kick(TextComponent::translate(
"multiplayer.disconnect.invalid_player_movement", translation::MULTIPLAYER_DISCONNECT_INVALID_PLAYER_MOVEMENT,
[], [],
)) ))
.await; .await;
@ -387,7 +404,7 @@ impl JavaClient {
|| !packet.pitch.is_finite() || !packet.pitch.is_finite()
{ {
self.kick(TextComponent::translate( self.kick(TextComponent::translate(
"multiplayer.disconnect.invalid_player_movement", translation::MULTIPLAYER_DISCONNECT_INVALID_PLAYER_MOVEMENT,
[], [],
)) ))
.await; .await;
@ -517,7 +534,7 @@ impl JavaClient {
} }
if !rotation.yaw.is_finite() || !rotation.pitch.is_finite() { if !rotation.yaw.is_finite() || !rotation.pitch.is_finite() {
self.kick(TextComponent::translate( self.kick(TextComponent::translate(
"multiplayer.disconnect.invalid_player_movement", translation::MULTIPLAYER_DISCONNECT_INVALID_PLAYER_MOVEMENT,
[], [],
)) ))
.await; .await;
@ -1215,7 +1232,7 @@ impl JavaClient {
if entity_id.0 == player.entity_id() { if entity_id.0 == player.entity_id() {
// This can't be triggered from a non-modded client. // This can't be triggered from a non-modded client.
self.kick(TextComponent::translate( self.kick(TextComponent::translate(
"multiplayer.disconnect.invalid_entity_attacked", translation::MULTIPLAYER_DISCONNECT_INVALID_ENTITY_ATTACKED,
[], [],
)) ))
.await; .await;
@ -1249,7 +1266,7 @@ impl JavaClient {
entity_id.0 entity_id.0
); );
self.kick(TextComponent::translate( self.kick(TextComponent::translate(
"multiplayer.disconnect.invalid_entity_attacked", translation::MULTIPLAYER_DISCONNECT_INVALID_ENTITY_ATTACKED,
[], [],
)) ))
.await; .await;
@ -1976,7 +1993,7 @@ impl JavaClient {
player player
.send_system_message_raw( .send_system_message_raw(
&TextComponent::translate( &TextComponent::translate(
"build.tooHigh", translation::BUILD_TOOHIGH,
vec![TextComponent::text((world.get_top_y()).to_string())], vec![TextComponent::text((world.get_top_y()).to_string())],
) )
.color_named(NamedColor::Red), .color_named(NamedColor::Red),

View File

@ -10,6 +10,7 @@ use crate::{
server::Server, server::Server,
}; };
use pumpkin_data::translation;
use pumpkin_protocol::{ClientPacket, Property}; use pumpkin_protocol::{ClientPacket, Property};
use pumpkin_util::{Hand, ProfileAction, text::TextComponent}; use pumpkin_util::{Hand, ProfileAction, text::TextComponent};
use serde::Deserialize; use serde::Deserialize;
@ -177,12 +178,12 @@ pub async fn can_not_join(
let mut banned_players = server.data.banned_player_list.write().await; let mut banned_players = server.data.banned_player_list.write().await;
if let Some(entry) = banned_players.get_entry(profile) { if let Some(entry) = banned_players.get_entry(profile) {
let text = TextComponent::translate( let text = TextComponent::translate(
"multiplayer.disconnect.banned.reason", translation::MULTIPLAYER_DISCONNECT_BANNED_REASON,
[TextComponent::text(entry.reason.clone())], [TextComponent::text(entry.reason.clone())],
); );
return Some(match entry.expires { return Some(match entry.expires {
Some(expires) => text.add_child(TextComponent::translate( Some(expires) => text.add_child(TextComponent::translate(
"multiplayer.disconnect.banned.expiration", translation::MULTIPLAYER_DISCONNECT_BANNED_EXPIRATION,
[TextComponent::text( [TextComponent::text(
expires.format(FORMAT_DESCRIPTION).unwrap(), expires.format(FORMAT_DESCRIPTION).unwrap(),
)], )],
@ -198,7 +199,7 @@ pub async fn can_not_join(
if ops.get_entry(&profile.id).is_none() && !whitelist.is_whitelisted(profile) { if ops.get_entry(&profile.id).is_none() && !whitelist.is_whitelisted(profile) {
return Some(TextComponent::translate( return Some(TextComponent::translate(
"multiplayer.disconnect.not_whitelisted", translation::MULTIPLAYER_DISCONNECT_NOT_WHITELISTED,
&[], &[],
)); ));
} }
@ -212,12 +213,12 @@ pub async fn can_not_join(
.get_entry(&address.ip()) .get_entry(&address.ip())
{ {
let text = TextComponent::translate( let text = TextComponent::translate(
"multiplayer.disconnect.banned_ip.reason", translation::MULTIPLAYER_DISCONNECT_BANNED_IP_REASON,
[TextComponent::text(entry.reason.clone())], [TextComponent::text(entry.reason.clone())],
); );
return Some(match entry.expires { return Some(match entry.expires {
Some(expires) => text.add_child(TextComponent::translate( Some(expires) => text.add_child(TextComponent::translate(
"multiplayer.disconnect.banned_ip.expiration", translation::MULTIPLAYER_DISCONNECT_BANNED_IP_EXPIRATION,
[TextComponent::text( [TextComponent::text(
expires.format(FORMAT_DESCRIPTION).unwrap(), expires.format(FORMAT_DESCRIPTION).unwrap(),
)], )],

View File

@ -2,6 +2,7 @@ use std::sync::atomic::{AtomicBool, AtomicI32, AtomicI64, Ordering};
use std::time::Instant; use std::time::Instant;
use crossbeam::atomic::AtomicCell; use crossbeam::atomic::AtomicCell;
use pumpkin_data::translation;
use pumpkin_protocol::java::client::play::{CSystemChatMessage, CTickingState, CTickingStep}; use pumpkin_protocol::java::client::play::{CSystemChatMessage, CTickingState, CTickingStep};
use pumpkin_util::text::{TextComponent, color::NamedColor}; use pumpkin_util::text::{TextComponent, color::NamedColor};
@ -160,7 +161,7 @@ impl ServerTickRateManager {
let mspt = time_spent_ms / total_sprinted_ticks as f64; let mspt = time_spent_ms / total_sprinted_ticks as f64;
TextComponent::translate( TextComponent::translate(
"commands.tick.sprint.report", translation::COMMANDS_TICK_SPRINT_REPORT,
[ [
TextComponent::text(format!("{tps:.2}")), TextComponent::text(format!("{tps:.2}")),
TextComponent::text(format!("{mspt:.2}")), TextComponent::text(format!("{mspt:.2}")),
@ -168,7 +169,7 @@ impl ServerTickRateManager {
) )
} else { } else {
// This is the message for `/tick sprint stop` or a zero-tick sprint. // This is the message for `/tick sprint stop` or a zero-tick sprint.
TextComponent::translate("commands.tick.sprint.stop.success", []) TextComponent::translate(translation::COMMANDS_TICK_SPRINT_STOP_SUCCESS, [])
}; };
// Construct the final component with the [Server: ...] wrapper // Construct the final component with the [Server: ...] wrapper

View File

@ -52,7 +52,7 @@ use pumpkin_data::{
sound::{Sound, SoundCategory}, sound::{Sound, SoundCategory},
world::{RAW, WorldEvent}, world::{RAW, WorldEvent},
}; };
use pumpkin_data::{BlockDirection, BlockState}; use pumpkin_data::{BlockDirection, BlockState, translation};
use pumpkin_inventory::screen_handler::InventoryPlayer; use pumpkin_inventory::screen_handler::InventoryPlayer;
use pumpkin_nbt::{compound::NbtCompound, to_bytes_unnamed}; use pumpkin_nbt::{compound::NbtCompound, to_bytes_unnamed};
use pumpkin_protocol::bedrock::client::set_actor_data::{ use pumpkin_protocol::bedrock::client::set_actor_data::{
@ -2475,7 +2475,7 @@ impl World {
let current_players = self.players.load(); let current_players = self.players.load();
player.clone().spawn_task(async move { player.clone().spawn_task(async move {
let msg_comp = TextComponent::translate( let msg_comp = TextComponent::translate(
"multiplayer.player.joined", translation::MULTIPLAYER_PLAYER_JOINED,
[TextComponent::text(player.gameprofile.name.clone())], [TextComponent::text(player.gameprofile.name.clone())],
) )
.color_named(NamedColor::Yellow); .color_named(NamedColor::Yellow);
@ -2539,7 +2539,7 @@ impl World {
if fire_event { if fire_event {
let msg_comp = TextComponent::translate( let msg_comp = TextComponent::translate(
"multiplayer.player.left", translation::MULTIPLAYER_PLAYER_LEFT,
[TextComponent::text(player.gameprofile.name.clone())], [TextComponent::text(player.gameprofile.name.clone())],
) )
.color_named(NamedColor::Yellow); .color_named(NamedColor::Yellow);