mod component;
mod packet;
use std::collections::HashMap;
use bevy::{prelude::*, ecs::event::ManualEventReader};
use bevy::utils::tracing;
use bevy_twite::{TwiteServerPlugin, TwiteServerConfig, ServerEvent, twite::frame::MessageType};
use component::*;
use packet::*;
use rmp_serde::Serializer;
use serde::Serialize;
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(Update, on_connection)
.add_systems(Update, on_position_change)
.run();
info!("Goodbye!");
}
fn spawn_planets(mut commands: Commands) {
debug!("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) {
if let ServerEvent::Connection(addr) = ev {
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 mut buf = Vec::new();
PlanetPositionPacket {
planets,
}.serialize(&mut Serializer::new(&mut buf)).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 parts = HashMap::new();
for (entity, transform) in part_query.iter() {
let id = commands.entity(entity).id().index();
let translation = transform.translation;
parts.insert(id, (0, translation.x, translation.y)); // Type hearty = 0
}
let mut buf = Vec::new();
let packet = PartPositionPacket {
parts,
};
packet.serialize(&mut Serializer::new(&mut buf)).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),
});
}
let mut buf = Vec::new();
let packet = PlanetPositionPacket {
planets,
};
packet.serialize(&mut Serializer::new(&mut buf)).unwrap();
packet_send.send(ServerEvent::Broadcast(MessageType::Text, buf));
}