Compare commits
No commits in common. "d0a5b55ae88a996284fea934f80150bb02fbeaf4" and "c3c3f832864a5312b7a732bb46e9397887e89d96" have entirely different histories.
d0a5b55ae8
...
c3c3f83286
@ -85,16 +85,12 @@ defmodule Amethyst.ConnectionHandler do
|
||||
end
|
||||
chunks = MapSet.new(visible_chunks_from(elem(cp, 0), elem(cp, 1), Map.get(state, :view_distance, 16)))
|
||||
new_chunks = MapSet.difference(chunks, prev_chunks)
|
||||
# We can process all chunks in parallel
|
||||
# me = self()
|
||||
# Task.Supervisor.async_stream(state |> Map.get(:game) |> Map.get(:refs) |> Map.get(:task_supervisor),
|
||||
# new_chunks,
|
||||
# fn chunk -> process_chunk(me, chunk, state) end,
|
||||
# [ordered: false]
|
||||
# ) |> Stream.run()
|
||||
if new_chunks |> Enum.map(&process_chunk(self(), &1, state)) |> Enum.any?(&(&1 != :ok)) do
|
||||
Logger.error("something happened while processing chunks")
|
||||
end
|
||||
# Process these chunks, we can process all chunks in parallel
|
||||
Task.Supervisor.async_stream(state |> Map.get(:game) |> Map.get(:refs) |> Map.get(:task_supervisor),
|
||||
new_chunks,
|
||||
fn chunk -> process_chunk(chunk, state) end,
|
||||
[ordered: false]
|
||||
) |> Stream.run()
|
||||
end
|
||||
loop(socket, connstate, version, state)
|
||||
{:send_packet, packet} ->
|
||||
@ -123,91 +119,28 @@ defmodule Amethyst.ConnectionHandler do
|
||||
end)
|
||||
end
|
||||
|
||||
defp process_chunk(to, chunk, state) do
|
||||
defp process_chunk(chunk, state) do
|
||||
import Amethyst.NBT.Write
|
||||
alias Amethyst.Minecraft.Write
|
||||
|
||||
chunk_array = Amethyst.API.Game.chunk(Map.get(state, :game), chunk)
|
||||
{cx, cz} = chunk
|
||||
|
||||
# TODO: Actually do heightmaps
|
||||
# TODO: Doing all this processing could be at home somewhere else
|
||||
heightmaps = compound(%{})
|
||||
|
||||
data = Enum.chunk_every(chunk_array, 16, 16, 0) # 0 -> air
|
||||
|> Enum.reduce("", fn chunk_section, acc ->
|
||||
|> Enum.reduce(fn chunk_section, acc ->
|
||||
blocks = chunk_section |> List.flatten()
|
||||
block_count = blocks |> Enum.filter(&(&1 != 0)) |> length
|
||||
block_count = blocks
|
||||
|> Enum.map(&(if &1 == 0, do: 0, else: 1))
|
||||
|> Enum.sum()
|
||||
|
||||
# Put together the palette
|
||||
unique_blocks = MapSet.new(blocks)
|
||||
min_bpe = MapSet.size(unique_blocks) |> :math.log2() |> ceil()
|
||||
paletted_container_data = case min_bpe do
|
||||
0 -> <<0::8>> <>
|
||||
# SINGLE VALUED
|
||||
Write.varint(MapSet.to_list(unique_blocks) |> List.first()) <>
|
||||
Write.varint(0) # No data, empty pallette
|
||||
min_bpe when min_bpe in 1..8 ->
|
||||
# INDIRECT
|
||||
# Minimum bpe accepted by minecraft is 4
|
||||
bpe = max(min_bpe, 4)
|
||||
palette = MapSet.to_list(unique_blocks) |>
|
||||
Enum.with_index() |>
|
||||
Map.new(fn {i, v} -> {v, i} end)
|
||||
paletted_blocks = blocks |>
|
||||
Enum.map(&(Map.get(palette, &1)))
|
||||
Logger.debug("got here")
|
||||
paletted_data = long_aligned_bit_string_reduce(paletted_blocks, bpe)
|
||||
|
||||
Write.ubyte(bpe) <>
|
||||
Write.varint(map_size(palette)) <>
|
||||
Enum.reduce(0..map_size(palette), "", fn i, acc ->
|
||||
acc <> Write.varint(Map.get(palette, i))
|
||||
end) <>
|
||||
Write.varint(floor(bit_size(paletted_data) / 64)) <>
|
||||
paletted_data
|
||||
_ ->
|
||||
# DIRECT
|
||||
Logger.debug("got here with bpe #{min_bpe}")
|
||||
data = long_aligned_bit_string_reduce(blocks, 15)
|
||||
Write.ubyte(15) <>
|
||||
Write.varint(floor(bit_size(data) / 64)) <>
|
||||
data
|
||||
end
|
||||
|
||||
# TODO: Send biome data, if that even makes sense
|
||||
acc <> Write.short(block_count) <> paletted_container_data <> <<0::8, 0::8>>
|
||||
# TODO: Proper paletting
|
||||
acc <> Write.short(block_count) <> Write.ubyte(15)
|
||||
end)
|
||||
|
||||
Logger.debug("Asking to send chunk packet...")
|
||||
send(to, {:send_packet, %{
|
||||
packet_type: :chunk_data_and_update_light,
|
||||
chunk_x: cx, chunk_z: cz,
|
||||
heightmaps: heightmaps,
|
||||
data: data,
|
||||
block_entities: [],
|
||||
# TODO: Light
|
||||
sky_light_mask: <<0>>,
|
||||
block_light_mask: <<0>>,
|
||||
empty_sky_light_mask: <<0>>,
|
||||
empty_block_light_mask: <<0>>,
|
||||
sky_light_arrays: [],
|
||||
block_light_arrays: []
|
||||
}})
|
||||
:ok
|
||||
end
|
||||
# TODO: Use paletting
|
||||
|
||||
defp long_aligned_bit_string_reduce(values, bpe) do
|
||||
values |> Enum.reduce("", fn value, acc ->
|
||||
next = acc <> <<value::size(bpe)-big>>
|
||||
# man i hope they dont suddenly change the size of a long
|
||||
if rem(bit_size(next), 64) + bpe < 64 do
|
||||
# gotta pad it
|
||||
next <> <<0::big-size(64 - rem(bit_size(next), 64))>>
|
||||
else
|
||||
next
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
defp handle_packet(id, data, connstate, version, state) do
|
||||
|
1
mix.lock
1
mix.lock
@ -2,7 +2,6 @@
|
||||
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
|
||||
"credo": {:hex, :credo, "1.7.7", "771445037228f763f9b2afd612b6aa2fd8e28432a95dbbc60d8e03ce71ba4446", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8bc87496c9aaacdc3f90f01b7b0582467b69b4bd2441fe8aae3109d843cc2f2e"},
|
||||
"earmark_parser": {:hex, :earmark_parser, "1.4.41", "ab34711c9dc6212dda44fcd20ecb87ac3f3fce6f0ca2f28d4a00e4154f8cd599", [:mix], [], "hexpm", "a81a04c7e34b6617c2792e291b5a2e57ab316365c2644ddc553bb9ed863ebefa"},
|
||||
"elixir_math": {:hex, :elixir_math, "0.1.2", "5655bdf7f34e30906f31cdcf3031b43dd522ce8d2936b60ad4696b2c752bf5c9", [:mix], [], "hexpm", "34f4e4384903097a8ec566784fa8e9aa2b741247d225741f07cc48250c2aa64c"},
|
||||
"ex_doc": {:hex, :ex_doc, "0.34.2", "13eedf3844ccdce25cfd837b99bea9ad92c4e511233199440488d217c92571e8", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "5ce5f16b41208a50106afed3de6a2ed34f4acfd65715b82a0b84b49d995f95c1"},
|
||||
"file_system": {:hex, :file_system, "1.0.1", "79e8ceaddb0416f8b8cd02a0127bdbababe7bf4a23d2a395b983c1f8b3f73edd", [:mix], [], "hexpm", "4414d1f38863ddf9120720cd976fce5bdde8e91d8283353f0e31850fa89feb9e"},
|
||||
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
|
||||
|
Loading…
Reference in New Issue
Block a user