57 #define CFLOGGER_CURRENT_FORMAT 3
81 int *format = (
int *)param;
83 *format = atoi(argv[0]);
109 err = sqlite3_exec(
database, sql, NULL, NULL, &msg);
110 if (err != SQLITE_OK) {
144 const char *select_columns) {
148 sql = sqlite3_mprintf(
"ALTER TABLE %s RENAME TO %s_old;", table, table);
151 if (err != SQLITE_OK)
154 sql = sqlite3_mprintf(
"CREATE TABLE %s(%s);", table, newschema);
157 if (err != SQLITE_OK)
160 sql = sqlite3_mprintf(
"INSERT INTO %s SELECT %s FROM %s_old;",
161 table, select_columns, table);
164 if (err != SQLITE_OK)
167 sql = sqlite3_mprintf(
"DROP TABLE %s_old;", table, table);
180 #define DO_OR_ROLLBACK(sqlstring) \
181 if (do_sql(sqlstring) != SQLITE_OK) { \
182 do_sql("rollback transaction;"); \
183 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);\
184 sqlite3_close(database); \
189 #define UPDATE_OR_ROLLBACK(tbl, newschema, select_columns) \
190 if (update_table_format((tbl), (newschema), (select_columns)) != SQLITE_OK) { \
191 do_sql("rollback transaction;"); \
192 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);\
193 sqlite3_close(database); \
221 if (
do_sql(
"BEGIN EXCLUSIVE TRANSACTION;") != SQLITE_OK) {
227 DO_OR_ROLLBACK(
"create table living(liv_id integer primary key autoincrement, liv_name text, liv_is_player integer, liv_level integer);");
228 DO_OR_ROLLBACK(
"create table region(reg_id integer primary key autoincrement, reg_name text);");
229 DO_OR_ROLLBACK(
"create table map(map_id integer primary key autoincrement, map_path text, map_reg_id integer);");
230 DO_OR_ROLLBACK(
"create table time(time_real integer, time_ingame text);");
232 DO_OR_ROLLBACK(
"create table living_event(le_liv_id integer, le_time integer, le_code integer, le_map_id integer);");
233 DO_OR_ROLLBACK(
"create table map_event(me_map_id integer, me_time integer, me_code integer, me_living_id integer);");
234 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 DO_OR_ROLLBACK(
"create table parameters(param_name text, param_value text);");
237 DO_OR_ROLLBACK(
"insert into parameters values( 'version', '1' );");
238 do_sql(
"COMMIT TRANSACTION;");
248 if (
do_sql(
"BEGIN EXCLUSIVE TRANSACTION;") != SQLITE_OK) {
257 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",
"*");
258 UPDATE_OR_ROLLBACK(
"region",
"reg_id INTEGER PRIMARY KEY AUTOINCREMENT, reg_name TEXT UNIQUE NOT NULL",
"*");
259 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)",
"*");
262 UPDATE_OR_ROLLBACK(
"time",
"time_real INTEGER PRIMARY KEY, time_ingame TEXT UNIQUE NOT NULL");
264 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",
"*");
265 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",
"*");
266 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",
"*");
277 DO_OR_ROLLBACK(
"CREATE TABLE parameters(param_name TEXT NOT NULL PRIMARY KEY, param_value TEXT);");
278 DO_OR_ROLLBACK(
"INSERT INTO parameters (param_name, param_value) VALUES( 'version', '2' );");
281 DO_OR_ROLLBACK(
"CREATE INDEX living_name_player_level ON living(liv_name,liv_is_player,liv_level);");
284 DO_OR_ROLLBACK(
"CREATE INDEX kill_event_time ON kill_event(ke_time);");
288 do_sql(
"COMMIT TRANSACTION;");
293 if (
do_sql(
"BEGIN EXCLUSIVE TRANSACTION;") != SQLITE_OK) {
299 UPDATE_OR_ROLLBACK(
"time",
"time_ingame TEXT NOT NULL PRIMARY KEY, time_real INTEGER NOT NULL",
"time_ingame, time_real");
300 DO_OR_ROLLBACK(
"UPDATE parameters SET param_value = '3' WHERE param_name = 'version';");
301 do_sql(
"COMMIT TRANSACTION;");
328 int nrow, ncolumn, id;
331 sql = sqlite3_mprintf(
"select liv_id from living where liv_name='%q' and liv_is_player = 1", living->
name);
333 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);
334 sqlite3_get_table(
database, sql, &line, &nrow, &ncolumn, NULL);
337 id = atoi(line[ncolumn]);
340 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 id = sqlite3_last_insert_rowid(
database);
345 sqlite3_free_table(line);
362 int nrow, ncolumn, id;
367 sql = sqlite3_mprintf(
"select reg_id from region where reg_name='%q'", reg->
name);
368 sqlite3_get_table(
database, sql, &line, &nrow, &ncolumn, NULL);
371 id = atoi(line[ncolumn]);
374 sql = sqlite3_mprintf(
"insert into region(reg_name) values( '%q' )", reg->
name);
376 id = sqlite3_last_insert_rowid(
database);
379 sqlite3_free_table(line);
398 int nrow, ncolumn, id, reg_id;
399 const char *path = map->
path;
401 if (strncmp(path,
"/random/", 7) == 0)
405 sql = sqlite3_mprintf(
"select map_id from map where map_path='%q' and map_reg_id = %d", path, reg_id);
406 sqlite3_get_table(
database, sql, &line, &nrow, &ncolumn, NULL);
409 id = atoi(line[ncolumn]);
412 sql = sqlite3_mprintf(
"insert into map(map_path, map_reg_id) values( '%q', %d)", path, reg_id);
414 id = sqlite3_last_insert_rowid(
database);
417 sqlite3_free_table(line);
445 sql = sqlite3_mprintf(
"select * from time where time_ingame='%q'", date);
446 sqlite3_get_table(
database, sql, &line, &nrow, &ncolumn, NULL);
448 sqlite3_free_table(line);
452 sql = sqlite3_mprintf(
"insert into time (time_ingame, time_real) values( '%s', %d )", date, now);
474 sql = sqlite3_mprintf(
"insert into living_event values( %d, %d, %d, %d)",
id, time(NULL), event_code, map_id);
498 sql = sqlite3_mprintf(
"insert into map_event values( %d, %d, %d, %d)", mapid, time(NULL), event_code, playerid);
514 int vid, kid, map_id;
517 if (!victim || !killer)
531 sql = sqlite3_mprintf(
"insert into kill_event values( %d, %d, %d, %d, %d, %d)", time(NULL), vid, victim->
level, map_id, kid, killer->
level);
564 const char *propname;
568 va_start(args, type);
569 propname = va_arg(args,
const char *);
571 if (!strcmp(propname,
"Identification")) {
572 buf = va_arg(args,
char *);
573 size = va_arg(args,
int);
577 }
else if (!strcmp(propname,
"FullName")) {
578 buf = va_arg(args,
char *);
579 size = va_arg(args,
int);
632 va_start(args, type);
633 event_code = va_arg(args,
int);
635 switch (event_code) {
641 op = va_arg(args,
object *);
647 pl = va_arg(args,
player *);
653 op = va_arg(args,
object *);
667 op = va_arg(args,
object *);
668 killer = va_arg(args,
object *);
697 snprintf(path,
sizeof(path),
"%s/cflogger.db", dir);
700 if (sqlite3_open(path, &
database) != SQLITE_OK) {
static sqlite3 * database
void cf_get_time(timeofday_t *tod)
CF_PLUGIN int closePlugin(void)
void *(* f_plug_api)(int *type,...)
#define CFAPI_OBJECT_PROP_OWNER
void cf_system_register_global_event(int event, const char *name, f_plug_api hook)
void cf_log(LogLevel logLevel, const char *format,...)
#define UPDATE_OR_ROLLBACK(tbl, newschema, select_columns)
static int do_sql(const char *sql)
static void add_death(object *victim, object *killer)
int cf_init_plugin(f_plug_api getHooks)
static int update_table_format(const char *table, const char *newschema, const char *select_columns)
static int get_map_id(mapstruct *map)
static int last_stored_day
static void add_player_event(object *pl, int event_code)
#define DO_OR_ROLLBACK(sqlstring)
CF_PLUGIN int cflogger_runPluginCommand(object *op, char *params)
CF_PLUGIN void * cflogger_globalEventListener(int *type,...)
static void add_map_event(mapstruct *map, int event_code, object *pl)
static int get_living_id(object *living)
#define CFLOGGER_CURRENT_FORMAT
static void check_tables(void)
object * cf_object_get_object_property(object *op, int propcode)
int snprintf(char *dest, int max, const char *format,...)
const char * cf_get_directory(int id)
#define EVENT_PLAYER_DEATH
void * eventListener(int *type,...)
CF_PLUGIN void * getPluginProperty(int *type,...)
CF_PLUGIN int initPlugin(const char *iversion, f_plug_api gethooksptr)
static int store_time(void)
static int get_region_id(region *reg)
struct regiondef * region
static int check_tables_callback(void *param, int argc, char **argv, char **azColName)
CF_PLUGIN int postInitPlugin(void)