mirror of
https://github.com/GIKExe/rust_mc_serv.git
synced 2025-06-23 18:02:57 +03:00
created sniff-packets program
sniffed update_tags and registry_data packets to .bin files
This commit is contained in:
parent
eb46fdfc45
commit
7ffccfed26
17
.envrc
Normal file
17
.envrc
Normal file
@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
# ^ make editor happy
|
||||
|
||||
#
|
||||
# Use https://direnv.net/ to automatically load the dev shell.
|
||||
#
|
||||
|
||||
if ! has nix_direnv_version || ! nix_direnv_version 3.0.4; then
|
||||
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.4/direnvrc" "sha256-DzlYZ33mWF/Gs8DDeyjr8mnVmQGx7ASYqA5WlxwvBG4="
|
||||
fi
|
||||
|
||||
watch_file nix/**
|
||||
watch_file -- **/*.nix
|
||||
# Adding files to git includes them in a flake
|
||||
# But it is also a bit much reloading.
|
||||
# watch_file .git/index .git/HEAD
|
||||
use flake . --show-trace
|
2
rust-toolchain.toml
Normal file
2
rust-toolchain.toml
Normal file
@ -0,0 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "stable"
|
@ -6,6 +6,7 @@ mkShell {
|
||||
direnv
|
||||
rustc
|
||||
cargo
|
||||
rustfmt
|
||||
python3
|
||||
python3Packages.beautifulsoup4
|
||||
python3Packages.requests
|
||||
|
1
sniff-packets/.gitignore
vendored
Normal file
1
sniff-packets/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
target/
|
192
sniff-packets/Cargo.lock
generated
Normal file
192
sniff-packets/Cargo.lock
generated
Normal file
@ -0,0 +1,192 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||
|
||||
[[package]]
|
||||
name = "cesu8"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "craftflow-nbt"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03a2d5312462b00f8420ace884a696f243be136ada9f50bf5f3d9858ff0c8e8e"
|
||||
dependencies = [
|
||||
"cesu8",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust_mc_proto"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "734168f5b9aef1991db4b11c0bcd71c0336b0a5ba98269f0df39b41b8463ac8c"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.140"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sniff-packets"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"craftflow-nbt",
|
||||
"rust_mc_proto",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
|
11
sniff-packets/Cargo.toml
Normal file
11
sniff-packets/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "sniff-packets"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
rust_mc_proto = "0.1.19"
|
||||
serde = "1.0.219"
|
||||
serde_json = "1.0.140"
|
||||
craftflow-nbt = "2.1.0"
|
||||
uuid = "1.16.0"
|
179
sniff-packets/src/main.rs
Normal file
179
sniff-packets/src/main.rs
Normal file
@ -0,0 +1,179 @@
|
||||
use std::{fs, io::Read};
|
||||
|
||||
use craftflow_nbt::DynNBT;
|
||||
use rust_mc_proto::{prelude::*, write_packet, MCConnTcp, Packet, ProtocolError};
|
||||
use uuid::Uuid;
|
||||
|
||||
|
||||
pub trait ReadWriteNBT<T>: DataReader + DataWriter {
|
||||
fn read_nbt(&mut self) -> Result<T, ProtocolError>;
|
||||
fn write_nbt(&mut self, val: &T) -> Result<(), ProtocolError>;
|
||||
}
|
||||
|
||||
impl ReadWriteNBT<DynNBT> for Packet {
|
||||
fn read_nbt(&mut self) -> Result<DynNBT, ProtocolError> {
|
||||
let mut data = Vec::new();
|
||||
let pos = self.get_ref().position();
|
||||
self.get_mut()
|
||||
.read_to_end(&mut data)
|
||||
.map_err(|_| ProtocolError::StringParseError)?;
|
||||
let (remaining, value) =
|
||||
craftflow_nbt::from_slice(&data).map_err(|_| ProtocolError::StringParseError)?;
|
||||
self.get_mut()
|
||||
.set_position(pos + (data.len() - remaining.len()) as u64);
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
fn write_nbt(&mut self, val: &DynNBT) -> Result<(), ProtocolError> {
|
||||
craftflow_nbt::to_writer(self.get_mut(), val).map_err(|_| ProtocolError::StringParseError)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn main() -> Result<(), ProtocolError> {
|
||||
let mut conn = MCConnTcp::connect("localhost:25565").unwrap();
|
||||
|
||||
conn.write_packet(&Packet::build(0x00, |packet| {
|
||||
packet.write_varint(770)?;
|
||||
packet.write_string("localhost")?;
|
||||
packet.write_unsigned_short(25565)?;
|
||||
packet.write_varint(2)
|
||||
})?)?;
|
||||
|
||||
conn.write_packet(&Packet::build(0x00, |packet| {
|
||||
packet.write_string("TheMixRay")?;
|
||||
packet.write_uuid(&Uuid::default())
|
||||
})?)?;
|
||||
|
||||
loop {
|
||||
let mut packet = conn.read_packet()?;
|
||||
|
||||
if packet.id() == 0x03 {
|
||||
let threshold = packet.read_varint()?;
|
||||
|
||||
if threshold >= 0 {
|
||||
conn.set_compression(Some(threshold as usize));
|
||||
}
|
||||
} else if packet.id() == 0x02 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
conn.write_packet(&Packet::empty(0x03))?;
|
||||
|
||||
conn.write_packet(&Packet::build(0x02, |packet| {
|
||||
packet.write_string("minecraft:brand")?;
|
||||
packet.write_string("vanilla")
|
||||
})?)?;
|
||||
|
||||
conn.write_packet(&Packet::build(0x00, |packet| {
|
||||
packet.write_string("en_us")?;
|
||||
packet.write_signed_byte(12)?;
|
||||
packet.write_varint(0)?;
|
||||
packet.write_boolean(true)?;
|
||||
packet.write_byte(127)?;
|
||||
packet.write_varint(1)?;
|
||||
packet.write_boolean(true)?;
|
||||
packet.write_boolean(true)?;
|
||||
packet.write_varint(0)
|
||||
})?)?;
|
||||
|
||||
let mut packet = conn.read_packet()?; // server brand
|
||||
|
||||
let id = packet.read_string()?;
|
||||
println!("message id: {}", id);
|
||||
println!("message data: {}", String::from_utf8_lossy(&packet.get_bytes()[id.len()+1..]));
|
||||
|
||||
let mut packet = conn.read_packet()?; // feature flags
|
||||
|
||||
let flags_len = packet.read_varint()?;
|
||||
|
||||
println!("got {} feature flags:", flags_len);
|
||||
|
||||
for _ in 0..flags_len {
|
||||
let flag = packet.read_string()?;
|
||||
|
||||
println!("flag: {}", flag);
|
||||
}
|
||||
|
||||
let mut packet = conn.read_packet()?; // wait for known packs packet
|
||||
|
||||
if packet.id() != 0x0E {
|
||||
println!("got unexpected packet while looking for 0x0E: 0x{:02X}", packet.id());
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let packs_len = packet.read_varint()?;
|
||||
|
||||
println!("got {} known packs:", packs_len);
|
||||
|
||||
for _ in 0..packs_len {
|
||||
println!("{}:{} v{}", packet.read_string()?, packet.read_string()?, packet.read_string()?);
|
||||
}
|
||||
|
||||
packet.set_id(0x07); // make it serverbound
|
||||
|
||||
conn.write_packet(&packet)?;
|
||||
|
||||
let mut data = Vec::new();
|
||||
|
||||
loop {
|
||||
let mut packet = conn.read_packet()?;
|
||||
|
||||
if packet.id() != 0x07 { // update tags
|
||||
let registries_len = packet.read_varint()?;
|
||||
|
||||
println!("got update tags: {}", registries_len);
|
||||
|
||||
for _ in 0..registries_len {
|
||||
let registry = packet.read_string()?;
|
||||
|
||||
println!("registry: {}", registry);
|
||||
|
||||
let tags_len = packet.read_varint()?;
|
||||
|
||||
for _ in 0..tags_len {
|
||||
let tag_name = packet.read_string()?;
|
||||
|
||||
println!("tag: {}", tag_name);
|
||||
|
||||
let entries_len = packet.read_varint()?;
|
||||
|
||||
for _ in 0..entries_len {
|
||||
let entry = packet.read_varint()?;
|
||||
|
||||
println!("entry: {}", entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fs::write("update-tags.bin", packet.get_bytes()).unwrap();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
println!("got registry: {}", packet.read_string()?);
|
||||
|
||||
let entries_len = packet.read_varint()?;
|
||||
|
||||
for _ in 0..entries_len {
|
||||
let entry_id = packet.read_string()?;
|
||||
let has_data = packet.read_boolean()?;
|
||||
|
||||
if has_data {
|
||||
let entry_data = packet.read_nbt()?;
|
||||
|
||||
println!("entry: {}, data: {:?}", entry_id, entry_data);
|
||||
} else {
|
||||
println!("entry: {}, no data", entry_id);
|
||||
}
|
||||
}
|
||||
|
||||
write_packet(&mut data, None, 0, &packet)?;
|
||||
}
|
||||
|
||||
fs::write("registry-data.bin", &data).unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
@ -157,6 +157,11 @@ pub fn handle_connection(
|
||||
particle_status,
|
||||
});
|
||||
|
||||
client.write_packet(&Packet::build(clientbound::configuration::PLUGIN_MESSAGE, |p| {
|
||||
p.write_string("minecraft:brand")?;
|
||||
p.write_string("rust_minecraft_server")
|
||||
})?)?;
|
||||
|
||||
handle_configuration_state(client.clone())?;
|
||||
|
||||
client.write_packet(&Packet::empty(clientbound::configuration::FINISH))?;
|
||||
|
@ -1,64 +1,67 @@
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
use std::{io::Cursor, sync::Arc};
|
||||
|
||||
use craftflow_nbt::DynNBT;
|
||||
use log::debug;
|
||||
use rust_mc_proto::{DataWriter, Packet};
|
||||
use serde_json::{json, Value};
|
||||
use rust_mc_proto::{read_packet, DataWriter, Packet};
|
||||
|
||||
use crate::server::{
|
||||
data::ReadWriteNBT, player::context::ClientContext, ServerError
|
||||
player::context::ClientContext, ServerError
|
||||
};
|
||||
|
||||
use super::id::{clientbound::{self, configuration::REGISTRY_DATA}, serverbound};
|
||||
use super::id::*;
|
||||
|
||||
pub fn send_update_tags(
|
||||
client: Arc<ClientContext>,
|
||||
) -> Result<(), ServerError> {
|
||||
|
||||
// rewrite this hardcode bullshit
|
||||
|
||||
client.write_packet(&Packet::from_bytes(clientbound::configuration::UPDATE_TAGS, include_bytes!("update-tags.bin")))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn send_registry_data(
|
||||
client: Arc<ClientContext>,
|
||||
) -> Result<(), ServerError> {
|
||||
let registry_data = include_str!("registry_data.json");
|
||||
let registry_data: Value = serde_json::from_str(registry_data).unwrap();
|
||||
let registry_data = registry_data.as_object().unwrap();
|
||||
|
||||
for (registry_name, registry_data) in registry_data {
|
||||
let registry_data = registry_data.as_object().unwrap();
|
||||
// rewrite this hardcode bullshit
|
||||
|
||||
let mut packet = Packet::empty(clientbound::configuration::REGISTRY_DATA);
|
||||
packet.write_string(registry_name)?;
|
||||
|
||||
packet.write_usize_varint(registry_data.len())?;
|
||||
|
||||
debug!("sending registry: {registry_name}");
|
||||
|
||||
for (key, value) in registry_data {
|
||||
packet.write_string(key)?;
|
||||
packet.write_boolean(true)?;
|
||||
|
||||
let mut data = Vec::new();
|
||||
craftflow_nbt::to_writer(&mut data, value).unwrap();
|
||||
|
||||
debug!("- {key}");
|
||||
|
||||
packet.write_bytes(&data)?;
|
||||
}
|
||||
|
||||
let mut registry_data = Cursor::new(include_bytes!("registry-data.bin"));
|
||||
|
||||
while let Ok(mut packet) = read_packet(&mut registry_data, None) {
|
||||
packet.set_id(clientbound::configuration::REGISTRY_DATA);
|
||||
client.write_packet(&packet)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn process_known_packs(
|
||||
client: Arc<ClientContext>
|
||||
) -> Result<(), ServerError> {
|
||||
let mut packet = Packet::empty(clientbound::configuration::KNOWN_PACKS);
|
||||
packet.write_varint(1)?;
|
||||
packet.write_string("minecraft")?;
|
||||
packet.write_string("core")?;
|
||||
packet.write_string("1.21.5")?;
|
||||
client.write_packet(&packet)?;
|
||||
|
||||
client.read_packet(serverbound::configuration::KNOWN_PACKS)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn handle_configuration_state(
|
||||
client: Arc<ClientContext>, // Контекст клиента
|
||||
) -> Result<(), ServerError> {
|
||||
|
||||
let mut p = Packet::empty(clientbound::configuration::KNOWN_PACKS);
|
||||
p.write_varint(1)?;
|
||||
p.write_string("minecraft")?;
|
||||
p.write_string("core")?;
|
||||
p.write_string("1.21.5")?;
|
||||
client.write_packet(&p)?;
|
||||
client.read_packet(serverbound::configuration::KNOWN_PACKS)?;
|
||||
let mut packet = Packet::empty(clientbound::configuration::FEATURE_FLAGS);
|
||||
packet.write_varint(1)?;
|
||||
packet.write_string("minecraft:vanilla")?;
|
||||
client.write_packet(&packet)?;
|
||||
|
||||
process_known_packs(client.clone())?;
|
||||
send_registry_data(client.clone())?;
|
||||
send_update_tags(client.clone())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -100,7 +103,14 @@ pub fn handle_play_state(
|
||||
packet.write_boolean(false)?; // Enforces Secure Chat
|
||||
client.write_packet(&packet)?;
|
||||
|
||||
loop {}
|
||||
loop {}
|
||||
|
||||
// TODO: отдельный поток для чтения пакетов
|
||||
|
||||
// TODO: переработка функции read_packet так чтобы когда
|
||||
// делаешь read_any_packet, пакет отправлялся сначала всем другим
|
||||
// функциям read_packet которые настроены на этот айди пакета,
|
||||
// а потом если таковых не осталось пакет возвращался
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
BIN
src/server/protocol/registry-data.bin
Normal file
BIN
src/server/protocol/registry-data.bin
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
src/server/protocol/update-tags.bin
Normal file
BIN
src/server/protocol/update-tags.bin
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user