Skip to content

Commit ef72391

Browse files
authored
Merge pull request #209 from radstevee/feat/lan_pinging
feat: lan pinging
2 parents 166626a + c6dc32a commit ef72391

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

src/bin/src/game_loop.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::errors::BinaryError;
22
use crate::packet_handlers::{play_packets, register_player_systems};
33
use crate::register_events::register_events;
44
use crate::register_resources::register_resources;
5+
use crate::systems::lan_pinger::LanPinger;
56
use crate::systems::register_game_systems;
67
use crate::systems::shutdown_systems::register_shutdown_systems;
78
use bevy_ecs::prelude::World;
@@ -19,6 +20,7 @@ use ferrumc_utils::formatting::format_duration;
1920
use play_packets::register_packet_handlers;
2021
use std::sync::Arc;
2122
use std::time::{Duration, Instant};
23+
use tokio::time::sleep;
2224
use tracing::{debug, error, info, info_span, trace, warn, Instrument};
2325

2426
pub fn start_game_loop(global_state: GlobalState) -> Result<(), BinaryError> {
@@ -214,6 +216,17 @@ fn tcp_conn_acceptor(
214216
.enable_all()
215217
.thread_name("Tokio-Async-Network")
216218
.build()?;
219+
async_runtime.spawn(async move {
220+
let Ok(mut pinger) = LanPinger::new().await else {
221+
error!("Failed creating LAN pinger");
222+
return
223+
};
224+
225+
loop {
226+
pinger.send().await;
227+
sleep(Duration::from_millis(1500)).await;
228+
}
229+
});
217230
async_runtime.block_on({
218231
let state = Arc::clone(&state);
219232
async move {

src/bin/src/systems/lan_pinger.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use ferrumc_config::server_config::get_global_config;
2+
use rand::prelude::IndexedRandom;
3+
use std::net::{Ipv4Addr, SocketAddrV4};
4+
use tokio::net::UdpSocket;
5+
use tracing::error;
6+
7+
pub struct LanPinger {
8+
socket: UdpSocket,
9+
addr: SocketAddrV4,
10+
}
11+
12+
impl LanPinger {
13+
pub async fn new() -> std::io::Result<Self> {
14+
const ADDR: Ipv4Addr = Ipv4Addr::new(224, 0, 2, 60); // mojang's UDP multicast address
15+
const PORT: u16 = 4445;
16+
17+
Ok(Self {
18+
socket: UdpSocket::bind("0.0.0.0:0").await?,
19+
addr: SocketAddrV4::new(ADDR, PORT),
20+
})
21+
}
22+
23+
pub fn announcement(&self) -> String {
24+
let cfg = get_global_config();
25+
let motd = cfg.motd.choose(&mut rand::rng()).unwrap();
26+
let port = cfg.port;
27+
28+
format!("[MOTD]{motd}[/MOTD][AD]{port}[/AD]")
29+
}
30+
31+
pub async fn send(&mut self) {
32+
let announcement = self.announcement();
33+
34+
if let Err(err) = self
35+
.socket
36+
.send_to(announcement.as_bytes(), self.addr)
37+
.await
38+
{
39+
error!("Failed sending LAN UDP Packet: {err}")
40+
}
41+
}
42+
}

src/bin/src/systems/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pub mod connection_killer;
22
mod cross_chunk_boundary;
33
pub mod keep_alive_system;
4+
pub mod lan_pinger;
45
mod mq;
56
pub mod new_connections;
67
pub mod player_count_update;

0 commit comments

Comments
 (0)