Skip to content

Commit

Permalink
feat: add killall
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewgazelka committed Mar 24, 2024
1 parent 1e70985 commit 785c1eb
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 18 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ RUN --mount=type=cache,target=/cargo-home \
--mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
--mount=type=cache,target=/app/target \
cargo build --release --locked -p server
CARGO_TERM_COLOR=never cargo build --release --locked -p server

RUN --mount=type=cache,target=/app/target \
mkdir -p /build && \
Expand All @@ -60,7 +60,7 @@ RUN --mount=type=cache,target=/cargo-home \
--mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
--mount=type=cache,target=/app/target \
cargo build --timings --locked -p server
CARGO_TERM_COLOR=never cargo build --timings --locked -p server

RUN --mount=type=cache,target=/app/target \
mkdir -p /build && \
Expand Down
11 changes: 4 additions & 7 deletions server/src/bounding_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use std::iter::Zip;
use evenio::{component::Component, entity::EntityId, fetch::Fetcher};
use fnv::FnvHashMap;
use smallvec::SmallVec;
use tracing::error;
use valence_protocol::math::{DVec2, DVec3, IVec2};

use crate::{EntityReaction, FullEntityPose};
Expand Down Expand Up @@ -160,14 +159,12 @@ impl EntityBoundingBoxes {
continue;
}

let (_, other_pose, _) = match fetcher.get(id) {
Ok(result) => result,
Err(e) => {
error!("Failed to get entity pose for id {id:?} ... {e} .. {e:?}");
continue;
}
let Ok((_, other_pose, _)) = fetcher.get(id) else {
// the entity is probably expired / has been removed
continue;
};


// todo: see which way ordering this has the most performance
if bounding.collides(other_pose.bounding) && !collisions_ids.contains(&id) {
collisions_ids.push(id);
Expand Down
30 changes: 27 additions & 3 deletions server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ struct KickPlayer {
reason: String,
}

#[derive(Event)]
struct KillAllEntities;

#[derive(Event)]
struct TpsEvent {
ms_per_tick: f64,
}

#[derive(Event)]
struct Gametick;

Expand All @@ -95,6 +103,8 @@ static GLOBAL: global::Global = global::Global {
struct Game {
world: World,
last_ticks: VecDeque<Instant>,
last_ms_per_tick: VecDeque<f64>,

incoming: flume::Receiver<ClientConnection>,
}

Expand Down Expand Up @@ -125,10 +135,11 @@ impl Game {
let now = Instant::now();
self.last_ticks.push_back(now);

// let mut tps = None;
if self.last_ticks.len() > HISTORY_SIZE {
let _front = self.last_ticks.pop_front().unwrap();
// let ticks_per_second = 100.0 / (now - front).as_secs_f64();
// info!("Ticks per second: {:?}", ticks_per_second);
// tps = Some(ticks_per_second);
}

while let Ok(connection) = self.incoming.try_recv() {
Expand All @@ -153,7 +164,17 @@ impl Game {

self.world.send(Gametick);

// let ms = now.elapsed().as_nanos() as f64 / 1_000_000.0;
let ms = now.elapsed().as_nanos() as f64 / 1_000_000.0;
self.last_ms_per_tick.push_back(ms);

if self.last_ms_per_tick.len() > HISTORY_SIZE {
self.last_ms_per_tick.pop_front().unwrap();

let ms_per_tick =
self.last_ms_per_tick.iter().sum::<f64>() / self.last_ms_per_tick.len() as f64;

self.world.send(TpsEvent { ms_per_tick });
}

// info!("Tick took: {:02.8}ms", ms);
}
Expand All @@ -163,7 +184,7 @@ impl Game {
fn process_packets(
_: Receiver<Gametick>,
mut fetcher: Fetcher<(EntityId, &mut Player, &mut FullEntityPose)>,
mut sender: Sender<(KickPlayer, InitEntity)>,
mut sender: Sender<(KickPlayer, InitEntity, KillAllEntities)>,
) {
// todo: flume the best things to use here? also this really ust needs to be mpsc not mpmc
// let (tx, rx) = flume::unbounded();
Expand Down Expand Up @@ -223,13 +244,16 @@ fn main() {

world.add_handler(system::keep_alive);
world.add_handler(process_packets);
world.add_handler(system::tps_message);
world.add_handler(system::kill_all);

let bounding_boxes = world.spawn();
world.insert(bounding_boxes, bounding_box::EntityBoundingBoxes::default());

let mut game = Game {
world,
last_ticks: VecDeque::default(),
last_ms_per_tick: VecDeque::default(),
incoming: server,
};

Expand Down
10 changes: 7 additions & 3 deletions server/src/packets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use evenio::event::Sender;
use tracing::{debug, warn};
use valence_protocol::{decode::PacketFrame, math::DVec3, packets::play, Decode, Packet};

use crate::{bounding_box::BoundingBox, FullEntityPose, InitEntity, KickPlayer, Player};
use crate::{bounding_box::BoundingBox, FullEntityPose, InitEntity, KickPlayer, KillAllEntities, Player};

fn confirm_teleport(_pkt: &[u8]) {
// ignore
Expand Down Expand Up @@ -141,13 +141,17 @@ fn chat_command(
mut data: &[u8],
player: &mut Player,
full_entity_pose: &FullEntityPose,
sender: &mut Sender<(KickPlayer, InitEntity)>,
sender: &mut Sender<(KickPlayer, InitEntity, KillAllEntities)>,
) -> anyhow::Result<()> {
let pkt = play::CommandExecutionC2s::decode(&mut data)?;

let mut cmd = pkt.command.0.split(' ');

let first = cmd.next();

if first == Some("killall") {
sender.send(KillAllEntities);
}

if first == Some("spawn") {
let args: Vec<_> = cmd.collect();
Expand Down Expand Up @@ -223,7 +227,7 @@ pub fn switch(
raw: PacketFrame,
player: &mut Player,
full_entity_pose: &mut FullEntityPose,
sender: &mut Sender<(KickPlayer, InitEntity)>,
sender: &mut Sender<(KickPlayer, InitEntity, KillAllEntities)>,
) -> anyhow::Result<()> {
let id = raw.id;
let data = raw.body;
Expand Down
5 changes: 5 additions & 0 deletions server/src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ mod keep_alive;
mod player_join_world;
mod player_kick;
mod reset_bounding_boxes;
mod tps_message;
mod kill_all;

pub use entity_detect_collisions::call as entity_detect_collisions;
pub use entity_move_logic::call as entity_move_logic;
Expand All @@ -15,3 +17,6 @@ pub use keep_alive::keep_alive;
pub use player_join_world::player_join_world;
pub use player_kick::player_kick;
pub use reset_bounding_boxes::call as reset_bounding_boxes;
pub use tps_message::call as tps_message;

pub use kill_all::kill_all as kill_all;
27 changes: 27 additions & 0 deletions server/src/system/kill_all.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use evenio::{prelude::*, rayon::prelude::*};
use valence_protocol::VarInt;

use crate::{KillAllEntities, MinecraftEntity, Player};

pub fn kill_all(
_r: ReceiverMut<KillAllEntities>,
entities: Fetcher<(EntityId, &MinecraftEntity, Not<&Player>)>,
mut players: Fetcher<&mut Player>,
mut s: Sender<Despawn>,
) {
let ids = entities.iter().map(|(id, ..)| id).collect::<Vec<_>>();

#[allow(clippy::cast_possible_wrap)]
let entity_ids = ids.iter().map(|id| VarInt(id.index().0 as i32)).collect();

let despawn_packet = valence_protocol::packets::play::EntitiesDestroyS2c { entity_ids };

players.par_iter_mut().for_each(|player| {
// todo: handle error
let _ = player.packets.writer.send_packet(&despawn_packet);
});

for &id in &ids {
s.send(Despawn(id));
}
}
16 changes: 13 additions & 3 deletions server/src/system/player_join_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ fn send_commands(io: &mut Packets) -> anyhow::Result<()> {
let root = Node {
data: NodeData::Root,
executable: false,
children: vec![VarInt(1)],
children: vec![VarInt(1), VarInt(3)],
redirect_node: None,
};

Expand All @@ -117,9 +117,19 @@ fn send_commands(io: &mut Packets) -> anyhow::Result<()> {
children: vec![],
redirect_node: None,
};

// id 3 = "killall"
let clear = Node {
data: NodeData::Literal {
name: "killall".to_owned(),
},
executable: true,
children: vec![],
redirect_node: None,
};

io.writer.send_packet(&play::CommandTreeS2c {
commands: vec![root, spawn, spawn_arg],
io.writer.send_packet(&CommandTreeS2c {
commands: vec![root, spawn, spawn_arg, clear],
root_index: VarInt(0),
})?;

Expand Down
20 changes: 20 additions & 0 deletions server/src/system/tps_message.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use evenio::prelude::*;
use evenio::rayon::prelude::*;

use crate::{Player, TpsEvent};

pub fn call(
r: Receiver<TpsEvent>,
mut players: Fetcher<&mut Player>,
) {
let ms_per_tick = r.event.ms_per_tick;

// with 4 zeroes
// lead 2 zeroes
let message = format!("MSPT: {ms_per_tick:07.4}");

players.par_iter_mut().for_each(|player| {
// todo: handle error
let _ = player.packets.writer.send_chat_message(&message);
});
}

0 comments on commit 785c1eb

Please sign in to comment.