mirror of
https://github.com/Pumpkin-MC/Pumpkin
synced 2025-04-12 17:33:04 +00:00
Use Cow's in TextComponent
We now don't always convert &str to Strings allowing us to use stack allocations
This commit is contained in:
pumpkin-protocol/src
pumpkin-registry/src
pumpkin-text/src
pumpkin/src
@ -7,7 +7,7 @@ use crate::{BitSet, ClientPacket, ServerPacket, VarInt, VarIntType};
|
||||
|
||||
use super::{deserializer, serializer, ByteBuffer, DeserializerError};
|
||||
|
||||
impl Serialize for BitSet<'static> {
|
||||
impl<'a> Serialize for BitSet<'a> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
|
@ -11,7 +11,7 @@ pub struct CConfigAddResourcePack<'a> {
|
||||
url: &'a str,
|
||||
hash: &'a str, // max 40
|
||||
forced: bool,
|
||||
prompt_message: Option<TextComponent>,
|
||||
prompt_message: Option<TextComponent<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> CConfigAddResourcePack<'a> {
|
||||
@ -20,7 +20,7 @@ impl<'a> CConfigAddResourcePack<'a> {
|
||||
url: &'a str,
|
||||
hash: &'a str,
|
||||
forced: bool,
|
||||
prompt_message: Option<TextComponent>,
|
||||
prompt_message: Option<TextComponent<'a>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
uuid,
|
||||
|
@ -1,7 +1,6 @@
|
||||
use pumpkin_macros::packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{bytebuf::ByteBuffer, ClientPacket};
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(0x01)]
|
||||
|
@ -4,12 +4,12 @@ use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(0x4C)]
|
||||
pub struct CActionBar {
|
||||
action_bar: TextComponent,
|
||||
pub struct CActionBar<'a> {
|
||||
action_bar: TextComponent<'a>,
|
||||
}
|
||||
|
||||
impl CActionBar {
|
||||
pub fn new(action_bar: TextComponent) -> Self {
|
||||
impl<'a> CActionBar<'a> {
|
||||
pub fn new(action_bar: TextComponent<'a>) -> Self {
|
||||
Self { action_bar }
|
||||
}
|
||||
}
|
||||
|
@ -6,19 +6,19 @@ use crate::VarInt;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(0x1E)]
|
||||
pub struct CDisguisedChatMessage {
|
||||
message: TextComponent,
|
||||
pub struct CDisguisedChatMessage<'a> {
|
||||
message: TextComponent<'a>,
|
||||
chat_type: VarInt,
|
||||
sender_name: TextComponent,
|
||||
target_name: Option<TextComponent>,
|
||||
sender_name: TextComponent<'a>,
|
||||
target_name: Option<TextComponent<'a>>,
|
||||
}
|
||||
|
||||
impl CDisguisedChatMessage {
|
||||
impl<'a> CDisguisedChatMessage<'a> {
|
||||
pub fn new(
|
||||
message: TextComponent,
|
||||
message: TextComponent<'a>,
|
||||
chat_type: VarInt,
|
||||
sender_name: TextComponent,
|
||||
target_name: Option<TextComponent>,
|
||||
sender_name: TextComponent<'a>,
|
||||
target_name: Option<TextComponent<'a>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
message,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use pumpkin_macros::packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
use crate::{position::WorldPosition, VarInt};
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(0x2B)]
|
||||
@ -23,7 +23,7 @@ pub struct CLogin<'a> {
|
||||
previous_gamemode: i8,
|
||||
debug: bool,
|
||||
is_flat: bool,
|
||||
death_dimension_name: Option<(String, i64)>, // POSITION NOT STRING
|
||||
death_dimension_name: Option<(WorldPosition, i64)>,
|
||||
portal_cooldown: VarInt,
|
||||
enforce_secure_chat: bool,
|
||||
}
|
||||
@ -47,7 +47,7 @@ impl<'a> CLogin<'a> {
|
||||
previous_gamemode: i8,
|
||||
debug: bool,
|
||||
is_flat: bool,
|
||||
death_dimension_name: Option<(String, i64)>,
|
||||
death_dimension_name: Option<(WorldPosition, i64)>,
|
||||
portal_cooldown: VarInt,
|
||||
enforce_secure_chat: bool,
|
||||
) -> Self {
|
||||
|
@ -6,14 +6,14 @@ use crate::VarInt;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(0x33)]
|
||||
pub struct COpenScreen {
|
||||
pub struct COpenScreen<'a> {
|
||||
window_id: VarInt,
|
||||
window_type: VarInt,
|
||||
window_title: TextComponent,
|
||||
window_title: TextComponent<'a>,
|
||||
}
|
||||
|
||||
impl COpenScreen {
|
||||
pub fn new(window_id: VarInt, window_type: VarInt, window_title: TextComponent) -> Self {
|
||||
impl<'a> COpenScreen<'a> {
|
||||
pub fn new(window_id: VarInt, window_type: VarInt, window_title: TextComponent<'a>) -> Self {
|
||||
Self {
|
||||
window_id,
|
||||
window_type,
|
||||
|
@ -4,12 +4,12 @@ use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(0x1D)]
|
||||
pub struct CPlayDisconnect {
|
||||
reason: TextComponent,
|
||||
pub struct CPlayDisconnect<'a> {
|
||||
reason: TextComponent<'a>,
|
||||
}
|
||||
|
||||
impl CPlayDisconnect {
|
||||
pub fn new(reason: TextComponent) -> Self {
|
||||
impl<'a> CPlayDisconnect<'a> {
|
||||
pub fn new(reason: TextComponent<'a>) -> Self {
|
||||
Self { reason }
|
||||
}
|
||||
}
|
||||
|
@ -11,19 +11,18 @@ pub struct CPlayerChatMessage<'a> {
|
||||
sender: UUID,
|
||||
index: VarInt,
|
||||
message_signature: Option<&'a [u8]>,
|
||||
message: String,
|
||||
message: &'a str,
|
||||
timestamp: i64,
|
||||
salt: i64,
|
||||
previous_messages_count: VarInt,
|
||||
previous_messages: &'a [PreviousMessage<'a>], // max 20
|
||||
unsigned_content: Option<TextComponent>,
|
||||
unsigned_content: Option<TextComponent<'a>>,
|
||||
/// See `FilterType`
|
||||
filter_type: VarInt,
|
||||
// TODO: THIS IS A HACK, We currently don't support writing or reading bitsets
|
||||
filter_type_bits: bool,
|
||||
filter_type_bits: Option<BitSet<'a>>,
|
||||
chat_type: VarInt,
|
||||
sender_name: TextComponent,
|
||||
target_name: Option<TextComponent>,
|
||||
sender_name: TextComponent<'a>,
|
||||
target_name: Option<TextComponent<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> CPlayerChatMessage<'a> {
|
||||
@ -32,15 +31,16 @@ impl<'a> CPlayerChatMessage<'a> {
|
||||
sender: UUID,
|
||||
index: VarInt,
|
||||
message_signature: Option<&'a [u8]>,
|
||||
message: String,
|
||||
message: &'a str,
|
||||
timestamp: i64,
|
||||
salt: i64,
|
||||
previous_messages: &'a [PreviousMessage<'a>],
|
||||
unsigned_content: Option<TextComponent>,
|
||||
unsigned_content: Option<TextComponent<'a>>,
|
||||
filter_type: VarInt,
|
||||
filter_type_bits: Option<BitSet<'a>>,
|
||||
chat_type: VarInt,
|
||||
sender_name: TextComponent,
|
||||
target_name: Option<TextComponent>,
|
||||
sender_name: TextComponent<'a>,
|
||||
target_name: Option<TextComponent<'a>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
sender,
|
||||
@ -53,7 +53,7 @@ impl<'a> CPlayerChatMessage<'a> {
|
||||
previous_messages,
|
||||
unsigned_content,
|
||||
filter_type,
|
||||
filter_type_bits: false,
|
||||
filter_type_bits,
|
||||
chat_type,
|
||||
sender_name,
|
||||
target_name,
|
||||
|
@ -4,12 +4,12 @@ use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(0x65)]
|
||||
pub struct CTitleText {
|
||||
title: TextComponent,
|
||||
pub struct CTitleText<'a> {
|
||||
title: TextComponent<'a>,
|
||||
}
|
||||
|
||||
impl CTitleText {
|
||||
pub fn new(title: TextComponent) -> Self {
|
||||
impl<'a> CTitleText<'a> {
|
||||
pub fn new(title: TextComponent<'a>) -> Self {
|
||||
Self { title }
|
||||
}
|
||||
}
|
||||
|
@ -4,12 +4,12 @@ use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(0x63)]
|
||||
pub struct CSubtitle {
|
||||
subtitle: TextComponent,
|
||||
pub struct CSubtitle<'a> {
|
||||
subtitle: TextComponent<'a>,
|
||||
}
|
||||
|
||||
impl CSubtitle {
|
||||
pub fn new(subtitle: TextComponent) -> Self {
|
||||
impl<'a> CSubtitle<'a> {
|
||||
pub fn new(subtitle: TextComponent<'a>) -> Self {
|
||||
Self { subtitle }
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,13 @@ use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(0x6C)]
|
||||
pub struct CSystemChatMessge {
|
||||
content: TextComponent,
|
||||
pub struct CSystemChatMessge<'a> {
|
||||
content: TextComponent<'a>,
|
||||
overlay: bool,
|
||||
}
|
||||
|
||||
impl CSystemChatMessge {
|
||||
pub fn new(content: TextComponent, overlay: bool) -> Self {
|
||||
impl<'a> CSystemChatMessge<'a> {
|
||||
pub fn new(content: TextComponent<'a>, overlay: bool) -> Self {
|
||||
Self { content, overlay }
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use bytebuf::{packet_id::Packet, ByteBuffer, DeserializerError};
|
||||
use bytes::Buf;
|
||||
use serde::{Deserialize, Serialize, Serializer};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::io::{self, Write};
|
||||
use thiserror::Error;
|
||||
|
||||
|
@ -2,7 +2,7 @@ use pumpkin_macros::packet;
|
||||
|
||||
use crate::{
|
||||
bytebuf::{ByteBuffer, DeserializerError},
|
||||
ServerPacket,
|
||||
ServerPacket, VarInt,
|
||||
};
|
||||
|
||||
// derive(Deserialize)]
|
||||
@ -12,7 +12,7 @@ pub struct SChatMessage {
|
||||
pub timestamp: i64,
|
||||
pub salt: i64,
|
||||
pub signature: Option<Vec<u8>>,
|
||||
// pub messagee_count: VarInt,
|
||||
pub messagee_count: VarInt,
|
||||
// acknowledged: BitSet,
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ impl ServerPacket for SChatMessage {
|
||||
timestamp: bytebuf.get_i64(),
|
||||
salt: bytebuf.get_i64(),
|
||||
signature: bytebuf.get_option(|v| v.get_slice().to_vec()),
|
||||
//messagee_count: bytebuf.get_var_int(),
|
||||
messagee_count: bytebuf.get_var_int(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
use std::char::MAX;
|
||||
|
||||
use num_derive::FromPrimitive;
|
||||
use num_traits::FromPrimitive;
|
||||
|
@ -11,7 +11,7 @@ pub struct ChatType {
|
||||
pub struct Decoration {
|
||||
translation_key: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
style: Option<Style>,
|
||||
style: Option<Style<'static>>,
|
||||
parameters: Vec<String>,
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,21 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
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 {
|
||||
pub enum ClickEvent<'a> {
|
||||
/// Opens a URL
|
||||
OpenUrl(String),
|
||||
OpenUrl(Cow<'a, str>),
|
||||
/// Works in signs, but only on the root text component
|
||||
RunCommand(String),
|
||||
RunCommand(Cow<'a, str>),
|
||||
/// Replaces the contents of the chat box with the text, not necessarily a
|
||||
/// command.
|
||||
SuggestCommand(String),
|
||||
SuggestCommand(Cow<'a, str>),
|
||||
/// 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),
|
||||
CopyToClipboard(Cow<'a, str>),
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::Text;
|
||||
@ -5,17 +7,17 @@ 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 {
|
||||
pub enum HoverEvent<'a> {
|
||||
/// Displays a tooltip with the given text.
|
||||
ShowText(Text),
|
||||
ShowText(Text<'a>),
|
||||
/// Shows an item.
|
||||
ShowItem {
|
||||
/// Resource identifier of the item
|
||||
id: String,
|
||||
id: Cow<'a, str>,
|
||||
/// Number of the items in the stack
|
||||
count: Option<i32>,
|
||||
/// NBT information about the item (sNBT format)
|
||||
tag: String,
|
||||
tag: Cow<'a, str>,
|
||||
},
|
||||
/// Shows an entity.
|
||||
ShowEntity {
|
||||
@ -24,9 +26,9 @@ pub enum HoverEvent {
|
||||
/// Resource identifier of the entity
|
||||
#[serde(rename = "type")]
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
kind: Option<String>,
|
||||
kind: Option<Cow<'a, str>>,
|
||||
/// Optional custom name for the entity
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
name: Option<Text>,
|
||||
name: Option<Text<'a>>,
|
||||
},
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use core::str;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use click::ClickEvent;
|
||||
use color::Color;
|
||||
@ -12,25 +13,34 @@ pub mod color;
|
||||
pub mod hover;
|
||||
pub mod style;
|
||||
|
||||
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct Text(pub Box<TextComponent>);
|
||||
pub struct Text<'a>(pub Box<TextComponent<'a>>);
|
||||
|
||||
// Represents a Text component
|
||||
// Reference: https://wiki.vg/Text_formatting#Text_components
|
||||
#[derive(Clone, Default, Debug, Deserialize)]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TextComponent {
|
||||
pub struct TextComponent<'a> {
|
||||
/// The actual text
|
||||
#[serde(flatten)]
|
||||
pub content: TextContent,
|
||||
pub content: TextContent<'a>,
|
||||
/// Style of the text. Bold, Italic, underline, Color...
|
||||
/// Also has `ClickEvent
|
||||
#[serde(flatten)]
|
||||
pub style: Style,
|
||||
pub style: Style<'a>,
|
||||
}
|
||||
|
||||
impl serde::Serialize for TextComponent {
|
||||
impl<'a> TextComponent<'a> {
|
||||
pub fn text(text: &'a str) -> Self {
|
||||
Self {
|
||||
content: TextContent::Text { text: text.into() },
|
||||
style: Style::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> serde::Serialize for TextComponent<'a> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
@ -39,7 +49,7 @@ impl serde::Serialize for TextComponent {
|
||||
}
|
||||
}
|
||||
|
||||
impl TextComponent {
|
||||
impl<'a> TextComponent<'a> {
|
||||
pub fn color(mut self, color: Color) -> Self {
|
||||
self.style.color = Some(color);
|
||||
self
|
||||
@ -87,13 +97,13 @@ impl TextComponent {
|
||||
}
|
||||
|
||||
/// Allows for events to occur when the player clicks on text. Only work in chat.
|
||||
pub fn click_event(mut self, event: ClickEvent) -> Self {
|
||||
pub fn click_event(mut self, event: ClickEvent<'a>) -> Self {
|
||||
self.style.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 {
|
||||
pub fn hover_event(mut self, event: HoverEvent<'a>) -> Self {
|
||||
self.style.hover_event = Some(event);
|
||||
self
|
||||
}
|
||||
@ -104,9 +114,9 @@ impl TextComponent {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct TempStruct<'a> {
|
||||
#[serde(flatten)]
|
||||
text: &'a TextContent,
|
||||
text: &'a TextContent<'a>,
|
||||
#[serde(flatten)]
|
||||
style: &'a Style,
|
||||
style: &'a Style<'a>,
|
||||
}
|
||||
let astruct = TempStruct {
|
||||
text: &self.content,
|
||||
@ -118,50 +128,24 @@ impl TextComponent {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for TextComponent {
|
||||
fn from(value: String) -> Self {
|
||||
Self {
|
||||
content: TextContent::Text { text: value },
|
||||
style: Style::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for TextComponent {
|
||||
fn from(value: &str) -> Self {
|
||||
Self {
|
||||
content: TextContent::Text {
|
||||
text: value.to_string(),
|
||||
},
|
||||
style: Style::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum TextContent {
|
||||
pub enum TextContent<'a> {
|
||||
/// Raw Text
|
||||
Text { text: String },
|
||||
Text { text: Cow<'a, str> },
|
||||
/// Translated text
|
||||
Translate {
|
||||
translate: String,
|
||||
translate: Cow<'a, str>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
with: Vec<Text>,
|
||||
with: Vec<Text<'a>>,
|
||||
},
|
||||
/// Displays the name of one or more entities found by a selector.
|
||||
EntityNames {
|
||||
selector: String,
|
||||
selector: Cow<'a, str>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
separator: Option<Text>,
|
||||
separator: Option<Cow<'a, str>>,
|
||||
},
|
||||
/// A keybind identifier
|
||||
/// https://minecraft.fandom.com/wiki/Controls#Configurable_controls
|
||||
Keybind { keybind: String },
|
||||
}
|
||||
|
||||
impl Default for TextContent {
|
||||
fn default() -> Self {
|
||||
Self::Text { text: "".into() }
|
||||
}
|
||||
Keybind { keybind: Cow<'a, str> },
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
|
||||
pub struct Style {
|
||||
pub struct Style<'a> {
|
||||
/// Changes the color to render the content
|
||||
pub color: Option<Color>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
@ -33,13 +33,13 @@ pub struct Style {
|
||||
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>,
|
||||
pub click_event: Option<ClickEvent<'a>>,
|
||||
/// 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>,
|
||||
pub hover_event: Option<HoverEvent<'a>>,
|
||||
}
|
||||
|
||||
impl Style {
|
||||
impl<'a> Style<'a> {
|
||||
pub fn color(mut self, color: Color) -> Self {
|
||||
self.color = Some(color);
|
||||
self
|
||||
@ -87,13 +87,13 @@ impl Style {
|
||||
}
|
||||
|
||||
/// Allows for events to occur when the player clicks on text. Only work in chat.
|
||||
pub fn click_event(mut self, event: ClickEvent) -> Self {
|
||||
pub fn click_event(mut self, event: ClickEvent<'a>) -> 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 {
|
||||
pub fn hover_event(mut self, event: HoverEvent<'a>) -> Self {
|
||||
self.hover_event = Some(event);
|
||||
self
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
use num_traits::FromPrimitive;
|
||||
use pumpkin_protocol::{
|
||||
client::{
|
||||
@ -199,7 +198,7 @@ impl Client {
|
||||
let prompt_message = if resource_config.prompt_message.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(TextComponent::from(resource_config.prompt_message.clone()))
|
||||
Some(TextComponent::text(&resource_config.prompt_message))
|
||||
};
|
||||
self.send_packet(&CConfigAddResourcePack::new(
|
||||
pumpkin_protocol::uuid::UUID(uuid::Uuid::new_v3(
|
||||
|
@ -375,7 +375,7 @@ impl Client {
|
||||
.unwrap_or_else(|_| self.close());
|
||||
}
|
||||
ConnectionState::Play => {
|
||||
self.try_send_packet(&CPlayDisconnect::new(TextComponent::from(reason)))
|
||||
self.try_send_packet(&CPlayDisconnect::new(TextComponent::text(reason)))
|
||||
.unwrap_or_else(|_| self.close());
|
||||
}
|
||||
_ => {
|
||||
|
@ -5,7 +5,8 @@ use pumpkin_entity::EntityId;
|
||||
use pumpkin_protocol::{
|
||||
client::play::{
|
||||
Animation, CBlockUpdate, CEntityAnimation, CEntityVelocity, CHeadRot, CHurtAnimation,
|
||||
CSystemChatMessge, CUpdateEntityPos, CUpdateEntityPosRot, CUpdateEntityRot,
|
||||
CPlayerChatMessage, CUpdateEntityPos, CUpdateEntityPosRot,
|
||||
CUpdateEntityRot, FilterType,
|
||||
},
|
||||
position::WorldPosition,
|
||||
server::play::{
|
||||
@ -209,38 +210,30 @@ impl Client {
|
||||
}
|
||||
|
||||
pub fn handle_chat_message(&mut self, server: &mut Server, chat_message: SChatMessage) {
|
||||
dbg!("got message");
|
||||
let message = chat_message.message;
|
||||
// TODO: filter message & validation
|
||||
let gameprofile = self.gameprofile.as_ref().unwrap();
|
||||
dbg!("got message");
|
||||
// yeah a "raw system message", the ugly way to do that, but it works
|
||||
|
||||
server.broadcast_packet(
|
||||
self,
|
||||
&CSystemChatMessge::new(
|
||||
TextComponent::from(format!("{}: {}", gameprofile.name, message)),
|
||||
false,
|
||||
),
|
||||
);
|
||||
|
||||
/* server.broadcast_packet(
|
||||
self,
|
||||
CPlayerChatMessage::new(
|
||||
&CPlayerChatMessage::new(
|
||||
pumpkin_protocol::uuid::UUID(gameprofile.id),
|
||||
0.into(),
|
||||
None,
|
||||
message.clone(),
|
||||
chat_message.messagee_count,
|
||||
chat_message.signature.as_deref(),
|
||||
&message,
|
||||
chat_message.timestamp,
|
||||
chat_message.salt,
|
||||
&[],
|
||||
Some(TextComponent::from(message.clone())),
|
||||
Some(TextComponent::text(&message)),
|
||||
pumpkin_protocol::VarInt(FilterType::PassThrough as i32),
|
||||
0.into(),
|
||||
TextComponent::from(gameprofile.name.clone()),
|
||||
None,
|
||||
1.into(),
|
||||
TextComponent::text(&gameprofile.name.clone()),
|
||||
None,
|
||||
),
|
||||
)
|
||||
|
||||
*/
|
||||
/* server.broadcast_packet(
|
||||
self,
|
||||
&CDisguisedChatMessage::new(
|
||||
@ -272,12 +265,13 @@ impl Client {
|
||||
pub fn handle_interact(&mut self, server: &mut Server, interact: SInteract) {
|
||||
let action = ActionType::from_i32(interact.typ.0).unwrap();
|
||||
if action == ActionType::Attack {
|
||||
let attacker_player = self.player.as_ref().unwrap();
|
||||
let entity_id = interact.entity_id;
|
||||
// TODO: do validation and stuff
|
||||
let config = &server.advanced_config.pvp;
|
||||
if config.enabled {
|
||||
let attacked_client = server.get_by_entityid(self, entity_id.0 as EntityId);
|
||||
let attacker_player = self.player.as_mut().unwrap();
|
||||
attacker_player.sneaking = interact.sneaking;
|
||||
if let Some(mut client) = attacked_client {
|
||||
let token = client.token.clone();
|
||||
let player = client.player.as_mut().unwrap();
|
||||
@ -299,9 +293,10 @@ impl Client {
|
||||
player.velocity.y as f32,
|
||||
player.velocity.z as f32,
|
||||
);
|
||||
attacker_player.velocity = attacker_player.velocity.multiply(0.6, 1.0, 0.6);
|
||||
|
||||
player.velocity = velo;
|
||||
client.send_packet(packet);
|
||||
// attacker_player.velocity = attacker_player.velocity.multiply(0.6, 1.0, 0.6);
|
||||
}
|
||||
if config.hurt_animation {
|
||||
// TODO
|
||||
|
@ -18,7 +18,7 @@ impl<'a> Command<'a> for GamemodeCommand {
|
||||
|
||||
if args.len() != 2 {
|
||||
player.send_system_message(
|
||||
TextComponent::from("Usage: /gamemode <mode>")
|
||||
TextComponent::text("Usage: /gamemode <mode>")
|
||||
.color_named(pumpkin_text::color::NamedColor::Red),
|
||||
);
|
||||
return;
|
||||
@ -28,21 +28,26 @@ impl<'a> Command<'a> for GamemodeCommand {
|
||||
match mode_str.parse() {
|
||||
Ok(mode) => {
|
||||
player.set_gamemode(mode);
|
||||
player.send_system_message(format!("Set own game mode to {:?}", mode).into());
|
||||
player.send_system_message(TextComponent::text(&format!(
|
||||
"Set own game mode to {:?}",
|
||||
mode
|
||||
)));
|
||||
}
|
||||
Err(_) => {
|
||||
// try to parse from number
|
||||
if let Ok(i) = mode_str.parse::<u8>() {
|
||||
if let Some(mode) = GameMode::from_u8(i) {
|
||||
player.set_gamemode(mode);
|
||||
player
|
||||
.send_system_message(format!("Set own game mode to {:?}", mode).into());
|
||||
player.send_system_message(TextComponent::text(&format!(
|
||||
"Set own game mode to {:?}",
|
||||
mode
|
||||
)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
player.send_system_message(
|
||||
TextComponent::from("Invalid gamemode")
|
||||
TextComponent::text("Invalid gamemode")
|
||||
.color_named(pumpkin_text::color::NamedColor::Red),
|
||||
);
|
||||
}
|
||||
|
@ -79,5 +79,5 @@ pub fn handle_command(sender: &mut CommandSender, command: &str) {
|
||||
return;
|
||||
}
|
||||
// TODO: red color
|
||||
sender.send_message("Command not Found".into());
|
||||
sender.send_message(TextComponent::text("Command not Found"));
|
||||
}
|
||||
|
@ -15,6 +15,6 @@ impl<'a> Command<'a> for PumpkinCommand {
|
||||
fn on_execute(sender: &mut super::CommandSender<'a>, _command: String) {
|
||||
let version = env!("CARGO_PKG_VERSION");
|
||||
let description = env!("CARGO_PKG_DESCRIPTION");
|
||||
sender.send_message(TextComponent::from(format!("Pumpkin {version}, {description} (Minecraft {CURRENT_MC_VERSION}, Protocol {CURRENT_MC_PROTOCOL})")).color_named(NamedColor::Green))
|
||||
sender.send_message(TextComponent::text(&format!("Pumpkin {version}, {description} (Minecraft {CURRENT_MC_VERSION}, Protocol {CURRENT_MC_PROTOCOL})")).color_named(NamedColor::Green))
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user