113 lines
2.1 KiB
Elixir
113 lines
2.1 KiB
Elixir
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
|