From 54113589f9658286e3f66eaab129e196709887e6 Mon Sep 17 00:00:00 2001 From: Kodi Craft Date: Wed, 10 Jul 2024 09:11:45 +0200 Subject: [PATCH] Structure tweaks --- lib/servers/configuration.ex | 9 +++++++++ lib/servers/generic.ex | 17 ++++++++++++++--- lib/servers/handhsake.ex | 14 +++++++++++--- lib/servers/login.ex | 10 +++++++++- lib/servers/status.ex | 8 ++++++++ 5 files changed, 51 insertions(+), 7 deletions(-) diff --git a/lib/servers/configuration.ex b/lib/servers/configuration.ex index 2b026ce..e789a15 100644 --- a/lib/servers/configuration.ex +++ b/lib/servers/configuration.ex @@ -24,7 +24,13 @@ defmodule Amethyst.Server.Configuration do alias Amethyst.Minecraft.Read alias Amethyst.Minecraft.Write + @impl true + def init(state) do + state + end + ## DESERIALIZATION + @impl true # Client Information https://wiki.vg/Protocol#Client_Information def deserialize(0x00, data) do {[locale, view_dist, chat_mode, chat_colors, displayed_skin_parts, main_hand, text_filtering, allow_listing], ""} = @@ -102,6 +108,7 @@ defmodule Amethyst.Server.Configuration do end ## SERIALIZATION + @impl true # Cookie Request https://wiki.vg/Protocol#Cookie_Request_(configuration) def serialize({:cookie_request, id}) do Write.varint(0x00) <> Write.string(id) @@ -227,6 +234,8 @@ defmodule Amethyst.Server.Configuration do end ## HANDLING + @impl true + # Serverbound Plugin Message https://wiki.vg/Protocol#Serverbound_Plugin_Message_(configuration) def handle({:serverbound_plugin_message, channel, data}, client, state) do handle_plugin_message(channel, data, client, state) end diff --git a/lib/servers/generic.ex b/lib/servers/generic.ex index 44e4956..b393181 100644 --- a/lib/servers/generic.ex +++ b/lib/servers/generic.ex @@ -46,12 +46,24 @@ defmodule Amethyst.Server do @moduledoc """ This module includes shared boilerplate code for all stages of the server. """ -require Logger + require Logger + + @callback init(any()) :: any() + @callback deserialize(integer(), binary()) :: any() + @callback serialize(any()) :: binary() + @callback handle(any(), :gen_tcp.socket(), any()) :: {:ok, any()} | {:unhandled, any()} defmacro __using__(_opts) do quote do - @spec serve(:gen_tcp.socket()) :: no_return() + @behaviour Amethyst.Server + + @spec serve(:gen_tcp.socket(), any()) :: no_return() def serve(client, state \\ []) do + Logger.debug("#{__MODULE__} serving client #{inspect(client)}") + serve(client, init(state)) + end + + defp serve_loop(client, state) do {id, data} = Amethyst.Server.Generic.get_packet(client) Logger.debug("State: #{inspect(state)}") packet = deserialize(id, data) @@ -63,7 +75,6 @@ require Logger serve(client, state) end - def transmit(packet, client) do Logger.debug("Transmitting #{inspect(packet)}") data = serialize(packet) diff --git a/lib/servers/handhsake.ex b/lib/servers/handhsake.ex index 4652b41..499d2cd 100644 --- a/lib/servers/handhsake.ex +++ b/lib/servers/handhsake.ex @@ -23,7 +23,13 @@ defmodule Amethyst.Server.Handshake do alias Amethyst.Minecraft.Read + @impl true + def init(state) do + state + end + ## DESERIALIZATION + @impl true # Handshake https://wiki.vg/Protocol#Handshake @spec deserialize(0, binary()) :: {:handshake, any(), any(), any(), :login | :status | :transfer} @@ -42,18 +48,20 @@ defmodule Amethyst.Server.Handshake do end ## SERIALIZATION + @impl true def serialize(_) do raise RuntimeError, "No packets can be transmitted while still in the handshake stage!" end ## HANDLING + @impl true # Handshake https://wiki.vg/Protocol#Handshake @spec handle(any(), any(), any()) :: no_return() - def handle({:handshake, 767, addr, port, next}, client, _state) do + def handle({:handshake, 767, addr, port, next}, client, state) do Logger.info("Got handshake, version 767 on #{addr}:#{port}. Wants to move to #{next}") case next do - :status -> Amethyst.Server.Status.serve(client) - :login -> Amethyst.Server.Login.serve(client) + :status -> Amethyst.Server.Status.serve(client, state) + :login -> Amethyst.Server.Login.serve(client, state) _ -> raise RuntimeError, "Unhandled move to next mode #{next}" end end diff --git a/lib/servers/login.ex b/lib/servers/login.ex index b65dc64..596bd0d 100644 --- a/lib/servers/login.ex +++ b/lib/servers/login.ex @@ -24,7 +24,13 @@ defmodule Amethyst.Server.Login do alias Amethyst.Minecraft.Read alias Amethyst.Minecraft.Write + @impl true + def init(state) do + state + end + ## DESERIALIZATION + @impl true # Login Start https://wiki.vg/Protocol#Login_Start def deserialize(0x00, data) do {[name, uuid], ""} = Read.start(data) |> Read.string() |> Read.uuid() |> Read.stop() @@ -66,6 +72,7 @@ defmodule Amethyst.Server.Login do end ## SERIALIZATION + @impl true # Disconnect (login) https://wiki.vg/Protocol#Disconnect_(login) def serialize({:disconnect, reason}) do Write.varint(0x00) <> Write.string(reason) @@ -103,6 +110,7 @@ defmodule Amethyst.Server.Login do end ## HANDLING + @impl true # Login Start https://wiki.vg/Protocol#Login_Start def handle({:login_start, name, uuid}, client, state) do Logger.info("Logging in #{name} (#{uuid})") @@ -118,7 +126,7 @@ defmodule Amethyst.Server.Login do {:ok, state} end def handle({:login_acknowledged}, client, state) do - Amethyst.Server.Configuration.serve(client) + Amethyst.Server.Configuration.serve(client, state) {:ok, state} end def handle(tuple, _, state) do diff --git a/lib/servers/status.ex b/lib/servers/status.ex index 597bb4a..23a272b 100644 --- a/lib/servers/status.ex +++ b/lib/servers/status.ex @@ -24,7 +24,13 @@ defmodule Amethyst.Server.Status do alias Amethyst.Minecraft.Read alias Amethyst.Minecraft.Write + @impl true + def init(state) do + state + end + ## DESERIALIZATION + @impl true # Status Request https://wiki.vg/Protocol#Status_Request def deserialize(0x00, _) do {:status_request} @@ -39,6 +45,7 @@ defmodule Amethyst.Server.Status do end ## SERIALIZATION + @impl true # Status Response https://wiki.vg/Protocol#Status_Response def serialize({:status_response, data}) do Write.varint(0x00) <> Write.string(data) @@ -51,6 +58,7 @@ defmodule Amethyst.Server.Status do end ## HANDLING + @impl true # Status Request https://wiki.vg/Protocol#Status_Request def handle({:status_request}, client, state) do # We want to make this more dynamic in the future, but this works for now