From 204c6b0142ccce6782bb0831ebfc9018e19b78b9 Mon Sep 17 00:00:00 2001 From: Kodi Craft Date: Sun, 21 Jul 2024 01:59:57 +0200 Subject: [PATCH] Get past configuration stage --- lib/servers/configuration.ex | 29 +++++++++++++++++--- lib/servers/play.ex | 52 ++++++++++++++++++++++++++++++++++++ mix.exs | 2 +- 3 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 lib/servers/play.ex diff --git a/lib/servers/configuration.ex b/lib/servers/configuration.ex index e789a15..946e203 100644 --- a/lib/servers/configuration.ex +++ b/lib/servers/configuration.ex @@ -97,11 +97,11 @@ defmodule Amethyst.Server.Configuration do # Serverbound Known Packs https://wiki.vg/Protocol#Serverbound_Known_Packs def deserialize(0x07, data) do {[count], rest} = Read.start(data) |> Read.varint |> Read.stop - {packs, _} = Enum.reduce(0..count, {[], rest}, fn _, {acc, rest} -> + {packs, _} = Enum.reduce(1..count, {[], rest}, fn _, {acc, rest} -> {[namespace, id, version], rest} = Read.start(rest) |> Read.string |> Read.string |> Read.string |> Read.stop {[{namespace, id, version} | acc], rest} end) - {:resource_pack_stack, packs} + {:serverbound_known_packs, packs} end def deserialize(type, _) do raise RuntimeError, "Got unknown packet type #{type}!" @@ -235,12 +235,35 @@ defmodule Amethyst.Server.Configuration do ## HANDLING @impl true + # Client Information https://wiki.vg/Protocol#Client_Information + def handle({:client_information, locale, v_dist, chat_mode, chat_colors, displayed_skin_parts, main_hand, text_filtering, allow_listing}, client, state) do + state = state |> Keyword.put(:locale, locale) |> Keyword.put(:view_dist, v_dist) |> Keyword.put(:chat_mode, chat_mode) |> + Keyword.put(:chat_colors, chat_colors) |> Keyword.put(:displayed_skin_parts, displayed_skin_parts) |> Keyword.put(:main_hand, main_hand) |> + Keyword.put(:text_filtering, text_filtering) |> Keyword.put(:allow_listing, allow_listing) + # TODO: Here we should create the game handling task for this player and give it + # this data. + transmit({:clientbound_plugin_message, "minecraft:brand", Write.string("amethyst")}, client) + transmit({:clientbound_known_packs, [{"minecraft", "core", "1.21"}]}, client) + {:ok, state} + end + # Serverbound Known Packs https://wiki.vg/Protocol#Serverbound_Known_Packs + def handle({:serverbound_known_packs, _packs}, client, state) do + # L + ratio + don't care + didn't ask + finish configuration + # TODO: we should send registries i think? does amethyst need to deal with vanilla registries at all? god only knows + transmit({:finish_configuration}, client) + {:ok, state} + end + # Acknowledge Finish Configuration https://wiki.vg/Protocol#Acknowledge_Finish_Configuration + def handle({:acknowledge_finish_configuration}, client, state) do + Amethyst.Server.Play.serve(client, state) + end # 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 - def handle(tuple, _) do + def handle(tuple, state) do Logger.error("Unhandled but known packet #{elem(tuple, 0)}") + {:unhandled, state} end defp handle_plugin_message("minecraft:brand", data, _client, state) do {[brand], ""} = Read.start(data) |> Read.string |> Read.stop diff --git a/lib/servers/play.ex b/lib/servers/play.ex new file mode 100644 index 0000000..69c4e1f --- /dev/null +++ b/lib/servers/play.ex @@ -0,0 +1,52 @@ +# Amethyst - An experimental Minecraft server written in Elixir. +# Copyright (C) 2024 KodiCraft +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +defmodule Amethyst.Server.Play do + @moduledoc """ + This module contains the logic for the Play stage of the server. + """ + require Logger + use Amethyst.Server + + alias Amethyst.Minecraft.Read + alias Amethyst.Minecraft.Write + + @impl true + def init(state) do + state + end + + ## DESERIALIZATION + @impl true + + def deserialize(type, _) do + raise RuntimeError, "Got unknown packet type #{type}!" + end + + ## SERIALIZATION + @impl true + + def serialize(packet) do + raise ArgumentError, "Tried serializing unknown packet #{inspect(packet)}" + end + + ## HANDLING + @impl true + def handle(tuple, _, state) do + Logger.error("Unhandled but known packet #{elem(tuple, 0)}") + {:unhandled, state} + end +end diff --git a/mix.exs b/mix.exs index bed6248..d24cd48 100644 --- a/mix.exs +++ b/mix.exs @@ -14,7 +14,7 @@ defmodule Amethyst.MixProject do # Run "mix help compile.app" to learn about applications. def application do [ - extra_applications: [:logger], + extra_applications: [:logger, :public_key], mod: {Amethyst.Application, []} ] end