aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Alexander Foremny <aforemny@posteo.de>2024-03-15 06:15:41 +0100
committerLibravatar Alexander Foremny <aforemny@posteo.de>2024-03-15 08:47:41 +0100
commit1e162629da53373f0e2502014d42c7636412e67e (patch)
tree0fd311e28042ebee4f1f3df4cb97063c6bb4eafc
parentaa6901736da520d4608adfb74b8bc0a8a9e121a8 (diff)
chore: release
-rw-r--r--Cargo.lock117
-rw-r--r--Cargo.toml7
-rw-r--r--README.md14
-rw-r--r--agame.nix31
-rw-r--r--default.nix5
-rw-r--r--src/client.rs73
-rw-r--r--src/client/network.rs7
-rw-r--r--src/main.rs51
-rw-r--r--src/shared.rs1
9 files changed, 264 insertions, 42 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 337fd1b..ecc189f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -102,6 +102,7 @@ name = "agame"
version = "0.1.0"
dependencies = [
"bevy",
+ "clap",
"crossbeam-channel",
"lightyear",
"rand",
@@ -206,6 +207,54 @@ dependencies = [
]
[[package]]
+name = "anstream"
+version = "0.6.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
+dependencies = [
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
+dependencies = [
+ "anstyle",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
name = "anyhow"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1419,6 +1468,46 @@ dependencies = [
]
[[package]]
+name = "clap"
+version = "4.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651"
+dependencies = [
+ "clap_builder",
+ "clap_derive",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "clap_lex",
+ "strsim 0.11.0",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.52",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
+
+[[package]]
name = "codespan-reporting"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1435,6 +1524,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
+name = "colorchoice"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
+
+[[package]]
name = "com"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1697,7 +1792,7 @@ dependencies = [
"ident_case",
"proc-macro2",
"quote",
- "strsim",
+ "strsim 0.10.0",
"syn 2.0.52",
]
@@ -2169,7 +2264,7 @@ dependencies = [
"vec_map",
"wasm-bindgen",
"web-sys",
- "windows 0.54.0",
+ "windows 0.48.0",
]
[[package]]
@@ -2388,6 +2483,12 @@ dependencies = [
]
[[package]]
+name = "heck"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+
+[[package]]
name = "hexasphere"
version = "10.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3739,6 +3840,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
+name = "strsim"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
+
+[[package]]
name = "subtle"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4019,6 +4126,12 @@ dependencies = [
]
[[package]]
+name = "utf8parse"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
+
+[[package]]
name = "uuid"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 7662bce..d406033 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,12 +4,17 @@ version = "0.1.0"
edition = "2021"
[dependencies]
-bevy = { version = "0.13.0", features = ["dynamic_linking"] }
+bevy = { version = "0.13.0" }
+clap = { version = "4.5.2", features = ["derive"] }
crossbeam-channel = { version = "0.5.12" }
lightyear = { version = "0.12.0" }
rand = { version = "0.8.5" }
serde = { version = "1.0.197" }
+[features]
+default = ["fast-compile"]
+fast-compile = ["bevy/dynamic_linking"]
+
[profile.dev]
opt-level = 1
diff --git a/README.md b/README.md
index 99ae3c7..239d5a2 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,18 @@
cargo run
```
+## run client (multi player)
+
+```console
+cargo run -- --connect-to 49.13.201.137:16384
+```
+
+## run server (headless)
+
+```console
+cargo run -- --server
+```
+
## controls
-- **left mouse** teleport
+- **left mouse** walk / attack
diff --git a/agame.nix b/agame.nix
new file mode 100644
index 0000000..993d768
--- /dev/null
+++ b/agame.nix
@@ -0,0 +1,31 @@
+{ alsa-lib
+, lib
+, libxkbcommon
+, pkg-config
+, rustPlatform
+, udev
+, vulkan-loader
+, wayland
+, xorg
+}:
+rustPlatform.buildRustPackage rec {
+ name = "agame";
+ src = ./.;
+ cargoLock.lockFile = ./Cargo.lock;
+ buildNoDefaultFeatures = true;
+ nativeBuildInputs = [
+ pkg-config
+ ];
+ buildInputs = [
+ alsa-lib
+ libxkbcommon
+ udev
+ vulkan-loader
+ wayland
+ xorg.libX11
+ xorg.libXcursor
+ xorg.libXi
+ xorg.libXrandr
+ ];
+ doCheck = false;
+}
diff --git a/default.nix b/default.nix
new file mode 100644
index 0000000..118527b
--- /dev/null
+++ b/default.nix
@@ -0,0 +1,5 @@
+{ pkgs ? import (import ./nix/sources.nix).nixpkgs { }
+}:
+{
+ agame = pkgs.callPackage ./agame.nix { };
+}
diff --git a/src/client.rs b/src/client.rs
index 8793c4a..a5a7845 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -8,6 +8,7 @@ use bevy::prelude::*;
use bevy::sprite::{MaterialMesh2dBundle, Mesh2dHandle};
use lightyear::client::input::InputSystemSet;
use lightyear::prelude::*;
+use std::net::SocketAddr;
mod network;
@@ -15,30 +16,42 @@ const PLAYER_RADIUS: f32 = 10.;
const PLAYER_HOVER_INDICATOR_RADIUS: f32 = 13.;
const PLAYER_HOVER_RADIUS: f32 = 20.;
-pub fn main(transport: TransportConfig) {
+pub fn main(server_addr: Option<SocketAddr>, client_id: u64, transport: TransportConfig) {
App::new()
.add_plugins(DefaultPlugins)
- .add_plugins(ClientPlugin { transport })
+ .add_plugins(ClientPlugin {
+ server_addr,
+ client_id,
+ transport,
+ })
.run();
}
+#[derive(Resource)]
+struct ClientId(pub u64);
+
struct ClientPlugin {
+ pub server_addr: Option<SocketAddr>,
+ pub client_id: u64,
pub transport: TransportConfig,
}
impl Plugin for ClientPlugin {
fn build(&self, app: &mut App) {
- app.add_plugins(NetworkPlugin {
- transport: self.transport.clone(),
- })
- .add_systems(Startup, setup)
- .add_systems(Update, (render_players, render_projectiles))
- .add_systems(Update, (move_players, move_projectiles))
- .add_systems(
- FixedPreUpdate,
- buffer_input.in_set(InputSystemSet::BufferInputs),
- )
- .add_systems(Last, (gizmos_hover_indicator, gizmos_attack_indicator));
+ app.insert_resource(ClientId(self.client_id))
+ .add_plugins(NetworkPlugin {
+ server_addr: self.server_addr.clone(),
+ client_id: self.client_id,
+ transport: self.transport.clone(),
+ })
+ .add_systems(Startup, setup)
+ .add_systems(Update, (render_players, render_projectiles))
+ .add_systems(Update, (move_players, move_projectiles))
+ .add_systems(
+ FixedPreUpdate,
+ buffer_input.in_set(InputSystemSet::BufferInputs),
+ )
+ .add_systems(Last, (gizmos_hover_indicator, gizmos_attack_indicator));
}
}
@@ -98,12 +111,15 @@ fn move_players(mut players: Query<(&mut Transform, &PlayerPosition), Changed<Pl
fn buffer_input(
attackables: Query<(&PlayerId, &PlayerPosition)>,
cameras: Query<(&Camera, &GlobalTransform)>,
+ client_id: Res<ClientId>,
mouse_input: Res<ButtonInput<MouseButton>>,
mut client: ClientMut,
windows: Query<&Window>,
) {
if mouse_input.just_pressed(MouseButton::Left) {
- if let Some((target_player, _)) = hovered_other_player(&windows, &cameras, &attackables) {
+ if let Some((target_player, _)) =
+ hovered_other_player(&cameras, &client_id, &attackables, &windows)
+ {
client.add_input(Inputs::Imperative(Imperative::Attack(target_player)));
} else {
if let Some(world_position) = cursor_world_position(&windows, &cameras) {
@@ -114,12 +130,14 @@ fn buffer_input(
}
fn gizmos_hover_indicator(
- mut gizmos: Gizmos,
- hoverables: Query<(&PlayerId, &PlayerPosition)>,
cameras: Query<(&Camera, &GlobalTransform)>,
+ client_id: Res<ClientId>,
+ hoverables: Query<(&PlayerId, &PlayerPosition)>,
+ mut gizmos: Gizmos,
windows: Query<&Window>,
) {
- let Some((_, position)) = hovered_other_player(&windows, &cameras, &hoverables) else {
+ let Some((_, position)) = hovered_other_player(&cameras, &client_id, &hoverables, &windows)
+ else {
return;
};
gizmos.circle_2d(position.0, PLAYER_HOVER_INDICATOR_RADIUS, Color::GREEN);
@@ -138,23 +156,24 @@ fn cursor_world_position(
}
fn hovered_other_player(
- windows: &Query<&Window>,
cameras: &Query<(&Camera, &GlobalTransform)>,
+ client_id: &Res<ClientId>,
hoverables: &Query<(&PlayerId, &PlayerPosition)>,
+ windows: &Query<&Window>,
) -> Option<(PlayerId, PlayerPosition)> {
- let Some((id, position)) = hovered_player(windows, cameras, hoverables) else {
+ let Some((id, position)) = hovered_player(cameras, hoverables, windows) else {
return None;
};
- if id.0 == 0 {
+ if id.0 == client_id.0 {
return None;
}
Some((id, position))
}
fn hovered_player(
- windows: &Query<&Window>,
cameras: &Query<(&Camera, &GlobalTransform)>,
hoverables: &Query<(&PlayerId, &PlayerPosition)>,
+ windows: &Query<&Window>,
) -> Option<(PlayerId, PlayerPosition)> {
let Some(world_position) = cursor_world_position(&windows, &cameras) else {
return None;
@@ -170,22 +189,26 @@ fn hovered_player(
fn gizmos_attack_indicator(
cameras: Query<(&Camera, &GlobalTransform)>,
+ client_id: Res<ClientId>,
hoverables: Query<(&PlayerId, &PlayerPosition)>,
mut gizmos: Gizmos,
players: Query<(&PlayerId, &PlayerPosition)>,
windows: Query<&Window>,
) {
- let Some(position) = player_position(&players) else {
+ let Some(position) = player_position(&client_id, &players) else {
return;
};
- if hovered_other_player(&windows, &cameras, &hoverables).is_some() {
+ if hovered_other_player(&cameras, &client_id, &hoverables, &windows).is_some() {
gizmos.circle_2d(position.0, ATTACK_RANGE, Color::YELLOW);
}
}
-fn player_position(players: &Query<(&PlayerId, &PlayerPosition)>) -> Option<PlayerPosition> {
+fn player_position(
+ client_id: &Res<ClientId>,
+ players: &Query<(&PlayerId, &PlayerPosition)>,
+) -> Option<PlayerPosition> {
for (id, position) in players.iter() {
- if id.0 == 0 {
+ if id.0 == client_id.0 {
return Some(*position);
}
}
diff --git a/src/client/network.rs b/src/client/network.rs
index 4d1a128..df55cc9 100644
--- a/src/client/network.rs
+++ b/src/client/network.rs
@@ -8,8 +8,11 @@ use lightyear::client::resource::Authentication;
use lightyear::prelude::client::NetConfig;
use lightyear::prelude::*;
use lightyear::transport::LOCAL_SOCKET;
+use std::net::SocketAddr;
pub struct NetworkPlugin {
+ pub server_addr: Option<SocketAddr>,
+ pub client_id: u64,
pub transport: TransportConfig,
}
@@ -20,8 +23,8 @@ impl Plugin for NetworkPlugin {
net: NetConfig::Netcode {
config: Default::default(),
auth: Authentication::Manual {
- server_addr: LOCAL_SOCKET,
- client_id: CLIENT_ID,
+ server_addr: self.server_addr.unwrap_or(LOCAL_SOCKET),
+ client_id: self.client_id,
private_key: KEY,
protocol_id: PROTOCOL_ID,
},
diff --git a/src/main.rs b/src/main.rs
index cdd7c17..f213197 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,6 @@
+use clap::Parser;
use lightyear::transport::io::TransportConfig;
+use rand::Rng;
use shared::SERVER_PORT;
use std::net::Ipv4Addr;
use std::net::SocketAddr;
@@ -9,19 +11,48 @@ mod protocol;
mod server;
mod shared;
+#[derive(Parser, Debug)]
+struct Cli {
+ #[arg(long, value_name = "HOST:PORT")]
+ connect_to: Option<SocketAddr>,
+ #[arg(long, num_args = 0)]
+ server: bool,
+}
+
fn main() {
- let (from_server_send, from_server_recv) = crossbeam_channel::unbounded();
- let (to_server_send, to_server_recv) = crossbeam_channel::unbounded();
+ let cli = Cli::parse();
+
+ let mut rng = rand::thread_rng();
+ let client_id = rng.gen_range(1..=SERVER_PORT);
- thread::spawn(|| {
+ if cli.connect_to.is_some() && cli.server {
+ panic!("cannot specify both `--connect-to` and `--server`");
+ }
+
+ if cli.server {
let server_addr = SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), SERVER_PORT);
- server::main(TransportConfig::Channels {
- channels: [(server_addr, to_server_recv, from_server_send)].to_vec(),
+ server::main(TransportConfig::UdpSocket(server_addr));
+ } else if let Some(server_addr) = cli.connect_to {
+ let client_addr = SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), SERVER_PORT + client_id);
+ client::main(Some(server_addr), client_id as u64, TransportConfig::UdpSocket(client_addr));
+ } else {
+ let (from_server_send, from_server_recv) = crossbeam_channel::unbounded();
+ let (to_server_send, to_server_recv) = crossbeam_channel::unbounded();
+
+ thread::spawn(|| {
+ let server_addr = SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), SERVER_PORT);
+ server::main(TransportConfig::Channels {
+ channels: [(server_addr, to_server_recv, from_server_send)].to_vec(),
+ });
});
- });
- client::main(TransportConfig::LocalChannel {
- recv: from_server_recv,
- send: to_server_send,
- });
+ client::main(
+ None,
+ client_id as u64,
+ TransportConfig::LocalChannel {
+ recv: from_server_recv,
+ send: to_server_send,
+ },
+ );
+ }
}
diff --git a/src/shared.rs b/src/shared.rs
index 4db5224..b3a7cc4 100644
--- a/src/shared.rs
+++ b/src/shared.rs
@@ -11,7 +11,6 @@ pub mod cooldown;
pub mod imperative;
pub mod projectile;
-pub const CLIENT_ID: u64 = 0;
pub const KEY: [u8; 32] = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];