Share Pastebin
Guest
Public paste!

Untitled

By: a guest | Feb 9th, 2010 | Syntax: C++ | Size: 23.99 KB | Hits: 7 | Expires: Never
This paste has a previous version, view the difference. Copy text to clipboard
  1. /*
  2.  * Copyright (c) 2007 cycad <cycad@zetasquad.com>
  3.  *
  4.  * This software is provided 'as-is', without any express or implied
  5.  * warranty. In no event will the author be held liable for any damages
  6.  * arising from the use of this software.
  7.  *
  8.  * Permission is granted to anyone to use this software for any purpose,
  9.  * including commercial applications, and to alter it and redistribute
  10.  * it freely, subject to the following restrictions:
  11.  *
  12.  *     1. The origin of this software must not be misrepresented; you
  13.  *     must not claim that you wrote the original software. If you use
  14.  *     this software in a product, an acknowledgment in the product
  15.  *     documentation would be appreciated but is not required.
  16.  *
  17.  *     2. Altered source versions must be plainly marked as such, and
  18.  *     must not be misrepresented as being the original software.
  19.  *
  20.  *     3. This notice may not be removed or altered from any source
  21.  *     distribution.
  22.  */
  23.  
  24. /*
  25.  * opencore is essentially a reimplementation of Ekted's PowerBot.
  26.  *
  27.  * The libs/ folder contains a test plugin, features.cpp.  This
  28.  * demonstrates the the capabilities of the core and explains them.
  29.  *
  30.  * Both the core and the test plugin can each be compiled with
  31.  * the Makefile in their directories. 'make' is all thats needed
  32.  * to compile them.
  33.  *
  34.  * The file 'master.conf' is the main bot's configuration file. Change
  35.  * ServerName in it to the IP of the test server. On the machine running
  36.  * the test server open subbill.exe and then subgame2.exe in that order.
  37.  *
  38.  * opencore should now be able to connect.
  39.  */
  40.  
  41. /*
  42.  * Bot Management
  43.  *
  44.  * This hasn't been designed yet so bot management is ugly. The
  45.  * single configuration file for each bot will need to be changed.
  46.  * Stopping/Starting bots is also ugly.
  47.  */
  48.  
  49. /*
  50.  * Player Management
  51.  *
  52.  * Every time a player enters or leaves an arena there are events
  53.  * generated, EVENT_ENTER and EVENT_LEAVE.
  54.  *
  55.  * Player management such as player allocation and deallocation
  56.  * is internal to the core. As such, pointers to PLAYER objects are
  57.  * NOT guaranteed to be constant between different events. In
  58.  * order to keep track of a specific player, store the player's
  59.  * PID and not the player's pointer.
  60.  *
  61.  * Player PID's are assigned by the subgame server and are
  62.  * guaranteed by the core to remain constant between ENTER and
  63.  * LEAVE events. The core only has visibility in one arena, however,
  64.  * and can't guarantee that a player's PID will remain constant
  65.  * if a player enters, leaves, and then reenters. Use a player's
  66.  * name to keep track of players between LEAVE and ENTER events.
  67.  *
  68.  * Player-specific data is managed by the core using Player Info or
  69.  * pinfo for short. pinfo is guaranteed to be constant even across
  70.  * ENTER and LEAVE events pinfo could be used to keep track of how
  71.  * many kills an individual player has had since the bot has loaded
  72.  * into the arena, for example.
  73.  *
  74.  * When a player is first seen by the core an EVENT_FIRSTSEEN
  75.  * is generated. pinfo is always zeroed out before EVENT_FIRSTSEEN.
  76.  * Plugins can use this event to do dynamic allocations and
  77.  * initialization of pinfo.
  78.  *
  79.  * To use pinfo, you need to define a structure and then set the
  80.  * LIB_PINFO_SIZE to the size of the pinfo structure.
  81.  *
  82.  * A small pinfo example:
  83.  *
  84.  *      // global namespace
  85.  *      struct PlayerInfo {
  86.  *              int nkills;             // number of kills
  87.  *              std::list<int> l;       // example dynamic data
  88.  *      };
  89.  *      LIB_PINFO_SIZE = sizeof(struct PlayerInfo);
  90.  *
  91.  *      // in EVENT_FIRSTSEEN
  92.  *      struct PlayerInfo *pi = GetPlayerInfo(cd, data->p1);
  93.  *      pi->nkills = 0; // unnecessary since pinfo is zeroed
  94.  *      pi->l = new std::list<int>;
  95.  *
  96.  *      // in EVENT_DEADSLOT
  97.  *      struct PlayerInfo *pi = GetPlayerInfo(cd, data->p1);
  98.  *      delete pi->l;
  99.  *
  100.  */
  101.  
  102. /*
  103.  * Thread-Specific Data / Bot-Specific Data
  104.  *
  105.  * Any number of threads can be active in a library at any one time,
  106.  * therefore access to any writable global data must be synchronized.
  107.  *
  108.  * To have data that is specific to a single thread (bot) you must
  109.  * use the 'user_data' convention.  CORE_DATA.user_data is a
  110.  * thread-specific pointer to memory region where a thread can
  111.  * store values it needs. CORE_DATA.user_data should be allocated
  112.  * and set during EVENT_START and freed during EVENT_STOP.
  113.  * The user_data structure allocated should contain all the thread-
  114.  * specific variables that a thread needs.
  115.  *
  116.  * An example of keeping track of the total number of kills that
  117.  * have occurred in an arena since the bot joined using a thread-
  118.  * specific approach.
  119.  *
  120.  *      // global namespace
  121.  *      struct UserData {
  122.  *              int tkills;     // total kills in the arena
  123.  *      };
  124.  *
  125.  *      // in EVENT_START
  126.  *      cd->user_data = malloc(sizeof(struct UserData));
  127.  *
  128.  *      // in EVENT_KILL
  129.  *      struct UserData *ud = (struct UserData)cd->user_data;
  130.  *      ud->tkills += 1;
  131.  *
  132.  *      // in EVENT_STOP
  133.  *      free(ud->user_data);
  134.  *
  135.  * With this example each thread will have its own unique user_data
  136.  * pointer and total kill counter. If this plugin is loaded by
  137.  * bots in 3 different arenas they will each keep their own kill
  138.  * tally.
  139.  *
  140.  * And a global version:
  141.  *
  142.  *      // global namespace
  143.  *      static int g_tkills = 0;
  144.  *      static pthread_mutex_t g_tkills_mutex =
  145.  *          PTHREAD_MUTEX_INITIALIZER;
  146.  *
  147.  *      // in EVENT_KILL
  148.  *      pthread_mutex_lock(&g_tkills_mutex);
  149.  *      g_tkills++;
  150.  *      pthread_mutex_lock(&g_tkills_mutex);
  151.  *
  152.  * If multiple bots were loaded that used this plugin they
  153.  * would all share the same kill counter.  This would keep track
  154.  * of kills in all arenas that plugin is running in.
  155.  */
  156.  
  157. /*
  158.  * Operators and Access Levels
  159.  *
  160.  * All players have an access level ranging from 0-9. Players not listed
  161.  * in ops.conf are level 0. Players in ops.conf have the access level
  162.  * specified on their line.
  163.  */
  164.  
  165. #ifndef _LIBOPENCORE_HPP
  166. #define _LIBOPENCORE_HPP
  167.  
  168. #include <stdint.h>
  169. #include <stdlib.h>
  170.  
  171. /* C linkage for functions */
  172. extern "C" {
  173.  
  174. /* This must match the core's version string */
  175. #define CORE_VERSION "0.18"
  176.  
  177. typedef uint32_t ticks_ms_t;
  178. typedef uint32_t ticks_hs_t;
  179.  
  180. /*
  181.  * These are the events that the core exports to modules.  In each event
  182.  * only SOME of the variables in the CORE_DATA structure are set. Any
  183.  * elements that are not set by the current event being handled should
  184.  * be treated as INVALID during that event.
  185.  *
  186.  * Variables set in CORE_DATA during each event are noted next to
  187.  * the event name.
  188.  *
  189.  * Variables that are sometimes set have a '!' suffix.
  190.  */
  191.                                 /* CORE_DATA elements set: */
  192. /*
  193.  * EVENT_START occurs when the library is loaded. It
  194.  * can be used to allocate CORE_DATA.user_data, register
  195.  * commands, and do other library-specific setup operations.
  196.  */
  197. #define EVENT_START     0       /* none */
  198.  
  199. /*
  200.  * EVENT_STOP occurs when the module is unloaded. It can be used
  201.  * to free CORE_DATA.user_data and to perform other shutdown
  202.  * operations.
  203.  */
  204. #define EVENT_STOP      1       /* none */
  205.  
  206. /*
  207.  * EVENT_LOGIN occurs when the bot logs in to the server.
  208.  * For modules loaded when the bot is already connected
  209.  * this event does not occur.
  210.  */
  211. #define EVENT_LOGIN     2       /* none */
  212.  
  213. /*
  214.  * EVENT_KILL occurs when a player is killed.
  215.  *
  216.  * p1 is killed by p2.
  217.  */
  218. #define EVENT_KILL      3       /* p1, p2 */
  219.        
  220. /*
  221.  * EVENT_FIRSTSEEN occurs when a player is first seen
  222.  * by the bot. This can be used to do allocations and
  223.  * initializations in pinfo.
  224.  *
  225.  * Players are kept cached for 1 hour since they were last seen.
  226.  * After a player has not been seen for 1 hour their internal
  227.  * player entry is deleted and an EVENT_DEADSLOT is generated.
  228.  * This event should be used to free any dynamically allocated
  229.  * pinfo data during EVENT_FIRSTSEEN.
  230.  */
  231. #define EVENT_FIRSTSEEN 4       /* p1 */
  232.  
  233. /*
  234.  * EVENT_ENTER occurs when a player enters the arena.
  235.  */
  236. #define EVENT_ENTER     5       /* p1 */
  237.  
  238. /*
  239.  * EVENT_LEAVE occurs when a player leaves the arena.
  240.  * When a bot disconnects or shuts down this event does
  241.  *  not occur.
  242.  */
  243. #define EVENT_LEAVE     6       /* p1 */
  244.  
  245. /*
  246.  * EVENT_CHANGE occurs when a player changes ship.
  247.  */
  248. #define EVENT_CHANGE    7       /* p1, old_freq, old_ship */
  249.  
  250. /*
  251.  * EVENT_DEADSLOT occurs when a player is deleted from
  252.  * the core-managed player array. This happens 1 hour
  253.  * since a player was last seen.  This event can be used
  254.  * to deallocate anything in pinfo. This is guaranteed
  255.  * to occur.
  256.  */
  257. #define EVENT_DEADSLOT  8       /* p1 */
  258.  
  259. /*
  260.  * EVENT_MESSAGE occurs when the bot receives a message.
  261.  *
  262.  * p1 always set, but is sometimes NULL such as during
  263.  * arena or remote messages.
  264.  */
  265. #define EVENT_MESSAGE   9       /* msg, msg_{type,name,chatname!,chatid!}, p1! */
  266.  
  267. /*
  268.  * EVENT_ALERT occurs when ?alerts are sent.
  269.  */
  270. #define EVENT_ALERT     10      /* alert_{msg,name,type,arena} */
  271.  
  272. /*
  273.  * EVENT_UPDATE occurs when a position packet is received.
  274.  */
  275. #define EVENT_UPDATE    11      /* p1, p1.status, p1.x, p1.y */
  276.  
  277. /*
  278.  * EVENT_TICK occurs every 100ms. It can be used for periodic
  279.  * checks.
  280.  */
  281. #define EVENT_TICK      12      /* none */
  282.  
  283. /*
  284.  * EVENT_TIMER occurs when a timer set by SetTimer() expires.
  285.  * timer_id is the timer's unique id number and can be used
  286.  * to identify a specific timer. timer_data1 and timer_data2
  287.  * are set exactly as they were passed to SetTimer().
  288.  *
  289.  * Timers are only granular to 100ms.
  290.  */
  291. #define EVENT_TIMER     13      /* timer_id, timer_data1, timer_data2 */
  292.  
  293. /*
  294.  * This event is not exported to the event callback, commands
  295.  * go directly to their handling callbacks.
  296.  */
  297. #define EVENT_COMMAND   14      /* cmd_* */
  298.  
  299. /*
  300.  * Happens when a players *info data is updated.
  301.  */
  302. #define EVENT_INFO      15      /* p1, p1->info */
  303.  
  304. /*
  305.  * Happens when a players *einfo data is updated.
  306.  */
  307. #define EVENT_EINFO     16      /* p1, p1->einfo */
  308.  
  309. /*
  310.  * Happens when the bot gets disconnected.
  311.  */
  312. #define EVENT_DISCONNECT 17     /* none */
  313.  
  314. /*
  315.  * Happens when a file has been received.
  316.  */
  317. #define EVENT_TRANSFER  18      /* transfer_direction, transfer_filename, transfer_success */
  318.  
  319. /*
  320.  * Happens when a file has been received.
  321.  */
  322. #define EVENT_ARENA_CHANGE      19      /* bot_arena */
  323.  
  324. /*
  325.  * Happens when the server is showing clients the arena list.
  326.  */
  327. #define EVENT_ARENA_LIST        20      /* arena_list, arena_list_count */
  328.  
  329. typedef uint16_t FREQ;
  330. #define FREQ_NONE               (FREQ)0xFFFF
  331.  
  332. typedef uint8_t MSG_TYPE;
  333. #define MSG_ARENA               (MSG_TYPE)0x00
  334. #define MSG_PUBLIC_MACRO        (MSG_TYPE)0x01
  335. #define MSG_PUBLIC              (MSG_TYPE)0x02
  336. #define MSG_TEAM                (MSG_TYPE)0x03
  337. #define MSG_FREQ                (MSG_TYPE)0x04
  338. #define MSG_PRIVATE             (MSG_TYPE)0x05
  339. #define MSG_WARNING             (MSG_TYPE)0x06
  340. #define MSG_REMOTE              (MSG_TYPE)0x07
  341. #define MSG_SYSOP               (MSG_TYPE)0x08
  342. #define MSG_CHAT                (MSG_TYPE)0x09
  343.  
  344. #define STATUS_STEALTH  (uint8_t)0x01
  345. #define STATUS_CLOAK    (uint8_t)0x02
  346. #define STATUS_XRADAR   (uint8_t)0x04
  347. #define STATUS_ANTIWARP (uint8_t)0x08
  348. #define STATUS_UNCLOAK  (uint8_t)0x10
  349. #define STATUS_SAFE     (uint8_t)0x20
  350. #define STATUS_UNKNOWN  (uint8_t)0x40
  351. #define STATUS_CONSTANT_VELOCITY (uint8_t)0x80
  352.  
  353. typedef uint8_t CMD_TYPE;
  354. #define CMD_REMOTE      (CMD_TYPE)0x01
  355. #define CMD_PUBLIC      (CMD_TYPE)0x02
  356. #define CMD_PRIVATE     (CMD_TYPE)0x04
  357.  
  358. typedef uint16_t PLAYER_ID;
  359. #define PID_NONE        (PLAYER_ID)0xFFFF
  360.  
  361. typedef uint8_t SHIP;
  362. #define SHIP_NONE       SHIP_SPECTATOR
  363. #define SHIP_WARBIRD    (SHIP)0x00
  364. #define SHIP_JAVELIN    (SHIP)0x01
  365. #define SHIP_SPIDER     (SHIP)0x02
  366. #define SHIP_LEVIATHAN  (SHIP)0x03
  367. #define SHIP_TERRIER    (SHIP)0x04
  368. #define SHIP_WEASEL     (SHIP)0x05
  369. #define SHIP_LANCASTER  (SHIP)0x06
  370. #define SHIP_SHARK      (SHIP)0x07
  371. #define SHIP_SPECTATOR  (SHIP)0x08
  372.  
  373. typedef uint8_t MATCH_TYPE;
  374. #define MATCH_HERE      (MATCH_TYPE)0x01        /* Match players present in arena */
  375. #define MATCH_GONE      (MATCH_TYPE)0x02        /* Match players absent from arena*/
  376. #define MATCH_PREFIX    (MATCH_TYPE)0x04        /* Match name prefix (name search only) */
  377.  
  378. typedef uint8_t SOUND;
  379. #define SOUND_NONE      (SOUND)0x00
  380.  
  381. typedef uint8_t OP_LEVEL;
  382. #define OP_PLAYER       (OP_LEVEL)0x00
  383. #define OP_REF          (OP_LEVEL)0x01
  384. #define OP_MOD          (OP_LEVEL)0x02
  385. #define OP_SENMOD       (OP_LEVEL)0x03
  386. #define OP_ASMOD        (OP_LEVEL)0x04
  387. #define OP_SMOD         (OP_LEVEL)0x05
  388. #define OP_SENSMOD      (OP_LEVEL)0x06
  389. #define OP_HSMOD        (OP_LEVEL)0x07
  390. #define OP_SYSOP        (OP_LEVEL)0x08
  391. #define OP_OWNER        (OP_LEVEL)0x09
  392.  
  393. #define TRANSFER_S2C    (uint8_t)0x00
  394. #define TRANSFER_C2S    (uint8_t)0x01   /* currently unused */
  395.  
  396.  
  397. typedef struct point POINT;
  398. struct point
  399. {
  400.         uint16_t        x;
  401.         uint16_t        y;
  402. };
  403.  
  404.  
  405. typedef struct arena_list ARENA_LIST;
  406. struct arena_list
  407. {
  408.         char name[16];          /* arena name */
  409.         uint16_t count;         /* number of players here */
  410.         int current_arena;      /* set if this is the arena the bot is in */
  411. };
  412.  
  413. /*
  414.  * Contains player data.
  415.  */
  416. typedef struct PLAYER_ PLAYER;
  417. struct PLAYER_ {
  418.         PLAYER*         here_next;      /* next player in here list */
  419.         PLAYER*         here_prev;      /* previous player in here list */
  420.         PLAYER*         spec_next;      /* next player in spec list */
  421.         PLAYER*         spec_prev;      /* previous player in spec list */
  422.         PLAYER*         ship_next;      /* next player in ship list */
  423.         PLAYER*         ship_prev;      /* previous player in ship list */
  424.  
  425.         char            name[20];       /* player's name */
  426.         char            squad[20];      /* squad name */
  427.  
  428.         PLAYER_ID       pid;            /* pid value retrieved from server */
  429.  
  430.         ticks_ms_t      enter_tick;     /* tick of when the player entered */
  431.         ticks_ms_t      leave_tick;     /* tick of when the player left */
  432.  
  433.         uint8_t         ship;           /* the players ship, SHIP_xxx */
  434.         uint16_t        freq;           /* the players freq */
  435.  
  436.         POINT           pos[1];         /* player position */
  437.         uint16_t        x_vel;          /* x velocity */
  438.         uint16_t        y_vel;          /* y velocity */
  439.  
  440.         uint8_t         status;         /* player's status (bitfield) see STATUS_xxx */
  441.  
  442.         uint8_t         in_arena;       /* non-zero if player is in the arena */
  443.  
  444.         struct {
  445.                 int valid;              /* non-zero when the entry is valid */
  446.  
  447.                 uint32_t mid;           /* machine id */
  448.                 uint32_t ip;            /* ip address in host format */
  449.  
  450.                 struct {
  451.                         ticks_ms_t current;    
  452.                         ticks_ms_t low;
  453.                         ticks_ms_t high;
  454.                         ticks_ms_t average;
  455.                 } ping[1];
  456.  
  457.                 struct {
  458.                         float s2c;
  459.                         float c2s;
  460.                         float s2c_wep;
  461.                 } ploss[1];
  462.  
  463.         } info[1];
  464.  
  465.         struct {
  466.                 int     valid;          /* non-zero when the entry is valid */
  467.  
  468.                 uint32_t userid;        /* user id */
  469.                 struct {
  470.                         uint16_t x;
  471.                         uint16_t y;
  472.                 } res[1];
  473.  
  474.                 ticks_ms_t      idle_ticks;
  475.                 uint32_t        timer_drift;
  476.         } einfo[1];
  477. };
  478.  
  479. /*
  480.  * Data from the core that is exported to event handlers.
  481.  */
  482. typedef struct core_data CORE_DATA;
  483. struct core_data
  484. {
  485.         int       event;        /* the event being exported */
  486.  
  487.         PLAYER   *p1;           /* player 1 */
  488.         PLAYER   *p2;           /* player 2 */
  489.  
  490.         char     *msg;          /* the content of the message */
  491.         char     *msg_name;     /* the name of the player, may be "" (zone/arena msgs */
  492.         MSG_TYPE  msg_type;     /* the type of msg, see MSG_xxx */
  493.         char     *msg_chatname; /* name of the chat, may be NULL */
  494.         int       msg_chatid;   /* id of the chat, range 1 .. n, 0 if unset */
  495.  
  496.         char     *alert_name;   /* the name of the player who sent the ?alert */
  497.         char     *alert_arena;  /* the arena the ?alert was sent from */
  498.         char     *alert_msg;    /* the text of the ?alert */
  499.         char     *alert_type;   /* the type of the alert */
  500.  
  501.         SHIP      old_ship;     /* the players old ship */
  502.         FREQ      old_freq;     /* the players old freq */
  503.  
  504.         long      timer_id;     /* unique timer id of the timer expiring */
  505.         void     *timer_data1;  /* data1 as passed to SetTimer() */
  506.         void     *timer_data2;  /* data2 as passed to SetTimer() */
  507.  
  508.         char     *cmd_name;     /* name of player issuing command */
  509.         CMD_TYPE  cmd_type;     /* type of command */
  510.         int       cmd_argc;     /* number of arguments, including command name */
  511.         int       cmd_level;    /* access level of player issuing command */
  512.         char    **cmd_argv;     /* individual arguments on command line */
  513.         char    **cmd_argr;     /* remaining arguments on command line */
  514.  
  515.         uint8_t   transfer_success;     /* set if the transfer was successful */
  516.         uint8_t   transfer_direction;   /* TRANSFER_S2C or TRANSFER_C2S */
  517.         char     *transfer_filename;    /* file name */
  518.  
  519.         char     ac_old_arena[16];      /* arena change old arena */
  520.  
  521.         ARENA_LIST *arena_list; /* EVENT_ARENA_LIST */
  522.         int arena_list_count;
  523.  
  524.         /* The below are always set during events (where they would be valid) */
  525.         PLAYER_ID bot_pid;      /* the bot's pid */
  526.         char     *bot_name;     /* the bot's name */
  527.         FREQ      bot_freq;     /* the bot's freq */
  528.         SHIP      bot_ship;     /* the bot's ship */
  529.         char     *bot_arena;    /* the bot's arena */
  530.  
  531.         PLAYER   *here_first;   /* head of here list */
  532.         PLAYER   *here_last;    /* tail of here list */
  533.         PLAYER   *spec_first;   /* head of here list */
  534.         PLAYER   *spec_last;    /* tail of here list */
  535.         PLAYER   *ship_first;   /* head of here list */
  536.         PLAYER   *ship_last;    /* tail of here list */
  537.         int       here_count;   /* number of players in the arena */
  538.         int       spec_count;   /* number of players in spec */
  539.         int       ship_count;   /* number of players in a ship */
  540.  
  541.         void     *user_data;    /* The thread-specific memory pointer */
  542.  
  543.         void    **pinfo_base;   /* The pinfo array base, used for pinfo */
  544.         PLAYER   *parray;       /* The player array base, used for pinfo */
  545.         int       phere;        /* number of used player slots */
  546. };
  547.  
  548. /*
  549.  * The plugin's game event callback.
  550.  */
  551. typedef void (*GameEvent_cb)(CORE_DATA *cd);
  552.  
  553.  
  554. /*
  555.  * Contains library data.
  556.  */
  557. typedef struct LIB_DATA_ LIB_DATA;
  558. struct LIB_DATA_ {
  559.         char    *name;
  560.         char    *author;
  561.         char    *version;
  562.         char    *date;
  563.         char    *time;
  564.         char    *description;
  565.         char    *oc_version;
  566.         int      pinfo_size;
  567.  
  568.         GameEvent_cb cb;
  569. };
  570.  
  571. /*
  572.  * This is the callback prototype used for commands. Commands must all be
  573.  *  registered with the RegisterCommand() function.
  574.  *
  575.  * 'name' is always set to the name of the player who issued the command.
  576.  * 'level' is always set to the player's bot access level.
  577.  * 'cmd_type' is one of CMD_xxx, indicating the type of message used to
  578.  *              issue the command. NOT interchangeable with MSG_xxx.
  579.  * 'argc' is the number of arguments sent to the command, including the
  580.  *              command name itself. argc-1 is the largest valid index
  581.  *              into the argv and argr arrays.
  582.  * 'argv' is an array of pointers to strings that contain each sequential
  583.  *              command argument. argv[0] is the command itself.
  584.  * 'argr' is an array of pointers to strings that contain each argument and
  585.  *              everything that follows it. argr[1] is the first
  586.  *              argument and everything after it.
  587.  */
  588. typedef void (*Command_cb)(CORE_DATA *cd);
  589.  
  590. /*
  591.  * Registers a command and its callback handler with the core.
  592.  *
  593.  * 'cmd_text' is the actual command. It must begin with a '!'.
  594.  * 'cmd_class' a one-word class/category that the command shows up in
  595.  *     when a player views !help.
  596.  * 'req_level' the op level that a player has to have to use the command.
  597.  * 'cmd_type' the class of messages that this command can be sent from. One
  598.  *     of CMD_xxx.
  599.  * 'cmd_args' arguments to the command. May be NULL. If a command has
  600.  *              arguments, they should be specified UNIX-style. Angle
  601.  *              brackets enclose required commands, square brackets
  602.  *              enclose optional arguments.
  603.  * 'cmd_desc' a short description of the plugin. May be NULL.
  604.  * 'cmd_ldesc' a long description of the command. May be NULL.
  605.  * 'func' the command handler callback.
  606.  */
  607. void    RegisterCommand(char *cmd_text, char *cmd_class, int req_level,
  608.             CMD_TYPE cmd_type, char *cmd_args, char *cmd_desc,
  609.             char *cmd_ldesc, Command_cb func);
  610.  
  611. /*
  612.  * Set a timer.  It will expire in 'duration' milliseconds, causing
  613.  * EVENT_TIMER to occur. SetTimer() returns a unique timer id
  614.  * that is passed as 'timer_id' in EVENT_TIMER. 'data1' and 'data2'
  615.  * are values that are passed back during EVENT_TIMER in 'timer_data1'
  616.  * and 'timer_data2'. This can be used to store user-specified data, or
  617.  * can be NULL if they are unused. Timers are only as granular as
  618.  * 100ms.
  619.  *
  620.  * To handle multiple timers, store SetTimer's return value and
  621.  * check it against CORE_DATA.timer_id during EVENT_TIMER.
  622.  */
  623. long    SetTimer(ticks_ms_t duration, void *data1, void *data2);
  624.  
  625. /*
  626.  * Kill a timer with id of 'timer_id'
  627.  */
  628. void    KillTimer(long timer_id);
  629.  
  630. /*
  631.  * Log a message to the log system. 'lvl' is the required op level to view
  632.  * in !log.
  633.  */
  634. void    Log(OP_LEVEL lvl, char *str);
  635. void    LogFmt(OP_LEVEL lvl, char *fmt, ...);
  636.  
  637. /*
  638.  * Functions for starting and stopping bots.
  639.  */
  640. char*   StartBot(char *type, char *arena, char *owner); /* returns error string on error */
  641. void    StopBot(char *reason);
  642. void    StopBotFmt(char *fmt, ...);
  643.  
  644. /*
  645.  * Change the bot's arena.
  646.  */
  647. void    Go(char *arena);
  648.  
  649. /*
  650.  * Set the bot's x and y coordinates (in pixels)
  651.  */
  652. void    SetPosition(uint16_t x, uint16_t y, uint16_t xv, uint16_t yv);
  653.  
  654. /*
  655.  * Queue a file for transfer. The file will be transferred as soon
  656.  * as possible and an EVENT_TRANSFER event will be generated when
  657.  * the transfer completes.
  658.  *
  659.  * Returns 1 on success, 0 on failure. Filenames containing
  660.  * '..', '\', or '/' fail.
  661.  */
  662. int     QueueGetFile(const char *filename, const char *initiator);
  663. int     QueueSendFile(const char *filename, const char *initiator);
  664.  
  665. /*
  666.  * Get the oplevel for 'name', as defined in 'ops.conf'.
  667.  */
  668. int     GetOpLevel(char *name);
  669.  
  670. /*
  671.  * Search functions:
  672.  *
  673.  * FindPlayerName:
  674.  * Find a player with the name of 'name'.  The player may
  675.  * or may not be in the arena. PLAYER.in_arena will be set to 1
  676.  * if the player is in the arena.
  677.  *
  678.  * FindPlayerPid:
  679.  * Search for a player by his player id. This only searches
  680.  * players who are currently in the arena.  Players who are not
  681.  * in the arena do not have valid ids since they may have left
  682.  * the zone and the server may have reassigned the pid to someone
  683.  * else.
  684.  */
  685. PLAYER* FindPlayerName(char *name, MATCH_TYPE match_type);
  686. PLAYER* FindPlayerPid(PLAYER_ID pid, MATCH_TYPE match_type);
  687.  
  688. /*
  689.  * Message Functions:
  690.  *
  691.  * Various functions for sending messages. RmtMessage* can be used
  692.  * for generic priv message sending such as in command handlers.
  693.  */
  694. void    ArenaMessage(const char *msg);
  695. void    ArenaMessageFmt(const char *fmt, ...);
  696. void    ChatMessage(const char *chat, const char *msg);
  697. void    ChatMessageFmt(const char *chat, const char *fmt, ...);
  698. char*   ChatName(int number);   /* 1 .. n */
  699. void    PubMessage(const char *msg);
  700. void    PubMessageFmt(const char *fmt, ...);
  701. void    PrivMessage(PLAYER *p, const char *msg);
  702. void    PrivMessageFmt(PLAYER *p, const char *fmt, ...);
  703. void    RmtMessage(const char *name, const char *msg);
  704. void    RmtMessageFmt(const char *name, const char *fmt, ...);
  705. void    TeamMessage(const char *msg);
  706. void    TeamMessageFmt(const char *fmt, ...);
  707. void    FreqMessage(PLAYER *p, const char *msg);
  708. void    FreqMessageFmt(PLAYER *p, const char *fmt, ...);
  709. /*
  710.  * These are only valid inside EVENT_COMMAND.
  711.  */
  712. void    Reply(const char *msg);
  713. void    ReplyFmt(const char *fmt, ...);
  714.  
  715. /*
  716.  * Copy a field from a string into a buffer.
  717.  *
  718.  * 'dst' is the destination
  719.  * 'len' is the size of the destination buffer
  720.  * 'src' is the source string
  721.  * 'arg' is the 0-based column to extract
  722.  * 'delim' is the delimiter between columns
  723.  * 'getremain' specifies whether or not to retrieve everything
  724.  * after the specified column, including delimiters
  725.  */
  726. void    DelimArgs(char *dst, int len, char *src, int arg, char delim, bool getremain);
  727.  
  728. /*
  729.  * Count the number of arguments in a 'delim'-delimted string.
  730.  *
  731.  * For example, assuming a ':'-delimited string:
  732.  * "" -> 0
  733.  * "asdf" -> 1
  734.  * "asdf:asdf" -> 2
  735.  * ...
  736.  */
  737. int     ArgCount(char *str, char delim);
  738.  
  739. /*
  740.  * Like DelimArgs, except the argument is converted to an integer.
  741.  */
  742. int     AtoiArg(char *src, int arg, char delim);
  743.  
  744. /*
  745.  * Count the number of delimiters in a string.
  746.  */
  747. int     DelimCount(char *str, char delim);
  748.  
  749. /*
  750.  * Convert ticks to a readable string.
  751.  */
  752. void    TicksToText(char *dst, int dstl, ticks_ms_t ticks);
  753.  
  754. /*
  755.  * Determines the type of an arena based on name.
  756.  */
  757. int     IsPub(char *arena);             /* 0-99 */
  758. int     IsSubarena(char *arena);        /* non-main pub, ex: duel, baseduel, ladder */
  759. int     IsPriv(char *arena);            /* priv */
  760.  
  761. /*
  762.  * Get the tick count.
  763.  */
  764. ticks_ms_t      GetTicksMs();
  765.  
  766. /*
  767.  * Retrieve a player-specific pinfo struct.  This is only valid if
  768.  * LIB_PINFO_SIZE is set.
  769.  */
  770. inline
  771. void*
  772. GetPlayerInfo(CORE_DATA *cd, PLAYER *p)
  773. {
  774.         return cd->pinfo_base[p - cd->parray];
  775. }
  776.  
  777. /*
  778.  * Wrappers for common functions.
  779.  */
  780. void    *xcalloc(size_t nmemb, size_t sz);
  781. void    *xmalloc(size_t sz);
  782. void    *xzmalloc(size_t sz);
  783.  
  784. void    strlwr(char *str);
  785.  
  786. /*
  787.  * Each of these must be defined in the library.
  788.  */
  789. extern LIB_DATA REGISTRATION_INFO;      /* single word library name */
  790.  
  791. #ifdef __cplusplus
  792. }
  793. #endif
  794.  
  795. #endif /* _LIBOPENCORE_HPP */