defmodule Odinsea.Channel.Players do @moduledoc """ Player storage for channel server. Manages online player state and lookups. Ported from Java handling.channel.PlayerStorage Uses ETS for fast in-memory lookups. """ require Logger @table :channel_players @doc """ Starts the player storage (creates ETS table). """ def start_link do :ets.new(@table, [ :set, :public, :named_table, read_concurrency: true, write_concurrency: true ]) {:ok, self()} end @doc """ Adds a player to the channel storage. """ def add_player(character_id, player_data) do :ets.insert(@table, {character_id, player_data}) :ok end @doc """ Removes a player from the channel storage. """ def remove_player(character_id) do :ets.delete(@table, character_id) :ok end @doc """ Gets player data by character ID. Returns nil if not found. """ def get_player(character_id) do case :ets.lookup(@table, character_id) do [{^character_id, data}] -> data [] -> nil end end @doc """ Checks if a character is online in this channel. """ def is_online?(character_id) do :ets.member(@table, character_id) end @doc """ Gets all online players. """ def get_all_players do :ets.tab2list(@table) |> Enum.map(fn {_id, data} -> data end) end @doc """ Gets player count. """ def count do :ets.info(@table, :size) end @doc """ Gets a player by name. """ def get_player_by_name(name) do @table |> :ets.tab2list() |> Enum.find(fn {_id, data} -> data.name == name end) |> case do nil -> nil {_, data} -> data end end @doc """ Updates player data. """ def update_player(character_id, updates) do case get_player(character_id) do nil -> :error data -> updated = Map.merge(data, updates) :ets.insert(@table, {character_id, updated}) :ok end end @doc """ Clears all players (e.g., during shutdown). """ def clear do :ets.delete_all_objects(@table) :ok end end