work on implementing some more packets
All checks were successful
Build & Test / nix-build (pull_request) Successful in 2m38s
Build & Test / nix-build (push) Successful in 2m39s

This commit is contained in:
Kodi Craft 2024-09-26 14:47:05 +02:00
parent 034f21ade7
commit f0c2ef80ec
Signed by: kodi
GPG Key ID: 69D9EED60B242822
3 changed files with 56 additions and 21 deletions

View File

@ -303,6 +303,11 @@ defmodule Amethyst.ConnectionState.Configuration do
packet_type: :synchronize_player_position, packet_type: :synchronize_player_position,
x: x, y: y, z: z, yaw: yaw, pitch: pitch, teleport_id: 0, flags: 0x00 x: x, y: y, z: z, yaw: yaw, pitch: pitch, teleport_id: 0, flags: 0x00
}}) }})
send(self(), {:send_packet, Amethyst.ConnectionState.Play.ge_start_waiting_for_level_chunks(767)})
send(self(), {:send_packet, %{packet_type: :set_center_chunk,
chunk_x: div(x, 16),
chunk_y: div(z, 16)
}})
state state
end end
end end

View File

@ -16,18 +16,18 @@
defmodule Amethyst.ConnectionState.Macros do defmodule Amethyst.ConnectionState.Macros do
require Logger require Logger
defmacro defpacket_serverbound(name, id, version, signature) do defmacro defpacket_serverbound(name, id, version, signature, where \\ true) do
quote do quote do
def deserialize(unquote(id), unquote(version), data) do def deserialize(unquote(id), unquote(version), data) when unquote(where) do
{packet, ""} = Amethyst.ConnectionState.Macros.read_signature(data, unquote(signature)) {packet, ""} = Amethyst.ConnectionState.Macros.read_signature(data, unquote(signature))
packet |> Map.put(:packet_type, unquote(name)) packet |> Map.put(:packet_type, unquote(name))
end end
end end
end end
defmacro defpacket_clientbound(name, id, version, signature) do defmacro defpacket_clientbound(name, id, version, signature, where \\ true) do
quote do quote do
def serialize(%{packet_type: unquote(name)} = packet, unquote(version)) do def serialize(%{packet_type: unquote(name)} = packet, unquote(version)) when unquote(where) do
if Amethyst.ConnectionState.Macros.check_type(packet, unquote(signature)) do if Amethyst.ConnectionState.Macros.check_type(packet, unquote(signature)) do
Amethyst.Minecraft.Write.varint(unquote(id)) <> Amethyst.ConnectionState.Macros.write_signature(packet, unquote(signature)) Amethyst.Minecraft.Write.varint(unquote(id)) <> Amethyst.ConnectionState.Macros.write_signature(packet, unquote(signature))
else else
@ -79,7 +79,6 @@ defmodule Amethyst.ConnectionState.Macros do
def write_signature(packet, signature) do def write_signature(packet, signature) do
Enum.reduce(signature, "", fn {name, type}, acc -> Enum.reduce(signature, "", fn {name, type}, acc ->
#acc <> apply(Write, type, [Map.get(packet, name)])
case type do case type do
{:optional, {:compound, signature}} -> {:optional, {:compound, signature}} ->
case Map.get(packet, name) do case Map.get(packet, name) do
@ -126,8 +125,8 @@ defmodule Amethyst.ConnectionState.Macros do
def type_matches(value, :ushort) when is_integer(value) and value in 0..65535, do: true def type_matches(value, :ushort) when is_integer(value) and value in 0..65535, do: true
def type_matches(value, :int) when is_integer(value) and value in -2147483648..2147483647, do: true def type_matches(value, :int) when is_integer(value) and value in -2147483648..2147483647, do: true
def type_matches(value, :long) when is_integer(value) and value in -9223372036854775808..9223372036854775807, do: true def type_matches(value, :long) when is_integer(value) and value in -9223372036854775808..9223372036854775807, do: true
def type_matches(value, :float) when is_float(value), do: true def type_matches(value, :float) when is_number(value), do: true
def type_matches(value, :double) when is_float(value), do: true def type_matches(value, :double) when is_number(value), do: true
def type_matches(value, :varint) when is_integer(value) and value in -2147483648..2147483647, do: true def type_matches(value, :varint) when is_integer(value) and value in -2147483648..2147483647, do: true
def type_matches(value, :varlong) when is_integer(value) and value in -9223372036854775808..9223372036854775807, do: true def type_matches(value, :varlong) when is_integer(value) and value in -9223372036854775808..9223372036854775807, do: true
def type_matches(value, :uuid) when is_binary(value) and byte_size(value) == 36, do: true def type_matches(value, :uuid) when is_binary(value) and byte_size(value) == 36, do: true

View File

@ -16,7 +16,6 @@
defmodule Amethyst.ConnectionState.Play do defmodule Amethyst.ConnectionState.Play do
require Amethyst.ConnectionState.Macros require Amethyst.ConnectionState.Macros
alias Amethyst.Minecraft.Write
alias Amethyst.ConnectionState.Macros alias Amethyst.ConnectionState.Macros
require Logger require Logger
@ -26,6 +25,28 @@ defmodule Amethyst.ConnectionState.Play do
""" """
Macros.defpacket_clientbound :disconnect, 0x1D, 767, [reason: :nbt] Macros.defpacket_clientbound :disconnect, 0x1D, 767, [reason: :nbt]
Macros.defpacket_clientbound :chunk_data_and_update_light, 0x27, 767, [
chunk_x: :int,
chunk_z: :int,
heightmaps: :nbt,
data: :byte_array,
block_entities: {:array, [
packed_xz: :ubyte, # TODO: This would be interesting to have in a clearer format
y: :short,
type: :varint,
data: :nbt
]},
sky_light_mask: :raw,
block_light_mask: :raw,
empty_sky_light_mask: :raw,
empty_block_light_mask: :raw,
sky_light_arrays: {:array, [
sky_light_array: :byte_array
]},
block_light_arrays: {:array, [
block_light_array: :byte_array
]}
]
Macros.defpacket_clientbound :login, 0x2B, 767, [ Macros.defpacket_clientbound :login, 0x2B, 767, [
entity_id: :int, entity_id: :int,
is_hardcore: :bool, is_hardcore: :bool,
@ -59,6 +80,29 @@ defmodule Amethyst.ConnectionState.Play do
flags: :byte, flags: :byte,
teleport_id: :varint teleport_id: :varint
] ]
Macros.defpacket_clientbound :set_center_chunk, 0x54, 767, [
chunk_x: :varint, chunk_z: :varint
]
Macros.defpacket_clientbound :game_event, 0x22, 767, [
event: :ubyte, value: :float
]
# We can use functions to wrap over this packet and make it a bit clearer.
# Taking the protocol version here makes it less portable but whatever, fuck this packet
def ge_no_respawn_block_available(767), do: %{packet_type: :game_event, event: 0, value: 0}
def ge_begin_raining(767), do: %{packet_type: :game_event, event: 1, value: 0}
def ge_end_raining(767), do: %{packet_type: :game_event, event: 2, value: 0}
def ge_change_game_mode(767, gm) when is_integer(gm), do: %{packet_type: :game_event, event: 3, value: gm}
def ge_win_game(767, credits?) when is_integer(credits?), do: %{packet_type: :game_event, event: 4, value: credits?}
def ge_game_event(767, event) when is_integer(event), do: %{packet_type: :game_event, event: 5, value: event}
def ge_arrow_hit_player(767), do: %{packet_type: :game_event, event: 6, value: 0}
def ge_rain_level_change(767, value) when is_number(value), do: %{packet_type: :game_event, event: 7, value: value}
def ge_thunder_level_change(767, value) when is_number(value), do: %{packet_type: :game_event, event: 8, value: value}
def ge_play_pufferfish_sting_sound(767), do: %{packet_type: :game_event, event: 9, value: 0}
def ge_play_elder_guardian_mob_appearance(767), do: %{packet_type: :game_event, event: 10, value: 0}
def ge_enable_respawn_screen(767, enabled?) when is_integer(enabled?), do: %{packet_type: :game_event, event: 11, value: enabled?}
def ge_limited_crafting(767, enabled?) when is_integer(enabled?), do: %{packet_type: :game_event, event: 12, value: enabled?}
def ge_start_waiting_for_level_chunks(767), do: %{packet_type: :game_event, event: 13, value: 0}
Macros.defpacket_serverbound :confirm_teleportation, 0x00, 767, [teleport_id: :varint] Macros.defpacket_serverbound :confirm_teleportation, 0x00, 767, [teleport_id: :varint]
Macros.defpacket_serverbound :set_player_position, 0x1A, 767, [ Macros.defpacket_serverbound :set_player_position, 0x1A, 767, [
@ -80,19 +124,6 @@ defmodule Amethyst.ConnectionState.Play do
pitch: :float, pitch: :float,
on_ground: :bool # I don't understand their obsession with this... on_ground: :bool # I don't understand their obsession with this...
] ]
# this packet sucks, thoughtful design is for losers anyway
def serialize(%{packet_type: :game_event, event: :no_respawn_block_available}, 767), do: Write.ubyte(0)
def serialize(%{packet_type: :game_event, event: :begin_raining}, 767), do: Write.ubyte(1)
def serialize(%{packet_type: :game_event, event: :end_raining}, 767), do: Write.ubyte(2)
def serialize(%{packet_type: :game_event, event: :change_gamemode, value: v}, 767), do: Write.ubyte(3) <> Write.float(v)
def serialize(%{packet_type: :game_event, event: :win_game, value: v}, 767), do: Write.ubyte(4) <> Write.float(v)
def serialize(%{packet_type: :game_event, event: :demo_event, value: v}, 767), do: Write.ubyte(5) <> Write.float(v)
def serialize(%{packet_type: :game_event, event: :arrow_hit_player}, 767), do: Write.ubyte(6)
def serialize(%{packet_type: :game_event, event: :rain_level_change, value: v}, 767), do: Write.ubyte(7) <> Write.float(v)
def serialize(%{packet_type: :game_event, event: :thunder_level_change, value: v}, 767), do: Write.ubyte(8) <> Write.float(v)
def serialize(%{packet_type: :game_event, event: :play_pufferfish_sting_sound}, 767), do: Write.ubyte(9)
def serialize(%{packet_type: :game_event, event: :play_elder_guardian_mob_appearance}, 767), do: Write.ubyte(10)
def handle(%{packet_type: :confirm_teleportation, teleport_id: id}, 767, state) do def handle(%{packet_type: :confirm_teleportation, teleport_id: id}, 767, state) do
Amethyst.API.Game.accept_teleport(state[:game], id) Amethyst.API.Game.accept_teleport(state[:game], id)