Index


GLOBAL VARIABLES

$cf::UPTIME

The timestamp of the server start (so not actually an uptime).

$cf::RUNTIME

The time this server has run, starts at 0 and is increased by $cf::TICK on every server tick.

$cf::CONFDIR $cf::DATADIR $cf::LIBDIR $cf::PODDIR $cf::MAPDIR $cf::LOCALDIR $cf::TMPDIR $cf::UNIQUEDIR $cf::PLAYERDIR $cf::RANDOMDIR $cf::BDBDIR

Various directories - "/etc", read-only install directory, perl-library directory, pod-directory, read-only maps directory, "/var", "/var/tmp", unique-items directory, player file directory, random maps directory and database environment.

$cf::NOW

The time of the last (current) server tick.

$cf::TICK

The interval between server ticks, in seconds.

$cf::LOADAVG

The current CPU load on the server (alpha-smoothed), as a value between 0 (none) and 1 (overloaded), indicating how much time is spent on processing objects per tick. Healthy values are < 0.5.

$cf::LOAD

The raw value load value from the last tick.

%cf::CFG

Configuration for the server, loaded from /etc/deliantra-server/config, or from wherever your confdir points to.

cf::wait_for_tick, cf::wait_for_tick_begin

These are functions that inhibit the current coroutine one tick. cf::wait_for_tick_begin only returns directly after the tick processing (and consequently, can only wake one process per tick), while cf::wait_for_tick wakes up all waiters after tick processing.

@cf::INVOKE_RESULTS

This array contains the results of the last invoke () call. When cf::override is called @cf::INVOKE_RESULTS is set to the parameters of that call.

UTILITY FUNCTIONS

dumpval $ref
$ref = cf::decode_json $json

Converts a JSON string into the corresponding perl data structure.

$json = cf::encode_json $ref

Converts a perl data structure into its JSON representation.

cf::lock_wait $string

Wait until the given lock is available. See cf::lock_acquire.

my $lock = cf::lock_acquire $string

Wait until the given lock is available and then acquires it and returns a Coro::guard object. If the guard object gets destroyed (goes out of scope, for example when the coroutine gets canceled), the lock is automatically returned.

Locks are *not* recursive, locking from the same coro twice results in a deadlocked coro.

Lock names should begin with a unique identifier (for example, cf::map::find uses map_find and cf::map::load uses map_load).

$locked = cf::lock_active $string

Return true if the lock is currently active, i.e. somebody has locked it.

cf::periodic $interval, $cb

Like EV::periodic, but randomly selects a starting point so that the actions get spread over timer.

cf::get_slot $time[, $priority[, $name]]

Allocate $time seconds of blocking CPU time at priority $priority: This call blocks and returns only when you have at least $time seconds of cpu time till the next tick. The slot is only valid till the next cede.

The optional $name can be used to identify the job to run. It might be used for statistical purposes and should identify the same time-class.

Useful for short background jobs.

cf::async { BLOCK }

Currently the same as Coro::async_pool, meaning you cannot use on_destroy, join or other gimmicks on these coroutines. The only thing you are allowed to do is call prio on it.

cf::sync_job { BLOCK }

The design of Deliantra requires that the main coroutine ($Coro::main) is always able to handle events or runnable, as Deliantra is only partly reentrant. Thus "blocking" it by e.g. waiting for I/O is not acceptable.

If it must be done, put the blocking parts into sync_job. This will run the given BLOCK in another coroutine while waiting for the result. The server will be frozen during this time, so the block should either finish fast or be very important.

$coro = cf::async_ext { BLOCK }

Like async, but this coro is automatically being canceled when the extension calling this is being unloaded.

fork_call { }, $args

Executes the given code block with the given arguments in a seperate process, returning the results. Everything must be serialisable with Coro::Storable. May, of course, block. Note that the executed sub may never block itself or use any form of event handling.

$value = cf::db_get $family => $key

Returns a single value from the environment database.

cf::db_put $family => $key => $value

Stores the given $value in the family. It can currently store binary data only (use Compress::LZF::sfreeze_cr/sthaw to convert to/from binary).

$db = cf::db_table "name"

Create and/or open a new database table. The string must not be "db" and must be unique within each server.

cf::cache $id => [$paths...], $processversion => $process

Generic caching function that returns the value of the resource $id, caching and regenerating as required.

This function can block.

cf::datalog type => key => value, ...

Log a datalog packet of the given type with the given key-value pairs.

ATTACHABLE OBJECTS

Many objects in crossfire are so-called attachable objects. That means you can attach callbacks/event handlers (a collection of which is called an "attachment") to it. All such attachable objects support the following methods.

In the following description, CLASS can be any of global, object player, client or map (i.e. the attachable objects in Deliantra).

$attachable->attach ($attachment, key => $value...)
$attachable->detach ($attachment)

Attach/detach a pre-registered attachment to a specific object and give it the specified key/value pairs as arguments.

Example, attach a minesweeper attachment to the given object, making it a 10x10 minesweeper game:

   $obj->attach (minesweeper => width => 10, height => 10);

$bool = $attachable->attached ($name)

Checks wether the named attachment is currently attached to the object.

cf::CLASS->attach ...
cf::CLASS->detach ...

Define an anonymous attachment and attach it to all objects of the given CLASS. See the next function for an explanation of its arguments.

You can attach to global events by using the cf::global class.

Example, log all player logins:

   cf::player->attach (
      on_login => sub {
         my ($pl) = @_;
         ...
      },
   );

Example, attach to the jeweler skill:

   cf::object->attach (
      type         => cf::SKILL,
      subtype      => cf::SK_JEWELER,
      on_use_skill => sub {
         my ($sk, $ob, $part, $dir, $msg) = @_;
         ...
      },
   );

cf::CLASS::attachment $name, ...

Register an attachment by $name through which attachable objects of the given CLASS can refer to this attachment.

Some classes such as crossfire maps and objects can specify attachments that are attached at load/instantiate time, thus the need for a name.

These calls expect any number of the following handler/hook descriptions:

prio => $number

Set the priority for all following handlers/hooks (unless overwritten by another prio setting). Lower priority handlers get executed earlier. The default priority is 0, and many built-in handlers are registered at priority -1000, so lower priorities should not be used unless you know what you are doing.

type => $type

(Only for cf::object->attach calls), limits the attachment to the given type of objects only (the additional parameter subtype can be used to further limit to the given subtype).

on_event => \&cb

Call the given code reference whenever the named event happens (event is something like instantiate, apply, use_skill and so on, and which handlers are recognised generally depends on the type of object these handlers attach to).

See include/eventinc.h for the full list of events supported, and their class.

package => package::

Look for sub functions of the name on_event in the given package and register them. Only handlers for eevents supported by the object/class are recognised.

Example, define an attachment called "sockpuppet" that calls the given event handler when a monster attacks:

   cf::object::attachment sockpuppet =>
      on_skill_attack => sub {
         my ($self, $victim) = @_;
         ...
      }
   }

$attachable->valid

Just because you have a perl object does not mean that the corresponding C-level object still exists. If you try to access an object that has no valid C counterpart anymore you get an exception at runtime. This method can be used to test for existence of the C object part without causing an exception.

$bool = cf::global::invoke (EVENT_CLASS_XXX, ...)
$bool = $attachable->invoke (EVENT_CLASS_XXX, ...)

Generate an object-specific event with the given arguments.

This API is preliminary (most likely, the EVENT_CLASS_xxx prefix will be removed in future versions), and there is no public API to access override results (if you must, access @cf::INVOKE_RESULTS directly).

COMMAND CALLBACKS

cf::register_command $name => \&callback($ob,$args);

Register a callback for execution when the client sends the user command $name.

cf::register_extcmd $name => \&callback($pl,$packet);

Register a callback for execution when the client sends an (synchronous) extcmd packet. Ext commands will be processed in the order they are received by the server, like other user commands. The first argument is the logged-in player. Ext commands can only be processed after a player has logged in successfully.

If the callback returns something, it is sent back as if reply was being called.

cf::register_exticmd $name => \&callback($ns,$packet);

Register a callback for execution when the client sends an (asynchronous) exticmd packet. Exti commands are processed by the server as soon as they are received, i.e. out of order w.r.t. other commands. The first argument is a client socket. Exti commands can be received anytime, even before log-in.

If the callback returns something, it is sent back as if reply was being called.

CORE EXTENSIONS

Functions and methods that extend core crossfire objects.

cf::player

cf::player::num_playing

Returns the official number of playing players, as per the Crossfire metaserver rules.

cf::player::find $login

Returns the given player object, loading it if necessary (might block).

$player->send_msg ($channel, $msg, $color, [extra...])
$pl->quit_character

Nukes the player without looking back. If logged in, the connection will be destroyed. May block for a long time.

$pl->kick

Kicks a player out of the game. This destroys the connection.

cf::player::list_logins

Returns am arrayref of all valid playernames in the system, can take a while and may block, so not sync_job-capable, ever.

$player->maps

Returns an arrayref of map paths that are private for this player. May block.

$protocol_xml = $player->expand_cfpod ($crossfire_pod)

Expand crossfire pod fragments into protocol xml.

$player->ext_reply ($msgid, @msg)

Sends an ext reply to the player.

$player->ext_msg ($type, @msg)

Sends an ext event to the client.

cf::region

cf::region::find_by_path $path

Tries to decuce the likely region for a map knowing only its path.

cf::map

cf::map->register ($regex, $prio)

Register a handler for the map path matching the given regex at the givne priority (higher is better, built-in handlers have priority 0, the default).

$maps = cf::map::tmp_maps

Returns an arrayref with all map paths of currently instantiated and saved maps. May block.

$maps = cf::map::random_maps

Returns an arrayref with all map paths of currently instantiated and saved random maps. May block.

cf::map::unique_maps

Returns an arrayref of paths of all shared maps that have instantiated unique items. May block.

cf::object

$ob->inv_recursive

Returns the inventory of the object _and_ their inventories, recursively.

$ref = $ob->ref

creates and returns a persistent reference to an objetc that can be stored as a string.

$ob = cf::object::deref ($refstring)

returns the objetc referenced by refstring. may return undef when it cnanot find the object, even if the object actually exists. May block.

cf::object::player

$player_object->reply ($npc, $msg[, $flags])

Sends a message to the player, as if the npc $npc replied. $npc can be undef. Does the right thing when the player is currently in a dialogue with the given NPC character.

$object->send_msg ($channel, $msg, $color, [extra...])
$player_object->may ("access")

Returns wether the given player is authorized to access resource "access" (e.g. "command_wizcast").

$player_object->enter_link

Freezes the player and moves him/her to a special map ({link}).

The player should be reasonably safe there for short amounts of time. You MUST call leave_link as soon as possible, though.

Will never block.

$player_object->leave_link ($map, $x, $y)

Moves the player out of the special {link} map onto the specified map. If the map is not valid (or omitted), the player will be moved back to the location he/she was before the call to enter_link, or, if that fails, to the emergency map position.

Might block.

$player_object->goto ($path, $x, $y[, $check->($map)[, $done->()]])

Moves the player to the given map-path and coordinates by first freezing her, loading and preparing them map, calling the provided $check callback that has to return the map if sucecssful, and then unfreezes the player on the new (success) or old (failed) map position. In either case, $done will be called at the end of this process.

$player_object->enter_exit ($exit_object)

cf::client

$client->send_drawinfo ($text, $flags)

Sends a drawinfo packet to the client. Circumvents output buffering so should not be used under normal circumstances.

$client->send_msg ($channel, $msg, $color, [extra...])

Send a drawinfo or msg packet to the client, formatting the msg for the client if neccessary. $type should be a string identifying the type of the message, with log being the default. If $color is negative, suppress the message unless the client supports the msg packet.

$client->ext_msg ($type, @msg)

Sends an ext event to the client.

$client->ext_reply ($msgid, @msg)

Sends an ext reply to the client.

$success = $client->query ($flags, "text", \&cb)

Queues a query to the client, calling the given callback with the reply text on a reply. flags can be cf::CS_QUERY_YESNO, cf::CS_QUERY_SINGLECHAR or cf::CS_QUERY_HIDEINPUT or 0.

Queries can fail, so check the return code. Or don't, as queries will become reliable at some point in the future.

$client->async (\&cb)

Create a new coroutine, running the specified callback. The coroutine will be automatically cancelled when the client gets destroyed (e.g. on logout, or loss of connection).

SAFE SCRIPTING

Functions that provide a safe environment to compile and execute snippets of perl code without them endangering the safety of the server itself. Looping constructs, I/O operators and other built-in functionality is not available in the safe scripting environment, and the number of functions and methods that can be called is greatly reduced.

The following functions and methods are available within a safe environment:

  cf::object
     contr pay_amount pay_player map x y force_find force_add destroy
     insert remove name archname title slaying race decrease_ob_nr

  cf::object::player
     player

  cf::player
     peaceful

  cf::map
     trigger

@retval = safe_eval $code, [var => value, ...]

Compiled and executes the given perl code snippet. additional var/value pairs result in temporary local (my) scalar variables of the given name that are available in the code snippet. Example:

   my $five = safe_eval '$first + $second', first => 1, second => 4;

cf::register_script_function $function => $cb

Register a function that can be called from within map/npc scripts. The function should be reasonably secure and should be put into a package name like the extension.

Example: register a function that gets called whenever a map script calls rent::overview, as used by the rent extension.

   cf::register_script_function "rent::overview" => sub {
     ...
   };