Skip to content

Commit

Permalink
joiner start + virtual fs testing server
Browse files Browse the repository at this point in the history
  • Loading branch information
Shrecknt committed Feb 27, 2024
1 parent e4a64df commit d37a71d
Show file tree
Hide file tree
Showing 11 changed files with 262 additions and 15 deletions.
14 changes: 12 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 8 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ resolver = "2"
members = ["crates/*"]

[workspace.dependencies]
snowstorm = { version = "0.1.0", path = "crates/snowstorm" }
bunger = { version = "0.1.0", path = "crates/bunger" }
database = { version = "0.1.0", path = "crates/database" }
common = { version = "0.1.0", path = "crates/common" }
config = { version = "0.1.0", path = "crates/config" }
database = { version = "0.1.0", path = "crates/database" }
discord = { version = "0.1.0", path = "crates/discord" }
io = { version = "0.1.0", path = "crates/io" }
jwt = { version = "0.1.0", path = "crates/jwt" }
web = { version = "0.1.0", path = "crates/web" }
mowojang = { version = "0.1.0", path = "crates/mowojang" }
ram_server = { version = "0.1.0", path = "crates/ram_server" }
scheduling = { version = "0.1.0", path = "crates/scheduling" }
discord = { version = "0.1.0", path = "crates/discord" }
config = { version = "0.1.0", path = "crates/config" }
snowstorm = { version = "0.1.0", path = "crates/snowstorm" }
web = { version = "0.1.0", path = "crates/web" }
axum = { version = "0.6.20", features = ["macros", "ws", "headers"] }
bcrypt = "0.15.0"
boringtun = "0.6.0"
Expand Down Expand Up @@ -60,3 +62,4 @@ pretty-duration = "0.1.1"
toml = "0.8.10"
smart-default = "0.7.1"
flate2 = { version = "1.0.17", features = ["zlib"], default-features = false }
semver = "1.0.22"
2 changes: 2 additions & 0 deletions crates/bunger/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ edition = "2021"

[dependencies]
config = { workspace = true }
ram_server = { workspace = true }
flate2 = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tokio = { workspace = true }
eyre = { workspace = true }
uuid = { workspace = true }
73 changes: 66 additions & 7 deletions crates/bunger/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ use std::{
io::{Cursor, Read},
net::SocketAddrV4,
};
use tokio::{io::AsyncReadExt, net::TcpStream};

use crate::varint::AsyncVarint;
use tokio::{
io::{AsyncReadExt, AsyncWriteExt},
net::TcpStream,
};
use uuid::uuid;
use varint::{AsyncVarint, SyncVarintWrite};

pub mod varint;

Expand All @@ -20,23 +23,79 @@ impl JoinData {
}
}

pub async fn join(addr: SocketAddrV4) -> JoinData {
pub async fn join(addr: SocketAddrV4, version: i32) -> JoinData {
let mut join_data = JoinData::new();

let res = join_internal(addr, &mut join_data).await;
let res = join_internal(addr, version, &mut join_data).await;
if let Err(err) = res {
join_data.error = Some(err.to_string());
}

join_data
}

async fn join_internal(addr: SocketAddrV4, join_data: &mut JoinData) -> eyre::Result<()> {
async fn join_internal(
addr: SocketAddrV4,
version: i32,
join_data: &mut JoinData,
) -> eyre::Result<()> {
let mut stream = TcpStream::connect(addr).await?;

let mut packet = Vec::new();
packet.write_varint(0x00)?;
packet.write_varint(version)?;
let addr = b"shrecked.dev";
packet.write_varint(addr.len() as i32)?;
packet.write_all(addr).await?;
packet.write_u16(42069).await?;
packet.write_varint(2)?;
write_packet(&mut stream, &packet, false).await?;

let mut packet = Vec::new();
packet.write_varint(0x00)?;
let username = b"Test_bot";
packet.write_varint(username.len() as i32)?;
packet.write_all(username).await?;
if version > 47 {
// TODO: not sure when uuid field was added but its not in 1.8.x (47)
let player_uuid = uuid!("36d4d63f-7268-4879-a57f-122e9df006c2").as_bytes();
packet.write_all(player_uuid).await?;
}
write_packet(&mut stream, &packet, false).await?;

let packet = read_packet(&mut stream, false).await?;
println!("packet = {packet:?}");
println!("got packet = {packet:?}");
match packet.0 {
0 => {
// kick
}
1 => {
// encryption, online mode probably
}
3 => {
// compression, offline mode probably
}
_ => {
// unknown packet
}
};

Ok(())
}

async fn write_packet(stream: &mut TcpStream, packet: &[u8], compressed: bool) -> eyre::Result<()> {
let mut to_send = Vec::new();

if compressed {
todo!()
} else {
to_send.write_varint(packet.len() as i32)?;
to_send.write_all(packet).await?;
}

println!("sending packet = {to_send:?}");

stream.write_all(&to_send).await?;
Ok(())
}

Expand Down
8 changes: 7 additions & 1 deletion crates/bunger/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ use std::{net::SocketAddrV4, str::FromStr};

#[tokio::main]
async fn main() -> eyre::Result<()> {
let data = bunger::join(SocketAddrV4::from_str("130.61.123.184:25565").unwrap()).await;
let mut server =
ram_server::run_server("1.8.9", 25569, false).expect("unable to start server :<");

let data = bunger::join(SocketAddrV4::from_str("127.0.0.1:25569").unwrap(), 47).await;

server.kill().expect("Unable to kill child process");

println!("data = {data:?}");

Ok(())
Expand Down
13 changes: 13 additions & 0 deletions crates/bunger/src/varint/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::future::Future;

pub mod r#async;
pub mod sync;

pub trait AsyncVarint {
type Error;
Expand All @@ -10,3 +11,15 @@ pub trait AsyncVarint {
fn read_varint(&mut self) -> impl Future<Output = Result<i32, Self::Error>> + Send;
fn read_varint_len(&mut self) -> impl Future<Output = Result<(u32, i32), Self::Error>> + Send;
}

pub trait SyncVarintRead {
type Error;

fn read_varint(&mut self) -> Result<i32, Self::Error>;
fn read_varint_len(&mut self) -> Result<(u32, i32), Self::Error>;
}
pub trait SyncVarintWrite {
type Error;

fn write_varint(&mut self, varint: i32) -> Result<(), Self::Error>;
}
54 changes: 54 additions & 0 deletions crates/bunger/src/varint/sync.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use super::{SyncVarintRead, SyncVarintWrite};
use std::io::{Read, Write};

impl<T: Read + ?Sized> SyncVarintRead for T {
type Error = tokio::io::Error;

fn read_varint(&mut self) -> Result<i32, Self::Error> {
Ok(self.read_varint_len()?.1)
}

fn read_varint_len(&mut self) -> Result<(u32, i32), Self::Error> {
let mut buf = [0u8];
let mut res = 0;
let mut count = 0u32;

loop {
self.read_exact(&mut buf)?;
res |= (buf[0] as i32 & (0b0111_1111_i32))
.checked_shl(7 * count)
.ok_or(tokio::io::ErrorKind::Other)?;

count += 1;
if count > 5 {
break Err(tokio::io::ErrorKind::Other.into());
} else if (buf[0] & (0b1000_0000_u8)) == 0 {
break Ok((count, res));
}
}
}
}

impl<T: Write + ?Sized> SyncVarintWrite for T {
type Error = tokio::io::Error;

fn write_varint(&mut self, varint: i32) -> Result<(), Self::Error> {
let mut buffer = [0];
let mut value = varint;

if value == 0 {
self.write_all(&buffer)?;
}

while value != 0 {
buffer[0] = (value & 0b0111_1111) as u8;
value = (value >> 7) & (i32::max_value() >> 6);
if value != 0 {
buffer[0] |= 0b1000_0000;
}
self.write_all(&buffer)?;
}

Ok(())
}
}
12 changes: 12 additions & 0 deletions crates/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ pub struct Config {

#[serde(default)]
pub mowojang: MowojangConfig,

#[serde(default)]
pub ram_server: RamServerConfig,
}

impl Config {
Expand Down Expand Up @@ -90,6 +93,15 @@ pub struct MowojangConfig {
pub internal_api_uri: Option<String>,
}

#[derive(Deserialize, SmartDefault)]
pub struct RamServerConfig {
pub java_8_path: PathBuf,
pub java_11_path: PathBuf,
pub java_17_path: PathBuf,
pub server_jar_path: PathBuf,
pub temp_fs_path: PathBuf,
}

#[derive(Deserialize, SmartDefault)]
pub struct OauthConfig {
#[serde(default)]
Expand Down
8 changes: 8 additions & 0 deletions crates/ram_server/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "ram_server"
version = "0.1.0"
edition = "2021"

[dependencies]
config = { workspace = true }
semver = { workspace = true }
73 changes: 73 additions & 0 deletions crates/ram_server/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use std::{
fs,
io::{BufRead, BufReader},
process::{Child, Command, Stdio},
};

pub fn run_server(version: impl ToString, port: u16, online_mode: bool) -> Option<Child> {
let config = config::get();
let version = version.to_string();
let java_path = {
let version = semver::Version::parse(&version).expect("Unable to parse version");
match version.minor {
..=17 => &config.ram_server.java_8_path,
18.. => &config.ram_server.java_17_path,
#[allow(unreachable_patterns)]
_ => &config.ram_server.java_11_path,
}
};
run_setup();
{
let mut from_path = config.ram_server.server_jar_path.clone().into_os_string();
from_path.push(format!("{version}.jar"));
let mut to_path = config.ram_server.temp_fs_path.clone().into_os_string();
to_path.push(format!("{version}.jar"));
fs::copy(from_path, to_path).expect("Unable to copy server jar to temp dir");
}
{
let mut eula_path = config.ram_server.temp_fs_path.clone().into_os_string();
eula_path.push("eula.txt");
fs::write(eula_path, b"eula=true").expect("Unable to write to eula file");
}
{
let mut server_properties_path = config.ram_server.temp_fs_path.clone().into_os_string();
server_properties_path.push("server.properties");
fs::write(
server_properties_path,
format!("server-port={port}\nonline-mode={online_mode}"),
)
.expect("Unable to write to server properties file");
}

let mut res = Command::new(java_path)
.current_dir(&config.ram_server.temp_fs_path)
.stdout(Stdio::piped())
.stderr(Stdio::null())
.stdin(Stdio::null())
.arg("-jar")
.arg(format!("{version}.jar"))
.arg("--nogui")
.spawn()
.expect("Could not start process");

let done_str = "[Server thread/INFO]: Done";
let stdout = res.stdout.take().expect("Could not take stdout");

let reader = BufReader::new(stdout);
let mut lines = reader.lines();
while let Some(Ok(line)) = lines.next() {
println!("{line}");
if line.contains(done_str) {
return Some(res);
}
}

res.kill().expect("Count not kill child process");
None
}

fn run_setup() {
let path = &config::get().ram_server.temp_fs_path;
fs::remove_dir_all(path).expect("Unable to delete old temp dir");
fs::create_dir(path).expect("Unable to create temp dir");
}
7 changes: 7 additions & 0 deletions crates/ram_server/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fn main() {
println!("Hello, World!");
let mut handle =
ram_server::run_server("1.20.4-paper", 25565, true).expect("Could not start server :<");
println!("server started!");
handle.kill().expect("Unable to kill server process");
}

0 comments on commit d37a71d

Please sign in to comment.