@@ 14,7 14,10 @@ pub enum PartType {
}
#[derive(Component)]
-pub struct Player(pub SocketAddr);
+pub struct Player {
+ pub addr: SocketAddr,
+ pub username: String,
+}
#[derive(Bundle)]
pub struct PlanetBundle {
@@ 31,5 34,5 @@ pub struct PartBundle {
#[derive(Bundle)]
pub struct PlayerBundle {
pub part: PartBundle,
- pub addr: Player,
+ pub player: Player,
}
@@ 81,6 81,8 @@ fn spawn_planets(mut commands: Commands) {
fn on_message(
mut commands: Commands,
planet_query: Query<(Entity, &PlanetType, &Transform)>,
+ player_query: Query<(Entity, &Player)>,
+ part_query: Query<(Entity, &PartType, &Transform)>,
mut packet_recv: Local<ManualEventReader<ServerEvent>>,
mut packet_send: ResMut<Events<ServerEvent>>,
) {
@@ 93,8 95,11 @@ fn on_message(
let data = json["c"].clone();
let packet_type = some_or_cont!(packet_type.as_str());
match packet_type {
+ // handshake
"ClientLogin" => {
// spawn player
+ let username = data["username"].clone();
+ let username = some_or_cont!(username.as_str());
let transform = Transform::from_xyz(0.0, 0.0, 0.0);
let id = commands
.spawn(PlayerBundle {
@@ 102,18 107,8 @@ fn on_message(
part_type: PartType::Hearty,
transform: TransformBundle::from(transform),
},
- addr: Player(*addr),
+ player: Player { addr: *addr, username: username.to_string() },
}).id().index();
- // tell other clients that a player has spawned
- let username = data["username"].clone();
- let username = some_or_cont!(username.as_str());
- let packet = Packet::SpawnPlayer {
- id,
- username: username.to_string(),
- position: proto_transform!(transform),
- };
- let buf = serde_json::to_vec(&packet).unwrap();
- packets.push(ServerEvent::Broadcast(MessageType::Text, buf));
// tell this player the planets
let mut planets = Vec::new();
@@ 126,6 121,43 @@ fn on_message(
let packet = Packet::PlanetPositions { planets };
let buf = serde_json::to_vec(&packet).unwrap();
packets.push(ServerEvent::Send(*addr, MessageType::Text, buf));
+
+ // tell the player already existing users
+ let mut players = Vec::new();
+ for (entity, player) in &player_query {
+ players.push((entity.index(), player.username.clone()));
+ }
+ let packet = Packet::PlayerList {
+ players,
+ };
+ let buf = serde_json::to_vec(&packet).unwrap();
+ packets.push(ServerEvent::Send(*addr, MessageType::Text, buf));
+
+ // tell other players that a player has spawned in
+ let packet = Packet::SpawnPlayer {
+ id,
+ username: username.to_string(),
+ };
+ let buf = serde_json::to_vec(&packet).unwrap();
+ packets.push(ServerEvent::Broadcast(MessageType::Text, buf));
+
+ // tell the player where parts are
+ let mut parts = Vec::new();
+ for (entity, part_type, transform) in &part_query {
+ parts.push((entity.index(), Part {
+ part_type: *part_type,
+ transform: proto_transform!(transform),
+ }));
+ }
+ parts.push((id, Part {
+ part_type: PartType::Hearty,
+ transform: proto_transform!(transform),
+ }));
+ let packet = Packet::PartPositions {
+ parts
+ };
+ let buf = serde_json::to_vec(&packet).unwrap();
+ packets.push(ServerEvent::Send(*addr, MessageType::Text, buf));
}
_ => continue
};
@@ 138,7 170,7 @@ fn on_message(
fn on_position_change(
mut commands: Commands,
- part_query: Query<(Entity, &PartType, &Transform), (With<Player>, Changed<Transform>)>,
+ part_query: Query<(Entity, &PartType, &Transform), Changed<Transform>>,
planet_query: Query<(Entity, &PlanetType, &Transform), Changed<Transform>>,
mut packet_send: EventWriter<ServerEvent>,
) {
@@ 32,14 32,18 @@ pub struct Part {
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "t", content = "c")]
pub enum Packet {
+ // serverbound
ClientLogin {
username: String,
jwt: Option<String>,
},
+ // clientbound
SpawnPlayer {
id: u32,
username: String,
- position: ProtoTransform
+ },
+ PlayerList {
+ players: Vec<(u32, String)>,
},
PlanetPositions {
planets: Vec<(u32, Planet)>
@@ 47,4 51,4 @@ pub enum Packet {
PartPositions {
parts: Vec<(u32, Part)>
}
-}>
\ No newline at end of file
+}