~starkingdoms/starkingdoms

ref: 1ec41be4083696df817c9e10c0154181b561c3da starkingdoms/server/src/main.rs -rw-r--r-- 4.0 KiB
1ec41be4 — core bevy_twite is having some serious doing-things issues 2 years 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
123
124
use std::collections::HashMap;

use bevy::utils::tracing;
use bevy::{ecs::event::ManualEventReader, prelude::*};
use bevy_twite::{twite::frame::MessageType, ServerEvent, TwiteServerConfig, TwiteServerPlugin};
use component::*;
use packet::*;

pub mod component;
pub mod packet;

fn main() {
    let subscriber = tracing_subscriber::FmtSubscriber::new();
    tracing::subscriber::set_global_default(subscriber).unwrap();
    info!(
        "StarKingdoms server v{} starting up",
        env!("CARGO_PKG_VERSION")
    );

    App::new()
        .insert_resource(TwiteServerConfig { port: 3000 })
        .add_plugins(MinimalPlugins)
        .add_plugins(TwiteServerPlugin)
        .add_systems(Startup, spawn_planets)
        .add_systems(FixedUpdate, on_connection)
        .add_systems(FixedUpdate, on_position_change)
        .run();

    info!("Goodbye!");
}

fn spawn_planets(mut commands: Commands) {
    info!("Spawning planets");
    let earth_pos = Transform::from_xyz(0.0, 0.0, 0.0);
    commands.spawn(PlanetBundle {
        planet_type: PlanetType::Earth,
        transform: TransformBundle::from(earth_pos),
    });
}

fn on_connection(
    mut commands: Commands,
    planet_query: Query<(Entity, &PlanetType, &Transform)>,
    mut reader: Local<ManualEventReader<ServerEvent>>,
    mut events: ResMut<Events<ServerEvent>>,
) {
    let mut packets = Vec::new();
    for ev in reader.read(&events) {
        info!("{:?}", ev);
        if let ServerEvent::Connection(addr) = ev {
            info!("client connected");
            let _id = commands
                .spawn(PlayerBundle {
                    part: PartBundle {
                        part_type: PartType::Hearty,
                        transform: TransformBundle::from(Transform::from_xyz(0.0, 0.0, 0.0)),
                    },
                    addr: Player(*addr),
                })
                .id()
                .index();

            let mut planets = HashMap::new();
            for (entity, planet_type, transform) in planet_query.iter() {
                planets.insert(
                    entity.index(),
                    PacketPlanet {
                        planet_type: *planet_type as u8,
                        position: (transform.translation.x, transform.translation.y),
                    },
                );
            }

            let packet = PlanetPositionPacket { planets };
            let buf = serde_json::to_vec(&packet).unwrap();

            packets.push(ServerEvent::Send(*addr, MessageType::Text, buf));
        }
    }
    for packet in packets {
        events.send(packet);
    }
}

fn on_position_change(
    mut commands: Commands,
    part_query: Query<(Entity, &Transform), (With<Player>, Changed<Transform>)>,
    planet_query: Query<(Entity, &PlanetType, &Transform), Changed<Transform>>,
    mut packet_send: EventWriter<ServerEvent>,
) {
    let mut updated_parts = HashMap::new();
    for (entity, transform) in part_query.iter() {
        let id = commands.entity(entity).id().index();
        let translation = transform.translation;
        updated_parts.insert(id, (0, translation.x, translation.y)); // Type hearty = 0
    }

    if !updated_parts.is_empty() {
        let packet = PartPositionPacket { parts: updated_parts };
        let buf = serde_json::to_vec(&packet).unwrap();

        packet_send.send(ServerEvent::Broadcast(MessageType::Text, buf));
    }

    let mut planets = HashMap::new();
    for (entity, planet_type, transform) in planet_query.iter() {
        let id = commands.entity(entity).id().index();
        let translation = transform.translation;
        planets.insert(
            id,
            PacketPlanet {
                planet_type: *planet_type as u8,
                position: (translation.x, translation.y),
            },
        );
    }

    if !planets.is_empty() {
        let packet = PlanetPositionPacket { planets };
        let buf = serde_json::to_vec(&packet).unwrap();

        packet_send.send(ServerEvent::Broadcast(MessageType::Text, buf));
    }
}