Skip to content

Commit c7f15de

Browse files
committed
Refactor Client
1 parent ae028da commit c7f15de

File tree

9 files changed

+369
-326
lines changed

9 files changed

+369
-326
lines changed

pumpkin/src/client/client_packet.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -269,12 +269,11 @@ impl Client {
269269

270270
pub async fn handle_config_acknowledged(
271271
&mut self,
272-
server: &mut Server,
272+
_server: &mut Server,
273273
_config_acknowledged: SAcknowledgeFinishConfig,
274274
) {
275275
dbg!("config acknowledged");
276276
self.connection_state = ConnectionState::Play;
277-
// generate a player
278-
server.spawn_player(self).await;
277+
self.make_player = true;
279278
}
280279
}

pumpkin/src/client/container.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use pumpkin_protocol::client::play::{COpenScreen, CSetContainerContent, CSetCont
44
use pumpkin_protocol::slot::Slot;
55
use pumpkin_world::item::Item;
66

7-
impl super::Client {
7+
use crate::entity::player::Player;
8+
9+
impl Player {
810
pub fn open_container(
911
&mut self,
1012
window_type: WindowType,
@@ -23,7 +25,7 @@ impl super::Client {
2325
.unwrap())
2426
.into();
2527
let title = TextComponent::text(window_title.unwrap_or(window_type.default_title()));
26-
self.send_packet(&COpenScreen::new(
28+
self.client.send_packet(&COpenScreen::new(
2729
(window_type.clone() as u8 + 1).into(),
2830
menu_protocol_id,
2931
title,
@@ -37,14 +39,12 @@ impl super::Client {
3739
items: Option<Vec<Option<&'a Item>>>,
3840
carried_item: Option<&'a Item>,
3941
) {
40-
let player = self.player.as_ref().unwrap();
41-
4242
let slots: Vec<Slot> = {
4343
if let Some(mut items) = items {
44-
items.extend(player.inventory.slots());
44+
items.extend(self.inventory.slots());
4545
items
4646
} else {
47-
player.inventory.slots()
47+
self.inventory.slots()
4848
}
4949
.into_iter()
5050
.map(|item| {
@@ -66,7 +66,7 @@ impl super::Client {
6666
};
6767
let packet =
6868
CSetContainerContent::new(window_type as u8 + 1, 0.into(), &slots, &carried_item);
69-
self.send_packet(&packet);
69+
self.client.send_packet(&packet);
7070
}
7171

7272
pub fn set_container_slot(
@@ -75,7 +75,7 @@ impl super::Client {
7575
slot: usize,
7676
item: Option<&Item>,
7777
) {
78-
self.send_packet(&CSetContainerSlot::new(
78+
self.client.send_packet(&CSetContainerSlot::new(
7979
window_type as i8,
8080
0,
8181
slot,

pumpkin/src/client/mod.rs

+24-116
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,22 @@ use std::{
66
};
77

88
use crate::{
9-
entity::player::{ChatMode, GameMode, Hand, Player},
9+
entity::player::{ChatMode, Hand},
1010
server::Server,
1111
};
1212

1313
use authentication::GameProfile;
1414
use mio::{event::Event, net::TcpStream, Token};
15-
use num_traits::ToPrimitive;
1615
use pumpkin_core::text::TextComponent;
1716
use pumpkin_protocol::{
1817
bytebuf::packet_id::Packet,
19-
client::{
20-
config::CConfigDisconnect,
21-
login::CLoginDisconnect,
22-
play::{CGameEvent, CPlayDisconnect, CSyncPlayerPosition, CSystemChatMessage},
23-
},
18+
client::{config::CConfigDisconnect, login::CLoginDisconnect, play::CPlayDisconnect},
2419
packet_decoder::PacketDecoder,
2520
packet_encoder::PacketEncoder,
2621
server::{
2722
config::{SAcknowledgeFinishConfig, SClientInformationConfig, SKnownPacks, SPluginMessage},
2823
handshake::SHandShake,
2924
login::{SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart},
30-
play::{
31-
SChatCommand, SChatMessage, SClientInformationPlay, SConfirmTeleport, SInteract,
32-
SPlayPingRequest, SPlayerAction, SPlayerCommand, SPlayerPosition,
33-
SPlayerPositionRotation, SPlayerRotation, SSetCreativeSlot, SSetHeldItem, SSwingArm,
34-
SUseItemOn,
35-
},
3625
status::{SStatusPingRequest, SStatusRequest},
3726
},
3827
ClientPacket, ConnectionState, PacketError, RawPacket, ServerPacket,
@@ -46,6 +35,7 @@ mod client_packet;
4635
mod container;
4736
pub mod player_packet;
4837

38+
#[derive(Clone)]
4939
pub struct PlayerConfig {
5040
pub locale: String, // 16
5141
pub view_distance: i8,
@@ -57,9 +47,22 @@ pub struct PlayerConfig {
5747
pub server_listing: bool,
5848
}
5949

60-
pub struct Client {
61-
pub player: Option<Player>,
50+
impl Default for PlayerConfig {
51+
fn default() -> Self {
52+
Self {
53+
locale: "en_us".to_string(),
54+
view_distance: 2,
55+
chat_mode: ChatMode::Enabled,
56+
chat_colors: true,
57+
skin_parts: 0,
58+
main_hand: Hand::Main,
59+
text_filtering: false,
60+
server_listing: false,
61+
}
62+
}
63+
}
6264

65+
pub struct Client {
6366
pub gameprofile: Option<GameProfile>,
6467

6568
pub config: Option<PlayerConfig>,
@@ -75,6 +78,8 @@ pub struct Client {
7578
enc: PacketEncoder,
7679
dec: PacketDecoder,
7780
pub client_packets_queue: VecDeque<RawPacket>,
81+
82+
pub make_player: bool,
7883
}
7984

8085
impl Client {
@@ -86,14 +91,14 @@ impl Client {
8691
brand: None,
8792
token,
8893
address,
89-
player: None,
9094
connection_state: ConnectionState::HandShake,
9195
connection,
9296
enc: PacketEncoder::default(),
9397
dec: PacketDecoder::default(),
9498
encryption: true,
9599
closed: false,
96100
client_packets_queue: VecDeque::new(),
101+
make_player: false,
97102
}
98103
}
99104

@@ -122,10 +127,6 @@ impl Client {
122127
self.enc.set_compression(compression);
123128
}
124129

125-
pub fn is_player(&self) -> bool {
126-
self.player.is_some()
127-
}
128-
129130
/// Send a Clientbound Packet to the Client
130131
pub fn send_packet<P: ClientPacket>(&mut self, packet: &P) {
131132
self.enc
@@ -145,37 +146,6 @@ impl Client {
145146
Ok(())
146147
}
147148

148-
pub fn teleport(&mut self, x: f64, y: f64, z: f64, yaw: f32, pitch: f32) {
149-
assert!(self.is_player());
150-
// TODO
151-
let id = 0;
152-
let player = self.player.as_mut().unwrap();
153-
let entity = &mut player.entity;
154-
entity.x = x;
155-
entity.y = y;
156-
entity.z = z;
157-
entity.lastx = x;
158-
entity.lasty = y;
159-
entity.lastz = z;
160-
entity.yaw = yaw;
161-
entity.pitch = pitch;
162-
player.awaiting_teleport = Some(id.into());
163-
self.send_packet(&CSyncPlayerPosition::new(x, y, z, yaw, pitch, 0, id.into()));
164-
}
165-
166-
pub fn update_health(&mut self, health: f32, food: i32, food_saturation: f32) {
167-
let player = self.player.as_mut().unwrap();
168-
player.health = health;
169-
player.food = food;
170-
player.food_saturation = food_saturation;
171-
}
172-
173-
pub fn set_gamemode(&mut self, gamemode: GameMode) {
174-
let player = self.player.as_mut().unwrap();
175-
player.gamemode = gamemode;
176-
self.send_packet(&CGameEvent::new(3, gamemode.to_f32().unwrap()));
177-
}
178-
179149
pub async fn process_packets(&mut self, server: &mut Server) {
180150
let mut i = 0;
181151
while i < self.client_packets_queue.len() {
@@ -185,7 +155,7 @@ impl Client {
185155
}
186156
}
187157

188-
/// Handles an incoming decoded Packet
158+
/// Handles an incoming decoded not Play state Packet
189159
pub async fn handle_packet(&mut self, server: &mut Server, packet: &mut RawPacket) {
190160
// TODO: handle each packet's Error instead of calling .unwrap()
191161
let bytebuf = &mut packet.bytebuf;
@@ -254,71 +224,13 @@ impl Client {
254224
packet.id.0
255225
),
256226
},
257-
pumpkin_protocol::ConnectionState::Play => {
258-
if self.player.is_some() {
259-
self.handle_play_packet(server, packet);
260-
} else {
261-
// should be impossible
262-
self.kick("no player in play state?")
263-
}
264-
}
265227
_ => log::error!("Invalid Connection state {:?}", self.connection_state),
266228
}
267229
}
268230

269-
pub fn handle_play_packet(&mut self, server: &mut Server, packet: &mut RawPacket) {
270-
let bytebuf = &mut packet.bytebuf;
271-
match packet.id.0 {
272-
SConfirmTeleport::PACKET_ID => {
273-
self.handle_confirm_teleport(server, SConfirmTeleport::read(bytebuf).unwrap())
274-
}
275-
SChatCommand::PACKET_ID => {
276-
self.handle_chat_command(server, SChatCommand::read(bytebuf).unwrap())
277-
}
278-
SPlayerPosition::PACKET_ID => {
279-
self.handle_position(server, SPlayerPosition::read(bytebuf).unwrap())
280-
}
281-
SPlayerPositionRotation::PACKET_ID => self
282-
.handle_position_rotation(server, SPlayerPositionRotation::read(bytebuf).unwrap()),
283-
SPlayerRotation::PACKET_ID => {
284-
self.handle_rotation(server, SPlayerRotation::read(bytebuf).unwrap())
285-
}
286-
SPlayerCommand::PACKET_ID => {
287-
self.handle_player_command(server, SPlayerCommand::read(bytebuf).unwrap())
288-
}
289-
SSwingArm::PACKET_ID => {
290-
self.handle_swing_arm(server, SSwingArm::read(bytebuf).unwrap())
291-
}
292-
SChatMessage::PACKET_ID => {
293-
self.handle_chat_message(server, SChatMessage::read(bytebuf).unwrap())
294-
}
295-
SClientInformationPlay::PACKET_ID => self.handle_client_information_play(
296-
server,
297-
SClientInformationPlay::read(bytebuf).unwrap(),
298-
),
299-
SInteract::PACKET_ID => self.handle_interact(server, SInteract::read(bytebuf).unwrap()),
300-
SPlayerAction::PACKET_ID => {
301-
self.handle_player_action(server, SPlayerAction::read(bytebuf).unwrap())
302-
}
303-
SUseItemOn::PACKET_ID => {
304-
self.handle_use_item_on(server, SUseItemOn::read(bytebuf).unwrap())
305-
}
306-
SSetHeldItem::PACKET_ID => {
307-
self.handle_set_held_item(server, SSetHeldItem::read(bytebuf).unwrap())
308-
}
309-
SSetCreativeSlot::PACKET_ID => {
310-
self.handle_set_creative_slot(server, SSetCreativeSlot::read(bytebuf).unwrap())
311-
}
312-
SPlayPingRequest::PACKET_ID => {
313-
self.handle_play_ping_request(server, SPlayPingRequest::read(bytebuf).unwrap())
314-
}
315-
_ => log::error!("Failed to handle player packet id {:#04x}", packet.id.0),
316-
}
317-
}
318-
319231
// Reads the connection until our buffer of len 4096 is full, then decode
320232
/// Close connection when an error occurs
321-
pub async fn poll(&mut self, server: &mut Server, event: &Event) {
233+
pub async fn poll(&mut self, event: &Event) {
322234
if event.is_readable() {
323235
let mut received_data = vec![0; 4096];
324236
let mut bytes_read = 0;
@@ -351,7 +263,6 @@ impl Client {
351263
Ok(packet) => {
352264
if let Some(packet) = packet {
353265
self.add_packet(packet);
354-
self.process_packets(server).await;
355266
}
356267
}
357268
Err(err) => self.kick(&err.to_string()),
@@ -361,10 +272,6 @@ impl Client {
361272
}
362273
}
363274

364-
pub fn send_system_message(&mut self, text: TextComponent) {
365-
self.send_packet(&CSystemChatMessage::new(text, false));
366-
}
367-
368275
/// Kicks the Client with a reason depending on the connection state
369276
pub fn kick(&mut self, reason: &str) {
370277
dbg!(reason);
@@ -379,6 +286,7 @@ impl Client {
379286
self.try_send_packet(&CConfigDisconnect::new(reason))
380287
.unwrap_or_else(|_| self.close());
381288
}
289+
// So we can also kick on errors, but generally should use Player::kick
382290
ConnectionState::Play => {
383291
self.try_send_packet(&CPlayDisconnect::new(TextComponent::text(reason)))
384292
.unwrap_or_else(|_| self.close());

0 commit comments

Comments
 (0)