View Source FLHook Client

Build Coverage Status Module Version Hex Docs License Last Updated

FLHook is a community-managed tool for managing Freelancer game servers. Freelancer is a pretty old game that has been released in 2003 by Microsoft, but it still has a very committed community.

FLHook allows connecting via a socket to run commands on and receive events from a Freelancer Server. This library provides an Elixir client for that matter. You could use it to build web-based management interfaces or ingame chat bots, for example.

Use Cases

  • Chat Bots
  • Web-based Services
    • Character Management
    • Character Money Deposit
    • Character Cargo Deposit
  • Player Tracking and Travel Journal
  • Custom Cargo Missions

Installation

The package is available in Hex and can be installed by adding fl_hook_client to your list of dependencies in mix.exs:

def deps do
  [
    {:fl_hook_client, "~> 2.1"}
  ]
end

Usage

Initiate a connection to a server (with a list of all possible options):

{:ok, client} =
  FLHook.Client.start_link(
    backoff_interval: 1234,
    codec: :unicode,
    connect_timeout: 2345,
    event_mode: true,
    host: "localhost",
    inet_adapter: :inet,
    name: CustomFLHookClient,
    password: "$3cret",
    port: 1920,
    recv_timeout: 3456,
    send_timeout: 4567,
    tcp_adapter: :gen_tcp
  )

Once connected, you can send commands to the server.

FLHook.cmd(client, "readcharfile Player1")
# => {:ok, %FLHook.Result{lines: ["...", "..."]}}

Alternatively, you can use the tuple format for commands:

FLHook.cmd(client, {"readcharfile", ["Player1"]})

Additionally, any value is accepted as command argument that implements the FLHook.Command protocol.

By setting event_mode: true, server events will be sent to all subscribed processes. You can add a listener for the current process as follows:

FLHook.subscribe(client)

You can also register other processes as listeners:

pid = self()

Task.async(fn ->
  FLHook.subscribe(client, pid)
end)

Unsubscription works the same way.

The received events have the following format:

iex> flush()
%FLHook.Event{
  type: "launch",
  dict: %FLHook.Dict{data: "system" => "Li01", "char" => "Player"}
}

Generally, it is recommended to start the client as part of your supervision tree. To do this, add a custom module using the FLHook.Client module.

defmodule MyApp.FLClient do
  use FLHook.Client, otp_app: :my_app
end

Then, add some configuration in config.exs or your environment-specific configs.

config :my_app, MyApp.FLClient,
  host: "localhost",
  port: 1920

After that, add your custom client to your application.ex.

def start(_type, _args) do
  children = [
    MyApp.FLClient
  ]

  # ...
end

Voilà! You can now send commands to the same server without passing the client process as first argument.

MyApp.FLClient.cmd(client, "readcharfile Player1")
# => {:ok, %FLHook.Result{lines: ["...", "..."]}}

Docs

Documentation can be generated with ExDoc and is published on HexDocs.