~starkingdoms/starkingdoms

ref: 016f6cec6d73c13a2a5ccc704688260cdbc72d17 starkingdoms/crates/server/src/player/packet.rs -rw-r--r-- 3.8 KiB
016f6cec — core cargo fix 8 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use bevy::{ecs::event::ManualEventReader, prelude::*};
use starkingdoms_common::{packet::{Packet, Part, Planet}, proto_part_flags, proto_transform};

use crate::{
    module::component::{Attach, PartFlags, PartType},
    planet::PlanetType,
    ws::{PacketMessageConvert, WsEvent},
    CLIENT_SCALE,
};

use super::component::Player;

pub fn send_player_energy(player_query: Query<&Player>, mut packet_send: EventWriter<WsEvent>) {
    for player in &player_query {
        let packet = Packet::EnergyUpdate {
            amount: player.energy,
            max: player.energy_capacity,
        };

        packet_send.send(WsEvent::Send {
            to: player.addr,
            message: packet.into_message(),
        });
    }
}

pub fn on_position_change(
    mut commands: Commands,
    part_query: Query<(Entity, &PartType, &Transform, &PartFlags), Changed<Transform>>,
    planet_query: Query<(Entity, &PlanetType, &Transform), Changed<Transform>>,
    mut packet_send: EventWriter<WsEvent>,
) {
    let mut updated_parts = Vec::new();
    for (entity, part_type, transform, flags) in part_query.iter() {
        let id = commands.entity(entity).id().index();
        updated_parts.push((
            id,
            Part {
                part_type: part_type.0,
                transform: proto_transform!(Transform::from_translation(
                    transform.translation * CLIENT_SCALE,
                )
                .with_rotation(transform.rotation)),
                flags: proto_part_flags!(flags),
            },
        ));
    }

    if !updated_parts.is_empty() {
        let packet = Packet::PartPositions {
            parts: updated_parts,
        };

        packet_send.send(WsEvent::Broadcast {
            message: packet.into_message(),
        });
    }

    let mut planets = Vec::new();
    for (entity, planet_type, transform) in planet_query.iter() {
        let id = commands.entity(entity).id().index();
        planets.push((
            id,
            Planet {
                planet_type: planet_type.0,
                transform: proto_transform!(Transform::from_translation(
                    transform.translation * CLIENT_SCALE
                )),
                radius: planet!(*planet_type).size * CLIENT_SCALE,
            },
        ));
    }

    if !planets.is_empty() {
        let packet = Packet::PlanetPositions { planets };

        packet_send.send(WsEvent::Broadcast {
            message: packet.into_message(),
        });
    }
}

pub fn on_close(
    player_query: Query<(Entity, &Player, &Attach)>,
    attached_query: Query<&Attach, With<PartType>>,
    part_query: Query<&PartType>,
    mut commands: Commands,
    mut packet_recv: Local<ManualEventReader<WsEvent>>,
    mut packet_send: ResMut<Events<WsEvent>>,
) {
    let mut packets = Vec::new();
    for packet in packet_recv.read(&packet_send) {
        if let WsEvent::Close { addr } = packet {
            for (entity, player, attach) in &player_query {
                if player.addr == *addr {
                    crate::module::despawn_module_tree(
                        &mut commands,
                        attach,
                        &attached_query,
                        &part_query,
                        &mut packets,
                    );
                    commands.entity(entity).despawn_recursive();

                    let packet = Packet::PlayerLeave { id: entity.index() };

                    for (in_entity, player, _) in &player_query {
                        if entity != in_entity {
                            packets.push(WsEvent::Send {
                                to: player.addr,
                                message: packet.clone().into_message(),
                            });
                        }
                    }
                }
            }
        }
    }
    for packet in packets {
        packet_send.send(packet);
    }
}