Skip to content

Commit b46cc50

Browse files
rj00adyc3
andauthored
Client Component Division (#266)
## Description Divides the `Client` component into a set of smaller components as described by #199 (with many deviations). `McEntity` will be dealt with in a future PR. - Divide `Client` into smaller components (There's a lot to look at). - Move common components to `component` module. - Remove `Username` type from `valence_protocol` because the added complexity wasn't adding much benefit. - Clean up the inventory module. I've stopped worrying about the "Effect When Added" and "Effect When Removed" behavior of components so much, and instead assume that all components of a particular thing are required unless otherwise stated. ## Test Plan Steps: 1. Run examples and tests. A large number of tweaks have been made to the inventory module. I tried to preserve semantics but I could have made a mistake there. --------- Co-authored-by: Carson McManus <[email protected]> Co-authored-by: Carson McManus <[email protected]>
1 parent 8bd20e9 commit b46cc50

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2298
-1884
lines changed

crates/playground/src/extras.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,17 @@ use valence::prelude::*;
77
/// Toggles client's game mode between survival and creative when they start
88
/// sneaking.
99
pub fn toggle_gamemode_on_sneak(
10-
mut clients: Query<&mut Client>,
10+
mut clients: Query<&mut GameMode>,
1111
mut events: EventReader<StartSneaking>,
1212
) {
1313
for event in events.iter() {
14-
let Ok(mut client) = clients.get_component_mut::<Client>(event.client) else {
14+
let Ok(mut mode) = clients.get_component_mut::<GameMode>(event.client) else {
1515
continue;
1616
};
17-
let mode = client.game_mode();
18-
client.set_game_mode(match mode {
17+
*mode = match *mode {
1918
GameMode::Survival => GameMode::Creative,
2019
GameMode::Creative => GameMode::Survival,
2120
_ => GameMode::Creative,
22-
});
21+
};
2322
}
2423
}

crates/playground/src/playground.template.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ const SPAWN_Y: i32 = 64;
99

1010
pub fn build_app(app: &mut App) {
1111
app.add_plugin(ServerPlugin::new(()))
12-
.add_system(default_event_handler.in_schedule(EventLoopSchedule))
1312
.add_startup_system(setup)
13+
.add_system(default_event_handler.in_schedule(EventLoopSchedule))
1414
.add_system(init_clients)
1515
.add_system(despawn_disconnected_clients);
1616
}
@@ -34,15 +34,12 @@ fn setup(mut commands: Commands, server: Res<Server>) {
3434
}
3535

3636
fn init_clients(
37-
mut clients: Query<&mut Client, Added<Client>>,
37+
mut clients: Query<(&mut Position, &mut Location), Added<Client>>,
3838
instances: Query<Entity, With<Instance>>,
3939
) {
40-
let instance = instances.get_single().unwrap();
41-
42-
for mut client in &mut clients {
43-
client.set_position([0.5, SPAWN_Y as f64 + 1.0, 0.5]);
44-
client.set_instance(instance);
45-
client.set_game_mode(GameMode::Survival);
40+
for (mut pos, mut loc) in &mut clients {
41+
pos.0 = [0.5, SPAWN_Y as f64 + 1.0, 0.5].into();
42+
loc.0 = instances.single();
4643
}
4744
}
4845

crates/valence/examples/bench_players.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![allow(clippy::type_complexity)]
2+
13
use std::time::Instant;
24

35
use valence::client::despawn_disconnected_clients;
@@ -65,19 +67,26 @@ fn setup(mut commands: Commands, server: Res<Server>) {
6567
}
6668

6769
fn init_clients(
68-
mut clients: Query<(Entity, &mut Client), Added<Client>>,
70+
mut clients: Query<
71+
(
72+
Entity,
73+
&UniqueId,
74+
&mut Position,
75+
&mut Location,
76+
&mut GameMode,
77+
),
78+
Added<Client>,
79+
>,
6980
instances: Query<Entity, With<Instance>>,
7081
mut commands: Commands,
7182
) {
72-
let instance = instances.single();
73-
74-
for (client_entity, mut client) in &mut clients {
75-
client.set_position([0.0, SPAWN_Y as f64 + 1.0, 0.0]);
76-
client.set_instance(instance);
77-
client.set_game_mode(GameMode::Creative);
78-
79-
let player_entity = McEntity::with_uuid(EntityKind::Player, instance, client.uuid());
80-
81-
commands.entity(client_entity).insert(player_entity);
83+
for (entity, unique_id, mut pos, mut loc, mut game_mode) in &mut clients {
84+
pos.0 = [0.0, SPAWN_Y as f64 + 1.0, 0.0].into();
85+
loc.0 = instances.single();
86+
*game_mode = GameMode::Creative;
87+
88+
commands
89+
.entity(entity)
90+
.insert(McEntity::with_uuid(EntityKind::Player, loc.0, unique_id.0));
8291
}
8392
}

crates/valence/examples/biomes.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![allow(clippy::type_complexity)]
2+
13
use valence::client::despawn_disconnected_clients;
24
use valence::client::event::default_event_handler;
35
use valence::prelude::*;
@@ -77,14 +79,12 @@ fn setup(mut commands: Commands, server: Res<Server>) {
7779
}
7880

7981
fn init_clients(
80-
mut clients: Query<&mut Client, Added<Client>>,
82+
mut clients: Query<(&mut Position, &mut Location, &mut GameMode), Added<Client>>,
8183
instances: Query<Entity, With<Instance>>,
8284
) {
83-
for mut client in &mut clients {
84-
client.set_position([0.0, SPAWN_Y as f64 + 1.0, 0.0]);
85-
client.set_respawn_screen(true);
86-
client.set_instance(instances.single());
87-
client.set_game_mode(GameMode::Creative);
88-
client.send_message("Welcome to Valence!".italic());
85+
for (mut pos, mut loc, mut game_mode) in &mut clients {
86+
pos.set([0.0, SPAWN_Y as f64 + 1.0, 0.0]);
87+
loc.0 = instances.single();
88+
*game_mode = GameMode::Creative;
8989
}
9090
}

crates/valence/examples/block_entities.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![allow(clippy::type_complexity)]
2+
13
use valence::client::despawn_disconnected_clients;
24
use valence::client::event::{default_event_handler, ChatMessage, PlayerInteractBlock};
35
use valence::nbt::{compound, List};
@@ -61,19 +63,34 @@ fn setup(mut commands: Commands, server: Res<Server>) {
6163
}
6264

6365
fn init_clients(
64-
mut clients: Query<&mut Client, Added<Client>>,
66+
mut clients: Query<
67+
(
68+
Entity,
69+
&UniqueId,
70+
&mut Position,
71+
&mut Look,
72+
&mut Location,
73+
&mut GameMode,
74+
),
75+
Added<Client>,
76+
>,
6577
instances: Query<Entity, With<Instance>>,
78+
mut commands: Commands,
6679
) {
67-
for mut client in &mut clients {
68-
client.set_position([1.5, FLOOR_Y as f64 + 1.0, 1.5]);
69-
client.set_yaw(-90.0);
70-
client.set_instance(instances.single());
71-
client.set_game_mode(GameMode::Creative);
80+
for (entity, uuid, mut pos, mut look, mut loc, mut game_mode) in &mut clients {
81+
pos.set([1.5, FLOOR_Y as f64 + 1.0, 1.5]);
82+
look.yaw = -90.0;
83+
loc.0 = instances.single();
84+
*game_mode = GameMode::Creative;
85+
86+
commands
87+
.entity(entity)
88+
.insert(McEntity::with_uuid(EntityKind::Player, loc.0, uuid.0));
7289
}
7390
}
7491

7592
fn event_handler(
76-
clients: Query<&Client>,
93+
clients: Query<(&Username, &Properties, &UniqueId)>,
7794
mut messages: EventReader<ChatMessage>,
7895
mut block_interacts: EventReader<PlayerInteractBlock>,
7996
mut instances: Query<&mut Instance>,
@@ -83,14 +100,14 @@ fn event_handler(
83100
client, message, ..
84101
} in messages.iter()
85102
{
86-
let Ok(client) = clients.get(*client) else {
103+
let Ok((username, _, _)) = clients.get(*client) else {
87104
continue
88105
};
89106

90107
let mut sign = instance.block_mut(SIGN_POS).unwrap();
91108
let nbt = sign.nbt_mut().unwrap();
92109
nbt.insert("Text2", message.to_string().color(Color::DARK_GREEN));
93-
nbt.insert("Text3", format!("~{}", client.username()).italic());
110+
nbt.insert("Text3", format!("~{}", username).italic());
94111
}
95112

96113
for PlayerInteractBlock {
@@ -101,19 +118,19 @@ fn event_handler(
101118
} in block_interacts.iter()
102119
{
103120
if *hand == Hand::Main && *position == SKULL_POS {
104-
let Ok(client) = clients.get(*client) else {
121+
let Ok((_, properties, uuid)) = clients.get(*client) else {
105122
continue
106123
};
107124

108-
let Some(textures) = client.properties().iter().find(|prop| prop.name == "textures") else {
109-
continue
125+
let Some(textures) = properties.textures() else {
126+
continue;
110127
};
111128

112129
let mut skull = instance.block_mut(SKULL_POS).unwrap();
113130
let nbt = skull.nbt_mut().unwrap();
114131
*nbt = compound! {
115132
"SkullOwner" => compound! {
116-
"Id" => client.uuid(),
133+
"Id" => uuid.0,
117134
"Properties" => compound! {
118135
"textures" => List::Compound(vec![compound! {
119136
"Value" => textures.value.clone(),

crates/valence/examples/building.rs

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![allow(clippy::type_complexity)]
2+
13
use valence::client::despawn_disconnected_clients;
24
use valence::client::event::{
35
default_event_handler, PlayerInteractBlock, StartDigging, StartSneaking, StopDestroyBlock,
@@ -48,85 +50,98 @@ fn setup(mut commands: Commands, server: Res<Server>) {
4850
}
4951

5052
fn init_clients(
51-
mut clients: Query<&mut Client, Added<Client>>,
53+
mut clients: Query<
54+
(
55+
Entity,
56+
&UniqueId,
57+
&mut Client,
58+
&mut Position,
59+
&mut Location,
60+
&mut GameMode,
61+
),
62+
Added<Client>,
63+
>,
5264
instances: Query<Entity, With<Instance>>,
65+
mut commands: Commands,
5366
) {
54-
for mut client in &mut clients {
55-
client.set_position([0.0, SPAWN_Y as f64 + 1.0, 0.0]);
56-
client.set_instance(instances.single());
57-
client.set_game_mode(GameMode::Creative);
67+
for (entity, uuid, mut client, mut pos, mut loc, mut game_mode) in &mut clients {
68+
pos.0 = [0.0, SPAWN_Y as f64 + 1.0, 0.0].into();
69+
loc.0 = instances.single();
70+
*game_mode = GameMode::Creative;
5871
client.send_message("Welcome to Valence! Build something cool.".italic());
72+
commands
73+
.entity(entity)
74+
.insert(McEntity::with_uuid(EntityKind::Player, loc.0, uuid.0));
5975
}
6076
}
6177

6278
fn toggle_gamemode_on_sneak(
63-
mut clients: Query<&mut Client>,
79+
mut clients: Query<&mut GameMode>,
6480
mut events: EventReader<StartSneaking>,
6581
) {
6682
for event in events.iter() {
67-
let Ok(mut client) = clients.get_component_mut::<Client>(event.client) else {
83+
let Ok(mut mode) = clients.get_component_mut::<GameMode>(event.client) else {
6884
continue;
6985
};
70-
let mode = client.game_mode();
71-
client.set_game_mode(match mode {
86+
*mode = match *mode {
7287
GameMode::Survival => GameMode::Creative,
7388
GameMode::Creative => GameMode::Survival,
7489
_ => GameMode::Creative,
75-
});
90+
};
7691
}
7792
}
7893

7994
fn digging_creative_mode(
80-
clients: Query<&Client>,
95+
clients: Query<&GameMode>,
8196
mut instances: Query<&mut Instance>,
8297
mut events: EventReader<StartDigging>,
8398
) {
8499
let mut instance = instances.single_mut();
85100

86101
for event in events.iter() {
87-
let Ok(client) = clients.get_component::<Client>(event.client) else {
102+
let Ok(game_mode) = clients.get(event.client) else {
88103
continue;
89104
};
90-
if client.game_mode() == GameMode::Creative {
105+
if *game_mode == GameMode::Creative {
91106
instance.set_block(event.position, BlockState::AIR);
92107
}
93108
}
94109
}
95110

96111
fn digging_survival_mode(
97-
clients: Query<&Client>,
112+
clients: Query<&GameMode>,
98113
mut instances: Query<&mut Instance>,
99114
mut events: EventReader<StopDestroyBlock>,
100115
) {
101116
let mut instance = instances.single_mut();
102117

103118
for event in events.iter() {
104-
let Ok(client) = clients.get_component::<Client>(event.client) else {
119+
let Ok(game_mode) = clients.get(event.client) else {
105120
continue;
106121
};
107-
if client.game_mode() == GameMode::Survival {
122+
if *game_mode == GameMode::Survival {
108123
instance.set_block(event.position, BlockState::AIR);
109124
}
110125
}
111126
}
112127

113128
fn place_blocks(
114-
mut clients: Query<(&Client, &mut Inventory)>,
129+
mut clients: Query<(&mut Inventory, &GameMode, &PlayerInventoryState)>,
115130
mut instances: Query<&mut Instance>,
116131
mut events: EventReader<PlayerInteractBlock>,
117132
) {
118133
let mut instance = instances.single_mut();
119134

120135
for event in events.iter() {
121-
let Ok((client, mut inventory)) = clients.get_mut(event.client) else {
136+
let Ok((mut inventory, game_mode, inv_state)) = clients.get_mut(event.client) else {
122137
continue;
123138
};
124139
if event.hand != Hand::Main {
125140
continue;
126141
}
127142

128143
// get the held item
129-
let slot_id = client.held_item_slot();
144+
let slot_id = inv_state.held_item_slot();
130145
let Some(stack) = inventory.slot(slot_id) else {
131146
// no item in the slot
132147
continue;
@@ -137,7 +152,7 @@ fn place_blocks(
137152
continue;
138153
};
139154

140-
if client.game_mode() == GameMode::Survival {
155+
if *game_mode == GameMode::Survival {
141156
// check if the player has the item in their inventory and remove
142157
// it.
143158
if stack.count() > 1 {

0 commit comments

Comments
 (0)