feat: add from_legacy_string to TextComponent
This commit is contained in:
parent
d64f538138
commit
72bd4dfbef
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -636,9 +636,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossfire"
|
name = "crossfire"
|
||||||
version = "3.0.2"
|
version = "3.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7e1ff29ef3add47897a4dab381889ccf8dedcedec4e2c8feed37efcf22a6392b"
|
checksum = "cf9c756fd351d7bc1f95698a33a90ce39c8f7458335cc7e95132d3d36124902a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@ -2386,7 +2386,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.10.0-rc.8"
|
version = "0.10.0-rc.8"
|
||||||
source = "git+https://github.com/rust-random/rand#47455a0b004d5992d2a3d23ecf244f1edea27f40"
|
source = "git+https://github.com/rust-random/rand#a4c9a8e565fa310de423e3ba89593b647b721e8c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chacha20",
|
"chacha20",
|
||||||
"getrandom 0.4.0-rc.1",
|
"getrandom 0.4.0-rc.1",
|
||||||
|
|||||||
@ -115,7 +115,7 @@ console-subscriber = { version = "0.5.0", default-features = false }
|
|||||||
crc-fast = "1.10.0"
|
crc-fast = "1.10.0"
|
||||||
criterion = { version = "0.8", default-features = false }
|
criterion = { version = "0.8", default-features = false }
|
||||||
crossbeam-utils = "0.8.21"
|
crossbeam-utils = "0.8.21"
|
||||||
crossfire = { version= "3.0.2", features = ["compat"]}
|
crossfire = { version= "3.0.3", features = ["compat"]}
|
||||||
dashmap = "6.1"
|
dashmap = "6.1"
|
||||||
ecdsa = "0.16.9"
|
ecdsa = "0.16.9"
|
||||||
enum_dispatch = "0.3.13"
|
enum_dispatch = "0.3.13"
|
||||||
|
|||||||
@ -92,6 +92,41 @@ impl Color {
|
|||||||
Self::Rgb(color) => text.truecolor(color.red, color.green, color.blue),
|
Self::Rgb(color) => text.truecolor(color.red, color.green, color.blue),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub const fn from_legacy_code(code: char) -> Option<Self> {
|
||||||
|
let named = match code.to_ascii_lowercase() {
|
||||||
|
'0' => NamedColor::Black,
|
||||||
|
'1' => NamedColor::DarkBlue,
|
||||||
|
'2' => NamedColor::DarkGreen,
|
||||||
|
'3' => NamedColor::DarkAqua,
|
||||||
|
'4' => NamedColor::DarkRed,
|
||||||
|
'5' => NamedColor::DarkPurple,
|
||||||
|
'6' => NamedColor::Gold,
|
||||||
|
'7' => NamedColor::Gray,
|
||||||
|
'8' => NamedColor::DarkGray,
|
||||||
|
'9' => NamedColor::Blue,
|
||||||
|
'a' => NamedColor::Green,
|
||||||
|
'b' => NamedColor::Aqua,
|
||||||
|
'c' => NamedColor::Red,
|
||||||
|
'd' => NamedColor::LightPurple,
|
||||||
|
'e' => NamedColor::Yellow,
|
||||||
|
'f' => NamedColor::White,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
Some(Self::Named(named))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn from_hex_str(hex: &str) -> Option<Self> {
|
||||||
|
if hex.len() != 6 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let r = u8::from_str_radix(&hex[0..2], 16).ok()?;
|
||||||
|
let g = u8::from_str_radix(&hex[2..4], 16).ok()?;
|
||||||
|
let b = u8::from_str_radix(&hex[4..6], 16).ok()?;
|
||||||
|
Some(Self::Rgb(RGBColor::new(r, g, b)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Clone, Copy, Eq, Hash, PartialEq)]
|
#[derive(Debug, Deserialize, Clone, Copy, Eq, Hash, PartialEq)]
|
||||||
|
|||||||
@ -284,6 +284,109 @@ impl TextComponent {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn from_legacy_string(input: &str) -> Self {
|
||||||
|
let mut root = Self::text("");
|
||||||
|
let parts: Vec<&str> = input.split('§').collect();
|
||||||
|
|
||||||
|
if !parts[0].is_empty() {
|
||||||
|
root = root.add_child(Self::text(parts[0].to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut current_color: Option<Color> = None;
|
||||||
|
let mut bold = false;
|
||||||
|
let mut italic = false;
|
||||||
|
let mut underlined = false;
|
||||||
|
let mut strikethrough = false;
|
||||||
|
let mut obfuscated = false;
|
||||||
|
|
||||||
|
let mut i = 1;
|
||||||
|
while i < parts.len() {
|
||||||
|
let part = parts[i];
|
||||||
|
if part.is_empty() {
|
||||||
|
i += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut chars = part.chars();
|
||||||
|
let code = chars.next().unwrap_or(' ').to_ascii_lowercase();
|
||||||
|
let remainder = &part[1..];
|
||||||
|
|
||||||
|
match code {
|
||||||
|
'x' if i + 6 < parts.len() => {
|
||||||
|
let mut hex = String::new();
|
||||||
|
for j in 1..=6 {
|
||||||
|
if let Some(c) = parts[i + j].chars().next() {
|
||||||
|
hex.push(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current_color = Color::from_hex_str(&hex);
|
||||||
|
|
||||||
|
i += 6;
|
||||||
|
|
||||||
|
let last_part = parts[i];
|
||||||
|
if last_part.len() > 1 {
|
||||||
|
let mut child = Self::text(last_part[1..].to_string());
|
||||||
|
if let Some(c) = current_color {
|
||||||
|
child = child.color(c);
|
||||||
|
}
|
||||||
|
root = root.add_child(child);
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
'0'..='9' | 'a'..='f' => {
|
||||||
|
current_color = Color::from_legacy_code(code);
|
||||||
|
bold = false;
|
||||||
|
italic = false;
|
||||||
|
underlined = false;
|
||||||
|
strikethrough = false;
|
||||||
|
obfuscated = false;
|
||||||
|
}
|
||||||
|
'l' => bold = true,
|
||||||
|
'o' => italic = true,
|
||||||
|
'n' => underlined = true,
|
||||||
|
'm' => strikethrough = true,
|
||||||
|
'k' => obfuscated = true,
|
||||||
|
'r' => {
|
||||||
|
current_color = None;
|
||||||
|
bold = false;
|
||||||
|
italic = false;
|
||||||
|
underlined = false;
|
||||||
|
strikethrough = false;
|
||||||
|
obfuscated = false;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !remainder.is_empty() {
|
||||||
|
let mut child = Self::text(remainder.to_string());
|
||||||
|
if let Some(c) = current_color {
|
||||||
|
child = child.color(c);
|
||||||
|
}
|
||||||
|
if bold {
|
||||||
|
child = child.bold();
|
||||||
|
}
|
||||||
|
if italic {
|
||||||
|
child = child.italic();
|
||||||
|
}
|
||||||
|
if underlined {
|
||||||
|
child = child.underlined();
|
||||||
|
}
|
||||||
|
if strikethrough {
|
||||||
|
child = child.strikethrough();
|
||||||
|
}
|
||||||
|
if obfuscated {
|
||||||
|
child = child.obfuscated();
|
||||||
|
}
|
||||||
|
root = root.add_child(child);
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
root
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn add_child(mut self, child: Self) -> Self {
|
pub fn add_child(mut self, child: Self) -> Self {
|
||||||
self.0.extra.push(child.0);
|
self.0.extra.push(child.0);
|
||||||
|
|||||||
@ -983,7 +983,7 @@ impl GenerationCache for Cache {
|
|||||||
// debug_assert!(dx >= 0 && dz >= 0);
|
// debug_assert!(dx >= 0 && dz >= 0);
|
||||||
if !(dx < self.size && dz < self.size && dx >= 0 && dz >= 0) {
|
if !(dx < self.size && dz < self.size && dx >= 0 && dz >= 0) {
|
||||||
// breakpoint here
|
// breakpoint here
|
||||||
log::error!(
|
log::debug!(
|
||||||
"illegal get_block_state {pos:?} cache pos ({}, {}) size {}",
|
"illegal get_block_state {pos:?} cache pos ({}, {}) size {}",
|
||||||
self.x,
|
self.x,
|
||||||
self.z,
|
self.z,
|
||||||
@ -1011,7 +1011,7 @@ impl GenerationCache for Cache {
|
|||||||
// debug_assert!(dx >= 0 && dz >= 0);
|
// debug_assert!(dx >= 0 && dz >= 0);
|
||||||
if !(dx < self.size && dz < self.size && dx >= 0 && dz >= 0) {
|
if !(dx < self.size && dz < self.size && dx >= 0 && dz >= 0) {
|
||||||
// breakpoint here
|
// breakpoint here
|
||||||
log::error!(
|
log::debug!(
|
||||||
"illegal set_block_state {pos:?} cache pos ({}, {}) size {}",
|
"illegal set_block_state {pos:?} cache pos ({}, {}) size {}",
|
||||||
self.x,
|
self.x,
|
||||||
self.z,
|
self.z,
|
||||||
|
|||||||
@ -178,8 +178,6 @@ impl PumpkinServer {
|
|||||||
|
|
||||||
let rcon = server.advanced_config.networking.rcon.clone();
|
let rcon = server.advanced_config.networking.rcon.clone();
|
||||||
|
|
||||||
let mut ticker = Ticker::new();
|
|
||||||
|
|
||||||
if server.advanced_config.commands.use_console
|
if server.advanced_config.commands.use_console
|
||||||
&& let Some((wrapper, _)) = LOGGER_IMPL.wait()
|
&& let Some((wrapper, _)) = LOGGER_IMPL.wait()
|
||||||
{
|
{
|
||||||
@ -267,7 +265,7 @@ impl PumpkinServer {
|
|||||||
{
|
{
|
||||||
let ticker_server = server.clone();
|
let ticker_server = server.clone();
|
||||||
server.spawn_task(async move {
|
server.spawn_task(async move {
|
||||||
ticker.run(&ticker_server).await;
|
Ticker::run(&ticker_server).await;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -5,26 +5,12 @@ use std::{
|
|||||||
};
|
};
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
|
||||||
pub struct Ticker {
|
pub struct Ticker;
|
||||||
last_tick: Instant,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Ticker {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Ticker {
|
impl Ticker {
|
||||||
#[must_use]
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
last_tick: Instant::now(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// IMPORTANT: Run this in a new thread/tokio task.
|
/// IMPORTANT: Run this in a new thread/tokio task.
|
||||||
pub async fn run(&mut self, server: &Arc<Server>) {
|
pub async fn run(server: &Arc<Server>) {
|
||||||
|
let mut last_tick = Instant::now();
|
||||||
while !SHOULD_STOP.load(Ordering::Relaxed) {
|
while !SHOULD_STOP.load(Ordering::Relaxed) {
|
||||||
let tick_start_time = Instant::now();
|
let tick_start_time = Instant::now();
|
||||||
let manager = &server.tick_rate_manager;
|
let manager = &server.tick_rate_manager;
|
||||||
@ -54,7 +40,7 @@ impl Ticker {
|
|||||||
|
|
||||||
// Sleep logic remains the same
|
// Sleep logic remains the same
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
let elapsed = now.duration_since(self.last_tick);
|
let elapsed = now.duration_since(last_tick);
|
||||||
|
|
||||||
let tick_interval = if manager.is_sprinting() {
|
let tick_interval = if manager.is_sprinting() {
|
||||||
Duration::ZERO
|
Duration::ZERO
|
||||||
@ -68,7 +54,7 @@ impl Ticker {
|
|||||||
sleep(sleep_time).await;
|
sleep(sleep_time).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.last_tick = Instant::now();
|
last_tick = Instant::now();
|
||||||
}
|
}
|
||||||
log::debug!("Ticker stopped");
|
log::debug!("Ticker stopped");
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user