"Implement" "login"
All checks were successful
Build & Test / nix-build (push) Successful in 1m8s

This commit is contained in:
Kodi Craft 2024-07-08 17:59:44 +02:00
parent 1f331fabfc
commit 1d741d785a
Signed by: kodi
GPG Key ID: 69D9EED60B242822
4 changed files with 30 additions and 6 deletions

View File

@ -1,4 +1,5 @@
import Config import Config
config :amethyst, config :amethyst,
port: 25599 # Bogus port for testing, avoids unexpected conflicts port: 25599, # Bogus port for testing, avoids unexpected conflicts
encryption: false

View File

@ -26,6 +26,13 @@ defmodule Amethyst.Minecraft.Write do
UUID.string_to_binary!(uuid) UUID.string_to_binary!(uuid)
end 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 def varint(value) when value in -2_147_483_648..2_147_483_647 do
<<value::32-unsigned>> = <<value::32-signed>> # This is a trick to allow the arithmetic shift to act as a logical shift <<value::32-unsigned>> = <<value::32-signed>> # This is a trick to allow the arithmetic shift to act as a logical shift
varnum("", value) varnum("", value)

View File

@ -24,9 +24,13 @@ defmodule Amethyst.Server.Generic do
def get_packet(client) do def get_packet(client) do
{[length], ""} = get_varint(client, "") {[length], ""} = get_varint(client, "")
{:ok, full_packet} = :gen_tcp.recv(client, length) recv = :gen_tcp.recv(client, length)
{[id], data} = Read.start(full_packet) |> Read.varint() |> Read.stop() case recv do
{id, data} {: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 end
defp get_varint(client, acc) do defp get_varint(client, acc) do

View File

@ -72,7 +72,7 @@ defmodule Amethyst.Server.Login do
end end
# Encryption Request https://wiki.vg/Protocol#Encryption_Request # Encryption Request https://wiki.vg/Protocol#Encryption_Request
def serialize({:encryption_request, id, pubkey, verify_token, auth}) do 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 <> <<auth::8>> Write.varint(0x01) <> Write.string(id) <> Write.varint(byte_size(pubkey)) <> pubkey <> Write.varint(byte_size(verify_token)) <> verify_token <> Write.bool(auth)
end end
# Login Success https://wiki.vg/Protocol#Login_Success # Login Success https://wiki.vg/Protocol#Login_Success
def serialize({:login_success, uuid, username, props, strict}) do 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 Enum.reduce(props, "", fn {name, value, signature}, acc -> acc <> Write.string(name) <> Write.string(value) <> case signature do
nil -> <<0x00>> nil -> <<0x00>>
signature -> <<0x01>> <> Write.string(signature) signature -> <<0x01>> <> Write.string(signature)
end end) <> <<strict::8>> end end) <> Write.bool(strict)
end end
# Set Compression https://wiki.vg/Protocol#Set_Compression # Set Compression https://wiki.vg/Protocol#Set_Compression
def serialize({:set_compression, threshold}) do def serialize({:set_compression, threshold}) do
@ -99,6 +99,18 @@ defmodule Amethyst.Server.Login do
end end
## HANDLING ## 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 def handle(tuple, _) do
Logger.error("Unhandled but known packet #{elem(tuple, 0)}") Logger.error("Unhandled but known packet #{elem(tuple, 0)}")
end end