126 lines
2.9 KiB
Elixir
126 lines
2.9 KiB
Elixir
defmodule Odinsea do
|
|
@moduledoc """
|
|
Odinsea - An Elixir/OTP MapleStory private server.
|
|
|
|
This is a port of the Java Odinsea server (GMS v342).
|
|
|
|
## Architecture
|
|
|
|
The server consists of multiple components:
|
|
|
|
- **Login Server**: Handles authentication and character selection
|
|
- **Channel Servers**: Game world instances (multiple channels)
|
|
- **Cash Shop Server**: Item purchasing
|
|
- **World Services**: Cross-server state management
|
|
|
|
## Quick Start
|
|
|
|
Start the server:
|
|
|
|
iex> Odinsea.start()
|
|
|
|
Or with Mix:
|
|
|
|
$ mix run --no-halt
|
|
|
|
## Configuration
|
|
|
|
See `config/runtime.exs` for all configuration options.
|
|
Environment variables are supported for all settings.
|
|
|
|
## Packet Handling
|
|
|
|
Incoming packets are decoded with `Odinsea.Net.Packet.In`:
|
|
|
|
packet = Odinsea.Net.Packet.In.new(binary_data)
|
|
{opcode, packet} = Odinsea.Net.Packet.In.decode_short(packet)
|
|
{value, packet} = Odinsea.Net.Packet.In.decode_int(packet)
|
|
|
|
Outgoing packets are encoded with `Odinsea.Net.Packet.Out`:
|
|
|
|
packet = Odinsea.Net.Packet.Out.new(0x00) # opcode
|
|
packet = Odinsea.Net.Packet.Out.encode_string(packet, "Hello")
|
|
binary = Odinsea.Net.Packet.Out.to_binary(packet)
|
|
|
|
## Constants
|
|
|
|
Game constants are in `Odinsea.Constants.Game`:
|
|
|
|
Odinsea.Constants.Game.max_level() # 250
|
|
Odinsea.Constants.Game.exp_rate() # configured rate
|
|
Odinsea.Constants.Game.job_name(112) # "Hero"
|
|
|
|
Server constants are in `Odinsea.Constants.Server`:
|
|
|
|
Odinsea.Constants.Server.maple_version() # 342
|
|
Odinsea.Constants.Server.server_name() # "Luna"
|
|
"""
|
|
|
|
alias Odinsea.Constants.Server
|
|
|
|
@doc """
|
|
Returns the server version string.
|
|
"""
|
|
@spec version() :: String.t()
|
|
def version do
|
|
"Odinsea Elixir v0.1.0 (Rev #{Server.server_revision()})"
|
|
end
|
|
|
|
@doc """
|
|
Returns the MapleStory client version.
|
|
"""
|
|
@spec client_version() :: integer()
|
|
def client_version do
|
|
Server.maple_version()
|
|
end
|
|
|
|
@doc """
|
|
Returns the server name.
|
|
"""
|
|
@spec server_name() :: String.t()
|
|
def server_name do
|
|
Server.server_name()
|
|
end
|
|
|
|
@doc """
|
|
Returns the current timestamp in milliseconds.
|
|
"""
|
|
@spec now() :: integer()
|
|
def now do
|
|
System.system_time(:millisecond)
|
|
end
|
|
|
|
@doc """
|
|
Starts the Odinsea application.
|
|
"""
|
|
@spec start() :: :ok | {:error, term()}
|
|
def start do
|
|
Application.ensure_all_started(:odinsea)
|
|
end
|
|
|
|
@doc """
|
|
Stops the Odinsea application.
|
|
"""
|
|
@spec stop() :: :ok
|
|
def stop do
|
|
Application.stop(:odinsea)
|
|
end
|
|
|
|
@doc """
|
|
Returns the application uptime in milliseconds.
|
|
"""
|
|
@spec uptime() :: integer()
|
|
def uptime do
|
|
Odinsea.Application.uptime()
|
|
end
|
|
|
|
@doc """
|
|
Returns true if the server is running.
|
|
"""
|
|
@spec running?() :: boolean()
|
|
def running? do
|
|
Application.started_applications()
|
|
|> Enum.any?(fn {app, _, _} -> app == :odinsea end)
|
|
end
|
|
end
|