add arguments, flake package

This commit is contained in:
Aubrey 2024-12-20 20:35:43 -06:00
parent c3f6a120df
commit 9d13b5c04a
No known key found for this signature in database
7 changed files with 237 additions and 108 deletions

1
.gitignore vendored
View file

@ -2,3 +2,4 @@
/.direnv
*.pem
*.p12
/result

156
Cargo.lock generated
View file

@ -32,12 +32,55 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3aa2999eb46af81abb65c2d30d446778d7e613b60bbf4e174a027e80f90a3c14"
[[package]]
name = "anstream"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anstyle-parse"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
dependencies = [
"anstyle",
"windows-sys 0.59.0",
]
[[package]]
name = "anyhow"
version = "1.0.94"
@ -166,9 +209,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "bytemuck"
version = "1.20.0"
version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a"
checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
[[package]]
name = "byteorder"
@ -193,9 +236,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.2.4"
version = "1.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf"
checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e"
dependencies = [
"shlex",
]
@ -219,6 +262,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
@ -227,11 +271,24 @@ version = "4.5.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.90",
]
[[package]]
name = "clap_lex"
version = "0.7.4"
@ -248,6 +305,12 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "colorchoice"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "core-foundation"
version = "0.10.0"
@ -294,9 +357,9 @@ dependencies = [
[[package]]
name = "cxx"
version = "1.0.134"
version = "1.0.135"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5a32d755fe20281b46118ee4b507233311fb7a48a0cfd42f554b93640521a2f"
checksum = "4d44ff199ff93242c3afe480ab588d544dd08d72e92885e152ffebc670f076ad"
dependencies = [
"cc",
"cxxbridge-cmd",
@ -308,9 +371,9 @@ dependencies = [
[[package]]
name = "cxx-build"
version = "1.0.134"
version = "1.0.135"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11645536ada5d1c8804312cbffc9ab950f2216154de431de930da47ca6955199"
checksum = "66fd8f17ad454fc1e4f4ab83abffcc88a532e90350d3ffddcb73030220fcbd52"
dependencies = [
"cc",
"codespan-reporting",
@ -322,9 +385,9 @@ dependencies = [
[[package]]
name = "cxxbridge-cmd"
version = "1.0.134"
version = "1.0.135"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebcc9c78e3c7289665aab921a2b394eaffe8bdb369aa18d81ffc0f534fd49385"
checksum = "4717c9c806a9e07fdcb34c84965a414ea40fafe57667187052cf1eb7f5e8a8a9"
dependencies = [
"clap",
"codespan-reporting",
@ -335,15 +398,15 @@ dependencies = [
[[package]]
name = "cxxbridge-flags"
version = "1.0.134"
version = "1.0.135"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a22a87bd9e78d7204d793261470a4c9d585154fddd251828d8aefbb5f74c3bf"
checksum = "2f6515329bf3d98f4073101c7866ff2bec4e635a13acb82e3f3753fff0bf43cb"
[[package]]
name = "cxxbridge-macro"
version = "1.0.134"
version = "1.0.135"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dfdb020ff8787c5daf6e0dca743005cc8782868faeadfbabb8824ede5cb1c72"
checksum = "fb93e6a7ce8ec985c02bbb758237a31598b340acbbc3c19c5a4fa6adaaac92ab"
dependencies = [
"proc-macro2",
"quote",
@ -421,9 +484,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "foldhash"
version = "0.1.3"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2"
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
[[package]]
name = "form_urlencoded"
@ -518,6 +581,12 @@ dependencies = [
"stable_deref_trait",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "httlib-huffman"
version = "0.3.4"
@ -673,6 +742,12 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itoa"
version = "1.0.14"
@ -703,9 +778,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.168"
version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "link-cplusplus"
@ -751,9 +826,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.8.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394"
dependencies = [
"adler2",
]
@ -965,7 +1040,7 @@ dependencies = [
"rustc-hash",
"rustls",
"socket2",
"thiserror 2.0.7",
"thiserror 2.0.8",
"tokio",
"tracing",
]
@ -984,7 +1059,7 @@ dependencies = [
"rustls",
"rustls-pki-types",
"slab",
"thiserror 2.0.7",
"thiserror 2.0.8",
"tinyvec",
"tracing",
"web-time",
@ -992,9 +1067,9 @@ dependencies = [
[[package]]
name = "quinn-udp"
version = "0.5.8"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52cd4b1eff68bf27940dd39811292c49e007f4d0b4c357358dc9b0197be6b527"
checksum = "1c40286217b4ba3a71d644d752e6a0b71f13f1b6a2c5311acfcbe0c2418ed904"
dependencies = [
"cfg_aliases",
"libc",
@ -1045,9 +1120,9 @@ dependencies = [
[[package]]
name = "rcgen"
version = "0.13.1"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54077e1872c46788540de1ea3d7f4ccb1983d12f9aa909b234468676c1a36779"
checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2"
dependencies = [
"pem",
"ring",
@ -1251,9 +1326,9 @@ checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152"
[[package]]
name = "security-framework"
version = "3.0.1"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1415a607e92bec364ea2cf9264646dcce0f91e6d65281bd6f2819cca3bf39c8"
checksum = "81d3f8c9bfcc3cbb6b0179eb57042d75b1582bdc65c3cb95f3fa999509c03cbc"
dependencies = [
"bitflags",
"core-foundation",
@ -1264,9 +1339,9 @@ dependencies = [
[[package]]
name = "security-framework-sys"
version = "2.12.1"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2"
checksum = "1863fd3768cd83c56a7f60faa4dc0d403f1b6df0a38c3c25f44b7894e45370d5"
dependencies = [
"core-foundation-sys",
"libc",
@ -1367,6 +1442,7 @@ name = "smo-server"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"crc32fast",
"glam",
"heapless",
@ -1474,11 +1550,11 @@ dependencies = [
[[package]]
name = "thiserror"
version = "2.0.7"
version = "2.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93605438cbd668185516ab499d589afb7ee1859ea3d5fc8f6b0755e1c7443767"
checksum = "08f5383f3e0071702bf93ab5ee99b52d26936be9dedd9413067cbdcddcb6141a"
dependencies = [
"thiserror-impl 2.0.7",
"thiserror-impl 2.0.8",
]
[[package]]
@ -1494,9 +1570,9 @@ dependencies = [
[[package]]
name = "thiserror-impl"
version = "2.0.7"
version = "2.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1d8749b4531af2117677a5fcd12b1348a3fe2b81e36e61ffeac5c4aa3273e36"
checksum = "f2f357fcec90b3caef6623a099691be676d033b40a058ac95d2a6ade6fa0c943"
dependencies = [
"proc-macro2",
"quote",
@ -1556,9 +1632,9 @@ dependencies = [
[[package]]
name = "tinyvec"
version = "1.8.0"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938"
checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8"
dependencies = [
"tinyvec_macros",
]
@ -1721,6 +1797,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.11.0"

View file

@ -5,6 +5,7 @@ edition = "2021"
[dependencies]
anyhow = { version = "1.0.94", features = ["backtrace"] }
clap = { version = "4.5.23", features = ["derive"] }
crc32fast = "1.4.2"
glam = "0.29.2"
heapless = "0.8.0"

View file

@ -7,27 +7,46 @@
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, flake-utils, fenix }:
outputs = {
self,
nixpkgs,
flake-utils,
fenix,
}:
flake-utils.lib.eachDefaultSystem
(system:
let
overlays = [ fenix.overlays.default ];
pkgs = import nixpkgs {
inherit system overlays;
};
in
with pkgs;
{
(
system: let
overlays = [fenix.overlays.default];
pkgs = import nixpkgs {
inherit system overlays;
};
in
with pkgs; {
devShells.default = mkShell {
buildInputs = [
pkgs.fenix.stable.completeToolchain
cmake
pkg-config
openssl
alsa-lib
ffmpeg
];
};
formatter = pkgs.alejandra;
packages.default = rustPlatform.buildRustPackage {
name = "smo-server";
src = ./.;
nativeBuildInputs = [pkg-config cmake];
buildInputs = [openssl];
cargoDeps = rustPlatform.importCargoLock {
lockFile = ./Cargo.lock;
outputHashes = {
"newtype-enum-0.1.0" = "sha256-DBFSgtuwn51U3nvSxa0SQZKEHniC4UFVBHIeQjkXAvw=";
};
};
};
# nixosModules.default = { config }: with pkgs.lib {
# options.services.smo-server = {
# enable = mkEnableOption ""
# };
# }
}
);
);
}

View file

@ -8,10 +8,12 @@ pub mod server;
use std::{
collections::HashMap,
io::Cursor,
net::{SocketAddr, ToSocketAddrs},
sync::{Arc, LazyLock},
net::{IpAddr, Ipv4Addr, SocketAddr, ToSocketAddrs},
path::PathBuf,
sync::{Arc, LazyLock, OnceLock},
};
use clap::Parser;
use faker::Faker;
use packet::{rw::read_packet, Packet};
use player::PlayerActor;
@ -31,13 +33,26 @@ pub fn clients() -> &'static RwLock<HashMap<u128, (PacketChannel, SocketAddr)>>
&CLIENTS
}
static MANAGER: OnceLock<Address<Manager>> = OnceLock::new();
pub fn manager() -> &'static Address<Manager> {
static MANAGER: LazyLock<Address<Manager>> = LazyLock::new(web_main);
&MANAGER
&MANAGER.get().unwrap()
}
#[derive(clap::Parser)]
struct Arguments {
#[arg(short, long, default_value_t = 1027)]
tcp_port: u16,
#[arg(short, long, default_value_t = 1027)]
udp_port: u16,
#[arg(short, long, default_value_t = 4433)]
prox_port: u16,
#[arg(long, default_value = "./cert.pem")]
prox_cert: PathBuf,
#[arg(long, default_value = "./key.pem")]
prox_key: PathBuf,
#[arg(long)]
enable_faker: bool,
}
#[tokio::main]
async fn main() {
@ -46,9 +61,17 @@ async fn main() {
*meta.level() < Level::INFO || meta.module_path().unwrap().contains("smo_server")
})))
.init();
let tcp = TcpListener::bind("0.0.0.0:1027").await.unwrap();
let arguments = Arguments::parse();
{
MANAGER.set(web_main(arguments.prox_port, arguments.prox_cert, arguments.prox_key).await).unwrap();
let tcp = TcpListener::bind(SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), arguments.tcp_port))
.await
.expect("failed to bind tcp listener");
if arguments.enable_faker {
// spawn test bot
info!("spawning faker for testing!");
let (address, mailbox) = Mailbox::unbounded();
let address = xtra::spawn_tokio(
Faker {
@ -60,35 +83,22 @@ async fn main() {
1,
(
MessageChannel::new(address),
"0.0.0.0:1027".to_socket_addrs().unwrap().next().unwrap(),
"0.0.0.0:0".to_socket_addrs().unwrap().next().unwrap(),
),
);
}
let socket = Arc::new(UdpSocket::bind("0.0.0.0:1027").await.unwrap());
tokio::spawn({
let socket = socket.clone();
async move {
loop {
let mut packet = [0u8; 256];
let (size, _addr) = socket.recv_from(&mut packet).await.unwrap();
// trace!("got packet from {_addr:?}");
match read_packet(&mut Cursor::new(&mut packet[..size]), true).await {
Ok(packet) => {
// info!("packet from udp {packet:?}");
if let Some(client) = clients().read().await.get(&packet.user_id) {
let _ = client.0.send(packet).detach().await;
}
}
Err(error) => {
error!("udp packet error: {error:?}");
}
};
}
}
});
let socket = Arc::new(
UdpSocket::bind(SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), arguments.udp_port))
.await
.expect("failed to bind udp socket"),
);
tokio::spawn(udp_server(socket.clone()));
info!("listening on port 1027");
info!(
"listening on tcp port {}, udp port {}",
arguments.tcp_port, arguments.udp_port
);
loop {
match tcp.accept().await {
Ok((stream, addr)) => {
@ -100,3 +110,22 @@ async fn main() {
}
}
}
async fn udp_server(socket: Arc<UdpSocket>) {
loop {
let mut packet = [0u8; 256];
let (size, _addr) = socket.recv_from(&mut packet).await.unwrap();
// trace!("got packet from {_addr:?}");
match read_packet(&mut Cursor::new(&mut packet[..size]), true).await {
Ok(packet) => {
// info!("packet from udp {packet:?}");
if let Some(client) = clients().read().await.get(&packet.user_id) {
let _ = client.0.send(packet).detach().await;
}
}
Err(error) => {
error!("udp packet error: {error:?}");
}
};
}
}

View file

@ -69,6 +69,7 @@ pub struct PlayerActor {
connection_kind: ConnectionKind,
name: String<CLIENT_NAME_SIZE>,
write_sender: mpsc::UnboundedSender<WriteMessage>,
udp_port: u16,
}
enum WriteMessage {
@ -98,6 +99,8 @@ impl PlayerActor {
.await
.expect("msfrarausfhsdagsdgkog");
let udp_port = socket.local_addr().unwrap().port();
let span = info_span!("Client", player = connect.client_name.to_string());
let (address, mailbox) = Mailbox::bounded(512);
let (sender, mut receiver) = mpsc::unbounded_channel();
@ -138,7 +141,7 @@ impl PlayerActor {
}
}
WriteMessage::SetUdp(port) => {
trace!("set udp port, connected on udp!");
trace!("now connected on udp!");
addr = Some(SocketAddr::new(ip, port))
}
}
@ -177,6 +180,7 @@ impl PlayerActor {
connection_kind: connect.kind,
name: connect.client_name,
write_sender: sender,
udp_port
},
)
.instrument(span)
@ -204,7 +208,7 @@ impl Actor for PlayerActor {
.send(WriteMessage::Data(Packet {
user_id: 0,
udp: false,
data: PacketData::UdpInit(UdpInit { port: 1027 }),
data: PacketData::UdpInit(UdpInit { port: self.udp_port }),
}))
.map_err(drop)?;
@ -226,14 +230,12 @@ impl Handler<Packet> for PlayerActor {
async fn handle(&mut self, packet: Packet, _: &mut xtra::Context<Self>) {
if matches!(packet.data, PacketData::HolePunch(..)) {
trace!("hole puncher");
return;
}
if packet.user_id == self.id {
match packet.data {
PacketData::UdpInit(UdpInit { port }) => {
trace!("hole puncher");
let _ = self.write_sender.send(WriteMessage::SetUdp(port));
let _ = self.write_sender.send(WriteMessage::Data(Packet {
user_id: 0,

View file

@ -1,10 +1,10 @@
mod prox;
use std::{collections::HashMap, sync::LazyLock};
use std::{collections::HashMap, path::PathBuf, sync::LazyLock};
use prox::{packet::HYP_UUID_SIZE, ProximityPlayer};
use tokio::sync::RwLock;
use tracing::{error, info_span, Instrument};
use tracing::{info, info_span, Instrument};
use wtransport::{Endpoint, Identity, ServerConfig};
use xtra::{Actor, Address, Handler, Mailbox};
use zerocopy::{FromZeros, Immutable, IntoBytes};
@ -22,8 +22,16 @@ fn listeners() -> &'static RwLock<HashMap<UuidString, Address<ProximityPlayer>>>
&LISTENERS
}
pub fn web_main() -> Address<Manager> {
let span = info_span!("wt");
pub async fn web_main(
port: u16,
cert: PathBuf,
key: PathBuf,
) -> Address<Manager> {
let span = info_span!("prox");
info!(parent: &span, "reading pems from {{ cert: {cert:?}, key: {key:?} }}");
let identity = Identity::load_pemfiles(cert, key).await.expect("failed to create identity from proximity pems");
let config = ServerConfig::builder().with_bind_default(port).with_identity(identity).build();
let endpoint = Endpoint::server(config).expect("failed to build proximity endpoint");
let manager = xtra::spawn_tokio(
Manager {
@ -35,8 +43,10 @@ pub fn web_main() -> Address<Manager> {
tokio::spawn({
let manager = manager.clone();
async move {
if let Err(result) = webtransport_server(manager).await {
error!("{:?}", result);
loop {
let connection = endpoint.accept().await;
ProximityPlayer::spawn(connection, manager.clone());
}
}
.instrument(span)
@ -44,21 +54,6 @@ pub fn web_main() -> Address<Manager> {
manager
}
async fn webtransport_server(manager: Address<Manager>) -> anyhow::Result<()> {
// let identity = Identity::self_signed(["localhost", "127.0.0.1", "::1"]).unwrap();
let identity = Identity::load_pemfiles("./cert.pem", "./key.pem").await.unwrap();
let config = ServerConfig::builder().with_bind_default(4433).with_identity(identity).build();
let endpoint = Endpoint::server(config)?;
loop {
let connection = endpoint.accept().await;
ProximityPlayer::spawn(connection, manager.clone());
}
}
#[derive(Actor)]
pub struct Manager {
players: HashMap<u128, PlayerInstance>,