From 1d741d785a55af202878755f2490a7dcf7755278 Mon Sep 17 00:00:00 2001 From: Kodi Craft Date: Mon, 8 Jul 2024 17:59:44 +0200 Subject: [PATCH] "Implement" "login" --- config/runtime.exs | 3 ++- lib/data.ex | 7 +++++++ lib/servers/generic.ex | 10 +++++++--- lib/servers/login.ex | 16 ++++++++++++++-- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/config/runtime.exs b/config/runtime.exs index 3cd9ca6..7ef1357 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -1,4 +1,5 @@ import Config config :amethyst, - port: 25599 # Bogus port for testing, avoids unexpected conflicts + port: 25599, # Bogus port for testing, avoids unexpected conflicts + encryption: false diff --git a/lib/data.ex b/lib/data.ex index 37afc44..a927731 100644 --- a/lib/data.ex +++ b/lib/data.ex @@ -26,6 +26,13 @@ defmodule Amethyst.Minecraft.Write do UUID.string_to_binary!(uuid) end + def bool(value) do + case value do + true -> <<0x01::8>> + false -> <<0x00::8>> + end + end + def varint(value) when value in -2_147_483_648..2_147_483_647 do <> = <> # This is a trick to allow the arithmetic shift to act as a logical shift varnum("", value) diff --git a/lib/servers/generic.ex b/lib/servers/generic.ex index 5731a0a..3acfe60 100644 --- a/lib/servers/generic.ex +++ b/lib/servers/generic.ex @@ -24,9 +24,13 @@ defmodule Amethyst.Server.Generic do def get_packet(client) do {[length], ""} = get_varint(client, "") - {:ok, full_packet} = :gen_tcp.recv(client, length) - {[id], data} = Read.start(full_packet) |> Read.varint() |> Read.stop() - {id, data} + recv = :gen_tcp.recv(client, length) + case recv do + {:ok, full_packet} -> ({[id], data} = Read.start(full_packet) |> Read.varint() |> Read.stop() + {id, data}) + {:error, :closed} -> raise RuntimeError, "TODO: Handle disconnections reasonably" + {:error, error} -> raise RuntimeError, "An error has occured while waiting on a packet: #{error}" + end end defp get_varint(client, acc) do diff --git a/lib/servers/login.ex b/lib/servers/login.ex index cade3ce..0cff919 100644 --- a/lib/servers/login.ex +++ b/lib/servers/login.ex @@ -72,7 +72,7 @@ defmodule Amethyst.Server.Login do end # Encryption Request https://wiki.vg/Protocol#Encryption_Request def serialize({:encryption_request, id, pubkey, verify_token, auth}) do - Write.varint(0x01) <> Write.string(id) <> Write.varint(byte_size(pubkey)) <> pubkey <> Write.varint(byte_size(verify_token)) <> verify_token <> <> + Write.varint(0x01) <> Write.string(id) <> Write.varint(byte_size(pubkey)) <> pubkey <> Write.varint(byte_size(verify_token)) <> verify_token <> Write.bool(auth) end # Login Success https://wiki.vg/Protocol#Login_Success def serialize({:login_success, uuid, username, props, strict}) do @@ -80,7 +80,7 @@ defmodule Amethyst.Server.Login do Enum.reduce(props, "", fn {name, value, signature}, acc -> acc <> Write.string(name) <> Write.string(value) <> case signature do nil -> <<0x00>> signature -> <<0x01>> <> Write.string(signature) - end end) <> <> + end end) <> Write.bool(strict) end # Set Compression https://wiki.vg/Protocol#Set_Compression def serialize({:set_compression, threshold}) do @@ -99,6 +99,18 @@ defmodule Amethyst.Server.Login do end ## HANDLING + # Login Start https://wiki.vg/Protocol#Login_Start + def handle({:login_start, name, uuid}, client) do + Logger.info("Logging in #{name} (#{uuid})") + if Application.fetch_env!(:amethyst, :encryption) do + raise RuntimeError, "Encryption is not currently supported!" + else + transmit({:login_success, uuid, name, [], false}, client) + end + end + def handle({:login_acknowledged}, _client) do + raise RuntimeError, "Configuration stage is not implemented." + end def handle(tuple, _) do Logger.error("Unhandled but known packet #{elem(tuple, 0)}") end