summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaru <haru@dotalux.com>2014-02-24 09:17:02 +0100
committerHaru <haru@dotalux.com>2014-03-05 22:35:02 +0100
commit78bf8d26567a2054bd9ff5268f9f73cb07d82b98 (patch)
tree68e5deedd9525d05151840c6446460add55d799e
parentd554d61417a6e7f48de96efcc69872e0b7b65da3 (diff)
downloadhercules-78bf8d26567a2054bd9ff5268f9f73cb07d82b98.tar.gz
hercules-78bf8d26567a2054bd9ff5268f9f73cb07d82b98.tar.bz2
hercules-78bf8d26567a2054bd9ff5268f9f73cb07d82b98.tar.xz
hercules-78bf8d26567a2054bd9ff5268f9f73cb07d82b98.zip
Ref redesign, part 1
- Moved string and numeric mapregs into the same DBMap (for consistency with the other reg types.) Signed-off-by: Haru <haru@dotalux.com>
-rw-r--r--src/map/mapreg.h18
-rw-r--r--src/map/mapreg_sql.c228
-rw-r--r--src/map/script.h11
3 files changed, 130 insertions, 127 deletions
diff --git a/src/map/mapreg.h b/src/map/mapreg.h
index c92b6f602..246f5b744 100644
--- a/src/map/mapreg.h
+++ b/src/map/mapreg.h
@@ -8,19 +8,19 @@
#include "../common/cbasetypes.h"
#include "../common/db.h"
+/** Container for a mapreg value */
struct mapreg_save {
- int64 uid;
+ int64 uid; ///< Unique ID
union {
- int i;
- char *str;
+ int i; ///< Numeric value
+ char *str; ///< String value
} u;
- bool save;
+ bool is_string; ///< true if it's a string, false if it's a number
+ bool save; ///< Whether a save operation is pending
};
struct mapreg_interface {
- DBMap *db; // int var_id -> int value
- /* TODO duck str_db, use same */
- DBMap *str_db; // int var_id -> char* value
+ DBMap *db; // int var_id -> struct mapreg_save
/* */
DBMap *array_db;
/* */
@@ -30,8 +30,7 @@ struct mapreg_interface {
/* */
char table[32];
/* */
- bool i_dirty;
- bool str_dirty;
+ bool dirty; ///< Whether there are modified regs to be saved
/* */
void (*init) (void);
void (*final) (void);
@@ -43,6 +42,7 @@ struct mapreg_interface {
void (*load) (void);
void (*save) (void);
int (*save_timer) (int tid, int64 tick, int id, intptr_t data);
+ int (*destroyreg) (DBKey key, DBData *data, va_list ap);
void (*reload) (void);
bool (*config_read) (const char *w1, const char *w2);
};
diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c
index 3cf92454d..926df2994 100644
--- a/src/map/mapreg_sql.c
+++ b/src/map/mapreg_sql.c
@@ -20,19 +20,35 @@ struct mapreg_interface mapreg_s;
#define MAPREG_AUTOSAVE_INTERVAL (300*1000)
-/// Looks up the value of an integer variable using its uid.
+/**
+ * Looks up the value of an integer variable using its uid.
+ *
+ * @param uid variable's unique identifier.
+ * @return variable's integer value
+ */
int mapreg_readreg(int64 uid) {
struct mapreg_save *m = i64db_get(mapreg->db, uid);
return m?m->u.i:0;
}
-/// Looks up the value of a string variable using its uid.
+/**
+ * Looks up the value of a string variable using its uid.
+ *
+ * @param uid variable's unique identifier
+ * @return variable's string value
+ */
char* mapreg_readregstr(int64 uid) {
- struct mapreg_save *m = i64db_get(mapreg->str_db, uid);
+ struct mapreg_save *m = i64db_get(mapreg->db, uid);
return m?m->u.str:NULL;
}
-/// Modifies the value of an integer variable.
+/**
+ * Modifies the value of an integer variable.
+ *
+ * @param uid variable's unique identifier
+ * @param val new value
+ * @retval true value was successfully set
+ */
bool mapreg_setreg(int64 uid, int val) {
struct mapreg_save *m;
int num = script_getvarid(uid);
@@ -44,7 +60,7 @@ bool mapreg_setreg(int64 uid, int val) {
m->u.i = val;
if(name[1] != '@') {
m->save = true;
- mapreg->i_dirty = true;
+ mapreg->dirty = true;
}
} else {
if( i )
@@ -55,6 +71,7 @@ bool mapreg_setreg(int64 uid, int val) {
m->u.i = val;
m->uid = uid;
m->save = false;
+ m->is_string = false;
if(name[1] != '@' && !mapreg->skip_insert) {// write new variable to database
char tmp_str[32*2+1];
@@ -81,13 +98,19 @@ bool mapreg_setreg(int64 uid, int val) {
return true;
}
-/// Modifies the value of a string variable.
+/**
+ * Modifies the value of a string variable.
+ *
+ * @param uid variable's unique identifier
+ * @param str new value
+ * @retval true value was successfully set
+ */
bool mapreg_setregstr(int64 uid, const char* str) {
struct mapreg_save *m;
int num = script_getvarid(uid);
unsigned int i = script_getvaridx(uid);
const char* name = script->get_str(num);
-
+
if( str == NULL || *str == 0 ) {
if( i )
script->array_update(&mapreg->array_db,uid,true);
@@ -95,31 +118,32 @@ bool mapreg_setregstr(int64 uid, const char* str) {
if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg->table, name, i) )
Sql_ShowDebug(map->mysql_handle);
}
- if( (m = i64db_get(mapreg->str_db,uid)) ) {
+ if( (m = i64db_get(mapreg->db,uid)) ) {
if( m->u.str != NULL )
aFree(m->u.str);
ers_free(mapreg->ers, m);
}
- i64db_remove(mapreg->str_db,uid);
+ i64db_remove(mapreg->db,uid);
} else {
- if( (m = i64db_get(mapreg->str_db,uid)) ) {
+ if( (m = i64db_get(mapreg->db,uid)) ) {
if( m->u.str != NULL )
aFree(m->u.str);
m->u.str = aStrdup(str);
if(name[1] != '@') {
- mapreg->str_dirty = true;
+ mapreg->dirty = true;
m->save = true;
}
} else {
if( i )
script->array_update(&mapreg->array_db,uid,false);
-
+
m = ers_alloc(mapreg->ers, struct mapreg_save);
m->uid = uid;
m->u.str = aStrdup(str);
m->save = false;
-
+ m->is_string = true;
+
if(name[1] != '@' && !mapreg->skip_insert) { //put returned null, so we must insert.
char tmp_str[32*2+1];
char tmp_str2[255*2+1];
@@ -128,14 +152,16 @@ bool mapreg_setregstr(int64 uid, const char* str) {
if( SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%s')", mapreg->table, tmp_str, i, tmp_str2) )
Sql_ShowDebug(map->mysql_handle);
}
- i64db_put(mapreg->str_db, uid, m);
+ i64db_put(mapreg->db, uid, m);
}
}
return true;
}
-/// Loads permanent variables from database
+/**
+ * Loads permanent variables from database.
+ */
void script_load_mapreg(void) {
/*
0 1 2
@@ -158,7 +184,7 @@ void script_load_mapreg(void) {
}
mapreg->skip_insert = true;
-
+
SQL->StmtBindColumn(stmt, 0, SQLDT_STRING, &varname[0], sizeof(varname), &length, NULL);
SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &index, 0, NULL, NULL);
SQL->StmtBindColumn(stmt, 2, SQLDT_STRING, &value[0], sizeof(value), NULL, NULL);
@@ -166,145 +192,127 @@ void script_load_mapreg(void) {
while ( SQL_SUCCESS == SQL->StmtNextRow(stmt) ) {
int s = script->add_str(varname);
int i = index;
-
+
+ if( i64db_exists(mapreg->db, reference_uid(s, i)) ) {
+ ShowWarning("load_mapreg: duplicate! '%s' => '%s' skipping...\n",varname,value);
+ continue;
+ }
if( varname[length-1] == '$' ) {
- if( i64db_exists(mapreg->str_db, reference_uid(s, i)) ) {
- ShowWarning("load_mapreg: duplicate! '%s' => '%s' skipping...\n",varname,value);
- continue;
- }
mapreg->setregstr(reference_uid(s, i),value);
} else {
- if( i64db_exists(mapreg->db, reference_uid(s, i)) ) {
- ShowWarning("load_mapreg: duplicate! '%s' => '%s' skipping...\n",varname,value);
- continue;
- }
mapreg->setreg(reference_uid(s, i),atoi(value));
}
}
-
+
SQL->StmtFree(stmt);
mapreg->skip_insert = false;
-
- mapreg->i_dirty = false;
- mapreg->str_dirty = false;
+
+ mapreg->dirty = false;
}
-/// Saves permanent variables to database
+/**
+ * Saves permanent variables to database.
+ */
void script_save_mapreg(void) {
DBIterator* iter;
struct mapreg_save *m = NULL;
- if( mapreg->i_dirty ) {
+ if( mapreg->dirty ) {
iter = db_iterator(mapreg->db);
for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) {
if( m->save ) {
int num = script_getvarid(m->uid);
int i = script_getvaridx(m->uid);
const char* name = script->get_str(num);
-
- if( SQL_ERROR == SQL->Query(map->mysql_handle, "UPDATE `%s` SET `value`='%d' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg->table, m->u.i, name, i) )
- Sql_ShowDebug(map->mysql_handle);
- m->save = false;
- }
- }
- dbi_destroy(iter);
- mapreg->i_dirty = false;
- }
-
- if( mapreg->str_dirty ) {
- iter = db_iterator(mapreg->str_db);
- for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) {
- if( m->save ) {
- int num = script_getvarid(m->uid);
- int i = script_getvaridx(m->uid);
- const char* name = script->get_str(num);
- char tmp_str2[2*255+1];
-
- SQL->EscapeStringLen(map->mysql_handle, tmp_str2, m->u.str, safestrnlen(m->u.str, 255));
- if( SQL_ERROR == SQL->Query(map->mysql_handle, "UPDATE `%s` SET `value`='%s' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg->table, tmp_str2, name, i) )
- Sql_ShowDebug(map->mysql_handle);
+ if (!m->is_string) {
+ if( SQL_ERROR == SQL->Query(map->mysql_handle, "UPDATE `%s` SET `value`='%d' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg->table, m->u.i, name, i) )
+ Sql_ShowDebug(map->mysql_handle);
+ } else {
+ char tmp_str2[2*255+1];
+ SQL->EscapeStringLen(map->mysql_handle, tmp_str2, m->u.str, safestrnlen(m->u.str, 255));
+ if( SQL_ERROR == SQL->Query(map->mysql_handle, "UPDATE `%s` SET `value`='%s' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg->table, tmp_str2, name, i) )
+ Sql_ShowDebug(map->mysql_handle);
+ }
m->save = false;
}
}
dbi_destroy(iter);
- mapreg->str_dirty = false;
+ mapreg->dirty = false;
}
}
+/**
+ * Timer event to auto-save permanent variables.
+ *
+ * @see timer->do_timer
+ */
int script_autosave_mapreg(int tid, int64 tick, int id, intptr_t data) {
mapreg->save();
return 0;
}
-
-void mapreg_reload(void) {
- DBIterator* iter;
+/**
+ * Destroys a mapreg_save structure, freeing the contained string, if any.
+ *
+ * @see DBApply
+ */
+int mapreg_destroyreg(DBKey key, DBData *data, va_list ap) {
struct mapreg_save *m = NULL;
- mapreg->save();
+ if (data->type != DB_DATA_PTR) // Sanity check
+ return 0;
- iter = db_iterator(mapreg->db);
- for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) {
- ers_free(mapreg->ers, m);
- }
- dbi_destroy(iter);
-
- iter = db_iterator(mapreg->str_db);
- for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) {
- if( m->u.str != NULL ) {
+ m = DB->data2ptr(data);
+
+ if (m->is_string) {
+ if (m->u.str)
aFree(m->u.str);
- }
- ers_free(mapreg->ers, m);
}
- dbi_destroy(iter);
-
- db_clear(mapreg->db);
- db_clear(mapreg->str_db);
-
+ ers_free(mapreg->ers, m);
+
+ return 0;
+}
+
+/**
+ * Reloads mapregs, saving to database beforehand.
+ *
+ * This has the effect of clearing the temporary variables, and
+ * reloading the permanent ones.
+ */
+void mapreg_reload(void) {
+ mapreg->save();
+
+ mapreg->db->clear(mapreg->db, mapreg->destroyreg);
+
if( mapreg->array_db ) {
mapreg->array_db->destroy(mapreg->array_db,script->array_free_db);
mapreg->array_db = NULL;
}
-
-
+
mapreg->load();
}
+/**
+ * Finalizer.
+ */
void mapreg_final(void) {
- DBIterator* iter;
- struct mapreg_save *m = NULL;
-
mapreg->save();
- iter = db_iterator(mapreg->db);
- for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) {
- ers_free(mapreg->ers, m);
- }
- dbi_destroy(iter);
-
- iter = db_iterator(mapreg->str_db);
- for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) {
- if( m->u.str != NULL ) {
- aFree(m->u.str);
- }
- ers_free(mapreg->ers, m);
- }
- dbi_destroy(iter);
-
- db_destroy(mapreg->db);
- db_destroy(mapreg->str_db);
-
+ mapreg->db->destroy(mapreg->db, mapreg->destroyreg);
+
ers_destroy(mapreg->ers);
-
+
if( mapreg->array_db )
mapreg->array_db->destroy(mapreg->array_db,script->array_free_db);
}
+/**
+ * Initializer.
+ */
void mapreg_init(void) {
mapreg->db = i64db_alloc(DB_OPT_BASE);
- mapreg->str_db = i64db_alloc(DB_OPT_BASE);
mapreg->ers = ers_new(sizeof(struct mapreg_save), "mapreg_sql.c::mapreg_ers", ERS_OPT_CLEAN);
mapreg->load();
@@ -313,6 +321,9 @@ void mapreg_init(void) {
timer->add_interval(timer->gettick() + MAPREG_AUTOSAVE_INTERVAL, mapreg->save_timer, 0, 0, MAPREG_AUTOSAVE_INTERVAL);
}
+/**
+ * Loads the mapreg configuration file.
+ */
bool mapreg_config_read(const char* w1, const char* w2) {
if(!strcmpi(w1, "mapreg_db"))
safestrncpy(mapreg->table, w2, sizeof(mapreg->table));
@@ -321,26 +332,28 @@ bool mapreg_config_read(const char* w1, const char* w2) {
return true;
}
+
+/**
+ * Interface defaults initializer.
+ */
void mapreg_defaults(void) {
mapreg = &mapreg_s;
-
+
/* */
mapreg->db = NULL;
- mapreg->str_db = NULL;
mapreg->ers = NULL;
mapreg->skip_insert = false;
-
+
safestrncpy(mapreg->table, "mapreg", sizeof(mapreg->table));
- mapreg->i_dirty = false;
- mapreg->str_dirty = false;
-
+ mapreg->dirty = false;
+
/* */
mapreg->array_db = NULL;
-
+
/* */
mapreg->init = mapreg_init;
mapreg->final = mapreg_final;
-
+
/* */
mapreg->readreg = mapreg_readreg;
mapreg->readregstr = mapreg_readregstr;
@@ -349,6 +362,7 @@ void mapreg_defaults(void) {
mapreg->load = script_load_mapreg;
mapreg->save = script_save_mapreg;
mapreg->save_timer = script_autosave_mapreg;
+ mapreg->destroyreg = mapreg_destroyreg;
mapreg->reload = mapreg_reload;
mapreg->config_read = mapreg_config_read;
diff --git a/src/map/script.h b/src/map/script.h
index 7ab7f17c6..c0160fd49 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -407,17 +407,6 @@ struct script_state {
unsigned int id;
};
-/* TODO: HELLO DUCK THIS */
-struct script_reg {
- int64 index;
- int data;
-};
-/* TODO: HELLO DUCK THIS */
-struct script_regstr {
- int64 index;
- char* data;
-};
-
struct script_function {
bool (*func)(struct script_state *st);
char *name;