Attempt at implementing versioned block registry
All checks were successful
Build & Test / nix-build (push) Successful in 1m47s
All checks were successful
Build & Test / nix-build (push) Successful in 1m47s
This commit is contained in:
parent
e8f0e1b4c0
commit
4a387ff296
@ -31,18 +31,7 @@ defmodule Amethyst.Application do
|
||||
child_spec: DynamicSupervisor.child_spec([]),
|
||||
name: Amethyst.GameMetaSupervisor
|
||||
},
|
||||
{PartitionSupervisor,
|
||||
child_spec: Amethyst.BlockRegistry.child_spec(%{}),
|
||||
name: Amethyst.BlockRegistry},
|
||||
Supervisor.child_spec(
|
||||
{Task, fn ->
|
||||
# TODO: not this
|
||||
Amethyst.DataGenerator.generate_and_populate_data(
|
||||
:latest,
|
||||
"/tmp/server.jar",
|
||||
"/tmp/amethyst-generated")
|
||||
end},
|
||||
id: Amethyst.DataGenerator)
|
||||
{Registry, keys: :unique, name: Amethyst.BlockStateRegistry},
|
||||
]
|
||||
|
||||
children = case Application.fetch_env!(:amethyst, :port) do
|
||||
|
@ -14,7 +14,7 @@
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
defmodule Amethyst.BlockRegistry do
|
||||
defmodule Amethyst.BlockStates do
|
||||
use GenServer
|
||||
@moduledoc """
|
||||
GenServer which can be populated with block states and their corresponding IDs.
|
||||
@ -22,8 +22,8 @@ defmodule Amethyst.BlockRegistry do
|
||||
"""
|
||||
require Logger
|
||||
|
||||
def start_link(map) do
|
||||
GenServer.start_link(__MODULE__, map)
|
||||
def start_link(map, name) do
|
||||
GenServer.start_link(__MODULE__, map, name: name)
|
||||
end
|
||||
|
||||
def init(map) do
|
||||
@ -52,22 +52,48 @@ defmodule Amethyst.BlockRegistry do
|
||||
Adds a block state to the registry.
|
||||
|
||||
## Parameters
|
||||
- `version` - The Minecraft version
|
||||
- `id` - The block identifier
|
||||
- `bs` - The block state
|
||||
- `bsi` - The block state ID
|
||||
"""
|
||||
@spec add(String.t(), map(), integer()) :: :ok
|
||||
def add(id, bs, bsi) do
|
||||
GenServer.cast({:via, PartitionSupervisor, {__MODULE__, id}}, {:add, id, bs, bsi})
|
||||
@spec add(String.t(), String.t(), map(), integer()) :: :ok
|
||||
def add(version, id, bs, bsi) do
|
||||
ps = {:via, Registry, {Amethyst.BlockStateRegistry, version}}
|
||||
GenServer.cast({:via, PartitionSupervisor, {ps, id}}, {:add, id, bs, bsi})
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets the block state ID for a given block identifier and block state.
|
||||
If no data is known for this version, errors. Prefer using `try_get/3`
|
||||
if you can wait for the data to be loaded.
|
||||
- `version` - The Minecraft version
|
||||
- `id` - The block identifier
|
||||
- `bs` - The block state, nil if the block has no states
|
||||
"""
|
||||
@spec get(String.t(), map() | nil) :: integer() | nil
|
||||
def get(id, bs \\ %{}) do
|
||||
GenServer.call({:via, PartitionSupervisor, {__MODULE__, id}}, {:get, id, bs})
|
||||
@spec get(String.t(), String.t(), map() | nil) :: integer() | nil
|
||||
def get(version, id, bs \\ %{}) do
|
||||
ps = {:via, Registry, {Amethyst.BlockStateRegistry, version}}
|
||||
GenServer.call({:via, PartitionSupervisor, {ps, id}}, {:get, id, bs})
|
||||
end
|
||||
|
||||
@doc """
|
||||
Tries to get the block state ID for a given block identifier and block state.
|
||||
If no data is known for this version, it will block until the data is loaded.
|
||||
- `version` - The Minecraft version
|
||||
- `id` - The block identifier
|
||||
- `bs` - The block state, nil if the block has no states
|
||||
"""
|
||||
@spec try_get(String.t(), String.t(), map() | nil) :: integer() | nil
|
||||
def try_get(version, id, bs \\ %{}) do
|
||||
case Registry.lookup(Amethyst.BlockStateRegistry, version) do
|
||||
[{_pid, _}] ->
|
||||
ps = {:via, Registry, {Amethyst.BlockStateRegistry, version}}
|
||||
GenServer.call({:via, PartitionSupervisor, {ps, id}}, {:get, id, bs})
|
||||
[] ->
|
||||
Logger.warning("BlockStateRegistry doesn't exist for version #{version}, generating it now!")
|
||||
Amethyst.DataGenerator.generate_and_populate_data(version, "/tmp/minecraft_server_#{version}.jar", "/tmp/minecraft_data_#{version}")
|
||||
try_get(version, id, bs)
|
||||
end
|
||||
end
|
||||
end
|
@ -75,8 +75,8 @@ defmodule Amethyst.DataGenerator do
|
||||
end
|
||||
end
|
||||
|
||||
@spec populate_blockregistry(String.t()) :: :ok | {:error, term}
|
||||
def populate_blockregistry(data_path) do
|
||||
@spec populate_blockstates(String.t(), String.t()) :: :ok | {:error, term}
|
||||
def populate_blockstates(data_path, version) do
|
||||
block_file = Path.join([data_path, "reports", "blocks.json"])
|
||||
case File.read(block_file) do
|
||||
{:ok, data} ->
|
||||
@ -84,8 +84,8 @@ defmodule Amethyst.DataGenerator do
|
||||
{:ok, blocks} ->
|
||||
Enum.each(blocks, fn {id, %{"states" => states}} ->
|
||||
Enum.each(states, fn
|
||||
%{"id" => bsi, "properties" => props} -> Amethyst.BlockRegistry.add(id, props, bsi)
|
||||
%{"id" => bsi, "default" => true} -> Amethyst.BlockRegistry.add(id, %{}, bsi)
|
||||
%{"id" => bsi, "properties" => props} -> Amethyst.BlockStates.add(version, id, props, bsi)
|
||||
%{"id" => bsi, "default" => true} -> Amethyst.BlockStates.add(version, id, %{}, bsi)
|
||||
end)
|
||||
end)
|
||||
:ok
|
||||
@ -95,15 +95,25 @@ defmodule Amethyst.DataGenerator do
|
||||
end
|
||||
end
|
||||
|
||||
defp create_blockregistry(version) do
|
||||
# TODO: unsupervised
|
||||
Amethyst.BlockStates.start_link(%{}, {:via, Registry, {Amethyst.BlockStateRegistry, version}})
|
||||
end
|
||||
|
||||
@spec generate_and_populate_data(String.t() | :latest, String.t(), String.t(), String.t() | nil) :: :ok | {:error, term}
|
||||
def generate_and_populate_data(version, jar_path, data_dir, java_bin \\ "java") do
|
||||
start_time = Time.utc_now()
|
||||
{:ok, version} = case version do
|
||||
:latest -> get_latest_version()
|
||||
version -> {:ok, version}
|
||||
end
|
||||
case get_server_jar(version, jar_path) do
|
||||
{:ok, jar_path} ->
|
||||
case generate_data_files(jar_path, data_dir, java_bin) do
|
||||
{:ok, data_path} ->
|
||||
Logger.info("Finished generating data in #{Time.diff(Time.utc_now(), start_time, :millisecond)}ms")
|
||||
populate_blockregistry(data_path)
|
||||
create_blockregistry(version)
|
||||
populate_blockstates(version, data_path)
|
||||
Logger.info("Finished generating and populating data in #{Time.diff(Time.utc_now(), start_time, :millisecond)}ms")
|
||||
{:error, code} -> {:error, code}
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user