Skip to content

Commit

Permalink
Create pumpkin-text
Browse files Browse the repository at this point in the history
  • Loading branch information
Snowiiii committed Aug 9, 2024
1 parent 5f3a4d3 commit f122b47
Show file tree
Hide file tree
Showing 18 changed files with 162 additions and 141 deletions.
12 changes: 11 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[workspace]
resolver = "2"
members = [ "pumpkin-entity", "pumpkin-macros/", "pumpkin-protocol/", "pumpkin-registry/", "pumpkin-world", "pumpkin/" ]
members = [ "pumpkin-entity", "pumpkin-macros/", "pumpkin-protocol/", "pumpkin-registry/", "pumpkin-text", "pumpkin-world", "pumpkin/" ]

[workspace.package]
version = "0.1.0"
Expand Down
5 changes: 1 addition & 4 deletions pumpkin-protocol/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ version.workspace = true
edition.workspace = true

[dependencies]

pumpkin-macros = { path = "../pumpkin-macros" }
pumpkin-text = { path = "../pumpkin-text" }

bytes = "1.7"

Expand All @@ -22,9 +22,6 @@ log = "0.4"
num-traits = "0.2"
num-derive = "0.4"

# for text component
fastnbt = { git = "https://github.com/owengage/fastnbt.git" }

# encryption
aes = "0.8.4"
cfb8 = "0.8.1"
Expand Down
3 changes: 2 additions & 1 deletion pumpkin-protocol/src/client/play/c_disguised_chat_message.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use pumpkin_macros::packet;
use pumpkin_text::TextComponent;

use crate::{text::TextComponent, ClientPacket, VarInt};
use crate::{ClientPacket, VarInt};

#[derive(Clone)]
#[packet(0x1E)]
Expand Down
3 changes: 1 addition & 2 deletions pumpkin-protocol/src/client/play/c_play_disconnect.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use pumpkin_macros::packet;
use pumpkin_text::TextComponent;
use serde::Serialize;

use crate::text::TextComponent;

#[derive(Serialize)]
#[packet(0x1D)]
pub struct CPlayDisconnect {
Expand Down
3 changes: 2 additions & 1 deletion pumpkin-protocol/src/client/play/c_player_chat_message.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use num_derive::{FromPrimitive, ToPrimitive};
use pumpkin_macros::packet;
use pumpkin_text::TextComponent;
use serde::Serialize;

use crate::{text::TextComponent, VarInt};
use crate::{ VarInt};

#[derive(Serialize, Clone)]
#[packet(0x39)]
Expand Down
3 changes: 1 addition & 2 deletions pumpkin-protocol/src/client/play/c_system_chat_message.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use pumpkin_macros::packet;
use pumpkin_text::TextComponent;
use serde::Serialize;

use crate::text::TextComponent;

#[derive(Serialize, Clone)]
#[packet(0x6C)]
pub struct CSystemChatMessge {
Expand Down
1 change: 0 additions & 1 deletion pumpkin-protocol/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use thiserror::Error;
pub mod bytebuf;
pub mod client;
pub mod server;
pub mod text;

pub mod packet_decoder;
pub mod packet_encoder;
Expand Down
9 changes: 9 additions & 0 deletions pumpkin-text/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "pumpkin-text"
version.workspace = true
edition.workspace = true

[dependencies]
serde = { version = "1.0", features = ["derive"] }
fastnbt = { git = "https://github.com/owengage/fastnbt.git" }
uuid = "1.10"
19 changes: 19 additions & 0 deletions pumpkin-text/src/click.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use serde::{Deserialize, Serialize};

/// Action to take on click of the text.
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
#[serde(tag = "action", content = "value", rename_all = "snake_case")]
pub enum ClickEvent {
/// Opens an URL
OpenUrl(String),
/// Works in signs, but only on the root text component
RunCommand(String),
/// Replaces the contents of the chat box with the text, not necessarily a
/// command.
SuggestCommand(String),
/// Only usable within written books. Changes the page of the book. Indexing
/// starts at 1.
ChangePage(i32),
/// Copies the given text to system clipboard
CopyToClipboard(String),
}
36 changes: 36 additions & 0 deletions pumpkin-text/src/color.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use serde::{Deserialize, Serialize};

/// Text color
#[derive(Default, Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Color {
/// The default color for the text will be used, which varies by context
/// (in some cases, it's white; in others, it's black; in still others, it
/// is a shade of gray that isn't normally used on text).
#[default]
Reset,
/// One of the 16 named Minecraft colors
Named(NamedColor),
}

/// Named Minecraft color
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum NamedColor {
Black = 0,
DarkBlue,
DarkGreen,
DarkAqua,
DarkRed,
DarkPurple,
Gold,
Gray,
DarkGray,
Blue,
Green,
Aqua,
Red,
LightPurple,
Yellow,
White,
}
32 changes: 32 additions & 0 deletions pumpkin-text/src/hover.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use serde::{Deserialize, Serialize};

use crate::Text;

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(tag = "action", content = "contents", rename_all = "snake_case")]
#[allow(clippy::enum_variant_names)]
pub enum HoverEvent {
/// Displays a tooltip with the given text.
ShowText(Text),
/// Shows an item.
ShowItem {
/// Resource identifier of the item
id: String,
/// Number of the items in the stack
count: Option<i32>,
/// NBT information about the item (sNBT format)
tag: String,
},
/// Shows an entity.
ShowEntity {
/// The entity's UUID
id: uuid::Uuid,
/// Resource identifier of the entity
#[serde(rename = "type")]
#[serde(default, skip_serializing_if = "Option::is_none")]
kind: Option<String>,
/// Optional custom name for the entity
#[serde(default, skip_serializing_if = "Option::is_none")]
name: Option<Text>,
},
}
75 changes: 38 additions & 37 deletions pumpkin-protocol/src/text.rs → pumpkin-text/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
use core::str;

use click::ClickEvent;
use color::Color;
use fastnbt::SerOpts;
use hover::HoverEvent;
use serde::{Deserialize, Serialize};

pub mod color;
pub mod click;
pub mod hover;

#[derive(Clone, Default, Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct Text(Box<TextComponent>);
pub struct Text(pub Box<TextComponent>);

// Fepresents a Text component
// Reference: https://wiki.vg/Text_formatting#Text_components
Expand Down Expand Up @@ -42,6 +49,12 @@ pub struct TextComponent {
/// When the text is shift-clicked by a player, this string is inserted in their chat input. It does not overwrite any existing text the player was writing. This only works in chat messages
#[serde(default, skip_serializing_if = "Option::is_none")]
pub insertion: Option<String>,
/// Allows for events to occur when the player clicks on text. Only work in chat.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub click_event: Option<ClickEvent>,
/// Allows for a tooltip to be displayed when the player hovers their mouse over text.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub hover_event: Option<HoverEvent>,
}

impl serde::Serialize for TextComponent {
Expand All @@ -59,7 +72,7 @@ impl TextComponent {
self
}

pub fn color_named(mut self, color: NamedColor) -> Self {
pub fn color_named(mut self, color: color::NamedColor) -> Self {
self.color = Some(Color::Named(color));
self
}
Expand Down Expand Up @@ -100,6 +113,18 @@ impl TextComponent {
self
}

/// Allows for events to occur when the player clicks on text. Only work in chat.
pub fn click_event(mut self, event: ClickEvent) -> Self {
self.click_event = Some(event);
self
}

/// Allows for a tooltip to be displayed when the player hovers their mouse over text.
pub fn hover_event(mut self, event: HoverEvent) -> Self {
self.hover_event = Some(event);
self
}

pub fn encode(&self) -> Vec<u8> {
// TODO: Somehow fix this ugly mess
#[derive(serde::Serialize, Debug)]
Expand All @@ -121,6 +146,10 @@ impl TextComponent {
pub obfuscated: &'a Option<u8>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub insertion: &'a Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub click_event: &'a Option<ClickEvent>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub hover_event: &'a Option<HoverEvent>,
}
let astruct = TempStruct {
text: &self.content,
Expand All @@ -131,7 +160,10 @@ impl TextComponent {
strikethrough: &self.strikethrough,
obfuscated: &self.obfuscated,
insertion: &self.insertion,
click_event: &self.click_event,
hover_event: &self.hover_event,
};
// dbg!(&serde_json::to_string(&astruct));
let nbt = fastnbt::to_bytes_with_opts(&astruct, SerOpts::network_nbt()).unwrap();
nbt
}
Expand All @@ -148,6 +180,8 @@ impl From<String> for TextComponent {
strikethrough: None,
obfuscated: None,
insertion: None,
click_event: None,
hover_event: None,
}
}
}
Expand All @@ -165,6 +199,8 @@ impl From<&str> for TextComponent {
strikethrough: None,
obfuscated: None,
insertion: None,
click_event: None,
hover_event: None,
}
}
}
Expand Down Expand Up @@ -196,38 +232,3 @@ impl Default for TextContent {
Self::Text { text: "".into() }
}
}

/// Text color
#[derive(Default, Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Color {
/// The default color for the text will be used, which varies by context
/// (in some cases, it's white; in others, it's black; in still others, it
/// is a shade of gray that isn't normally used on text).
#[default]
Reset,
/// One of the 16 named Minecraft colors
Named(NamedColor),
}

/// Named Minecraft color
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum NamedColor {
Black = 0,
DarkBlue,
DarkGreen,
DarkAqua,
DarkRed,
DarkPurple,
Gold,
Gray,
DarkGray,
Blue,
Green,
Aqua,
Red,
LightPurple,
Yellow,
White,
}
1 change: 1 addition & 0 deletions pumpkin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ description = "Empowering everyone to host fast and efficient Minecraft servers.
edition = "2021"

[dependencies]
pumpkin-text = { path = "../pumpkin-text" }
pumpkin-world = { path = "../pumpkin-world"}
pumpkin-entity = { path = "../pumpkin-entity"}
pumpkin-protocol = { path = "../pumpkin-protocol"}
Expand Down
2 changes: 1 addition & 1 deletion pumpkin/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ use pumpkin_protocol::{
},
status::{SPingRequest, SStatusRequest},
},
text::TextComponent,
ClientPacket, ConnectionState, PacketError, RawPacket, ServerPacket,
};
use pumpkin_text::TextComponent;

use std::io::Read;
use thiserror::Error;
Expand Down
2 changes: 1 addition & 1 deletion pumpkin/src/client/player_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use pumpkin_protocol::{
SChatCommand, SChatMessage, SConfirmTeleport, SPlayerCommand, SPlayerPosition,
SPlayerPositionRotation, SPlayerRotation, SSwingArm,
},
text::TextComponent,
};
use pumpkin_text::TextComponent;

use crate::{
commands::{handle_command, CommandSender},
Expand Down
2 changes: 1 addition & 1 deletion pumpkin/src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use gamemode::GamemodeCommand;
use pumpkin::PumpkinCommand;
use pumpkin_protocol::text::TextComponent;
use pumpkin_text::TextComponent;

use crate::client::Client;

Expand Down
Loading

0 comments on commit f122b47

Please sign in to comment.