From 508bfa93c0b3de898aa76f5007088631ce02db24 Mon Sep 17 00:00:00 2001
From: Christian Bergschneider
<37768199+Bloeckchengrafik@users.noreply.github.com>
Date: Mon, 13 Jun 2022 20:35:38 +0200
Subject: [PATCH 01/15] rotating_light: fix clippy warnings
---
README.md | 4 ++--
feather/base/src/anvil/player.rs | 8 +++-----
libcraft/items/src/item_stack.rs | 10 +++++++++-
3 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index aa6cfef37..99b37a98b 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
-# Feather
+# Feather
+
[](https://github.com/feather-rs/feather/actions)
[](https://discordapp.com/invite/4eYmK69)
-
A Minecraft server implementation written in Rust.
### Status
diff --git a/feather/base/src/anvil/player.rs b/feather/base/src/anvil/player.rs
index 2e6100eda..798ffa9ed 100644
--- a/feather/base/src/anvil/player.rs
+++ b/feather/base/src/anvil/player.rs
@@ -72,16 +72,14 @@ pub struct InventorySlot {
impl InventorySlot {
/// Converts an [`ItemStack`] and network protocol index into an [`InventorySlot`].
pub fn from_network_index(network: usize, stack: &ItemStack) -> Option {
- let slot = if SLOT_HOTBAR_OFFSET <= network && network < SLOT_HOTBAR_OFFSET + HOTBAR_SIZE {
+ let slot = if (SLOT_HOTBAR_OFFSET..SLOT_HOTBAR_OFFSET+HOTBAR_SIZE).contains(&network) {
// Hotbar
(network - SLOT_HOTBAR_OFFSET) as i8
} else if network == SLOT_OFFHAND {
-106
- } else if SLOT_ARMOR_MIN <= network && network <= SLOT_ARMOR_MAX {
+ } else if (SLOT_ARMOR_MIN..SLOT_ARMOR_MAX).contains(&network) {
((SLOT_ARMOR_MAX - network) + 100) as i8
- } else if SLOT_INVENTORY_OFFSET <= network
- && network < SLOT_INVENTORY_OFFSET + INVENTORY_SIZE
- {
+ } else if (SLOT_INVENTORY_OFFSET..SLOT_INVENTORY_OFFSET + INVENTORY_SIZE).contains(&network) {
network as i8
} else {
return None;
diff --git a/libcraft/items/src/item_stack.rs b/libcraft/items/src/item_stack.rs
index 067e0ac16..d1ec8b031 100644
--- a/libcraft/items/src/item_stack.rs
+++ b/libcraft/items/src/item_stack.rs
@@ -366,7 +366,15 @@ pub enum ItemStackError {
impl Display for ItemStackError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}", self)
+ let name = match self {
+ ItemStackError::ClientOverflow => "Client overflow",
+ ItemStackError::EmptyStack => "Empty stack",
+ ItemStackError::ExceedsStackSize => "Exceeds stack size",
+ ItemStackError::IncompatibleStacks => "Incompatible stacks",
+ ItemStackError::NotEnoughItems => "Not enough items",
+ };
+
+ write!(f, "{}", name)
}
}
From bdc2a80d8cb4630928675f20addf529d6712ff24 Mon Sep 17 00:00:00 2001
From: Christian Bergschneider
<37768199+Bloeckchengrafik@users.noreply.github.com>
Date: Mon, 13 Jun 2022 22:07:21 +0200
Subject: [PATCH 02/15] rotating_light: rustfmt
---
feather/base/src/anvil/player.rs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/feather/base/src/anvil/player.rs b/feather/base/src/anvil/player.rs
index 798ffa9ed..02cc2e3d0 100644
--- a/feather/base/src/anvil/player.rs
+++ b/feather/base/src/anvil/player.rs
@@ -72,14 +72,15 @@ pub struct InventorySlot {
impl InventorySlot {
/// Converts an [`ItemStack`] and network protocol index into an [`InventorySlot`].
pub fn from_network_index(network: usize, stack: &ItemStack) -> Option {
- let slot = if (SLOT_HOTBAR_OFFSET..SLOT_HOTBAR_OFFSET+HOTBAR_SIZE).contains(&network) {
+ let slot = if (SLOT_HOTBAR_OFFSET..SLOT_HOTBAR_OFFSET + HOTBAR_SIZE).contains(&network) {
// Hotbar
(network - SLOT_HOTBAR_OFFSET) as i8
} else if network == SLOT_OFFHAND {
-106
} else if (SLOT_ARMOR_MIN..SLOT_ARMOR_MAX).contains(&network) {
((SLOT_ARMOR_MAX - network) + 100) as i8
- } else if (SLOT_INVENTORY_OFFSET..SLOT_INVENTORY_OFFSET + INVENTORY_SIZE).contains(&network) {
+ } else if (SLOT_INVENTORY_OFFSET..SLOT_INVENTORY_OFFSET + INVENTORY_SIZE).contains(&network)
+ {
network as i8
} else {
return None;
From 8ab69a28f2d8d86ed1beaa281c50efc77769a605 Mon Sep 17 00:00:00 2001
From: Bloeckchengrafik <37768199+Bloeckchengrafik@users.noreply.github.com>
Date: Wed, 15 Jun 2022 08:20:36 +0200
Subject: [PATCH 03/15] Fix tests
---
feather/base/src/anvil/player.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/feather/base/src/anvil/player.rs b/feather/base/src/anvil/player.rs
index 02cc2e3d0..cdaa27b19 100644
--- a/feather/base/src/anvil/player.rs
+++ b/feather/base/src/anvil/player.rs
@@ -72,12 +72,12 @@ pub struct InventorySlot {
impl InventorySlot {
/// Converts an [`ItemStack`] and network protocol index into an [`InventorySlot`].
pub fn from_network_index(network: usize, stack: &ItemStack) -> Option {
- let slot = if (SLOT_HOTBAR_OFFSET..SLOT_HOTBAR_OFFSET + HOTBAR_SIZE).contains(&network) {
+ let slot = if (SLOT_HOTBAR_OFFSET..(SLOT_HOTBAR_OFFSET + HOTBAR_SIZE)).contains(&network) {
// Hotbar
(network - SLOT_HOTBAR_OFFSET) as i8
} else if network == SLOT_OFFHAND {
-106
- } else if (SLOT_ARMOR_MIN..SLOT_ARMOR_MAX).contains(&network) {
+ } else if (SLOT_ARMOR_MIN..(SLOT_ARMOR_MAX+1)).contains(&network) {
((SLOT_ARMOR_MAX - network) + 100) as i8
} else if (SLOT_INVENTORY_OFFSET..SLOT_INVENTORY_OFFSET + INVENTORY_SIZE).contains(&network)
{
From d14d82f83c9357fd786462849bc6de1283edbe36 Mon Sep 17 00:00:00 2001
From: Christian Bergschneider
<37768199+Bloeckchengrafik@users.noreply.github.com>
Date: Wed, 15 Jun 2022 19:35:18 +0200
Subject: [PATCH 04/15] rotating_light: rustfmt 2
---
feather/base/src/anvil/player.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/feather/base/src/anvil/player.rs b/feather/base/src/anvil/player.rs
index cdaa27b19..45afa1475 100644
--- a/feather/base/src/anvil/player.rs
+++ b/feather/base/src/anvil/player.rs
@@ -77,7 +77,7 @@ impl InventorySlot {
(network - SLOT_HOTBAR_OFFSET) as i8
} else if network == SLOT_OFFHAND {
-106
- } else if (SLOT_ARMOR_MIN..(SLOT_ARMOR_MAX+1)).contains(&network) {
+ } else if (SLOT_ARMOR_MIN..(SLOT_ARMOR_MAX + 1)).contains(&network) {
((SLOT_ARMOR_MAX - network) + 100) as i8
} else if (SLOT_INVENTORY_OFFSET..SLOT_INVENTORY_OFFSET + INVENTORY_SIZE).contains(&network)
{
From 6e54320e3eebb4fdf2406236ebba769b2054eb31 Mon Sep 17 00:00:00 2001
From: Christian Bergschneider
<37768199+Bloeckchengrafik@users.noreply.github.com>
Date: Thu, 16 Jun 2022 10:50:18 +0200
Subject: [PATCH 05/15] sparkles: Begin Chat-Ansi Implementation
---
Cargo.lock | 7 +++
feather/base/src/ansi.rs | 78 ++++++++++++++++++++++++++++++
feather/base/src/lib.rs | 1 +
feather/server/src/systems/chat.rs | 15 +++++-
libcraft/text/Cargo.toml | 1 +
libcraft/text/src/text.rs | 41 ++++++++++++++++
6 files changed, 142 insertions(+), 1 deletion(-)
create mode 100644 feather/base/src/ansi.rs
diff --git a/Cargo.lock b/Cargo.lock
index 0b4381092..84a8ecbf5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1430,6 +1430,7 @@ dependencies = [
"serde",
"serde_json",
"serde_with",
+ "string-builder",
"thiserror",
"uuid",
]
@@ -2769,6 +2770,12 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
+[[package]]
+name = "string-builder"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2bd10a070fb1f2796a288abec42695db4682a82b6f12ffacd60fb8d5ad3a4a12"
+
[[package]]
name = "strsim"
version = "0.10.0"
diff --git a/feather/base/src/ansi.rs b/feather/base/src/ansi.rs
new file mode 100644
index 000000000..dac77aebd
--- /dev/null
+++ b/feather/base/src/ansi.rs
@@ -0,0 +1,78 @@
+pub struct AnsiStyle {
+ format: u8,
+}
+
+impl AnsiStyle {
+ pub fn regular() -> AnsiStyle {
+ AnsiStyle { format: 0 }
+ }
+
+ pub fn bold() -> AnsiStyle {
+ AnsiStyle { format: 1 }
+ }
+
+ pub fn underline() -> AnsiStyle {
+ AnsiStyle { format: 4 }
+ }
+
+ fn format(&self, color: u8) -> String { format!("\033[{};{}m", self.format, color) }
+
+ pub fn black(&self) -> String { self.format(30) }
+
+ pub fn red(&self) -> String { self.format(31) }
+
+ pub fn green(&self) -> String { self.format(32) }
+
+ pub fn yellow(&self) -> String { self.format(33) }
+
+ pub fn blue(&self) -> String { self.format(34) }
+
+ pub fn magenta(&self) -> String { self.format(35) }
+
+ pub fn cyan(&self) -> String { self.format(36) }
+
+ pub fn white(&self) -> String { self.format(37) }
+
+ pub fn reset(&self) -> &'static str { "\033[0m" }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_ansi_style() {
+ let style = AnsiStyle::regular();
+ assert_eq!(style.black(), "\033[0;30m");
+ assert_eq!(style.red(), "\033[0;31m");
+ assert_eq!(style.green(), "\033[0;32m");
+ assert_eq!(style.yellow(), "\033[0;33m");
+ assert_eq!(style.blue(), "\033[0;34m");
+ assert_eq!(style.magenta(), "\033[0;35m");
+ assert_eq!(style.cyan(), "\033[0;36m");
+ assert_eq!(style.white(), "\033[0;37m");
+ assert_eq!(style.reset(), "\033[0m");
+
+ let style = AnsiStyle::bold();
+ assert_eq!(style.black(), "\033[1;30m");
+ assert_eq!(style.red(), "\033[1;31m");
+ assert_eq!(style.green(), "\033[1;32m");
+ assert_eq!(style.yellow(), "\033[1;33m");
+ assert_eq!(style.blue(), "\033[1;34m");
+ assert_eq!(style.magenta(), "\033[1;35m");
+ assert_eq!(style.cyan(), "\033[1;36m");
+ assert_eq!(style.white(), "\033[1;37m");
+ assert_eq!(style.reset(), "\033[0m");
+
+ let style = AnsiStyle::underline();
+ assert_eq!(style.black(), "\033[4;30m");
+ assert_eq!(style.red(), "\033[4;31m");
+ assert_eq!(style.green(), "\033[4;32m");
+ assert_eq!(style.yellow(), "\033[4;33m");
+ assert_eq!(style.blue(), "\033[4;34m");
+ assert_eq!(style.magenta(), "\033[4;35m");
+ assert_eq!(style.cyan(), "\033[4;36m");
+ assert_eq!(style.white(), "\033[4;37m");
+ assert_eq!(style.reset(), "\033[0m");
+ }
+}
\ No newline at end of file
diff --git a/feather/base/src/lib.rs b/feather/base/src/lib.rs
index 730d4c51a..5548e11e2 100644
--- a/feather/base/src/lib.rs
+++ b/feather/base/src/lib.rs
@@ -15,6 +15,7 @@ pub mod chunk;
pub mod chunk_lock;
pub mod inventory;
pub mod metadata;
+pub mod ansi;
pub use block::{BlockPositionValidationError, ValidBlockPosition};
pub use blocks::*;
diff --git a/feather/server/src/systems/chat.rs b/feather/server/src/systems/chat.rs
index d19aa64ed..ca48d4a97 100644
--- a/feather/server/src/systems/chat.rs
+++ b/feather/server/src/systems/chat.rs
@@ -38,7 +38,7 @@ fn flush_console_chat_box(game: &mut Game) -> SysResult {
for (_, (_console, mailbox)) in game.ecs.query::<(&Console, &mut ChatBox)>().iter() {
for message in mailbox.drain() {
// TODO: properly display chat message
- log::info!("{:?}", message.text());
+ log::info!("{:?}", message.text().as_ansi());
}
}
@@ -56,3 +56,16 @@ fn flush_title_chat_boxes(game: &mut Game, server: &mut Server) -> SysResult {
Ok(())
}
+
+#[cfg(test)]
+mod tests {
+ use base::Text;
+
+ #[test]
+ fn test_ansi_text_serialization() {
+ let text = Text::from("Hello, world!");
+ let ansi_text = text.as_ansi();
+ println!("{} / {}", ansi_text, text);
+ assert_eq!(0, 1);
+ }
+}
\ No newline at end of file
diff --git a/libcraft/text/Cargo.toml b/libcraft/text/Cargo.toml
index b99bd785c..50b6f3e42 100644
--- a/libcraft/text/Cargo.toml
+++ b/libcraft/text/Cargo.toml
@@ -13,3 +13,4 @@ serde_json = "1"
serde_with = "1"
uuid = { version = "0.8", features = [ "serde" ] }
thiserror = "1"
+string-builder = "0.2.0"
\ No newline at end of file
diff --git a/libcraft/text/src/text.rs b/libcraft/text/src/text.rs
index 90af776de..dd356522e 100644
--- a/libcraft/text/src/text.rs
+++ b/libcraft/text/src/text.rs
@@ -375,6 +375,23 @@ pub enum TextValue {
},
}
+impl TextValue{
+ pub fn name_of(&self) -> &'static str {
+ match self {
+ TextValue::Text { .. } => "text",
+ TextValue::Translate { .. } => "translate",
+ TextValue::Score { .. } => "score",
+ TextValue::Selector { .. } => "selector",
+ TextValue::Keybind { .. } => "keybind",
+ TextValue::Nbt { .. } => "nbt",
+ }
+ }
+
+ pub(crate) fn as_ansi(&self) -> String {
+ format!("", self.name_of()) // TODO
+ }
+}
+
impl From for TextValue
where
T: Into>,
@@ -966,6 +983,30 @@ impl Text {
pub fn nbt>(nbt: A) -> Text {
Text::from(TextValue::nbt(nbt))
}
+
+ pub fn as_ansi(&self) -> String {
+ let mut ansi = string_builder::Builder::default();
+
+ let component = self.clone().into_component();
+ let mut to_serialize: Vec = Vec::new();
+
+ to_serialize.push(component.value);
+
+ if component.extra.is_some() {
+ for extra in component.extra.unwrap() {
+ to_serialize.push(extra.into_component().value);
+ }
+ }
+
+ for value in to_serialize {
+ ansi.append(value.as_ansi());
+ }
+
+ ansi.string().expect(&*format!(
+ "Failed to convert text to ansi: {}",
+ &serde_json::to_string(self).unwrap()
+ ))
+ }
}
impl From for String {
From 6b3d10725f93dcf9047de21639f2b0449291f34c Mon Sep 17 00:00:00 2001
From: Christian Bergschneider
<37768199+Bloeckchengrafik@users.noreply.github.com>
Date: Thu, 16 Jun 2022 11:03:42 +0200
Subject: [PATCH 06/15] reformat
---
feather/base/src/ansi.rs | 42 ++++++++++++++++++++++--------
feather/base/src/lib.rs | 2 +-
feather/server/src/systems/chat.rs | 2 +-
libcraft/text/src/text.rs | 2 +-
4 files changed, 34 insertions(+), 14 deletions(-)
diff --git a/feather/base/src/ansi.rs b/feather/base/src/ansi.rs
index dac77aebd..9e67afe4b 100644
--- a/feather/base/src/ansi.rs
+++ b/feather/base/src/ansi.rs
@@ -15,25 +15,45 @@ impl AnsiStyle {
AnsiStyle { format: 4 }
}
- fn format(&self, color: u8) -> String { format!("\033[{};{}m", self.format, color) }
+ fn format(&self, color: u8) -> String {
+ format!("\033[{};{}m", self.format, color)
+ }
- pub fn black(&self) -> String { self.format(30) }
+ pub fn black(&self) -> String {
+ self.format(30)
+ }
- pub fn red(&self) -> String { self.format(31) }
+ pub fn red(&self) -> String {
+ self.format(31)
+ }
- pub fn green(&self) -> String { self.format(32) }
+ pub fn green(&self) -> String {
+ self.format(32)
+ }
- pub fn yellow(&self) -> String { self.format(33) }
+ pub fn yellow(&self) -> String {
+ self.format(33)
+ }
- pub fn blue(&self) -> String { self.format(34) }
+ pub fn blue(&self) -> String {
+ self.format(34)
+ }
- pub fn magenta(&self) -> String { self.format(35) }
+ pub fn magenta(&self) -> String {
+ self.format(35)
+ }
- pub fn cyan(&self) -> String { self.format(36) }
+ pub fn cyan(&self) -> String {
+ self.format(36)
+ }
- pub fn white(&self) -> String { self.format(37) }
+ pub fn white(&self) -> String {
+ self.format(37)
+ }
- pub fn reset(&self) -> &'static str { "\033[0m" }
+ pub fn reset(&self) -> &'static str {
+ "\033[0m"
+ }
}
#[cfg(test)]
@@ -75,4 +95,4 @@ mod tests {
assert_eq!(style.white(), "\033[4;37m");
assert_eq!(style.reset(), "\033[0m");
}
-}
\ No newline at end of file
+}
diff --git a/feather/base/src/lib.rs b/feather/base/src/lib.rs
index 5548e11e2..954d0e400 100644
--- a/feather/base/src/lib.rs
+++ b/feather/base/src/lib.rs
@@ -9,13 +9,13 @@ use std::time::Duration;
use num_derive::{FromPrimitive, ToPrimitive};
use serde::{Deserialize, Serialize};
+pub mod ansi;
pub mod anvil;
mod block;
pub mod chunk;
pub mod chunk_lock;
pub mod inventory;
pub mod metadata;
-pub mod ansi;
pub use block::{BlockPositionValidationError, ValidBlockPosition};
pub use blocks::*;
diff --git a/feather/server/src/systems/chat.rs b/feather/server/src/systems/chat.rs
index ca48d4a97..827281bc7 100644
--- a/feather/server/src/systems/chat.rs
+++ b/feather/server/src/systems/chat.rs
@@ -68,4 +68,4 @@ mod tests {
println!("{} / {}", ansi_text, text);
assert_eq!(0, 1);
}
-}
\ No newline at end of file
+}
diff --git a/libcraft/text/src/text.rs b/libcraft/text/src/text.rs
index dd356522e..ab28aefbe 100644
--- a/libcraft/text/src/text.rs
+++ b/libcraft/text/src/text.rs
@@ -375,7 +375,7 @@ pub enum TextValue {
},
}
-impl TextValue{
+impl TextValue {
pub fn name_of(&self) -> &'static str {
match self {
TextValue::Text { .. } => "text",
From 3916d38b5af998e1adf2be233413ed48607996e3 Mon Sep 17 00:00:00 2001
From: Christian Bergschneider
<37768199+Bloeckchengrafik@users.noreply.github.com>
Date: Thu, 16 Jun 2022 11:09:55 +0200
Subject: [PATCH 07/15] fix clippy warning
---
libcraft/text/src/text.rs | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/libcraft/text/src/text.rs b/libcraft/text/src/text.rs
index ab28aefbe..e570c09e9 100644
--- a/libcraft/text/src/text.rs
+++ b/libcraft/text/src/text.rs
@@ -988,9 +988,7 @@ impl Text {
let mut ansi = string_builder::Builder::default();
let component = self.clone().into_component();
- let mut to_serialize: Vec = Vec::new();
-
- to_serialize.push(component.value);
+ let mut to_serialize: Vec = vec![component.value];
if component.extra.is_some() {
for extra in component.extra.unwrap() {
From 0e902dad7d441cc3a18fad402ee44e311c023792 Mon Sep 17 00:00:00 2001
From: Bloeckchengrafik <37768199+Bloeckchengrafik@users.noreply.github.com>
Date: Thu, 16 Jun 2022 14:57:56 +0200
Subject: [PATCH 08/15] fix 29 clippy warnings, adding 20000 prob
---
feather/base/src/ansi.rs | 58 ++++++++++++-------------
quill/example-plugins/simple/src/lib.rs | 18 ++++----
2 files changed, 39 insertions(+), 37 deletions(-)
diff --git a/feather/base/src/ansi.rs b/feather/base/src/ansi.rs
index 9e67afe4b..ad37faaa7 100644
--- a/feather/base/src/ansi.rs
+++ b/feather/base/src/ansi.rs
@@ -16,7 +16,7 @@ impl AnsiStyle {
}
fn format(&self, color: u8) -> String {
- format!("\033[{};{}m", self.format, color)
+ format!("\x1b[{};{}m", self.format, color)
}
pub fn black(&self) -> String {
@@ -52,7 +52,7 @@ impl AnsiStyle {
}
pub fn reset(&self) -> &'static str {
- "\033[0m"
+ "\x1b[0m"
}
}
@@ -63,36 +63,36 @@ mod tests {
#[test]
fn test_ansi_style() {
let style = AnsiStyle::regular();
- assert_eq!(style.black(), "\033[0;30m");
- assert_eq!(style.red(), "\033[0;31m");
- assert_eq!(style.green(), "\033[0;32m");
- assert_eq!(style.yellow(), "\033[0;33m");
- assert_eq!(style.blue(), "\033[0;34m");
- assert_eq!(style.magenta(), "\033[0;35m");
- assert_eq!(style.cyan(), "\033[0;36m");
- assert_eq!(style.white(), "\033[0;37m");
- assert_eq!(style.reset(), "\033[0m");
+ assert_eq!(style.black(), "\x1b[0;30m");
+ assert_eq!(style.red(), "\x1b[0;31m");
+ assert_eq!(style.green(), "\x1b[0;32m");
+ assert_eq!(style.yellow(), "\x1b[0;33m");
+ assert_eq!(style.blue(), "\x1b[0;34m");
+ assert_eq!(style.magenta(), "\x1b[0;35m");
+ assert_eq!(style.cyan(), "\x1b[0;36m");
+ assert_eq!(style.white(), "\x1b[0;37m");
+ assert_eq!(style.reset(), "\x1b[0m");
let style = AnsiStyle::bold();
- assert_eq!(style.black(), "\033[1;30m");
- assert_eq!(style.red(), "\033[1;31m");
- assert_eq!(style.green(), "\033[1;32m");
- assert_eq!(style.yellow(), "\033[1;33m");
- assert_eq!(style.blue(), "\033[1;34m");
- assert_eq!(style.magenta(), "\033[1;35m");
- assert_eq!(style.cyan(), "\033[1;36m");
- assert_eq!(style.white(), "\033[1;37m");
- assert_eq!(style.reset(), "\033[0m");
+ assert_eq!(style.black(), "\x1b[1;30m");
+ assert_eq!(style.red(), "\x1b[1;31m");
+ assert_eq!(style.green(), "\x1b[1;32m");
+ assert_eq!(style.yellow(), "\x1b[1;33m");
+ assert_eq!(style.blue(), "\x1b[1;34m");
+ assert_eq!(style.magenta(), "\x1b[1;35m");
+ assert_eq!(style.cyan(), "\x1b[1;36m");
+ assert_eq!(style.white(), "\x1b[1;37m");
+ assert_eq!(style.reset(), "\x1b[0m");
let style = AnsiStyle::underline();
- assert_eq!(style.black(), "\033[4;30m");
- assert_eq!(style.red(), "\033[4;31m");
- assert_eq!(style.green(), "\033[4;32m");
- assert_eq!(style.yellow(), "\033[4;33m");
- assert_eq!(style.blue(), "\033[4;34m");
- assert_eq!(style.magenta(), "\033[4;35m");
- assert_eq!(style.cyan(), "\033[4;36m");
- assert_eq!(style.white(), "\033[4;37m");
- assert_eq!(style.reset(), "\033[0m");
+ assert_eq!(style.black(), "\x1b[4;30m");
+ assert_eq!(style.red(), "\x1b[4;31m");
+ assert_eq!(style.green(), "\x1b[4;32m");
+ assert_eq!(style.yellow(), "\x1b[4;33m");
+ assert_eq!(style.blue(), "\x1b[4;34m");
+ assert_eq!(style.magenta(), "\x1b[4;35m");
+ assert_eq!(style.cyan(), "\x1b[4;36m");
+ assert_eq!(style.white(), "\x1b[4;37m");
+ assert_eq!(style.reset(), "\x1b[0m");
}
}
diff --git a/quill/example-plugins/simple/src/lib.rs b/quill/example-plugins/simple/src/lib.rs
index d6ac19dae..a76361d4d 100644
--- a/quill/example-plugins/simple/src/lib.rs
+++ b/quill/example-plugins/simple/src/lib.rs
@@ -23,14 +23,16 @@ fn test_system(plugin: &mut SimplePlugin, game: &mut Game) {
for (entity, (position, name, gamemode, uuid)) in
game.query::<(&Position, &Name, &Gamemode, &Uuid)>()
{
- entity.send_message(format!(
- "[{}] Hi {}. Your gamemode is {:?} and your position is {:.1?} and your UUID is {}",
- plugin.tick_counter,
- name,
- gamemode,
- position,
- uuid.to_hyphenated()
- ));
+ if plugin.tick_counter % 50 == 0 {
+ entity.send_message(format!(
+ "[{}] Hi {}. Your gamemode is {:?} and your position is {:.1?} and your UUID is {}",
+ plugin.tick_counter,
+ name,
+ gamemode,
+ position,
+ uuid.to_hyphenated()
+ ));
+ }
if plugin.tick_counter % 100 == 0 {
entity.send_message("Spawning a mob on you");
From 26b84e690b3fa8883326fbcb62797ada36aef4bc Mon Sep 17 00:00:00 2001
From: Bloeckchengrafik <37768199+Bloeckchengrafik@users.noreply.github.com>
Date: Fri, 17 Jun 2022 19:10:14 +0200
Subject: [PATCH 09/15] sparkles: finish component to ansi
---
Cargo.lock | 11 +
feather/base/src/lib.rs | 5 +-
feather/protocol/src/packets/server/play.rs | 2 +-
feather/server/Cargo.toml | 2 +
feather/server/src/main.rs | 11 +
feather/server/src/systems/chat.rs | 3 +-
feather/server/src/systems/player_join.rs | 4 +-
{feather/base => libcraft/text}/src/ansi.rs | 4 +-
libcraft/text/src/lib.rs | 1 +
libcraft/text/src/text.rs | 225 +++++++++++++++-----
10 files changed, 204 insertions(+), 64 deletions(-)
rename {feather/base => libcraft/text}/src/ansi.rs (96%)
diff --git a/Cargo.lock b/Cargo.lock
index 84a8ecbf5..6e1986871 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -713,6 +713,15 @@ version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
+[[package]]
+name = "enable-ansi-support"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28d29d3ca9ba14c336417f8d7bc7f373e8c16d10c30cc0794b09d3cecab631ab"
+dependencies = [
+ "winapi",
+]
+
[[package]]
name = "enumset"
version = "1.0.8"
@@ -939,6 +948,7 @@ dependencies = [
"base64ct",
"colored",
"crossbeam-utils",
+ "enable-ansi-support",
"feather-base",
"feather-common",
"feather-ecs",
@@ -953,6 +963,7 @@ dependencies = [
"hematite-nbt",
"libcraft-core",
"libcraft-items",
+ "libcraft-text",
"log",
"md-5",
"num-bigint",
diff --git a/feather/base/src/lib.rs b/feather/base/src/lib.rs
index 954d0e400..d78e65c66 100644
--- a/feather/base/src/lib.rs
+++ b/feather/base/src/lib.rs
@@ -9,7 +9,6 @@ use std::time::Duration;
use num_derive::{FromPrimitive, ToPrimitive};
use serde::{Deserialize, Serialize};
-pub mod ansi;
pub mod anvil;
mod block;
pub mod chunk;
@@ -19,12 +18,12 @@ pub mod metadata;
pub use block::{BlockPositionValidationError, ValidBlockPosition};
pub use blocks::*;
-pub use chunk::{Chunk, ChunkSection, CHUNK_HEIGHT, CHUNK_WIDTH};
+pub use chunk::{Chunk, CHUNK_HEIGHT, CHUNK_WIDTH, ChunkSection};
pub use chunk_lock::*;
pub use libcraft_blocks::{BlockKind, BlockState};
pub use libcraft_core::{
- position, vec3, Biome, BlockPosition, ChunkPosition, EntityKind, Gamemode, Position, Vec3d,
+ Biome, BlockPosition, ChunkPosition, EntityKind, Gamemode, position, Position, vec3, Vec3d,
};
pub use libcraft_inventory::{Area, Inventory};
pub use libcraft_items::{Item, ItemStack, ItemStackBuilder, ItemStackError};
diff --git a/feather/protocol/src/packets/server/play.rs b/feather/protocol/src/packets/server/play.rs
index e52266b58..97f636f6e 100644
--- a/feather/protocol/src/packets/server/play.rs
+++ b/feather/protocol/src/packets/server/play.rs
@@ -370,7 +370,7 @@ pub enum GameStateChange {
WinGame {
show_credits: bool,
},
- /// See https://help.minecraft.net/hc/en-us/articles/4408948974989-Minecraft-Java-Edition-Demo-Mode-
+ /// See
DemoEvent(DemoEventType),
/// Sent when any player is struck by an arrow.
ArrowHitAnyPlayer,
diff --git a/feather/server/Cargo.toml b/feather/server/Cargo.toml
index 970560311..5aa655cf8 100644
--- a/feather/server/Cargo.toml
+++ b/feather/server/Cargo.toml
@@ -22,6 +22,7 @@ colored = "2"
common = { path = "../common", package = "feather-common" }
crossbeam-utils = "0.8"
ecs = { path = "../ecs", package = "feather-ecs" }
+enable-ansi-support = "0.1.2"
fern = "0.6"
flate2 = "1"
flume = "0.10"
@@ -55,6 +56,7 @@ uuid = "0.8"
slab = "0.4"
libcraft-core = { path = "../../libcraft/core" }
libcraft-items = { path = "../../libcraft/items" }
+libcraft-text = { path = "../../libcraft/text" }
worldgen = { path = "../worldgen", package = "feather-worldgen" }
[features]
diff --git a/feather/server/src/main.rs b/feather/server/src/main.rs
index c3bf7ea16..906a84056 100644
--- a/feather/server/src/main.rs
+++ b/feather/server/src/main.rs
@@ -15,6 +15,8 @@ const CONFIG_PATH: &str = "config.toml";
#[tokio::main]
async fn main() -> anyhow::Result<()> {
+ enable_ansi();
+
let feather_server::config::ConfigContainer {
config,
was_config_created,
@@ -36,6 +38,15 @@ async fn main() -> anyhow::Result<()> {
Ok(())
}
+fn enable_ansi() {
+ match enable_ansi_support::enable_ansi_support() {
+ Ok(()) => {}
+ Err(_) => {
+ log::warn!("Failed to enable ANSI support, Output will not work properly");
+ }
+ }
+}
+
fn init_game(server: Server, config: &Config) -> anyhow::Result {
let mut game = Game::new();
init_systems(&mut game, server);
diff --git a/feather/server/src/systems/chat.rs b/feather/server/src/systems/chat.rs
index 827281bc7..71ca23f81 100644
--- a/feather/server/src/systems/chat.rs
+++ b/feather/server/src/systems/chat.rs
@@ -37,8 +37,7 @@ fn flush_chat_boxes(game: &mut Game, server: &mut Server) -> SysResult {
fn flush_console_chat_box(game: &mut Game) -> SysResult {
for (_, (_console, mailbox)) in game.ecs.query::<(&Console, &mut ChatBox)>().iter() {
for message in mailbox.drain() {
- // TODO: properly display chat message
- log::info!("{:?}", message.text().as_ansi());
+ log::info!("{}", message.text().as_ansi().replace("\n", ""));
}
}
diff --git a/feather/server/src/systems/player_join.rs b/feather/server/src/systems/player_join.rs
index f8e01b195..311a01eb4 100644
--- a/feather/server/src/systems/player_join.rs
+++ b/feather/server/src/systems/player_join.rs
@@ -1,4 +1,5 @@
use libcraft_items::InventorySlot;
+use libcraft_text::{IntoTextComponent, TextComponent, TextComponentBuilder};
use log::debug;
use base::anvil::player::PlayerAbilities;
@@ -143,7 +144,8 @@ fn accept_new_player(game: &mut Game, server: &mut Server, client_id: ClientId)
fn broadcast_player_join(game: &mut Game, username: &str) {
let message = Text::translate_with("multiplayer.player.joined", vec![username.to_owned()]);
- game.broadcast_chat(ChatKind::System, message);
+ let mut component = message.into_component().yellow();
+ game.broadcast_chat(ChatKind::System, component);
}
fn player_abilities_or_default(
diff --git a/feather/base/src/ansi.rs b/libcraft/text/src/ansi.rs
similarity index 96%
rename from feather/base/src/ansi.rs
rename to libcraft/text/src/ansi.rs
index ad37faaa7..72b9c0cde 100644
--- a/feather/base/src/ansi.rs
+++ b/libcraft/text/src/ansi.rs
@@ -16,7 +16,7 @@ impl AnsiStyle {
}
fn format(&self, color: u8) -> String {
- format!("\x1b[{};{}m", self.format, color)
+ format!("\x1B[{};{}m", self.format, color)
}
pub fn black(&self) -> String {
@@ -51,7 +51,7 @@ impl AnsiStyle {
self.format(37)
}
- pub fn reset(&self) -> &'static str {
+ pub fn reset() -> &'static str {
"\x1b[0m"
}
}
diff --git a/libcraft/text/src/lib.rs b/libcraft/text/src/lib.rs
index 672851c8c..b6ae5b6fb 100644
--- a/libcraft/text/src/lib.rs
+++ b/libcraft/text/src/lib.rs
@@ -1,5 +1,6 @@
pub mod text;
pub mod title;
+pub mod ansi;
pub use text::*;
pub use title::Title;
diff --git a/libcraft/text/src/text.rs b/libcraft/text/src/text.rs
index e570c09e9..bc6c7e875 100644
--- a/libcraft/text/src/text.rs
+++ b/libcraft/text/src/text.rs
@@ -5,6 +5,7 @@ use std::borrow::Cow;
use std::fmt::{self, Display, Formatter};
use std::str::FromStr;
use uuid::Uuid;
+use crate::ansi::AnsiStyle;
pub mod markdown;
@@ -146,10 +147,51 @@ impl From for Text {
}
}
+impl From for String {
+ fn from(bind: Keybind) -> Self {
+ match bind {
+ Keybind::Attack => "attack".to_string(),
+ Keybind::UseItem => "use".to_string(),
+ Keybind::Forward => "forward".to_string(),
+ Keybind::Left => "left".to_string(),
+ Keybind::Back => "back".to_string(),
+ Keybind::Right => "right".to_string(),
+ Keybind::Jump => "jump".to_string(),
+ Keybind::Sneak => "sneak".to_string(),
+ Keybind::Sprint => "sprint".to_string(),
+ Keybind::Drop => "drop".to_string(),
+ Keybind::Inventory => "inventory".to_string(),
+ Keybind::Chat => "chat".to_string(),
+ Keybind::ListPlayers => "list_players".to_string(),
+ Keybind::PickBlock => "pick_block".to_string(),
+ Keybind::Command => "command".to_string(),
+ Keybind::Screenshot => "screenshot".to_string(),
+ Keybind::Perspective => "perspective".to_string(),
+ Keybind::MouseSmoothing => "mouse_smoothing".to_string(),
+ Keybind::Fullscreen => "fullscreen".to_string(),
+ Keybind::SpectatorOutlines => "spectator_outlines".to_string(),
+ Keybind::SwapHands => "swap_hands".to_string(),
+ Keybind::SaveToolbar => "save_toolbar".to_string(),
+ Keybind::LoadToolbar => "load_toolbar".to_string(),
+ Keybind::Advancements => "advancements".to_string(),
+ Keybind::Hotbar1 => "hotbar1".to_string(),
+ Keybind::Hotbar2 => "hotbar2".to_string(),
+ Keybind::Hotbar3 => "hotbar3".to_string(),
+ Keybind::Hotbar4 => "hotbar4".to_string(),
+ Keybind::Hotbar5 => "hotbar5".to_string(),
+ Keybind::Hotbar6 => "hotbar6".to_string(),
+ Keybind::Hotbar7 => "hotbar7".to_string(),
+ Keybind::Hotbar8 => "hotbar8".to_string(),
+ Keybind::Hotbar9 => "hotbar9".to_string(),
+ Keybind::Custom(s) => s.to_string()
+ }
+ }
+}
+
impl Serialize for Keybind {
fn serialize(&self, serializer: S) -> Result
- where
- S: Serializer,
+ where
+ S: Serializer,
{
serializer.serialize_str(String::from(self).as_ref())
}
@@ -157,8 +199,8 @@ impl Serialize for Keybind {
impl<'de> Deserialize<'de> for Keybind {
fn deserialize(deserializer: D) -> Result
- where
- D: Deserializer<'de>,
+ where
+ D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(Keybind::from(s))
@@ -166,8 +208,8 @@ impl<'de> Deserialize<'de> for Keybind {
}
impl From for Keybind
-where
- T: Into>,
+ where
+ T: Into>,
{
fn from(keybind: T) -> Self {
let keybind = keybind.into();
@@ -248,7 +290,7 @@ impl From<&Keybind> for String {
Keybind::Hotbar9 => "key_key.hotbar.9",
Keybind::Custom(bind) => bind.as_ref(),
}
- .into()
+ .into()
}
}
@@ -260,10 +302,30 @@ pub enum Translate {
Custom(Cow<'static, str>),
}
+impl Translate {
+ fn to_text(&self, args: &Vec, style: &String) -> String {
+ match self {
+ Translate::ChatTypeText => format!("<{}{}> {}", args[0].as_ansi(), style, args[1].as_ansi()),
+ Translate::MultiplayerPlayerJoined => format!("{}{} joined the game", args[0].as_ansi(), style),
+ Translate::Custom(name) => {
+ let mut args_strings: String = String::new();
+
+ for arg in args {
+ args_strings = format!("{} '{}{}'", args_strings, arg.as_ansi(), style);
+ }
+
+ args_strings.push(' ');
+
+ format!("", name, args_strings)
+ }
+ }
+ }
+}
+
impl Serialize for Translate {
fn serialize(&self, serializer: S) -> Result
- where
- S: Serializer,
+ where
+ S: Serializer,
{
serializer.serialize_str(String::from(self).as_ref())
}
@@ -271,8 +333,8 @@ impl Serialize for Translate {
impl<'de> Deserialize<'de> for Translate {
fn deserialize(deserializer: D) -> Result
- where
- D: Deserializer<'de>,
+ where
+ D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(Translate::from(s))
@@ -280,9 +342,9 @@ impl<'de> Deserialize<'de> for Translate {
}
impl std::ops::Mul for Translate
-where
- T: IntoIterator,
- T::Item: Into,
+ where
+ T: IntoIterator,
+ T::Item: Into,
{
type Output = Text;
fn mul(self, rhs: T) -> Text {
@@ -291,8 +353,8 @@ where
}
impl From for Translate
-where
- T: Into>,
+ where
+ T: Into>,
{
fn from(value: T) -> Translate {
let value = value.into();
@@ -311,7 +373,7 @@ impl<'a> From<&Translate> for String {
Translate::MultiplayerPlayerJoined => "multiplayer.player.joined",
Translate::Custom(key) => key.as_ref(),
}
- .into()
+ .into()
}
}
@@ -386,15 +448,11 @@ impl TextValue {
TextValue::Nbt { .. } => "nbt",
}
}
-
- pub(crate) fn as_ansi(&self) -> String {
- format!("", self.name_of()) // TODO
- }
}
impl From for TextValue
-where
- T: Into>,
+ where
+ T: Into>,
{
fn from(value: T) -> Self {
Self::text(value.into())
@@ -407,8 +465,8 @@ impl TextValue {
}
pub fn translate(translate: A) -> Self
- where
- A: Into,
+ where
+ A: Into,
{
TextValue::Translate {
translate: translate.into(),
@@ -417,10 +475,10 @@ impl TextValue {
}
pub fn translate_with(translate: A, with: B) -> Self
- where
- A: Into,
- B: IntoIterator,
- B::Item: Into,
+ where
+ A: Into,
+ B: IntoIterator,
+ B::Item: Into,
{
let with = with.into_iter().map(|e| e.into()).collect();
TextValue::Translate {
@@ -490,6 +548,67 @@ impl TextComponent {
pub fn empty() -> TextComponent {
TextComponent::from("")
}
+
+ pub(crate) fn as_ansi(&self) -> String {
+ let mut style_type = AnsiStyle::regular();
+
+ if self.bold.unwrap_or(false) {
+ style_type = AnsiStyle::bold()
+ }
+
+ if self.underlined.unwrap_or(false) {
+ style_type = AnsiStyle::underline()
+ }
+
+ let mut style =style_type.white();
+
+ if self.color.is_some() {
+ let color = self.color.as_ref().unwrap();
+
+ match color {
+ Color::Black => style = style_type.black(),
+ Color::DarkGray => style = style_type.black(),
+ Color::White => style = style_type.white(),
+ Color::Gray => style = style_type.black(),
+ Color::Red => style = style_type.red(),
+ Color::DarkRed => style = style_type.red(),
+ Color::Gold => style = style_type.yellow(),
+ Color::Yellow => style = style_type.yellow(),
+ Color::DarkGreen => style = style_type.green(),
+ Color::Green => style = style_type.green(),
+ Color::Aqua => style = style_type.cyan(),
+ Color::DarkAqua => style = style_type.cyan(),
+ Color::DarkBlue => style = style_type.blue(),
+ Color::Blue => style = style_type.blue(),
+ Color::LightPurple => style = style_type.magenta(),
+ Color::DarkPurple => style = style_type.magenta(),
+ Color::Custom(_) => style = style_type.black(),
+ }
+ }
+
+
+ let content = if let TextValue::Text {text} = self.clone().value {
+ String::from(text)
+ } else if let TextValue::Translate {translate, with} = self.clone().value {
+ translate.to_text(&with, &style)
+ } else if let TextValue::Score {value, name, objective} = self.clone().value {
+ if value.is_some() {
+ format!("", name, objective, value.unwrap())
+ } else {
+ format!("", objective, name)
+ }
+ } else if let TextValue::Selector {selector} = self.clone().value {
+ format!("{}", selector)
+ } else if let TextValue::Keybind {keybind} = self.clone().value {
+ format!("", String::from(keybind))
+ } else if let TextValue::Nbt {nbt} = self.clone().value {
+ format!("", nbt)
+ } else {
+ panic!("Unsupported TextValue")
+ };
+
+ format!("{}{}{}", &style, content, AnsiStyle::reset())
+ }
}
pub enum Reset {
@@ -580,9 +699,9 @@ pub trait TextComponentBuilder {
/// Inherited Text; they will inherent the parent's style, color, insertion, on_click, and on_hover.
fn extra(self, extra: A) -> Self
- where
- A: IntoIterator,
- A::Item: Into;
+ where
+ A: IntoIterator,
+ A::Item: Into;
fn push_extra>(self, extra: A) -> Self;
fn reset_extra(self) -> Self;
@@ -601,8 +720,8 @@ impl IntoTextComponent for TextComponent {
}
impl TextComponentBuilder for T
-where
- T: IntoTextComponent + From,
+ where
+ T: IntoTextComponent + From,
{
fn set_style(self, style: Style, value: Option) -> Self {
let mut component = self.into_component();
@@ -846,9 +965,9 @@ where
}
fn extra(self, extra: A) -> Self
- where
- A: IntoIterator,
- A::Item: Into,
+ where
+ A: IntoIterator,
+ A::Item: Into,
{
let mut component = self.into_component();
component.extra = Some(extra.into_iter().map(|e| e.into()).collect());
@@ -897,8 +1016,8 @@ where
}
impl From for TextComponent
-where
- T: Into,
+ where
+ T: Into,
{
fn from(value: T) -> Self {
TextComponent {
@@ -956,10 +1075,10 @@ impl Text {
}
pub fn translate_with(translate: A, with: B) -> Self
- where
- A: Into,
- B: IntoIterator,
- B::Item: Into,
+ where
+ A: Into,
+ B: IntoIterator,
+ B::Item: Into,
{
Text::from(TextValue::translate_with(translate, with))
}
@@ -988,18 +1107,14 @@ impl Text {
let mut ansi = string_builder::Builder::default();
let component = self.clone().into_component();
- let mut to_serialize: Vec = vec![component.value];
+ ansi.append(component.as_ansi());
if component.extra.is_some() {
for extra in component.extra.unwrap() {
- to_serialize.push(extra.into_component().value);
+ ansi.append(extra.as_ansi());
}
}
- for value in to_serialize {
- ansi.append(value.as_ansi());
- }
-
ansi.string().expect(&*format!(
"Failed to convert text to ansi: {}",
&serde_json::to_string(self).unwrap()
@@ -1032,8 +1147,8 @@ impl From for Text {
}
impl From for Text
-where
- T: Into>,
+ where
+ T: Into>,
{
fn from(value: T) -> Self {
Text::String(value.into())
@@ -1063,8 +1178,8 @@ impl std::ops::Add for Text {
/// A `Deserialize` impl for `Text` which uses the text markdown format.
pub fn deserialize_text<'de, D>(deserializer: D) -> Result
-where
- D: Deserializer<'de>,
+ where
+ D: Deserializer<'de>,
{
let string = String::deserialize(deserializer)?;
@@ -1084,8 +1199,8 @@ impl From for String {
}
impl From for TextRoot
-where
- T: Into,
+ where
+ T: Into,
{
fn from(text: T) -> Self {
match text.into() {
From 2bc6db17589749b351983f1d01adc84967ac240a Mon Sep 17 00:00:00 2001
From: Bloeckchengrafik <37768199+Bloeckchengrafik@users.noreply.github.com>
Date: Fri, 17 Jun 2022 19:23:45 +0200
Subject: [PATCH 10/15] sparkles: Add test and fix warnings
---
feather/server/src/systems/chat.rs | 9 ++++-----
feather/server/src/systems/player_join.rs | 4 ++--
libcraft/text/src/ansi.rs | 5 ++---
3 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/feather/server/src/systems/chat.rs b/feather/server/src/systems/chat.rs
index 71ca23f81..ddb9e73f9 100644
--- a/feather/server/src/systems/chat.rs
+++ b/feather/server/src/systems/chat.rs
@@ -37,7 +37,7 @@ fn flush_chat_boxes(game: &mut Game, server: &mut Server) -> SysResult {
fn flush_console_chat_box(game: &mut Game) -> SysResult {
for (_, (_console, mailbox)) in game.ecs.query::<(&Console, &mut ChatBox)>().iter() {
for message in mailbox.drain() {
- log::info!("{}", message.text().as_ansi().replace("\n", ""));
+ log::info!("{}", message.text().as_ansi());
}
}
@@ -58,13 +58,12 @@ fn flush_title_chat_boxes(game: &mut Game, server: &mut Server) -> SysResult {
#[cfg(test)]
mod tests {
- use base::Text;
+ use libcraft_text::{TextComponent, TextComponentBuilder};
#[test]
fn test_ansi_text_serialization() {
- let text = Text::from("Hello, world!");
+ let text = TextComponent::from("Hello, world!").red().bold();
let ansi_text = text.as_ansi();
- println!("{} / {}", ansi_text, text);
- assert_eq!(0, 1);
+ assert_eq!("\x1b[1;31mHello, world!\x1b[0m", ansi_text);
}
}
diff --git a/feather/server/src/systems/player_join.rs b/feather/server/src/systems/player_join.rs
index 311a01eb4..9d7755632 100644
--- a/feather/server/src/systems/player_join.rs
+++ b/feather/server/src/systems/player_join.rs
@@ -1,5 +1,5 @@
use libcraft_items::InventorySlot;
-use libcraft_text::{IntoTextComponent, TextComponent, TextComponentBuilder};
+use libcraft_text::{IntoTextComponent, TextComponentBuilder};
use log::debug;
use base::anvil::player::PlayerAbilities;
@@ -144,7 +144,7 @@ fn accept_new_player(game: &mut Game, server: &mut Server, client_id: ClientId)
fn broadcast_player_join(game: &mut Game, username: &str) {
let message = Text::translate_with("multiplayer.player.joined", vec![username.to_owned()]);
- let mut component = message.into_component().yellow();
+ let component = message.into_component().yellow();
game.broadcast_chat(ChatKind::System, component);
}
diff --git a/libcraft/text/src/ansi.rs b/libcraft/text/src/ansi.rs
index 72b9c0cde..c5ddc4fba 100644
--- a/libcraft/text/src/ansi.rs
+++ b/libcraft/text/src/ansi.rs
@@ -62,6 +62,8 @@ mod tests {
#[test]
fn test_ansi_style() {
+ assert_eq!(AnsiStyle::reset(), "\x1b[0m");
+
let style = AnsiStyle::regular();
assert_eq!(style.black(), "\x1b[0;30m");
assert_eq!(style.red(), "\x1b[0;31m");
@@ -71,7 +73,6 @@ mod tests {
assert_eq!(style.magenta(), "\x1b[0;35m");
assert_eq!(style.cyan(), "\x1b[0;36m");
assert_eq!(style.white(), "\x1b[0;37m");
- assert_eq!(style.reset(), "\x1b[0m");
let style = AnsiStyle::bold();
assert_eq!(style.black(), "\x1b[1;30m");
@@ -82,7 +83,6 @@ mod tests {
assert_eq!(style.magenta(), "\x1b[1;35m");
assert_eq!(style.cyan(), "\x1b[1;36m");
assert_eq!(style.white(), "\x1b[1;37m");
- assert_eq!(style.reset(), "\x1b[0m");
let style = AnsiStyle::underline();
assert_eq!(style.black(), "\x1b[4;30m");
@@ -93,6 +93,5 @@ mod tests {
assert_eq!(style.magenta(), "\x1b[4;35m");
assert_eq!(style.cyan(), "\x1b[4;36m");
assert_eq!(style.white(), "\x1b[4;37m");
- assert_eq!(style.reset(), "\x1b[0m");
}
}
From 665fccee3dce8eb691f1905c8a0093ab7f51104c Mon Sep 17 00:00:00 2001
From: Bloeckchengrafik <37768199+Bloeckchengrafik@users.noreply.github.com>
Date: Fri, 17 Jun 2022 19:25:56 +0200
Subject: [PATCH 11/15] rotating_light: fmt
---
feather/base/src/lib.rs | 4 +-
feather/server/src/main.rs | 2 +-
libcraft/text/src/lib.rs | 2 +-
libcraft/text/src/text.rs | 138 +++++++++++++++++++++----------------
4 files changed, 81 insertions(+), 65 deletions(-)
diff --git a/feather/base/src/lib.rs b/feather/base/src/lib.rs
index d78e65c66..730d4c51a 100644
--- a/feather/base/src/lib.rs
+++ b/feather/base/src/lib.rs
@@ -18,12 +18,12 @@ pub mod metadata;
pub use block::{BlockPositionValidationError, ValidBlockPosition};
pub use blocks::*;
-pub use chunk::{Chunk, CHUNK_HEIGHT, CHUNK_WIDTH, ChunkSection};
+pub use chunk::{Chunk, ChunkSection, CHUNK_HEIGHT, CHUNK_WIDTH};
pub use chunk_lock::*;
pub use libcraft_blocks::{BlockKind, BlockState};
pub use libcraft_core::{
- Biome, BlockPosition, ChunkPosition, EntityKind, Gamemode, position, Position, vec3, Vec3d,
+ position, vec3, Biome, BlockPosition, ChunkPosition, EntityKind, Gamemode, Position, Vec3d,
};
pub use libcraft_inventory::{Area, Inventory};
pub use libcraft_items::{Item, ItemStack, ItemStackBuilder, ItemStackError};
diff --git a/feather/server/src/main.rs b/feather/server/src/main.rs
index 906a84056..1b0f0eca5 100644
--- a/feather/server/src/main.rs
+++ b/feather/server/src/main.rs
@@ -16,7 +16,7 @@ const CONFIG_PATH: &str = "config.toml";
#[tokio::main]
async fn main() -> anyhow::Result<()> {
enable_ansi();
-
+
let feather_server::config::ConfigContainer {
config,
was_config_created,
diff --git a/libcraft/text/src/lib.rs b/libcraft/text/src/lib.rs
index b6ae5b6fb..e6493fc34 100644
--- a/libcraft/text/src/lib.rs
+++ b/libcraft/text/src/lib.rs
@@ -1,6 +1,6 @@
+pub mod ansi;
pub mod text;
pub mod title;
-pub mod ansi;
pub use text::*;
pub use title::Title;
diff --git a/libcraft/text/src/text.rs b/libcraft/text/src/text.rs
index bc6c7e875..ea8d4619c 100644
--- a/libcraft/text/src/text.rs
+++ b/libcraft/text/src/text.rs
@@ -1,11 +1,11 @@
//! Implementation of the Minecraft chat component format.
+use crate::ansi::AnsiStyle;
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use std::borrow::Cow;
use std::fmt::{self, Display, Formatter};
use std::str::FromStr;
use uuid::Uuid;
-use crate::ansi::AnsiStyle;
pub mod markdown;
@@ -183,15 +183,15 @@ impl From for String {
Keybind::Hotbar7 => "hotbar7".to_string(),
Keybind::Hotbar8 => "hotbar8".to_string(),
Keybind::Hotbar9 => "hotbar9".to_string(),
- Keybind::Custom(s) => s.to_string()
+ Keybind::Custom(s) => s.to_string(),
}
}
}
impl Serialize for Keybind {
fn serialize(&self, serializer: S) -> Result
- where
- S: Serializer,
+ where
+ S: Serializer,
{
serializer.serialize_str(String::from(self).as_ref())
}
@@ -199,8 +199,8 @@ impl Serialize for Keybind {
impl<'de> Deserialize<'de> for Keybind {
fn deserialize(deserializer: D) -> Result
- where
- D: Deserializer<'de>,
+ where
+ D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(Keybind::from(s))
@@ -208,8 +208,8 @@ impl<'de> Deserialize<'de> for Keybind {
}
impl From for Keybind
- where
- T: Into>,
+where
+ T: Into>,
{
fn from(keybind: T) -> Self {
let keybind = keybind.into();
@@ -290,7 +290,7 @@ impl From<&Keybind> for String {
Keybind::Hotbar9 => "key_key.hotbar.9",
Keybind::Custom(bind) => bind.as_ref(),
}
- .into()
+ .into()
}
}
@@ -303,10 +303,14 @@ pub enum Translate {
}
impl Translate {
- fn to_text(&self, args: &Vec, style: &String) -> String {
+ fn to_text(&self, args: &[Text], style: &str) -> String {
match self {
- Translate::ChatTypeText => format!("<{}{}> {}", args[0].as_ansi(), style, args[1].as_ansi()),
- Translate::MultiplayerPlayerJoined => format!("{}{} joined the game", args[0].as_ansi(), style),
+ Translate::ChatTypeText => {
+ format!("<{}{}> {}", args[0].as_ansi(), style, args[1].as_ansi())
+ }
+ Translate::MultiplayerPlayerJoined => {
+ format!("{}{} joined the game", args[0].as_ansi(), style)
+ }
Translate::Custom(name) => {
let mut args_strings: String = String::new();
@@ -316,7 +320,10 @@ impl Translate {
args_strings.push(' ');
- format!("", name, args_strings)
+ format!(
+ "",
+ name, args_strings
+ )
}
}
}
@@ -324,8 +331,8 @@ impl Translate {
impl Serialize for Translate {
fn serialize(&self, serializer: S) -> Result
- where
- S: Serializer,
+ where
+ S: Serializer,
{
serializer.serialize_str(String::from(self).as_ref())
}
@@ -333,8 +340,8 @@ impl Serialize for Translate {
impl<'de> Deserialize<'de> for Translate {
fn deserialize(deserializer: D) -> Result
- where
- D: Deserializer<'de>,
+ where
+ D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(Translate::from(s))
@@ -342,9 +349,9 @@ impl<'de> Deserialize<'de> for Translate {
}
impl std::ops::Mul for Translate
- where
- T: IntoIterator,
- T::Item: Into,
+where
+ T: IntoIterator,
+ T::Item: Into,
{
type Output = Text;
fn mul(self, rhs: T) -> Text {
@@ -353,8 +360,8 @@ impl std::ops::Mul for Translate
}
impl From for Translate
- where
- T: Into>,
+where
+ T: Into>,
{
fn from(value: T) -> Translate {
let value = value.into();
@@ -373,7 +380,7 @@ impl<'a> From<&Translate> for String {
Translate::MultiplayerPlayerJoined => "multiplayer.player.joined",
Translate::Custom(key) => key.as_ref(),
}
- .into()
+ .into()
}
}
@@ -451,8 +458,8 @@ impl TextValue {
}
impl From for TextValue
- where
- T: Into>,
+where
+ T: Into>,
{
fn from(value: T) -> Self {
Self::text(value.into())
@@ -465,8 +472,8 @@ impl TextValue {
}
pub fn translate(translate: A) -> Self
- where
- A: Into,
+ where
+ A: Into,
{
TextValue::Translate {
translate: translate.into(),
@@ -475,10 +482,10 @@ impl TextValue {
}
pub fn translate_with(translate: A, with: B) -> Self
- where
- A: Into,
- B: IntoIterator,
- B::Item: Into,
+ where
+ A: Into,
+ B: IntoIterator,
+ B::Item: Into,
{
let with = with.into_iter().map(|e| e.into()).collect();
TextValue::Translate {
@@ -549,7 +556,7 @@ impl TextComponent {
TextComponent::from("")
}
- pub(crate) fn as_ansi(&self) -> String {
+ pub fn as_ansi(&self) -> String {
let mut style_type = AnsiStyle::regular();
if self.bold.unwrap_or(false) {
@@ -560,7 +567,7 @@ impl TextComponent {
style_type = AnsiStyle::underline()
}
- let mut style =style_type.white();
+ let mut style = style_type.white();
if self.color.is_some() {
let color = self.color.as_ref().unwrap();
@@ -586,22 +593,31 @@ impl TextComponent {
}
}
-
- let content = if let TextValue::Text {text} = self.clone().value {
+ let content = if let TextValue::Text { text } = self.clone().value {
String::from(text)
- } else if let TextValue::Translate {translate, with} = self.clone().value {
+ } else if let TextValue::Translate { translate, with } = self.clone().value {
translate.to_text(&with, &style)
- } else if let TextValue::Score {value, name, objective} = self.clone().value {
+ } else if let TextValue::Score {
+ value,
+ name,
+ objective,
+ } = self.clone().value
+ {
if value.is_some() {
- format!("", name, objective, value.unwrap())
+ format!(
+ "",
+ name,
+ objective,
+ value.unwrap()
+ )
} else {
format!("", objective, name)
}
- } else if let TextValue::Selector {selector} = self.clone().value {
+ } else if let TextValue::Selector { selector } = self.clone().value {
format!("{}", selector)
- } else if let TextValue::Keybind {keybind} = self.clone().value {
+ } else if let TextValue::Keybind { keybind } = self.clone().value {
format!("", String::from(keybind))
- } else if let TextValue::Nbt {nbt} = self.clone().value {
+ } else if let TextValue::Nbt { nbt } = self.clone().value {
format!("", nbt)
} else {
panic!("Unsupported TextValue")
@@ -699,9 +715,9 @@ pub trait TextComponentBuilder {
/// Inherited Text; they will inherent the parent's style, color, insertion, on_click, and on_hover.
fn extra(self, extra: A) -> Self
- where
- A: IntoIterator,
- A::Item: Into;
+ where
+ A: IntoIterator,
+ A::Item: Into;
fn push_extra>(self, extra: A) -> Self;
fn reset_extra(self) -> Self;
@@ -720,8 +736,8 @@ impl IntoTextComponent for TextComponent {
}
impl TextComponentBuilder for T
- where
- T: IntoTextComponent + From,
+where
+ T: IntoTextComponent + From,
{
fn set_style(self, style: Style, value: Option) -> Self {
let mut component = self.into_component();
@@ -965,9 +981,9 @@ impl TextComponentBuilder for T
}
fn extra(self, extra: A) -> Self
- where
- A: IntoIterator,
- A::Item: Into,
+ where
+ A: IntoIterator,
+ A::Item: Into,
{
let mut component = self.into_component();
component.extra = Some(extra.into_iter().map(|e| e.into()).collect());
@@ -1016,8 +1032,8 @@ impl TextComponentBuilder for T
}
impl From for TextComponent
- where
- T: Into,
+where
+ T: Into,
{
fn from(value: T) -> Self {
TextComponent {
@@ -1075,10 +1091,10 @@ impl Text {
}
pub fn translate_with(translate: A, with: B) -> Self
- where
- A: Into,
- B: IntoIterator,
- B::Item: Into,
+ where
+ A: Into,
+ B: IntoIterator,
+ B::Item: Into,
{
Text::from(TextValue::translate_with(translate, with))
}
@@ -1147,8 +1163,8 @@ impl From for Text {
}
impl From for Text
- where
- T: Into>,
+where
+ T: Into>,
{
fn from(value: T) -> Self {
Text::String(value.into())
@@ -1178,8 +1194,8 @@ impl std::ops::Add for Text {
/// A `Deserialize` impl for `Text` which uses the text markdown format.
pub fn deserialize_text<'de, D>(deserializer: D) -> Result
- where
- D: Deserializer<'de>,
+where
+ D: Deserializer<'de>,
{
let string = String::deserialize(deserializer)?;
@@ -1199,8 +1215,8 @@ impl From for String {
}
impl From for TextRoot
- where
- T: Into,
+where
+ T: Into,
{
fn from(text: T) -> Self {
match text.into() {
From bcedda8f0c6a8fd7f6dc72a63b05d7c1c564f0e0 Mon Sep 17 00:00:00 2001
From: Bloeckchengrafik <37768199+Bloeckchengrafik@users.noreply.github.com>
Date: Fri, 17 Jun 2022 19:46:30 +0200
Subject: [PATCH 12/15] sparkles: Add "multiplayer.player.left translation key"
---
libcraft/text/src/text.rs | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/libcraft/text/src/text.rs b/libcraft/text/src/text.rs
index ea8d4619c..b0d5bbcd4 100644
--- a/libcraft/text/src/text.rs
+++ b/libcraft/text/src/text.rs
@@ -299,6 +299,7 @@ impl From<&Keybind> for String {
pub enum Translate {
ChatTypeText,
MultiplayerPlayerJoined,
+ MultiplayerPlayerLeft,
Custom(Cow<'static, str>),
}
@@ -310,6 +311,9 @@ impl Translate {
}
Translate::MultiplayerPlayerJoined => {
format!("{}{} joined the game", args[0].as_ansi(), style)
+ },
+ Translate::MultiplayerPlayerLeft => {
+ format!("{}{} left the game", args[0].as_ansi(), style)
}
Translate::Custom(name) => {
let mut args_strings: String = String::new();
@@ -368,6 +372,7 @@ where
match value.as_ref() {
"chat.type.text" => Translate::ChatTypeText,
"multiplayer.player.joined" => Translate::MultiplayerPlayerJoined,
+ "multiplayer.player.left" => Translate::MultiplayerPlayerLeft,
_ => Translate::Custom(value),
}
}
@@ -378,6 +383,7 @@ impl<'a> From<&Translate> for String {
match translate {
Translate::ChatTypeText => "chat.type.text",
Translate::MultiplayerPlayerJoined => "multiplayer.player.joined",
+ Translate::MultiplayerPlayerLeft => "multiplayer.player.left",
Translate::Custom(key) => key.as_ref(),
}
.into()
From 0e1444ec3776296bd72eeb62d9c6989c9d5e15dc Mon Sep 17 00:00:00 2001
From: Bloeckchengrafik <37768199+Bloeckchengrafik@users.noreply.github.com>
Date: Fri, 17 Jun 2022 19:49:22 +0200
Subject: [PATCH 13/15] rotating_light: fmt
---
libcraft/text/src/text.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcraft/text/src/text.rs b/libcraft/text/src/text.rs
index b0d5bbcd4..3c3543bf3 100644
--- a/libcraft/text/src/text.rs
+++ b/libcraft/text/src/text.rs
@@ -311,7 +311,7 @@ impl Translate {
}
Translate::MultiplayerPlayerJoined => {
format!("{}{} joined the game", args[0].as_ansi(), style)
- },
+ }
Translate::MultiplayerPlayerLeft => {
format!("{}{} left the game", args[0].as_ansi(), style)
}
From 96b344e88ba4f7c234e9bb9b8076030c943d4f6a Mon Sep 17 00:00:00 2001
From: Bloeckchengrafik <37768199+Bloeckchengrafik@users.noreply.github.com>
Date: Fri, 17 Jun 2022 20:57:18 +0200
Subject: [PATCH 14/15] Revert unnessecary readme change
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 99b37a98b..c904c8a24 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Feather
+# Feather
[](https://github.com/feather-rs/feather/actions)
[](https://discordapp.com/invite/4eYmK69)
From 1d2f12d466621d0423a553d74570c660bc4244cf Mon Sep 17 00:00:00 2001
From: Bloeckchengrafik <37768199+Bloeckchengrafik@users.noreply.github.com>
Date: Fri, 17 Jun 2022 21:06:44 +0200
Subject: [PATCH 15/15] Revert Changes for Clippy `manual Range::contains
implementation`
---
feather/base/src/anvil/player.rs | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/feather/base/src/anvil/player.rs b/feather/base/src/anvil/player.rs
index 45afa1475..2e6100eda 100644
--- a/feather/base/src/anvil/player.rs
+++ b/feather/base/src/anvil/player.rs
@@ -72,14 +72,15 @@ pub struct InventorySlot {
impl InventorySlot {
/// Converts an [`ItemStack`] and network protocol index into an [`InventorySlot`].
pub fn from_network_index(network: usize, stack: &ItemStack) -> Option {
- let slot = if (SLOT_HOTBAR_OFFSET..(SLOT_HOTBAR_OFFSET + HOTBAR_SIZE)).contains(&network) {
+ let slot = if SLOT_HOTBAR_OFFSET <= network && network < SLOT_HOTBAR_OFFSET + HOTBAR_SIZE {
// Hotbar
(network - SLOT_HOTBAR_OFFSET) as i8
} else if network == SLOT_OFFHAND {
-106
- } else if (SLOT_ARMOR_MIN..(SLOT_ARMOR_MAX + 1)).contains(&network) {
+ } else if SLOT_ARMOR_MIN <= network && network <= SLOT_ARMOR_MAX {
((SLOT_ARMOR_MAX - network) + 100) as i8
- } else if (SLOT_INVENTORY_OFFSET..SLOT_INVENTORY_OFFSET + INVENTORY_SIZE).contains(&network)
+ } else if SLOT_INVENTORY_OFFSET <= network
+ && network < SLOT_INVENTORY_OFFSET + INVENTORY_SIZE
{
network as i8
} else {