summaryrefslogblamecommitdiff
path: root/src/map/mapreg_sql.c
blob: c6ebe33b79a3775957defdd937deeee5f51d6599 (plain) (tree)
1
2
3
4
5
6



                                                         

                                            













                                                                        



                     


                                         
                        

                       
                          
                          




                           


                   
                                        
                                
 

                                           





                                                           

                                    
                                                                  
                          

 





                                                         

                                         
                                                                  
                               

 
   
                                               
  







                                                                                         
 


                                                                  
 

                                                               
 
                                                                    
 


                                 
 



                                                          
 

                            
 


                                                                
 












                                                                          
                 










                                                                                                    
                 
 

                                    
 

                    
 













                                                                                 
 


























                                                                                                    
                 

                                    


                    

 
   


















                                                                                  
                                              
  







                                                                                                 
 





















                                                                              
                 




















                                                                          
                 










                                                                                                    
                 

                                    


                    

 
   








































































                                                                                                       





































































































                                                                                                              

                                           

                                    

                              
                              

 
   






































































                                                                                            

                                         
                                    
 
                            

                                                                         

                                                                                 

                                                                   
                                                                        
                                                  
 
                                                  
                                                                             
                                    
                                                                               
 



                                                
                                      
         

 




                                                

                                                                             
                       
                 

 




                                                                          
                                                                              
 
                                     
 

                                                      
 



                               
                                        
         










                                                               

                               

                       
                                                                        
 


                                                                                         
         
 
                       

 
   



































                                                                                                                   

             

                              
                       
 
                                                                          
 
                                 
 

                                                                                         

 


               

                             
                                                     
                                                                                                     
 
                       
 

                                                                                                                             

 
   

                                  

                          
                           
 
             
                                 
                           
                                    
 

                                                                              

                              
             
                                   
 
             

                                     
 


                                               

                                                     
                                       

                                                     
                                             

                                                 
                                          

                                                 

                                                    
                                               
                                       
                                                                   
 
/**
 * This file is part of Hercules.
 * http://herc.ws - http://github.com/HerculesWS/Hercules
 *
 * Copyright (C) 2012-2020 Hercules Dev Team
 * Copyright (C) Athena Dev Teams
 *
 * Hercules is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#define HERCULES_CORE

#include "mapreg.h"

#include "map/map.h" // map-"mysql_handle
#include "map/script.h"
#include "common/cbasetypes.h"
#include "common/conf.h"
#include "common/db.h"
#include "common/ers.h"
#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/showmsg.h"
#include "common/sql.h"
#include "common/strlib.h"
#include "common/timer.h"

#include <stdlib.h>
#include <string.h>

static struct mapreg_interface mapreg_s;
struct mapreg_interface *mapreg;

#define MAPREG_AUTOSAVE_INTERVAL (300*1000)

/**
 * Looks up the value of an integer variable using its uid.
 *
 * @param uid variable's unique identifier.
 * @return variable's integer value
 */
static int mapreg_readreg(int64 uid)
{
	struct mapreg_save *m = i64db_get(mapreg->regs.vars, uid);
	return m?m->u.i:0;
}

/**
 * Looks up the value of a string variable using its uid.
 *
 * @param uid variable's unique identifier
 * @return variable's string value
 */
static char *mapreg_readregstr(int64 uid)
{
	struct mapreg_save *m = i64db_get(mapreg->regs.vars, uid);
	return m?m->u.str:NULL;
}

/**
 * Sets the value of a global integer variable.
 *
 * @param uid The variable's unique ID.
 * @param name The variable's name.
 * @param index The variable's array index.
 * @param value The variable's new value.
 * @return True on success, otherwise false.
 *
 **/
static bool mapreg_set_num_db(int64 uid, const char *name, unsigned int index, int value)
{
	nullpo_retr(false, name);
	Assert_retr(false, *name != '\0');
	Assert_retr(false, strlen(name) <= SCRIPT_VARNAME_LENGTH);

	if (value == 0)
		return mapreg->delete_num_db(uid, name, index);

	struct mapreg_save *var = i64db_get(mapreg->regs.vars, uid);

	// Update variable.
	if (var != NULL) {
		var->u.i = value;

		if (script->is_permanent_variable(name)) {
			var->save = true;
			mapreg->dirty = true;
		}

		return true;
	}

	// Add new variable.
	if (index != 0)
		script->array_update(&mapreg->regs, uid, false);

	var = ers_alloc(mapreg->ers, struct mapreg_save);
	var->u.i = value;
	var->uid = uid;
	var->save = false;
	var->is_string = false;
	i64db_put(mapreg->regs.vars, uid, var);

	if (script->is_permanent_variable(name) && !mapreg->skip_insert) {
		struct SqlStmt *stmt = SQL->StmtMalloc(map->mysql_handle);

		if (stmt == NULL) {
			SqlStmt_ShowDebug(stmt);
			return false;
		}

		const char *query = "INSERT INTO `%s` (`key`, `index`, `value`) VALUES (?, ?, ?)";

		if (SQL_ERROR == SQL->StmtPrepare(stmt, query, mapreg->num_db)
		    || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_STRING, name, strlen(name))
		    || SQL_ERROR == SQL->StmtBindParam(stmt, 1, SQLDT_UINT32, &index, sizeof(index))
		    || SQL_ERROR == SQL->StmtBindParam(stmt, 2, SQLDT_INT32, &value, sizeof(value))
		    || SQL_ERROR == SQL->StmtExecute(stmt)) {
			SqlStmt_ShowDebug(stmt);
			SQL->StmtFree(stmt);
			return false;
		}

		SQL->StmtFree(stmt);
	}

	return true;
}

/**
 * Deletes a global integer variable.
 *
 * @param uid The variable's unique ID.
 * @param name The variable's name.
 * @param index The variable's array index.
 * @return True on success, otherwise false.
 *
 **/
static bool mapreg_delete_num_db(int64 uid, const char *name, unsigned int index)
{
	nullpo_retr(false, name);
	Assert_retr(false, *name != '\0');
	Assert_retr(false, strlen(name) <= SCRIPT_VARNAME_LENGTH);

	struct mapreg_save *var = i64db_get(mapreg->regs.vars, uid);

	if (var != NULL)
		ers_free(mapreg->ers, var);

	if (index != 0)
		script->array_update(&mapreg->regs, uid, true);

	i64db_remove(mapreg->regs.vars, uid);

	if (script->is_permanent_variable(name)) {
		struct SqlStmt *stmt = SQL->StmtMalloc(map->mysql_handle);

		if (stmt == NULL) {
			SqlStmt_ShowDebug(stmt);
			return false;
		}

		const char *query = "DELETE FROM `%s` WHERE `key`=? AND `index`=?";

		if (SQL_ERROR == SQL->StmtPrepare(stmt, query, mapreg->num_db)
		    || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_STRING, name, strlen(name))
		    || SQL_ERROR == SQL->StmtBindParam(stmt, 1, SQLDT_UINT32, &index, sizeof(index))
		    || SQL_ERROR == SQL->StmtExecute(stmt)) {
			SqlStmt_ShowDebug(stmt);
			SQL->StmtFree(stmt);
			return false;
		}

		SQL->StmtFree(stmt);
	}

	return true;
}

/**
 * Sets the value of a global integer variable or deletes it if passed value is 0.
 *
 * @param uid The variable's unique ID.
 * @param val The variable's new value.
 * @return True on success, otherwise false.
 *
 **/
static bool mapreg_setreg(int64 uid, int val)
{
	unsigned int index = script_getvaridx(uid);
	const char *name = script->get_str(script_getvarid(uid));

	if (val != 0)
		return mapreg->set_num_db(uid, name, index, val);
	else
		return mapreg->delete_num_db(uid, name, index);
}

/**
 * Sets the value of a global string variable.
 *
 * @param uid The variable's unique ID.
 * @param name The variable's name.
 * @param index The variable's array index.
 * @param value The variable's new value.
 * @return True on success, otherwise false.
 *
 **/
static bool mapreg_set_str_db(int64 uid, const char *name, unsigned int index, const char *value)
{
	nullpo_retr(false, name);
	Assert_retr(false, *name != '\0');
	Assert_retr(false, strlen(name) <= SCRIPT_VARNAME_LENGTH);

	if (value == NULL || *value == '\0')
		return mapreg->delete_str_db(uid, name, index);

	if (script->is_permanent_variable(name))
		Assert_retr(false, strlen(value) <= SCRIPT_STRING_VAR_LENGTH);

	struct mapreg_save *var = i64db_get(mapreg->regs.vars, uid);

	// Update variable.
	if (var != NULL) {
		if (var->u.str != NULL)
			aFree(var->u.str);

		var->u.str = aStrdup(value);

		if (script->is_permanent_variable(name)) {
			var->save = true;
			mapreg->dirty = true;
		}

		return true;
	}

	// Add new variable.
	if (index != 0)
		script->array_update(&mapreg->regs, uid, false);

	var = ers_alloc(mapreg->ers, struct mapreg_save);
	var->u.str = aStrdup(value);
	var->uid = uid;
	var->save = false;
	var->is_string = true;
	i64db_put(mapreg->regs.vars, uid, var);

	if (script->is_permanent_variable(name) && !mapreg->skip_insert) {
		struct SqlStmt *stmt = SQL->StmtMalloc(map->mysql_handle);

		if (stmt == NULL) {
			SqlStmt_ShowDebug(stmt);
			return false;
		}

		const char *query = "INSERT INTO `%s` (`key`, `index`, `value`) VALUES (?, ?, ?)";

		if (SQL_ERROR == SQL->StmtPrepare(stmt, query, mapreg->str_db)
		    || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_STRING, name, strlen(name))
		    || SQL_ERROR == SQL->StmtBindParam(stmt, 1, SQLDT_UINT32, &index, sizeof(index))
		    || SQL_ERROR == SQL->StmtBindParam(stmt, 2, SQLDT_STRING, value, strlen(value))
		    || SQL_ERROR == SQL->StmtExecute(stmt)) {
			SqlStmt_ShowDebug(stmt);
			SQL->StmtFree(stmt);
			return false;
		}

		SQL->StmtFree(stmt);
	}

	return true;
}

/**
 * Deletes a global string variable.
 *
 * @param uid The variable's unique ID.
 * @param name The variable's name.
 * @param index The variable's array index.
 * @return True on success, otherwise false.
 *
 **/
static bool mapreg_delete_str_db(int64 uid, const char *name, unsigned int index)
{
	nullpo_retr(false, name);
	Assert_retr(false, *name != '\0');
	Assert_retr(false, strlen(name) <= SCRIPT_VARNAME_LENGTH);

	struct mapreg_save *var = i64db_get(mapreg->regs.vars, uid);

	if (var != NULL) {
		if (var->u.str != NULL)
			aFree(var->u.str);

		ers_free(mapreg->ers, var);
	}

	if (index != 0)
		script->array_update(&mapreg->regs, uid, true);

	i64db_remove(mapreg->regs.vars, uid);

	if (script->is_permanent_variable(name)) {
		struct SqlStmt *stmt = SQL->StmtMalloc(map->mysql_handle);

		if (stmt == NULL) {
			SqlStmt_ShowDebug(stmt);
			return false;
		}

		const char *query = "DELETE FROM `%s` WHERE `key`=? AND `index`=?";

		if (SQL_ERROR == SQL->StmtPrepare(stmt, query, mapreg->str_db)
		    || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_STRING, name, strlen(name))
		    || SQL_ERROR == SQL->StmtBindParam(stmt, 1, SQLDT_UINT32, &index, sizeof(index))
		    || SQL_ERROR == SQL->StmtExecute(stmt)) {
			SqlStmt_ShowDebug(stmt);
			SQL->StmtFree(stmt);
			return false;
		}

		SQL->StmtFree(stmt);
	}

	return true;
}

/**
 * Sets the value of a global string variable or deletes it if passed value is NULL or an empty string.
 *
 * @param uid The variable's unique ID.
 * @param str The variable's new value.
 * @return True on success, otherwise false.
 *
 **/
static bool mapreg_setregstr(int64 uid, const char *str)
{
	unsigned int index = script_getvaridx(uid);
	const char *name = script->get_str(script_getvarid(uid));

	if (str != NULL && *str != '\0')
		return mapreg->set_str_db(uid, name, index, str);
	else
		return mapreg->delete_str_db(uid, name, index);
}

/**
 * Loads permanent global interger variables from the database.
 *
 **/
static void mapreg_load_num_db(void)
{
	struct SqlStmt *stmt = SQL->StmtMalloc(map->mysql_handle);

	if (stmt == NULL) {
		SqlStmt_ShowDebug(stmt);
		return;
	}

	const char *query = "SELECT `key`, `index`, `value` FROM `%s`";
	char name[SCRIPT_VARNAME_LENGTH + 1];
	unsigned int index;
	int value;

	if (SQL_ERROR == SQL->StmtPrepare(stmt, query, mapreg->num_db)
	    || SQL_ERROR == SQL->StmtExecute(stmt)
	    || SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_STRING, &name, sizeof(name), NULL, NULL)
	    || SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_UINT32, &index, sizeof(index), NULL, NULL)
	    || SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_INT32, &value, sizeof(value), NULL, NULL)) {
		SqlStmt_ShowDebug(stmt);
		SQL->StmtFree(stmt);
		return;
	}

	if (SQL->StmtNumRows(stmt) < 1) {
		SQL->StmtFree(stmt);
		return;
	}

	mapreg->skip_insert = true;

	while (SQL_SUCCESS == SQL->StmtNextRow(stmt)) {
		int var_key = script->add_variable(name);
		int64 uid = reference_uid(var_key, index);

		if (i64db_exists(mapreg->regs.vars, uid)) {
			ShowWarning("mapreg_load_num_db: Duplicate! '%s' => '%d' Skipping...\n", name, value);
			continue;
		}

		mapreg->setreg(uid, value);
	}

	mapreg->skip_insert = false;
	SQL->StmtFree(stmt);
}

/**
 * Loads permanent global string variables from the database.
 *
 **/
static void mapreg_load_str_db(void)
{
	struct SqlStmt *stmt = SQL->StmtMalloc(map->mysql_handle);

	if (stmt == NULL) {
		SqlStmt_ShowDebug(stmt);
		return;
	}

	const char *query = "SELECT `key`, `index`, `value` FROM `%s`";
	char name[SCRIPT_VARNAME_LENGTH + 1];
	unsigned int index;
	char value[SCRIPT_STRING_VAR_LENGTH + 1];

	if (SQL_ERROR == SQL->StmtPrepare(stmt, query, mapreg->str_db)
	    || SQL_ERROR == SQL->StmtExecute(stmt)
	    || SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_STRING, &name, sizeof(name), NULL, NULL)
	    || SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_UINT32, &index, sizeof(index), NULL, NULL)
	    || SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_STRING, &value, sizeof(value), NULL, NULL)) {
		SqlStmt_ShowDebug(stmt);
		SQL->StmtFree(stmt);
		return;
	}

	if (SQL->StmtNumRows(stmt) < 1) {
		SQL->StmtFree(stmt);
		return;
	}

	mapreg->skip_insert = true;

	while (SQL_SUCCESS == SQL->StmtNextRow(stmt)) {
		int var_key = script->add_variable(name);
		int64 uid = reference_uid(var_key, index);

		if (i64db_exists(mapreg->regs.vars, uid)) {
			ShowWarning("mapreg_load_str_db: Duplicate! '%s' => '%s' Skipping...\n", name, value);
			continue;
		}

		mapreg->setregstr(uid, value);
	}

	mapreg->skip_insert = false;
	SQL->StmtFree(stmt);
}

/**
 * Loads permanent variables from database.
 */
static void script_load_mapreg(void)
{
	mapreg->load_num_db();
	mapreg->load_str_db();
	mapreg->dirty = false;
}

/**
 * Saves a permanent global integer variable to the database.
 *
 * @param name The variable's name.
 * @param index The variable's array index.
 * @param value The variable's value.
 *
 **/
static void mapreg_save_num_db(const char *name, unsigned int index, int value)
{
	nullpo_retv(name);
	Assert_retv(*name != '\0');
	Assert_retv(strlen(name) <= SCRIPT_VARNAME_LENGTH);

	struct SqlStmt *stmt = SQL->StmtMalloc(map->mysql_handle);

	if (stmt == NULL) {
		SqlStmt_ShowDebug(stmt);
		return;
	}

	const char *query = "UPDATE `%s` SET `value`=? WHERE `key`=? AND `index`=? LIMIT 1";

	if (SQL_ERROR == SQL->StmtPrepare(stmt, query, mapreg->num_db)
	    || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT32, &value, sizeof(value))
	    || SQL_ERROR == SQL->StmtBindParam(stmt, 1, SQLDT_STRING, name, strlen(name))
	    || SQL_ERROR == SQL->StmtBindParam(stmt, 2, SQLDT_UINT32, &index, sizeof(index))
	    || SQL_ERROR == SQL->StmtExecute(stmt)) {
		SqlStmt_ShowDebug(stmt);
	}

	SQL->StmtFree(stmt);
}

/**
 * Saves a permanent global string variable to the database.
 *
 * @param name The variable's name.
 * @param index The variable's array index.
 * @param value The variable's value.
 *
 **/
static void mapreg_save_str_db(const char *name, unsigned int index, const char *value)
{
	nullpo_retv(name);
	nullpo_retv(value);
	Assert_retv(*name != '\0');
	Assert_retv(strlen(name) <= SCRIPT_VARNAME_LENGTH);
	Assert_retv(*value != '\0');
	Assert_retv(strlen(value) <= SCRIPT_STRING_VAR_LENGTH);

	struct SqlStmt *stmt = SQL->StmtMalloc(map->mysql_handle);

	if (stmt == NULL) {
		SqlStmt_ShowDebug(stmt);
		return;
	}

	const char *query = "UPDATE `%s` SET `value`=? WHERE `key`=? AND `index`=? LIMIT 1";

	if (SQL_ERROR == SQL->StmtPrepare(stmt, query, mapreg->str_db)
	    || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_STRING, value, strlen(value))
	    || SQL_ERROR == SQL->StmtBindParam(stmt, 1, SQLDT_STRING, name, strlen(name))
	    || SQL_ERROR == SQL->StmtBindParam(stmt, 2, SQLDT_UINT32, &index, sizeof(index))
	    || SQL_ERROR == SQL->StmtExecute(stmt)) {
		SqlStmt_ShowDebug(stmt);
	}

	SQL->StmtFree(stmt);
}

/**
 * Saves permanent variables to database.
 */
static void script_save_mapreg(void)
{
	if (mapreg->dirty) {
		struct DBIterator *iter = db_iterator(mapreg->regs.vars);
		struct mapreg_save *m = NULL;
		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);
				nullpo_retv(name);

				if (!m->is_string)
					mapreg->save_num_db(name, i, m->u.i);
				else
					mapreg->save_str_db(name, i, m->u.str);

				m->save = false;
			}
		}
		dbi_destroy(iter);
		mapreg->dirty = false;
	}
}

/**
 * Timer event to auto-save permanent variables.
 *
 * @see timer->do_timer
 */
static int script_autosave_mapreg(int tid, int64 tick, int id, intptr_t data)
{
	mapreg->save();
	return 0;
}

/**
 * Destroys a mapreg_save structure, freeing the contained string, if any.
 *
 * @see DBApply
 */
static int mapreg_destroyreg(union DBKey key, struct DBData *data, va_list ap)
{
	struct mapreg_save *m = NULL;

	if (data->type != DB_DATA_PTR) // Sanity check
		return 0;

	m = DB->data2ptr(data);

	if (m->is_string) {
		if (m->u.str)
			aFree(m->u.str);
	}
	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.
 */
static void mapreg_reload(void)
{
	mapreg->save();

	mapreg->regs.vars->clear(mapreg->regs.vars, mapreg->destroyreg);

	if( mapreg->regs.arrays ) {
		mapreg->regs.arrays->destroy(mapreg->regs.arrays, script->array_free_db);
		mapreg->regs.arrays = NULL;
	}

	mapreg->load();
}

/**
 * Loads the mapreg database table names from configuration file.
 *
 * @param filename Path to configuration file. (Used in error and warning messages).
 * @param config The current config being parsed.
 * @param imported Whether the current config is imported from another file.
 * @return True on success, otherwise false.
 *
 **/
static bool mapreg_config_read_registry(const char *filename, const struct config_setting_t *config, bool imported)
{
	nullpo_retr(false, filename);
	nullpo_retr(false, config);
	
	bool ret_val = true;
	size_t sz = sizeof(mapreg->num_db);
	int result = libconfig->setting_lookup_mutable_string(config, "map_reg_num_db", mapreg->num_db, sz);

	if (result != CONFIG_TRUE && !imported) {
		ShowError("%s: inter_configuration/database_names/registry/map_reg_num_db was not found in %s!\n",
			  __func__, filename);
		ret_val = false;
	}

	sz = sizeof(mapreg->str_db);
	result = libconfig->setting_lookup_mutable_string(config, "map_reg_str_db", mapreg->str_db, sz);

	if (result != CONFIG_TRUE && !imported) {
		ShowError("%s: inter_configuration/database_names/registry/map_reg_str_db was not found in %s!\n",
			  __func__, filename);
		ret_val = false;
	}

	return ret_val;
}

/**
 * Finalizer.
 */
static void mapreg_final(void)
{
	mapreg->save();

	mapreg->regs.vars->destroy(mapreg->regs.vars, mapreg->destroyreg);

	ers_destroy(mapreg->ers);

	if( mapreg->regs.arrays )
		mapreg->regs.arrays->destroy(mapreg->regs.arrays, script->array_free_db);
}

/**
 * Initializer.
 */
static void mapreg_init(void)
{
	mapreg->regs.vars = i64db_alloc(DB_OPT_BASE);
	mapreg->ers = ers_new(sizeof(struct mapreg_save), "mapreg_sql.c::mapreg_ers", ERS_OPT_CLEAN);

	mapreg->load();

	timer->add_func_list(mapreg->save_timer, "mapreg_script_autosave_mapreg");
	timer->add_interval(timer->gettick() + MAPREG_AUTOSAVE_INTERVAL, mapreg->save_timer, 0, 0, MAPREG_AUTOSAVE_INTERVAL);
}

/**
 * Interface defaults initializer.
 */
void mapreg_defaults(void)
{
	mapreg = &mapreg_s;

	/* */
	mapreg->regs.vars = NULL;
	mapreg->ers = NULL;
	mapreg->skip_insert = false;

	safestrncpy(mapreg->num_db, "map_reg_num_db", sizeof(mapreg->num_db));
	safestrncpy(mapreg->str_db, "map_reg_str_db", sizeof(mapreg->str_db));
	mapreg->dirty = false;

	/* */
	mapreg->regs.arrays = NULL;

	/* */
	mapreg->init = mapreg_init;
	mapreg->final = mapreg_final;

	/* */
	mapreg->readreg = mapreg_readreg;
	mapreg->readregstr = mapreg_readregstr;
	mapreg->set_num_db = mapreg_set_num_db;
	mapreg->delete_num_db = mapreg_delete_num_db;
	mapreg->setreg = mapreg_setreg;
	mapreg->set_str_db = mapreg_set_str_db;
	mapreg->delete_str_db = mapreg_delete_str_db;
	mapreg->setregstr = mapreg_setregstr;
	mapreg->load_num_db = mapreg_load_num_db;
	mapreg->load_str_db = mapreg_load_str_db;
	mapreg->load = script_load_mapreg;
	mapreg->save_num_db = mapreg_save_num_db;
	mapreg->save_str_db = mapreg_save_str_db;
	mapreg->save = script_save_mapreg;
	mapreg->save_timer = script_autosave_mapreg;
	mapreg->destroyreg = mapreg_destroyreg;
	mapreg->reload = mapreg_reload;
	mapreg->config_read_registry = mapreg_config_read_registry;
}