mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2026-04-05 07:16:18 +00:00
wip downloading (it doesnt work)
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -97,6 +97,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"flate2",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"nalgebra",
|
||||
"num_enum",
|
||||
|
||||
@@ -9,6 +9,8 @@ edition = "2021"
|
||||
log = "0.4"
|
||||
pretty_env_logger = "0.4.0"
|
||||
|
||||
lazy_static = "1"
|
||||
|
||||
anyhow = "1.0.66"
|
||||
nalgebra = "0.31"
|
||||
num_enum = "0.5.7"
|
||||
|
||||
BIN
Resources/Client/LuuksDraftingMod.zip
Normal file
BIN
Resources/Client/LuuksDraftingMod.zip
Normal file
Binary file not shown.
BIN
Resources/Client/LuuksRadarMod.zip
Normal file
BIN
Resources/Client/LuuksRadarMod.zip
Normal file
Binary file not shown.
@@ -2,6 +2,9 @@ use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Config {
|
||||
#[serde(skip)] // Skipping uses Default::default, which makes a new vector for us :)
|
||||
pub mods: Vec<(String, usize)>,
|
||||
|
||||
#[serde(rename = "General")]
|
||||
pub general: GeneralSettings,
|
||||
}
|
||||
|
||||
23
src/main.rs
23
src/main.rs
@@ -1,12 +1,16 @@
|
||||
#[macro_use] extern crate async_trait;
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] extern crate async_trait;
|
||||
#[macro_use] extern crate lazy_static;
|
||||
|
||||
mod server;
|
||||
mod config;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let user_config: config::Config = toml::from_str(
|
||||
pretty_env_logger::formatted_timed_builder().filter_level(log::LevelFilter::max()).init();
|
||||
// pretty_env_logger::formatted_timed_builder().filter_level(log::LevelFilter::Info).init();
|
||||
|
||||
let mut user_config: config::Config = toml::from_str(
|
||||
&std::fs::read_to_string("ServerConfig.toml")
|
||||
.map_err(|_| error!("Failed to read config file!"))
|
||||
.expect("Failed to read config file!")
|
||||
@@ -14,6 +18,21 @@ async fn main() {
|
||||
.map_err(|_| error!("Failed to parse config file!"))
|
||||
.expect("Failed to parse config file!");
|
||||
|
||||
// TODO: This should not error lol
|
||||
for entry in std::fs::read_dir("Resources/Client").expect("Failed to read Resources/Client!") {
|
||||
if let Ok(entry) = entry {
|
||||
if entry.path().is_file() {
|
||||
if let Ok(metadata) = entry.metadata() {
|
||||
if let Some(filename) = entry.path().file_name().map(|s| s.to_string_lossy()) {
|
||||
user_config.mods.push((filename.to_string(), metadata.len() as usize));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug!("Mods: {:?}", user_config.mods);
|
||||
|
||||
let user_config = std::sync::Arc::new(user_config);
|
||||
|
||||
let mut server = server::Server::new(user_config)
|
||||
|
||||
@@ -24,6 +24,10 @@ use super::packet::*;
|
||||
|
||||
static ATOMIC_ID_COUNTER: AtomicU8 = AtomicU8::new(0);
|
||||
|
||||
lazy_static! {
|
||||
static ref CLIENT_MOD_PROGRESS: Mutex<HashMap<usize, usize>> = Mutex::new(HashMap::new());
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum ClientState {
|
||||
None,
|
||||
@@ -114,7 +118,7 @@ impl Client {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn authenticate(&mut self, config: &super::Config) -> anyhow::Result<()> {
|
||||
pub async fn authenticate(&mut self, config: &super::Config) -> anyhow::Result<bool> {
|
||||
debug!("Authenticating client {}...", self.id);
|
||||
|
||||
'waiting_for_c: loop {
|
||||
@@ -128,6 +132,11 @@ impl Client {
|
||||
debug!("code: '{}' / {}", code as char, code);
|
||||
match code as char {
|
||||
'C' => {
|
||||
// We now delete existing data for this client ID, just in case.
|
||||
// TODO: This seems like a recipe for disaster
|
||||
let mut lock = CLIENT_MOD_PROGRESS.lock().await;
|
||||
lock.remove(&(self.id as usize));
|
||||
|
||||
// TODO: Check client version
|
||||
trace!("Client version packet");
|
||||
self.socket.readable().await?;
|
||||
@@ -136,10 +145,54 @@ impl Client {
|
||||
break 'waiting_for_c;
|
||||
}
|
||||
'D' => {
|
||||
let id = self.read_raw(1).await?[0];
|
||||
// The download sequence is so awful
|
||||
// It currently requires us to track what the next file is that
|
||||
// we need to provide, which is hard to do with the current
|
||||
// server design.
|
||||
// I think I will simply keep a counter around that will
|
||||
// track what the next mod is per client.
|
||||
// TODO: Clean this up. It also needs to be moved out of the client code IMO
|
||||
let id = self.read_raw(1).await?[0] as usize;
|
||||
debug!("HandleDownload connection for client id: {}", id);
|
||||
debug!("Not handling this for now!");
|
||||
return Err(ClientError::IsDownloader.into());
|
||||
|
||||
self.write_packet(Packet::Raw(RawPacket::from_str("AG"))).await?;
|
||||
|
||||
// TODO: How does this work???
|
||||
|
||||
let mut lock = CLIENT_MOD_PROGRESS.lock().await;
|
||||
if lock.get(&id).is_none() { lock.insert(id, 0); }
|
||||
let next_id = lock.get_mut(&id).unwrap();
|
||||
|
||||
let bmod = &config.mods[*next_id]; // TODO: This is a bit uhh yeah
|
||||
|
||||
*next_id += 1;
|
||||
|
||||
debug!("Mod name: {}", bmod.0);
|
||||
|
||||
let mut mod_name = bmod.0.clone();
|
||||
if mod_name.starts_with("/") == false {
|
||||
mod_name = format!("/{mod_name}");
|
||||
}
|
||||
|
||||
let mod_path = format!("Resources/Client{mod_name}");
|
||||
let file_data = std::fs::read(mod_path)?;
|
||||
|
||||
let packet = RawPacket::from_data(file_data);
|
||||
// self.write_packet(Packet::Raw(packet)).await?;
|
||||
|
||||
{
|
||||
let mut lock = self.write_half.lock().await;
|
||||
lock.writable().await?;
|
||||
trace!("Sending packet!");
|
||||
if let Err(e) = tcp_write_raw(lock.deref_mut(), Packet::Raw(packet)).await {
|
||||
error!("{:?}", e);
|
||||
}
|
||||
trace!("Packet sent!");
|
||||
drop(lock);
|
||||
}
|
||||
|
||||
// return Err(ClientError::IsDownloader.into());
|
||||
return Ok(false);
|
||||
}
|
||||
_ => {
|
||||
return Err(ClientError::AuthenticateError.into());
|
||||
@@ -186,7 +239,7 @@ impl Client {
|
||||
);
|
||||
self.sync(config).await?;
|
||||
|
||||
Ok(())
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
// TODO: https://github.com/BeamMP/BeamMP-Server/blob/master/src/TNetwork.cpp#L619
|
||||
@@ -205,9 +258,20 @@ impl Client {
|
||||
match packet.data[0] as char {
|
||||
'S' if packet.data.len() > 1 => match packet.data[1] as char {
|
||||
'R' => {
|
||||
let file_packet = RawPacket::from_code('-');
|
||||
// let file_packet = RawPacket::from_code('-');
|
||||
// let file_data = "/bepis_dysoon_uu201_v3.zip;/bepis_laudi_v8_revolution.zip;/simraceclubclient.zip;48353220;50283849;1937;";
|
||||
// let file_packet = RawPacket::from_str(file_data);
|
||||
let mut file_data = String::new();
|
||||
for (name, size) in &config.mods {
|
||||
let mut mod_name = name.clone();
|
||||
if mod_name.starts_with("/") == false {
|
||||
mod_name = format!("/{mod_name}");
|
||||
}
|
||||
file_data.push_str(&format!("{mod_name};"));
|
||||
}
|
||||
for (name, size) in &config.mods {
|
||||
file_data.push_str(&format!("{size};"));
|
||||
}
|
||||
let file_packet = RawPacket::from_str(&file_data);
|
||||
self.write_packet(Packet::Raw(file_packet))
|
||||
.await?
|
||||
}
|
||||
@@ -218,13 +282,6 @@ impl Client {
|
||||
let mut file_name = packet.data_as_string().clone();
|
||||
file_name.remove(0); // Remove f
|
||||
debug!("Client requested file {}", file_name);
|
||||
self.kick(&format!("You have not yet downloaded {}!", file_name)).await;
|
||||
// let mut lock = self.write_half.lock().await;
|
||||
// lock.writable().await?;
|
||||
// trace!("Sending packet!");
|
||||
// if let Err(e) = tcp_send_file(lock.deref_mut(), file_name).await {
|
||||
// error!("{:?}", e);
|
||||
// }
|
||||
}
|
||||
_ => error!("Unknown packet! {:?}", packet),
|
||||
}
|
||||
|
||||
@@ -80,11 +80,11 @@ impl Server {
|
||||
let ci_ref = clients_incoming_ref.clone();
|
||||
|
||||
set.spawn(async move {
|
||||
socket.set_nodelay(true);
|
||||
socket.set_nodelay(true); // TODO: Is this good?
|
||||
|
||||
let mut client = Client::new(socket);
|
||||
match client.authenticate(&cfg_ref).await {
|
||||
Ok(_) => {
|
||||
Ok(b) if b => {
|
||||
let mut lock = ci_ref
|
||||
.lock()
|
||||
.map_err(|e| error!("{:?}", e))
|
||||
@@ -92,6 +92,9 @@ impl Server {
|
||||
lock.push(client);
|
||||
drop(lock);
|
||||
},
|
||||
Ok(b) => {
|
||||
debug!("Downloader?");
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Authentication error occured, kicking player...");
|
||||
error!("{:?}", e);
|
||||
|
||||
@@ -73,6 +73,13 @@ impl RawPacket {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_data(data: Vec<u8>) -> Self {
|
||||
Self {
|
||||
header: data.len() as u32,
|
||||
data,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(str_data: &str) -> Self {
|
||||
let data = str_data.as_bytes().to_vec();
|
||||
Self {
|
||||
|
||||
Reference in New Issue
Block a user