summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--Cargo.toml9
-rw-r--r--packetorder.txt159
-rw-r--r--rust-toolchain.toml2
-rw-r--r--src/main.rs179
5 files changed, 335 insertions, 15 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 901bd67..b9cd0ef 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -104,7 +104,6 @@ dependencies = [
[[package]]
name = "craftio-rs"
version = "0.1.0"
-source = "git+https://github.com/romangraef/craftio-rs.git?branch=fix/read_packet_len#565eb610bd4da8110eabcb79bd06b66c1c815384"
dependencies = [
"aes",
"async-trait",
diff --git a/Cargo.toml b/Cargo.toml
index 7b38169..323ed46 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,12 +22,11 @@ version = "*"
version = "*"
features = ["default", "v1_19_3"]
+[patch.crates-io.craftio-rs]
+# git = "https://github.com/Twister915/craftio-rs.git"
+path = "../craftio-rs"
+
[patch.crates-io.mcproto-rs]
# git = "https://github.com/Web-44/mcproto-rs.git"
path = "../mcproto-rs"
-[patch.crates-io.craftio-rs]
-git = "https://github.com/romangraef/craftio-rs.git"
-branch = "fix/read_packet_len"
-
-
diff --git a/packetorder.txt b/packetorder.txt
new file mode 100644
index 0000000..89c9f4d
--- /dev/null
+++ b/packetorder.txt
@@ -0,0 +1,159 @@
+0 0x0 ClientboundAddEntityPacket
+1 0x1 ClientboundAddExperienceOrbPacket
+2 0x2 ClientboundAddPlayerPacket
+3 0x3 ClientboundAnimatePacket
+4 0x4 ClientboundAwardStatsPacket
+5 0x5 ClientboundBlockChangedAckPacket
+6 0x6 ClientboundBlockDestructionPacket
+7 0x7 ClientboundBlockEntityDataPacket
+8 0x8 ClientboundBlockEventPacket
+9 0x9 ClientboundBlockUpdatePacket
+10 0xa ClientboundBossEventPacket
+11 0xb ClientboundChangeDifficultyPacket
+12 0xc ClientboundClearTitlesPacket
+13 0xd ClientboundCommandSuggestionsPacket
+14 0xe ClientboundCommandsPacket
+15 0xf ClientboundContainerClosePacket
+16 0x10 ClientboundContainerSetContentPacket
+17 0x11 ClientboundContainerSetDataPacket
+18 0x12 ClientboundContainerSetSlotPacket
+19 0x13 ClientboundCooldownPacket
+20 0x14 ClientboundCustomChatCompletionsPacket
+21 0x15 ClientboundCustomPayloadPacket
+22 0x16 ClientboundDeleteChatPacket
+23 0x17 ClientboundDisconnectPacket
+24 0x18 ClientboundDisguisedChatPacket
+25 0x19 ClientboundEntityEventPacket
+26 0x1a ClientboundExplodePacket
+27 0x1b ClientboundForgetLevelChunkPacket
+28 0x1c ClientboundGameEventPacket
+29 0x1d ClientboundHorseScreenOpenPacket
+30 0x1e ClientboundInitializeBorderPacket
+31 0x1f ClientboundKeepAlivePacket
+32 0x20 ClientboundLevelChunkWithLightPacket
+33 0x21 ClientboundLevelEventPacket
+34 0x22 ClientboundLevelParticlesPacket
+35 0x23 ClientboundLightUpdatePacket
+36 0x24 ClientboundLoginPacket
+37 0x25 ClientboundMapItemDataPacket
+38 0x26 ClientboundMerchantOffersPacket
+39 0x27 ClientboundMoveEntityPacket
+40 0x28 ClientboundMoveEntityPacket
+41 0x29 ClientboundMoveEntityPacket
+42 0x2a ClientboundMoveVehiclePacket
+43 0x2b ClientboundOpenBookPacket
+44 0x2c ClientboundOpenScreenPacket
+45 0x2d ClientboundOpenSignEditorPacket
+46 0x2e ClientboundPingPacket
+47 0x2f ClientboundPlaceGhostRecipePacket
+48 0x30 ClientboundPlayerAbilitiesPacket
+49 0x31 ClientboundPlayerChatPacket
+50 0x32 ClientboundPlayerCombatEndPacket
+51 0x33 ClientboundPlayerCombatEnterPacket
+52 0x34 ClientboundPlayerCombatKillPacket
+53 0x35 ClientboundPlayerInfoRemovePacket
+54 0x36 ClientboundPlayerInfoUpdatePacket
+55 0x37 ClientboundPlayerLookAtPacket
+56 0x38 ClientboundPlayerPositionPacket
+57 0x39 ClientboundRecipePacket
+58 0x3a ClientboundRemoveEntitiesPacket
+59 0x3b ClientboundRemoveMobEffectPacket
+60 0x3c ClientboundResourcePackPacket
+61 0x3d ClientboundRespawnPacket
+62 0x3e ClientboundRotateHeadPacket
+63 0x3f ClientboundSectionBlocksUpdatePacket
+64 0x40 ClientboundSelectAdvancementsTabPacket
+65 0x41 ClientboundServerDataPacket
+66 0x42 ClientboundSetActionBarTextPacket
+67 0x43 ClientboundSetBorderCenterPacket
+68 0x44 ClientboundSetBorderLerpSizePacket
+69 0x45 ClientboundSetBorderSizePacket
+70 0x46 ClientboundSetBorderWarningDelayPacket
+71 0x47 ClientboundSetBorderWarningDistancePacket
+72 0x48 ClientboundSetCameraPacket
+73 0x49 ClientboundSetCarriedItemPacket
+74 0x4a ClientboundSetChunkCacheCenterPacket
+75 0x4b ClientboundSetChunkCacheRadiusPacket
+76 0x4c ClientboundSetDefaultSpawnPositionPacket
+77 0x4d ClientboundSetDisplayObjectivePacket
+78 0x4e ClientboundSetEntityDataPacket
+79 0x4f ClientboundSetEntityLinkPacket
+80 0x50 ClientboundSetEntityMotionPacket
+81 0x51 ClientboundSetEquipmentPacket
+82 0x52 ClientboundSetExperiencePacket
+83 0x53 ClientboundSetHealthPacket
+84 0x54 ClientboundSetObjectivePacket
+85 0x55 ClientboundSetPassengersPacket
+86 0x56 ClientboundSetPlayerTeamPacket
+87 0x57 ClientboundSetScorePacket
+88 0x58 ClientboundSetSimulationDistancePacket
+89 0x59 ClientboundSetSubtitleTextPacket
+90 0x5a ClientboundSetTimePacket
+91 0x5b ClientboundSetTitleTextPacket
+92 0x5c ClientboundSetTitlesAnimationPacket
+93 0x5d ClientboundSoundEntityPacket
+94 0x5e ClientboundSoundPacket
+95 0x5f ClientboundStopSoundPacket
+96 0x60 ClientboundSystemChatPacket
+97 0x61 ClientboundTabListPacket
+98 0x62 ClientboundTagQueryPacket
+99 0x63 ClientboundTakeItemEntityPacket
+100 0x64 ClientboundTeleportEntityPacket
+101 0x65 ClientboundUpdateAdvancementsPacket
+102 0x66 ClientboundUpdateAttributesPacket
+103 0x67 ClientboundUpdateEnabledFeaturesPacket
+104 0x68 ClientboundUpdateMobEffectPacket
+105 0x69 ClientboundUpdateRecipesPacket
+106 0x6a ClientboundUpdateTagsPacket
+
+0 0x0 ServerboundAcceptTeleportationPacket
+1 0x1 ServerboundBlockEntityTagQuery
+2 0x2 ServerboundChangeDifficultyPacket
+3 0x3 ServerboundChatAckPacket
+4 0x4 ServerboundChatCommandPacket
+5 0x5 ServerboundChatPacket
+6 0x6 ServerboundClientCommandPacket
+7 0x7 ServerboundClientInformationPacket
+8 0x8 ServerboundCommandSuggestionPacket
+9 0x9 ServerboundContainerButtonClickPacket
+10 0xa ServerboundContainerClickPacket
+11 0xb ServerboundContainerClosePacket
+12 0xc ServerboundCustomPayloadPacket
+13 0xd ServerboundEditBookPacket
+14 0xe ServerboundEntityTagQuery
+15 0xf ServerboundInteractPacket
+16 0x10 ServerboundJigsawGeneratePacket
+17 0x11 ServerboundKeepAlivePacket
+18 0x12 ServerboundLockDifficultyPacket
+19 0x13 ServerboundMovePlayerPacket
+20 0x14 ServerboundMovePlayerPacket
+21 0x15 ServerboundMovePlayerPacket
+22 0x16 ServerboundMovePlayerPacket
+23 0x17 ServerboundMoveVehiclePacket
+24 0x18 ServerboundPaddleBoatPacket
+25 0x19 ServerboundPickItemPacket
+26 0x1a ServerboundPlaceRecipePacket
+27 0x1b ServerboundPlayerAbilitiesPacket
+28 0x1c ServerboundPlayerActionPacket
+29 0x1d ServerboundPlayerCommandPacket
+30 0x1e ServerboundPlayerInputPacket
+31 0x1f ServerboundPongPacket
+32 0x20 ServerboundChatSessionUpdatePacket
+33 0x21 ServerboundRecipeBookChangeSettingsPacket
+34 0x22 ServerboundRecipeBookSeenRecipePacket
+35 0x23 ServerboundRenameItemPacket
+36 0x24 ServerboundResourcePackPacket
+37 0x25 ServerboundSeenAdvancementsPacket
+38 0x26 ServerboundSelectTradePacket
+39 0x27 ServerboundSetBeaconPacket
+40 0x28 ServerboundSetCarriedItemPacket
+41 0x29 ServerboundSetCommandBlockPacket
+42 0x2a ServerboundSetCommandMinecartPacket
+43 0x2b ServerboundSetCreativeModeSlotPacket
+44 0x2c ServerboundSetJigsawBlockPacket
+45 0x2d ServerboundSetStructureBlockPacket
+46 0x2e ServerboundSignUpdatePacket
+47 0x2f ServerboundSwingPacket
+48 0x30 ServerboundTeleportToEntityPacket
+49 0x31 ServerboundUseItemOnPacket
+50 0x32 ServerboundUseItemPacket \ No newline at end of file
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
new file mode 100644
index 0000000..5d56faf
--- /dev/null
+++ b/rust-toolchain.toml
@@ -0,0 +1,2 @@
+[toolchain]
+channel = "nightly"
diff --git a/src/main.rs b/src/main.rs
index 80dea19..1e1c306 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,15 +1,16 @@
use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener, TcpStream};
+use std::time::Duration;
use anyhow::Result;
use craftio_rs::{CraftIo, CraftSyncReader, CraftSyncWriter, CraftTcpConnection};
-use mcproto_rs::nbt::{NamedTag, Tag};
+use mcproto_rs::nbt::Tag;
use mcproto_rs::protocol::{HasPacketKind, State};
+use mcproto_rs::Serializer;
use mcproto_rs::status::{StatusPlayersSpec, StatusSpec, StatusVersionSpec};
-use mcproto_rs::types::{Chat, NamedNbtTag};
+use mcproto_rs::types::{BytesSerializer, Chat, IntPosition, ItemStack, NamedNbtTag, Slot, Vec3};
use mcproto_rs::uuid::UUID4;
-use mcproto_rs::v1_19_3::{GameMode, HandshakeNextState, LoginPlaySpec, LoginSuccessSpec,
- Packet761, Packet761Kind, PingRequestSpec, PingResponseSpec,
- PreviousGameMode, RawPacket761, StatusResponseSpec};
+use mcproto_rs::v1_19_3::{BitSet, BlobArray, BookSettings, ChunkDataAndUpdateLightSpec, ChunkDataSpec, ChunkSection, CommandNode, CommandNodeSpec, CommandsSpec, EntityEventSpec, InitializeWorldBorderSpec, KeepAliveClientBoundSpec, LightDataSpec, PalettedContainer, RecipeBookAction, RecipeBookInitSpec, SetCenterChunkSpec, SetContainerContentSpec, SetDefaultSpawnPositionSpec, SynchronizePlayerPositionSpec, TagType, TypedTagList, UpdateRecipeBookSpec};
+use mcproto_rs::v1_19_3::{GameMode, HandshakeNextState, LoginPlaySpec, LoginSuccessSpec, Packet761, Packet761Kind, PingRequestSpec, PingResponseSpec, PreviousGameMode, RawPacket761, SetHeldItemClientSpec, StatusResponseSpec, UpdateRecipesSpec, UpdateTagsSpec};
use tokio;
pub struct MinecraftClient {
@@ -197,6 +198,12 @@ async fn handle_conn(mut client: MinecraftClient) -> Result<()> {
properties: vec![].into(),
}))
.await?;
+ let min_build_height = -64i32;
+ let max_build_height = 256i32;
+ let world_height = max_build_height - min_build_height;
+ let min_world_section = min_build_height >> 4;
+ let max_world_section = ((max_build_height - 1) >> 4) + 1;
+ let section_count = max_world_section - min_world_section;
let overworld_spec = nbt! {
"id" :: (0),
"name" :: ("minecraft:overworld"),
@@ -208,10 +215,10 @@ async fn handle_conn(mut client: MinecraftClient) -> Result<()> {
"has_ceiling" :: (false),
"has_skylight" :: (true),
"has_raids" :: (false),
- "height" :: (384),
+ "height" :: (world_height),
"infiniburn" :: ("#minecraft:infiniburn_overworld"),
- "logical_height" :: (384),
- "min_y" :: (-64),
+ "logical_height" :: (world_height),
+ "min_y" :: (min_build_height),
"monster_spawn_block_light_limit" :: (0),
"monster_spawn_light_level" :: {
"type" :: ("minecraft:uniform"),
@@ -287,7 +294,161 @@ async fn handle_conn(mut client: MinecraftClient) -> Result<()> {
.await?;
let client_information = await_packet!(ClientInformation, client);
println!("Client Information: {:?}", client_information);
- anyhow::bail!("TODO");
+ client.send_packet(Packet761::SetHeldItemClient(SetHeldItemClientSpec {
+ selected_slot: 0,
+ })).await?;
+ client.send_packet(Packet761::UpdateRecipes(UpdateRecipesSpec { recipes: vec![].into() })).await?;
+ client.send_packet(Packet761::UpdateTags(UpdateTagsSpec {
+ tags: vec![
+ TypedTagList {
+ tag_type: TagType::Block,
+ tags: vec![].into(),
+ },
+ TypedTagList {
+ tag_type: TagType::Item,
+ tags: vec![].into(),
+ },
+ TypedTagList {
+ tag_type: TagType::EntityType,
+ tags: vec![].into(),
+ },
+ TypedTagList {
+ tag_type: TagType::GameEvent,
+ tags: vec![].into(),
+ },
+ TypedTagList {
+ tag_type: TagType::Fluid,
+ tags: vec![].into(),
+ },
+ ].into(),
+ })).await?;
+ client.send_packet(Packet761::EntityEvent(EntityEventSpec {
+ entity_id: 0,
+ entity_status: 24 /* OP permission level = 0 */,
+ })).await?;
+ client.send_packet(Packet761::Commands(CommandsSpec {
+ nodes: vec![
+ CommandNodeSpec {
+ children_indices: vec![].into(),
+ redirect_node: None,
+ is_executable: false,
+ node: CommandNode::Root,
+ }
+ ].into(),
+ root_index: 0.into(),
+ })).await?;
+ client.send_packet(Packet761::UpdateRecipeBook(UpdateRecipeBookSpec {
+ action: RecipeBookAction::Init(RecipeBookInitSpec {
+ book_settings: BookSettings::default(),
+ known_recipes: vec![].into(),
+ highlighted_recipes: vec![].into(),
+ })
+ })).await?;
+ client.send_packet(Packet761::SynchronizePlayerPosition(SynchronizePlayerPositionSpec {
+ position: Vec3 {
+ x: 0f64,
+ y: 100f64,
+ z: 0f64,
+ },
+ yaw: 0.0,
+ pitch: 0.0,
+ flags: Default::default(),
+ teleport_id: 0.into(),
+ dismount_vehicle: false,
+ })).await?;
+ client.send_packet(Packet761::SetCenterChunk(SetCenterChunkSpec {
+ chunk_x: 0.into(),
+ chunk_z: 0.into(),
+ })).await?;
+ for i in -7..7 {
+ for j in -7..7 {
+ let mut heightmap = BlobArray::new(9);
+ for cx in 0..(16 * 16) {
+ heightmap.set_entry(cx, 2)
+ }
+ let mut chunk_dat_serializer = BytesSerializer::default();
+ for i in 0..section_count {
+ let section = ChunkSection {
+ block_count: if i < 4 { 16 * 16 * 16 } else { 0 },
+ block_state: PalettedContainer { singular_value: if i < 4 { 1.into() } else { 0.into() } },
+ biomes: PalettedContainer { singular_value: 0.into() },
+ };
+ chunk_dat_serializer.serialize_other(&section)?;
+ }
+ let chunk_column_bytes = chunk_dat_serializer.into_bytes();
+ client.send_packet(Packet761::ChunkDataAndUpdateLight(ChunkDataAndUpdateLightSpec {
+ chunk_x: i,
+ chunk_z: j,
+ chunk_data: ChunkDataSpec {
+ heightmaps: NamedNbtTag {
+ root: nbt! {
+ "MOTION_BLOCKING" :: (Tag::LongArray(heightmap.data.iter().map(|n| n.to_owned() as _).collect())),
+ "WORLD_SURFACE" :: (Tag::LongArray(heightmap.data.iter().map(|n| n.to_owned() as _).collect())),
+ }.with_name("root")
+ },
+ buffer: chunk_column_bytes.into(),
+ block_entities: vec![].into(),
+ },
+ light_data: LightDataSpec {
+ trust_edges: true,
+ sky_y_mask: BitSet::empty(),
+ block_y_mask: BitSet::empty(),
+ empty_sky_y_mask: BitSet::empty(),
+ empty_block_y_mask: BitSet::empty(),
+ sky_updates: vec![].into(),
+ block_updates: vec![].into(),
+ },
+ })).await?;
+ }
+ }
+ client.send_packet(Packet761::InitializeWorldBorder(InitializeWorldBorderSpec {
+ x: 0.0,
+ z: 0.0,
+ old_diameter: 10000000.0,
+ new_diameter: 10000000.0,
+ speed: 0.into(),
+ portal_teleport_boundary: 29999984.into(),
+ warning_blocks: 0.into(),
+ warning_time: 0.into(),
+ })).await?;
+ client.send_packet(Packet761::SetDefaultSpawnPosition(SetDefaultSpawnPositionSpec {
+ location: IntPosition {
+ x: 0,
+ y: 0,
+ z: 0,
+ },
+ angle: 0.0,
+ })).await?;
+ client.send_packet(Packet761::SynchronizePlayerPosition(SynchronizePlayerPositionSpec {
+ position: Vec3 {
+ x: 0f64,
+ y: 100f64,
+ z: 0f64,
+ },
+ yaw: 0.0,
+ pitch: 0.0,
+ flags: Default::default(),
+ teleport_id: 0.into(),
+ dismount_vehicle: false,
+ })).await?;
+ client.send_packet(Packet761::SetContainerContent(SetContainerContentSpec {
+ window_id: 0,
+ state_id: 0.into(),
+ slot_data: vec![Some(ItemStack {
+ item_id: 1.into(),
+ item_count: 1,
+ nbt: None,
+ }); 45].into(),
+ carried_item: None,
+ }));
+ let mut i = 0;
+ loop {
+ client.send_packet(Packet761::KeepAliveClientBound(KeepAliveClientBoundSpec {
+ keep_alive_id: i,
+ })).await?;
+ i += 1;
+ tokio::time::sleep(Duration::from_secs(10)).await;
+ }
} else if hs.next_state == HandshakeNextState::Status {
return handle_status(client).await;
} else {