Crossfire Server, Trunk  1.75.0
cflogger.cpp
Go to the documentation of this file.
1 /*****************************************************************************/
2 /* Logger plugin version 1.0 alpha. */
3 /* Contact: */
4 /*****************************************************************************/
5 /* That code is placed under the GNU General Public Licence (GPL) */
6 /* (C)2007 by Weeger Nicolas (Feel free to deliver your complaints) */
7 /*****************************************************************************/
8 /* CrossFire, A Multiplayer game for X-windows */
9 /* */
10 /* Copyright (C) 2000 Mark Wedel */
11 /* Copyright (C) 1992 Frank Tore Johansen */
12 /* */
13 /* This program is free software; you can redistribute it and/or modify */
14 /* it under the terms of the GNU General Public License as published by */
15 /* the Free Software Foundation; either version 2 of the License, or */
16 /* (at your option) any later version. */
17 /* */
18 /* This program is distributed in the hope that it will be useful, */
19 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
20 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
21 /* GNU General Public License for more details. */
22 /* */
23 /* You should have received a copy of the GNU General Public License */
24 /* along with this program; if not, write to the Free Software */
25 /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
26 /* */
27 /*****************************************************************************/
28 
48 #include <cflogger.h>
49 #include <cflogger_proto.h>
50 #include <sqlite3.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #include <svnversion.h>
54 
56 
58 #define CFLOGGER_CURRENT_FORMAT 3
59 
61 static sqlite3 *database;
62 
64 static int last_stored_day = -1;
65 
81 static int check_tables_callback(void *param, int argc, char **argv, char **azColName) {
82  int *format = (int *)param;
83 
84  *format = atoi(argv[0]);
85  return 0;
86 }
87 
103 static int do_sql(const char *sql) {
104  int err;
105  char *msg;
106 
107  if (!database)
108  return -1;
109 
110  err = sqlite3_exec(database, sql, NULL, NULL, &msg);
111  if (err != SQLITE_OK) {
112  cf_log(llevError, " [%s] error: %d [%s] for sql = %s\n", PLUGIN_NAME, err, msg, sql);
113  sqlite3_free(msg);
114  }
115  return err;
116 }
117 
144 static int update_table_format(const char *table, const char *newschema,
145  const char *select_columns) {
146  char *sql;
147  int err;
148 
149  sql = sqlite3_mprintf("ALTER TABLE %s RENAME TO %s_old;", table, table);
150  err = do_sql(sql);
151  sqlite3_free(sql);
152  if (err != SQLITE_OK)
153  return err;
154 
155  sql = sqlite3_mprintf("CREATE TABLE %s(%s);", table, newschema);
156  err = do_sql(sql);
157  sqlite3_free(sql);
158  if (err != SQLITE_OK)
159  return err;
160 
161  sql = sqlite3_mprintf("INSERT INTO %s SELECT %s FROM %s_old;",
162  table, select_columns, table);
163  err = do_sql(sql);
164  sqlite3_free(sql);
165  if (err != SQLITE_OK)
166  return err;
167 
168  sql = sqlite3_mprintf("DROP TABLE %s_old;", table, table);
169  err = do_sql(sql);
170  sqlite3_free(sql);
171  /* Final return. */
172  return err;
173 }
174 
181 #define DO_OR_ROLLBACK(sqlstring) \
182  if (do_sql(sqlstring) != SQLITE_OK) { \
183  do_sql("rollback transaction;"); \
184  cf_log(llevError, " [%s] Logger database format update failed! Couldn't upgrade from format %d to fromat %d!. Won't log.\n", PLUGIN_NAME, format, CFLOGGER_CURRENT_FORMAT);\
185  sqlite3_close(database); \
186  database = NULL; \
187  return; \
188  }
189 
190 #define UPDATE_OR_ROLLBACK(tbl, newschema, select_columns) \
191  if (update_table_format((tbl), (newschema), (select_columns)) != SQLITE_OK) { \
192  do_sql("rollback transaction;"); \
193  cf_log(llevError, " [%s] Logger database format update failed! Couldn't upgrade from format %d to fromat %d!. Won't log.\n", PLUGIN_NAME, format, CFLOGGER_CURRENT_FORMAT);\
194  sqlite3_close(database); \
195  database = NULL; \
196  return; \
197  }
198 
202 static void check_tables(void) {
203  int format;
204  /*int err;*/
205  format = 0;
206 
207  /*err =*/ sqlite3_exec(database, "select param_value from parameters where param_name = 'version';", check_tables_callback, &format, NULL);
208 
209  /* Safety check. */
210  if (format > CFLOGGER_CURRENT_FORMAT) {
211  cf_log(llevError, " [%s] Logger database format (%d) is newer than supported (%d) by this binary!. Won't log.\n", PLUGIN_NAME, format, CFLOGGER_CURRENT_FORMAT);
212  /* This will disable using the db since do_sql() checks if database is
213  * NULL.
214  */
215  sqlite3_close(database);
216  database = NULL;
217  }
218 
219  /* Check if we need to upgrade/create database. */
220  if (format < 1) {
221  cf_log(llevDebug, " [%s] Creating logger database schema (format 1).\n", PLUGIN_NAME);
222  if (do_sql("BEGIN EXCLUSIVE TRANSACTION;") != SQLITE_OK) {
223  cf_log(llevError, " [%s] Logger database format update failed! Couldn't acquire exclusive lock to database when upgrading from format %d to format %d!. Won't log.\n", PLUGIN_NAME, format, CFLOGGER_CURRENT_FORMAT);
224  sqlite3_close(database);
225  database = NULL;
226  return;
227  }
228  DO_OR_ROLLBACK("create table living(liv_id integer primary key autoincrement, liv_name text, liv_is_player integer, liv_level integer);");
229  DO_OR_ROLLBACK("create table region(reg_id integer primary key autoincrement, reg_name text);");
230  DO_OR_ROLLBACK("create table map(map_id integer primary key autoincrement, map_path text, map_reg_id integer);");
231  DO_OR_ROLLBACK("create table time(time_real integer, time_ingame text);");
232 
233  DO_OR_ROLLBACK("create table living_event(le_liv_id integer, le_time integer, le_code integer, le_map_id integer);");
234  DO_OR_ROLLBACK("create table map_event(me_map_id integer, me_time integer, me_code integer, me_living_id integer);");
235  DO_OR_ROLLBACK("create table kill_event(ke_time integer, ke_victim_id integer, ke_victim_level integer, ke_map_id integer , ke_killer_id integer, ke_killer_level integer);");
236 
237  DO_OR_ROLLBACK("create table parameters(param_name text, param_value text);");
238  DO_OR_ROLLBACK("insert into parameters values( 'version', '1' );");
239  do_sql("COMMIT TRANSACTION;");
240  }
241 
242  /* Must be able to handle update from format 1. If we are creating a new
243  * database, format 1 is still created first, then updated.
244  *
245  * This way is simpler than having to create two ways to make a format 2 db.
246  */
247  if (format < 2) {
248  cf_log(llevDebug, " [%s] Upgrading logger database schema (to format 2).\n", PLUGIN_NAME);
249  if (do_sql("BEGIN EXCLUSIVE TRANSACTION;") != SQLITE_OK) {
250  cf_log(llevError, " [%s] Logger database format update failed! Couldn't acquire exclusive lock to database when upgrading from format %d to format %d!. Won't log.\n", PLUGIN_NAME, format, CFLOGGER_CURRENT_FORMAT);
251  sqlite3_close(database);
252  database = NULL;
253  return;
254  }
255  /* Update schema for various tables. Why so complex? Because ALTER TABLE
256  * can't add the "primary key" bit or other constraints...
257  */
258  UPDATE_OR_ROLLBACK("living", "liv_id INTEGER PRIMARY KEY AUTOINCREMENT, liv_name TEXT NOT NULL, liv_is_player INTEGER NOT NULL, liv_level INTEGER NOT NULL", "*");
259  UPDATE_OR_ROLLBACK("region", "reg_id INTEGER PRIMARY KEY AUTOINCREMENT, reg_name TEXT UNIQUE NOT NULL", "*");
260  UPDATE_OR_ROLLBACK("map", "map_id INTEGER PRIMARY KEY AUTOINCREMENT, map_path TEXT NOT NULL, map_reg_id INTEGER NOT NULL, CONSTRAINT map_path_reg_id UNIQUE(map_path, map_reg_id)", "*");
261 #if 0
262  /* Turned out this was incorrect. And version 1 -> 3 directly works for this. */
263  UPDATE_OR_ROLLBACK("time", "time_real INTEGER PRIMARY KEY, time_ingame TEXT UNIQUE NOT NULL");
264 #endif
265  UPDATE_OR_ROLLBACK("living_event", "le_liv_id INTEGER NOT NULL, le_time INTEGER NOT NULL, le_code INTEGER NOT NULL, le_map_id INTEGER NOT NULL", "*");
266  UPDATE_OR_ROLLBACK("map_event", "me_map_id INTEGER NOT NULL, me_time INTEGER NOT NULL, me_code INTEGER NOT NULL, me_living_id INTEGER NOT NULL", "*");
267  UPDATE_OR_ROLLBACK("kill_event", "ke_time INTEGER NOT NULL, ke_victim_id INTEGER NOT NULL, ke_victim_level INTEGER NOT NULL, ke_map_id INTEGER NOT NULL, ke_killer_id INTEGER NOT NULL, ke_killer_level INTEGER NOT NULL", "*");
268 
269  /* Handle changed parameters table format: */
270  /* Due to backward compatiblity "primary key" in SQLite doesn't imply
271  * "not null" (http://www.sqlite.org/lang_createtable.html), unless it
272  * is "integer primary key".
273  *
274  * We don't need to save anything stored in this in format 1, it was
275  * only used for storing what format was used.
276  */
277  DO_OR_ROLLBACK("DROP TABLE parameters;");
278  DO_OR_ROLLBACK("CREATE TABLE parameters(param_name TEXT NOT NULL PRIMARY KEY, param_value TEXT);");
279  DO_OR_ROLLBACK("INSERT INTO parameters (param_name, param_value) VALUES( 'version', '2' );");
280 
281  /* Create various indexes. */
282  DO_OR_ROLLBACK("CREATE INDEX living_name_player_level ON living(liv_name,liv_is_player,liv_level);");
283 
284  /* Newspaper module could make use of some indexes too: */
285  DO_OR_ROLLBACK("CREATE INDEX kill_event_time ON kill_event(ke_time);");
286  DO_OR_ROLLBACK("CREATE INDEX map_reg_id ON map(map_reg_id);");
287 
288  /* Finally commit the transaction. */
289  do_sql("COMMIT TRANSACTION;");
290  }
291 
292  if (format < 3) {
293  cf_log(llevDebug, " [%s] Upgrading logger database schema (to format 3).\n", PLUGIN_NAME);
294  if (do_sql("BEGIN EXCLUSIVE TRANSACTION;") != SQLITE_OK) {
295  cf_log(llevError, " [%s] Logger database format update failed! Couldn't acquire exclusive lock to database when upgrading from format %d to format %d!. Won't log.\n", PLUGIN_NAME, format, CFLOGGER_CURRENT_FORMAT);
296  sqlite3_close(database);
297  database = NULL;
298  return;
299  }
300  UPDATE_OR_ROLLBACK("time", "time_ingame TEXT NOT NULL PRIMARY KEY, time_real INTEGER NOT NULL", "time_ingame, time_real");
301  DO_OR_ROLLBACK("UPDATE parameters SET param_value = '3' WHERE param_name = 'version';");
302  do_sql("COMMIT TRANSACTION;");
303  /* After all these changes better vacuum... The tables could have been
304  * huge, and since we recreated several of them above there could be a
305  * lot of wasted space.
306  */
307  do_sql("VACUUM;");
308  }
309 }
310 
326 static int get_living_id(object *living) {
327  char **line;
328  char *sql;
329  int nrow, ncolumn, id;
330 
331  if (living->type == PLAYER)
332  sql = sqlite3_mprintf("select liv_id from living where liv_name='%q' and liv_is_player = 1", living->name);
333  else
334  sql = sqlite3_mprintf("select liv_id from living where liv_name='%q' and liv_is_player = 0 and liv_level = %d", living->name, living->level);
335  sqlite3_get_table(database, sql, &line, &nrow, &ncolumn, NULL);
336 
337  if (nrow > 0)
338  id = atoi(line[ncolumn]);
339  else {
340  sqlite3_free(sql);
341  sql = sqlite3_mprintf("insert into living(liv_name, liv_is_player, liv_level) values('%q', %d, %d)", living->name, living->type == PLAYER ? 1 : 0, living->level);
342  do_sql(sql);
343  id = sqlite3_last_insert_rowid(database);
344  }
345  sqlite3_free(sql);
346  sqlite3_free_table(line);
347  return id;
348 }
349 
360 static int get_region_id(region *reg) {
361  char **line;
362  char *sql;
363  int nrow, ncolumn, id;
364 
365  if (!reg)
366  return 0;
367 
368  sql = sqlite3_mprintf("select reg_id from region where reg_name='%q'", reg->name);
369  sqlite3_get_table(database, sql, &line, &nrow, &ncolumn, NULL);
370 
371  if (nrow > 0)
372  id = atoi(line[ncolumn]);
373  else {
374  sqlite3_free(sql);
375  sql = sqlite3_mprintf("insert into region(reg_name) values( '%q' )", reg->name);
376  do_sql(sql);
377  id = sqlite3_last_insert_rowid(database);
378  }
379  sqlite3_free(sql);
380  sqlite3_free_table(line);
381  return id;
382 }
383 
396 static int get_map_id(mapstruct *map) {
397  char **line;
398  char *sql;
399  int nrow, ncolumn, id, reg_id;
400  const char *path = map->path;
401 
402  if (strncmp(path, "/random/", 7) == 0)
403  path = "/random/";
404 
405  reg_id = get_region_id(map->region);
406  sql = sqlite3_mprintf("select map_id from map where map_path='%q' and map_reg_id = %d", path, reg_id);
407  sqlite3_get_table(database, sql, &line, &nrow, &ncolumn, NULL);
408 
409  if (nrow > 0)
410  id = atoi(line[ncolumn]);
411  else {
412  sqlite3_free(sql);
413  sql = sqlite3_mprintf("insert into map(map_path, map_reg_id) values( '%q', %d)", path, reg_id);
414  do_sql(sql);
415  id = sqlite3_last_insert_rowid(database);
416  }
417  sqlite3_free(sql);
418  sqlite3_free_table(line);
419 
420  return id;
421 }
422 
429 static int store_time(void) {
430  char **line;
431  char *sql;
432  int nrow, ncolumn;
433  char date[50];
434  time_t now;
435  timeofday_t tod;
436 
437  cf_get_time(&tod);
438  now = time(NULL);
439 
440  if (tod.day == last_stored_day)
441  return 0;
442  last_stored_day = tod.day;
443 
444  snprintf(date, 50, "%10d-%2d-%2d %2d:%2d", tod.year, tod.month, tod.day, tod.hour, tod.minute);
445 
446  sql = sqlite3_mprintf("select * from time where time_ingame='%q'", date);
447  sqlite3_get_table(database, sql, &line, &nrow, &ncolumn, NULL);
448  sqlite3_free(sql);
449  sqlite3_free_table(line);
450  if (nrow > 0)
451  return 0;
452 
453  sql = sqlite3_mprintf("insert into time (time_ingame, time_real) values( '%s', %d )", date, now);
454  do_sql(sql);
455  sqlite3_free(sql);
456  return 1;
457 }
458 
467 static void add_player_event(object *pl, int event_code) {
468  int map_id = 0;
469  char *sql;
470 
471  if (pl == NULL)
472  return;
473 
474  int id = get_living_id(pl);
475  if (pl->map)
476  map_id = get_map_id(pl->map);
477 
478  sql = sqlite3_mprintf("insert into living_event values( %d, %d, %d, %d)", id, time(NULL), event_code, map_id);
479  do_sql(sql);
480  sqlite3_free(sql);
481 }
482 
493 static void add_map_event(mapstruct *map, int event_code, object *pl) {
494  int mapid;
495  int playerid = 0;
496  char *sql;
497 
498  if (pl && pl->type == PLAYER)
499  playerid = get_living_id(pl);
500 
501  mapid = get_map_id(map);
502  sql = sqlite3_mprintf("insert into map_event values( %d, %d, %d, %d)", mapid, time(NULL), event_code, playerid);
503  do_sql(sql);
504  sqlite3_free(sql);
505 }
506 
517 static void add_death(object *victim, object *killer) {
518  int vid, kid, map_id;
519  char *sql;
520 
521  if (!victim || !killer)
522  return;
523  if (victim->type != PLAYER && killer->type != PLAYER) {
524  /* Killer might be a bullet, which might be owned by the player. */
526  if (owner != NULL && owner->type == PLAYER)
527  killer = owner;
528  else
529  return;
530  }
531 
532  vid = get_living_id(victim);
533  kid = get_living_id(killer);
534  map_id = get_map_id(victim->map);
535  sql = sqlite3_mprintf("insert into kill_event values( %d, %d, %d, %d, %d, %d)", time(NULL), vid, victim->level, map_id, kid, killer->level);
536  do_sql(sql);
537  sqlite3_free(sql);
538 }
539 
540 extern "C" int initPlugin(const char *iversion, f_plug_api gethooksptr) {
541  cf_init_plugin(gethooksptr);
542  cf_log(llevInfo, "%s init\n", PLUGIN_VERSION);
543  return 0;
544 }
545 
546 extern "C" void *getPluginProperty(int *type, ...) {
547  va_list args;
548  const char *propname;
549  char *buf;
550  int size;
551 
552  va_start(args, type);
553  propname = va_arg(args, const char *);
554 
555  if (!strcmp(propname, "Identification")) {
556  buf = va_arg(args, char *);
557  size = va_arg(args, int);
558  va_end(args);
559  snprintf(buf, size, PLUGIN_NAME);
560  return NULL;
561  } else if (!strcmp(propname, "FullName")) {
562  buf = va_arg(args, char *);
563  size = va_arg(args, int);
564  va_end(args);
565  snprintf(buf, size, PLUGIN_VERSION);
566  return NULL;
567  }
568  va_end(args);
569  return NULL;
570 }
571 
582 extern "C" int cflogger_runPluginCommand(object *op, char *params) {
583  return -1;
584 }
585 
586 extern "C" int eventListener(int *type, ...) {
587  return 0;
588 }
589 
598 extern "C" int cflogger_globalEventListener(int *type, ...) {
599  va_list args;
600  int rv = 0;
601  player *pl;
602  object *op/*, *op2*/;
603  int event_code;
604  mapstruct *map;
605 
606  va_start(args, type);
607  event_code = va_arg(args, int);
608 
609  switch (event_code) {
610  case EVENT_BORN:
611  case EVENT_REMOVE:
612  case EVENT_MUZZLE:
613  case EVENT_KICK:
614  op = va_arg(args, object *);
615  add_player_event(op, event_code);
616  break;
617 
618  case EVENT_PLAYER_DEATH:
619  op = va_arg(args, object *);
620  /*op2 =*/ va_arg(args, object *);
621  add_player_event(op, event_code);
622  break;
623 
624  case EVENT_LOGIN:
625  case EVENT_LOGOUT:
626  pl = va_arg(args, player *);
627  add_player_event(pl->ob, event_code);
628  break;
629 
630  case EVENT_MAPENTER:
631  case EVENT_MAPLEAVE:
632  op = va_arg(args, object *);
633  map = va_arg(args, mapstruct *);
634  add_map_event(map, event_code, op);
635  break;
636 
637  case EVENT_MAPLOAD:
638  case EVENT_MAPUNLOAD:
639  case EVENT_MAPRESET:
640  map = va_arg(args, mapstruct *);
641  add_map_event(map, event_code, NULL);
642  break;
643 
644  case EVENT_GKILL: {
645  object *killer;
646  op = va_arg(args, object *);
647  killer = va_arg(args, object *);
648  add_death(op, killer);
649  }
650  break;
651 
652  case EVENT_CLOCK:
653  store_time();
654  break;
655  }
656  va_end(args);
657 
658  return rv;
659 }
660 
661 extern "C" int postInitPlugin(void) {
662  char path[500];
663  const char *dir;
664 
665  cf_log(llevInfo, "%s post init\n", PLUGIN_VERSION);
666 
667  dir = cf_get_directory(4);
668  snprintf(path, sizeof(path), "%s/cflogger.db", dir);
669  cf_log(llevDebug, " [%s] database file: %s\n", PLUGIN_NAME, path);
670 
671  if (sqlite3_open(path, &database) != SQLITE_OK) {
672  cf_log(llevError, " [%s] database error!\n", PLUGIN_NAME);
673  sqlite3_close(database);
674  database = NULL;
675  return 0;
676  }
677 
678  check_tables();
679 
680  store_time();
681 
687 
689 
695 
698 
700 
701  return 0;
702 }
703 
712 extern "C" int closePlugin(void) {
713  cf_log(llevInfo, "%s closing.\n", PLUGIN_VERSION);
714  if (database) {
715  sqlite3_close(database);
716  database = NULL;
717  }
718  return 0;
719 }
EVENT_REMOVE
#define EVENT_REMOVE
A Player character has been removed.
Definition: events.h:67
PLAYER
@ PLAYER
Definition: object.h:112
cf_log
void cf_log(LogLevel logLevel, const char *format,...)
Wrapper for LOG().
Definition: plugin_common.cpp:1541
mapstruct::region
struct region * region
What jurisdiction in the game world this map is ruled by points to the struct containing all the prop...
Definition: map.h:324
do_sql
static int do_sql(const char *sql)
Helper function to run a SQL query.
Definition: cflogger.cpp:103
EVENT_LOGOUT
#define EVENT_LOGOUT
Player logout.
Definition: events.h:58
cf_get_directory
const char * cf_get_directory(int id)
Gets a directory Crossfire uses.
Definition: plugin_common.cpp:1139
llevError
@ llevError
Problems requiring server admin to fix.
Definition: logger.h:11
EVENT_MAPUNLOAD
#define EVENT_MAPUNLOAD
A map is freed (includes swapping out)
Definition: events.h:64
check_tables_callback
static int check_tables_callback(void *param, int argc, char **argv, char **azColName)
Simple callback to get an integer from a query.
Definition: cflogger.cpp:81
player
One player.
Definition: player.h:107
timeofday_t::year
int year
Definition: tod.h:39
update_table_format
static int update_table_format(const char *table, const char *newschema, const char *select_columns)
Updates a table to a new schema, used for when ALTER TABLE doesn't work.
Definition: cflogger.cpp:144
postInitPlugin
int postInitPlugin(void)
The server calls this function to actually initialize the plugin here, after object handlers are regi...
Definition: cflogger.cpp:661
cf_object_get_object_property
object * cf_object_get_object_property(object *op, int propcode)
Definition: plugin_common.cpp:365
UPDATE_OR_ROLLBACK
#define UPDATE_OR_ROLLBACK(tbl, newschema, select_columns)
Definition: cflogger.cpp:190
time
same as sound ncom command like but with extra the client want tick commands so it knows animation timing the client wants to be informed of pickup mode changes Mode will be sent when the player successfully logs and afterward any time the value is but over time
Definition: protocol.txt:416
add_map_event
static void add_map_event(mapstruct *map, int event_code, object *pl)
Logs an event for a map.
Definition: cflogger.cpp:493
get_map_id
static int get_map_id(mapstruct *map)
Gets the unique identifier for a map.
Definition: cflogger.cpp:396
player::ob
object * ob
The object representing the player.
Definition: player.h:179
SVN_REV
#define SVN_REV
Definition: svnversion.h:2
object::map
struct mapstruct * map
Pointer to the map in which this object is present.
Definition: object.h:305
get_region_id
static int get_region_id(region *reg)
Gets the unique identifier for a region.
Definition: cflogger.cpp:360
timeofday_t
Represents the ingame time.
Definition: tod.h:38
region::name
char * name
Shortend name of the region as maps refer to it.
Definition: map.h:280
EVENT_LOGIN
#define EVENT_LOGIN
Player login.
Definition: events.h:57
mapstruct::path
char path[HUGE_BUF]
Filename of the map.
Definition: map.h:360
object::level
int16_t level
Level of creature or object.
Definition: object.h:361
buf
StringBuffer * buf
Definition: readable.cpp:1564
EVENT_KICK
#define EVENT_KICK
A player was Kicked by a DM
Definition: events.h:56
initPlugin
int initPlugin(const char *iversion, f_plug_api gethooksptr)
The server calls this function after loading the plugin.
Definition: cflogger.cpp:540
timeofday_t::day
int day
Definition: tod.h:41
is_valid_types_gen.line
line
Definition: is_valid_types_gen.py:34
cflogger_runPluginCommand
int cflogger_runPluginCommand(object *op, char *params)
Runs a plugin command.
Definition: cflogger.cpp:582
CF_PLUGIN
#define CF_PLUGIN
Definition: plugin_common.h:38
f_plug_api
void(* f_plug_api)(int *type,...)
General API function.
Definition: plugin.h:79
EVENT_GKILL
#define EVENT_GKILL
Triggered when anything got killed by anyone.
Definition: events.h:55
cf_init_plugin
int cf_init_plugin(f_plug_api getHooks)
Definition: plugin_common.cpp:146
PLUGIN_NAME
#define PLUGIN_NAME
Definition: cfanim.h:32
object::type
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:348
EVENT_CLOCK
#define EVENT_CLOCK
Global time event.
Definition: events.h:53
cflogger_globalEventListener
int cflogger_globalEventListener(int *type,...)
Handles a global event.
Definition: cflogger.cpp:598
CFLOGGER_CURRENT_FORMAT
#define CFLOGGER_CURRENT_FORMAT
Current database format.
Definition: cflogger.cpp:58
add_player_event
static void add_player_event(object *pl, int event_code)
Logs an event for a living object.
Definition: cflogger.cpp:467
EVENT_MAPRESET
#define EVENT_MAPRESET
A map is resetting.
Definition: events.h:63
EVENT_PLAYER_DEATH
#define EVENT_PLAYER_DEATH
Global Death event
Definition: events.h:66
EVENT_BORN
#define EVENT_BORN
A new character has been created.
Definition: events.h:52
store_time
static int store_time(void)
Stores a line to match current ingame and real time.
Definition: cflogger.cpp:429
CFAPI_OBJECT_PROP_OWNER
#define CFAPI_OBJECT_PROP_OWNER
Definition: plugin.h:191
timeofday_t::month
int month
Definition: tod.h:40
living
Various statistics of objects.
Definition: living.h:35
EVENT_MAPLEAVE
#define EVENT_MAPLEAVE
A player left a map.
Definition: events.h:60
last_stored_day
static int last_stored_day
To keep track of stored ingame/real time matching.
Definition: cflogger.cpp:64
PLUGIN_VERSION
#define PLUGIN_VERSION
Definition: cfanim.h:33
region
This is a game region.
Definition: map.h:279
SvnRevPlugin
CF_PLUGIN char SvnRevPlugin[]
Definition: cflogger.cpp:55
cf_system_register_global_event
void cf_system_register_global_event(int event, const char *name, f_plug_event hook)
Definition: plugin_common.cpp:1111
llevInfo
@ llevInfo
Information.
Definition: logger.h:14
getPluginProperty
void * getPluginProperty(int *type,...)
The server calls this function to get information about the plugin, notably the name and version.
Definition: cflogger.cpp:546
cflogger_proto.h
eventListener
int eventListener(int *type,...)
Handles an object-related event.
Definition: cflogger.cpp:586
timeofday_t::minute
int minute
Definition: tod.h:44
add_death
static void add_death(object *victim, object *killer)
Logs a death.
Definition: cflogger.cpp:517
mapstruct
This is a game-map.
Definition: map.h:320
EVENT_MAPENTER
#define EVENT_MAPENTER
A player entered a map.
Definition: events.h:59
database
static sqlite3 * database
Pointer to the logging database.
Definition: cflogger.cpp:61
closePlugin
int closePlugin(void)
Close the plugin.
Definition: cflogger.cpp:712
timeofday_t::hour
int hour
Definition: tod.h:43
get_living_id
static int get_living_id(object *living)
Returns a unique identifier for specified object.
Definition: cflogger.cpp:326
DO_OR_ROLLBACK
#define DO_OR_ROLLBACK(sqlstring)
Helper macros for rolling back and returning if query failed.
Definition: cflogger.cpp:181
check_tables
static void check_tables(void)
Checks the database format, and applies changes if old version.
Definition: cflogger.cpp:202
EVENT_MAPLOAD
#define EVENT_MAPLOAD
A map is loaded (pristine state)
Definition: events.h:61
EVENT_MUZZLE
#define EVENT_MUZZLE
A player was Muzzled (no_shout set).
Definition: events.h:65
svnversion.h
cflogger.h
cf_get_time
void cf_get_time(timeofday_t *tod)
Definition: plugin_common.cpp:1568
llevDebug
@ llevDebug
Only for debugging purposes.
Definition: logger.h:15
is_valid_types_gen.type
list type
Definition: is_valid_types_gen.py:25