Nicotine/src/lib.rs
alterwain efc4b40421 modified: Cargo.lock
modified:   Cargo.toml
	deleted:    src/7zip/7za.dll
	deleted:    src/7zip/7zxa.dll
	modified:   src/lib.rs
2025-03-18 17:58:41 +03:00

87 lines
2.7 KiB
Rust

use std::{error::Error, io::Cursor, path::{Path, PathBuf}, process::Command};
const ZIP_BIN: &[u8; 1327616] = include_bytes!("7zip/7za.exe");
fn find_subsequence(haystack: &[u8], needle: &[u8]) -> Vec<usize> {
haystack.windows(needle.len())
.enumerate()
.filter_map(|(i, arr)| if arr == needle { Some(i) } else { None })
.collect()
}
fn recursively_find_classes(path: PathBuf) -> Vec<PathBuf> {
let e = std::fs::read_dir(path).unwrap();
let mut classes = Vec::new();
for entry in e.flatten() {
match entry.metadata().unwrap().is_dir() {
true => classes.append(&mut recursively_find_classes(entry.path())),
false => {
if entry.file_name().to_str().unwrap().ends_with(".class") {
classes.push(entry.path());
}
}
}
}
classes
}
// patch_jar(r#"D:\Documents\RustroverProjects\XCraft\xcraft\libraries\com\mojang\authlib\1.5.22\authlib-1.5.22__.jar"#, "authlib_patched.jar", "http://localhost:8999/api/")
fn write_7za() {
let _ = std::fs::write("tmp/7za.exe", ZIP_BIN);
}
pub fn patch_jar(input_jar: &str, output_jar: &str, endpoint: &str) -> Result<(), Box<dyn Error + Sync + Send>> {
write_7za();
let mut target_dir = PathBuf::new();
target_dir.push("out");
let archive = std::fs::read(input_jar)?;
zip_extract::extract(Cursor::new(archive), &target_dir, true)?;
let needle = b"https://sessionserver.mojang.com/session/minecraft/";
let replacement = endpoint.as_bytes();
for path in recursively_find_classes(PathBuf::from(".\\out")) {
let mut haystack = std::fs::read(&path).unwrap();
let mut v = find_subsequence(&haystack, needle);
if v.is_empty() { continue; }
while let Some(g) = v.first() {
let (a,b) = haystack.split_at(*g);
let l = a[a.len()-1];
let mut a = a[..a.len()-1].to_vec();
a.push( if l as usize > needle.len() { (replacement.len() + (l as usize - needle.len())) as u8 } else { replacement.len() as u8 });
a.append(&mut replacement.to_vec());
a.append(&mut b[needle.len()..].to_vec());
haystack = a;
v = find_subsequence(&haystack, needle);
}
std::fs::write(path, haystack)?;
}
zip_dir(&target_dir, output_jar)?;
std::fs::remove_dir_all(&target_dir)?;
Ok(())
}
fn zip_dir(
src_dir: &Path,
writer: &str,
) -> Result<(), Box<dyn Error + Sync + Send>> {
let _a = Command::new("tmp/7za.exe")
.arg("a")
.arg("-tzip")
.arg("-mx=0")
.arg(writer)
.arg([src_dir.to_str().unwrap(), "/", "*"].concat())
.spawn()?;
Ok(())
}