Support Minecraft v1.16.3 to v1.17.1 in lobby and probe logic

This commit is contained in:
timvisee
2021-11-23 15:50:07 +01:00
parent b404ab0a87
commit f6d60318e8
12 changed files with 35 additions and 35 deletions

4
Cargo.lock generated

@@ -869,7 +869,7 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "minecraft-protocol"
version = "0.1.0"
source = "git+https://github.com/timvisee/rust-minecraft-protocol?rev=5b80bc2#5b80bc2df31e07e2e6e203e652a301bd8a29a610"
source = "git+https://github.com/timvisee/rust-minecraft-protocol?rev=edfdf87#edfdf876c0c21be02afdd885e3400983f3137ec9"
dependencies = [
"byteorder",
"minecraft-protocol-derive",
@@ -882,7 +882,7 @@ dependencies = [
[[package]]
name = "minecraft-protocol-derive"
version = "0.0.0"
source = "git+https://github.com/timvisee/rust-minecraft-protocol?rev=5b80bc2#5b80bc2df31e07e2e6e203e652a301bd8a29a610"
source = "git+https://github.com/timvisee/rust-minecraft-protocol?rev=edfdf87#edfdf876c0c21be02afdd885e3400983f3137ec9"
dependencies = [
"proc-macro2",
"quote",

@@ -42,7 +42,7 @@ dotenv = "0.15"
flate2 = { version = "1.0", default-features = false, features = ["default"] }
futures = { version = "0.3", default-features = false, features = ["executor"] }
log = "0.4"
minecraft-protocol = { git = "https://github.com/timvisee/rust-minecraft-protocol", rev = "5b80bc2" }
minecraft-protocol = { git = "https://github.com/timvisee/rust-minecraft-protocol", rev = "edfdf87" }
named-binary-tag = "0.6"
notify = "4.0"
pretty_env_logger = "0.4"

@@ -23,7 +23,7 @@ Current limitations:
- Only works with offline mode
- Only works with vanilla Minecraft clients, does not work with modded (e.g. Forge, FTB)
- Probably only works with Minecraft 1.17-1.17.1 (tested with 1.17.1)
- Probably only works with Minecraft 1.16.3-1.17.1 (tested with 1.17.1)
- This method will consume the client, following configured join methods won't be used.
At this time it is unknown if some of the above limitations will ever be lifted,

@@ -134,7 +134,7 @@ command = "java -Xmx1G -Xms1G -jar server.jar --nogui"
# Don't enable this unless you know what you're doing.
#
# - Only works with offline mode
# - Only works with Minecraft 1.17-1.17.1 (tested with 1.17.1)
# - Only works with Minecraft 1.16.3-1.17.1 (tested with 1.17.1)
# - Only works with vanilla Minecraft clients, does not work with modded
# Maximum time in seconds in the lobby while the server starts.

@@ -1,6 +1,6 @@
use minecraft_protocol::decoder::Decoder;
use minecraft_protocol::error::DecodeError;
use minecraft_protocol::version::{v1_16_5, v1_17};
use minecraft_protocol::version::{v1_16_3, v1_17};
use nbt::CompoundTag;
#[cfg(feature = "lobby")]
use tokio::net::tcp::WriteHalf;
@@ -33,16 +33,16 @@ impl JoinGameData {
/// Extract join game data from given packet.
pub fn from_packet(client_info: &ClientInfo, packet: RawPacket) -> Result<Self, DecodeError> {
match client_info.protocol() {
Some(p) if p <= v1_16_5::PROTOCOL => {
Ok(v1_16_5::game::JoinGame::decode(&mut packet.data.as_slice())?.into())
Some(p) if p <= v1_16_3::PROTOCOL => {
Ok(v1_16_3::game::JoinGame::decode(&mut packet.data.as_slice())?.into())
}
_ => Ok(v1_17::game::JoinGame::decode(&mut packet.data.as_slice())?.into()),
}
}
}
impl From<v1_16_5::game::JoinGame> for JoinGameData {
fn from(join_game: v1_16_5::game::JoinGame) -> Self {
impl From<v1_16_3::game::JoinGame> for JoinGameData {
fn from(join_game: v1_16_3::game::JoinGame) -> Self {
Self {
dimension: Some(join_game.dimension),
dimension_codec: Some(join_game.dimension_codec),
@@ -74,7 +74,7 @@ impl From<v1_17::game::JoinGame> for JoinGameData {
/// Check whether the packet ID matches.
pub fn is_packet(client_info: &ClientInfo, packet_id: u8) -> bool {
match client_info.protocol() {
Some(p) if p <= v1_16_5::PROTOCOL => packet_id == v1_16_5::game::JoinGame::PACKET_ID,
Some(p) if p <= v1_16_3::PROTOCOL => packet_id == v1_16_3::game::JoinGame::PACKET_ID,
_ => packet_id == v1_17::game::JoinGame::PACKET_ID,
}
}
@@ -102,9 +102,9 @@ pub async fn lobby_send(
let status = server.status().await;
match client_info.protocol() {
Some(p) if p <= v1_16_5::PROTOCOL => {
Some(p) if p <= v1_16_3::PROTOCOL => {
packet::write_packet(
v1_16_5::game::JoinGame {
v1_16_3::game::JoinGame {
// Player ID must be unique, if it collides with another server entity ID the player gets
// in a weird state and cannot move
entity_id: 0,

@@ -1,6 +1,6 @@
use std::sync::atomic::{AtomicU64, Ordering};
use minecraft_protocol::version::{v1_16_5, v1_17};
use minecraft_protocol::version::{v1_16_3, v1_17};
use tokio::net::tcp::WriteHalf;
use crate::proto::client::{Client, ClientInfo};
@@ -21,8 +21,8 @@ pub async fn send(
let id = KEEP_ALIVE_ID.fetch_add(1, Ordering::Relaxed);
match client_info.protocol() {
Some(p) if p <= v1_16_5::PROTOCOL => {
packet::write_packet(v1_16_5::game::ClientBoundKeepAlive { id }, client, writer).await
Some(p) if p <= v1_16_3::PROTOCOL => {
packet::write_packet(v1_16_3::game::ClientBoundKeepAlive { id }, client, writer).await
}
_ => packet::write_packet(v1_17::game::ClientBoundKeepAlive { id }, client, writer).await,
}

@@ -1,4 +1,4 @@
use minecraft_protocol::version::{v1_16_5, v1_17};
use minecraft_protocol::version::{v1_16_3, v1_17};
use tokio::net::tcp::WriteHalf;
use crate::proto::client::{Client, ClientInfo};
@@ -11,9 +11,9 @@ pub async fn send(
writer: &mut WriteHalf<'_>,
) -> Result<(), ()> {
match client_info.protocol() {
Some(p) if p <= v1_16_5::PROTOCOL => {
Some(p) if p <= v1_16_3::PROTOCOL => {
packet::write_packet(
v1_16_5::game::PlayerPositionAndLook {
v1_16_3::game::PlayerPositionAndLook {
x: 0.0,
y: 0.0,
z: 0.0,

@@ -1,4 +1,4 @@
use minecraft_protocol::version::{v1_16_5, v1_17};
use minecraft_protocol::version::{v1_16_3, v1_17};
use tokio::net::tcp::WriteHalf;
use super::join_game::JoinGameData;
@@ -16,9 +16,9 @@ pub async fn lobby_send(
data: JoinGameData,
) -> Result<(), ()> {
match client_info.protocol() {
Some(p) if p <= v1_16_5::PROTOCOL => {
Some(p) if p <= v1_16_3::PROTOCOL => {
packet::write_packet(
v1_16_5::game::Respawn {
v1_16_3::game::Respawn {
dimension: data.dimension.unwrap_or_else(|| {
dimension::lobby_dimension(
&data

@@ -1,4 +1,4 @@
use minecraft_protocol::version::{v1_16_5, v1_17};
use minecraft_protocol::version::{v1_16_3, v1_17};
use tokio::net::tcp::WriteHalf;
use crate::proto::client::{Client, ClientInfo};
@@ -19,9 +19,9 @@ pub async fn send(
writer: &mut WriteHalf<'_>,
) -> Result<(), ()> {
match client_info.protocol() {
Some(p) if p <= v1_16_5::PROTOCOL => {
Some(p) if p <= v1_16_3::PROTOCOL => {
packet::write_packet(
v1_16_5::game::ClientBoundPluginMessage {
v1_16_3::game::ClientBoundPluginMessage {
channel: CHANNEL.into(),
data: SERVER_BRAND.into(),
},

@@ -1,4 +1,4 @@
use minecraft_protocol::version::{v1_16_5, v1_17};
use minecraft_protocol::version::{v1_16_3, v1_17};
use tokio::net::tcp::WriteHalf;
use crate::proto::client::{Client, ClientInfo};
@@ -12,9 +12,9 @@ pub async fn send(
sound_name: &str,
) -> Result<(), ()> {
match client_info.protocol() {
Some(p) if p <= v1_16_5::PROTOCOL => {
Some(p) if p <= v1_16_3::PROTOCOL => {
packet::write_packet(
v1_16_5::game::NamedSoundEffect {
v1_16_3::game::NamedSoundEffect {
sound_name: sound_name.into(),
sound_category: 0,
effect_pos_x: 0,

@@ -1,4 +1,4 @@
use minecraft_protocol::version::{v1_16_5, v1_17};
use minecraft_protocol::version::{v1_16_3, v1_17};
use tokio::net::tcp::WriteHalf;
use crate::proto::client::{Client, ClientInfo};
@@ -15,9 +15,9 @@ pub async fn send(
writer: &mut WriteHalf<'_>,
) -> Result<(), ()> {
match client_info.protocol() {
Some(p) if p <= v1_16_5::PROTOCOL => {
Some(p) if p <= v1_16_3::PROTOCOL => {
packet::write_packet(
v1_16_5::game::TimeUpdate {
v1_16_3::game::TimeUpdate {
world_age: 0,
time_of_day: 0,
},

@@ -1,5 +1,5 @@
use minecraft_protocol::data::chat::{Message, Payload};
use minecraft_protocol::version::{v1_16_5, v1_17};
use minecraft_protocol::version::{v1_16_3, v1_17};
use tokio::net::tcp::WriteHalf;
#[cfg(feature = "lobby")]
@@ -29,18 +29,18 @@ pub async fn send(
let subtitle = text.lines().skip(1).collect::<Vec<_>>().join("\n");
match client_info.protocol() {
Some(p) if p <= v1_16_5::PROTOCOL => send_v1_16_5(client, writer, title, &subtitle).await,
Some(p) if p <= v1_16_3::PROTOCOL => send_v1_16_3(client, writer, title, &subtitle).await,
_ => send_v1_17(client, writer, title, &subtitle).await,
}
}
async fn send_v1_16_5(
async fn send_v1_16_3(
client: &Client,
writer: &mut WriteHalf<'_>,
title: &str,
subtitle: &str,
) -> Result<(), ()> {
use v1_16_5::game::{Title, TitleAction};
use v1_16_3::game::{Title, TitleAction};
// Set title
packet::write_packet(