Implement compression

This commit is contained in:
Kodi Craft 2024-10-06 15:20:39 +02:00
parent fb98dd4864
commit be44916461
Signed by: kodi
GPG Key ID: 69D9EED60B242822
2 changed files with 24 additions and 30 deletions

View File

@ -258,27 +258,26 @@ defmodule Amethyst.ConnectionHandler do
defp send_packet(socket, connstate, packet, version, state) do
try do
data = connstate.serialize(packet, version)
length = byte_size(data) |> Amethyst.Minecraft.Write.varint()
to_write = case Map.get(state, :compression_threshold) do
nil ->
# No compression
length <> data
threshold when byte_size(length <> data) < threshold ->
# Compression unnecessary
<<0>> <> length <> data
threshold when byte_size(length <> data) >= threshold ->
# Compression
cdata = :zlib.compress(data)
outer_length = byte_size(length <> cdata)
Write.varint(outer_length) <> length <> cdata
container = if Map.get(state, :compression) == nil do
# Packet ID is included in data
Write.varint(byte_size(data)) <> data
else
threshold = Map.get(state, :compression, 0)
data_length = byte_size(data)
if data_length >= threshold do
compressed = Write.varint(data_length) <> :zlib.zip(data)
Write.varint(byte_size(compressed)) <> compressed
else
compressed = Write.varint(0) <> data
Write.varint(byte_size(compressed)) <> compressed
end
end
encrypted = if Map.get(state, :encryption_state) == nil do
container
else
Map.get(state, :encryption_state) |> :crypto.crypto_update(container)
end
case Map.get(state, :encryption_state) do
nil ->
:gen_tcp.send(socket, to_write)
estate ->
encrypted = :crypto.crypto_update(estate, to_write)
:gen_tcp.send(socket, encrypted)
end
rescue
e ->
Logger.error("Error sending packet #{inspect(packet)} in state #{connstate}: #{Exception.format(:error, e, __STACKTRACE__)}")

View File

@ -60,25 +60,20 @@ defmodule Amethyst.ConnectionReceiver do
estate = if estate == nil do
# Ask the handler if we have encryption now
send(sender, {:get_encryption, self()})
Logger.debug("Asking for news on encryption...")
receive do
nil -> nil
some ->
Logger.debug("Enabled decryption")
some
some -> some
end
else nil end
else estate end
cstate = if cstate == nil do
# Ask the handler if we have encryption now
send(sender, {:get_compression, self()})
Logger.debug("Asking for news on compression...")
receive do
nil -> nil
some ->
Logger.debug("Enabled decompression")
some
some -> some
end
else nil end
else cstate end
receive(socket, sender, estate, cstate)
end
@ -109,7 +104,7 @@ defmodule Amethyst.ConnectionReceiver do
rest
else
# Compressed data
rest |> :zlib.uncompress()
rest |> :zlib.unzip()
end
end