basics being displayed
This commit is contained in:
57
lib/cobblemon_ui/cobblemon_fs/pc_store.ex
Normal file
57
lib/cobblemon_ui/cobblemon_fs/pc_store.ex
Normal file
@@ -0,0 +1,57 @@
|
||||
defmodule CobblemonUi.CobblemonFS.PCStore do
|
||||
@moduledoc """
|
||||
Parses a player's PC storage `.dat` file.
|
||||
|
||||
PC layout:
|
||||
Root -> boxes -> box0..boxN -> slot0..slotN
|
||||
"""
|
||||
|
||||
alias CobblemonUi.CobblemonFS.{NBT, Pokemon}
|
||||
|
||||
@doc """
|
||||
Reads and parses a PC storage `.dat` file at the given path.
|
||||
|
||||
Returns `{:ok, [%{box: integer, pokemon: list}]}` or `{:error, reason}`.
|
||||
"""
|
||||
@spec parse(String.t()) :: {:ok, list(map())} | {:error, term()}
|
||||
def parse(path) do
|
||||
with {:ok, data} <- File.read(path),
|
||||
{:ok, {_name, root}} <- NBT.decode(data) do
|
||||
boxes = Map.get(root, "boxes", %{})
|
||||
{:ok, normalize_boxes(boxes)}
|
||||
else
|
||||
{:error, :enoent} -> {:error, :not_found}
|
||||
{:error, reason} -> {:error, {:corrupt_data, reason}}
|
||||
end
|
||||
end
|
||||
|
||||
defp normalize_boxes(boxes) when is_map(boxes) do
|
||||
boxes
|
||||
|> Enum.filter(fn {key, _} -> String.starts_with?(key, "box") end)
|
||||
|> Enum.sort_by(fn {key, _} -> extract_index(key) end)
|
||||
|> Enum.map(fn {key, box_data} ->
|
||||
%{
|
||||
box: extract_index(key),
|
||||
pokemon: normalize_box_slots(box_data)
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
defp normalize_boxes(_), do: []
|
||||
|
||||
defp normalize_box_slots(box) when is_map(box) do
|
||||
box
|
||||
|> Enum.filter(fn {key, _} -> String.starts_with?(key, "slot") end)
|
||||
|> Enum.sort_by(fn {key, _} -> extract_index(key) end)
|
||||
|> Enum.map(fn {_key, slot_data} -> Pokemon.normalize(slot_data) end)
|
||||
end
|
||||
|
||||
defp normalize_box_slots(_), do: []
|
||||
|
||||
defp extract_index(key) do
|
||||
case Integer.parse(String.replace(key, ~r/[^\d]/, "")) do
|
||||
{n, _} -> n
|
||||
:error -> 0
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user