diff --git a/lib/data.ex b/lib/data.ex index a927731..7ffe1db 100644 --- a/lib/data.ex +++ b/lib/data.ex @@ -63,6 +63,10 @@ defmodule Amethyst.Minecraft.Write do def string(value) do <> end + + def position({x, y, z}) do + <> + end end defmodule Amethyst.Minecraft.Read do diff --git a/lib/servers/play.ex b/lib/servers/play.ex index 69c4e1f..55daef5 100644 --- a/lib/servers/play.ex +++ b/lib/servers/play.ex @@ -38,7 +38,23 @@ defmodule Amethyst.Server.Play do ## SERIALIZATION @impl true - + # Login https://wiki.vg/Protocol#Login_(play) + def serialize({:login, eid, hardcore, dimensions, + max_players, view_distance, simulation_distance, + reduce_debug, enable_respawn_screen, limited_crafting, + dim_type, dim_name, hashed_seed, gamemode, prev_gm, + is_debug, is_flat, death_loc, portal_cooldown, enforce_chat}) do + # TODO: this singlehandedly made me regret not making the write API better, please rework :( + <> <> if(hardcore, do: <<1::big-8>>, else: <<0::big-8>>) <> + Write.varint(length(dimensions)) <> Enum.reduce(dimensions, "", fn dim, acc -> acc <> Write.string(dim) end) <> + Write.varint(max_players) <> Write.varint(view_distance) <> Write.varint(simulation_distance) <> if(reduce_debug, do: <<1::big-8>>, else: <<0::big-8>>) <> + if(enable_respawn_screen, do: <<1::big-8>>, else: <<0::big-8>>) + if(limited_crafting, do: <<1::big-8>>, else: <<0::big-8>>) <> Write.varint(dim_type) <> Write.string(dim_name) <> + hashed_seed <> <> <> <> <> + if(is_debug, do: <<1::big-8>>, else: <<0::big-8>>) <> if(is_flat, do: <<1::big-8>>, else: <<0::big-8>>) <> + if(death_loc == nil, do: <<0::big-8>>, else: <<1::big-8>> <> Write.string(elem(death_loc, 0)) <> Write.position(elem(death_loc, 1))) <> + Write.varint(portal_cooldown) <> if(enforce_chat, do: <<1::big-8>>, else: <<0::big-8>>) + end def serialize(packet) do raise ArgumentError, "Tried serializing unknown packet #{inspect(packet)}" end @@ -49,4 +65,14 @@ defmodule Amethyst.Server.Play do Logger.error("Unhandled but known packet #{elem(tuple, 0)}") {:unhandled, state} end + + defp gamemode_id(gm) do + case gm do + nil -> -1 + :survival -> 0 + :creative -> 1 + :adventure -> 2 + :spectator -> 3 + end + end end