1use yog_core::Server;
8use yog_entity::Entity;
9
10pub struct Player<'a> {
17 server: &'a dyn Server,
18 name: String,
19 uuid: Option<String>,
20}
21
22impl<'a> Player<'a> {
23 pub fn new(server: &'a dyn Server, name: impl Into<String>) -> Self {
26 Self {
27 server,
28 name: name.into(),
29 uuid: None,
30 }
31 }
32
33 pub fn with_uuid(
35 server: &'a dyn Server,
36 name: impl Into<String>,
37 uuid: impl Into<String>,
38 ) -> Self {
39 Self {
40 server,
41 name: name.into(),
42 uuid: Some(uuid.into()),
43 }
44 }
45
46 pub fn name(&self) -> &str {
47 &self.name
48 }
49
50 pub fn uuid(&self) -> Option<&str> {
51 self.uuid.as_deref()
52 }
53
54 pub fn entity(&self) -> Option<Entity<'_>> {
56 self.uuid.as_deref().map(|u| Entity::new(self.server, u))
57 }
58
59 pub fn give(&self, item_id: &str, count: u32) -> bool {
63 self.server.give_item(&self.name, item_id, count)
64 }
65
66 pub fn send_packet(&self, channel: &str, payload: &[u8]) -> bool {
68 self.server.send_to_player(&self.name, channel, payload)
69 }
70
71 pub fn teleport(&self, x: f64, y: f64, z: f64) -> bool {
76 match &self.uuid {
77 Some(u) => self.server.entity_teleport(u, x, y, z),
78 None => self.server.teleport(&self.name, x, y, z),
79 }
80 }
81
82 pub fn position(&self) -> Option<(f64, f64, f64)> {
84 self.entity()?.position()
85 }
86
87 pub fn health(&self) -> Option<f32> {
89 self.entity()?.health()
90 }
91
92 pub fn set_health(&self, health: f32) -> bool {
94 self.entity()
95 .is_some_and(|e: Entity<'_>| e.set_health(health))
96 }
97
98 pub fn kill(&self) -> bool {
100 self.entity().is_some_and(|e: Entity<'_>| e.kill())
101 }
102
103 pub fn send_title(
105 &self,
106 title: &str,
107 subtitle: &str,
108 fadein: i32,
109 stay: i32,
110 fadeout: i32,
111 ) -> bool {
112 self.server
113 .send_title(&self.name, title, subtitle, fadein, stay, fadeout)
114 }
115
116 pub fn send_actionbar(&self, message: &str) -> bool {
118 self.server.send_actionbar(&self.name, message)
119 }
120
121 pub fn kick(&self, reason: &str) -> bool {
123 self.server.kick_player(&self.name, reason)
124 }
125
126 pub fn set_gamemode(&self, gamemode: &str) -> bool {
128 self.server.set_gamemode(&self.name, gamemode)
129 }
130
131 pub fn play_sound(&self, sound_id: &str, volume: f32, pitch: f32) -> bool {
133 self.server
134 .play_sound_to_player(&self.name, sound_id, volume, pitch)
135 }
136
137 pub fn add_effect(
138 &self,
139 effect_id: &str,
140 duration_ticks: i32,
141 amplifier: u8,
142 show_particles: bool,
143 ) -> bool {
144 self.entity().is_some_and(|e: Entity<'_>| {
145 e.add_effect(effect_id, duration_ticks, amplifier, show_particles)
146 })
147 }
148
149 pub fn remove_effect(&self, effect_id: &str) -> bool {
150 self.entity()
151 .is_some_and(|e: Entity<'_>| e.remove_effect(effect_id))
152 }
153
154 pub fn clear_effects(&self) -> bool {
155 self.entity().is_some_and(|e: Entity<'_>| e.clear_effects())
156 }
157
158 pub fn inventory(&self) -> Vec<(u32, String, u32)> {
163 self.server
164 .player_inventory(&self.name)
165 .into_iter()
166 .filter(|(slot, _, _)| *slot <= 35)
167 .collect()
168 }
169
170 pub fn hotbar(&self) -> Vec<(u32, String, u32)> {
172 self.server
173 .player_inventory(&self.name)
174 .into_iter()
175 .filter(|(slot, _, _)| *slot <= 8)
176 .collect()
177 }
178
179 pub fn armor(&self) -> Vec<(u32, String, u32)> {
182 self.server
183 .player_inventory(&self.name)
184 .into_iter()
185 .filter(|(slot, _, _)| *slot >= 36 && *slot <= 39)
186 .map(|(slot, id, count)| (slot - 36, id, count))
187 .collect()
188 }
189
190 pub fn set_slot(&self, slot: u32, item_id: &str, count: u32) -> bool {
192 self.server
193 .player_set_slot(&self.name, slot, item_id, count)
194 }
195
196 pub fn teleport_to_dim(&self, dimension: &str, x: f64, y: f64, z: f64) -> bool {
200 self.server.teleport_to_dim(&self.name, dimension, x, y, z)
201 }
202}