Structure tweaks
All checks were successful
Build & Test / nix-build (push) Successful in 1m7s

This commit is contained in:
Kodi Craft 2024-07-10 09:11:45 +02:00
parent 361655da52
commit 54113589f9
Signed by: kodi
GPG Key ID: 69D9EED60B242822
5 changed files with 51 additions and 7 deletions

View File

@ -24,7 +24,13 @@ defmodule Amethyst.Server.Configuration do
alias Amethyst.Minecraft.Read alias Amethyst.Minecraft.Read
alias Amethyst.Minecraft.Write alias Amethyst.Minecraft.Write
@impl true
def init(state) do
state
end
## DESERIALIZATION ## DESERIALIZATION
@impl true
# Client Information https://wiki.vg/Protocol#Client_Information # Client Information https://wiki.vg/Protocol#Client_Information
def deserialize(0x00, data) do def deserialize(0x00, data) do
{[locale, view_dist, chat_mode, chat_colors, displayed_skin_parts, main_hand, text_filtering, allow_listing], ""} = {[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 end
## SERIALIZATION ## SERIALIZATION
@impl true
# Cookie Request https://wiki.vg/Protocol#Cookie_Request_(configuration) # Cookie Request https://wiki.vg/Protocol#Cookie_Request_(configuration)
def serialize({:cookie_request, id}) do def serialize({:cookie_request, id}) do
Write.varint(0x00) <> Write.string(id) Write.varint(0x00) <> Write.string(id)
@ -227,6 +234,8 @@ defmodule Amethyst.Server.Configuration do
end end
## HANDLING ## HANDLING
@impl true
# Serverbound Plugin Message https://wiki.vg/Protocol#Serverbound_Plugin_Message_(configuration)
def handle({:serverbound_plugin_message, channel, data}, client, state) do def handle({:serverbound_plugin_message, channel, data}, client, state) do
handle_plugin_message(channel, data, client, state) handle_plugin_message(channel, data, client, state)
end end

View File

@ -46,12 +46,24 @@ defmodule Amethyst.Server do
@moduledoc """ @moduledoc """
This module includes shared boilerplate code for all stages of the server. 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 defmacro __using__(_opts) do
quote 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 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) {id, data} = Amethyst.Server.Generic.get_packet(client)
Logger.debug("State: #{inspect(state)}") Logger.debug("State: #{inspect(state)}")
packet = deserialize(id, data) packet = deserialize(id, data)
@ -63,7 +75,6 @@ require Logger
serve(client, state) serve(client, state)
end end
def transmit(packet, client) do def transmit(packet, client) do
Logger.debug("Transmitting #{inspect(packet)}") Logger.debug("Transmitting #{inspect(packet)}")
data = serialize(packet) data = serialize(packet)

View File

@ -23,7 +23,13 @@ defmodule Amethyst.Server.Handshake do
alias Amethyst.Minecraft.Read alias Amethyst.Minecraft.Read
@impl true
def init(state) do
state
end
## DESERIALIZATION ## DESERIALIZATION
@impl true
# Handshake https://wiki.vg/Protocol#Handshake # Handshake https://wiki.vg/Protocol#Handshake
@spec deserialize(0, binary()) :: @spec deserialize(0, binary()) ::
{:handshake, any(), any(), any(), :login | :status | :transfer} {:handshake, any(), any(), any(), :login | :status | :transfer}
@ -42,18 +48,20 @@ defmodule Amethyst.Server.Handshake do
end end
## SERIALIZATION ## SERIALIZATION
@impl true
def serialize(_) do def serialize(_) do
raise RuntimeError, "No packets can be transmitted while still in the handshake stage!" raise RuntimeError, "No packets can be transmitted while still in the handshake stage!"
end end
## HANDLING ## HANDLING
@impl true
# Handshake https://wiki.vg/Protocol#Handshake # Handshake https://wiki.vg/Protocol#Handshake
@spec handle(any(), any(), any()) :: no_return() @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}") Logger.info("Got handshake, version 767 on #{addr}:#{port}. Wants to move to #{next}")
case next do case next do
:status -> Amethyst.Server.Status.serve(client) :status -> Amethyst.Server.Status.serve(client, state)
:login -> Amethyst.Server.Login.serve(client) :login -> Amethyst.Server.Login.serve(client, state)
_ -> raise RuntimeError, "Unhandled move to next mode #{next}" _ -> raise RuntimeError, "Unhandled move to next mode #{next}"
end end
end end

View File

@ -24,7 +24,13 @@ defmodule Amethyst.Server.Login do
alias Amethyst.Minecraft.Read alias Amethyst.Minecraft.Read
alias Amethyst.Minecraft.Write alias Amethyst.Minecraft.Write
@impl true
def init(state) do
state
end
## DESERIALIZATION ## DESERIALIZATION
@impl true
# Login Start https://wiki.vg/Protocol#Login_Start # Login Start https://wiki.vg/Protocol#Login_Start
def deserialize(0x00, data) do def deserialize(0x00, data) do
{[name, uuid], ""} = Read.start(data) |> Read.string() |> Read.uuid() |> Read.stop() {[name, uuid], ""} = Read.start(data) |> Read.string() |> Read.uuid() |> Read.stop()
@ -66,6 +72,7 @@ defmodule Amethyst.Server.Login do
end end
## SERIALIZATION ## SERIALIZATION
@impl true
# Disconnect (login) https://wiki.vg/Protocol#Disconnect_(login) # Disconnect (login) https://wiki.vg/Protocol#Disconnect_(login)
def serialize({:disconnect, reason}) do def serialize({:disconnect, reason}) do
Write.varint(0x00) <> Write.string(reason) Write.varint(0x00) <> Write.string(reason)
@ -103,6 +110,7 @@ defmodule Amethyst.Server.Login do
end end
## HANDLING ## HANDLING
@impl true
# Login Start https://wiki.vg/Protocol#Login_Start # Login Start https://wiki.vg/Protocol#Login_Start
def handle({:login_start, name, uuid}, client, state) do def handle({:login_start, name, uuid}, client, state) do
Logger.info("Logging in #{name} (#{uuid})") Logger.info("Logging in #{name} (#{uuid})")
@ -118,7 +126,7 @@ defmodule Amethyst.Server.Login do
{:ok, state} {:ok, state}
end end
def handle({:login_acknowledged}, client, state) do def handle({:login_acknowledged}, client, state) do
Amethyst.Server.Configuration.serve(client) Amethyst.Server.Configuration.serve(client, state)
{:ok, state} {:ok, state}
end end
def handle(tuple, _, state) do def handle(tuple, _, state) do

View File

@ -24,7 +24,13 @@ defmodule Amethyst.Server.Status do
alias Amethyst.Minecraft.Read alias Amethyst.Minecraft.Read
alias Amethyst.Minecraft.Write alias Amethyst.Minecraft.Write
@impl true
def init(state) do
state
end
## DESERIALIZATION ## DESERIALIZATION
@impl true
# Status Request https://wiki.vg/Protocol#Status_Request # Status Request https://wiki.vg/Protocol#Status_Request
def deserialize(0x00, _) do def deserialize(0x00, _) do
{:status_request} {:status_request}
@ -39,6 +45,7 @@ defmodule Amethyst.Server.Status do
end end
## SERIALIZATION ## SERIALIZATION
@impl true
# Status Response https://wiki.vg/Protocol#Status_Response # Status Response https://wiki.vg/Protocol#Status_Response
def serialize({:status_response, data}) do def serialize({:status_response, data}) do
Write.varint(0x00) <> Write.string(data) Write.varint(0x00) <> Write.string(data)
@ -51,6 +58,7 @@ defmodule Amethyst.Server.Status do
end end
## HANDLING ## HANDLING
@impl true
# Status Request https://wiki.vg/Protocol#Status_Request # Status Request https://wiki.vg/Protocol#Status_Request
def handle({:status_request}, client, state) do def handle({:status_request}, client, state) do
# We want to make this more dynamic in the future, but this works for now # We want to make this more dynamic in the future, but this works for now