kimi gone wild
This commit is contained in:
150
lib/odinsea/admin/handler.ex
Normal file
150
lib/odinsea/admin/handler.ex
Normal file
@@ -0,0 +1,150 @@
|
||||
defmodule Odinsea.Admin.Handler do
|
||||
@moduledoc """
|
||||
Main admin command handler.
|
||||
Ported from Java handling.admin.AdminHandler
|
||||
|
||||
Parses chat messages starting with '!' as admin commands
|
||||
and routes them to the appropriate command implementation.
|
||||
"""
|
||||
|
||||
require Logger
|
||||
|
||||
alias Odinsea.Admin.Commands
|
||||
alias Odinsea.Channel.Packets
|
||||
|
||||
@doc """
|
||||
Parses and executes an admin command from chat message.
|
||||
|
||||
Commands start with '!' followed by the command name and arguments.
|
||||
Example: "!warp PlayerName 100000000"
|
||||
|
||||
Returns:
|
||||
- {:ok, result_message} - Command executed successfully
|
||||
- {:error, reason} - Command failed
|
||||
- :not_command - Message is not an admin command
|
||||
"""
|
||||
def handle_command(message, client_state) when is_binary(message) do
|
||||
# Check if message is a command (starts with !)
|
||||
if String.starts_with?(message, "!") do
|
||||
parse_and_execute(message, client_state)
|
||||
else
|
||||
:not_command
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Parses command string and executes.
|
||||
"""
|
||||
def parse_and_execute(message, client_state) do
|
||||
# Remove leading '!' and split into command and arguments
|
||||
command_str = String.slice(message, 1..-1//-1)
|
||||
parts = String.split(command_str)
|
||||
|
||||
case parts do
|
||||
[] ->
|
||||
{:error, "Empty command"}
|
||||
|
||||
[command | args] ->
|
||||
command = String.downcase(command)
|
||||
|
||||
char_id = if client_state.character_id, do: client_state.character_id, else: "unknown"
|
||||
Logger.info("Admin command from #{char_id}: #{command} #{inspect(args)}")
|
||||
|
||||
# Get admin state (character info with GM level)
|
||||
admin_state = build_admin_state(client_state)
|
||||
|
||||
case Commands.execute(command, args, admin_state) do
|
||||
{:ok, result} ->
|
||||
# Send success message back to admin
|
||||
notify_admin(client_state, result)
|
||||
{:ok, result}
|
||||
|
||||
{:error, reason} ->
|
||||
# Send error message back to admin
|
||||
notify_admin(client_state, "Error: #{reason}")
|
||||
{:error, reason}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Checks if a message is an admin command.
|
||||
"""
|
||||
def admin_command?(message) do
|
||||
String.starts_with?(message, "!")
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets the command name from a message (for logging).
|
||||
"""
|
||||
def extract_command_name(message) do
|
||||
case String.split(message) do
|
||||
[first | _] -> String.downcase(String.trim_leading(first, "!"))
|
||||
_ -> "unknown"
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Sends help information to the admin.
|
||||
"""
|
||||
def send_help(client_state) do
|
||||
commands = Commands.list_commands()
|
||||
|
||||
help_text = [
|
||||
"=== Admin Commands ===",
|
||||
""
|
||||
| Enum.map(commands, fn {cmd, args, desc} ->
|
||||
"!#{cmd} #{args} - #{desc}"
|
||||
end)
|
||||
]
|
||||
|> Enum.join("\n")
|
||||
|
||||
notify_admin(client_state, help_text)
|
||||
end
|
||||
|
||||
# ============================================================================
|
||||
# Private Functions
|
||||
# ============================================================================
|
||||
|
||||
defp build_admin_state(client_state) do
|
||||
# Get character information including GM level
|
||||
gm_level = get_gm_level(client_state)
|
||||
|
||||
%{
|
||||
character_id: client_state.character_id,
|
||||
channel_id: client_state.channel_id,
|
||||
gm_level: gm_level,
|
||||
client_pid: self()
|
||||
}
|
||||
end
|
||||
|
||||
defp get_gm_level(client_state) do
|
||||
# Try to get GM level from character
|
||||
case client_state.character_id do
|
||||
nil -> 0
|
||||
character_id ->
|
||||
# In a full implementation, this would query the character state
|
||||
# For now, use a default or check player storage
|
||||
case Odinsea.Channel.Players.get_player(character_id) do
|
||||
nil -> 0
|
||||
player_data -> Map.get(player_data, :gm, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp notify_admin(client_state, message) do
|
||||
case client_state.character_id do
|
||||
nil ->
|
||||
:ok
|
||||
character_id ->
|
||||
case Odinsea.Channel.Players.get_player(character_id) do
|
||||
nil -> :ok
|
||||
%{client_pid: pid} when is_pid(pid) ->
|
||||
packet = Packets.drop_message(5, message)
|
||||
send(pid, {:send_packet, packet})
|
||||
:ok
|
||||
_ -> :ok
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user