2023-10-29 20:49:01 +01:00
|
|
|
use bevy::prelude::*;
|
2023-10-30 14:25:05 +01:00
|
|
|
use std::{net::UdpSocket, time::SystemTime};
|
2023-10-29 20:49:01 +01:00
|
|
|
|
2023-10-31 16:29:05 +01:00
|
|
|
use bevy_renet::{
|
|
|
|
|
renet::{transport::ClientAuthentication, ConnectionConfig, RenetClient},
|
|
|
|
|
transport::NetcodeClientPlugin,
|
|
|
|
|
RenetClientPlugin,
|
2023-10-29 20:49:01 +01:00
|
|
|
};
|
2023-10-31 16:29:05 +01:00
|
|
|
use renet::transport::{NetcodeClientTransport, NetcodeTransportError, NETCODE_USER_DATA_BYTES};
|
2023-10-29 20:49:01 +01:00
|
|
|
|
|
|
|
|
// This id needs to be the same as the server is using
|
|
|
|
|
const PROTOCOL_ID: u64 = 2878;
|
|
|
|
|
|
2022-12-01 18:04:03 +01:00
|
|
|
fn main() {
|
2023-10-29 20:49:01 +01:00
|
|
|
// Get username from stdin args
|
|
|
|
|
let args = std::env::args().collect::<Vec<String>>();
|
|
|
|
|
let username = &args[1];
|
|
|
|
|
|
2023-10-31 14:32:21 +01:00
|
|
|
let (client, transport) = new_renet_client(&username).unwrap();
|
2023-10-29 20:49:01 +01:00
|
|
|
App::new()
|
|
|
|
|
// Lets add a nice dark grey background color
|
|
|
|
|
.insert_resource(ClearColor(Color::hex("282828").unwrap()))
|
2023-10-30 14:25:05 +01:00
|
|
|
.add_plugins(DefaultPlugins.set(WindowPlugin {
|
|
|
|
|
primary_window: Some(Window {
|
|
|
|
|
// Adding the username to the window title makes debugging a whole lot easier.
|
|
|
|
|
title: format!("TricTrac <{}>", username),
|
|
|
|
|
resolution: (480.0, 540.0).into(),
|
|
|
|
|
..default()
|
|
|
|
|
}),
|
|
|
|
|
..default()
|
|
|
|
|
}))
|
2023-10-29 20:49:01 +01:00
|
|
|
// Renet setup
|
2023-10-30 14:25:05 +01:00
|
|
|
.add_plugins(RenetClientPlugin)
|
2023-10-31 16:29:05 +01:00
|
|
|
.add_plugins(NetcodeClientPlugin)
|
2023-10-30 14:25:05 +01:00
|
|
|
.insert_resource(client)
|
2023-10-31 14:32:21 +01:00
|
|
|
.insert_resource(transport)
|
|
|
|
|
.add_systems(Update, panic_on_error_system)
|
2023-10-29 20:49:01 +01:00
|
|
|
.run();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////// RENET NETWORKING //////////
|
|
|
|
|
// Creates a RenetClient thats already connected to a server.
|
|
|
|
|
// Returns an Err if connection fails
|
2023-10-31 14:32:21 +01:00
|
|
|
fn new_renet_client(username: &String) -> anyhow::Result<(RenetClient, NetcodeClientTransport)> {
|
|
|
|
|
let client = RenetClient::new(ConnectionConfig::default());
|
2023-10-29 20:49:01 +01:00
|
|
|
let server_addr = "127.0.0.1:5000".parse()?;
|
|
|
|
|
let socket = UdpSocket::bind("127.0.0.1:0")?;
|
|
|
|
|
let current_time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?;
|
|
|
|
|
let client_id = current_time.as_millis() as u64;
|
|
|
|
|
|
|
|
|
|
// Place username in user data
|
|
|
|
|
let mut user_data = [0u8; NETCODE_USER_DATA_BYTES];
|
|
|
|
|
if username.len() > NETCODE_USER_DATA_BYTES - 8 {
|
|
|
|
|
panic!("Username is too big");
|
|
|
|
|
}
|
|
|
|
|
user_data[0..8].copy_from_slice(&(username.len() as u64).to_le_bytes());
|
|
|
|
|
user_data[8..username.len() + 8].copy_from_slice(username.as_bytes());
|
|
|
|
|
|
2023-10-30 14:25:05 +01:00
|
|
|
let authentication = ClientAuthentication::Unsecure {
|
|
|
|
|
server_addr,
|
2023-10-29 20:49:01 +01:00
|
|
|
client_id,
|
2023-10-30 14:25:05 +01:00
|
|
|
user_data: Some(user_data),
|
|
|
|
|
protocol_id: PROTOCOL_ID,
|
|
|
|
|
};
|
|
|
|
|
let transport = NetcodeClientTransport::new(current_time, authentication, socket).unwrap();
|
2023-10-29 20:49:01 +01:00
|
|
|
|
2023-10-31 14:32:21 +01:00
|
|
|
Ok((client, transport))
|
2023-10-29 20:49:01 +01:00
|
|
|
}
|
|
|
|
|
|
2023-10-31 14:32:21 +01:00
|
|
|
// If any error is found we just panic
|
|
|
|
|
fn panic_on_error_system(mut renet_error: EventReader<NetcodeTransportError>) {
|
|
|
|
|
for e in renet_error.iter() {
|
|
|
|
|
panic!("{}", e);
|
|
|
|
|
}
|
|
|
|
|
}
|