91 lines
2.0 KiB
Elixir
91 lines
2.0 KiB
Elixir
defmodule Odinsea.Shop.Client do
|
|
@moduledoc """
|
|
Client connection handler for the cash shop server.
|
|
"""
|
|
|
|
use GenServer, restart: :temporary
|
|
|
|
require Logger
|
|
|
|
alias Odinsea.Net.Packet.In
|
|
|
|
defstruct [:socket, :ip, :state, :character_id, :account_id]
|
|
|
|
def start_link(socket) do
|
|
GenServer.start_link(__MODULE__, socket)
|
|
end
|
|
|
|
@impl true
|
|
def init(socket) do
|
|
{:ok, {ip, _port}} = :inet.peername(socket)
|
|
ip_string = format_ip(ip)
|
|
|
|
Logger.info("Cash shop client connected from #{ip_string}")
|
|
|
|
state = %__MODULE__{
|
|
socket: socket,
|
|
ip: ip_string,
|
|
state: :connected,
|
|
character_id: nil,
|
|
account_id: nil
|
|
}
|
|
|
|
send(self(), :receive)
|
|
{:ok, state}
|
|
end
|
|
|
|
@impl true
|
|
def handle_info(:receive, %{socket: socket} = state) do
|
|
case :gen_tcp.recv(socket, 0, 30_000) do
|
|
{:ok, data} ->
|
|
new_state = handle_packet(data, state)
|
|
send(self(), :receive)
|
|
{:noreply, new_state}
|
|
|
|
{:error, :closed} ->
|
|
Logger.info("Cash shop client disconnected: #{state.ip}")
|
|
{:stop, :normal, state}
|
|
|
|
{:error, reason} ->
|
|
Logger.warning("Cash shop client error: #{inspect(reason)}")
|
|
{:stop, :normal, state}
|
|
end
|
|
end
|
|
|
|
@impl true
|
|
def terminate(_reason, state) do
|
|
if state.socket do
|
|
:gen_tcp.close(state.socket)
|
|
end
|
|
|
|
:ok
|
|
end
|
|
|
|
defp handle_packet(data, state) do
|
|
packet = In.new(data)
|
|
|
|
case In.decode_short(packet) do
|
|
{opcode, packet} ->
|
|
Logger.debug("Cash shop packet: opcode=0x#{Integer.to_string(opcode, 16)}")
|
|
dispatch_packet(opcode, packet, state)
|
|
|
|
:error ->
|
|
Logger.warning("Failed to read packet opcode")
|
|
state
|
|
end
|
|
end
|
|
|
|
defp dispatch_packet(_opcode, _packet, state) do
|
|
# TODO: Implement cash shop packet handlers
|
|
state
|
|
end
|
|
|
|
defp format_ip({a, b, c, d}) do
|
|
"#{a}.#{b}.#{c}.#{d}"
|
|
end
|
|
|
|
defp format_ip({a, b, c, d, e, f, g, h}) do
|
|
"#{a}:#{b}:#{c}:#{d}:#{e}:#{f}:#{g}:#{h}"
|
|
end
|
|
end
|