use std::{io::Error, thread::sleep, time::Duration}; use rust_mc_proto::{DataBufferReader, DataBufferWriter, MinecraftConnection, Packet, ProtocolError}; use socks::Socks5Stream; use crate::utils; pub struct Socks5Bot { username: String, proxy_addr: String, server_addr: String, conn: MinecraftConnection, should_restart: bool, } impl Socks5Bot { pub fn new(username: String, proxy_addr: String, server_addr: String) -> Result { println!("[{}] Creating bot with proxy {}", username, proxy_addr); let stream = Socks5Stream::connect(proxy_addr.as_str(), server_addr.as_str()); let should_restart = false; match stream { Ok(stream) => Ok(Socks5Bot { username, proxy_addr, server_addr, conn: MinecraftConnection::new(stream), should_restart }), Err(e) => Err(e), } } // bot登录函数 pub fn login(&mut self) -> Result<(), ProtocolError> { 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(); self.conn.write_packet(&Packet::build(0x00, |packet| { packet.write_u16_varint(763)?; // protocol_version packet.write_string(&server_host)?; // server_address packet.write_unsigned_short(server_port_num)?; // server_port 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)// ?; // packet.write_uuid(&Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap()) })?)?; // login start packet Ok(()) } pub fn handle_keepalive(&mut self,packet: &mut Packet) -> Result<(), ProtocolError> { // keep alive let id = packet.read_long()?; 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("验证程序已启用") { println!("[{}] Restart flag setted, will restart after 1.5 min", self.username); sleep(Duration::from_secs(90)); self.should_restart = true; } Ok(()) } // 处理网络数据包 pub fn handle_packets(&mut self) -> Result<(), ProtocolError> { let mut status = 0; while self.conn.is_alive() { let mut packet = self.conn.read_packet()?; match packet.id() { 0x02 => { // login success println!("[{}] Successfully logged in!",self.username); status = 1; } 0x03 => { // set compression let threshold = packet.read_i32_varint()?; if threshold >= 0 { self.conn.set_compression(Some(threshold as usize)); // println!("[{}] Compression threshold set to {}", self.username, threshold) } } 0x23 => { self.handle_keepalive(&mut packet)?; } 0x1A => { // disconnect self.handle_disconnect(&mut packet)?; break; } 0x00 => { if status == 0{ let text = packet.read_string()?; println!("[{}] Failed to login: {}", self.username, utils::parse_json_component(text.as_str())); break; } } 0x38 => { // player died println!("[{}] Player died,respawning...",self.username); self.conn.write_packet(&Packet::build(0x07, |packet| { packet.write_u8_varint(0) })?)? } _ => { } } } Ok(()) } pub fn run(&mut self) -> Result<(), ProtocolError> { println!("[{}] Connecting to {} with proxy {}", self.username, self.server_addr,self.proxy_addr); self.login().unwrap(); self.handle_packets().unwrap_or(()); Ok(()) } pub fn should_restart(&self) -> bool { self.should_restart } }