viewing paste ra-charlogin_explode.diff | Diff

Posted on the
  1. Index: src/login/ipban_sql.c
  2. ===================================================================
  3. --- src/login/ipban_sql.c	(revision 17367)
  4. +++ src/login/ipban_sql.c	(working copy)
  5. @@ -1,258 +0,0 @@
  6. -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  7. -// For more information, see LICENCE in the main folder
  8. -
  9. -#include "../common/cbasetypes.h"
  10. -#include "../common/db.h"
  11. -#include "../common/malloc.h"
  12. -#include "../common/sql.h"
  13. -#include "../common/socket.h"
  14. -#include "../common/strlib.h"
  15. -#include "../common/timer.h"
  16. -#include "login.h"
  17. -#include "ipban.h"
  18. -#include "loginlog.h"
  19. -#include <stdlib.h>
  20. -#include <string.h>
  21. -
  22. -// global sql settings
  23. -static char   global_db_hostname[32] = "127.0.0.1";
  24. -static uint16 global_db_port = 3306;
  25. -static char   global_db_username[32] = "ragnarok";
  26. -static char   global_db_password[32] = "ragnarok";
  27. -static char   global_db_database[32] = "ragnarok";
  28. -static char   global_codepage[32] = "";
  29. -// local sql settings
  30. -static char   ipban_db_hostname[32] = "";
  31. -static uint16 ipban_db_port = 0;
  32. -static char   ipban_db_username[32] = "";
  33. -static char   ipban_db_password[32] = "";
  34. -static char   ipban_db_database[32] = "";
  35. -static char   ipban_codepage[32] = "";
  36. -static char   ipban_table[32] = "ipbanlist";
  37. -
  38. -// globals
  39. -static Sql* sql_handle = NULL;
  40. -static int cleanup_timer_id = INVALID_TIMER;
  41. -static bool ipban_inited = false;
  42. -
  43. -int ipban_cleanup(int tid, unsigned int tick, int id, intptr_t data);
  44. -
  45. -
  46. -// initialize
  47. -void ipban_init(void)
  48. -{
  49. -	const char* username;
  50. -	const char* password;
  51. -	const char* hostname;
  52. -	uint16      port;
  53. -	const char* database;
  54. -	const char* codepage;
  55. -
  56. -	ipban_inited = true;
  57. -
  58. -	if( !login_config.ipban )
  59. -		return;// ipban disabled
  60. -
  61. -	if( ipban_db_hostname[0] != '\0' )
  62. -	{// local settings
  63. -		username = ipban_db_username;
  64. -		password = ipban_db_password;
  65. -		hostname = ipban_db_hostname;
  66. -		port     = ipban_db_port;
  67. -		database = ipban_db_database;
  68. -		codepage = ipban_codepage;
  69. -	}
  70. -	else
  71. -	{// global settings
  72. -		username = global_db_username;
  73. -		password = global_db_password;
  74. -		hostname = global_db_hostname;
  75. -		port     = global_db_port;
  76. -		database = global_db_database;
  77. -		codepage = global_codepage;
  78. -	}
  79. -
  80. -	// establish connections
  81. -	sql_handle = Sql_Malloc();
  82. -	if( SQL_ERROR == Sql_Connect(sql_handle, username, password, hostname, port, database) )
  83. -	{
  84. -		Sql_ShowDebug(sql_handle);
  85. -		Sql_Free(sql_handle);
  86. -		exit(EXIT_FAILURE);
  87. -	}
  88. -	if( codepage[0] != '\0' && SQL_ERROR == Sql_SetEncoding(sql_handle, codepage) )
  89. -		Sql_ShowDebug(sql_handle);
  90. -
  91. -	if( login_config.ipban_cleanup_interval > 0 )
  92. -	{ // set up periodic cleanup of connection history and active bans
  93. -		add_timer_func_list(ipban_cleanup, "ipban_cleanup");
  94. -		cleanup_timer_id = add_timer_interval(gettick()+10, ipban_cleanup, 0, 0, login_config.ipban_cleanup_interval*1000);
  95. -	} else // make sure it gets cleaned up on login-server start regardless of interval-based cleanups
  96. -		ipban_cleanup(0,0,0,0);
  97. -}
  98. -
  99. -// finalize
  100. -void ipban_final(void)
  101. -{
  102. -	if( !login_config.ipban )
  103. -		return;// ipban disabled
  104. -
  105. -	if( login_config.ipban_cleanup_interval > 0 )
  106. -		// release data
  107. -		delete_timer(cleanup_timer_id, ipban_cleanup);
  108. -	
  109. -	ipban_cleanup(0,0,0,0); // always clean up on login-server stop
  110. -
  111. -	// close connections
  112. -	Sql_Free(sql_handle);
  113. -	sql_handle = NULL;
  114. -}
  115. -
  116. -// load configuration options
  117. -bool ipban_config_read(const char* key, const char* value)
  118. -{
  119. -	const char* signature;
  120. -
  121. -	if( ipban_inited )
  122. -		return false;// settings can only be changed before init
  123. -
  124. -	signature = "sql.";
  125. -	if( strncmpi(key, signature, strlen(signature)) == 0 )
  126. -	{
  127. -		key += strlen(signature);
  128. -		if( strcmpi(key, "db_hostname") == 0 )
  129. -			safestrncpy(global_db_hostname, value, sizeof(global_db_hostname));
  130. -		else
  131. -		if( strcmpi(key, "db_port") == 0 )
  132. -			global_db_port = (uint16)strtoul(value, NULL, 10);
  133. -		else
  134. -		if( strcmpi(key, "db_username") == 0 )
  135. -			safestrncpy(global_db_username, value, sizeof(global_db_username));
  136. -		else
  137. -		if( strcmpi(key, "db_password") == 0 )
  138. -			safestrncpy(global_db_password, value, sizeof(global_db_password));
  139. -		else
  140. -		if( strcmpi(key, "db_database") == 0 )
  141. -			safestrncpy(global_db_database, value, sizeof(global_db_database));
  142. -		else
  143. -		if( strcmpi(key, "codepage") == 0 )
  144. -			safestrncpy(global_codepage, value, sizeof(global_codepage));
  145. -		else
  146. -			return false;// not found
  147. -		return true;
  148. -	}
  149. -
  150. -	signature = "ipban.sql.";
  151. -	if( strncmpi(key, signature, strlen(signature)) == 0 )
  152. -	{
  153. -		key += strlen(signature);
  154. -		if( strcmpi(key, "db_hostname") == 0 )
  155. -			safestrncpy(ipban_db_hostname, value, sizeof(ipban_db_hostname));
  156. -		else
  157. -		if( strcmpi(key, "db_port") == 0 )
  158. -			ipban_db_port = (uint16)strtoul(value, NULL, 10);
  159. -		else
  160. -		if( strcmpi(key, "db_username") == 0 )
  161. -			safestrncpy(ipban_db_username, value, sizeof(ipban_db_username));
  162. -		else
  163. -		if( strcmpi(key, "db_password") == 0 )
  164. -			safestrncpy(ipban_db_password, value, sizeof(ipban_db_password));
  165. -		else
  166. -		if( strcmpi(key, "db_database") == 0 )
  167. -			safestrncpy(ipban_db_database, value, sizeof(ipban_db_database));
  168. -		else
  169. -		if( strcmpi(key, "codepage") == 0 )
  170. -			safestrncpy(ipban_codepage, value, sizeof(ipban_codepage));
  171. -		else
  172. -		if( strcmpi(key, "ipban_table") == 0 )
  173. -			safestrncpy(ipban_table, value, sizeof(ipban_table));
  174. -		else
  175. -			return false;// not found
  176. -		return true;
  177. -	}
  178. -
  179. -	signature = "ipban.";
  180. -	if( strncmpi(key, signature, strlen(signature)) == 0 )
  181. -	{
  182. -		key += strlen(signature);
  183. -		if( strcmpi(key, "enable") == 0 )
  184. -			login_config.ipban = (bool)config_switch(value);
  185. -		else
  186. -		if( strcmpi(key, "dynamic_pass_failure_ban") == 0 )
  187. -			login_config.dynamic_pass_failure_ban = (bool)config_switch(value);
  188. -		else
  189. -		if( strcmpi(key, "dynamic_pass_failure_ban_interval") == 0 )
  190. -			login_config.dynamic_pass_failure_ban_interval = atoi(value);
  191. -		else
  192. -		if( strcmpi(key, "dynamic_pass_failure_ban_limit") == 0 )
  193. -			login_config.dynamic_pass_failure_ban_limit = atoi(value);
  194. -		else
  195. -		if( strcmpi(key, "dynamic_pass_failure_ban_duration") == 0 )
  196. -			login_config.dynamic_pass_failure_ban_duration = atoi(value);
  197. -		else
  198. -			return false;// not found
  199. -		return true;
  200. -	}
  201. -
  202. -	return false;// not found
  203. -}
  204. -
  205. -// check ip against active bans list
  206. -bool ipban_check(uint32 ip)
  207. -{
  208. -	uint8* p = (uint8*)&ip;
  209. -	char* data = NULL;
  210. -	int matches;
  211. -
  212. -	if( !login_config.ipban )
  213. -		return false;// ipban disabled
  214. -
  215. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT count(*) FROM `%s` WHERE `rtime` > NOW() AND (`list` = '%u.*.*.*' OR `list` = '%u.%u.*.*' OR `list` = '%u.%u.%u.*' OR `list` = '%u.%u.%u.%u')",
  216. -		ipban_table, p[3], p[3], p[2], p[3], p[2], p[1], p[3], p[2], p[1], p[0]) )
  217. -	{
  218. -		Sql_ShowDebug(sql_handle);
  219. -		// close connection because we can't verify their connectivity.
  220. -		return true;
  221. -	}
  222. -
  223. -	if( SQL_ERROR == Sql_NextRow(sql_handle) )
  224. -		return true;// Shouldn't happen, but just in case...
  225. -
  226. -	Sql_GetData(sql_handle, 0, &data, NULL);
  227. -	matches = atoi(data);
  228. -	Sql_FreeResult(sql_handle);
  229. -
  230. -	return( matches > 0 );
  231. -}
  232. -
  233. -// log failed attempt
  234. -void ipban_log(uint32 ip)
  235. -{
  236. -	unsigned long failures;
  237. -
  238. -	if( !login_config.ipban )
  239. -		return;// ipban disabled
  240. -
  241. -	failures = loginlog_failedattempts(ip, login_config.dynamic_pass_failure_ban_interval);// how many times failed account? in one ip.
  242. -
  243. -	// if over the limit, add a temporary ban entry
  244. -	if( failures >= login_config.dynamic_pass_failure_ban_limit )
  245. -	{
  246. -		uint8* p = (uint8*)&ip;
  247. -		if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s`(`list`,`btime`,`rtime`,`reason`) VALUES ('%u.%u.%u.*', NOW() , NOW() +  INTERVAL %d MINUTE ,'Password error ban')",
  248. -			ipban_table, p[3], p[2], p[1], login_config.dynamic_pass_failure_ban_duration) )
  249. -			Sql_ShowDebug(sql_handle);
  250. -	}
  251. -}
  252. -
  253. -// remove expired bans
  254. -int ipban_cleanup(int tid, unsigned int tick, int id, intptr_t data)
  255. -{
  256. -	if( !login_config.ipban )
  257. -		return 0;// ipban disabled
  258. -
  259. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `ipbanlist` WHERE `rtime` <= NOW()") )
  260. -		Sql_ShowDebug(sql_handle);
  261. -
  262. -	return 0;
  263. -}
  264. Index: src/login/login.c
  265. ===================================================================
  266. --- src/login/login.c	(revision 17367)
  267. +++ src/login/login.c	(working copy)
  268. @@ -7,16 +7,18 @@
  269.  #include "../common/md5calc.h"
  270.  #include "../common/random.h"
  271.  #include "../common/showmsg.h"
  272. -#include "../common/socket.h"
  273. +#include "../common/socket.h" //ip2str
  274.  #include "../common/strlib.h"
  275.  #include "../common/timer.h"
  276.  #include "../common/msg_conf.h"
  277. -#include "../common/cli.h"
  278. -#include "../common/ers.h"
  279. +#include "../common/utils.h"
  280.  #include "account.h"
  281.  #include "ipban.h"
  282.  #include "login.h"
  283.  #include "loginlog.h"
  284. +#include "loginclif.h"
  285. +#include "loginchrif.h"
  286. +#include "logincnslif.h"
  287.  
  288.  #include <stdio.h>
  289.  #include <stdlib.h>
  290. @@ -24,11 +26,6 @@
  291.  
  292.  #define LOGIN_MAX_MSG 30
  293.  static char* msg_table[LOGIN_MAX_MSG]; // Login Server messages_conf
  294. -struct Login_Config login_config;
  295. -
  296. -int login_fd; // login server socket
  297. -struct mmo_char_server server[MAX_SERVERS]; // char server data
  298. -
  299.  // Account engines available
  300.  static struct{
  301.  	AccountDB* (*constructor)(void);
  302. @@ -53,60 +50,25 @@
  303.  	// end of structure
  304.  	{NULL, NULL}
  305.  };
  306. -// account database
  307. -AccountDB* accounts = NULL;
  308. -
  309. -//Account registration flood protection [Kevin]
  310. -int allowed_regs = 1;
  311. -int time_allowed = 10; //in seconds
  312. -
  313. +AccountDB* accounts = NULL; // account database«
  314.  // Advanced subnet check [LuzZza]
  315.  struct s_subnet {
  316.  	uint32 mask;
  317.  	uint32 char_ip;
  318.  	uint32 map_ip;
  319.  } subnet[16];
  320. -
  321.  int subnet_count = 0;
  322.  
  323. -int mmo_auth_new(const char* userid, const char* pass, const char sex, const char* last_ip);
  324. +int login_fd; // login server socket
  325.  
  326. -//-----------------------------------------------------
  327. -// Auth database
  328. -//-----------------------------------------------------
  329. -#define AUTH_TIMEOUT 30000
  330. +AccountDB* login_get_accounts_db(void){
  331. +	return accounts;
  332. +}
  333.  
  334. -struct auth_node {
  335. -
  336. -	int account_id;
  337. -	uint32 login_id1;
  338. -	uint32 login_id2;
  339. -	uint32 ip;
  340. -	char sex;
  341. -	uint32 version;
  342. -	uint8 clienttype;
  343. -};
  344. -
  345. -static DBMap* auth_db; // int account_id -> struct auth_node*
  346. -
  347. -
  348. -//-----------------------------------------------------
  349. -// Online User Database [Wizputer]
  350. -//-----------------------------------------------------
  351. -struct online_login_data {
  352. -
  353. -	int account_id;
  354. -	int waiting_disconnect;
  355. -	int char_server;
  356. -};
  357. -
  358. -static DBMap* online_db; // int account_id -> struct online_login_data*
  359. -static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t data);
  360. -
  361.  /**
  362.   * @see DBCreateData
  363.   */
  364. -static DBData create_online_user(DBKey key, va_list args)
  365. +DBData create_online_user(DBKey key, va_list args)
  366.  {
  367.  	struct online_login_data* p;
  368.  	CREATE(p, struct online_login_data, 1);
  369. @@ -141,7 +103,7 @@
  370.  	idb_remove(online_db, account_id);
  371.  }
  372.  
  373. -static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t data)
  374. +int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t data)
  375.  {
  376.  	struct online_login_data* p = (struct online_login_data*)idb_get(online_db, id);
  377.  	if( p != NULL && p->waiting_disconnect == tid && p->account_id == id )
  378. @@ -154,9 +116,9 @@
  379.  }
  380.  
  381.  /**
  382. - * @see DBApply
  383. + * Mark a char offline
  384.   */
  385. -static int online_db_setoffline(DBKey key, DBData *data, va_list ap)
  386. +int online_db_setoffline(DBKey key, DBData *data, va_list ap)
  387.  {
  388.  	struct online_login_data* p = db_data2ptr(data);
  389.  	int server = va_arg(ap, int);
  390. @@ -192,766 +154,7 @@
  391.  }
  392.  
  393.  
  394. -//--------------------------------------------------------------------
  395. -// Packet send to all char-servers, except one (wos: without our self)
  396. -//--------------------------------------------------------------------
  397. -int charif_sendallwos(int sfd, uint8* buf, size_t len)
  398. -{
  399. -	int i, c;
  400.  
  401. -	for( i = 0, c = 0; i < ARRAYLENGTH(server); ++i )
  402. -	{
  403. -		int fd = server[i].fd;
  404. -		if( session_isValid(fd) && fd != sfd )
  405. -		{
  406. -			WFIFOHEAD(fd,len);
  407. -			memcpy(WFIFOP(fd,0), buf, len);
  408. -			WFIFOSET(fd,len);
  409. -			++c;
  410. -		}
  411. -	}
  412. -
  413. -	return c;
  414. -}
  415. -
  416. -
  417. -/// Initializes a server structure.
  418. -void chrif_server_init(int id)
  419. -{
  420. -	memset(&server[id], 0, sizeof(server[id]));
  421. -	server[id].fd = -1;
  422. -}
  423. -
  424. -
  425. -/// Destroys a server structure.
  426. -void chrif_server_destroy(int id)
  427. -{
  428. -	if( server[id].fd != -1 )
  429. -	{
  430. -		do_close(server[id].fd);
  431. -		server[id].fd = -1;
  432. -	}
  433. -}
  434. -
  435. -
  436. -/// Resets all the data related to a server.
  437. -void chrif_server_reset(int id)
  438. -{
  439. -	online_db->foreach(online_db, online_db_setoffline, id); //Set all chars from this char server to offline.
  440. -	chrif_server_destroy(id);
  441. -	chrif_server_init(id);
  442. -}
  443. -
  444. -
  445. -/// Called when the connection to Char Server is disconnected.
  446. -void chrif_on_disconnect(int id)
  447. -{
  448. -	ShowStatus("Char-server '%s' has disconnected.\n", server[id].name);
  449. -	chrif_server_reset(id);
  450. -}
  451. -
  452. -
  453. -//-----------------------------------------------------
  454. -// periodic ip address synchronization
  455. -//-----------------------------------------------------
  456. -static int sync_ip_addresses(int tid, unsigned int tick, int id, intptr_t data)
  457. -{
  458. -	uint8 buf[2];
  459. -	ShowInfo("IP Sync in progress...\n");
  460. -	WBUFW(buf,0) = 0x2735;
  461. -	charif_sendallwos(-1, buf, 2);
  462. -	return 0;
  463. -}
  464. -
  465. -
  466. -//-----------------------------------------------------
  467. -// encrypted/unencrypted password check (from eApp)
  468. -//-----------------------------------------------------
  469. -bool check_encrypted(const char* str1, const char* str2, const char* passwd)
  470. -{
  471. -	char tmpstr[64+1], md5str[32+1];
  472. -
  473. -	safesnprintf(tmpstr, sizeof(tmpstr), "%s%s", str1, str2);
  474. -	MD5_String(tmpstr, md5str);
  475. -
  476. -	return (0==strcmp(passwd, md5str));
  477. -}
  478. -
  479. -bool check_password(const char* md5key, int passwdenc, const char* passwd, const char* refpass)
  480. -{
  481. -	if(passwdenc == 0)
  482. -	{
  483. -		return (0==strcmp(passwd, refpass));
  484. -	}
  485. -	else
  486. -	{
  487. -		// password mode set to 1 -> md5(md5key, refpass) enable with <passwordencrypt></passwordencrypt>
  488. -		// password mode set to 2 -> md5(refpass, md5key) enable with <passwordencrypt2></passwordencrypt2>
  489. -
  490. -		return ((passwdenc&0x01) && check_encrypted(md5key, refpass, passwd)) ||
  491. -		       ((passwdenc&0x02) && check_encrypted(refpass, md5key, passwd));
  492. -	}
  493. -}
  494. -
  495. -
  496. -//-----------------------------------------------------
  497. -// custom timestamp formatting (from eApp)
  498. -//-----------------------------------------------------
  499. -const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format)
  500. -{
  501. -	size_t len = strftime(str, size, format, localtime(&timestamp));
  502. -	memset(str + len, '\0', size - len);
  503. -	return str;
  504. -}
  505. -
  506. -
  507. -//--------------------------------------------
  508. -// Test to know if an IP come from LAN or WAN.
  509. -//--------------------------------------------
  510. -int lan_subnetcheck(uint32 ip)
  511. -{
  512. -	int i;
  513. -	ARR_FIND( 0, subnet_count, i, (subnet[i].char_ip & subnet[i].mask) == (ip & subnet[i].mask) );
  514. -	return ( i < subnet_count ) ? subnet[i].char_ip : 0;
  515. -}
  516. -
  517. -//----------------------------------
  518. -// Reading Lan Support configuration
  519. -//----------------------------------
  520. -int login_lan_config_read(const char *lancfgName)
  521. -{
  522. -	FILE *fp;
  523. -	int line_num = 0;
  524. -	char line[1024], w1[64], w2[64], w3[64], w4[64];
  525. -
  526. -	if((fp = fopen(lancfgName, "r")) == NULL) {
  527. -		ShowWarning("LAN Support configuration file is not found: %s\n", lancfgName);
  528. -		return 1;
  529. -	}
  530. -
  531. -	while(fgets(line, sizeof(line), fp))
  532. -	{
  533. -		line_num++;
  534. -		if ((line[0] == '/' && line[1] == '/') || line[0] == '\n' || line[1] == '\n')
  535. -			continue;
  536. -
  537. -		if(sscanf(line,"%[^:]: %[^:]:%[^:]:%[^\r\n]", w1, w2, w3, w4) != 4)
  538. -		{
  539. -			ShowWarning("Error syntax of configuration file %s in line %d.\n", lancfgName, line_num);
  540. -			continue;
  541. -		}
  542. -
  543. -		if( strcmpi(w1, "subnet") == 0 )
  544. -		{
  545. -			subnet[subnet_count].mask = str2ip(w2);
  546. -			subnet[subnet_count].char_ip = str2ip(w3);
  547. -			subnet[subnet_count].map_ip = str2ip(w4);
  548. -
  549. -			if( (subnet[subnet_count].char_ip & subnet[subnet_count].mask) != (subnet[subnet_count].map_ip & subnet[subnet_count].mask) )
  550. -			{
  551. -				ShowError("%s: Configuration Error: The char server (%s) and map server (%s) belong to different subnetworks!\n", lancfgName, w3, w4);
  552. -				continue;
  553. -			}
  554. -
  555. -			subnet_count++;
  556. -		}
  557. -	}
  558. -
  559. -	if( subnet_count > 1 ) /* only useful if there is more than 1 available */
  560. -		ShowStatus("Read information about %d subnetworks.\n", subnet_count);
  561. -
  562. -	fclose(fp);
  563. -	return 0;
  564. -}
  565. -
  566. -//-----------------------
  567. -// Console Command Parser [Wizputer]
  568. -//-----------------------
  569. -int parse_console(const char* buf){
  570. -	char type[64];
  571. -	char command[64];
  572. -	int n=0;
  573. -
  574. -	if( ( n = sscanf(buf, "%127[^:]:%255[^\n\r]", type, command) ) < 2 ){
  575. -		if((n = sscanf(buf, "%63[^\n]", type))<1) return -1; //nothing to do no arg
  576. -	}
  577. -	if( n != 2 ){ //end string
  578. -		ShowNotice("Type: '%s'\n",type);
  579. -		command[0] = '\0';
  580. -	}
  581. -	else
  582. -		ShowNotice("Type of command: '%s' || Command: '%s'\n",type,command);
  583. -
  584. -	if( n == 2 ){
  585. -		if(strcmpi("server", type) == 0 ){
  586. -			if( strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0 ){
  587. -				runflag = 0;
  588. -			}
  589. -			else if( strcmpi("alive", command) == 0 || strcmpi("status", command) == 0 )
  590. -				ShowInfo(CL_CYAN"Console: "CL_BOLD"I'm Alive."CL_RESET"\n");
  591. -		}
  592. -		if( strcmpi("create",type) == 0 )
  593. -		{
  594. -			char username[NAME_LENGTH], password[NAME_LENGTH], md5password[32+1], sex; //23+1 plaintext 32+1 md5
  595. -			bool md5 = 0;
  596. -			if( sscanf(command, "%23s %23s %c", username, password, &sex) < 3 || strnlen(username, sizeof(username)) < 4 || strnlen(password, sizeof(password)) < 1 ){
  597. -				ShowWarning("Console: Invalid parameters for '%s'. Usage: %s <username> <password> <sex:F/M>\n", type, type);
  598. -				return 0;
  599. -			}
  600. -			if( login_config.use_md5_passwds ){
  601. -				MD5_String(password,md5password);
  602. -				md5 = 1;
  603. -			}
  604. -			if( mmo_auth_new(username,(md5?md5password:password), TOUPPER(sex), "0.0.0.0") != -1 ){
  605. -				ShowError("Console: Account creation failed.\n");
  606. -				return 0;
  607. -			}
  608. -			ShowStatus("Console: Account '%s' created successfully.\n", username);
  609. -		}
  610. -	}
  611. -	else if( strcmpi("ers_report", type) == 0 ){
  612. -		ers_report();
  613. -	}
  614. -	else if( strcmpi("help", type) == 0 ){
  615. -		ShowInfo("Available commands:\n");
  616. -		ShowInfo("\t server:shutdown => Stops the server.\n");
  617. -		ShowInfo("\t server:alive => Checks if the server is running.\n");
  618. -		ShowInfo("\t ers_report => Displays database usage.\n");
  619. -		ShowInfo("\t create:<username> <password> <sex:M|F> => Creates a new account.\n");
  620. -	}
  621. -	else{ // commands with parameters
  622. -
  623. -
  624. -
  625. -	}
  626. -
  627. -	return 0;
  628. -}
  629. -
  630. -
  631. -//--------------------------------
  632. -// Packet parsing for char-servers
  633. -//--------------------------------
  634. -int parse_fromchar(int fd){
  635. -	int j, id;
  636. -	uint32 ipl;
  637. -	char ip[16];
  638. -
  639. -	ARR_FIND( 0, ARRAYLENGTH(server), id, server[id].fd == fd );
  640. -	if( id == ARRAYLENGTH(server) ){// not a char server
  641. -		ShowDebug("parse_fromchar: Disconnecting invalid session #%d (is not a char-server)\n", fd);
  642. -		set_eof(fd);
  643. -		do_close(fd);
  644. -		return 0;
  645. -	}
  646. -
  647. -	if( session[fd]->flag.eof ){
  648. -		do_close(fd);
  649. -		server[id].fd = -1;
  650. -		chrif_on_disconnect(id);
  651. -		return 0;
  652. -	}
  653. -
  654. -	ipl = server[id].ip;
  655. -	ip2str(ipl, ip);
  656. -
  657. -	while( RFIFOREST(fd) >= 2 ){
  658. -		uint16 command = RFIFOW(fd,0);
  659. -
  660. -		switch( command ){
  661. -
  662. -		case 0x2712: // request from char-server to authenticate an account
  663. -			if( RFIFOREST(fd) < 23 )
  664. -				return 0;
  665. -			else{
  666. -				struct auth_node* node;
  667. -				int account_id = RFIFOL(fd,2);
  668. -				uint32 login_id1 = RFIFOL(fd,6);
  669. -				uint32 login_id2 = RFIFOL(fd,10);
  670. -				uint8 sex = RFIFOB(fd,14);
  671. -				//uint32 ip_ = ntohl(RFIFOL(fd,15));
  672. -				int request_id = RFIFOL(fd,19);
  673. -				RFIFOSKIP(fd,23);
  674. -
  675. -				node = (struct auth_node*)idb_get(auth_db, account_id);
  676. -				if( runflag == LOGINSERVER_ST_RUNNING &&
  677. -					node != NULL &&
  678. -					node->account_id == account_id &&
  679. -					node->login_id1  == login_id1 &&
  680. -					node->login_id2  == login_id2 &&
  681. -					node->sex        == sex_num2str(sex) /*&&
  682. -					node->ip         == ip_*/ ){// found
  683. -					//ShowStatus("Char-server '%s': authentication of the account %d accepted (ip: %s).\n", server[id].name, account_id, ip);
  684. -
  685. -					// send ack
  686. -					WFIFOHEAD(fd,25);
  687. -					WFIFOW(fd,0) = 0x2713;
  688. -					WFIFOL(fd,2) = account_id;
  689. -					WFIFOL(fd,6) = login_id1;
  690. -					WFIFOL(fd,10) = login_id2;
  691. -					WFIFOB(fd,14) = sex;
  692. -					WFIFOB(fd,15) = 0;// ok
  693. -					WFIFOL(fd,16) = request_id;
  694. -					WFIFOL(fd,20) = node->version;
  695. -					WFIFOB(fd,24) = node->clienttype;
  696. -					WFIFOSET(fd,25);
  697. -
  698. -					// each auth entry can only be used once
  699. -					idb_remove(auth_db, account_id);
  700. -				}else{// authentication not found
  701. -					ShowStatus("Char-server '%s': authentication of the account %d REFUSED (ip: %s).\n", server[id].name, account_id, ip);
  702. -					WFIFOHEAD(fd,25);
  703. -					WFIFOW(fd,0) = 0x2713;
  704. -					WFIFOL(fd,2) = account_id;
  705. -					WFIFOL(fd,6) = login_id1;
  706. -					WFIFOL(fd,10) = login_id2;
  707. -					WFIFOB(fd,14) = sex;
  708. -					WFIFOB(fd,15) = 1;// auth failed
  709. -					WFIFOL(fd,16) = request_id;
  710. -					WFIFOL(fd,20) = 0;
  711. -					WFIFOB(fd,24) = 0;
  712. -					WFIFOSET(fd,25);
  713. -				}
  714. -			}
  715. -		break;
  716. -
  717. -		case 0x2714:
  718. -			if( RFIFOREST(fd) < 6 )
  719. -				return 0;
  720. -			else{
  721. -				int users = RFIFOL(fd,2);
  722. -				RFIFOSKIP(fd,6);
  723. -
  724. -				// how many users on world? (update)
  725. -				if( server[id].users != users ){
  726. -					ShowStatus("set users %s : %d\n", server[id].name, users);
  727. -
  728. -					server[id].users = users;
  729. -				}
  730. -			}
  731. -		break;
  732. -
  733. -		case 0x2715: // request from char server to change e-email from default "[email protected]"
  734. -			if (RFIFOREST(fd) < 46)
  735. -				return 0;
  736. -			else{
  737. -				struct mmo_account acc;
  738. -				char email[40];
  739. -
  740. -				int account_id = RFIFOL(fd,2);
  741. -				safestrncpy(email, (char*)RFIFOP(fd,6), 40); remove_control_chars(email);
  742. -				RFIFOSKIP(fd,46);
  743. -
  744. -				if( e_mail_check(email) == 0 )
  745. -					ShowNotice("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - e-mail is invalid (account: %d, ip: %s)\n", server[id].name, account_id, ip);
  746. -				else if( !accounts->load_num(accounts, &acc, account_id) || strcmp(acc.email, "[email protected]") == 0 || acc.email[0] == '\0' )
  747. -					ShowNotice("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - account doesn't exist or e-mail of account isn't default e-mail (account: %d, ip: %s).\n", server[id].name, account_id, ip);
  748. -				else{
  749. -					memcpy(acc.email, email, 40);
  750. -					ShowNotice("Char-server '%s': Create an e-mail on an account with a default e-mail (account: %d, new e-mail: %s, ip: %s).\n", server[id].name, account_id, email, ip);
  751. -					// Save
  752. -					accounts->save(accounts, &acc);
  753. -				}
  754. -			}
  755. -		break;
  756. -
  757. -		case 0x2716: // request account data
  758. -			if( RFIFOREST(fd) < 6 )
  759. -				return 0;
  760. -			else{
  761. -				struct mmo_account acc;
  762. -				time_t expiration_time = 0;
  763. -				char email[40] = "";
  764. -				uint8 char_slots = 0;
  765. -				int group_id = 0;
  766. -				char birthdate[10+1] = "";
  767. -				char pincode[PINCODE_LENGTH+1];
  768. -				int account_id = RFIFOL(fd,2);
  769. -
  770. -				memset(pincode,0,PINCODE_LENGTH+1);
  771. -
  772. -				RFIFOSKIP(fd,6);
  773. -
  774. -				if( !accounts->load_num(accounts, &acc, account_id) )
  775. -					ShowNotice("Char-server '%s': account %d NOT found (ip: %s).\n", server[id].name, account_id, ip);
  776. -				else{
  777. -					safestrncpy(email, acc.email, sizeof(email));
  778. -					expiration_time = acc.expiration_time;
  779. -					group_id = acc.group_id;
  780. -					char_slots = acc.char_slots;
  781. -					safestrncpy(birthdate, acc.birthdate, sizeof(birthdate));
  782. -					safestrncpy(pincode, acc.pincode, sizeof(pincode));
  783. -				}
  784. -
  785. -				WFIFOHEAD(fd,72);
  786. -				WFIFOW(fd,0) = 0x2717;
  787. -				WFIFOL(fd,2) = account_id;
  788. -				safestrncpy((char*)WFIFOP(fd,6), email, 40);
  789. -				WFIFOL(fd,46) = (uint32)expiration_time;
  790. -				WFIFOB(fd,50) = (unsigned char)group_id;
  791. -				WFIFOB(fd,51) = char_slots;
  792. -				safestrncpy((char*)WFIFOP(fd,52), birthdate, 10+1);
  793. -				safestrncpy((char*)WFIFOP(fd,63), pincode, 4+1 );
  794. -				WFIFOL(fd,68) = (uint32)acc.pincode_change;
  795. -				WFIFOSET(fd,72);
  796. -			}
  797. -		break;
  798. -
  799. -		case 0x2719: // ping request from charserver
  800. -			RFIFOSKIP(fd,2);
  801. -
  802. -			WFIFOHEAD(fd,2);
  803. -			WFIFOW(fd,0) = 0x2718;
  804. -			WFIFOSET(fd,2);
  805. -		break;
  806. -
  807. -		// Map server send information to change an email of an account via char-server
  808. -		case 0x2722:	// 0x2722 <account_id>.L <actual_e-mail>.40B <new_e-mail>.40B
  809. -			if (RFIFOREST(fd) < 86)
  810. -				return 0;
  811. -			else{
  812. -				struct mmo_account acc;
  813. -				char actual_email[40];
  814. -				char new_email[40];
  815. -
  816. -				int account_id = RFIFOL(fd,2);
  817. -				safestrncpy(actual_email, (char*)RFIFOP(fd,6), 40);
  818. -				safestrncpy(new_email, (char*)RFIFOP(fd,46), 40);
  819. -				RFIFOSKIP(fd, 86);
  820. -
  821. -				if( e_mail_check(actual_email) == 0 )
  822. -					ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)\n", server[id].name, account_id, ip);
  823. -				else if( e_mail_check(new_email) == 0 )
  824. -					ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a invalid new e-mail (account: %d, ip: %s)\n", server[id].name, account_id, ip);
  825. -				else if( strcmpi(new_email, "[email protected]") == 0 )
  826. -					ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)\n", server[id].name, account_id, ip);
  827. -				else if( !accounts->load_num(accounts, &acc, account_id) )
  828. -					ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but account doesn't exist (account: %d, ip: %s).\n", server[id].name, account_id, ip);
  829. -				else if( strcmpi(acc.email, actual_email) != 0 )
  830. -					ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual e-mail is incorrect (account: %d (%s), actual e-mail: %s, proposed e-mail: %s, ip: %s).\n", server[id].name, account_id, acc.userid, acc.email, actual_email, ip);
  831. -				else{
  832. -					safestrncpy(acc.email, new_email, 40);
  833. -					ShowNotice("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s).\n", server[id].name, account_id, acc.userid, new_email, ip);
  834. -					// Save
  835. -					accounts->save(accounts, &acc);
  836. -				}
  837. -			}
  838. -		break;
  839. -
  840. -		case 0x2724: // Receiving an account state update request from a map-server (relayed via char-server)
  841. -			if (RFIFOREST(fd) < 10)
  842. -				return 0;
  843. -			else{
  844. -				struct mmo_account acc;
  845. -
  846. -				int account_id = RFIFOL(fd,2);
  847. -				unsigned int state = RFIFOL(fd,6);
  848. -				RFIFOSKIP(fd,10);
  849. -
  850. -				if( !accounts->load_num(accounts, &acc, account_id) )
  851. -					ShowNotice("Char-server '%s': Error of Status change (account: %d not found, suggested status %d, ip: %s).\n", server[id].name, account_id, state, ip);
  852. -				else if( acc.state == state )
  853. -					ShowNotice("Char-server '%s':  Error of Status change - actual status is already the good status (account: %d, status %d, ip: %s).\n", server[id].name, account_id, state, ip);
  854. -				else{
  855. -					ShowNotice("Char-server '%s': Status change (account: %d, new status %d, ip: %s).\n", server[id].name, account_id, state, ip);
  856. -
  857. -					acc.state = state;
  858. -					// Save
  859. -					accounts->save(accounts, &acc);
  860. -
  861. -					// notify other servers
  862. -					if (state != 0){
  863. -						uint8 buf[11];
  864. -						WBUFW(buf,0) = 0x2731;
  865. -						WBUFL(buf,2) = account_id;
  866. -						WBUFB(buf,6) = 0; // 0: change of state, 1: ban
  867. -						WBUFL(buf,7) = state; // status or final date of a banishment
  868. -						charif_sendallwos(-1, buf, 11);
  869. -					}
  870. -				}
  871. -			}
  872. -		break;
  873. -
  874. -		case 0x2725: // Receiving of map-server via char-server a ban request
  875. -			if (RFIFOREST(fd) < 18)
  876. -				return 0;
  877. -			else{
  878. -				struct mmo_account acc;
  879. -
  880. -				int account_id = RFIFOL(fd,2);
  881. -				int year = (short)RFIFOW(fd,6);
  882. -				int month = (short)RFIFOW(fd,8);
  883. -				int mday = (short)RFIFOW(fd,10);
  884. -				int hour = (short)RFIFOW(fd,12);
  885. -				int min = (short)RFIFOW(fd,14);
  886. -				int sec = (short)RFIFOW(fd,16);
  887. -				RFIFOSKIP(fd,18);
  888. -
  889. -				if( !accounts->load_num(accounts, &acc, account_id) )
  890. -					ShowNotice("Char-server '%s': Error of ban request (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
  891. -				else{
  892. -					time_t timestamp;
  893. -					struct tm *tmtime;
  894. -					if (acc.unban_time == 0 || acc.unban_time < time(NULL))
  895. -						timestamp = time(NULL); // new ban
  896. -					else
  897. -						timestamp = acc.unban_time; // add to existing ban
  898. -					tmtime = localtime(&timestamp);
  899. -					tmtime->tm_year = tmtime->tm_year + year;
  900. -					tmtime->tm_mon  = tmtime->tm_mon + month;
  901. -					tmtime->tm_mday = tmtime->tm_mday + mday;
  902. -					tmtime->tm_hour = tmtime->tm_hour + hour;
  903. -					tmtime->tm_min  = tmtime->tm_min + min;
  904. -					tmtime->tm_sec  = tmtime->tm_sec + sec;
  905. -					timestamp = mktime(tmtime);
  906. -					if (timestamp == -1)
  907. -						ShowNotice("Char-server '%s': Error of ban request (account: %d, invalid date, ip: %s).\n", server[id].name, account_id, ip);
  908. -					else if( timestamp <= time(NULL) || timestamp == 0 )
  909. -						ShowNotice("Char-server '%s': Error of ban request (account: %d, new date unbans the account, ip: %s).\n", server[id].name, account_id, ip);
  910. -					else{
  911. -						uint8 buf[11];
  912. -						char tmpstr[24];
  913. -						timestamp2string(tmpstr, sizeof(tmpstr), timestamp, login_config.date_format);
  914. -						ShowNotice("Char-server '%s': Ban request (account: %d, new final date of banishment: %d (%s), ip: %s).\n", server[id].name, account_id, timestamp, tmpstr, ip);
  915. -
  916. -						acc.unban_time = timestamp;
  917. -
  918. -						// Save
  919. -						accounts->save(accounts, &acc);
  920. -
  921. -						WBUFW(buf,0) = 0x2731;
  922. -						WBUFL(buf,2) = account_id;
  923. -						WBUFB(buf,6) = 1; // 0: change of status, 1: ban
  924. -						WBUFL(buf,7) = (uint32)timestamp; // status or final date of a banishment
  925. -						charif_sendallwos(-1, buf, 11);
  926. -					}
  927. -				}
  928. -			}
  929. -		break;
  930. -
  931. -		case 0x2727: // Change of sex (sex is reversed)
  932. -			if( RFIFOREST(fd) < 6 )
  933. -				return 0;
  934. -			else{
  935. -				struct mmo_account acc;
  936. -
  937. -				int account_id = RFIFOL(fd,2);
  938. -				RFIFOSKIP(fd,6);
  939. -
  940. -				if( !accounts->load_num(accounts, &acc, account_id) )
  941. -					ShowNotice("Char-server '%s': Error of sex change (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
  942. -				else if( acc.sex == 'S' )
  943. -					ShowNotice("Char-server '%s': Error of sex change - account to change is a Server account (account: %d, ip: %s).\n", server[id].name, account_id, ip);
  944. -				else{
  945. -					unsigned char buf[7];
  946. -					char sex = ( acc.sex == 'M' ) ? 'F' : 'M'; //Change gender
  947. -
  948. -					ShowNotice("Char-server '%s': Sex change (account: %d, new sex %c, ip: %s).\n", server[id].name, account_id, sex, ip);
  949. -
  950. -					acc.sex = sex;
  951. -					// Save
  952. -					accounts->save(accounts, &acc);
  953. -
  954. -					// announce to other servers
  955. -					WBUFW(buf,0) = 0x2723;
  956. -					WBUFL(buf,2) = account_id;
  957. -					WBUFB(buf,6) = sex_str2num(sex);
  958. -					charif_sendallwos(-1, buf, 7);
  959. -				}
  960. -			}
  961. -		break;
  962. -
  963. -		case 0x2728:	// We receive account_reg2 from a char-server, and we send them to other map-servers.
  964. -			if( RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2) )
  965. -				return 0;
  966. -			else{
  967. -				struct mmo_account acc;
  968. -
  969. -				int account_id = RFIFOL(fd,4);
  970. -
  971. -				if( !accounts->load_num(accounts, &acc, account_id) )
  972. -					ShowStatus("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
  973. -				else{
  974. -					int len;
  975. -					int p;
  976. -					ShowNotice("char-server '%s': receiving (from the char-server) of account_reg2 (account: %d, ip: %s).\n", server[id].name, account_id, ip);
  977. -					for( j = 0, p = 13; j < ACCOUNT_REG2_NUM && p < RFIFOW(fd,2); ++j ){
  978. -						sscanf((char*)RFIFOP(fd,p), "%31c%n", acc.account_reg2[j].str, &len);
  979. -						acc.account_reg2[j].str[len]='\0';
  980. -						p +=len+1; //+1 to skip the '\0' between strings.
  981. -						sscanf((char*)RFIFOP(fd,p), "%255c%n", acc.account_reg2[j].value, &len);
  982. -						acc.account_reg2[j].value[len]='\0';
  983. -						p +=len+1;
  984. -						remove_control_chars(acc.account_reg2[j].str);
  985. -						remove_control_chars(acc.account_reg2[j].value);
  986. -					}
  987. -					acc.account_reg2_num = j;
  988. -
  989. -					// Save
  990. -					accounts->save(accounts, &acc);
  991. -
  992. -					// Sending information towards the other char-servers.
  993. -					RFIFOW(fd,0) = 0x2729;// reusing read buffer
  994. -					charif_sendallwos(fd, RFIFOP(fd,0), RFIFOW(fd,2));
  995. -				}
  996. -				RFIFOSKIP(fd,RFIFOW(fd,2));
  997. -			}
  998. -		break;
  999. -
  1000. -		case 0x272a:	// Receiving of map-server via char-server an unban request
  1001. -			if( RFIFOREST(fd) < 6 )
  1002. -				return 0;
  1003. -			else{
  1004. -				struct mmo_account acc;
  1005. -
  1006. -				int account_id = RFIFOL(fd,2);
  1007. -				RFIFOSKIP(fd,6);
  1008. -
  1009. -				if( !accounts->load_num(accounts, &acc, account_id) )
  1010. -					ShowNotice("Char-server '%s': Error of UnBan request (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
  1011. -				else if( acc.unban_time == 0 )
  1012. -					ShowNotice("Char-server '%s': Error of UnBan request (account: %d, no change for unban date, ip: %s).\n", server[id].name, account_id, ip);
  1013. -				else{
  1014. -					ShowNotice("Char-server '%s': UnBan request (account: %d, ip: %s).\n", server[id].name, account_id, ip);
  1015. -					acc.unban_time = 0;
  1016. -					accounts->save(accounts, &acc);
  1017. -				}
  1018. -			}
  1019. -		break;
  1020. -
  1021. -		case 0x272b:    // Set account_id to online [Wizputer]
  1022. -			if( RFIFOREST(fd) < 6 )
  1023. -				return 0;
  1024. -			add_online_user(id, RFIFOL(fd,2));
  1025. -			RFIFOSKIP(fd,6);
  1026. -		break;
  1027. -
  1028. -		case 0x272c:   // Set account_id to offline [Wizputer]
  1029. -			if( RFIFOREST(fd) < 6 )
  1030. -				return 0;
  1031. -			remove_online_user(RFIFOL(fd,2));
  1032. -			RFIFOSKIP(fd,6);
  1033. -		break;
  1034. -
  1035. -		case 0x272d:	// Receive list of all online accounts. [Skotlex]
  1036. -			if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
  1037. -				return 0;
  1038. -			else{
  1039. -				struct online_login_data *p;
  1040. -				int aid;
  1041. -				uint32 i, users;
  1042. -				online_db->foreach(online_db, online_db_setoffline, id); //Set all chars from this char-server offline first
  1043. -				users = RFIFOW(fd,4);
  1044. -				for (i = 0; i < users; i++) {
  1045. -					aid = RFIFOL(fd,6+i*4);
  1046. -					p = idb_ensure(online_db, aid, create_online_user);
  1047. -					p->char_server = id;
  1048. -					if (p->waiting_disconnect != INVALID_TIMER){
  1049. -						delete_timer(p->waiting_disconnect, waiting_disconnect_timer);
  1050. -						p->waiting_disconnect = INVALID_TIMER;
  1051. -					}
  1052. -				}
  1053. -
  1054. -				RFIFOSKIP(fd,RFIFOW(fd,2));
  1055. -			}
  1056. -		break;
  1057. -
  1058. -		case 0x272e: //Request account_reg2 for a character.
  1059. -			if (RFIFOREST(fd) < 10)
  1060. -				return 0;
  1061. -			else{
  1062. -				struct mmo_account acc;
  1063. -				size_t off;
  1064. -
  1065. -				int account_id = RFIFOL(fd,2);
  1066. -				int char_id = RFIFOL(fd,6);
  1067. -				RFIFOSKIP(fd,10);
  1068. -
  1069. -				WFIFOHEAD(fd,ACCOUNT_REG2_NUM*sizeof(struct global_reg));
  1070. -				WFIFOW(fd,0) = 0x2729;
  1071. -				WFIFOL(fd,4) = account_id;
  1072. -				WFIFOL(fd,8) = char_id;
  1073. -				WFIFOB(fd,12) = 1; //Type 1 for Account2 registry
  1074. -
  1075. -				off = 13;
  1076. -				if( accounts->load_num(accounts, &acc, account_id) ){
  1077. -					for( j = 0; j < acc.account_reg2_num; j++ ){
  1078. -						if( acc.account_reg2[j].str[0] != '\0' ){
  1079. -							off += sprintf((char*)WFIFOP(fd,off), "%s", acc.account_reg2[j].str)+1; //We add 1 to consider the '\0' in place.
  1080. -							off += sprintf((char*)WFIFOP(fd,off), "%s", acc.account_reg2[j].value)+1;
  1081. -						}
  1082. -					}
  1083. -				}
  1084. -
  1085. -				WFIFOW(fd,2) = (uint16)off;
  1086. -				WFIFOSET(fd,WFIFOW(fd,2));
  1087. -			}
  1088. -		break;
  1089. -
  1090. -		case 0x2736: // WAN IP update from char-server
  1091. -			if( RFIFOREST(fd) < 6 )
  1092. -				return 0;
  1093. -			server[id].ip = ntohl(RFIFOL(fd,2));
  1094. -			ShowInfo("Updated IP of Server #%d to %d.%d.%d.%d.\n",id, CONVIP(server[id].ip));
  1095. -			RFIFOSKIP(fd,6);
  1096. -		break;
  1097. -
  1098. -		case 0x2737: //Request to set all offline.
  1099. -			ShowInfo("Setting accounts from char-server %d offline.\n", id);
  1100. -			online_db->foreach(online_db, online_db_setoffline, id);
  1101. -			RFIFOSKIP(fd,2);
  1102. -		break;
  1103. -
  1104. -		case 0x2738: //Change PIN Code for a account
  1105. -			if( RFIFOREST(fd) < 11 )
  1106. -				return 0;
  1107. -			else{
  1108. -				struct mmo_account acc;
  1109. -
  1110. -				if( accounts->load_num(accounts, &acc, RFIFOL(fd,2) ) ){
  1111. -					strncpy( acc.pincode, (char*)RFIFOP(fd,6), 5 );
  1112. -					acc.pincode_change = time( NULL );
  1113. -					accounts->save(accounts, &acc);
  1114. -				}
  1115. -
  1116. -				RFIFOSKIP(fd,11);
  1117. -			}
  1118. -		break;
  1119. -
  1120. -		case 0x2739: // PIN Code was entered wrong too often
  1121. -			if( RFIFOREST(fd) < 6 )
  1122. -				return 0;
  1123. -			else{
  1124. -				struct mmo_account acc;
  1125. -
  1126. -				if( accounts->load_num(accounts, &acc, RFIFOL(fd,2) ) ){
  1127. -					struct online_login_data* ld;
  1128. -
  1129. -					ld = (struct online_login_data*)idb_get(online_db,acc.account_id);
  1130. -
  1131. -					if( ld == NULL )
  1132. -						return 0;
  1133. -
  1134. -					login_log( host2ip(acc.last_ip), acc.userid, 100, "PIN Code check failed" );
  1135. -				}
  1136. -
  1137. -				remove_online_user(acc.account_id);
  1138. -
  1139. -				RFIFOSKIP(fd,6);
  1140. -			}
  1141. -		break;
  1142. -
  1143. -		default:
  1144. -			ShowError("parse_fromchar: Unknown packet 0x%x from a char-server! Disconnecting!\n", command);
  1145. -			set_eof(fd);
  1146. -			return 0;
  1147. -		} // switch
  1148. -	} // while
  1149. -
  1150. -	return 0;
  1151. -}
  1152. -
  1153. -
  1154.  //-------------------------------------
  1155.  // Make new account
  1156.  //-------------------------------------
  1157. @@ -964,7 +167,7 @@
  1158.  	//Account Registration Flood Protection by [Kevin]
  1159.  	if( new_reg_tick == 0 )
  1160.  		new_reg_tick = gettick();
  1161. -	if( DIFF_TICK(tick, new_reg_tick) < 0 && num_regs >= allowed_regs ) {
  1162. +	if( DIFF_TICK(tick, new_reg_tick) < 0 && num_regs >= login_config.allowed_regs ) {
  1163.  		ShowNotice("Account registration denied (registration limit exceeded)\n");
  1164.  		return 3;
  1165.  	}
  1166. @@ -1004,7 +207,7 @@
  1167.  
  1168.  	if( DIFF_TICK(tick, new_reg_tick) > 0 ) {// Update the registration check.
  1169.  		num_regs = 0;
  1170. -		new_reg_tick = tick + time_allowed*1000;
  1171. +		new_reg_tick = tick + login_config.time_allowed*1000;
  1172.  	}
  1173.  	++num_regs;
  1174.  
  1175. @@ -1041,8 +244,11 @@
  1176.  	}
  1177.  
  1178.  	//Client Version check
  1179. -	if( login_config.check_client_version && sd->version != login_config.client_version_to_connect )
  1180. +	if( login_config.check_client_version && sd->version != login_config.client_version_to_connect ){
  1181. +		ShowNotice("Invalid version (account: '%s', auth_vers: '%d', received version: '%d', ip: %s)\n",
  1182. +			sd->userid, login_config.client_version_to_connect, sd->version, ip);
  1183.  		return 5;
  1184. +	}
  1185.  
  1186.  	len = strnlen(sd->userid, NAME_LENGTH);
  1187.  
  1188. @@ -1093,15 +299,16 @@
  1189.  
  1190.  	if( login_config.client_hash_check && !isServer ) {
  1191.  		struct client_hash_node *node = login_config.client_hash_nodes;
  1192. +		uint8 anyhash[16];
  1193.  		bool match = false;
  1194.  
  1195.  		if( !sd->has_client_hash ) {
  1196.  			ShowNotice("Client doesn't sent client hash (account: %s, pass: %s, ip: %s)\n", sd->userid, sd->passwd, acc.state, ip);
  1197.  			return 5;
  1198.  		}
  1199. -
  1200. +		memset(anyhash,1,sizeof(anyhash));
  1201.  		while( node ) {
  1202. -			if( node->group_id <= acc.group_id && memcmp(node->hash, sd->client_hash, 16) == 0 ) {
  1203. +			if( node->group_id <= acc.group_id && (memcmp(node->hash,anyhash,16)==0 || memcmp(node->hash, sd->client_hash, 16) == 0 ) ){
  1204.  				match = true;
  1205.  				break;
  1206.  			}
  1207. @@ -1145,466 +352,97 @@
  1208.  	return -1; // account OK
  1209.  }
  1210.  
  1211. -void login_auth_ok(struct login_session_data* sd)
  1212. +//-----------------------------------------------------
  1213. +// encrypted/unencrypted password check (from eApp)
  1214. +//-----------------------------------------------------
  1215. +bool check_encrypted(const char* str1, const char* str2, const char* passwd)
  1216.  {
  1217. -	int fd = sd->fd;
  1218. -	uint32 ip = session[fd]->client_addr;
  1219. +	char tmpstr[64+1], md5str[32+1];
  1220.  
  1221. -	uint8 server_num, n;
  1222. -	uint32 subnet_char_ip;
  1223. -	struct auth_node* node;
  1224. -	int i;
  1225. +	safesnprintf(tmpstr, sizeof(tmpstr), "%s%s", str1, str2);
  1226. +	MD5_String(tmpstr, md5str);
  1227.  
  1228. -	if( runflag != LOGINSERVER_ST_RUNNING )
  1229. -	{
  1230. -		// players can only login while running
  1231. -		WFIFOHEAD(fd,3);
  1232. -		WFIFOW(fd,0) = 0x81;
  1233. -		WFIFOB(fd,2) = 1;// server closed
  1234. -		WFIFOSET(fd,3);
  1235. -		return;
  1236. -	}
  1237. +	return (0==strcmp(passwd, md5str));
  1238. +}
  1239.  
  1240. -	if( login_config.group_id_to_connect >= 0 && sd->group_id != login_config.group_id_to_connect ) {
  1241. -		ShowStatus("Connection refused: the required group id for connection is %d (account: %s, group: %d).\n", login_config.group_id_to_connect, sd->userid, sd->group_id);
  1242. -		WFIFOHEAD(fd,3);
  1243. -		WFIFOW(fd,0) = 0x81;
  1244. -		WFIFOB(fd,2) = 1; // 01 = Server closed
  1245. -		WFIFOSET(fd,3);
  1246. -		return;
  1247. -	} else if( login_config.min_group_id_to_connect >= 0 && login_config.group_id_to_connect == -1 && sd->group_id < login_config.min_group_id_to_connect ) {
  1248. -		ShowStatus("Connection refused: the minium group id required for connection is %d (account: %s, group: %d).\n", login_config.min_group_id_to_connect, sd->userid, sd->group_id);
  1249. -		WFIFOHEAD(fd,3);
  1250. -		WFIFOW(fd,0) = 0x81;
  1251. -		WFIFOB(fd,2) = 1; // 01 = Server closed
  1252. -		WFIFOSET(fd,3);
  1253. -		return;
  1254. -	}
  1255. -
  1256. -	server_num = 0;
  1257. -	for( i = 0; i < ARRAYLENGTH(server); ++i )
  1258. -		if( session_isActive(server[i].fd) )
  1259. -			server_num++;
  1260. -
  1261. -	if( server_num == 0 )
  1262. -	{// if no char-server, don't send void list of servers, just disconnect the player with proper message
  1263. -		ShowStatus("Connection refused: there is no char-server online (account: %s).\n", sd->userid);
  1264. -		WFIFOHEAD(fd,3);
  1265. -		WFIFOW(fd,0) = 0x81;
  1266. -		WFIFOB(fd,2) = 1; // 01 = Server closed
  1267. -		WFIFOSET(fd,3);
  1268. -		return;
  1269. -	}
  1270. -
  1271. +bool check_password(const char* md5key, int passwdenc, const char* passwd, const char* refpass)
  1272. +{
  1273. +	if(passwdenc == 0)
  1274.  	{
  1275. -		struct online_login_data* data = (struct online_login_data*)idb_get(online_db, sd->account_id);
  1276. -		if( data )
  1277. -		{// account is already marked as online!
  1278. -			if( data->char_server > -1 )
  1279. -			{// Request char servers to kick this account out. [Skotlex]
  1280. -				uint8 buf[6];
  1281. -				ShowNotice("User '%s' is already online - Rejected.\n", sd->userid);
  1282. -				WBUFW(buf,0) = 0x2734;
  1283. -				WBUFL(buf,2) = sd->account_id;
  1284. -				charif_sendallwos(-1, buf, 6);
  1285. -				if( data->waiting_disconnect == INVALID_TIMER )
  1286. -					data->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, waiting_disconnect_timer, sd->account_id, 0);
  1287. -
  1288. -				WFIFOHEAD(fd,3);
  1289. -				WFIFOW(fd,0) = 0x81;
  1290. -				WFIFOB(fd,2) = 8; // 08 = Server still recognizes your last login
  1291. -				WFIFOSET(fd,3);
  1292. -				return;
  1293. -			}
  1294. -			else
  1295. -			if( data->char_server == -1 )
  1296. -			{// client has authed but did not access char-server yet
  1297. -				// wipe previous session
  1298. -				idb_remove(auth_db, sd->account_id);
  1299. -				remove_online_user(sd->account_id);
  1300. -				data = NULL;
  1301. -			}
  1302. -		}
  1303. +		return (0==strcmp(passwd, refpass));
  1304.  	}
  1305. -
  1306. -	login_log(ip, sd->userid, 100, "login ok");
  1307. -	ShowStatus("Connection of the account '%s' accepted.\n", sd->userid);
  1308. -
  1309. -	WFIFOHEAD(fd,47+32*server_num);
  1310. -	WFIFOW(fd,0) = 0x69;
  1311. -	WFIFOW(fd,2) = 47+32*server_num;
  1312. -	WFIFOL(fd,4) = sd->login_id1;
  1313. -	WFIFOL(fd,8) = sd->account_id;
  1314. -	WFIFOL(fd,12) = sd->login_id2;
  1315. -	WFIFOL(fd,16) = 0; // in old version, that was for ip (not more used)
  1316. -	//memcpy(WFIFOP(fd,20), sd->lastlogin, 24); // in old version, that was for name (not more used)
  1317. -	memset(WFIFOP(fd,20), 0, 24);
  1318. -	WFIFOW(fd,44) = 0; // unknown
  1319. -	WFIFOB(fd,46) = sex_str2num(sd->sex);
  1320. -	for( i = 0, n = 0; i < ARRAYLENGTH(server); ++i )
  1321. +	else
  1322.  	{
  1323. -		if( !session_isValid(server[i].fd) )
  1324. -			continue;
  1325. +		// password mode set to 1 -> md5(md5key, refpass) enable with <passwordencrypt></passwordencrypt>
  1326. +		// password mode set to 2 -> md5(refpass, md5key) enable with <passwordencrypt2></passwordencrypt2>
  1327.  
  1328. -		subnet_char_ip = lan_subnetcheck(ip); // Advanced subnet check [LuzZza]
  1329. -		WFIFOL(fd,47+n*32) = htonl((subnet_char_ip) ? subnet_char_ip : server[i].ip);
  1330. -		WFIFOW(fd,47+n*32+4) = ntows(htons(server[i].port)); // [!] LE byte order here [!]
  1331. -		memcpy(WFIFOP(fd,47+n*32+6), server[i].name, 20);
  1332. -		WFIFOW(fd,47+n*32+26) = server[i].users;
  1333. -		WFIFOW(fd,47+n*32+28) = server[i].type;
  1334. -		WFIFOW(fd,47+n*32+30) = server[i].new_;
  1335. -		n++;
  1336. +		return ((passwdenc&0x01) && check_encrypted(md5key, refpass, passwd)) ||
  1337. +		       ((passwdenc&0x02) && check_encrypted(refpass, md5key, passwd));
  1338.  	}
  1339. -	WFIFOSET(fd,47+32*server_num);
  1340. -
  1341. -	// create temporary auth entry
  1342. -	CREATE(node, struct auth_node, 1);
  1343. -	node->account_id = sd->account_id;
  1344. -	node->login_id1 = sd->login_id1;
  1345. -	node->login_id2 = sd->login_id2;
  1346. -	node->sex = sd->sex;
  1347. -	node->ip = ip;
  1348. -	node->version = sd->version;
  1349. -	node->clienttype = sd->clienttype;
  1350. -	idb_put(auth_db, sd->account_id, node);
  1351. -
  1352. -	{
  1353. -		struct online_login_data* data;
  1354. -
  1355. -		// mark client as 'online'
  1356. -		data = add_online_user(-1, sd->account_id);
  1357. -
  1358. -		// schedule deletion of this node
  1359. -		data->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, waiting_disconnect_timer, sd->account_id, 0);
  1360. -	}
  1361.  }
  1362.  
  1363. -/* Log the result of a failed connection attempt by sd
  1364. - * result: nb (msg define in conf)
  1365. -    0 = Unregistered ID
  1366. -    1 = Incorrect Password
  1367. -    2 = This ID is expired
  1368. -    3 = Rejected from Server
  1369. -    4 = You have been blocked by the GM Team
  1370. -    5 = Your Game's EXE file is not the latest version
  1371. -    6 = Your are Prohibited to log in until %s
  1372. -    7 = Server is jammed due to over populated
  1373. -    8 = No more accounts may be connected from this company
  1374. -    9 = MSI_REFUSE_BAN_BY_DBA
  1375. -    10 = MSI_REFUSE_EMAIL_NOT_CONFIRMED
  1376. -    11 = MSI_REFUSE_BAN_BY_GM
  1377. -    12 = MSI_REFUSE_TEMP_BAN_FOR_DBWORK
  1378. -    13 = MSI_REFUSE_SELF_LOCK
  1379. -    14 = MSI_REFUSE_NOT_PERMITTED_GROUP
  1380. -    15 = MSI_REFUSE_NOT_PERMITTED_GROUP
  1381. -    99 = This ID has been totally erased
  1382. -    100 = Login information remains at %s
  1383. -    101 = Account has been locked for a hacking investigation. Please contact the GM Team for more information
  1384. -    102 = This account has been temporarily prohibited from login due to a bug-related investigation
  1385. -    103 = This character is being deleted. Login is temporarily unavailable for the time being
  1386. -    104 = This character is being deleted. Login is temporarily unavailable for the time being
  1387. -     default = Unknown Error.
  1388. - */
  1389. -void login_auth_failed(struct login_session_data* sd, int result)
  1390. +//--------------------------------------------
  1391. +// Test to know if an IP come from LAN or WAN.
  1392. +//--------------------------------------------
  1393. +int lan_subnetcheck(uint32 ip)
  1394.  {
  1395. -	int fd = sd->fd;
  1396. -	uint32 ip = session[fd]->client_addr;
  1397. -
  1398. -	if (login_config.log_login)
  1399. -	{
  1400. -		if(result >= 0 && result <= 15)
  1401. -		    login_log(ip, sd->userid, result, msg_txt(result));
  1402. -		else if(result >= 99 && result <= 104)
  1403. -		    login_log(ip, sd->userid, result, msg_txt(result-83)); //-83 offset
  1404. -		else
  1405. -		    login_log(ip, sd->userid, result, msg_txt(22)); //unknow error
  1406. -	}
  1407. -
  1408. -	if( result == 1 && login_config.dynamic_pass_failure_ban )
  1409. -		ipban_log(ip); // log failed password attempt
  1410. -
  1411. -#if PACKETVER >= 20120000 /* not sure when this started */
  1412. -	WFIFOHEAD(fd,26);
  1413. -	WFIFOW(fd,0) = 0x83e;
  1414. -	WFIFOL(fd,2) = result;
  1415. -	if( result != 6 )
  1416. -		memset(WFIFOP(fd,6), '\0', 20);
  1417. -	else { // 6 = Your are Prohibited to log in until %s
  1418. -		struct mmo_account acc;
  1419. -		time_t unban_time = ( accounts->load_str(accounts, &acc, sd->userid) ) ? acc.unban_time : 0;
  1420. -		timestamp2string((char*)WFIFOP(fd,6), 20, unban_time, login_config.date_format);
  1421. -	}
  1422. -	WFIFOSET(fd,26);
  1423. -#else
  1424. -	WFIFOHEAD(fd,23);
  1425. -	WFIFOW(fd,0) = 0x6a;
  1426. -	WFIFOB(fd,2) = (uint8)result;
  1427. -	if( result != 6 )
  1428. -		memset(WFIFOP(fd,3), '\0', 20);
  1429. -	else { // 6 = Your are Prohibited to log in until %s
  1430. -		struct mmo_account acc;
  1431. -		time_t unban_time = ( accounts->load_str(accounts, &acc, sd->userid) ) ? acc.unban_time : 0;
  1432. -		timestamp2string((char*)WFIFOP(fd,3), 20, unban_time, login_config.date_format);
  1433. -	}
  1434. -	WFIFOSET(fd,23);
  1435. -#endif
  1436. +	int i;
  1437. +	ARR_FIND( 0, subnet_count, i, (subnet[i].char_ip & subnet[i].mask) == (ip & subnet[i].mask) );
  1438. +	return ( i < subnet_count ) ? subnet[i].char_ip : 0;
  1439.  }
  1440.  
  1441. -
  1442. -//----------------------------------------------------------------------------------------
  1443. -// Default packet parsing (normal players or char-server connection requests)
  1444. -//----------------------------------------------------------------------------------------
  1445. -int parse_login(int fd)
  1446. +//----------------------------------
  1447. +// Reading Lan Support configuration
  1448. +//----------------------------------
  1449. +int login_lan_config_read(const char *lancfgName)
  1450.  {
  1451. -	struct login_session_data* sd = (struct login_session_data*)session[fd]->session_data;
  1452. -	int result;
  1453. +	FILE *fp;
  1454. +	int line_num = 0;
  1455. +	char line[1024], w1[64], w2[64], w3[64], w4[64];
  1456.  
  1457. -	char ip[16];
  1458. -	uint32 ipl = session[fd]->client_addr;
  1459. -	ip2str(ipl, ip);
  1460. -
  1461. -	if( session[fd]->flag.eof )
  1462. -	{
  1463. -		ShowInfo("Closed connection from '"CL_WHITE"%s"CL_RESET"'.\n", ip);
  1464. -		do_close(fd);
  1465. -		return 0;
  1466. +	if((fp = fopen(lancfgName, "r")) == NULL) {
  1467. +		ShowWarning("LAN Support configuration file is not found: %s\n", lancfgName);
  1468. +		return 1;
  1469.  	}
  1470.  
  1471. -	if( sd == NULL )
  1472. +	while(fgets(line, sizeof(line), fp))
  1473.  	{
  1474. -		// Perform ip-ban check
  1475. -		if( login_config.ipban && ipban_check(ipl) )
  1476. -		{
  1477. -			ShowStatus("Connection refused: IP isn't authorised (deny/allow, ip: %s).\n", ip);
  1478. -			login_log(ipl, "unknown", -3, "ip banned");
  1479. -			WFIFOHEAD(fd,23);
  1480. -			WFIFOW(fd,0) = 0x6a;
  1481. -			WFIFOB(fd,2) = 3; // 3 = Rejected from Server
  1482. -			WFIFOSET(fd,23);
  1483. -			set_eof(fd);
  1484. -			return 0;
  1485. -		}
  1486. +		line_num++;
  1487. +		if ((line[0] == '/' && line[1] == '/') || line[0] == '\n' || line[1] == '\n')
  1488. +			continue;
  1489.  
  1490. -		// create a session for this new connection
  1491. -		CREATE(session[fd]->session_data, struct login_session_data, 1);
  1492. -		sd = (struct login_session_data*)session[fd]->session_data;
  1493. -		sd->fd = fd;
  1494. -	}
  1495. -
  1496. -	while( RFIFOREST(fd) >= 2 )
  1497. -	{
  1498. -		uint16 command = RFIFOW(fd,0);
  1499. -
  1500. -		switch( command )
  1501. +		if(sscanf(line,"%[^:]: %[^:]:%[^:]:%[^\r\n]", w1, w2, w3, w4) != 4)
  1502.  		{
  1503. -
  1504. -		case 0x0200:		// New alive packet: structure: 0x200 <account.userid>.24B. used to verify if client is always alive.
  1505. -			if (RFIFOREST(fd) < 26)
  1506. -				return 0;
  1507. -			RFIFOSKIP(fd,26);
  1508. -		break;
  1509. -
  1510. -		// client md5 hash (binary)
  1511. -		case 0x0204: // S 0204 <md5 hash>.16B (kRO 2004-05-31aSakexe langtype 0 and 6)
  1512. -			if (RFIFOREST(fd) < 18)
  1513. -				return 0;
  1514. -
  1515. -			sd->has_client_hash = 1;
  1516. -			memcpy(sd->client_hash, RFIFOP(fd, 2), 16);
  1517. -
  1518. -			RFIFOSKIP(fd,18);
  1519. -		break;
  1520. -
  1521. -		// request client login (raw password)
  1522. -		case 0x0064: // S 0064 <version>.L <username>.24B <password>.24B <clienttype>.B
  1523. -		case 0x0277: // S 0277 <version>.L <username>.24B <password>.24B <clienttype>.B <ip address>.16B <adapter address>.13B
  1524. -		case 0x02b0: // S 02b0 <version>.L <username>.24B <password>.24B <clienttype>.B <ip address>.16B <adapter address>.13B <g_isGravityID>.B
  1525. -		// request client login (md5-hashed password)
  1526. -		case 0x01dd: // S 01dd <version>.L <username>.24B <password hash>.16B <clienttype>.B
  1527. -		case 0x01fa: // S 01fa <version>.L <username>.24B <password hash>.16B <clienttype>.B <?>.B(index of the connection in the clientinfo file (+10 if the command-line contains "pc"))
  1528. -		case 0x027c: // S 027c <version>.L <username>.24B <password hash>.16B <clienttype>.B <?>.13B(junk)
  1529. -		case 0x0825: // S 0825 <packetsize>.W <version>.L <clienttype>.B <userid>.24B <password>.27B <mac>.17B <ip>.15B <token>.(packetsize - 0x5C)B
  1530. -		{
  1531. -			size_t packet_len = RFIFOREST(fd);
  1532. -
  1533. -			if( (command == 0x0064 && packet_len < 55)
  1534. -			||  (command == 0x0277 && packet_len < 84)
  1535. -			||  (command == 0x02b0 && packet_len < 85)
  1536. -			||  (command == 0x01dd && packet_len < 47)
  1537. -			||  (command == 0x01fa && packet_len < 48)
  1538. -			||  (command == 0x027c && packet_len < 60)
  1539. -			||  (command == 0x0825 && (packet_len < 4 || packet_len < RFIFOW(fd, 2))) )
  1540. -				return 0;
  1541. +			ShowWarning("Error syntax of configuration file %s in line %d.\n", lancfgName, line_num);
  1542. +			continue;
  1543.  		}
  1544. -		{
  1545. -			uint32 version;
  1546. -			char username[NAME_LENGTH];
  1547. -			char password[NAME_LENGTH];
  1548. -			unsigned char passhash[16];
  1549. -			uint8 clienttype;
  1550. -			bool israwpass = (command==0x0064 || command==0x0277 || command==0x02b0 || command == 0x0825);
  1551.  
  1552. -			// Shinryo: For the time being, just use token as password.
  1553. -			if(command == 0x0825)
  1554. -			{
  1555. -				char *accname = (char *)RFIFOP(fd, 9);
  1556. -				char *token = (char *)RFIFOP(fd, 0x5C);
  1557. -				size_t uAccLen = strlen(accname);
  1558. -				size_t uTokenLen = RFIFOREST(fd) - 0x5C;
  1559. -
  1560. -				version = RFIFOL(fd,4);
  1561. -
  1562. -				if(uAccLen > NAME_LENGTH - 1 || uAccLen <= 0 || uTokenLen > NAME_LENGTH - 1  || uTokenLen <= 0)
  1563. -				{
  1564. -					login_auth_failed(sd, 3);
  1565. -					return 0;
  1566. -				}
  1567. -
  1568. -				safestrncpy(username, accname, uAccLen + 1);
  1569. -				safestrncpy(password, token, uTokenLen + 1);
  1570. -				clienttype = RFIFOB(fd, 8);
  1571. -			}
  1572. -			else
  1573. -			{
  1574. -				version = RFIFOL(fd,2);
  1575. -				safestrncpy(username, (const char*)RFIFOP(fd,6), NAME_LENGTH);
  1576. -				if( israwpass )
  1577. -				{
  1578. -					safestrncpy(password, (const char*)RFIFOP(fd,30), NAME_LENGTH);
  1579. -					clienttype = RFIFOB(fd,54);
  1580. -				}
  1581. -				else
  1582. -				{
  1583. -					memcpy(passhash, RFIFOP(fd,30), 16);
  1584. -					clienttype = RFIFOB(fd,46);
  1585. -				}
  1586. -			}
  1587. -			RFIFOSKIP(fd,RFIFOREST(fd)); // assume no other packet was sent
  1588. -
  1589. -			sd->clienttype = clienttype;
  1590. -			sd->version = version;
  1591. -			safestrncpy(sd->userid, username, NAME_LENGTH);
  1592. -			if( israwpass )
  1593. -			{
  1594. -				ShowStatus("Request for connection of %s (ip: %s) version=%d\n", sd->userid, ip,sd->version);
  1595. -				safestrncpy(sd->passwd, password, NAME_LENGTH);
  1596. -				if( login_config.use_md5_passwds )
  1597. -					MD5_String(sd->passwd, sd->passwd);
  1598. -				sd->passwdenc = 0;
  1599. -			}
  1600. -			else
  1601. -			{
  1602. -				ShowStatus("Request for connection (passwdenc mode) of %s (ip: %s) version=%d\n", sd->userid, ip,sd->version);
  1603. -				bin2hex(sd->passwd, passhash, 16); // raw binary data here!
  1604. -				sd->passwdenc = PASSWORDENC;
  1605. -			}
  1606. -
  1607. -			if( sd->passwdenc != 0 && login_config.use_md5_passwds )
  1608. -			{
  1609. -				login_auth_failed(sd, 3); // send "rejected from server"
  1610. -				return 0;
  1611. -			}
  1612. -
  1613. -			result = mmo_auth(sd, false);
  1614. -
  1615. -			if( result == -1 )
  1616. -				login_auth_ok(sd);
  1617. -			else
  1618. -				login_auth_failed(sd, result);
  1619. -		}
  1620. -		break;
  1621. -
  1622. -		case 0x01db:	// Sending request of the coding key
  1623. -			RFIFOSKIP(fd,2);
  1624. +		if( strcmpi(w1, "subnet") == 0 )
  1625.  		{
  1626. -			memset(sd->md5key, '\0', sizeof(sd->md5key));
  1627. -			sd->md5keylen = (uint16)(12 + rnd() % 4);
  1628. -			MD5_Salt(sd->md5keylen, sd->md5key);
  1629. +			subnet[subnet_count].mask = str2ip(w2);
  1630. +			subnet[subnet_count].char_ip = str2ip(w3);
  1631. +			subnet[subnet_count].map_ip = str2ip(w4);
  1632.  
  1633. -			WFIFOHEAD(fd,4 + sd->md5keylen);
  1634. -			WFIFOW(fd,0) = 0x01dc;
  1635. -			WFIFOW(fd,2) = 4 + sd->md5keylen;
  1636. -			memcpy(WFIFOP(fd,4), sd->md5key, sd->md5keylen);
  1637. -			WFIFOSET(fd,WFIFOW(fd,2));
  1638. -		}
  1639. -		break;
  1640. -
  1641. -		case 0x2710:	// Connection request of a char-server
  1642. -			if (RFIFOREST(fd) < 86)
  1643. -				return 0;
  1644. -		{
  1645. -			char server_name[20];
  1646. -			char message[256];
  1647. -			uint32 server_ip;
  1648. -			uint16 server_port;
  1649. -			uint16 type;
  1650. -			uint16 new_;
  1651. -
  1652. -			safestrncpy(sd->userid, (char*)RFIFOP(fd,2), NAME_LENGTH);
  1653. -			safestrncpy(sd->passwd, (char*)RFIFOP(fd,26), NAME_LENGTH);
  1654. -			if( login_config.use_md5_passwds )
  1655. -				MD5_String(sd->passwd, sd->passwd);
  1656. -			sd->passwdenc = 0;
  1657. -			sd->version = login_config.client_version_to_connect; // hack to skip version check
  1658. -			server_ip = ntohl(RFIFOL(fd,54));
  1659. -			server_port = ntohs(RFIFOW(fd,58));
  1660. -			safestrncpy(server_name, (char*)RFIFOP(fd,60), 20);
  1661. -			type = RFIFOW(fd,82);
  1662. -			new_ = RFIFOW(fd,84);
  1663. -			RFIFOSKIP(fd,86);
  1664. -
  1665. -			ShowInfo("Connection request of the char-server '%s' @ %u.%u.%u.%u:%u (account: '%s', pass: '%s', ip: '%s')\n", server_name, CONVIP(server_ip), server_port, sd->userid, sd->passwd, ip);
  1666. -			sprintf(message, "charserver - %s@%u.%u.%u.%u:%u", server_name, CONVIP(server_ip), server_port);
  1667. -			login_log(session[fd]->client_addr, sd->userid, 100, message);
  1668. -
  1669. -			result = mmo_auth(sd, true);
  1670. -			if( runflag == LOGINSERVER_ST_RUNNING &&
  1671. -				result == -1 &&
  1672. -				sd->sex == 'S' &&
  1673. -				sd->account_id >= 0 && sd->account_id < ARRAYLENGTH(server) &&
  1674. -				!session_isValid(server[sd->account_id].fd) )
  1675. +			if( (subnet[subnet_count].char_ip & subnet[subnet_count].mask) != (subnet[subnet_count].map_ip & subnet[subnet_count].mask) )
  1676.  			{
  1677. -				ShowStatus("Connection of the char-server '%s' accepted.\n", server_name);
  1678. -				safestrncpy(server[sd->account_id].name, server_name, sizeof(server[sd->account_id].name));
  1679. -				server[sd->account_id].fd = fd;
  1680. -				server[sd->account_id].ip = server_ip;
  1681. -				server[sd->account_id].port = server_port;
  1682. -				server[sd->account_id].users = 0;
  1683. -				server[sd->account_id].type = type;
  1684. -				server[sd->account_id].new_ = new_;
  1685. -
  1686. -				session[fd]->func_parse = parse_fromchar;
  1687. -				session[fd]->flag.server = 1;
  1688. -				realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
  1689. -
  1690. -				// send connection success
  1691. -				WFIFOHEAD(fd,3);
  1692. -				WFIFOW(fd,0) = 0x2711;
  1693. -				WFIFOB(fd,2) = 0;
  1694. -				WFIFOSET(fd,3);
  1695. +				ShowError("%s: Configuration Error: The char server (%s) and map server (%s) belong to different subnetworks!\n", lancfgName, w3, w4);
  1696. +				continue;
  1697.  			}
  1698. -			else
  1699. -			{
  1700. -				ShowNotice("Connection of the char-server '%s' REFUSED.\n", server_name);
  1701. -				WFIFOHEAD(fd,3);
  1702. -				WFIFOW(fd,0) = 0x2711;
  1703. -				WFIFOB(fd,2) = 3;
  1704. -				WFIFOSET(fd,3);
  1705. -			}
  1706. -		}
  1707. -		return 0; // processing will continue elsewhere
  1708.  
  1709. -		default:
  1710. -			ShowNotice("Abnormal end of connection (ip: %s): Unknown packet 0x%x\n", ip, command);
  1711. -			set_eof(fd);
  1712. -			return 0;
  1713. +			subnet_count++;
  1714.  		}
  1715.  	}
  1716.  
  1717. +	if( subnet_count > 1 ) /* only useful if there is more than 1 available */
  1718. +		ShowStatus("Read information about %d subnetworks.\n", subnet_count);
  1719. +
  1720. +	fclose(fp);
  1721.  	return 0;
  1722.  }
  1723.  
  1724. -
  1725. +/*
  1726. + * Init default configuration
  1727. + */
  1728.  void login_set_defaults()
  1729.  {
  1730.  	login_config.login_ip = INADDR_ANY;
  1731. @@ -1620,7 +458,8 @@
  1732.  	login_config.group_id_to_connect = -1;
  1733.  	login_config.min_group_id_to_connect = -1;
  1734.  	login_config.check_client_version = false;
  1735. -	login_config.client_version_to_connect = 20;
  1736. +	login_config.client_version_to_connect = date2version(PACKETVER); //20120410 => 30
  1737. +	ShowInfo("loginconfig: client_version_to_connect = %d\n",login_config.client_version_to_connect);
  1738.  
  1739.  	login_config.ipban = true;
  1740.  	login_config.dynamic_pass_failure_ban = true;
  1741. @@ -1630,9 +469,16 @@
  1742.  	login_config.use_dnsbl = false;
  1743.  	safestrncpy(login_config.dnsbl_servs, "", sizeof(login_config.dnsbl_servs));
  1744.  	safestrncpy(login_config.account_engine, "auto", sizeof(login_config.account_engine));
  1745. +	login_config.allowed_regs = true;
  1746. +	login_config.time_allowed = 10; //in second
  1747.  
  1748.  	login_config.client_hash_check = 0;
  1749.  	login_config.client_hash_nodes = NULL;
  1750. +
  1751. +	//other default conf
  1752. +	login_config.loginconf_name = "conf/login_athena.conf";
  1753. +	login_config.lanconf_name = "conf/subnet_athena.conf";
  1754. +	login_config.msgconf_name = "conf/msg_conf/login_msg.conf";
  1755.  }
  1756.  
  1757.  //-----------------------------------
  1758. @@ -1696,9 +542,9 @@
  1759.  		else if(!strcmpi(w1, "console"))
  1760.  			login_config.console = (bool)config_switch(w2);
  1761.  		else if(!strcmpi(w1, "allowed_regs")) //account flood protection system
  1762. -			allowed_regs = atoi(w2);
  1763. +			login_config.allowed_regs = atoi(w2);
  1764.  		else if(!strcmpi(w1, "time_allowed"))
  1765. -			time_allowed = atoi(w2);
  1766. +			login_config.time_allowed = atoi(w2);
  1767.  		else if(!strcmpi(w1, "use_dnsbl"))
  1768.  			login_config.use_dnsbl = (bool)config_switch(w2);
  1769.  		else if(!strcmpi(w1, "dnsbl_servers"))
  1770. @@ -1718,15 +564,20 @@
  1771.  				int i;
  1772.  				CREATE(nnode, struct client_hash_node, 1);
  1773.  
  1774. -				for (i = 0; i < 32; i += 2) {
  1775. -					char buf[3];
  1776. -					unsigned int byte;
  1777. +				if(!strcmpi(md5,"any")){
  1778. +					memset(nnode->hash,1,sizeof(nnode->hash));
  1779. +				}
  1780. +				else {
  1781. +					for (i = 0; i < 32; i += 2) {
  1782. +						char buf[3];
  1783. +						unsigned int byte;
  1784.  
  1785. -					memcpy(buf, &md5[i], 2);
  1786. -					buf[2] = 0;
  1787. +						memcpy(buf, &md5[i], 2);
  1788. +						buf[2] = 0;
  1789.  
  1790. -					sscanf(buf, "%x", &byte);
  1791. -					nnode->hash[i / 2] = (uint8)(byte & 0xFF);
  1792. +						sscanf(buf, "%x", &byte);
  1793. +						nnode->hash[i / 2] = (uint8)(byte & 0xFF);
  1794. +					}
  1795.  				}
  1796.  
  1797.  				nnode->group_id = group;
  1798. @@ -1818,8 +669,7 @@
  1799.  	online_db->destroy(online_db, NULL);
  1800.  	auth_db->destroy(auth_db, NULL);
  1801.  
  1802. -	for( i = 0; i < ARRAYLENGTH(server); ++i )
  1803. -		chrif_server_destroy(i);
  1804. +	do_final_loginchrif();
  1805.  
  1806.  	if( login_fd != -1 )
  1807.  	{
  1808. @@ -1849,12 +699,10 @@
  1809.  {
  1810.  	if( runflag != LOGINSERVER_ST_SHUTDOWN )
  1811.  	{
  1812. -		int id;
  1813.  		runflag = LOGINSERVER_ST_SHUTDOWN;
  1814.  		ShowStatus("Shutting down...\n");
  1815.  		// TODO proper shutdown procedure; kick all characters, wait for acks, ...  [FlavioJS]
  1816. -		for( id = 0; id < ARRAYLENGTH(server); ++id )
  1817. -			chrif_server_reset(id);
  1818. +		do_shutdown_loginchrif();
  1819.  		flush_fifos();
  1820.  		runflag = CORE_ST_STOP;
  1821.  	}
  1822. @@ -1874,21 +722,16 @@
  1823.  
  1824.  	// read login-server configuration
  1825.  	login_set_defaults();
  1826. +	cnsl_get_options(argc,argv);
  1827.  
  1828. -	LOGIN_CONF_NAME = "conf/login_athena.conf";
  1829. -	LAN_CONF_NAME = "conf/subnet_athena.conf";
  1830. -	MSG_CONF_NAME_EN = "conf/msg_conf/login_msg.conf";
  1831. +	login_config_read(login_config.loginconf_name);
  1832. +	msg_config_read(login_config.msgconf_name);
  1833. +	login_lan_config_read(login_config.lanconf_name);
  1834. +	//end config
  1835.  
  1836. -	cli_get_options(argc,argv);
  1837. -
  1838. -	msg_config_read(MSG_CONF_NAME_EN);
  1839. -	login_config_read(LOGIN_CONF_NAME);
  1840. -	login_lan_config_read(LAN_CONF_NAME);
  1841. -
  1842.  	rnd_init();
  1843.  
  1844. -	for( i = 0; i < ARRAYLENGTH(server); ++i )
  1845. -		chrif_server_init(i);
  1846. +	do_init_loginchrif();
  1847.  
  1848.  	// initialize logging
  1849.  	if( login_config.log_login )
  1850. @@ -1911,12 +754,6 @@
  1851.  	add_timer_func_list(online_data_cleanup, "online_data_cleanup");
  1852.  	add_timer_interval(gettick() + 600*1000, online_data_cleanup, 0, 0, 600*1000);
  1853.  
  1854. -	// add timer to detect ip address change and perform update
  1855. -	if (login_config.ip_sync_interval) {
  1856. -		add_timer_func_list(sync_ip_addresses, "sync_ip_addresses");
  1857. -		add_timer_interval(gettick() + login_config.ip_sync_interval, sync_ip_addresses, 0, 0, login_config.ip_sync_interval);
  1858. -	}
  1859. -
  1860.  	// Account database init
  1861.  	accounts = get_account_engine();
  1862.  	if( accounts == NULL ) {
  1863. @@ -1941,14 +778,11 @@
  1864.  		runflag = LOGINSERVER_ST_RUNNING;
  1865.  	}
  1866.  
  1867. +	do_init_logincnslif();
  1868. +
  1869.  	ShowStatus("The login-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %u).\n\n", login_config.login_port);
  1870.  	login_log(0, "login server", 100, "login server started");
  1871.  
  1872. -	if( login_config.console ) {
  1873. -		add_timer_func_list(parse_console_timer, "parse_console_timer");
  1874. -		add_timer_interval(gettick()+1000, parse_console_timer, 0, 0, 1000); //start in 1s each 1sec
  1875. -	}
  1876. -
  1877.  	return 0;
  1878.  }
  1879.  
  1880. @@ -1961,21 +795,3 @@
  1881.  void login_do_final_msg(void){
  1882.  	_do_final_msg(LOGIN_MAX_MSG,msg_table);
  1883.  }
  1884. -
  1885. -/*======================================================
  1886. - * Login-Server help option info
  1887. - *------------------------------------------------------*/
  1888. -void display_helpscreen(bool do_exit)
  1889. -{
  1890. -	ShowInfo("Usage: %s [options]\n", SERVER_NAME);
  1891. -	ShowInfo("\n");
  1892. -	ShowInfo("Options:\n");
  1893. -	ShowInfo("  -?, -h [--help]\t\tDisplays this help screen.\n");
  1894. -	ShowInfo("  -v [--version]\t\tDisplays the server's version.\n");
  1895. -	ShowInfo("  --run-once\t\t\tCloses server after loading (testing).\n");
  1896. -	ShowInfo("  --login-config <file>\t\tAlternative login-server configuration.\n");
  1897. -	ShowInfo("  --lan-config <file>\t\tAlternative lag configuration.\n");
  1898. -	ShowInfo("  --msg-config <file>\t\tAlternative message configuration.\n");
  1899. -	if( do_exit )
  1900. -		exit(EXIT_SUCCESS);
  1901. -}
  1902. Index: src/login/account_sql.c
  1903. ===================================================================
  1904. --- src/login/account_sql.c	(revision 17367)
  1905. +++ src/login/account_sql.c	(working copy)
  1906. @@ -1,689 +0,0 @@
  1907. -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  1908. -// For more information, see LICENCE in the main folder
  1909. -
  1910. -#include "../common/malloc.h"
  1911. -#include "../common/mmo.h"
  1912. -#include "../common/showmsg.h"
  1913. -#include "../common/sql.h"
  1914. -#include "../common/strlib.h"
  1915. -#include "../common/timer.h"
  1916. -#include "account.h"
  1917. -#include <stdlib.h>
  1918. -#include <string.h>
  1919. -
  1920. -/// global defines
  1921. -#define ACCOUNT_SQL_DB_VERSION 20110114
  1922. -
  1923. -/// internal structure
  1924. -typedef struct AccountDB_SQL
  1925. -{
  1926. -	AccountDB vtable;    // public interface
  1927. -
  1928. -	Sql* accounts;       // SQL accounts storage
  1929. -
  1930. -	// global sql settings
  1931. -	char   global_db_hostname[32];
  1932. -	uint16 global_db_port;
  1933. -	char   global_db_username[32];
  1934. -	char   global_db_password[32];
  1935. -	char   global_db_database[32];
  1936. -	char   global_codepage[32];
  1937. -	// local sql settings
  1938. -	char   db_hostname[32];
  1939. -	uint16 db_port;
  1940. -	char   db_username[32];
  1941. -	char   db_password[32];
  1942. -	char   db_database[32];
  1943. -	char   codepage[32];
  1944. -	// other settings
  1945. -	bool case_sensitive;
  1946. -	char account_db[32];
  1947. -	char accreg_db[32];
  1948. -
  1949. -} AccountDB_SQL;
  1950. -
  1951. -/// internal structure
  1952. -typedef struct AccountDBIterator_SQL
  1953. -{
  1954. -	AccountDBIterator vtable;    // public interface
  1955. -
  1956. -	AccountDB_SQL* db;
  1957. -	int last_account_id;
  1958. -} AccountDBIterator_SQL;
  1959. -
  1960. -/// internal functions
  1961. -static bool account_db_sql_init(AccountDB* self);
  1962. -static void account_db_sql_destroy(AccountDB* self);
  1963. -static bool account_db_sql_get_property(AccountDB* self, const char* key, char* buf, size_t buflen);
  1964. -static bool account_db_sql_set_property(AccountDB* self, const char* option, const char* value);
  1965. -static bool account_db_sql_create(AccountDB* self, struct mmo_account* acc);
  1966. -static bool account_db_sql_remove(AccountDB* self, const int account_id);
  1967. -static bool account_db_sql_save(AccountDB* self, const struct mmo_account* acc);
  1968. -static bool account_db_sql_load_num(AccountDB* self, struct mmo_account* acc, const int account_id);
  1969. -static bool account_db_sql_load_str(AccountDB* self, struct mmo_account* acc, const char* userid);
  1970. -static AccountDBIterator* account_db_sql_iterator(AccountDB* self);
  1971. -static void account_db_sql_iter_destroy(AccountDBIterator* self);
  1972. -static bool account_db_sql_iter_next(AccountDBIterator* self, struct mmo_account* acc);
  1973. -
  1974. -static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int account_id);
  1975. -static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, bool is_new);
  1976. -
  1977. -/// public constructor
  1978. -AccountDB* account_db_sql(void)
  1979. -{
  1980. -	AccountDB_SQL* db = (AccountDB_SQL*)aCalloc(1, sizeof(AccountDB_SQL));
  1981. -
  1982. -	// set up the vtable
  1983. -	db->vtable.init         = &account_db_sql_init;
  1984. -	db->vtable.destroy      = &account_db_sql_destroy;
  1985. -	db->vtable.get_property = &account_db_sql_get_property;
  1986. -	db->vtable.set_property = &account_db_sql_set_property;
  1987. -	db->vtable.save         = &account_db_sql_save;
  1988. -	db->vtable.create       = &account_db_sql_create;
  1989. -	db->vtable.remove       = &account_db_sql_remove;
  1990. -	db->vtable.load_num     = &account_db_sql_load_num;
  1991. -	db->vtable.load_str     = &account_db_sql_load_str;
  1992. -	db->vtable.iterator     = &account_db_sql_iterator;
  1993. -
  1994. -	// initialize to default values
  1995. -	db->accounts = NULL;
  1996. -	// global sql settings
  1997. -	safestrncpy(db->global_db_hostname, "127.0.0.1", sizeof(db->global_db_hostname));
  1998. -	db->global_db_port = 3306;
  1999. -	safestrncpy(db->global_db_username, "ragnarok", sizeof(db->global_db_username));
  2000. -	safestrncpy(db->global_db_password, "ragnarok", sizeof(db->global_db_password));
  2001. -	safestrncpy(db->global_db_database, "ragnarok", sizeof(db->global_db_database));
  2002. -	safestrncpy(db->global_codepage, "", sizeof(db->global_codepage));
  2003. -	// local sql settings
  2004. -	safestrncpy(db->db_hostname, "", sizeof(db->db_hostname));
  2005. -	db->db_port = 3306;
  2006. -	safestrncpy(db->db_username, "", sizeof(db->db_username));
  2007. -	safestrncpy(db->db_password, "", sizeof(db->db_password));
  2008. -	safestrncpy(db->db_database, "", sizeof(db->db_database));
  2009. -	safestrncpy(db->codepage, "", sizeof(db->codepage));
  2010. -	// other settings
  2011. -	db->case_sensitive = false;
  2012. -	safestrncpy(db->account_db, "login", sizeof(db->account_db));
  2013. -	safestrncpy(db->accreg_db, "global_reg_value", sizeof(db->accreg_db));
  2014. -
  2015. -	return &db->vtable;
  2016. -}
  2017. -
  2018. -
  2019. -/* ------------------------------------------------------------------------- */
  2020. -
  2021. -
  2022. -/// establishes database connection
  2023. -static bool account_db_sql_init(AccountDB* self)
  2024. -{
  2025. -	AccountDB_SQL* db = (AccountDB_SQL*)self;
  2026. -	Sql* sql_handle;
  2027. -	const char* username;
  2028. -	const char* password;
  2029. -	const char* hostname;
  2030. -	uint16      port;
  2031. -	const char* database;
  2032. -	const char* codepage;
  2033. -
  2034. -	db->accounts = Sql_Malloc();
  2035. -	sql_handle = db->accounts;
  2036. -
  2037. -	if( db->db_hostname[0] != '\0' )
  2038. -	{// local settings
  2039. -		username = db->db_username;
  2040. -		password = db->db_password;
  2041. -		hostname = db->db_hostname;
  2042. -		port     = db->db_port;
  2043. -		database = db->db_database;
  2044. -		codepage = db->codepage;
  2045. -	}
  2046. -	else
  2047. -	{// global settings
  2048. -		username = db->global_db_username;
  2049. -		password = db->global_db_password;
  2050. -		hostname = db->global_db_hostname;
  2051. -		port     = db->global_db_port;
  2052. -		database = db->global_db_database;
  2053. -		codepage = db->global_codepage;
  2054. -	}
  2055. -
  2056. -	if( SQL_ERROR == Sql_Connect(sql_handle, username, password, hostname, port, database) )
  2057. -	{
  2058. -		Sql_ShowDebug(sql_handle);
  2059. -		Sql_Free(db->accounts);
  2060. -		db->accounts = NULL;
  2061. -		return false;
  2062. -	}
  2063. -
  2064. -	if( codepage[0] != '\0' && SQL_ERROR == Sql_SetEncoding(sql_handle, codepage) )
  2065. -		Sql_ShowDebug(sql_handle);
  2066. -
  2067. -	return true;
  2068. -}
  2069. -
  2070. -/// disconnects from database
  2071. -static void account_db_sql_destroy(AccountDB* self)
  2072. -{
  2073. -	AccountDB_SQL* db = (AccountDB_SQL*)self;
  2074. -
  2075. -	Sql_Free(db->accounts);
  2076. -	db->accounts = NULL;
  2077. -	aFree(db);
  2078. -}
  2079. -
  2080. -/// Gets a property from this database.
  2081. -static bool account_db_sql_get_property(AccountDB* self, const char* key, char* buf, size_t buflen)
  2082. -{
  2083. -	AccountDB_SQL* db = (AccountDB_SQL*)self;
  2084. -	const char* signature;
  2085. -
  2086. -	signature = "engine.";
  2087. -	if( strncmpi(key, signature, strlen(signature)) == 0 )
  2088. -	{
  2089. -		key += strlen(signature);
  2090. -		if( strcmpi(key, "name") == 0 )
  2091. -			safesnprintf(buf, buflen, "sql");
  2092. -		else
  2093. -		if( strcmpi(key, "version") == 0 )
  2094. -			safesnprintf(buf, buflen, "%d", ACCOUNT_SQL_DB_VERSION);
  2095. -		else
  2096. -		if( strcmpi(key, "comment") == 0 )
  2097. -			safesnprintf(buf, buflen, "SQL Account Database");
  2098. -		else
  2099. -			return false;// not found
  2100. -		return true;
  2101. -	}
  2102. -
  2103. -	signature = "sql.";
  2104. -	if( strncmpi(key, signature, strlen(signature)) == 0 )
  2105. -	{
  2106. -		key += strlen(signature);
  2107. -		if( strcmpi(key, "db_hostname") == 0 )
  2108. -			safesnprintf(buf, buflen, "%s", db->global_db_hostname);
  2109. -		else
  2110. -		if( strcmpi(key, "db_port") == 0 )
  2111. -			safesnprintf(buf, buflen, "%d", db->global_db_port);
  2112. -		else
  2113. -		if( strcmpi(key, "db_username") == 0 )
  2114. -			safesnprintf(buf, buflen, "%s", db->global_db_username);
  2115. -		else
  2116. -		if(	strcmpi(key, "db_password") == 0 )
  2117. -			safesnprintf(buf, buflen, "%s", db->global_db_password);
  2118. -		else
  2119. -		if( strcmpi(key, "db_database") == 0 )
  2120. -			safesnprintf(buf, buflen, "%s", db->global_db_database);
  2121. -		else
  2122. -		if( strcmpi(key, "codepage") == 0 )
  2123. -			safesnprintf(buf, buflen, "%s", db->global_codepage);
  2124. -		else
  2125. -			return false;// not found
  2126. -		return true;
  2127. -	}
  2128. -
  2129. -	signature = "account.sql.";
  2130. -	if( strncmpi(key, signature, strlen(signature)) == 0 )
  2131. -	{
  2132. -		key += strlen(signature);
  2133. -		if( strcmpi(key, "db_hostname") == 0 )
  2134. -			safesnprintf(buf, buflen, "%s", db->db_hostname);
  2135. -		else
  2136. -		if( strcmpi(key, "db_port") == 0 )
  2137. -			safesnprintf(buf, buflen, "%d", db->db_port);
  2138. -		else
  2139. -		if( strcmpi(key, "db_username") == 0 )
  2140. -			safesnprintf(buf, buflen, "%s", db->db_username);
  2141. -		else
  2142. -		if(	strcmpi(key, "db_password") == 0 )
  2143. -			safesnprintf(buf, buflen, "%s", db->db_password);
  2144. -		else
  2145. -		if( strcmpi(key, "db_database") == 0 )
  2146. -			safesnprintf(buf, buflen, "%s", db->db_database);
  2147. -		else
  2148. -		if( strcmpi(key, "codepage") == 0 )
  2149. -			safesnprintf(buf, buflen, "%s", db->codepage);
  2150. -		else
  2151. -		if( strcmpi(key, "case_sensitive") == 0 )
  2152. -			safesnprintf(buf, buflen, "%d", (db->case_sensitive ? 1 : 0));
  2153. -		else
  2154. -		if( strcmpi(key, "account_db") == 0 )
  2155. -			safesnprintf(buf, buflen, "%s", db->account_db);
  2156. -		else
  2157. -		if( strcmpi(key, "accreg_db") == 0 )
  2158. -			safesnprintf(buf, buflen, "%s", db->accreg_db);
  2159. -		else
  2160. -			return false;// not found
  2161. -		return true;
  2162. -	}
  2163. -
  2164. -	return false;// not found
  2165. -}
  2166. -
  2167. -/// if the option is supported, adjusts the internal state
  2168. -static bool account_db_sql_set_property(AccountDB* self, const char* key, const char* value)
  2169. -{
  2170. -	AccountDB_SQL* db = (AccountDB_SQL*)self;
  2171. -	const char* signature;
  2172. -
  2173. -
  2174. -	signature = "sql.";
  2175. -	if( strncmp(key, signature, strlen(signature)) == 0 )
  2176. -	{
  2177. -		key += strlen(signature);
  2178. -		if( strcmpi(key, "db_hostname") == 0 )
  2179. -			safestrncpy(db->global_db_hostname, value, sizeof(db->global_db_hostname));
  2180. -		else
  2181. -		if( strcmpi(key, "db_port") == 0 )
  2182. -			db->global_db_port = (uint16)strtoul(value, NULL, 10);
  2183. -		else
  2184. -		if( strcmpi(key, "db_username") == 0 )
  2185. -			safestrncpy(db->global_db_username, value, sizeof(db->global_db_username));
  2186. -		else
  2187. -		if( strcmpi(key, "db_password") == 0 )
  2188. -			safestrncpy(db->global_db_password, value, sizeof(db->global_db_password));
  2189. -		else
  2190. -		if( strcmpi(key, "db_database") == 0 )
  2191. -			safestrncpy(db->global_db_database, value, sizeof(db->global_db_database));
  2192. -		else
  2193. -		if( strcmpi(key, "codepage") == 0 )
  2194. -			safestrncpy(db->global_codepage, value, sizeof(db->global_codepage));
  2195. -		else
  2196. -			return false;// not found
  2197. -		return true;
  2198. -	}
  2199. -
  2200. -	signature = "account.sql.";
  2201. -	if( strncmp(key, signature, strlen(signature)) == 0 )
  2202. -	{
  2203. -		key += strlen(signature);
  2204. -		if( strcmpi(key, "db_hostname") == 0 )
  2205. -			safestrncpy(db->db_hostname, value, sizeof(db->db_hostname));
  2206. -		else
  2207. -		if( strcmpi(key, "db_port") == 0 )
  2208. -			db->db_port = (uint16)strtoul(value, NULL, 10);
  2209. -		else
  2210. -		if( strcmpi(key, "db_username") == 0 )
  2211. -			safestrncpy(db->db_username, value, sizeof(db->db_username));
  2212. -		else
  2213. -		if( strcmpi(key, "db_password") == 0 )
  2214. -			safestrncpy(db->db_password, value, sizeof(db->db_password));
  2215. -		else
  2216. -		if( strcmpi(key, "db_database") == 0 )
  2217. -			safestrncpy(db->db_database, value, sizeof(db->db_database));
  2218. -		else
  2219. -		if( strcmpi(key, "codepage") == 0 )
  2220. -			safestrncpy(db->codepage, value, sizeof(db->codepage));
  2221. -		else
  2222. -		if( strcmpi(key, "case_sensitive") == 0 )
  2223. -			db->case_sensitive = config_switch(value);
  2224. -		else
  2225. -		if( strcmpi(key, "account_db") == 0 )
  2226. -			safestrncpy(db->account_db, value, sizeof(db->account_db));
  2227. -		else
  2228. -		if( strcmpi(key, "accreg_db") == 0 )
  2229. -			safestrncpy(db->accreg_db, value, sizeof(db->accreg_db));
  2230. -		else
  2231. -			return false;// not found
  2232. -		return true;
  2233. -	}
  2234. -
  2235. -	return false;// not found
  2236. -}
  2237. -
  2238. -/// create a new account entry
  2239. -/// If acc->account_id is -1, the account id will be auto-generated,
  2240. -/// and its value will be written to acc->account_id if everything succeeds.
  2241. -static bool account_db_sql_create(AccountDB* self, struct mmo_account* acc)
  2242. -{
  2243. -	AccountDB_SQL* db = (AccountDB_SQL*)self;
  2244. -	Sql* sql_handle = db->accounts;
  2245. -
  2246. -	// decide on the account id to assign
  2247. -	int account_id;
  2248. -	if( acc->account_id != -1 )
  2249. -	{// caller specifies it manually
  2250. -		account_id = acc->account_id;
  2251. -	}
  2252. -	else
  2253. -	{// ask the database
  2254. -		char* data;
  2255. -		size_t len;
  2256. -
  2257. -		if( SQL_SUCCESS != Sql_Query(sql_handle, "SELECT MAX(`account_id`)+1 FROM `%s`", db->account_db) )
  2258. -		{
  2259. -			Sql_ShowDebug(sql_handle);
  2260. -			return false;
  2261. -		}
  2262. -		if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
  2263. -		{
  2264. -			Sql_ShowDebug(sql_handle);
  2265. -			Sql_FreeResult(sql_handle);
  2266. -			return false;
  2267. -		}
  2268. -
  2269. -		Sql_GetData(sql_handle, 0, &data, &len);
  2270. -		account_id = ( data != NULL ) ? atoi(data) : 0;
  2271. -		Sql_FreeResult(sql_handle);
  2272. -
  2273. -		if( account_id < START_ACCOUNT_NUM )
  2274. -			account_id = START_ACCOUNT_NUM;
  2275. -
  2276. -	}
  2277. -
  2278. -	// zero value is prohibited
  2279. -	if( account_id == 0 )
  2280. -		return false;
  2281. -
  2282. -	// absolute maximum
  2283. -	if( account_id > END_ACCOUNT_NUM )
  2284. -		return false;
  2285. -
  2286. -	// insert the data into the database
  2287. -	acc->account_id = account_id;
  2288. -	return mmo_auth_tosql(db, acc, true);
  2289. -}
  2290. -
  2291. -/// delete an existing account entry + its regs
  2292. -static bool account_db_sql_remove(AccountDB* self, const int account_id)
  2293. -{
  2294. -	AccountDB_SQL* db = (AccountDB_SQL*)self;
  2295. -	Sql* sql_handle = db->accounts;
  2296. -	bool result = false;
  2297. -
  2298. -	if( SQL_SUCCESS != Sql_QueryStr(sql_handle, "START TRANSACTION")
  2299. -	||  SQL_SUCCESS != Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->account_db, account_id)
  2300. -	||  SQL_SUCCESS != Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->accreg_db, account_id) )
  2301. -		Sql_ShowDebug(sql_handle);
  2302. -	else
  2303. -		result = true;
  2304. -
  2305. -	result &= ( SQL_SUCCESS == Sql_QueryStr(sql_handle, (result == true) ? "COMMIT" : "ROLLBACK") );
  2306. -
  2307. -	return result;
  2308. -}
  2309. -
  2310. -/// update an existing account with the provided new data (both account and regs)
  2311. -static bool account_db_sql_save(AccountDB* self, const struct mmo_account* acc)
  2312. -{
  2313. -	AccountDB_SQL* db = (AccountDB_SQL*)self;
  2314. -	return mmo_auth_tosql(db, acc, false);
  2315. -}
  2316. -
  2317. -/// retrieve data from db and store it in the provided data structure
  2318. -static bool account_db_sql_load_num(AccountDB* self, struct mmo_account* acc, const int account_id)
  2319. -{
  2320. -	AccountDB_SQL* db = (AccountDB_SQL*)self;
  2321. -	return mmo_auth_fromsql(db, acc, account_id);
  2322. -}
  2323. -
  2324. -/// retrieve data from db and store it in the provided data structure
  2325. -static bool account_db_sql_load_str(AccountDB* self, struct mmo_account* acc, const char* userid)
  2326. -{
  2327. -	AccountDB_SQL* db = (AccountDB_SQL*)self;
  2328. -	Sql* sql_handle = db->accounts;
  2329. -	char esc_userid[2*NAME_LENGTH+1];
  2330. -	int account_id;
  2331. -	char* data;
  2332. -
  2333. -	Sql_EscapeString(sql_handle, esc_userid, userid);
  2334. -
  2335. -	// get the list of account IDs for this user ID
  2336. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id` FROM `%s` WHERE `userid`= %s '%s'",
  2337. -		db->account_db, (db->case_sensitive ? "BINARY" : ""), esc_userid) )
  2338. -	{
  2339. -		Sql_ShowDebug(sql_handle);
  2340. -		return false;
  2341. -	}
  2342. -
  2343. -	if( Sql_NumRows(sql_handle) > 1 )
  2344. -	{// serious problem - duplicit account
  2345. -		ShowError("account_db_sql_load_str: multiple accounts found when retrieving data for account '%s'!\n", userid);
  2346. -		Sql_FreeResult(sql_handle);
  2347. -		return false;
  2348. -	}
  2349. -
  2350. -	if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
  2351. -	{// no such entry
  2352. -		Sql_FreeResult(sql_handle);
  2353. -		return false;
  2354. -	}
  2355. -
  2356. -	Sql_GetData(sql_handle, 0, &data, NULL);
  2357. -	account_id = atoi(data);
  2358. -
  2359. -	return account_db_sql_load_num(self, acc, account_id);
  2360. -}
  2361. -
  2362. -
  2363. -/// Returns a new forward iterator.
  2364. -static AccountDBIterator* account_db_sql_iterator(AccountDB* self)
  2365. -{
  2366. -	AccountDB_SQL* db = (AccountDB_SQL*)self;
  2367. -	AccountDBIterator_SQL* iter = (AccountDBIterator_SQL*)aCalloc(1, sizeof(AccountDBIterator_SQL));
  2368. -
  2369. -	// set up the vtable
  2370. -	iter->vtable.destroy = &account_db_sql_iter_destroy;
  2371. -	iter->vtable.next    = &account_db_sql_iter_next;
  2372. -
  2373. -	// fill data
  2374. -	iter->db = db;
  2375. -	iter->last_account_id = -1;
  2376. -
  2377. -	return &iter->vtable;
  2378. -}
  2379. -
  2380. -
  2381. -/// Destroys this iterator, releasing all allocated memory (including itself).
  2382. -static void account_db_sql_iter_destroy(AccountDBIterator* self)
  2383. -{
  2384. -	AccountDBIterator_SQL* iter = (AccountDBIterator_SQL*)self;
  2385. -	aFree(iter);
  2386. -}
  2387. -
  2388. -
  2389. -/// Fetches the next account in the database.
  2390. -static bool account_db_sql_iter_next(AccountDBIterator* self, struct mmo_account* acc)
  2391. -{
  2392. -	AccountDBIterator_SQL* iter = (AccountDBIterator_SQL*)self;
  2393. -	AccountDB_SQL* db = (AccountDB_SQL*)iter->db;
  2394. -	Sql* sql_handle = db->accounts;
  2395. -	char* data;
  2396. -
  2397. -	// get next account ID
  2398. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id` FROM `%s` WHERE `account_id` > '%d' ORDER BY `account_id` ASC LIMIT 1",
  2399. -		db->account_db, iter->last_account_id) )
  2400. -	{
  2401. -		Sql_ShowDebug(sql_handle);
  2402. -		return false;
  2403. -	}
  2404. -
  2405. -	if( SQL_SUCCESS == Sql_NextRow(sql_handle) &&
  2406. -		SQL_SUCCESS == Sql_GetData(sql_handle, 0, &data, NULL) &&
  2407. -		data != NULL )
  2408. -	{// get account data
  2409. -		int account_id;
  2410. -		account_id = atoi(data);
  2411. -		if( mmo_auth_fromsql(db, acc, account_id) )
  2412. -		{
  2413. -			iter->last_account_id = account_id;
  2414. -			Sql_FreeResult(sql_handle);
  2415. -			return true;
  2416. -		}
  2417. -	}
  2418. -	Sql_FreeResult(sql_handle);
  2419. -	return false;
  2420. -}
  2421. -
  2422. -
  2423. -static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int account_id)
  2424. -{
  2425. -	Sql* sql_handle = db->accounts;
  2426. -	char* data;
  2427. -	int i = 0;
  2428. -
  2429. -	// retrieve login entry for the specified account
  2430. -	if( SQL_ERROR == Sql_Query(sql_handle,
  2431. -	    "SELECT `account_id`,`userid`,`user_pass`,`sex`,`email`,`group_id`,`state`,`unban_time`,`expiration_time`,`logincount`,`lastlogin`,`last_ip`,`birthdate`,`character_slots`,`pincode`, `pincode_change` FROM `%s` WHERE `account_id` = %d",
  2432. -		db->account_db, account_id )
  2433. -	) {
  2434. -		Sql_ShowDebug(sql_handle);
  2435. -		return false;
  2436. -	}
  2437. -
  2438. -	if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
  2439. -	{// no such entry
  2440. -		Sql_FreeResult(sql_handle);
  2441. -		return false;
  2442. -	}
  2443. -
  2444. -	Sql_GetData(sql_handle,  0, &data, NULL); acc->account_id = atoi(data);
  2445. -	Sql_GetData(sql_handle,  1, &data, NULL); safestrncpy(acc->userid, data, sizeof(acc->userid));
  2446. -	Sql_GetData(sql_handle,  2, &data, NULL); safestrncpy(acc->pass, data, sizeof(acc->pass));
  2447. -	Sql_GetData(sql_handle,  3, &data, NULL); acc->sex = data[0];
  2448. -	Sql_GetData(sql_handle,  4, &data, NULL); safestrncpy(acc->email, data, sizeof(acc->email));
  2449. -	Sql_GetData(sql_handle,  5, &data, NULL); acc->group_id = atoi(data);
  2450. -	Sql_GetData(sql_handle,  6, &data, NULL); acc->state = strtoul(data, NULL, 10);
  2451. -	Sql_GetData(sql_handle,  7, &data, NULL); acc->unban_time = atol(data);
  2452. -	Sql_GetData(sql_handle,  8, &data, NULL); acc->expiration_time = atol(data);
  2453. -	Sql_GetData(sql_handle,  9, &data, NULL); acc->logincount = strtoul(data, NULL, 10);
  2454. -	Sql_GetData(sql_handle, 10, &data, NULL); safestrncpy(acc->lastlogin, data, sizeof(acc->lastlogin));
  2455. -	Sql_GetData(sql_handle, 11, &data, NULL); safestrncpy(acc->last_ip, data, sizeof(acc->last_ip));
  2456. -	Sql_GetData(sql_handle, 12, &data, NULL); safestrncpy(acc->birthdate, data, sizeof(acc->birthdate));
  2457. -	Sql_GetData(sql_handle, 13, &data, NULL); acc->char_slots = atoi(data);
  2458. -	Sql_GetData(sql_handle, 14, &data, NULL); safestrncpy(acc->pincode, data, sizeof(acc->pincode));
  2459. -	Sql_GetData(sql_handle, 15, &data, NULL); acc->pincode_change = atol(data);
  2460. -
  2461. -	Sql_FreeResult(sql_handle);
  2462. -
  2463. -
  2464. -	// retrieve account regs for the specified user
  2465. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `str`,`value` FROM `%s` WHERE `type`='1' AND `account_id`='%d'", db->accreg_db, acc->account_id) )
  2466. -	{
  2467. -		Sql_ShowDebug(sql_handle);
  2468. -		return false;
  2469. -	}
  2470. -
  2471. -	acc->account_reg2_num = (int)Sql_NumRows(sql_handle);
  2472. -
  2473. -	while( SQL_SUCCESS == Sql_NextRow(sql_handle) )
  2474. -	{
  2475. -		char* data;
  2476. -		Sql_GetData(sql_handle, 0, &data, NULL); safestrncpy(acc->account_reg2[i].str, data, sizeof(acc->account_reg2[i].str));
  2477. -		Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(acc->account_reg2[i].value, data, sizeof(acc->account_reg2[i].value));
  2478. -		++i;
  2479. -	}
  2480. -	Sql_FreeResult(sql_handle);
  2481. -
  2482. -	if( i != acc->account_reg2_num )
  2483. -		return false;
  2484. -
  2485. -	return true;
  2486. -}
  2487. -
  2488. -static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, bool is_new)
  2489. -{
  2490. -	Sql* sql_handle = db->accounts;
  2491. -	SqlStmt* stmt = SqlStmt_Malloc(sql_handle);
  2492. -	bool result = false;
  2493. -	int i;
  2494. -
  2495. -	// try
  2496. -	do
  2497. -	{
  2498. -
  2499. -	if( SQL_SUCCESS != Sql_QueryStr(sql_handle, "START TRANSACTION") )
  2500. -	{
  2501. -		Sql_ShowDebug(sql_handle);
  2502. -		break;
  2503. -	}
  2504. -
  2505. -	if( is_new )
  2506. -	{// insert into account table
  2507. -		if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
  2508. -			"INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`, `character_slots`, `pincode`, `pincode_change`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
  2509. -			db->account_db)
  2510. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  0, SQLDT_INT,    (void*)&acc->account_id,      sizeof(acc->account_id))
  2511. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  1, SQLDT_STRING, (void*)acc->userid,           strlen(acc->userid))
  2512. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  2, SQLDT_STRING, (void*)acc->pass,             strlen(acc->pass))
  2513. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  3, SQLDT_ENUM,   (void*)&acc->sex,             sizeof(acc->sex))
  2514. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  4, SQLDT_STRING, (void*)&acc->email,           strlen(acc->email))
  2515. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  5, SQLDT_INT,    (void*)&acc->group_id,        sizeof(acc->group_id))
  2516. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  6, SQLDT_UINT,   (void*)&acc->state,           sizeof(acc->state))
  2517. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  7, SQLDT_LONG,   (void*)&acc->unban_time,      sizeof(acc->unban_time))
  2518. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  8, SQLDT_INT,    (void*)&acc->expiration_time, sizeof(acc->expiration_time))
  2519. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  9, SQLDT_UINT,   (void*)&acc->logincount,      sizeof(acc->logincount))
  2520. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 10, SQLDT_STRING, (void*)&acc->lastlogin,       strlen(acc->lastlogin))
  2521. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 11, SQLDT_STRING, (void*)&acc->last_ip,         strlen(acc->last_ip))
  2522. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 12, SQLDT_STRING, (void*)&acc->birthdate,       strlen(acc->birthdate))
  2523. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 13, SQLDT_UCHAR,  (void*)&acc->char_slots,      sizeof(acc->char_slots))
  2524. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 14, SQLDT_STRING, (void*)&acc->pincode,         strlen(acc->pincode))
  2525. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 15, SQLDT_LONG,   (void*)&acc->pincode_change,  sizeof(acc->pincode_change))
  2526. -		||  SQL_SUCCESS != SqlStmt_Execute(stmt)
  2527. -		) {
  2528. -			SqlStmt_ShowDebug(stmt);
  2529. -			break;
  2530. -		}
  2531. -	}
  2532. -	else
  2533. -	{// update account table
  2534. -		if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`group_id`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=?,`character_slots`=?,`pincode`=?, `pincode_change`=? WHERE `account_id` = '%d'", db->account_db, acc->account_id)
  2535. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  0, SQLDT_STRING, (void*)acc->userid,           strlen(acc->userid))
  2536. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  1, SQLDT_STRING, (void*)acc->pass,             strlen(acc->pass))
  2537. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  2, SQLDT_ENUM,   (void*)&acc->sex,             sizeof(acc->sex))
  2538. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  3, SQLDT_STRING, (void*)acc->email,            strlen(acc->email))
  2539. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  4, SQLDT_INT,    (void*)&acc->group_id,        sizeof(acc->group_id))
  2540. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  5, SQLDT_UINT,   (void*)&acc->state,           sizeof(acc->state))
  2541. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  6, SQLDT_LONG,   (void*)&acc->unban_time,      sizeof(acc->unban_time))
  2542. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  7, SQLDT_LONG,   (void*)&acc->expiration_time, sizeof(acc->expiration_time))
  2543. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  8, SQLDT_UINT,   (void*)&acc->logincount,      sizeof(acc->logincount))
  2544. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  9, SQLDT_STRING, (void*)&acc->lastlogin,       strlen(acc->lastlogin))
  2545. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 10, SQLDT_STRING, (void*)&acc->last_ip,         strlen(acc->last_ip))
  2546. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 11, SQLDT_STRING, (void*)&acc->birthdate,       strlen(acc->birthdate))
  2547. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 12, SQLDT_UCHAR,  (void*)&acc->char_slots,      sizeof(acc->char_slots))
  2548. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 13, SQLDT_STRING, (void*)&acc->pincode,         strlen(acc->pincode))
  2549. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 14, SQLDT_LONG,   (void*)&acc->pincode_change,  sizeof(acc->pincode_change))
  2550. -		||  SQL_SUCCESS != SqlStmt_Execute(stmt)
  2551. -		) {
  2552. -			SqlStmt_ShowDebug(stmt);
  2553. -			break;
  2554. -		}
  2555. -	}
  2556. -
  2557. -	// remove old account regs
  2558. -	if( SQL_SUCCESS != Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`='1' AND `account_id`='%d'", db->accreg_db, acc->account_id) )
  2559. -	{
  2560. -		Sql_ShowDebug(sql_handle);
  2561. -		break;
  2562. -	}
  2563. -	// insert new account regs
  2564. -	if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "INSERT INTO `%s` (`type`, `account_id`, `str`, `value`) VALUES ( 1 , '%d' , ? , ? );",  db->accreg_db, acc->account_id) )
  2565. -	{
  2566. -		SqlStmt_ShowDebug(stmt);
  2567. -		break;
  2568. -	}
  2569. -	for( i = 0; i < acc->account_reg2_num; ++i )
  2570. -	{
  2571. -		if( SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, (void*)acc->account_reg2[i].str, strlen(acc->account_reg2[i].str))
  2572. -		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void*)acc->account_reg2[i].value, strlen(acc->account_reg2[i].value))
  2573. -		||  SQL_SUCCESS != SqlStmt_Execute(stmt)
  2574. -		) {
  2575. -			SqlStmt_ShowDebug(stmt);
  2576. -			break;
  2577. -		}
  2578. -	}
  2579. -	if( i < acc->account_reg2_num )
  2580. -	{
  2581. -		result = false;
  2582. -		break;
  2583. -	}
  2584. -
  2585. -	// if we got this far, everything was successful
  2586. -	result = true;
  2587. -
  2588. -	} while(0);
  2589. -	// finally
  2590. -
  2591. -	result &= ( SQL_SUCCESS == Sql_QueryStr(sql_handle, (result == true) ? "COMMIT" : "ROLLBACK") );
  2592. -	SqlStmt_Free(stmt);
  2593. -
  2594. -	return result;
  2595. -}
  2596. Index: src/login/login.h
  2597. ===================================================================
  2598. --- src/login/login.h	(revision 17367)
  2599. +++ src/login/login.h	(working copy)
  2600. @@ -6,6 +6,7 @@
  2601.  
  2602.  #include "../common/mmo.h" // NAME_LENGTH,SEX_*
  2603.  #include "../common/core.h" // CORE_ST_LAST
  2604. +#include "account.h"
  2605.  
  2606.  enum E_LOGINSERVER_ST
  2607.  {
  2608. @@ -40,8 +41,8 @@
  2609.  	int fd;
  2610.  };
  2611.  
  2612. +#define MAX_SERVERS 30
  2613.  struct mmo_char_server {
  2614. -
  2615.  	char name[20];
  2616.  	int fd;
  2617.  	uint32 ip;
  2618. @@ -49,7 +50,7 @@
  2619.  	uint16 users;       // user count on this server
  2620.  	uint16 type;        // 0=normal, 1=maintenance, 2=over 18, 3=paying, 4=P2P
  2621.  	uint16 new_;        // should display as 'new'?
  2622. -};
  2623. +} server[MAX_SERVERS]; // char server data
  2624.  
  2625.  struct client_hash_node {
  2626.  	int group_id;
  2627. @@ -83,10 +84,15 @@
  2628.  	char dnsbl_servs[1024];                         // comma-separated list of dnsbl servers
  2629.  
  2630.  	char account_engine[256];                       // name of the engine to use (defaults to auto, for the first available engine)
  2631. +	int allowed_regs;				//max number of registration
  2632. +	int time_allowed;				//registration intervall in seconds
  2633.  
  2634.  	int client_hash_check;							// flags for checking client md5
  2635.  	struct client_hash_node *client_hash_nodes;		// linked list containg md5 hash for each gm group
  2636. -};
  2637. +	char *loginconf_name;
  2638. +	char *msgconf_name;
  2639. +	char *lanconf_name;
  2640. +} login_config;
  2641.  
  2642.  #define sex_num2str(num) ( (num ==  SEX_FEMALE  ) ? 'F' : (num ==  SEX_MALE  ) ? 'M' : 'S' )
  2643.  #define sex_str2num(str) ( (str == 'F' ) ?  SEX_FEMALE  : (str == 'M' ) ?  SEX_MALE  :  SEX_SERVER  )
  2644. @@ -94,15 +100,51 @@
  2645.  #define msg_config_read(cfgName) login_msg_config_read(cfgName)
  2646.  #define msg_txt(msg_number) login_msg_txt(msg_number)
  2647.  #define do_final_msg() login_do_final_msg()
  2648. -
  2649.  int login_msg_config_read(char *cfgName);
  2650.  const char* login_msg_txt(int msg_number);
  2651.  void login_do_final_msg(void);
  2652.  
  2653. +//-----------------------------------------------------
  2654. +// Online User Database [Wizputer]
  2655. +//-----------------------------------------------------
  2656. +struct online_login_data {
  2657. +	int account_id;
  2658. +	int waiting_disconnect;
  2659. +	int char_server;
  2660. +};
  2661. +DBMap* online_db; // int account_id -> struct online_login_data*
  2662.  
  2663. -#define MAX_SERVERS 30
  2664. -extern struct mmo_char_server server[MAX_SERVERS];
  2665. -extern struct Login_Config login_config;
  2666. +//-----------------------------------------------------
  2667. +// Auth database
  2668. +//-----------------------------------------------------
  2669. +#define AUTH_TIMEOUT 30000
  2670. +struct auth_node {
  2671. +	int account_id;
  2672. +	uint32 login_id1;
  2673. +	uint32 login_id2;
  2674. +	uint32 ip;
  2675. +	char sex;
  2676. +	uint32 version;
  2677. +	uint8 clienttype;
  2678. +};
  2679. +DBMap* auth_db; // int account_id -> struct auth_node*
  2680.  
  2681.  
  2682. +AccountDB* login_get_accounts_db(void);
  2683. +
  2684. +
  2685. +bool check_encrypted(const char* str1, const char* str2, const char* passwd);
  2686. +bool check_password(const char* md5key, int passwdenc, const char* passwd, const char* refpass);
  2687. +
  2688. +int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t data);
  2689. +void remove_online_user(int account_id);
  2690. +struct online_login_data* add_online_user(int char_server, int account_id);
  2691. +int lan_subnetcheck(uint32 ip);
  2692. +
  2693. +int online_db_setoffline(DBKey key, DBData *data, va_list ap);
  2694. +DBData create_online_user(DBKey key, va_list args);
  2695. +
  2696. +int mmo_auth_new(const char* userid, const char* pass, const char sex, const char* last_ip);
  2697. +int mmo_auth(struct login_session_data* sd, bool isServer);
  2698. +
  2699.  #endif /* _LOGIN_H_ */
  2700. Index: src/login/sql/CMakeLists.txt
  2701. ===================================================================
  2702. --- src/login/sql/CMakeLists.txt	(revision 17367)
  2703. +++ src/login/sql/CMakeLists.txt	(working copy)
  2704. @@ -8,13 +8,19 @@
  2705.  	"${SQL_LOGIN_SOURCE_DIR}/account.h"
  2706.  	"${SQL_LOGIN_SOURCE_DIR}/ipban.h"
  2707.  	"${SQL_LOGIN_SOURCE_DIR}/login.h"
  2708. +	"${SQL_LOGIN_SOURCE_DIR}/loginclif.h"
  2709. +	"${SQL_LOGIN_SOURCE_DIR}/loginchrif.h"
  2710. +	"${SQL_LOGIN_SOURCE_DIR}/logincnslif.h"
  2711.  	"${SQL_LOGIN_SOURCE_DIR}/loginlog.h"
  2712.  	)
  2713.  set( SQL_LOGIN_SOURCES
  2714. -	"${SQL_LOGIN_SOURCE_DIR}/account_sql.c"
  2715. -	"${SQL_LOGIN_SOURCE_DIR}/ipban_sql.c"
  2716. +	"${SQL_LOGIN_SOURCE_DIR}/account.c"
  2717. +	"${SQL_LOGIN_SOURCE_DIR}/ipban.c"
  2718.  	"${SQL_LOGIN_SOURCE_DIR}/login.c"
  2719. -	"${SQL_LOGIN_SOURCE_DIR}/loginlog_sql.c"
  2720. +	"${SQL_LOGIN_SOURCE_DIR}/loginclif.c"
  2721. +	"${SQL_LOGIN_SOURCE_DIR}/loginchrif.c"
  2722. +	"${SQL_LOGIN_SOURCE_DIR}/logincnslif.c"
  2723. +	"${SQL_LOGIN_SOURCE_DIR}/loginlog.c"
  2724.  	)
  2725.  set( DEPENDENCIES common_sql )
  2726.  set( LIBRARIES ${GLOBAL_LIBRARIES} )
  2727. Index: src/login/loginlog_sql.c
  2728. ===================================================================
  2729. --- src/login/loginlog_sql.c	(revision 17367)
  2730. +++ src/login/loginlog_sql.c	(working copy)
  2731. @@ -1,184 +0,0 @@
  2732. -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  2733. -// For more information, see LICENCE in the main folder
  2734. -
  2735. -#include "../common/cbasetypes.h"
  2736. -#include "../common/mmo.h"
  2737. -#include "../common/socket.h"
  2738. -#include "../common/sql.h"
  2739. -#include "../common/strlib.h"
  2740. -#include <string.h>
  2741. -#include <stdlib.h> // exit
  2742. -
  2743. -// global sql settings (in ipban_sql.c)
  2744. -static char   global_db_hostname[32] = "127.0.0.1";
  2745. -static uint16 global_db_port = 3306;
  2746. -static char   global_db_username[32] = "ragnarok";
  2747. -static char   global_db_password[32] = "ragnarok";
  2748. -static char   global_db_database[32] = "ragnarok";
  2749. -static char   global_codepage[32] = "";
  2750. -// local sql settings
  2751. -static char   log_db_hostname[32] = "";
  2752. -static uint16 log_db_port = 0;
  2753. -static char   log_db_username[32] = "";
  2754. -static char   log_db_password[32] = "";
  2755. -static char   log_db_database[32] = "";
  2756. -static char   log_codepage[32] = "";
  2757. -static char   log_login_db[256] = "loginlog";
  2758. -
  2759. -static Sql* sql_handle = NULL;
  2760. -static bool enabled = false;
  2761. -
  2762. -
  2763. -// Returns the number of failed login attemps by the ip in the last minutes.
  2764. -unsigned long loginlog_failedattempts(uint32 ip, unsigned int minutes)
  2765. -{
  2766. -	unsigned long failures = 0;
  2767. -
  2768. -	if( !enabled )
  2769. -		return 0;
  2770. -
  2771. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT count(*) FROM `%s` WHERE `ip` = '%s' AND `rcode` = '1' AND `time` > NOW() - INTERVAL %d MINUTE",
  2772. -		log_login_db, ip2str(ip,NULL), minutes) )// how many times failed account? in one ip.
  2773. -		Sql_ShowDebug(sql_handle);
  2774. -
  2775. -	if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
  2776. -	{
  2777. -		char* data;
  2778. -		Sql_GetData(sql_handle, 0, &data, NULL);
  2779. -		failures = strtoul(data, NULL, 10);
  2780. -		Sql_FreeResult(sql_handle);
  2781. -	}
  2782. -	return failures;
  2783. -}
  2784. -
  2785. -
  2786. -/*=============================================
  2787. - * Records an event in the login log
  2788. - *---------------------------------------------*/
  2789. -void login_log(uint32 ip, const char* username, int rcode, const char* message)
  2790. -{
  2791. -	char esc_username[NAME_LENGTH*2+1];
  2792. -	char esc_message[255*2+1];
  2793. -	int retcode;
  2794. -
  2795. -	if( !enabled )
  2796. -		return;
  2797. -
  2798. -	Sql_EscapeStringLen(sql_handle, esc_username, username, strnlen(username, NAME_LENGTH));
  2799. -	Sql_EscapeStringLen(sql_handle, esc_message, message, strnlen(message, 255));
  2800. -
  2801. -	retcode = Sql_Query(sql_handle,
  2802. -		"INSERT INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%s', '%s', '%d', '%s')",
  2803. -		log_login_db, ip2str(ip,NULL), esc_username, rcode, esc_message);
  2804. -
  2805. -	if( retcode != SQL_SUCCESS )
  2806. -		Sql_ShowDebug(sql_handle);
  2807. -}
  2808. -
  2809. -bool loginlog_init(void)
  2810. -{
  2811. -	const char* username;
  2812. -	const char* password;
  2813. -	const char* hostname;
  2814. -	uint16      port;
  2815. -	const char* database;
  2816. -	const char* codepage;
  2817. -
  2818. -	if( log_db_hostname[0] != '\0' )
  2819. -	{// local settings
  2820. -		username = log_db_username;
  2821. -		password = log_db_password;
  2822. -		hostname = log_db_hostname;
  2823. -		port     = log_db_port;
  2824. -		database = log_db_database;
  2825. -		codepage = log_codepage;
  2826. -	}
  2827. -	else
  2828. -	{// global settings
  2829. -		username = global_db_username;
  2830. -		password = global_db_password;
  2831. -		hostname = global_db_hostname;
  2832. -		port     = global_db_port;
  2833. -		database = global_db_database;
  2834. -		codepage = global_codepage;
  2835. -	}
  2836. -
  2837. -	sql_handle = Sql_Malloc();
  2838. -
  2839. -	if( SQL_ERROR == Sql_Connect(sql_handle, username, password, hostname, port, database) )
  2840. -	{
  2841. -		Sql_ShowDebug(sql_handle);
  2842. -		Sql_Free(sql_handle);
  2843. -		exit(EXIT_FAILURE);
  2844. -	}
  2845. -
  2846. -	if( codepage[0] != '\0' && SQL_ERROR == Sql_SetEncoding(sql_handle, codepage) )
  2847. -		Sql_ShowDebug(sql_handle);
  2848. -
  2849. -	enabled = true;
  2850. -
  2851. -	return true;
  2852. -}
  2853. -
  2854. -bool loginlog_final(void)
  2855. -{
  2856. -	Sql_Free(sql_handle);
  2857. -	sql_handle = NULL;
  2858. -	return true;
  2859. -}
  2860. -
  2861. -bool loginlog_config_read(const char* key, const char* value)
  2862. -{
  2863. -	const char* signature;
  2864. -
  2865. -	signature = "sql.";
  2866. -	if( strncmpi(key, signature, strlen(signature)) == 0 )
  2867. -	{
  2868. -		key += strlen(signature);
  2869. -		if( strcmpi(key, "db_hostname") == 0 )
  2870. -			safestrncpy(global_db_hostname, value, sizeof(global_db_hostname));
  2871. -		else
  2872. -		if( strcmpi(key, "db_port") == 0 )
  2873. -			global_db_port = (uint16)strtoul(value, NULL, 10);
  2874. -		else
  2875. -		if( strcmpi(key, "db_username") == 0 )
  2876. -			safestrncpy(global_db_username, value, sizeof(global_db_username));
  2877. -		else
  2878. -		if( strcmpi(key, "db_password") == 0 )
  2879. -			safestrncpy(global_db_password, value, sizeof(global_db_password));
  2880. -		else
  2881. -		if( strcmpi(key, "db_database") == 0 )
  2882. -			safestrncpy(global_db_database, value, sizeof(global_db_database));
  2883. -		else
  2884. -		if( strcmpi(key, "codepage") == 0 )
  2885. -			safestrncpy(global_codepage, value, sizeof(global_codepage));
  2886. -		else
  2887. -			return false;// not found
  2888. -		return true;
  2889. -	}
  2890. -
  2891. -	if( strcmpi(key, "log_db_ip") == 0 )
  2892. -		safestrncpy(log_db_hostname, value, sizeof(log_db_hostname));
  2893. -	else
  2894. -	if( strcmpi(key, "log_db_port") == 0 )
  2895. -		log_db_port = (uint16)strtoul(value, NULL, 10);
  2896. -	else
  2897. -	if( strcmpi(key, "log_db_id") == 0 )
  2898. -		safestrncpy(log_db_username, value, sizeof(log_db_username));
  2899. -	else
  2900. -	if( strcmpi(key, "log_db_pw") == 0 )
  2901. -		safestrncpy(log_db_password, value, sizeof(log_db_password));
  2902. -	else
  2903. -	if( strcmpi(key, "log_db_db") == 0 )
  2904. -		safestrncpy(log_db_database, value, sizeof(log_db_database));
  2905. -	else
  2906. -	if( strcmpi(key, "log_codepage") == 0 )
  2907. -		safestrncpy(log_codepage, value, sizeof(log_codepage));
  2908. -	else
  2909. -	if( strcmpi(key, "log_login_db") == 0 )
  2910. -		safestrncpy(log_login_db, value, sizeof(log_login_db));
  2911. -	else
  2912. -		return false;
  2913. -
  2914. -	return true;
  2915. -}
  2916. Index: src/login/ipban.c
  2917. ===================================================================
  2918. --- src/login/ipban.c	(working copy)
  2919. +++ src/login/ipban.c	(working copy)
  2920. @@ -100,7 +100,7 @@
  2921.  	if( login_config.ipban_cleanup_interval > 0 )
  2922.  		// release data
  2923.  		delete_timer(cleanup_timer_id, ipban_cleanup);
  2924. -	
  2925. +
  2926.  	ipban_cleanup(0,0,0,0); // always clean up on login-server stop
  2927.  
  2928.  	// close connections
  2929. Index: src/login/Makefile.in
  2930. ===================================================================
  2931. --- src/login/Makefile.in	(revision 17367)
  2932. +++ src/login/Makefile.in	(working copy)
  2933. @@ -12,10 +12,9 @@
  2934.  	../../3rdparty/libconfig/strbuf.h ../../3rdparty/libconfig/wincompat.h
  2935.  LIBCONFIG_INCLUDE = -I../../3rdparty/libconfig
  2936.  
  2937. -LOGIN_OBJ = login.o
  2938. -LOGIN_SQL_OBJ = $(LOGIN_OBJ:%=obj_sql/%) \
  2939. -	obj_sql/account_sql.o obj_sql/ipban_sql.o obj_sql/loginlog_sql.o
  2940. -LOGIN_H = login.h account.h ipban.h loginlog.h
  2941. +LOGIN_OBJ = login.o loginclif.o loginchrif.o logincnslif.o account.o ipban.o loginlog.o
  2942. +LOGIN_H = login.h loginclif.h loginchrif.h logincnslif.h account.h ipban.h loginlog.h
  2943. +LOGIN_SQL_OBJ = $(LOGIN_OBJ:%=obj_sql/%)
  2944.  
  2945.  HAVE_MYSQL=@HAVE_MYSQL@
  2946.  ifeq ($(HAVE_MYSQL),yes)
  2947. @@ -62,8 +61,8 @@
  2948.  login-server_sql: obj_sql $(LOGIN_SQL_OBJ) ../common/obj_sql/common_sql.a ../common/obj_all/common.a  $(MT19937AR_OBJ)
  2949.  	@echo "	LD	$@"
  2950.  	@@CC@ @LDFLAGS@ -o ../../login-server_sql@EXEEXT@ $(LOGIN_SQL_OBJ) ../common/obj_sql/common_sql.a ../common/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @MYSQL_LIBS@
  2951. -	    
  2952.  
  2953. +
  2954.  # login object files
  2955.  
  2956.  obj_sql/%.o: %.c $(LOGIN_H) $(COMMON_H) $(MT19937AR_H) $(LIBCONFIG_H)
  2957. Index: src/map/pc.h
  2958. ===================================================================
  2959. --- src/map/pc.h	(revision 17367)
  2960. +++ src/map/pc.h	(working copy)
  2961. @@ -185,6 +185,7 @@
  2962.  		unsigned int bonus_coma : 1;
  2963.  	} special_state;
  2964.  	int login_id1, login_id2;
  2965. +	int version;
  2966.  	unsigned short class_;	//This is the internal job ID used by the map server to simplify comparisons/queries/etc. [Skotlex]
  2967.  	int group_id, group_pos, group_level;
  2968.  	unsigned int permissions;/* group permissions */
  2969. Index: src/map/chrif.c
  2970. ===================================================================
  2971. --- src/map/chrif.c	(revision 17367)
  2972. +++ src/map/chrif.c	(working copy)
  2973. @@ -722,13 +722,14 @@
  2974.  
  2975.  	chrif_check(-1);
  2976.  
  2977. -	WFIFOHEAD(char_fd,18);
  2978. +	WFIFOHEAD(char_fd,19);
  2979.  	WFIFOW(char_fd, 0) = 0x2b02;
  2980.  	WFIFOL(char_fd, 2) = sd->bl.id;
  2981.  	WFIFOL(char_fd, 6) = sd->login_id1;
  2982.  	WFIFOL(char_fd,10) = sd->login_id2;
  2983.  	WFIFOL(char_fd,14) = htonl(s_ip);
  2984. -	WFIFOSET(char_fd,18);
  2985. +	WFIFOB(char_fd,18) = sd->version;
  2986. +	WFIFOSET(char_fd,19);
  2987.  
  2988.  	return 0;
  2989.  }
  2990. Index: src/char/int_party.c
  2991. ===================================================================
  2992. --- src/char/int_party.c	(revision 17367)
  2993. +++ src/char/int_party.c	(working copy)
  2994. @@ -11,6 +11,7 @@
  2995.  #include "../common/mapindex.h"
  2996.  #include "../common/sql.h"
  2997.  #include "char.h"
  2998. +#include "char_mapif.h"
  2999.  #include "inter.h"
  3000.  #include "int_party.h"
  3001.  
  3002. @@ -130,9 +131,9 @@
  3003.  	if( flag & PS_BREAK )
  3004.  	{// Break the party
  3005.  		// we'll skip name-checking and just reset everyone with the same party id [celest]
  3006. -		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", char_db, party_id) )
  3007. +		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", schema_config.char_db, party_id) )
  3008.  			Sql_ShowDebug(sql_handle);
  3009. -		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `party_id`='%d'", party_db, party_id) )
  3010. +		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `party_id`='%d'", schema_config.party_db, party_id) )
  3011.  			Sql_ShowDebug(sql_handle);
  3012.  		//Remove from memory
  3013.  		idb_remove(party_db_, party_id);
  3014. @@ -144,7 +145,7 @@
  3015.  		if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
  3016.  			"(`name`, `exp`, `item`, `leader_id`, `leader_char`) "
  3017.  			"VALUES ('%s', '%d', '%d', '%d', '%d')",
  3018. -			party_db, esc_name, p->exp, p->item, p->member[index].account_id, p->member[index].char_id) )
  3019. +			schema_config.party_db, esc_name, p->exp, p->item, p->member[index].account_id, p->member[index].char_id) )
  3020.  		{
  3021.  			Sql_ShowDebug(sql_handle);
  3022.  			return 0;
  3023. @@ -155,32 +156,32 @@
  3024.  	if( flag & PS_BASIC )
  3025.  	{// Update party info.
  3026.  		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `name`='%s', `exp`='%d', `item`='%d' WHERE `party_id`='%d'",
  3027. -			party_db, esc_name, p->exp, p->item, party_id) )
  3028. +			schema_config.party_db, esc_name, p->exp, p->item, party_id) )
  3029.  			Sql_ShowDebug(sql_handle);
  3030.  	}
  3031.  
  3032.  	if( flag & PS_LEADER )
  3033.  	{// Update leader
  3034.  		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s`  SET `leader_id`='%d', `leader_char`='%d' WHERE `party_id`='%d'",
  3035. -			party_db, p->member[index].account_id, p->member[index].char_id, party_id) )
  3036. +			schema_config.party_db, p->member[index].account_id, p->member[index].char_id, party_id) )
  3037.  			Sql_ShowDebug(sql_handle);
  3038.  	}
  3039. -	
  3040. +
  3041.  	if( flag & PS_ADDMEMBER )
  3042.  	{// Add one party member.
  3043.  		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='%d' WHERE `account_id`='%d' AND `char_id`='%d'",
  3044. -			char_db, party_id, p->member[index].account_id, p->member[index].char_id) )
  3045. +			schema_config.char_db, party_id, p->member[index].account_id, p->member[index].char_id) )
  3046.  			Sql_ShowDebug(sql_handle);
  3047.  	}
  3048.  
  3049.  	if( flag & PS_DELMEMBER )
  3050.  	{// Remove one party member.
  3051.  		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d' AND `account_id`='%d' AND `char_id`='%d'",
  3052. -			char_db, party_id, p->member[index].account_id, p->member[index].char_id) )
  3053. +			schema_config.char_db, party_id, p->member[index].account_id, p->member[index].char_id) )
  3054.  			Sql_ShowDebug(sql_handle);
  3055.  	}
  3056.  
  3057. -	if( save_log )
  3058. +	if( charserv_config.save_log )
  3059.  		ShowInfo("Party Saved (%d - %s)\n", party_id, p->name);
  3060.  	return 1;
  3061.  }
  3062. @@ -201,7 +202,7 @@
  3063.  #endif
  3064.  	if( party_id <= 0 )
  3065.  		return NULL;
  3066. -	
  3067. +
  3068.  	//Load from memory
  3069.  	p = (struct party_data*)idb_get(party_db_, party_id);
  3070.  	if( p != NULL )
  3071. @@ -210,7 +211,7 @@
  3072.  	p = party_pt;
  3073.  	memset(p, 0, sizeof(struct party_data));
  3074.  
  3075. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `party_id`, `name`,`exp`,`item`, `leader_id`, `leader_char` FROM `%s` WHERE `party_id`='%d'", party_db, party_id) )
  3076. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `party_id`, `name`,`exp`,`item`, `leader_id`, `leader_char` FROM `%s` WHERE `party_id`='%d'", schema_config.party_db, party_id) )
  3077.  	{
  3078.  		Sql_ShowDebug(sql_handle);
  3079.  		return NULL;
  3080. @@ -228,7 +229,7 @@
  3081.  	Sql_FreeResult(sql_handle);
  3082.  
  3083.  	// Load members
  3084. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`char_id`,`name`,`base_level`,`last_map`,`online`,`class` FROM `%s` WHERE `party_id`='%d'", char_db, party_id) )
  3085. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`char_id`,`name`,`base_level`,`last_map`,`online`,`class` FROM `%s` WHERE `party_id`='%d'", schema_config.char_db, party_id) )
  3086.  	{
  3087.  		Sql_ShowDebug(sql_handle);
  3088.  		return NULL;
  3089. @@ -247,7 +248,7 @@
  3090.  	}
  3091.  	Sql_FreeResult(sql_handle);
  3092.  
  3093. -	if( save_log )
  3094. +	if( charserv_config.save_log )
  3095.  		ShowInfo("Party loaded (%d - %s).\n", party_id, p->party.name);
  3096.  	//Add party to memory.
  3097.  	CREATE(p, struct party_data, 1);
  3098. @@ -292,7 +293,7 @@
  3099.  	struct party_data* p = NULL;
  3100.  
  3101.  	Sql_EscapeStringLen(sql_handle, esc_name, str, safestrnlen(str, NAME_LENGTH));
  3102. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `party_id` FROM `%s` WHERE `name`='%s'", party_db, esc_name) )
  3103. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `party_id` FROM `%s` WHERE `name`='%s'", schema_config.party_db, esc_name) )
  3104.  		Sql_ShowDebug(sql_handle);
  3105.  	else if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
  3106.  	{
  3107. @@ -473,9 +474,9 @@
  3108.  		return 0;
  3109.  	}
  3110.  	// Check Authorised letters/symbols in the name of the character
  3111. -	if (char_name_option == 1) { // only letters/symbols in char_name_letters are authorised
  3112. +	if (charserv_config.char_name_option == 1) { // only letters/symbols in char_name_letters are authorised
  3113.  		for (i = 0; i < NAME_LENGTH && name[i]; i++)
  3114. -			if (strchr(char_name_letters, name[i]) == NULL) {
  3115. +			if (strchr(charserv_config.char_name_letters, name[i]) == NULL) {
  3116.  				if( name[i] == '"' ) { /* client-special-char */
  3117.  					normalize_name(name,"\"");
  3118.  					mapif_parse_CreateParty(fd,name,item,item2,leader);
  3119. @@ -484,16 +485,16 @@
  3120.  				mapif_party_created(fd,leader->account_id,leader->char_id,NULL);
  3121.  				return 0;
  3122.  			}
  3123. -	} else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
  3124. +	} else if (charserv_config.char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
  3125.  		for (i = 0; i < NAME_LENGTH && name[i]; i++)
  3126. -			if (strchr(char_name_letters, name[i]) != NULL) {
  3127. +			if (strchr(charserv_config.char_name_letters, name[i]) != NULL) {
  3128.  				mapif_party_created(fd,leader->account_id,leader->char_id,NULL);
  3129.  				return 0;
  3130.  			}
  3131.  	}
  3132.  
  3133.  	p = (struct party_data*)aCalloc(1, sizeof(struct party_data));
  3134. -	
  3135. +
  3136.  	memcpy(p->party.name,name,NAME_LENGTH);
  3137.  	p->party.exp=0;
  3138.  	p->party.item=(item?1:0)|(item2?2:0);
  3139. @@ -597,7 +598,7 @@
  3140.  	p = inter_party_fromsql(party_id);
  3141.  	if( p == NULL )
  3142.  	{// Party does not exists?
  3143. -		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", char_db, party_id) )
  3144. +		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", schema_config.char_db, party_id) )
  3145.  			Sql_ShowDebug(sql_handle);
  3146.  		return 0;
  3147.  	}
  3148. @@ -634,7 +635,7 @@
  3149.  			int_party_check_lv(p);
  3150.  		}
  3151.  	}
  3152. -		
  3153. +
  3154.  	if (party_check_empty(p) == 0)
  3155.  		mapif_party_info(-1, &p->party, 0);
  3156.  	return 0;
  3157. @@ -649,7 +650,7 @@
  3158.  	if (p == NULL)
  3159.  		return 0;
  3160.  
  3161. -	for(i = 0; i < MAX_PARTY && 
  3162. +	for(i = 0; i < MAX_PARTY &&
  3163.  		(p->party.member[i].account_id != account_id ||
  3164.  		p->party.member[i].char_id != char_id); i++);
  3165.  
  3166. @@ -663,7 +664,7 @@
  3167.  		else
  3168.  			p->party.count--;
  3169.  		// Even share check situations: Family state (always breaks)
  3170. -		// character logging on/off is max/min level (update level range) 
  3171. +		// character logging on/off is max/min level (update level range)
  3172.  		// or character logging on/off has a different level (update level range using new level)
  3173.  		if (p->family ||
  3174.  			(p->party.member[i].lv <= p->min_lv || p->party.member[i].lv >= p->max_lv) ||
  3175. @@ -728,7 +729,7 @@
  3176.  
  3177.  	for (i = 0; i < MAX_PARTY; i++)
  3178.  	{
  3179. -		if(p->party.member[i].leader) 
  3180. +		if(p->party.member[i].leader)
  3181.  			p->party.member[i].leader = 0;
  3182.  		if(p->party.member[i].account_id == account_id &&
  3183.  			p->party.member[i].char_id == char_id)
  3184. @@ -800,7 +801,7 @@
  3185.  	{// Get party_id from the database
  3186.  		char* data;
  3187.  
  3188. -		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT party_id FROM `%s` WHERE char_id='%d'", char_db, char_id) )
  3189. +		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT party_id FROM `%s` WHERE char_id='%d'", schema_config.char_db, char_id) )
  3190.  		{
  3191.  			Sql_ShowDebug(sql_handle);
  3192.  			return 0;
  3193. @@ -815,7 +816,7 @@
  3194.  	}
  3195.  	if (party_id == 0)
  3196.  		return 0; //No party...
  3197. -	
  3198. +
  3199.  	p = inter_party_fromsql(party_id);
  3200.  	if(!p) {
  3201.  		ShowError("Character %d's party %d not found!\n", char_id, party_id);
  3202. @@ -846,7 +847,7 @@
  3203.  	{// Get guild_id from the database
  3204.  		char* data;
  3205.  
  3206. -		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT party_id FROM `%s` WHERE char_id='%d'", char_db, char_id) )
  3207. +		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT party_id FROM `%s` WHERE char_id='%d'", schema_config.char_db, char_id) )
  3208.  		{
  3209.  			Sql_ShowDebug(sql_handle);
  3210.  			return 0;
  3211. @@ -861,7 +862,7 @@
  3212.  	}
  3213.  	if (party_id == 0)
  3214.  		return 0; //No party...
  3215. -	
  3216. +
  3217.  	//Character has a party, set character offline and check if they were the only member online
  3218.  	if ((p = inter_party_fromsql(party_id)) == NULL)
  3219.  		return 0;
  3220. Index: src/char/char.c
  3221. ===================================================================
  3222. --- src/char/char.c	(revision 17367)
  3223. +++ src/char/char.c	(working copy)
  3224. @@ -21,8 +21,12 @@
  3225.  #include "int_elemental.h"
  3226.  #include "int_party.h"
  3227.  #include "int_storage.h"
  3228. +#include "inter.h"
  3229. +#include "char_logif.h"
  3230. +#include "char_mapif.h"
  3231. +#include "char_cnslif.h"
  3232. +#include "char_clif.h"
  3233.  #include "char.h"
  3234. -#include "inter.h"
  3235.  
  3236.  #include <sys/types.h>
  3237.  #include <time.h>
  3238. @@ -33,88 +37,22 @@
  3239.  #include <stdlib.h>
  3240.  #include <malloc.h>
  3241.  
  3242. -#define MAX_STARTITEM 32
  3243. +
  3244.  #define CHAR_MAX_MSG 300
  3245.  static char* msg_table[CHAR_MAX_MSG]; // Login Server messages_conf
  3246.  
  3247. -char char_db[256] = "char";
  3248. -char scdata_db[256] = "sc_data";
  3249. -char cart_db[256] = "cart_inventory";
  3250. -char inventory_db[256] = "inventory";
  3251. -char charlog_db[256] = "charlog";
  3252. -char storage_db[256] = "storage";
  3253. -char interlog_db[256] = "interlog";
  3254. -char reg_db[256] = "global_reg_value";
  3255. -char skill_db[256] = "skill";
  3256. -char memo_db[256] = "memo";
  3257. -char guild_db[256] = "guild";
  3258. -char guild_alliance_db[256] = "guild_alliance";
  3259. -char guild_castle_db[256] = "guild_castle";
  3260. -char guild_expulsion_db[256] = "guild_expulsion";
  3261. -char guild_member_db[256] = "guild_member";
  3262. -char guild_position_db[256] = "guild_position";
  3263. -char guild_skill_db[256] = "guild_skill";
  3264. -char guild_storage_db[256] = "guild_storage";
  3265. -char party_db[256] = "party";
  3266. -char pet_db[256] = "pet";
  3267. -char mail_db[256] = "mail"; // MAIL SYSTEM
  3268. -char auction_db[256] = "auction"; // Auctions System
  3269. -char friend_db[256] = "friends";
  3270. -char hotkey_db[256] = "hotkey";
  3271. -char quest_db[256] = "quest";
  3272. -char homunculus_db[256] = "homunculus";
  3273. -char skill_homunculus_db[256] = "skill_homunculus";
  3274. -char mercenary_db[256] = "mercenary";
  3275. -char mercenary_owner_db[256] = "mercenary_owner";
  3276. -char ragsrvinfo_db[256] = "ragsrvinfo";
  3277. +// check for exit signal
  3278. +// 0 is saving complete
  3279. +// other is char_id
  3280. +unsigned int save_flag = 0;
  3281.  
  3282. -// show loading/saving messages
  3283. -int save_log = 1;
  3284. +#define MAX_STARTITEM 32
  3285. +struct startitem {
  3286. +	int nameid; //Item ID
  3287. +	int amount; //Number of items
  3288. +	int pos; //Position (for auto-equip)
  3289. +} start_items[MAX_STARTITEM+1];
  3290.  
  3291. -static DBMap* char_db_; // int char_id -> struct mmo_charstatus*
  3292. -
  3293. -char db_path[1024] = "db";
  3294. -
  3295. -int db_use_sqldbs;
  3296. -
  3297. -struct mmo_map_server {
  3298. -	int fd;
  3299. -	uint32 ip;
  3300. -	uint16 port;
  3301. -	int users;
  3302. -	unsigned short map[MAX_MAP_PER_SERVER];
  3303. -} server[MAX_MAP_SERVERS];
  3304. -
  3305. -int login_fd=-1, char_fd=-1;
  3306. -char userid[24];
  3307. -char passwd[24];
  3308. -char server_name[20];
  3309. -char wisp_server_name[NAME_LENGTH] = "Server";
  3310. -char login_ip_str[128];
  3311. -uint32 login_ip = 0;
  3312. -uint16 login_port = 6900;
  3313. -char char_ip_str[128];
  3314. -uint32 char_ip = 0;
  3315. -char bind_ip_str[128];
  3316. -uint32 bind_ip = INADDR_ANY;
  3317. -uint16 char_port = 6121;
  3318. -int char_maintenance = 0;
  3319. -bool char_new = true;
  3320. -int char_new_display = 0;
  3321. -
  3322. -bool name_ignoring_case = false; // Allow or not identical name for characters but with a different case by [Yor]
  3323. -int char_name_option = 0; // Option to know which letters/symbols are authorised in the name of a character (0: all, 1: only those in char_name_letters, 2: all EXCEPT those in char_name_letters) by [Yor]
  3324. -char unknown_char_name[NAME_LENGTH] = "Unknown"; // Name to use when the requested name cannot be determined
  3325. -#define TRIM_CHARS "\255\xA0\032\t\x0A\x0D " //The following characters are trimmed regardless because they cause confusion and problems on the servers. [Skotlex]
  3326. -char char_name_letters[1024] = ""; // list of letters/symbols allowed (or not) in a character name. by [Yor]
  3327. -
  3328. -int char_per_account = 0; //Maximum chars per account (default unlimited) [Sirius]
  3329. -int char_del_level = 0; //From which level u can delete character [Lupus]
  3330. -int char_del_delay = 86400;
  3331. -
  3332. -int log_char = 1;	// loggin char or not [devil]
  3333. -int log_inter = 1;	// loggin inter or not [devil]
  3334. -
  3335.  // Advanced subnet check [LuzZza]
  3336.  struct s_subnet {
  3337.  	uint32 mask;
  3338. @@ -123,130 +61,17 @@
  3339.  } subnet[16];
  3340.  int subnet_count = 0;
  3341.  
  3342. -struct char_session_data {
  3343. -	bool auth; // whether the session is authed or not
  3344. -	int account_id, login_id1, login_id2, sex;
  3345. -	int found_char[MAX_CHARS]; // ids of chars on this account
  3346. -	char email[40]; // e-mail (default: [email protected]) by [Yor]
  3347. -	time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
  3348. -	int group_id; // permission
  3349. -	uint8 char_slots;
  3350. -	uint32 version;
  3351. -	uint8 clienttype;
  3352. -	char new_name[NAME_LENGTH];
  3353. -	char birthdate[10+1];  // YYYY-MM-DD
  3354. -	// Pincode system
  3355. -	char pincode[PINCODE_LENGTH+1];
  3356. -	uint32 pincode_seed;
  3357. -	time_t pincode_change;
  3358. -	uint16 pincode_try;
  3359. -	// Addon system
  3360. -	unsigned int char_moves[MAX_CHARS]; // character moves left
  3361. -};
  3362. +DBMap* auth_db; // int account_id -> struct auth_node*
  3363. +DBMap* online_char_db; // int account_id -> struct online_char_data*
  3364. +DBMap* char_db_; // int char_id -> struct mmo_charstatus*
  3365. +DBMap* char_get_authdb() { return auth_db; }
  3366. +DBMap* char_get_onlinedb() { return online_char_db; }
  3367. +DBMap* char_get_chardb() { return char_db_; }
  3368.  
  3369. -struct startitem {
  3370. -	int nameid; //Item ID
  3371. -	int amount; //Number of items
  3372. -	int pos; //Position (for auto-equip)
  3373. -} start_items[MAX_STARTITEM+1];
  3374. -
  3375. -int max_connect_user = -1;
  3376. -int gm_allow_group = -1;
  3377. -int autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
  3378. -int start_zeny = 0;
  3379. -int guild_exp_rate = 100;
  3380. -
  3381. -// Pincode system
  3382. -#define PINCODE_OK 0
  3383. -#define PINCODE_ASK 1
  3384. -#define PINCODE_NOTSET 2
  3385. -#define PINCODE_EXPIRED 3
  3386. -#define PINCODE_NEW 4
  3387. -#define PINCODE_PASSED 7
  3388. -#define	PINCODE_WRONG 8
  3389. -
  3390. -bool pincode_enabled = true;
  3391. -int pincode_changetime = 0;
  3392. -int pincode_maxtry = 3;
  3393. -bool pincode_force = true;
  3394. -
  3395. -void pincode_check( int fd, struct char_session_data* sd );
  3396. -void pincode_change( int fd, struct char_session_data* sd );
  3397. -void pincode_setnew( int fd, struct char_session_data* sd );
  3398. -void pincode_sendstate( int fd, struct char_session_data* sd, uint16 state );
  3399. -void pincode_notifyLoginPinUpdate( int account_id, char* pin );
  3400. -void pincode_notifyLoginPinError( int account_id );
  3401. -void pincode_decrypt( uint32 userSeed, char* pin );
  3402. -int pincode_compare( int fd, struct char_session_data* sd, char* pin );
  3403. -
  3404. -// Addon system
  3405. -bool char_move_enabled = true;
  3406. -bool char_movetoused = true;
  3407. -bool char_moves_unlimited = false;
  3408. -
  3409. -void moveCharSlot( int fd, struct char_session_data* sd, unsigned short from, unsigned short to );
  3410. -void moveCharSlotReply( int fd, struct char_session_data* sd, unsigned short index, short reason );
  3411. -
  3412. -//Custom limits for the fame lists. [Skotlex]
  3413. -int fame_list_size_chemist = MAX_FAME_LIST;
  3414. -int fame_list_size_smith = MAX_FAME_LIST;
  3415. -int fame_list_size_taekwon = MAX_FAME_LIST;
  3416. -
  3417. -// Char-server-side stored fame lists [DracoRPG]
  3418. -struct fame_list smith_fame_list[MAX_FAME_LIST];
  3419. -struct fame_list chemist_fame_list[MAX_FAME_LIST];
  3420. -struct fame_list taekwon_fame_list[MAX_FAME_LIST];
  3421. -
  3422. -// check for exit signal
  3423. -// 0 is saving complete
  3424. -// other is char_id
  3425. -unsigned int save_flag = 0;
  3426. -
  3427. -// Initial position (it's possible to set it in conf file)
  3428. -struct point start_point = { 0, 53, 111 };
  3429. -
  3430. -int console = 0;
  3431. -
  3432. -//-----------------------------------------------------
  3433. -// Auth database
  3434. -//-----------------------------------------------------
  3435. -#define AUTH_TIMEOUT 30000
  3436. -
  3437. -struct auth_node {
  3438. -	int account_id;
  3439. -	int char_id;
  3440. -	uint32 login_id1;
  3441. -	uint32 login_id2;
  3442. -	uint32 ip;
  3443. -	int sex;
  3444. -	time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
  3445. -	int group_id;
  3446. -	unsigned changing_mapservers : 1;
  3447. -};
  3448. -
  3449. -static DBMap* auth_db; // int account_id -> struct auth_node*
  3450. -
  3451. -//-----------------------------------------------------
  3452. -// Online User Database
  3453. -//-----------------------------------------------------
  3454. -
  3455. -struct online_char_data {
  3456. -	int account_id;
  3457. -	int char_id;
  3458. -	int fd;
  3459. -	int waiting_disconnect;
  3460. -	short server; // -2: unknown server, -1: not connected, 0+: id of server
  3461. -	bool pincode_success;
  3462. -};
  3463. -
  3464. -static DBMap* online_char_db; // int account_id -> struct online_char_data*
  3465. -static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data);
  3466. -int delete_char_sql(int char_id);
  3467. -
  3468.  /**
  3469.   * @see DBCreateData
  3470.   */
  3471. -static DBData create_online_char_data(DBKey key, va_list args)
  3472. +DBData create_online_char_data(DBKey key, va_list args)
  3473.  {
  3474.  	struct online_char_data* character;
  3475.  	CREATE(character, struct online_char_data, 1);
  3476. @@ -276,13 +101,7 @@
  3477.  		character->waiting_disconnect = INVALID_TIMER;
  3478.  	}
  3479.  
  3480. -	if (login_fd > 0 && !session[login_fd]->flag.eof)
  3481. -	{
  3482. -		WFIFOHEAD(login_fd,6);
  3483. -		WFIFOW(login_fd,0) = 0x272b;
  3484. -		WFIFOL(login_fd,2) = account_id;
  3485. -		WFIFOSET(login_fd,6);
  3486. -	}
  3487. +	char_send_setacconline(account_id);
  3488.  
  3489.  }
  3490.  
  3491. @@ -292,7 +111,7 @@
  3492.  	struct mmo_charstatus *cp;
  3493.  
  3494.  	//Update DB
  3495. -	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='1' WHERE `char_id`='%d' LIMIT 1", char_db, char_id) )
  3496. +	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='1' WHERE `char_id`='%d' LIMIT 1", schema_config.char_db, char_id) )
  3497.  		Sql_ShowDebug(sql_handle);
  3498.  
  3499.  	//Check to see for online conflicts
  3500. @@ -322,13 +141,7 @@
  3501.  	inter_guild_CharOnline(char_id, cp?cp->guild_id:-1);
  3502.  
  3503.  	//Notify login server
  3504. -	if (login_fd > 0 && !session[login_fd]->flag.eof)
  3505. -	{
  3506. -		WFIFOHEAD(login_fd,6);
  3507. -		WFIFOW(login_fd,0) = 0x272b;
  3508. -		WFIFOL(login_fd,2) = account_id;
  3509. -		WFIFOSET(login_fd,6);
  3510. -	}
  3511. +	char_send_setacconline(account_id);
  3512.  }
  3513.  
  3514.  void set_char_offline(int char_id, int account_id)
  3515. @@ -337,7 +150,7 @@
  3516.  
  3517.  	if ( char_id == -1 )
  3518.  	{
  3519. -		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='0' WHERE `account_id`='%d'", char_db, account_id) )
  3520. +		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='0' WHERE `account_id`='%d'", schema_config.char_db, account_id) )
  3521.  			Sql_ShowDebug(sql_handle);
  3522.  	}
  3523.  	else
  3524. @@ -347,7 +160,7 @@
  3525.  		if (cp)
  3526.  			idb_remove(char_db_,char_id);
  3527.  
  3528. -		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='0' WHERE `char_id`='%d' LIMIT 1", char_db, char_id) )
  3529. +		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='0' WHERE `char_id`='%d' LIMIT 1", schema_config.char_db, char_id) )
  3530.  			Sql_ShowDebug(sql_handle);
  3531.  	}
  3532.  
  3533. @@ -374,20 +187,15 @@
  3534.  	}
  3535.  
  3536.  	//Remove char if 1- Set all offline, or 2- character is no longer connected to char-server.
  3537. -	if (login_fd > 0 && !session[login_fd]->flag.eof && (char_id == -1 || character == NULL || character->fd == -1))
  3538. -	{
  3539. -		WFIFOHEAD(login_fd,6);
  3540. -		WFIFOW(login_fd,0) = 0x272c;
  3541. -		WFIFOL(login_fd,2) = account_id;
  3542. -		WFIFOSET(login_fd,6);
  3543. +	if (char_id == -1 || character == NULL || character->fd == -1){
  3544. +		char_send_setaccoffline(login_fd,account_id);
  3545.  	}
  3546.  }
  3547.  
  3548.  /**
  3549.   * @see DBApply
  3550.   */
  3551. -static int char_db_setoffline(DBKey key, DBData *data, va_list ap)
  3552. -{
  3553. +int char_db_setoffline(DBKey key, DBData *data, va_list ap) {
  3554.  	struct online_char_data* character = (struct online_char_data*)db_data2ptr(data);
  3555.  	int server = va_arg(ap, int);
  3556.  	if (server == -1) {
  3557. @@ -434,20 +242,17 @@
  3558.  
  3559.  	if (id >= 0 || login_fd <= 0 || session[login_fd]->flag.eof)
  3560.  		return;
  3561. -	//Tell login-server to also mark all our characters as offline.
  3562. -	WFIFOHEAD(login_fd,2);
  3563. -	WFIFOW(login_fd,0) = 0x2737;
  3564. -	WFIFOSET(login_fd,2);
  3565. +	char_send_setallaccoffline(login_fd);
  3566.  }
  3567.  
  3568.  void set_all_offline_sql(void)
  3569.  {
  3570.  	//Set all players to 'OFFLINE'
  3571. -	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online` = '0'", char_db) )
  3572. +	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online` = '0'", schema_config.char_db) )
  3573.  		Sql_ShowDebug(sql_handle);
  3574. -	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online` = '0'", guild_member_db) )
  3575. +	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online` = '0'", schema_config.guild_member_db) )
  3576.  		Sql_ShowDebug(sql_handle);
  3577. -	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `connect_member` = '0'", guild_db) )
  3578. +	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `connect_member` = '0'", schema_config.guild_db) )
  3579.  		Sql_ShowDebug(sql_handle);
  3580.  }
  3581.  
  3582. @@ -533,7 +338,7 @@
  3583.  			"`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d', `rename`='%d',"
  3584.  			"`delete_date`='%lu',`robe`='%d',`moves`='%d'"
  3585.  			" WHERE  `account_id`='%d' AND `char_id` = '%d'",
  3586. -			char_db, p->base_level, p->job_level,
  3587. +			schema_config.char_db, p->base_level, p->job_level,
  3588.  			p->base_exp, p->job_exp, p->zeny,
  3589.  			p->max_hp, p->hp, p->max_sp, p->sp, p->status_point, p->skill_point,
  3590.  			p->str, p->agi, p->vit, p->int_, p->dex, p->luk,
  3591. @@ -566,7 +371,7 @@
  3592.  			"`partner_id`='%d', `father`='%d', `mother`='%d', `child`='%d',"
  3593.  			"`karma`='%d',`manner`='%d', `fame`='%d'"
  3594.  			" WHERE  `account_id`='%d' AND `char_id` = '%d'",
  3595. -			char_db, p->class_,
  3596. +			schema_config.char_db, p->class_,
  3597.  			p->hair, p->hair_color, p->clothes_color,
  3598.  			p->partner_id, p->father, p->mother, p->child,
  3599.  			p->karma, p->manner, p->fame,
  3600. @@ -596,7 +401,7 @@
  3601.  		char esc_mapname[NAME_LENGTH*2+1];
  3602.  
  3603.  		//`memo` (`memo_id`,`char_id`,`map`,`x`,`y`)
  3604. -		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", memo_db, p->char_id) )
  3605. +		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", schema_config.memo_db, p->char_id) )
  3606.  		{
  3607.  			Sql_ShowDebug(sql_handle);
  3608.  			errors++;
  3609. @@ -604,7 +409,7 @@
  3610.  
  3611.  		//insert here.
  3612.  		StringBuf_Clear(&buf);
  3613. -		StringBuf_Printf(&buf, "INSERT INTO `%s`(`char_id`,`map`,`x`,`y`) VALUES ", memo_db);
  3614. +		StringBuf_Printf(&buf, "INSERT INTO `%s`(`char_id`,`map`,`x`,`y`) VALUES ", schema_config.memo_db);
  3615.  		for( i = 0, count = 0; i < MAX_MEMOPOINTS; ++i )
  3616.  		{
  3617.  			if( p->memo_point[i].map )
  3618. @@ -637,14 +442,14 @@
  3619.  	if( memcmp(p->skill, cp->skill, sizeof(p->skill)) )
  3620.  	{
  3621.  		//`skill` (`char_id`, `id`, `lv`)
  3622. -		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", skill_db, p->char_id) )
  3623. +		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", schema_config.skill_db, p->char_id) )
  3624.  		{
  3625.  			Sql_ShowDebug(sql_handle);
  3626.  			errors++;
  3627.  		}
  3628.  
  3629.  		StringBuf_Clear(&buf);
  3630. -		StringBuf_Printf(&buf, "INSERT INTO `%s`(`char_id`,`id`,`lv`,`flag`) VALUES ", skill_db);
  3631. +		StringBuf_Printf(&buf, "INSERT INTO `%s`(`char_id`,`id`,`lv`,`flag`) VALUES ", schema_config.skill_db);
  3632.  		//insert here.
  3633.  		for( i = 0, count = 0; i < MAX_SKILL; ++i ) {
  3634.  			if( p->skill[i].id != 0 && p->skill[i].flag != SKILL_FLAG_TEMPORARY ) {
  3635. @@ -684,14 +489,14 @@
  3636.  
  3637.  	if(diff == 1)
  3638.  	{	//Save friends
  3639. -		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", friend_db, char_id) )
  3640. +		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", schema_config.friend_db, char_id) )
  3641.  		{
  3642.  			Sql_ShowDebug(sql_handle);
  3643.  			errors++;
  3644.  		}
  3645.  
  3646.  		StringBuf_Clear(&buf);
  3647. -		StringBuf_Printf(&buf, "INSERT INTO `%s` (`char_id`, `friend_account`, `friend_id`) VALUES ", friend_db);
  3648. +		StringBuf_Printf(&buf, "INSERT INTO `%s` (`char_id`, `friend_account`, `friend_id`) VALUES ", schema_config.friend_db);
  3649.  		for( i = 0, count = 0; i < MAX_FRIENDS; ++i )
  3650.  		{
  3651.  			if( p->friends[i].char_id > 0 )
  3652. @@ -716,7 +521,7 @@
  3653.  #ifdef HOTKEY_SAVING
  3654.  	// hotkeys
  3655.  	StringBuf_Clear(&buf);
  3656. -	StringBuf_Printf(&buf, "REPLACE INTO `%s` (`char_id`, `hotkey`, `type`, `itemskill_id`, `skill_lvl`) VALUES ", hotkey_db);
  3657. +	StringBuf_Printf(&buf, "REPLACE INTO `%s` (`char_id`, `hotkey`, `type`, `itemskill_id`, `skill_lvl`) VALUES ", schema_config.hotkey_db);
  3658.  	diff = 0;
  3659.  	for(i = 0; i < ARRAYLENGTH(p->hotkeys); i++){
  3660.  		if(memcmp(&p->hotkeys[i], &cp->hotkeys[i], sizeof(struct hotkey)))
  3661. @@ -737,7 +542,7 @@
  3662.  	}
  3663.  #endif
  3664.  	StringBuf_Destroy(&buf);
  3665. -	if (save_status[0]!='\0' && save_log)
  3666. +	if (save_status[0]!='\0' && charserv_config.save_log)
  3667.  		ShowInfo("Saved char %d - %s:%s.\n", char_id, p->name, save_status);
  3668.  	if (!errors)
  3669.  		memcpy(cp, p, sizeof(struct mmo_charstatus));
  3670. @@ -759,10 +564,10 @@
  3671.  	int errors = 0;
  3672.  
  3673.  	switch (tableswitch) {
  3674. -	case TABLE_INVENTORY:     tablename = inventory_db;     selectoption = "char_id";    break;
  3675. -	case TABLE_CART:          tablename = cart_db;          selectoption = "char_id";    break;
  3676. -	case TABLE_STORAGE:       tablename = storage_db;       selectoption = "account_id"; break;
  3677. -	case TABLE_GUILD_STORAGE: tablename = guild_storage_db; selectoption = "guild_id";   break;
  3678. +	case TABLE_INVENTORY:     tablename = schema_config.inventory_db;     selectoption = "char_id";    break;
  3679. +	case TABLE_CART:          tablename = schema_config.cart_db;          selectoption = "char_id";    break;
  3680. +	case TABLE_STORAGE:       tablename = schema_config.storage_db;       selectoption = "account_id"; break;
  3681. +	case TABLE_GUILD_STORAGE: tablename = schema_config.guild_storage_db; selectoption = "guild_id";   break;
  3682.  	default:
  3683.  		ShowError("Invalid table name!\n");
  3684.  		return 1;
  3685. @@ -924,7 +729,7 @@
  3686.  	StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`");
  3687.  	for( j = 0; j < MAX_SLOTS; ++j )
  3688.  		StringBuf_Printf(&buf, ", `card%d`", j);
  3689. -	StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`='%d'", inventory_db, id);
  3690. +	StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`='%d'", schema_config.inventory_db, id);
  3691.  
  3692.  	stmt = SqlStmt_Malloc(sql_handle);
  3693.  	if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
  3694. @@ -980,7 +785,7 @@
  3695.  					// update all fields.
  3696.  					StringBuf_Clear(&buf);
  3697.  					StringBuf_Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u', `favorite`='%d', `bound`='%d'",
  3698. -									 inventory_db, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite, items[i].bound);
  3699. +					    schema_config.inventory_db, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite, items[i].bound);
  3700.  					for( j = 0; j < MAX_SLOTS; ++j )
  3701.  						StringBuf_Printf(&buf, ", `card%d`=%d", j, items[i].card[j]);
  3702.  					StringBuf_Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id);
  3703. @@ -996,7 +801,7 @@
  3704.  			}
  3705.  		}
  3706.  		if( !found ) {// Item not present in inventory, remove it.
  3707. -			if( SQL_ERROR == Sql_Query(sql_handle, "DELETE from `%s` where `id`='%d' LIMIT 1", inventory_db, item.id) ) {
  3708. +			if( SQL_ERROR == Sql_Query(sql_handle, "DELETE from `%s` where `id`='%d' LIMIT 1", schema_config.inventory_db, item.id) ) {
  3709.  				Sql_ShowDebug(sql_handle);
  3710.  				errors++;
  3711.  			}
  3712. @@ -1005,7 +810,7 @@
  3713.  	SqlStmt_Free(stmt);
  3714.  
  3715.  	StringBuf_Clear(&buf);
  3716. -	StringBuf_Printf(&buf, "INSERT INTO `%s` (`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`, `unique_id`", inventory_db);
  3717. +	StringBuf_Printf(&buf, "INSERT INTO `%s` (`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`, `unique_id`", schema_config.inventory_db);
  3718.  	for( j = 0; j < MAX_SLOTS; ++j )
  3719.  		StringBuf_Printf(&buf, ", `card%d`", j);
  3720.  	StringBuf_AppendStr(&buf, ") VALUES ");
  3721. @@ -1074,7 +879,7 @@
  3722.  		"`status_point`,`skill_point`,`option`,`karma`,`manner`,`hair`,`hair_color`,"
  3723.  		"`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`rename`,`delete_date`,"
  3724.  		"`robe`,`moves`"
  3725. -		" FROM `%s` WHERE `account_id`='%d' AND `char_num` < '%d'", char_db, sd->account_id, MAX_CHARS)
  3726. +		" FROM `%s` WHERE `account_id`='%d' AND `char_num` < '%d'", schema_config.char_db, sd->account_id, MAX_CHARS)
  3727.  	||	SQL_ERROR == SqlStmt_Execute(stmt)
  3728.  	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 0,  SQLDT_INT,    &p.char_id, 0, NULL, NULL)
  3729.  	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 1,  SQLDT_UCHAR,  &p.slot, 0, NULL, NULL)
  3730. @@ -1159,7 +964,7 @@
  3731.  
  3732.  	memset(p, 0, sizeof(struct mmo_charstatus));
  3733.  
  3734. -	if (save_log) ShowInfo("Char load request (%d)\n", char_id);
  3735. +	if (charserv_config.save_log) ShowInfo("Char load request (%d)\n", char_id);
  3736.  
  3737.  	stmt = SqlStmt_Malloc(sql_handle);
  3738.  	if( stmt == NULL )
  3739. @@ -1175,7 +980,7 @@
  3740.  		"`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`elemental_id`,`hair`,"
  3741.  		"`hair_color`,`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`last_x`,`last_y`,"
  3742.  		"`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,`robe`, `moves`"
  3743. -		" FROM `%s` WHERE `char_id`=? LIMIT 1", char_db)
  3744. +		" FROM `%s` WHERE `char_id`=? LIMIT 1", schema_config.char_db)
  3745.  	||	SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
  3746.  	||	SQL_ERROR == SqlStmt_Execute(stmt)
  3747.  	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 0,  SQLDT_INT,    &p->char_id, 0, NULL, NULL)
  3748. @@ -1268,7 +1073,7 @@
  3749.  
  3750.  	//read memo data
  3751.  	//`memo` (`memo_id`,`char_id`,`map`,`x`,`y`)
  3752. -	if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `map`,`x`,`y` FROM `%s` WHERE `char_id`=? ORDER by `memo_id` LIMIT %d", memo_db, MAX_MEMOPOINTS)
  3753. +	if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `map`,`x`,`y` FROM `%s` WHERE `char_id`=? ORDER by `memo_id` LIMIT %d", schema_config.memo_db, MAX_MEMOPOINTS)
  3754.  	||	SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
  3755.  	||	SQL_ERROR == SqlStmt_Execute(stmt)
  3756.  	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_STRING, &point_map, sizeof(point_map), NULL, NULL)
  3757. @@ -1289,7 +1094,7 @@
  3758.  	StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`, `unique_id`");
  3759.  	for( i = 0; i < MAX_SLOTS; ++i )
  3760.  		StringBuf_Printf(&buf, ", `card%d`", i);
  3761. -	StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", inventory_db, MAX_INVENTORY);
  3762. +	StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", schema_config.inventory_db, MAX_INVENTORY);
  3763.  
  3764.  	if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
  3765.  	||	SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
  3766. @@ -1321,7 +1126,7 @@
  3767.  	StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`");
  3768.  	for( j = 0; j < MAX_SLOTS; ++j )
  3769.  		StringBuf_Printf(&buf, ", `card%d`", j);
  3770. -	StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", cart_db, MAX_CART);
  3771. +	StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", schema_config.cart_db, MAX_CART);
  3772.  
  3773.  	if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
  3774.  	||	SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
  3775. @@ -1351,7 +1156,7 @@
  3776.  
  3777.  	//read skill
  3778.  	//`skill` (`char_id`, `id`, `lv`)
  3779. -	if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `id`, `lv`,`flag` FROM `%s` WHERE `char_id`=? LIMIT %d", skill_db, MAX_SKILL)
  3780. +	if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `id`, `lv`,`flag` FROM `%s` WHERE `char_id`=? LIMIT %d", schema_config.skill_db, MAX_SKILL)
  3781.  	||	SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
  3782.  	||	SQL_ERROR == SqlStmt_Execute(stmt)
  3783.  	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_USHORT, &tmp_skill.id  , 0, NULL, NULL)
  3784. @@ -1373,7 +1178,7 @@
  3785.  
  3786.  	//read friends
  3787.  	//`friends` (`char_id`, `friend_account`, `friend_id`)
  3788. -	if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT c.`account_id`, c.`char_id`, c.`name` FROM `%s` c LEFT JOIN `%s` f ON f.`friend_account` = c.`account_id` AND f.`friend_id` = c.`char_id` WHERE f.`char_id`=? LIMIT %d", char_db, friend_db, MAX_FRIENDS)
  3789. +	if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT c.`account_id`, c.`char_id`, c.`name` FROM `%s` c LEFT JOIN `%s` f ON f.`friend_account` = c.`account_id` AND f.`friend_id` = c.`char_id` WHERE f.`char_id`=? LIMIT %d", schema_config.char_db, schema_config.friend_db, MAX_FRIENDS)
  3790.  	||	SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
  3791.  	||	SQL_ERROR == SqlStmt_Execute(stmt)
  3792.  	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT,    &tmp_friend.account_id, 0, NULL, NULL)
  3793. @@ -1388,7 +1193,7 @@
  3794.  #ifdef HOTKEY_SAVING
  3795.  	//read hotkeys
  3796.  	//`hotkey` (`char_id`, `hotkey`, `type`, `itemskill_id`, `skill_lvl`
  3797. -	if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `hotkey`, `type`, `itemskill_id`, `skill_lvl` FROM `%s` WHERE `char_id`=?", hotkey_db)
  3798. +	if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `hotkey`, `type`, `itemskill_id`, `skill_lvl` FROM `%s` WHERE `char_id`=?", schema_config.hotkey_db)
  3799.  	||	SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
  3800.  	||	SQL_ERROR == SqlStmt_Execute(stmt)
  3801.  	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT,    &hotkey_num, 0, NULL, NULL)
  3802. @@ -1412,7 +1217,7 @@
  3803.  	strcat(t_msg, " mercenary");
  3804.  
  3805.  
  3806. -	if (save_log) ShowInfo("Loaded char (%d - %s): %s\n", char_id, p->name, t_msg);	//ok. all data load successfuly!
  3807. +	if (charserv_config.save_log) ShowInfo("Loaded char (%d - %s): %s\n", char_id, p->name, t_msg);	//ok. all data load successfuly!
  3808.  	SqlStmt_Free(stmt);
  3809.  	StringBuf_Destroy(&buf);
  3810.  
  3811. @@ -1426,7 +1231,7 @@
  3812.  {
  3813.  	char_db_= idb_alloc(DB_OPT_RELEASE_DATA);
  3814.  
  3815. -	ShowStatus("Characters per Account: '%d'.\n", char_per_account);
  3816. +	ShowStatus("Characters per Account: '%d'.\n", char_config.char_per_account);
  3817.  
  3818.  	//the 'set offline' part is now in check_login_conn ...
  3819.  	//if the server connects to loginserver
  3820. @@ -1460,13 +1265,13 @@
  3821.  	Sql_EscapeStringLen(sql_handle, esc_name, sd->new_name, strnlen(sd->new_name, NAME_LENGTH));
  3822.  
  3823.  	// check if the char exist
  3824. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `name` LIKE '%s' LIMIT 1", char_db, esc_name) )
  3825. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `name` LIKE '%s' LIMIT 1", schema_config.char_db, esc_name) )
  3826.  	{
  3827.  		Sql_ShowDebug(sql_handle);
  3828.  		return 4;
  3829.  	}
  3830.  
  3831. -	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `name` = '%s', `rename` = '%d' WHERE `char_id` = '%d'", char_db, esc_name, --char_dat.rename, char_id) )
  3832. +	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `name` = '%s', `rename` = '%d' WHERE `char_id` = '%d'", schema_config.char_db, esc_name, --char_dat.rename, char_id) )
  3833.  	{
  3834.  		Sql_ShowDebug(sql_handle);
  3835.  		return 3;
  3836. @@ -1480,11 +1285,11 @@
  3837.  	memset(sd->new_name,0,sizeof(sd->new_name));
  3838.  
  3839.  	// log change
  3840. -	if( log_char )
  3841. +	if( charserv_config.log_char )
  3842.  	{
  3843.  		if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`time`, `char_msg`,`account_id`,`char_num`,`name`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hair`,`hair_color`)"
  3844.  			"VALUES (NOW(), '%s', '%d', '%d', '%s', '0', '0', '0', '0', '0', '0', '0', '0')",
  3845. -			charlog_db, "change char name", sd->account_id, char_dat.slot, esc_name) )
  3846. +			schema_config.charlog_db, "change char name", sd->account_id, char_dat.slot, esc_name) )
  3847.  			Sql_ShowDebug(sql_handle);
  3848.  	}
  3849.  
  3850. @@ -1509,29 +1314,29 @@
  3851.  		return -2; // control chars in name
  3852.  
  3853.  	// check for reserved names
  3854. -	if( strcmpi(name, wisp_server_name) == 0 )
  3855. +	if( strcmpi(name, charserv_config.wisp_server_name) == 0 )
  3856.  		return -1; // nick reserved for internal server messages
  3857.  
  3858.  	// Check Authorised letters/symbols in the name of the character
  3859. -	if( char_name_option == 1 )
  3860. +	if( charserv_config.char_name_option == 1 )
  3861.  	{ // only letters/symbols in char_name_letters are authorised
  3862.  		for( i = 0; i < NAME_LENGTH && name[i]; i++ )
  3863. -			if( strchr(char_name_letters, name[i]) == NULL )
  3864. +			if( strchr(charserv_config.char_name_letters, name[i]) == NULL )
  3865.  				return -2;
  3866.  	}
  3867. -	else if( char_name_option == 2 )
  3868. +	else if( charserv_config.char_name_option == 2 )
  3869.  	{ // letters/symbols in char_name_letters are forbidden
  3870.  		for( i = 0; i < NAME_LENGTH && name[i]; i++ )
  3871. -			if( strchr(char_name_letters, name[i]) != NULL )
  3872. +			if( strchr(charserv_config.char_name_letters, name[i]) != NULL )
  3873.  				return -2;
  3874.  	}
  3875. -	if( name_ignoring_case ) {
  3876. -		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE BINARY `name` = '%s' LIMIT 1", char_db, esc_name) ) {
  3877. +	if( charserv_config.name_ignoring_case ) {
  3878. +		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE BINARY `name` = '%s' LIMIT 1", schema_config.char_db, esc_name) ) {
  3879.  			Sql_ShowDebug(sql_handle);
  3880.  			return -2;
  3881.  		}
  3882.  	} else {
  3883. -		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `name` = '%s' LIMIT 1", char_db, esc_name) ) {
  3884. +		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `name` = '%s' LIMIT 1", schema_config.char_db, esc_name) ) {
  3885.  			Sql_ShowDebug(sql_handle);
  3886.  			return -2;
  3887.  		}
  3888. @@ -1581,24 +1386,24 @@
  3889.  
  3890.  
  3891.  	// check the number of already existing chars in this account
  3892. -	if( char_per_account != 0 ) {
  3893. -		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d'", char_db, sd->account_id) )
  3894. +	if( char_config.char_per_account != 0 ) {
  3895. +		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d'", schema_config.char_db, sd->account_id) )
  3896.  			Sql_ShowDebug(sql_handle);
  3897. -		if( Sql_NumRows(sql_handle) >= char_per_account )
  3898. +		if( Sql_NumRows(sql_handle) >= char_config.char_per_account )
  3899.  			return -2; // character account limit exceeded
  3900.  	}
  3901.  
  3902.  	// check char slot
  3903. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d' LIMIT 1", char_db, sd->account_id, slot) )
  3904. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d' LIMIT 1", schema_config.char_db, sd->account_id, slot) )
  3905.  		Sql_ShowDebug(sql_handle);
  3906.  	if( Sql_NumRows(sql_handle) > 0 )
  3907.  		return -2; // slot already in use
  3908.  
  3909.  	// validation success, log result
  3910. -	if (log_char) {
  3911. +	if (charserv_config.log_char) {
  3912.  		if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`time`, `char_msg`,`account_id`,`char_num`,`name`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hair`,`hair_color`)"
  3913.  			"VALUES (NOW(), '%s', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
  3914. -			charlog_db, "make new char", sd->account_id, slot, esc_name, str, agi, vit, int_, dex, luk, hair_style, hair_color) )
  3915. +			schema_config.charlog_db, "make new char", sd->account_id, slot, esc_name, str, agi, vit, int_, dex, luk, hair_style, hair_color) )
  3916.  			Sql_ShowDebug(sql_handle);
  3917.  	}
  3918.  #if PACKETVER >= 20120307
  3919. @@ -1606,9 +1411,9 @@
  3920.  	if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`account_id`, `char_num`, `name`, `zeny`, `status_point`,`str`, `agi`, `vit`, `int`, `dex`, `luk`, `max_hp`, `hp`,"
  3921.  		"`max_sp`, `sp`, `hair`, `hair_color`, `last_map`, `last_x`, `last_y`, `save_map`, `save_x`, `save_y`) VALUES ("
  3922.  		"'%d', '%d', '%s', '%d',  '%d','%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d','%d', '%d','%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d')",
  3923. -		char_db, sd->account_id , slot, esc_name, start_zeny, 48, str, agi, vit, int_, dex, luk,
  3924. +		schema_config.char_db, sd->account_id , slot, esc_name, charserv_config.start_zeny, 48, str, agi, vit, int_, dex, luk,
  3925.  		(40 * (100 + vit)/100) , (40 * (100 + vit)/100 ),  (11 * (100 + int_)/100), (11 * (100 + int_)/100), hair_style, hair_color,
  3926. -		mapindex_id2name(start_point.map), start_point.x, start_point.y, mapindex_id2name(start_point.map), start_point.x, start_point.y) )
  3927. +		mapindex_id2name(charserv_config.start_point.map), charserv_config.start_point.x, charserv_config.start_point.y, mapindex_id2name(charserv_config.start_point.map), charserv_config.start_point.x, charserv_config.start_point.y) )
  3928.  	{
  3929.  		Sql_ShowDebug(sql_handle);
  3930.  		return -2; //No, stop the procedure!
  3931. @@ -1616,11 +1421,11 @@
  3932.  #else
  3933.  	//Insert the new char entry to the database
  3934.  	if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`account_id`, `char_num`, `name`, `zeny`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `max_hp`, `hp`,"
  3935. -							   "`max_sp`, `sp`, `hair`, `hair_color`, `last_map`, `last_x`, `last_y`, `save_map`, `save_x`, `save_y`) VALUES ("
  3936. -							   "'%d', '%d', '%s', '%d',  '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d','%d', '%d','%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d')",
  3937. -							   char_db, sd->account_id , slot, esc_name, start_zeny, str, agi, vit, int_, dex, luk,
  3938. -							   (40 * (100 + vit)/100) , (40 * (100 + vit)/100 ),  (11 * (100 + int_)/100), (11 * (100 + int_)/100), hair_style, hair_color,
  3939. -							   mapindex_id2name(start_point.map), start_point.x, start_point.y, mapindex_id2name(start_point.map), start_point.x, start_point.y) )
  3940. +		"`max_sp`, `sp`, `hair`, `hair_color`, `last_map`, `last_x`, `last_y`, `save_map`, `save_x`, `save_y`) VALUES ("
  3941. +		"'%d', '%d', '%s', '%d',  '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d','%d', '%d','%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d')",
  3942. +		char_db, sd->account_id , slot, esc_name, start_zeny, str, agi, vit, int_, dex, luk,
  3943. +		(40 * (100 + vit)/100) , (40 * (100 + vit)/100 ),  (11 * (100 + int_)/100), (11 * (100 + int_)/100), hair_style, hair_color,
  3944. +		mapindex_id2name(start_point.map), start_point.x, start_point.y, mapindex_id2name(start_point.map), start_point.x, start_point.y) )
  3945.  	{
  3946.  		Sql_ShowDebug(sql_handle);
  3947.  		return -2; //No, stop the procedure!
  3948. @@ -1630,7 +1435,7 @@
  3949.  	char_id = (int)Sql_LastInsertId(sql_handle);
  3950.  	//Give the char the default items
  3951.  	for (k = 0; k <= MAX_STARTITEM && start_items[k].nameid != 0; k ++) {
  3952. -		if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `equip`, `identify`) VALUES ('%d', '%d', '%d', '%d', '%d')", inventory_db, char_id, start_items[k].nameid, start_items[k].amount, start_items[k].pos, 1) )
  3953. +		if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `equip`, `identify`) VALUES ('%d', '%d', '%d', '%d', '%d')", schema_config.inventory_db, char_id, start_items[k].nameid, start_items[k].amount, start_items[k].pos, 1) )
  3954.  			Sql_ShowDebug(sql_handle);
  3955.  	}
  3956.  
  3957. @@ -1641,20 +1446,12 @@
  3958.  /*----------------------------------------------------------------------------------------------------------*/
  3959.  /* Divorce Players */
  3960.  /*----------------------------------------------------------------------------------------------------------*/
  3961. -int divorce_char_sql(int partner_id1, int partner_id2)
  3962. -{
  3963. -	unsigned char buf[64];
  3964. -
  3965. -	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `partner_id`='0' WHERE `char_id`='%d' OR `char_id`='%d' LIMIT 2", char_db, partner_id1, partner_id2) )
  3966. +int divorce_char_sql(int partner_id1, int partner_id2){
  3967. +	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `partner_id`='0' WHERE `char_id`='%d' OR `char_id`='%d' LIMIT 2", schema_config.char_db, partner_id1, partner_id2) )
  3968.  		Sql_ShowDebug(sql_handle);
  3969. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE (`nameid`='%d' OR `nameid`='%d') AND (`char_id`='%d' OR `char_id`='%d') LIMIT 2", inventory_db, WEDDING_RING_M, WEDDING_RING_F, partner_id1, partner_id2) )
  3970. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE (`nameid`='%d' OR `nameid`='%d') AND (`char_id`='%d' OR `char_id`='%d') LIMIT 2", schema_config.inventory_db, WEDDING_RING_M, WEDDING_RING_F, partner_id1, partner_id2) )
  3971.  		Sql_ShowDebug(sql_handle);
  3972. -
  3973. -	WBUFW(buf,0) = 0x2b12;
  3974. -	WBUFL(buf,2) = partner_id1;
  3975. -	WBUFL(buf,6) = partner_id2;
  3976. -	mapif_sendall(buf,10);
  3977. -
  3978. +	char_send_ackdivorce(partner_id1, partner_id2);
  3979.  	return 0;
  3980.  }
  3981.  
  3982. @@ -1672,7 +1469,7 @@
  3983.  	char *data;
  3984.  	size_t len;
  3985.  
  3986. -	if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `name`,`account_id`,`party_id`,`guild_id`,`base_level`,`homun_id`,`partner_id`,`father`,`mother`,`elemental_id` FROM `%s` WHERE `char_id`='%d'", char_db, char_id))
  3987. +	if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `name`,`account_id`,`party_id`,`guild_id`,`base_level`,`homun_id`,`partner_id`,`father`,`mother`,`elemental_id` FROM `%s` WHERE `char_id`='%d'", schema_config.char_db, char_id))
  3988.  		Sql_ShowDebug(sql_handle);
  3989.  
  3990.  	if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
  3991. @@ -1698,8 +1495,8 @@
  3992.  
  3993.  	//check for config char del condition [Lupus]
  3994.  	// TODO: Move this out to packet processing (0x68/0x1fb).
  3995. -	if( ( char_del_level > 0 && base_level >= char_del_level )
  3996. -	 || ( char_del_level < 0 && base_level <= -char_del_level )
  3997. +	if( ( char_config.char_del_level > 0 && base_level >= char_config.char_del_level )
  3998. +	 || ( char_config.char_del_level < 0 && base_level <= -char_config.char_del_level )
  3999.  	) {
  4000.  			ShowInfo("Char deletion aborted: %s, BaseLevel: %i\n", name, base_level);
  4001.  			return -1;
  4002. @@ -1714,9 +1511,9 @@
  4003.  	{ // Char is Baby
  4004.  		unsigned char buf[64];
  4005.  
  4006. -		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `child`='0' WHERE `char_id`='%d' OR `char_id`='%d'", char_db, father_id, mother_id) )
  4007. +		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `child`='0' WHERE `char_id`='%d' OR `char_id`='%d'", schema_config.char_db, father_id, mother_id) )
  4008.  			Sql_ShowDebug(sql_handle);
  4009. -		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '410'AND (`char_id`='%d' OR `char_id`='%d')", skill_db, father_id, mother_id) )
  4010. +		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '410'AND (`char_id`='%d' OR `char_id`='%d')", schema_config.skill_db, father_id, mother_id) )
  4011.  			Sql_ShowDebug(sql_handle);
  4012.  
  4013.  		WBUFW(buf,0) = 0x2b25;
  4014. @@ -1732,13 +1529,13 @@
  4015.  
  4016.  	/* delete char's pet */
  4017.  	//Delete the hatched pet if you have one...
  4018. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d' AND `incuvate` = '0'", pet_db, char_id) )
  4019. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d' AND `incuvate` = '0'", schema_config.pet_db, char_id) )
  4020.  		Sql_ShowDebug(sql_handle);
  4021.  
  4022.  	//Delete all pets that are stored in eggs (inventory + cart)
  4023. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` USING `%s` JOIN `%s` ON `pet_id` = `card1`|`card2`<<16 WHERE `%s`.char_id = '%d' AND card0 = -256", pet_db, pet_db, inventory_db, inventory_db, char_id) )
  4024. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` USING `%s` JOIN `%s` ON `pet_id` = `card1`|`card2`<<16 WHERE `%s`.char_id = '%d' AND card0 = -256", schema_config.pet_db, schema_config.pet_db, schema_config.inventory_db, schema_config.inventory_db, char_id) )
  4025.  		Sql_ShowDebug(sql_handle);
  4026. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` USING `%s` JOIN `%s` ON `pet_id` = `card1`|`card2`<<16 WHERE `%s`.char_id = '%d' AND card0 = -256", pet_db, pet_db, cart_db, cart_db, char_id) )
  4027. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` USING `%s` JOIN `%s` ON `pet_id` = `card1`|`card2`<<16 WHERE `%s`.char_id = '%d' AND card0 = -256", schema_config.pet_db, schema_config.pet_db, schema_config.cart_db, schema_config.cart_db, char_id) )
  4028.  		Sql_ShowDebug(sql_handle);
  4029.  
  4030.  	/* remove homunculus */
  4031. @@ -1753,58 +1550,58 @@
  4032.  	mercenary_owner_delete(char_id);
  4033.  
  4034.  	/* delete char's friends list */
  4035. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d'", friend_db, char_id) )
  4036. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d'", schema_config.friend_db, char_id) )
  4037.  		Sql_ShowDebug(sql_handle);
  4038.  
  4039.  	/* delete char from other's friend list */
  4040.  	//NOTE: Won't this cause problems for people who are already online? [Skotlex]
  4041. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `friend_id` = '%d'", friend_db, char_id) )
  4042. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `friend_id` = '%d'", schema_config.friend_db, char_id) )
  4043.  		Sql_ShowDebug(sql_handle);
  4044.  
  4045.  #ifdef HOTKEY_SAVING
  4046.  	/* delete hotkeys */
  4047. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", hotkey_db, char_id) )
  4048. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", schema_config.hotkey_db, char_id) )
  4049.  		Sql_ShowDebug(sql_handle);
  4050.  #endif
  4051.  
  4052.  	/* delete inventory */
  4053. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", inventory_db, char_id) )
  4054. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", schema_config.inventory_db, char_id) )
  4055.  		Sql_ShowDebug(sql_handle);
  4056.  
  4057.  	/* delete cart inventory */
  4058. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", cart_db, char_id) )
  4059. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", schema_config.cart_db, char_id) )
  4060.  		Sql_ShowDebug(sql_handle);
  4061.  
  4062.  	/* delete memo areas */
  4063. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", memo_db, char_id) )
  4064. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", schema_config.memo_db, char_id) )
  4065.  		Sql_ShowDebug(sql_handle);
  4066.  
  4067.  	/* delete character registry */
  4068. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) )
  4069. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", schema_config.reg_db, char_id) )
  4070.  		Sql_ShowDebug(sql_handle);
  4071.  
  4072.  	/* delete skills */
  4073. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", skill_db, char_id) )
  4074. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", schema_config.skill_db, char_id) )
  4075.  		Sql_ShowDebug(sql_handle);
  4076.  
  4077.  	/* delete mails (only received) */
  4078. -	if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `dest_id`='%d'", mail_db, char_id))
  4079. +	if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `dest_id`='%d'", schema_config.mail_db, char_id))
  4080.  		Sql_ShowDebug(sql_handle);
  4081.  
  4082.  #ifdef ENABLE_SC_SAVING
  4083.  	/* status changes */
  4084. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_id`='%d'", scdata_db, account_id, char_id) )
  4085. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_id`='%d'", schema_config.scdata_db, account_id, char_id) )
  4086.  		Sql_ShowDebug(sql_handle);
  4087.  #endif
  4088.  
  4089. -	if (log_char) {
  4090. +	if (charserv_config.log_char) {
  4091.  		if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s`(`time`, `account_id`,`char_num`,`char_msg`,`name`) VALUES (NOW(), '%d', '%d', 'Deleted char (CID %d)', '%s')",
  4092. -			charlog_db, account_id, 0, char_id, esc_name) )
  4093. +			schema_config.charlog_db, account_id, 0, char_id, esc_name) )
  4094.  			Sql_ShowDebug(sql_handle);
  4095.  	}
  4096.  
  4097.  	/* delete character */
  4098. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", char_db, char_id) )
  4099. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", schema_config.char_db, char_id) )
  4100.  		Sql_ShowDebug(sql_handle);
  4101.  
  4102.  	/* No need as we used inter_guild_leave [Skotlex]
  4103. @@ -1813,7 +1610,7 @@
  4104.  		Sql_ShowDebug(sql_handle);
  4105.  	*/
  4106.  
  4107. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `char_id` = '%d'", guild_db, char_id) )
  4108. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `char_id` = '%d'", schema_config.guild_db, char_id) )
  4109.  		Sql_ShowDebug(sql_handle);
  4110.  	else if( Sql_NumRows(sql_handle) > 0 )
  4111.  		mapif_parse_BreakGuild(0,guild_id);
  4112. @@ -1841,7 +1638,6 @@
  4113.  // Writes char data to the buffer in the format used by the client.
  4114.  // Used in packets 0x6b (chars info) and 0x6d (new char info)
  4115.  // Returns the size
  4116. -#define MAX_CHAR_BUF 144 //Max size (for WFIFOHEAD calls)
  4117.  int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p)
  4118.  {
  4119.  	unsigned short offset = 0;
  4120. @@ -1908,9 +1704,9 @@
  4121.  #if PACKETVER != 20111116 //2011-11-16 wants 136, ask gravity.
  4122.  	#if PACKETVER >= 20110928
  4123.  		// change slot feature (0 = disabled, otherwise enabled)
  4124. -		if( !char_move_enabled )
  4125. +		if( (charmove_config.char_move_enabled)==0 )
  4126.  			WBUFL(buf,132) = 0;
  4127. -		else if( char_moves_unlimited )
  4128. +		else if( charmove_config.char_moves_unlimited )
  4129.  			WBUFL(buf,132) = 1;
  4130.  		else
  4131.  			WBUFL(buf,132) = max( 0, (int)p->character_moves );
  4132. @@ -1925,101 +1721,9 @@
  4133.  	return 106+offset;
  4134.  }
  4135.  
  4136. -//----------------------------------------
  4137. -// Tell client how many pages, kRO sends 17 (Yommy)
  4138. -//----------------------------------------
  4139. -void char_charlist_notify( int fd, struct char_session_data* sd ){
  4140. -	WFIFOHEAD(fd, 6);
  4141. -	WFIFOW(fd, 0) = 0x9a0;
  4142. -	// pages to req / send them all in 1 until mmo_chars_fromsql can split them up
  4143. -	WFIFOL(fd, 2) = (sd->char_slots>3)?sd->char_slots/3:1; //int TotalCnt (nb page to load)
  4144. -	WFIFOSET(fd,6);
  4145. -}
  4146. -
  4147. -void char_block_character( int fd, struct char_session_data* sd ){
  4148. -	WFIFOHEAD(fd, 4);
  4149. -	WFIFOW(fd, 0) = 0x20d;
  4150. -	WFIFOW(fd, 2) = 4; //packet len
  4151. -	WFIFOSET(fd,4);
  4152. -}
  4153. -
  4154. -void mmo_char_send099d(int fd, struct char_session_data *sd) {
  4155. -	WFIFOHEAD(fd,4 + (MAX_CHARS*MAX_CHAR_BUF));
  4156. -	WFIFOW(fd,0) = 0x99d;
  4157. -	WFIFOW(fd,2) = mmo_chars_fromsql(sd, WFIFOP(fd,4)) + 4;
  4158. -	WFIFOSET(fd,WFIFOW(fd,2));
  4159. -}
  4160. -
  4161. -//struct PACKET_CH_CHARLIST_REQ { 0x0 short PacketType}
  4162. -void char_parse_req_charlist(int fd, struct char_session_data* sd){
  4163. -	mmo_char_send099d(fd,sd);
  4164. -}
  4165. -
  4166. -//----------------------------------------
  4167. -// Function to send characters to a player
  4168. -//----------------------------------------
  4169. -int mmo_char_send006b(int fd, struct char_session_data* sd){
  4170. -	int j, offset = 0;
  4171. -	//bool newvers = (sd->version >= date2version(20100413) );
  4172. -#if PACKETVER >= 20100413
  4173. -	//if(newvers) //20100413
  4174. -		offset += 3;
  4175. -#endif
  4176. -	if (save_log)
  4177. -		ShowInfo("Loading Char Data ("CL_BOLD"%d"CL_RESET")\n",sd->account_id);
  4178. -
  4179. -	j = 24 + offset; // offset
  4180. -	WFIFOHEAD(fd,j + MAX_CHARS*MAX_CHAR_BUF);
  4181. -	WFIFOW(fd,0) = 0x6b;
  4182. -#if PACKETVER >= 20100413
  4183. -//	if(newvers){ //20100413
  4184. -		WFIFOB(fd,4) = MAX_CHARS; // Max slots.
  4185. -		WFIFOB(fd,5) = sd->char_slots; // Available slots. (PremiumStartSlot)
  4186. -		WFIFOB(fd,6) = MAX_CHARS; // Premium slots. (Any existent chars past sd->char_slots but within MAX_CHARS will show a 'Premium Service' in red)
  4187. -//	}
  4188. -#endif
  4189. -	memset(WFIFOP(fd,4 + offset), 0, 20); // unknown bytes
  4190. -	j+=mmo_chars_fromsql(sd, WFIFOP(fd,j));
  4191. -	WFIFOW(fd,2) = j; // packet len
  4192. -	WFIFOSET(fd,j);
  4193. -
  4194. -	return 0;
  4195. -}
  4196. -
  4197. -//----------------------------------------
  4198. -// Notify client about charselect window data [Ind]
  4199. -//----------------------------------------
  4200. -void mmo_char_send082d(int fd, struct char_session_data* sd) {
  4201. -	if (save_log)
  4202. -		ShowInfo("Loading Char Data ("CL_BOLD"%d"CL_RESET")\n",sd->account_id);
  4203. -	WFIFOHEAD(fd,29);
  4204. -	WFIFOW(fd,0) = 0x82d;
  4205. -	WFIFOW(fd,2) = 29;
  4206. -	WFIFOB(fd,4) = sd->char_slots;
  4207. -	WFIFOB(fd,5) = MAX_CHARS - sd->char_slots;
  4208. -	WFIFOB(fd,6) = MAX_CHARS - sd->char_slots;
  4209. -	WFIFOB(fd,7) = sd->char_slots;
  4210. -	WFIFOB(fd,8) = sd->char_slots;
  4211. -	memset(WFIFOP(fd,9), 0, 20); // unused bytes
  4212. -	WFIFOSET(fd,29);
  4213. -}
  4214. -
  4215. -void mmo_char_send(int fd, struct char_session_data* sd){
  4216. -	//ShowInfo("sd->version = %d\n",sd->version);
  4217. -#if PACKETVER >= 20130000
  4218. -	//if(sd->version > date2version(20130000) ){
  4219. -		mmo_char_send082d(fd,sd);
  4220. -		char_charlist_notify(fd,sd);
  4221. -		char_block_character(fd,sd);
  4222. -#endif
  4223. -	//}
  4224. -	//@FIXME dump from kro doesn't show 6b transmission
  4225. -	mmo_char_send006b(fd,sd);
  4226. -}
  4227. -
  4228.  int char_married(int pl1, int pl2)
  4229.  {
  4230. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `partner_id` FROM `%s` WHERE `char_id` = '%d'", char_db, pl1) )
  4231. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `partner_id` FROM `%s` WHERE `char_id` = '%d'", schema_config.char_db, pl1) )
  4232.  		Sql_ShowDebug(sql_handle);
  4233.  	else if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
  4234.  	{
  4235. @@ -2038,7 +1742,7 @@
  4236.  
  4237.  int char_child(int parent_id, int child_id)
  4238.  {
  4239. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `child` FROM `%s` WHERE `char_id` = '%d'", char_db, parent_id) )
  4240. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `child` FROM `%s` WHERE `char_id` = '%d'", schema_config.char_db, parent_id) )
  4241.  		Sql_ShowDebug(sql_handle);
  4242.  	else if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
  4243.  	{
  4244. @@ -2057,7 +1761,7 @@
  4245.  
  4246.  int char_family(int cid1, int cid2, int cid3)
  4247.  {
  4248. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`partner_id`,`child` FROM `%s` WHERE `char_id` IN ('%d','%d','%d')", char_db, cid1, cid2, cid3) )
  4249. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`partner_id`,`child` FROM `%s` WHERE `char_id` IN ('%d','%d','%d')", schema_config.char_db, cid1, cid2, cid3) )
  4250.  		Sql_ShowDebug(sql_handle);
  4251.  	else while( SQL_SUCCESS == Sql_NextRow(sql_handle) )
  4252.  	{
  4253. @@ -2096,8 +1800,9 @@
  4254.  		set_eof(i);
  4255.  }
  4256.  
  4257. -static void char_auth_ok(int fd, struct char_session_data *sd)
  4258. -{
  4259. +
  4260. +
  4261. +void char_auth_ok(int fd, struct char_session_data *sd) {
  4262.  	struct online_char_data* character;
  4263.  
  4264.  	if( (character = (struct online_char_data*)idb_get(online_char_db, sd->account_id)) != NULL )
  4265. @@ -2107,30 +1812,18 @@
  4266.  			mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
  4267.  			if (character->waiting_disconnect == INVALID_TIMER)
  4268.  				character->waiting_disconnect = add_timer(gettick()+20000, chardb_waiting_disconnect, character->account_id, 0);
  4269. -			WFIFOHEAD(fd,3);
  4270. -			WFIFOW(fd,0) = 0x81;
  4271. -			WFIFOB(fd,2) = 8;
  4272. -			WFIFOSET(fd,3);
  4273. +			char_send_auth_result(fd,8);
  4274.  			return;
  4275.  		}
  4276.  		if (character->fd >= 0 && character->fd != fd)
  4277.  		{	//There's already a connection from this account that hasn't picked a char yet.
  4278. -			WFIFOHEAD(fd,3);
  4279. -			WFIFOW(fd,0) = 0x81;
  4280. -			WFIFOB(fd,2) = 8;
  4281. -			WFIFOSET(fd,3);
  4282. +			char_send_auth_result(fd,8);
  4283.  			return;
  4284.  		}
  4285.  		character->fd = fd;
  4286.  	}
  4287.  
  4288. -	if (login_fd > 0) {
  4289. -		// request account data
  4290. -		WFIFOHEAD(login_fd,6);
  4291. -		WFIFOW(login_fd,0) = 0x2716;
  4292. -		WFIFOL(login_fd,2) = sd->account_id;
  4293. -		WFIFOSET(login_fd,6);
  4294. -	}
  4295. +	char_send_reqaccdata(login_fd,sd); // request account data
  4296.  
  4297.  	// mark session as 'authed'
  4298.  	sd->auth = true;
  4299. @@ -2141,469 +1834,6 @@
  4300.  	// continues when account data is received...
  4301.  }
  4302.  
  4303. -int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data);
  4304. -void mapif_server_reset(int id);
  4305. -
  4306. -
  4307. -/// Resets all the data.
  4308. -void loginif_reset(void)
  4309. -{
  4310. -	int id;
  4311. -	// TODO kick everyone out and reset everything or wait for connect and try to reaquire locks [FlavioJS]
  4312. -	for( id = 0; id < ARRAYLENGTH(server); ++id )
  4313. -		mapif_server_reset(id);
  4314. -	flush_fifos();
  4315. -	exit(EXIT_FAILURE);
  4316. -}
  4317. -
  4318. -
  4319. -/// Checks the conditions for the server to stop.
  4320. -/// Releases the cookie when all characters are saved.
  4321. -/// If all the conditions are met, it stops the core loop.
  4322. -void loginif_check_shutdown(void)
  4323. -{
  4324. -	if( runflag != CHARSERVER_ST_SHUTDOWN )
  4325. -		return;
  4326. -	runflag = CORE_ST_STOP;
  4327. -}
  4328. -
  4329. -
  4330. -/// Called when the connection to Login Server is disconnected.
  4331. -void loginif_on_disconnect(void)
  4332. -{
  4333. -	ShowWarning("Connection to Login Server lost.\n\n");
  4334. -}
  4335. -
  4336. -
  4337. -/// Called when all the connection steps are completed.
  4338. -void loginif_on_ready(void)
  4339. -{
  4340. -	int i;
  4341. -
  4342. -	loginif_check_shutdown();
  4343. -
  4344. -	//Send online accounts to login server.
  4345. -	send_accounts_tologin(INVALID_TIMER, gettick(), 0, 0);
  4346. -
  4347. -	// if no map-server already connected, display a message...
  4348. -	ARR_FIND( 0, ARRAYLENGTH(server), i, server[i].fd > 0 && server[i].map[0] );
  4349. -	if( i == ARRAYLENGTH(server) )
  4350. -		ShowStatus("Awaiting maps from map-server.\n");
  4351. -}
  4352. -
  4353. -
  4354. -int parse_fromlogin(int fd) {
  4355. -	struct char_session_data* sd = NULL;
  4356. -	int i;
  4357. -
  4358. -	// only process data from the login-server
  4359. -	if( fd != login_fd ) {
  4360. -		ShowDebug("parse_fromlogin: Disconnecting invalid session #%d (is not the login-server)\n", fd);
  4361. -		do_close(fd);
  4362. -		return 0;
  4363. -	}
  4364. -
  4365. -	if( session[fd]->flag.eof ) {
  4366. -		do_close(fd);
  4367. -		login_fd = -1;
  4368. -		loginif_on_disconnect();
  4369. -		return 0;
  4370. -	} else if ( session[fd]->flag.ping ) {/* we've reached stall time */
  4371. -		if( DIFF_TICK(last_tick, session[fd]->rdata_tick) > (stall_time * 2) ) {/* we can't wait any longer */
  4372. -			set_eof(fd);
  4373. -			return 0;
  4374. -		} else if( session[fd]->flag.ping != 2 ) { /* we haven't sent ping out yet */
  4375. -			WFIFOHEAD(fd,2);// sends a ping packet to login server (will receive pong 0x2718)
  4376. -			WFIFOW(fd,0) = 0x2719;
  4377. -			WFIFOSET(fd,2);
  4378. -
  4379. -			session[fd]->flag.ping = 2;
  4380. -		}
  4381. -	}
  4382. -
  4383. -	sd = (struct char_session_data*)session[fd]->session_data;
  4384. -
  4385. -	while(RFIFOREST(fd) >= 2) {
  4386. -		uint16 command = RFIFOW(fd,0);
  4387. -
  4388. -		switch( command )
  4389. -		{
  4390. -
  4391. -		// acknowledgement of connect-to-loginserver request
  4392. -		case 0x2711:
  4393. -			if (RFIFOREST(fd) < 3)
  4394. -				return 0;
  4395. -
  4396. -			if (RFIFOB(fd,2)) {
  4397. -				//printf("connect login server error : %d\n", RFIFOB(fd,2));
  4398. -				ShowError("Can not connect to login-server.\n");
  4399. -				ShowError("The server communication passwords (default s1/p1) are probably invalid.\n");
  4400. -				ShowError("Also, please make sure your login db has the correct communication username/passwords and the gender of the account is S.\n");
  4401. -				ShowError("The communication passwords are set in map_athena.conf and char_athena.conf\n");
  4402. -				set_eof(fd);
  4403. -				return 0;
  4404. -			} else {
  4405. -				ShowStatus("Connected to login-server (connection #%d).\n", fd);
  4406. -				loginif_on_ready();
  4407. -			}
  4408. -			RFIFOSKIP(fd,3);
  4409. -		break;
  4410. -
  4411. -		// acknowledgement of account authentication request
  4412. -		case 0x2713:
  4413. -			if (RFIFOREST(fd) < 25)
  4414. -				return 0;
  4415. -		{
  4416. -			int account_id = RFIFOL(fd,2);
  4417. -			uint32 login_id1 = RFIFOL(fd,6);
  4418. -			uint32 login_id2 = RFIFOL(fd,10);
  4419. -			uint8 sex = RFIFOB(fd,14);
  4420. -			uint8 result = RFIFOB(fd,15);
  4421. -			int request_id = RFIFOL(fd,16);
  4422. -			uint32 version = RFIFOL(fd,20);
  4423. -			uint8 clienttype = RFIFOB(fd,24);
  4424. -			RFIFOSKIP(fd,25);
  4425. -
  4426. -			if( session_isActive(request_id) && (sd=(struct char_session_data*)session[request_id]->session_data) &&
  4427. -				!sd->auth && sd->account_id == account_id && sd->login_id1 == login_id1 && sd->login_id2 == login_id2 && sd->sex == sex )
  4428. -			{
  4429. -				int client_fd = request_id;
  4430. -				sd->version = version;
  4431. -				sd->clienttype = clienttype;
  4432. -				switch( result )
  4433. -				{
  4434. -				case 0:// ok
  4435. -					char_auth_ok(client_fd, sd);
  4436. -					break;
  4437. -				case 1:// auth failed
  4438. -					WFIFOHEAD(client_fd,3);
  4439. -					WFIFOW(client_fd,0) = 0x6c;
  4440. -					WFIFOB(client_fd,2) = 0;// rejected from server
  4441. -					WFIFOSET(client_fd,3);
  4442. -					break;
  4443. -				}
  4444. -			}
  4445. -		}
  4446. -		break;
  4447. -
  4448. -		case 0x2717: // account data
  4449. -			if (RFIFOREST(fd) < 72)
  4450. -				return 0;
  4451. -
  4452. -			// find the authenticated session with this account id
  4453. -			ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->auth && sd->account_id == RFIFOL(fd,2) );
  4454. -			if( i < fd_max )
  4455. -			{
  4456. -				int server_id;
  4457. -				memcpy(sd->email, RFIFOP(fd,6), 40);
  4458. -				sd->expiration_time = (time_t)RFIFOL(fd,46);
  4459. -				sd->group_id = RFIFOB(fd,50);
  4460. -				sd->char_slots = RFIFOB(fd,51);
  4461. -				if( sd->char_slots > MAX_CHARS ) {
  4462. -					ShowError("Account '%d' `character_slots` column is higher than supported MAX_CHARS (%d), update MAX_CHARS in mmo.h! capping to MAX_CHARS...\n",sd->account_id,sd->char_slots);
  4463. -					sd->char_slots = MAX_CHARS;/* cap to maximum */
  4464. -				} else if ( !sd->char_slots )/* no value aka 0 in sql */
  4465. -					sd->char_slots = MAX_CHARS;/* cap to maximum */
  4466. -				safestrncpy(sd->birthdate, (const char*)RFIFOP(fd,52), sizeof(sd->birthdate));
  4467. -				safestrncpy(sd->pincode, (const char*)RFIFOP(fd,63), sizeof(sd->pincode));
  4468. -				sd->pincode_change = (time_t)RFIFOL(fd,68);
  4469. -				ARR_FIND( 0, ARRAYLENGTH(server), server_id, server[server_id].fd > 0 && server[server_id].map[0] );
  4470. -				// continued from char_auth_ok...
  4471. -				if( server_id == ARRAYLENGTH(server) || //server not online, bugreport:2359
  4472. -					(max_connect_user == 0 && sd->group_id != gm_allow_group) ||
  4473. -					( max_connect_user > 0 && count_users() >= max_connect_user && sd->group_id != gm_allow_group ) ) {
  4474. -					// refuse connection (over populated)
  4475. -					WFIFOHEAD(i,3);
  4476. -					WFIFOW(i,0) = 0x6c;
  4477. -					WFIFOW(i,2) = 0;
  4478. -					WFIFOSET(i,3);
  4479. -				} else {
  4480. -					// send characters to player
  4481. -					mmo_char_send(i, sd);
  4482. -#if PACKETVER >=  20110309
  4483. -					if( pincode_enabled ){
  4484. -						// PIN code system enabled
  4485. -						if( strlen( sd->pincode ) <= 0 ){
  4486. -							// No PIN code has been set yet
  4487. -							if( pincode_force ){
  4488. -								pincode_sendstate( i, sd, PINCODE_NEW );
  4489. -							}else{
  4490. -								pincode_sendstate( i, sd, PINCODE_PASSED );
  4491. -							}
  4492. -						}else{
  4493. -							if( !pincode_changetime || ( sd->pincode_change + pincode_changetime ) > time(NULL) ){
  4494. -								struct online_char_data* node = (struct online_char_data*)idb_get( online_char_db, sd->account_id );
  4495. -
  4496. -								if( node != NULL && node->pincode_success ){
  4497. -									// User has already passed the check
  4498. -									pincode_sendstate( i, sd, PINCODE_PASSED );
  4499. -								}else{
  4500. -									// Ask user for his PIN code
  4501. -									pincode_sendstate( i, sd, PINCODE_ASK );
  4502. -								}
  4503. -							}else{
  4504. -								// User hasnt changed his PIN code too long
  4505. -								pincode_sendstate( i, sd, PINCODE_EXPIRED );
  4506. -							}
  4507. -						}
  4508. -					}else{
  4509. -						// PIN code system disabled
  4510. -						pincode_sendstate( i, sd, PINCODE_OK );
  4511. -					}
  4512. -#endif
  4513. -				}
  4514. -			}
  4515. -			RFIFOSKIP(fd,72);
  4516. -		break;
  4517. -
  4518. -		// login-server alive packet
  4519. -		case 0x2718:
  4520. -			if (RFIFOREST(fd) < 2)
  4521. -				return 0;
  4522. -			RFIFOSKIP(fd,2);
  4523. -			session[fd]->flag.ping = 0;
  4524. -		break;
  4525. -
  4526. -		// changesex reply
  4527. -		case 0x2723:
  4528. -			if (RFIFOREST(fd) < 7)
  4529. -				return 0;
  4530. -		{
  4531. -			unsigned char buf[7];
  4532. -
  4533. -			int acc = RFIFOL(fd,2);
  4534. -			int sex = RFIFOB(fd,6);
  4535. -			RFIFOSKIP(fd,7);
  4536. -
  4537. -			if( acc > 0 )
  4538. -			{// TODO: Is this even possible?
  4539. -				int char_id[MAX_CHARS];
  4540. -				int class_[MAX_CHARS];
  4541. -				int guild_id[MAX_CHARS];
  4542. -				int num;
  4543. -				char* data;
  4544. -
  4545. -				struct auth_node* node = (struct auth_node*)idb_get(auth_db, acc);
  4546. -				if( node != NULL )
  4547. -					node->sex = sex;
  4548. -
  4549. -				// get characters
  4550. -				if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`class`,`guild_id` FROM `%s` WHERE `account_id` = '%d'", char_db, acc) )
  4551. -					Sql_ShowDebug(sql_handle);
  4552. -				for( i = 0; i < MAX_CHARS && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
  4553. -				{
  4554. -					Sql_GetData(sql_handle, 0, &data, NULL); char_id[i] = atoi(data);
  4555. -					Sql_GetData(sql_handle, 1, &data, NULL); class_[i] = atoi(data);
  4556. -					Sql_GetData(sql_handle, 2, &data, NULL); guild_id[i] = atoi(data);
  4557. -				}
  4558. -				num = i;
  4559. -				for( i = 0; i < num; ++i )
  4560. -				{
  4561. -					if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER ||
  4562. -						class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY ||
  4563. -						class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER ||
  4564. -						class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER ||
  4565. -						class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T ||
  4566. -						class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER ||
  4567. -						class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO )
  4568. -					{
  4569. -						// job modification
  4570. -						if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER )
  4571. -							class_[i] = (sex ? JOB_BARD : JOB_DANCER);
  4572. -						else if( class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY )
  4573. -							class_[i] = (sex ? JOB_CLOWN : JOB_GYPSY);
  4574. -						else if( class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER )
  4575. -							class_[i] = (sex ? JOB_BABY_BARD : JOB_BABY_DANCER);
  4576. -						else if( class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER )
  4577. -							class_[i] = (sex ? JOB_MINSTREL : JOB_WANDERER);
  4578. -						else if( class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T )
  4579. -							class_[i] = (sex ? JOB_MINSTREL_T : JOB_WANDERER_T);
  4580. -						else if( class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER )
  4581. -							class_[i] = (sex ? JOB_BABY_MINSTREL : JOB_BABY_WANDERER);
  4582. -						else if( class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO )
  4583. -							class_[i] = (sex ? JOB_KAGEROU : JOB_OBORO);
  4584. -					}
  4585. -
  4586. -					if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d', `weapon`='0', `shield`='0', `head_top`='0', `head_mid`='0', `head_bottom`='0' WHERE `char_id`='%d'", char_db, class_[i], char_id[i]) )
  4587. -						Sql_ShowDebug(sql_handle);
  4588. -
  4589. -					if( guild_id[i] )// If there is a guild, update the guild_member data [Skotlex]
  4590. -						inter_guild_sex_changed(guild_id[i], acc, char_id[i], sex);
  4591. -				}
  4592. -				Sql_FreeResult(sql_handle);
  4593. -
  4594. -				// disconnect player if online on char-server
  4595. -				disconnect_player(acc);
  4596. -			}
  4597. -
  4598. -			// notify all mapservers about this change
  4599. -			WBUFW(buf,0) = 0x2b0d;
  4600. -			WBUFL(buf,2) = acc;
  4601. -			WBUFB(buf,6) = sex;
  4602. -			mapif_sendall(buf, 7);
  4603. -		}
  4604. -		break;
  4605. -
  4606. -		// reply to an account_reg2 registry request
  4607. -		case 0x2729:
  4608. -			if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
  4609. -				return 0;
  4610. -
  4611. -		{	//Receive account_reg2 registry, forward to map servers.
  4612. -			unsigned char buf[13+ACCOUNT_REG2_NUM*sizeof(struct global_reg)];
  4613. -			memcpy(buf,RFIFOP(fd,0), RFIFOW(fd,2));
  4614. -			WBUFW(buf,0) = 0x3804; //Map server can now receive all kinds of reg values with the same packet. [Skotlex]
  4615. -			mapif_sendall(buf, WBUFW(buf,2));
  4616. -			RFIFOSKIP(fd, RFIFOW(fd,2));
  4617. -		}
  4618. -		break;
  4619. -
  4620. -		// State change of account/ban notification (from login-server)
  4621. -		case 0x2731:
  4622. -			if (RFIFOREST(fd) < 11)
  4623. -				return 0;
  4624. -
  4625. -		{	// send to all map-servers to disconnect the player
  4626. -			unsigned char buf[11];
  4627. -			WBUFW(buf,0) = 0x2b14;
  4628. -			WBUFL(buf,2) = RFIFOL(fd,2);
  4629. -			WBUFB(buf,6) = RFIFOB(fd,6); // 0: change of statut, 1: ban
  4630. -			WBUFL(buf,7) = RFIFOL(fd,7); // status or final date of a banishment
  4631. -			mapif_sendall(buf, 11);
  4632. -		}
  4633. -			// disconnect player if online on char-server
  4634. -			disconnect_player(RFIFOL(fd,2));
  4635. -
  4636. -			RFIFOSKIP(fd,11);
  4637. -		break;
  4638. -
  4639. -		// Login server request to kick a character out. [Skotlex]
  4640. -		case 0x2734:
  4641. -			if (RFIFOREST(fd) < 6)
  4642. -				return 0;
  4643. -		{
  4644. -			int aid = RFIFOL(fd,2);
  4645. -			struct online_char_data* character = (struct online_char_data*)idb_get(online_char_db, aid);
  4646. -			RFIFOSKIP(fd,6);
  4647. -			if( character != NULL )
  4648. -			{// account is already marked as online!
  4649. -				if( character->server > -1 )
  4650. -				{	//Kick it from the map server it is on.
  4651. -					mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
  4652. -					if (character->waiting_disconnect == INVALID_TIMER)
  4653. -						character->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, chardb_waiting_disconnect, character->account_id, 0);
  4654. -				}
  4655. -				else
  4656. -				{// Manual kick from char server.
  4657. -					struct char_session_data *tsd;
  4658. -					int i;
  4659. -					ARR_FIND( 0, fd_max, i, session[i] && (tsd = (struct char_session_data*)session[i]->session_data) && tsd->account_id == aid );
  4660. -					if( i < fd_max )
  4661. -					{
  4662. -						WFIFOHEAD(i,3);
  4663. -						WFIFOW(i,0) = 0x81;
  4664. -						WFIFOB(i,2) = 2; // "Someone has already logged in with this id"
  4665. -						WFIFOSET(i,3);
  4666. -						set_eof(i);
  4667. -					}
  4668. -					else // still moving to the map-server
  4669. -						set_char_offline(-1, aid);
  4670. -				}
  4671. -			}
  4672. -			idb_remove(auth_db, aid);// reject auth attempts from map-server
  4673. -		}
  4674. -		break;
  4675. -
  4676. -		// ip address update signal from login server
  4677. -		case 0x2735:
  4678. -		{
  4679. -			unsigned char buf[2];
  4680. -			uint32 new_ip = 0;
  4681. -
  4682. -			WBUFW(buf,0) = 0x2b1e;
  4683. -			mapif_sendall(buf, 2);
  4684. -
  4685. -			new_ip = host2ip(login_ip_str);
  4686. -			if (new_ip && new_ip != login_ip)
  4687. -				login_ip = new_ip; //Update login ip, too.
  4688. -
  4689. -			new_ip = host2ip(char_ip_str);
  4690. -			if (new_ip && new_ip != char_ip)
  4691. -			{	//Update ip.
  4692. -				char_ip = new_ip;
  4693. -				ShowInfo("Updating IP for [%s].\n", char_ip_str);
  4694. -				// notify login server about the change
  4695. -				WFIFOHEAD(fd,6);
  4696. -				WFIFOW(fd,0) = 0x2736;
  4697. -				WFIFOL(fd,2) = htonl(char_ip);
  4698. -				WFIFOSET(fd,6);
  4699. -			}
  4700. -
  4701. -			RFIFOSKIP(fd,2);
  4702. -		}
  4703. -		break;
  4704. -
  4705. -		default:
  4706. -			ShowError("Unknown packet 0x%04x received from login-server, disconnecting.\n", command);
  4707. -			set_eof(fd);
  4708. -			return 0;
  4709. -		}
  4710. -	}
  4711. -
  4712. -	RFIFOFLUSH(fd);
  4713. -	return 0;
  4714. -}
  4715. -
  4716. -int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data);
  4717. -int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data);
  4718. -
  4719. -void do_init_loginif(void)
  4720. -{
  4721. -	// establish char-login connection if not present
  4722. -	add_timer_func_list(check_connect_login_server, "check_connect_login_server");
  4723. -	add_timer_interval(gettick() + 1000, check_connect_login_server, 0, 0, 10 * 1000);
  4724. -
  4725. -	// send a list of all online account IDs to login server
  4726. -	add_timer_func_list(send_accounts_tologin, "send_accounts_tologin");
  4727. -	add_timer_interval(gettick() + 1000, send_accounts_tologin, 0, 0, 3600 * 1000); //Sync online accounts every hour
  4728. -}
  4729. -
  4730. -void do_final_loginif(void)
  4731. -{
  4732. -	if( login_fd != -1 )
  4733. -	{
  4734. -		do_close(login_fd);
  4735. -		login_fd = -1;
  4736. -	}
  4737. -}
  4738. -
  4739. -int request_accreg2(int account_id, int char_id)
  4740. -{
  4741. -	if (login_fd > 0) {
  4742. -		WFIFOHEAD(login_fd,10);
  4743. -		WFIFOW(login_fd,0) = 0x272e;
  4744. -		WFIFOL(login_fd,2) = account_id;
  4745. -		WFIFOL(login_fd,6) = char_id;
  4746. -		WFIFOSET(login_fd,10);
  4747. -		return 1;
  4748. -	}
  4749. -	return 0;
  4750. -}
  4751. -
  4752. -//Send packet forward to login-server for account saving
  4753. -int save_accreg2(unsigned char* buf, int len)
  4754. -{
  4755. -	if (login_fd > 0) {
  4756. -		WFIFOHEAD(login_fd,len+4);
  4757. -		memcpy(WFIFOP(login_fd,4), buf, len);
  4758. -		WFIFOW(login_fd,0) = 0x2728;
  4759. -		WFIFOW(login_fd,2) = len+4;
  4760. -		WFIFOSET(login_fd,len+4);
  4761. -		return 1;
  4762. -	}
  4763. -	return 0;
  4764. -}
  4765. -
  4766.  void char_read_fame_list(void)
  4767.  {
  4768.  	int i;
  4769. @@ -2615,7 +1845,7 @@
  4770.  	memset(chemist_fame_list, 0, sizeof(chemist_fame_list));
  4771.  	memset(taekwon_fame_list, 0, sizeof(taekwon_fame_list));
  4772.  	// Build Blacksmith ranking list
  4773. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`fame`,`name` FROM `%s` WHERE `fame`>0 AND (`class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d') ORDER BY `fame` DESC LIMIT 0,%d", char_db, JOB_BLACKSMITH, JOB_WHITESMITH, JOB_BABY_BLACKSMITH, JOB_MECHANIC, JOB_MECHANIC_T, JOB_BABY_MECHANIC, fame_list_size_smith) )
  4774. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`fame`,`name` FROM `%s` WHERE `fame`>0 AND (`class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d') ORDER BY `fame` DESC LIMIT 0,%d", schema_config.char_db, JOB_BLACKSMITH, JOB_WHITESMITH, JOB_BABY_BLACKSMITH, JOB_MECHANIC, JOB_MECHANIC_T, JOB_BABY_MECHANIC, fame_list_size_smith) )
  4775.  		Sql_ShowDebug(sql_handle);
  4776.  	for( i = 0; i < fame_list_size_smith && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
  4777.  	{
  4778. @@ -2630,7 +1860,7 @@
  4779.  		memcpy(smith_fame_list[i].name, data, min(len, NAME_LENGTH));
  4780.  	}
  4781.  	// Build Alchemist ranking list
  4782. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`fame`,`name` FROM `%s` WHERE `fame`>0 AND (`class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d') ORDER BY `fame` DESC LIMIT 0,%d", char_db, JOB_ALCHEMIST, JOB_CREATOR, JOB_BABY_ALCHEMIST, JOB_GENETIC, JOB_GENETIC_T, JOB_BABY_GENETIC, fame_list_size_chemist) )
  4783. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`fame`,`name` FROM `%s` WHERE `fame`>0 AND (`class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d' OR `class`='%d') ORDER BY `fame` DESC LIMIT 0,%d", schema_config.char_db, JOB_ALCHEMIST, JOB_CREATOR, JOB_BABY_ALCHEMIST, JOB_GENETIC, JOB_GENETIC_T, JOB_BABY_GENETIC, fame_list_size_chemist) )
  4784.  		Sql_ShowDebug(sql_handle);
  4785.  	for( i = 0; i < fame_list_size_chemist && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
  4786.  	{
  4787. @@ -2645,7 +1875,7 @@
  4788.  		memcpy(chemist_fame_list[i].name, data, min(len, NAME_LENGTH));
  4789.  	}
  4790.  	// Build Taekwon ranking list
  4791. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`fame`,`name` FROM `%s` WHERE `fame`>0 AND (`class`='%d') ORDER BY `fame` DESC LIMIT 0,%d", char_db, JOB_TAEKWON, fame_list_size_taekwon) )
  4792. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`fame`,`name` FROM `%s` WHERE `fame`>0 AND (`class`='%d') ORDER BY `fame` DESC LIMIT 0,%d", schema_config.char_db, JOB_TAEKWON, fame_list_size_taekwon) )
  4793.  		Sql_ShowDebug(sql_handle);
  4794.  	for( i = 0; i < fame_list_size_taekwon && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
  4795.  	{
  4796. @@ -2662,53 +1892,7 @@
  4797.  	Sql_FreeResult(sql_handle);
  4798.  }
  4799.  
  4800. -// Send map-servers the fame ranking lists
  4801. -int char_send_fame_list(int fd)
  4802. -{
  4803. -	int i, len = 8;
  4804. -	unsigned char buf[32000];
  4805.  
  4806. -	WBUFW(buf,0) = 0x2b1b;
  4807. -
  4808. -	for(i = 0; i < fame_list_size_smith && smith_fame_list[i].id; i++) {
  4809. -		memcpy(WBUFP(buf, len), &smith_fame_list[i], sizeof(struct fame_list));
  4810. -		len += sizeof(struct fame_list);
  4811. -	}
  4812. -	// add blacksmith's block length
  4813. -	WBUFW(buf, 6) = len;
  4814. -
  4815. -	for(i = 0; i < fame_list_size_chemist && chemist_fame_list[i].id; i++) {
  4816. -		memcpy(WBUFP(buf, len), &chemist_fame_list[i], sizeof(struct fame_list));
  4817. -		len += sizeof(struct fame_list);
  4818. -	}
  4819. -	// add alchemist's block length
  4820. -	WBUFW(buf, 4) = len;
  4821. -
  4822. -	for(i = 0; i < fame_list_size_taekwon && taekwon_fame_list[i].id; i++) {
  4823. -		memcpy(WBUFP(buf, len), &taekwon_fame_list[i], sizeof(struct fame_list));
  4824. -		len += sizeof(struct fame_list);
  4825. -	}
  4826. -	// add total packet length
  4827. -	WBUFW(buf, 2) = len;
  4828. -
  4829. -	if (fd != -1)
  4830. -		mapif_send(fd, buf, len);
  4831. -	else
  4832. -		mapif_sendall(buf, len);
  4833. -
  4834. -	return 0;
  4835. -}
  4836. -
  4837. -void char_update_fame_list(int type, int index, int fame)
  4838. -{
  4839. -	unsigned char buf[8];
  4840. -	WBUFW(buf,0) = 0x2b22;
  4841. -	WBUFB(buf,2) = type;
  4842. -	WBUFB(buf,3) = index;
  4843. -	WBUFL(buf,4) = fame;
  4844. -	mapif_sendall(buf, 8);
  4845. -}
  4846. -
  4847.  //Loads a character's name and stores it in the buffer given (must be NAME_LENGTH in size)
  4848.  //Returns 1 on found, 0 on not found (buffer is filled with Unknown char name)
  4849.  int char_loadName(int char_id, char* name)
  4850. @@ -2716,7 +1900,7 @@
  4851.  	char* data;
  4852.  	size_t len;
  4853.  
  4854. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `name` FROM `%s` WHERE `char_id`='%d'", char_db, char_id) )
  4855. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `name` FROM `%s` WHERE `char_id`='%d'", schema_config.char_db, char_id) )
  4856.  		Sql_ShowDebug(sql_handle);
  4857.  	else if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
  4858.  	{
  4859. @@ -2726,7 +1910,7 @@
  4860.  	}
  4861.  	else
  4862.  	{
  4863. -		safestrncpy(name, unknown_char_name, NAME_LENGTH);
  4864. +		safestrncpy(name, charserv_config.unknown_char_name, NAME_LENGTH);
  4865.  	}
  4866.  	return 0;
  4867.  }
  4868. @@ -2734,806 +1918,6 @@
  4869.  int search_mapserver(unsigned short map, uint32 ip, uint16 port);
  4870.  
  4871.  
  4872. -/// Initializes a server structure.
  4873. -void mapif_server_init(int id)
  4874. -{
  4875. -	memset(&server[id], 0, sizeof(server[id]));
  4876. -	server[id].fd = -1;
  4877. -}
  4878. -
  4879. -
  4880. -/// Destroys a server structure.
  4881. -void mapif_server_destroy(int id)
  4882. -{
  4883. -	if( server[id].fd == -1 )
  4884. -	{
  4885. -		do_close(server[id].fd);
  4886. -		server[id].fd = -1;
  4887. -	}
  4888. -}
  4889. -
  4890. -
  4891. -/// Resets all the data related to a server.
  4892. -void mapif_server_reset(int id)
  4893. -{
  4894. -	int i,j;
  4895. -	unsigned char buf[16384];
  4896. -	int fd = server[id].fd;
  4897. -	//Notify other map servers that this one is gone. [Skotlex]
  4898. -	WBUFW(buf,0) = 0x2b20;
  4899. -	WBUFL(buf,4) = htonl(server[id].ip);
  4900. -	WBUFW(buf,8) = htons(server[id].port);
  4901. -	j = 0;
  4902. -	for(i = 0; i < MAX_MAP_PER_SERVER; i++)
  4903. -		if (server[id].map[i])
  4904. -			WBUFW(buf,10+(j++)*4) = server[id].map[i];
  4905. -	if (j > 0) {
  4906. -		WBUFW(buf,2) = j * 4 + 10;
  4907. -		mapif_sendallwos(fd, buf, WBUFW(buf,2));
  4908. -	}
  4909. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `index`='%d'", ragsrvinfo_db, server[id].fd) )
  4910. -		Sql_ShowDebug(sql_handle);
  4911. -	online_char_db->foreach(online_char_db,char_db_setoffline,id); //Tag relevant chars as 'in disconnected' server.
  4912. -	mapif_server_destroy(id);
  4913. -	mapif_server_init(id);
  4914. -}
  4915. -
  4916. -
  4917. -/// Called when the connection to a Map Server is disconnected.
  4918. -void mapif_on_disconnect(int id)
  4919. -{
  4920. -	ShowStatus("Map-server #%d has disconnected.\n", id);
  4921. -	mapif_server_reset(id);
  4922. -}
  4923. -
  4924. -
  4925. -int parse_frommap(int fd)
  4926. -{
  4927. -	int i, j;
  4928. -	int id;
  4929. -
  4930. -	ARR_FIND( 0, ARRAYLENGTH(server), id, server[id].fd == fd );
  4931. -	if( id == ARRAYLENGTH(server) )
  4932. -	{// not a map server
  4933. -		ShowDebug("parse_frommap: Disconnecting invalid session #%d (is not a map-server)\n", fd);
  4934. -		do_close(fd);
  4935. -		return 0;
  4936. -	}
  4937. -	if( session[fd]->flag.eof )
  4938. -	{
  4939. -		do_close(fd);
  4940. -		server[id].fd = -1;
  4941. -		mapif_on_disconnect(id);
  4942. -		return 0;
  4943. -	}
  4944. -
  4945. -	while(RFIFOREST(fd) >= 2){
  4946. -		switch(RFIFOW(fd,0)){
  4947. -
  4948. -		case 0x2afa: // Receiving map names list from the map-server
  4949. -			if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
  4950. -				return 0;
  4951. -
  4952. -			memset(server[id].map, 0, sizeof(server[id].map));
  4953. -			j = 0;
  4954. -			for(i = 4; i < RFIFOW(fd,2); i += 4) {
  4955. -				server[id].map[j] = RFIFOW(fd,i);
  4956. -				j++;
  4957. -			}
  4958. -
  4959. -			ShowStatus("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d.\n",
  4960. -						id, j, CONVIP(server[id].ip), server[id].port);
  4961. -			ShowStatus("Map-server %d loading complete.\n", id);
  4962. -
  4963. -			// send name for wisp to player
  4964. -			WFIFOHEAD(fd, 3 + NAME_LENGTH);
  4965. -			WFIFOW(fd,0) = 0x2afb;
  4966. -			WFIFOB(fd,2) = 0;
  4967. -			memcpy(WFIFOP(fd,3), wisp_server_name, NAME_LENGTH);
  4968. -			WFIFOSET(fd,3+NAME_LENGTH);
  4969. -
  4970. -			char_send_fame_list(fd); //Send fame list.
  4971. -
  4972. -			{
  4973. -			unsigned char buf[16384];
  4974. -			int x;
  4975. -			if (j == 0) {
  4976. -				ShowWarning("Map-server %d has NO maps.\n", id);
  4977. -			} else {
  4978. -				// Transmitting maps information to the other map-servers
  4979. -				WBUFW(buf,0) = 0x2b04;
  4980. -				WBUFW(buf,2) = j * 4 + 10;
  4981. -				WBUFL(buf,4) = htonl(server[id].ip);
  4982. -				WBUFW(buf,8) = htons(server[id].port);
  4983. -				memcpy(WBUFP(buf,10), RFIFOP(fd,4), j * 4);
  4984. -				mapif_sendallwos(fd, buf, WBUFW(buf,2));
  4985. -			}
  4986. -			// Transmitting the maps of the other map-servers to the new map-server
  4987. -			for(x = 0; x < ARRAYLENGTH(server); x++) {
  4988. -				if (server[x].fd > 0 && x != id) {
  4989. -					WFIFOHEAD(fd,10 +4*ARRAYLENGTH(server[x].map));
  4990. -					WFIFOW(fd,0) = 0x2b04;
  4991. -					WFIFOL(fd,4) = htonl(server[x].ip);
  4992. -					WFIFOW(fd,8) = htons(server[x].port);
  4993. -					j = 0;
  4994. -					for(i = 0; i < ARRAYLENGTH(server[x].map); i++)
  4995. -						if (server[x].map[i])
  4996. -							WFIFOW(fd,10+(j++)*4) = server[x].map[i];
  4997. -					if (j > 0) {
  4998. -						WFIFOW(fd,2) = j * 4 + 10;
  4999. -						WFIFOSET(fd,WFIFOW(fd,2));
  5000. -					}
  5001. -				}
  5002. -			}
  5003. -			}
  5004. -			RFIFOSKIP(fd,RFIFOW(fd,2));
  5005. -		break;
  5006. -
  5007. -		case 0x2afc: //Packet command is now used for sc_data request. [Skotlex]
  5008. -			if (RFIFOREST(fd) < 10)
  5009. -				return 0;
  5010. -		{
  5011. -#ifdef ENABLE_SC_SAVING
  5012. -			int aid, cid;
  5013. -			aid = RFIFOL(fd,2);
  5014. -			cid = RFIFOL(fd,6);
  5015. -			if( SQL_ERROR == Sql_Query(sql_handle, "SELECT type, tick, val1, val2, val3, val4 from `%s` WHERE `account_id` = '%d' AND `char_id`='%d'",
  5016. -				scdata_db, aid, cid) )
  5017. -			{
  5018. -				Sql_ShowDebug(sql_handle);
  5019. -				break;
  5020. -			}
  5021. -			if( Sql_NumRows(sql_handle) > 0 )
  5022. -			{
  5023. -				struct status_change_data scdata;
  5024. -				int count;
  5025. -				char* data;
  5026. -
  5027. -				WFIFOHEAD(fd,14+50*sizeof(struct status_change_data));
  5028. -				WFIFOW(fd,0) = 0x2b1d;
  5029. -				WFIFOL(fd,4) = aid;
  5030. -				WFIFOL(fd,8) = cid;
  5031. -				for( count = 0; count < 50 && SQL_SUCCESS == Sql_NextRow(sql_handle); ++count )
  5032. -				{
  5033. -					Sql_GetData(sql_handle, 0, &data, NULL); scdata.type = atoi(data);
  5034. -					Sql_GetData(sql_handle, 1, &data, NULL); scdata.tick = atoi(data);
  5035. -					Sql_GetData(sql_handle, 2, &data, NULL); scdata.val1 = atoi(data);
  5036. -					Sql_GetData(sql_handle, 3, &data, NULL); scdata.val2 = atoi(data);
  5037. -					Sql_GetData(sql_handle, 4, &data, NULL); scdata.val3 = atoi(data);
  5038. -					Sql_GetData(sql_handle, 5, &data, NULL); scdata.val4 = atoi(data);
  5039. -					memcpy(WFIFOP(fd, 14+count*sizeof(struct status_change_data)), &scdata, sizeof(struct status_change_data));
  5040. -				}
  5041. -				if (count >= 50)
  5042. -					ShowWarning("Too many status changes for %d:%d, some of them were not loaded.\n", aid, cid);
  5043. -				if (count > 0)
  5044. -				{
  5045. -					WFIFOW(fd,2) = 14 + count*sizeof(struct status_change_data);
  5046. -					WFIFOW(fd,12) = count;
  5047. -					WFIFOSET(fd,WFIFOW(fd,2));
  5048. -
  5049. -					//Clear the data once loaded.
  5050. -					if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_id`='%d'", scdata_db, aid, cid) )
  5051. -						Sql_ShowDebug(sql_handle);
  5052. -				}
  5053. -			}
  5054. -			Sql_FreeResult(sql_handle);
  5055. -#endif
  5056. -			RFIFOSKIP(fd, 10);
  5057. -		}
  5058. -		break;
  5059. -
  5060. -		case 0x2afe: //set MAP user count
  5061. -			if (RFIFOREST(fd) < 4)
  5062. -				return 0;
  5063. -			if (RFIFOW(fd,2) != server[id].users) {
  5064. -				server[id].users = RFIFOW(fd,2);
  5065. -				ShowInfo("User Count: %d (Server: %d)\n", server[id].users, id);
  5066. -			}
  5067. -			RFIFOSKIP(fd, 4);
  5068. -			break;
  5069. -
  5070. -		case 0x2aff: //set MAP users
  5071. -			if (RFIFOREST(fd) < 6 || RFIFOREST(fd) < RFIFOW(fd,2))
  5072. -				return 0;
  5073. -		{
  5074. -			//TODO: When data mismatches memory, update guild/party online/offline states.
  5075. -			int aid, cid;
  5076. -			struct online_char_data* character;
  5077. -
  5078. -			server[id].users = RFIFOW(fd,4);
  5079. -			online_char_db->foreach(online_char_db,char_db_setoffline,id); //Set all chars from this server as 'unknown'
  5080. -			for(i = 0; i < server[id].users; i++) {
  5081. -				aid = RFIFOL(fd,6+i*8);
  5082. -				cid = RFIFOL(fd,6+i*8+4);
  5083. -				character = idb_ensure(online_char_db, aid, create_online_char_data);
  5084. -				if( character->server > -1 && character->server != id )
  5085. -				{
  5086. -					ShowNotice("Set map user: Character (%d:%d) marked on map server %d, but map server %d claims to have (%d:%d) online!\n",
  5087. -						character->account_id, character->char_id, character->server, id, aid, cid);
  5088. -					mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
  5089. -				}
  5090. -				character->server = id;
  5091. -				character->char_id = cid;
  5092. -			}
  5093. -			//If any chars remain in -2, they will be cleaned in the cleanup timer.
  5094. -			RFIFOSKIP(fd,RFIFOW(fd,2));
  5095. -		}
  5096. -		break;
  5097. -
  5098. -		case 0x2b01: // Receive character data from map-server for saving
  5099. -			if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
  5100. -				return 0;
  5101. -		{
  5102. -			int aid = RFIFOL(fd,4), cid = RFIFOL(fd,8), size = RFIFOW(fd,2);
  5103. -			struct online_char_data* character;
  5104. -
  5105. -			if (size - 13 != sizeof(struct mmo_charstatus))
  5106. -			{
  5107. -				ShowError("parse_from_map (save-char): Size mismatch! %d != %d\n", size-13, sizeof(struct mmo_charstatus));
  5108. -				RFIFOSKIP(fd,size);
  5109. -				break;
  5110. -			}
  5111. -			//Check account only if this ain't final save. Final-save goes through because of the char-map reconnect
  5112. -			if (RFIFOB(fd,12) || RFIFOB(fd,13) || (
  5113. -				(character = (struct online_char_data*)idb_get(online_char_db, aid)) != NULL &&
  5114. -				character->char_id == cid))
  5115. -			{
  5116. -				struct mmo_charstatus char_dat;
  5117. -				memcpy(&char_dat, RFIFOP(fd,13), sizeof(struct mmo_charstatus));
  5118. -				mmo_char_tosql(cid, &char_dat);
  5119. -			} else {	//This may be valid on char-server reconnection, when re-sending characters that already logged off.
  5120. -				ShowError("parse_from_map (save-char): Received data for non-existant/offline character (%d:%d).\n", aid, cid);
  5121. -				set_char_online(id, cid, aid);
  5122. -			}
  5123. -
  5124. -			if (RFIFOB(fd,12))
  5125. -			{	//Flag, set character offline after saving. [Skotlex]
  5126. -				set_char_offline(cid, aid);
  5127. -				WFIFOHEAD(fd,10);
  5128. -				WFIFOW(fd,0) = 0x2b21; //Save ack only needed on final save.
  5129. -				WFIFOL(fd,2) = aid;
  5130. -				WFIFOL(fd,6) = cid;
  5131. -				WFIFOSET(fd,10);
  5132. -			}
  5133. -			RFIFOSKIP(fd,size);
  5134. -		}
  5135. -		break;
  5136. -
  5137. -		case 0x2b02: // req char selection
  5138. -			if( RFIFOREST(fd) < 18 )
  5139. -				return 0;
  5140. -			else{
  5141. -				int account_id = RFIFOL(fd,2);
  5142. -				uint32 login_id1 = RFIFOL(fd,6);
  5143. -				uint32 login_id2 = RFIFOL(fd,10);
  5144. -				uint32 ip = RFIFOL(fd,14);
  5145. -				RFIFOSKIP(fd,18);
  5146. -
  5147. -				if( runflag != CHARSERVER_ST_RUNNING ){
  5148. -					WFIFOHEAD(fd,7);
  5149. -					WFIFOW(fd,0) = 0x2b03;
  5150. -					WFIFOL(fd,2) = account_id;
  5151. -					WFIFOB(fd,6) = 0;// not ok
  5152. -					WFIFOSET(fd,7);
  5153. -				}else{
  5154. -					struct auth_node* node;
  5155. -
  5156. -					// create temporary auth entry
  5157. -					CREATE(node, struct auth_node, 1);
  5158. -					node->account_id = account_id;
  5159. -					node->char_id = 0;
  5160. -					node->login_id1 = login_id1;
  5161. -					node->login_id2 = login_id2;
  5162. -					//node->sex = 0;
  5163. -					node->ip = ntohl(ip);
  5164. -					//node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server)
  5165. -					//node->gmlevel = 0;
  5166. -					idb_put(auth_db, account_id, node);
  5167. -
  5168. -					//Set char to "@ char select" in online db [Kevin]
  5169. -					set_char_charselect(account_id);
  5170. -
  5171. -					{
  5172. -						struct online_char_data* character = (struct online_char_data*)idb_get(online_char_db, account_id);
  5173. -
  5174. -						if( character != NULL ){
  5175. -							character->pincode_success = true;
  5176. -						}
  5177. -					}
  5178. -
  5179. -					WFIFOHEAD(fd,7);
  5180. -					WFIFOW(fd,0) = 0x2b03;
  5181. -					WFIFOL(fd,2) = account_id;
  5182. -					WFIFOB(fd,6) = 1;// ok
  5183. -					WFIFOSET(fd,7);
  5184. -				}
  5185. -			}
  5186. -		break;
  5187. -
  5188. -		case 0x2b05: // request "change map server"
  5189. -			if (RFIFOREST(fd) < 39)
  5190. -				return 0;
  5191. -		{
  5192. -			int map_id, map_fd = -1;
  5193. -			struct mmo_charstatus* char_data;
  5194. -			struct mmo_charstatus char_dat;
  5195. -
  5196. -			map_id = search_mapserver(RFIFOW(fd,18), ntohl(RFIFOL(fd,24)), ntohs(RFIFOW(fd,28))); //Locate mapserver by ip and port.
  5197. -			if (map_id >= 0)
  5198. -				map_fd = server[map_id].fd;
  5199. -			//Char should just had been saved before this packet, so this should be safe. [Skotlex]
  5200. -			char_data = (struct mmo_charstatus*)uidb_get(char_db_,RFIFOL(fd,14));
  5201. -			if (char_data == NULL) {	//Really shouldn't happen.
  5202. -				mmo_char_fromsql(RFIFOL(fd,14), &char_dat, true);
  5203. -				char_data = (struct mmo_charstatus*)uidb_get(char_db_,RFIFOL(fd,14));
  5204. -			}
  5205. -
  5206. -			if( runflag == CHARSERVER_ST_RUNNING &&
  5207. -				session_isActive(map_fd) &&
  5208. -				char_data )
  5209. -			{	//Send the map server the auth of this player.
  5210. -				struct online_char_data* data;
  5211. -				struct auth_node* node;
  5212. -
  5213. -				//Update the "last map" as this is where the player must be spawned on the new map server.
  5214. -				char_data->last_point.map = RFIFOW(fd,18);
  5215. -				char_data->last_point.x = RFIFOW(fd,20);
  5216. -				char_data->last_point.y = RFIFOW(fd,22);
  5217. -				char_data->sex = RFIFOB(fd,30);
  5218. -
  5219. -				// create temporary auth entry
  5220. -				CREATE(node, struct auth_node, 1);
  5221. -				node->account_id = RFIFOL(fd,2);
  5222. -				node->char_id = RFIFOL(fd,14);
  5223. -				node->login_id1 = RFIFOL(fd,6);
  5224. -				node->login_id2 = RFIFOL(fd,10);
  5225. -				node->sex = RFIFOB(fd,30);
  5226. -				node->expiration_time = 0; // FIXME (this thing isn't really supported we could as well purge it instead of fixing)
  5227. -				node->ip = ntohl(RFIFOL(fd,31));
  5228. -				node->group_id = RFIFOL(fd,35);
  5229. -				node->changing_mapservers = 1;
  5230. -				idb_put(auth_db, RFIFOL(fd,2), node);
  5231. -
  5232. -				data = idb_ensure(online_char_db, RFIFOL(fd,2), create_online_char_data);
  5233. -				data->char_id = char_data->char_id;
  5234. -				data->server = map_id; //Update server where char is.
  5235. -
  5236. -				//Reply with an ack.
  5237. -				WFIFOHEAD(fd,30);
  5238. -				WFIFOW(fd,0) = 0x2b06;
  5239. -				memcpy(WFIFOP(fd,2), RFIFOP(fd,2), 28);
  5240. -				WFIFOSET(fd,30);
  5241. -			} else { //Reply with nak
  5242. -				WFIFOHEAD(fd,30);
  5243. -				WFIFOW(fd,0) = 0x2b06;
  5244. -				memcpy(WFIFOP(fd,2), RFIFOP(fd,2), 28);
  5245. -				WFIFOL(fd,6) = 0; //Set login1 to 0.
  5246. -				WFIFOSET(fd,30);
  5247. -			}
  5248. -			RFIFOSKIP(fd,39);
  5249. -		}
  5250. -		break;
  5251. -
  5252. -		case 0x2b07: // Remove RFIFOL(fd,6) (friend_id) from RFIFOL(fd,2) (char_id) friend list [Ind]
  5253. -			if (RFIFOREST(fd) < 10)
  5254. -				return 0;
  5255. -			{
  5256. -				int char_id, friend_id;
  5257. -				char_id = RFIFOL(fd,2);
  5258. -				friend_id = RFIFOL(fd,6);
  5259. -				if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d' AND `friend_id`='%d' LIMIT 1",
  5260. -					friend_db, char_id, friend_id) ) {
  5261. -					Sql_ShowDebug(sql_handle);
  5262. -					break;
  5263. -				}
  5264. -				RFIFOSKIP(fd,10);
  5265. -			}
  5266. -		break;
  5267. -
  5268. -		case 0x2b08: // char name request
  5269. -			if (RFIFOREST(fd) < 6)
  5270. -				return 0;
  5271. -
  5272. -			WFIFOHEAD(fd,30);
  5273. -			WFIFOW(fd,0) = 0x2b09;
  5274. -			WFIFOL(fd,2) = RFIFOL(fd,2);
  5275. -			char_loadName((int)RFIFOL(fd,2), (char*)WFIFOP(fd,6));
  5276. -			WFIFOSET(fd,30);
  5277. -
  5278. -			RFIFOSKIP(fd,6);
  5279. -		break;
  5280. -
  5281. -		case 0x2b0c: // Map server send information to change an email of an account -> login-server
  5282. -			if (RFIFOREST(fd) < 86)
  5283. -				return 0;
  5284. -			if (login_fd > 0) { // don't send request if no login-server
  5285. -				WFIFOHEAD(login_fd,86);
  5286. -				memcpy(WFIFOP(login_fd,0), RFIFOP(fd,0),86); // 0x2722 <account_id>.L <actual_e-mail>.40B <new_e-mail>.40B
  5287. -				WFIFOW(login_fd,0) = 0x2722;
  5288. -				WFIFOSET(login_fd,86);
  5289. -			}
  5290. -			RFIFOSKIP(fd, 86);
  5291. -		break;
  5292. -
  5293. -		case 0x2b0e: // Request from map-server to change an account's status (will just be forwarded to login server)
  5294. -			if (RFIFOREST(fd) < 44)
  5295. -				return 0;
  5296. -		{
  5297. -			int result = 0; // 0-login-server request done, 1-player not found, 2-gm level too low, 3-login-server offline
  5298. -			char esc_name[NAME_LENGTH*2+1];
  5299. -
  5300. -			int acc = RFIFOL(fd,2); // account_id of who ask (-1 if server itself made this request)
  5301. -			const char* name = (char*)RFIFOP(fd,6); // name of the target character
  5302. -			int type = RFIFOW(fd,30); // type of operation: 1-block, 2-ban, 3-unblock, 4-unban
  5303. -			short year = RFIFOW(fd,32);
  5304. -			short month = RFIFOW(fd,34);
  5305. -			short day = RFIFOW(fd,36);
  5306. -			short hour = RFIFOW(fd,38);
  5307. -			short minute = RFIFOW(fd,40);
  5308. -			short second = RFIFOW(fd,42);
  5309. -			RFIFOSKIP(fd,44);
  5310. -
  5311. -			Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
  5312. -			if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name` FROM `%s` WHERE `name` = '%s'", char_db, esc_name) )
  5313. -				Sql_ShowDebug(sql_handle);
  5314. -			else
  5315. -			if( Sql_NumRows(sql_handle) == 0 )
  5316. -			{
  5317. -				result = 1; // 1-player not found
  5318. -			}
  5319. -			else
  5320. -			if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
  5321. -				Sql_ShowDebug(sql_handle);
  5322. -				//FIXME: set proper result value?
  5323. -			else
  5324. -			{
  5325. -				char name[NAME_LENGTH];
  5326. -				int account_id;
  5327. -				char* data;
  5328. -
  5329. -				Sql_GetData(sql_handle, 0, &data, NULL); account_id = atoi(data);
  5330. -				Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name));
  5331. -
  5332. -				if( login_fd <= 0 )
  5333. -					result = 3; // 3-login-server offline
  5334. -				//FIXME: need to move this check to login server [ultramage]
  5335. -//				else
  5336. -//				if( acc != -1 && isGM(acc) < isGM(account_id) )
  5337. -//					result = 2; // 2-gm level too low
  5338. -				else
  5339. -				switch( type ) {
  5340. -				case 1: // block
  5341. -						WFIFOHEAD(login_fd,10);
  5342. -						WFIFOW(login_fd,0) = 0x2724;
  5343. -						WFIFOL(login_fd,2) = account_id;
  5344. -						WFIFOL(login_fd,6) = 5; // new account status
  5345. -						WFIFOSET(login_fd,10);
  5346. -				break;
  5347. -				case 2: // ban
  5348. -						WFIFOHEAD(login_fd,18);
  5349. -						WFIFOW(login_fd, 0) = 0x2725;
  5350. -						WFIFOL(login_fd, 2) = account_id;
  5351. -						WFIFOW(login_fd, 6) = year;
  5352. -						WFIFOW(login_fd, 8) = month;
  5353. -						WFIFOW(login_fd,10) = day;
  5354. -						WFIFOW(login_fd,12) = hour;
  5355. -						WFIFOW(login_fd,14) = minute;
  5356. -						WFIFOW(login_fd,16) = second;
  5357. -						WFIFOSET(login_fd,18);
  5358. -				break;
  5359. -				case 3: // unblock
  5360. -						WFIFOHEAD(login_fd,10);
  5361. -						WFIFOW(login_fd,0) = 0x2724;
  5362. -						WFIFOL(login_fd,2) = account_id;
  5363. -						WFIFOL(login_fd,6) = 0; // new account status
  5364. -						WFIFOSET(login_fd,10);
  5365. -				break;
  5366. -				case 4: // unban
  5367. -						WFIFOHEAD(login_fd,6);
  5368. -						WFIFOW(login_fd,0) = 0x272a;
  5369. -						WFIFOL(login_fd,2) = account_id;
  5370. -						WFIFOSET(login_fd,6);
  5371. -				break;
  5372. -				case 5: // changesex
  5373. -						WFIFOHEAD(login_fd,6);
  5374. -						WFIFOW(login_fd,0) = 0x2727;
  5375. -						WFIFOL(login_fd,2) = account_id;
  5376. -						WFIFOSET(login_fd,6);
  5377. -				break;
  5378. -				}
  5379. -			}
  5380. -
  5381. -			Sql_FreeResult(sql_handle);
  5382. -
  5383. -			// send answer if a player ask, not if the server ask
  5384. -			if( acc != -1 && type != 5) { // Don't send answer for changesex
  5385. -				WFIFOHEAD(fd,34);
  5386. -				WFIFOW(fd, 0) = 0x2b0f;
  5387. -				WFIFOL(fd, 2) = acc;
  5388. -				safestrncpy((char*)WFIFOP(fd,6), name, NAME_LENGTH);
  5389. -				WFIFOW(fd,30) = type;
  5390. -				WFIFOW(fd,32) = result;
  5391. -				WFIFOSET(fd,34);
  5392. -			}
  5393. -		}
  5394. -		break;
  5395. -
  5396. -		case 0x2b10: // Update and send fame ranking list
  5397. -			if (RFIFOREST(fd) < 11)
  5398. -				return 0;
  5399. -		{
  5400. -			int cid = RFIFOL(fd, 2);
  5401. -			int fame = RFIFOL(fd, 6);
  5402. -			char type = RFIFOB(fd, 10);
  5403. -			int size;
  5404. -			struct fame_list* list;
  5405. -			int player_pos;
  5406. -			int fame_pos;
  5407. -
  5408. -			switch(type)
  5409. -			{
  5410. -				case 1:  size = fame_list_size_smith;   list = smith_fame_list;   break;
  5411. -				case 2:  size = fame_list_size_chemist; list = chemist_fame_list; break;
  5412. -				case 3:  size = fame_list_size_taekwon; list = taekwon_fame_list; break;
  5413. -				default: size = 0;                      list = NULL;              break;
  5414. -			}
  5415. -
  5416. -			ARR_FIND(0, size, player_pos, list[player_pos].id == cid);// position of the player
  5417. -			ARR_FIND(0, size, fame_pos, list[fame_pos].fame <= fame);// where the player should be
  5418. -
  5419. -			if( player_pos == size && fame_pos == size )
  5420. -				;// not on list and not enough fame to get on it
  5421. -			else if( fame_pos == player_pos )
  5422. -			{// same position
  5423. -				list[player_pos].fame = fame;
  5424. -				char_update_fame_list(type, player_pos, fame);
  5425. -			}
  5426. -			else
  5427. -			{// move in the list
  5428. -				if( player_pos == size )
  5429. -				{// new ranker - not in the list
  5430. -					ARR_MOVE(size - 1, fame_pos, list, struct fame_list);
  5431. -					list[fame_pos].id = cid;
  5432. -					list[fame_pos].fame = fame;
  5433. -					char_loadName(cid, list[fame_pos].name);
  5434. -				}
  5435. -				else
  5436. -				{// already in the list
  5437. -					if( fame_pos == size )
  5438. -						--fame_pos;// move to the end of the list
  5439. -					ARR_MOVE(player_pos, fame_pos, list, struct fame_list);
  5440. -					list[fame_pos].fame = fame;
  5441. -				}
  5442. -				char_send_fame_list(-1);
  5443. -			}
  5444. -
  5445. -			RFIFOSKIP(fd,11);
  5446. -		}
  5447. -		break;
  5448. -
  5449. -		// Divorce chars
  5450. -		case 0x2b11:
  5451. -			if( RFIFOREST(fd) < 10 )
  5452. -				return 0;
  5453. -			divorce_char_sql(RFIFOL(fd,2), RFIFOL(fd,6));
  5454. -			RFIFOSKIP(fd,10);
  5455. -		break;
  5456. -
  5457. -		case 0x2b16: // Receive rates [Wizputer]
  5458. -			if( RFIFOREST(fd) < 14 )
  5459. -				return 0;
  5460. -		{
  5461. -			char esc_server_name[sizeof(server_name)*2+1];
  5462. -
  5463. -			Sql_EscapeString(sql_handle, esc_server_name, server_name);
  5464. -
  5465. -			if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` SET `index`='%d',`name`='%s',`exp`='%d',`jexp`='%d',`drop`='%d'",
  5466. -				ragsrvinfo_db, fd, esc_server_name, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)) )
  5467. -				Sql_ShowDebug(sql_handle);
  5468. -			RFIFOSKIP(fd,14);
  5469. -		}
  5470. -		break;
  5471. -
  5472. -		case 0x2b17: // Character disconnected set online 0 [Wizputer]
  5473. -			if (RFIFOREST(fd) < 6)
  5474. -				return 0;
  5475. -			set_char_offline(RFIFOL(fd,2),RFIFOL(fd,6));
  5476. -			RFIFOSKIP(fd,10);
  5477. -		break;
  5478. -
  5479. -		case 0x2b18: // Reset all chars to offline [Wizputer]
  5480. -			set_all_offline(id);
  5481. -			RFIFOSKIP(fd,2);
  5482. -		break;
  5483. -
  5484. -		case 0x2b19: // Character set online [Wizputer]
  5485. -			if (RFIFOREST(fd) < 10)
  5486. -				return 0;
  5487. -			set_char_online(id, RFIFOL(fd,2),RFIFOL(fd,6));
  5488. -			RFIFOSKIP(fd,10);
  5489. -		break;
  5490. -
  5491. -		case 0x2b1a: // Build and send fame ranking lists [DracoRPG]
  5492. -			if (RFIFOREST(fd) < 2)
  5493. -				return 0;
  5494. -			char_read_fame_list();
  5495. -			char_send_fame_list(-1);
  5496. -			RFIFOSKIP(fd,2);
  5497. -		break;
  5498. -
  5499. -		case 0x2b1c: //Request to save status change data. [Skotlex]
  5500. -			if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
  5501. -				return 0;
  5502. -		{
  5503. -#ifdef ENABLE_SC_SAVING
  5504. -			int count, aid, cid;
  5505. -
  5506. -			aid = RFIFOL(fd, 4);
  5507. -			cid = RFIFOL(fd, 8);
  5508. -			count = RFIFOW(fd, 12);
  5509. -
  5510. -			if( count > 0 )
  5511. -			{
  5512. -				struct status_change_data data;
  5513. -				StringBuf buf;
  5514. -				int i;
  5515. -
  5516. -				StringBuf_Init(&buf);
  5517. -				StringBuf_Printf(&buf, "INSERT INTO `%s` (`account_id`, `char_id`, `type`, `tick`, `val1`, `val2`, `val3`, `val4`) VALUES ", scdata_db);
  5518. -				for( i = 0; i < count; ++i )
  5519. -				{
  5520. -					memcpy (&data, RFIFOP(fd, 14+i*sizeof(struct status_change_data)), sizeof(struct status_change_data));
  5521. -					if( i > 0 )
  5522. -						StringBuf_AppendStr(&buf, ", ");
  5523. -					StringBuf_Printf(&buf, "('%d','%d','%hu','%d','%d','%d','%d','%d')", aid, cid,
  5524. -						data.type, data.tick, data.val1, data.val2, data.val3, data.val4);
  5525. -				}
  5526. -				if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
  5527. -					Sql_ShowDebug(sql_handle);
  5528. -				StringBuf_Destroy(&buf);
  5529. -			}
  5530. -#endif
  5531. -			RFIFOSKIP(fd, RFIFOW(fd, 2));
  5532. -		}
  5533. -		break;
  5534. -
  5535. -		case 0x2b23: // map-server alive packet
  5536. -			WFIFOHEAD(fd,2);
  5537. -			WFIFOW(fd,0) = 0x2b24;
  5538. -			WFIFOSET(fd,2);
  5539. -			RFIFOSKIP(fd,2);
  5540. -		break;
  5541. -
  5542. -		case 0x2b26: // auth request from map-server
  5543. -			if (RFIFOREST(fd) < 19)
  5544. -				return 0;
  5545. -
  5546. -		{
  5547. -			int account_id;
  5548. -			int char_id;
  5549. -			int login_id1;
  5550. -			char sex;
  5551. -			uint32 ip;
  5552. -			struct auth_node* node;
  5553. -			struct mmo_charstatus* cd;
  5554. -			struct mmo_charstatus char_dat;
  5555. -
  5556. -			account_id = RFIFOL(fd,2);
  5557. -			char_id    = RFIFOL(fd,6);
  5558. -			login_id1  = RFIFOL(fd,10);
  5559. -			sex        = RFIFOB(fd,14);
  5560. -			ip         = ntohl(RFIFOL(fd,15));
  5561. -			RFIFOSKIP(fd,19);
  5562. -
  5563. -			node = (struct auth_node*)idb_get(auth_db, account_id);
  5564. -			cd = (struct mmo_charstatus*)uidb_get(char_db_,char_id);
  5565. -			if( cd == NULL )
  5566. -			{	//Really shouldn't happen.
  5567. -				mmo_char_fromsql(char_id, &char_dat, true);
  5568. -				cd = (struct mmo_charstatus*)uidb_get(char_db_,char_id);
  5569. -			}
  5570. -			if( runflag == CHARSERVER_ST_RUNNING &&
  5571. -				cd != NULL &&
  5572. -				node != NULL &&
  5573. -				node->account_id == account_id &&
  5574. -				node->char_id == char_id &&
  5575. -				node->login_id1 == login_id1 &&
  5576. -				node->sex == sex /*&&
  5577. -				node->ip == ip*/ )
  5578. -			{// auth ok
  5579. -				cd->sex = sex;
  5580. -
  5581. -				WFIFOHEAD(fd,25 + sizeof(struct mmo_charstatus));
  5582. -				WFIFOW(fd,0) = 0x2afd;
  5583. -				WFIFOW(fd,2) = 25 + sizeof(struct mmo_charstatus);
  5584. -				WFIFOL(fd,4) = account_id;
  5585. -				WFIFOL(fd,8) = node->login_id1;
  5586. -				WFIFOL(fd,12) = node->login_id2;
  5587. -				WFIFOL(fd,16) = (uint32)node->expiration_time; // FIXME: will wrap to negative after "19-Jan-2038, 03:14:07 AM GMT"
  5588. -				WFIFOL(fd,20) = node->group_id;
  5589. -				WFIFOB(fd,24) = node->changing_mapservers;
  5590. -				memcpy(WFIFOP(fd,25), cd, sizeof(struct mmo_charstatus));
  5591. -				WFIFOSET(fd, WFIFOW(fd,2));
  5592. -
  5593. -				// only use the auth once and mark user online
  5594. -				idb_remove(auth_db, account_id);
  5595. -				set_char_online(id, char_id, account_id);
  5596. -			}
  5597. -			else
  5598. -			{// auth failed
  5599. -				WFIFOHEAD(fd,19);
  5600. -				WFIFOW(fd,0) = 0x2b27;
  5601. -				WFIFOL(fd,2) = account_id;
  5602. -				WFIFOL(fd,6) = char_id;
  5603. -				WFIFOL(fd,10) = login_id1;
  5604. -				WFIFOB(fd,14) = sex;
  5605. -				WFIFOL(fd,15) = htonl(ip);
  5606. -				WFIFOSET(fd,19);
  5607. -			}
  5608. -		}
  5609. -		break;
  5610. -
  5611. -		case 0x2736: // ip address update
  5612. -			if (RFIFOREST(fd) < 6) return 0;
  5613. -			server[id].ip = ntohl(RFIFOL(fd, 2));
  5614. -			ShowInfo("Updated IP address of map-server #%d to %d.%d.%d.%d.\n", id, CONVIP(server[id].ip));
  5615. -			RFIFOSKIP(fd,6);
  5616. -		break;
  5617. -
  5618. -		case 0x3008:
  5619. -			if( RFIFOREST(fd) < RFIFOW(fd,4) )
  5620. -				return 0;/* packet wasn't fully received yet (still fragmented) */
  5621. -			else {
  5622. -				int sfd;/* stat server fd */
  5623. -				RFIFOSKIP(fd, 2);/* we skip first 2 bytes which are the 0x3008, so we end up with a buffer equal to the one we send */
  5624. -
  5625. -				if( (sfd = make_connection(host2ip("stats.rathena.org"),(uint16)25421,true,10) ) == -1 ) {
  5626. -					RFIFOSKIP(fd, RFIFOW(fd,2) );/* skip this packet */
  5627. -					break;/* connection not possible, we drop the report */
  5628. -				}
  5629. -
  5630. -				session[sfd]->flag.server = 1;/* to ensure we won't drop our own packet */
  5631. -				WFIFOHEAD(sfd, RFIFOW(fd,2) );
  5632. -				memcpy((char*)WFIFOP(sfd,0), (char*)RFIFOP(fd, 0), RFIFOW(fd,2));
  5633. -				WFIFOSET(sfd, RFIFOW(fd,2) );
  5634. -				flush_fifo(sfd);
  5635. -				do_close(sfd);
  5636. -				RFIFOSKIP(fd, RFIFOW(fd,2) );/* skip this packet */
  5637. -		}
  5638. -		break;
  5639. -
  5640. -		default:
  5641. -		{
  5642. -			// inter server - packet
  5643. -			int r = inter_parse_frommap(fd);
  5644. -			if (r == 1) break;		// processed
  5645. -			if (r == 2) return 0;	// need more packet
  5646. -
  5647. -			// no inter server packet. no char server packet -> disconnect
  5648. -			ShowError("Unknown packet 0x%04x from map server, disconnecting.\n", RFIFOW(fd,0));
  5649. -			set_eof(fd);
  5650. -			return 0;
  5651. -		}
  5652. -		} // switch
  5653. -	} // while
  5654. -
  5655. -	return 0;
  5656. -}
  5657. -
  5658. -void do_init_mapif(void)
  5659. -{
  5660. -	int i;
  5661. -	for( i = 0; i < ARRAYLENGTH(server); ++i )
  5662. -		mapif_server_init(i);
  5663. -}
  5664. -
  5665. -void do_final_mapif(void)
  5666. -{
  5667. -	int i;
  5668. -	for( i = 0; i < ARRAYLENGTH(server); ++i )
  5669. -		mapif_server_destroy(i);
  5670. -}
  5671. -
  5672.  // Searches for the mapserver that has a given map (and optionally ip/port, if not -1).
  5673.  // If found, returns the server's index in the 'server' array (otherwise returns -1).
  5674.  int search_mapserver(unsigned short map, uint32 ip, uint16 port)
  5675. @@ -3555,17 +1939,10 @@
  5676.  	return -1;
  5677.  }
  5678.  
  5679. -// Initialization process (currently only initialization inter_mapif)
  5680. -static int char_mapif_init(int fd)
  5681. -{
  5682. -	return inter_mapif_init(fd);
  5683. -}
  5684. -
  5685.  //--------------------------------------------
  5686.  // Test to know if an IP come from LAN or WAN.
  5687.  //--------------------------------------------
  5688. -int lan_subnetcheck(uint32 ip)
  5689. -{
  5690. +int lan_subnetcheck(uint32 ip){
  5691.  	int i;
  5692.  	ARR_FIND( 0, subnet_count, i, (subnet[i].char_ip & subnet[i].mask) == (ip & subnet[i].mask) );
  5693.  	if( i < subnet_count ) {
  5694. @@ -3578,937 +1955,8 @@
  5695.  }
  5696.  
  5697.  
  5698. -/// @param result
  5699. -/// 0 (0x718): An unknown error has occurred.
  5700. -/// 1: none/success
  5701. -/// 3 (0x719): A database error occurred.
  5702. -/// 4 (0x71a): To delete a character you must withdraw from the guild.
  5703. -/// 5 (0x71b): To delete a character you must withdraw from the party.
  5704. -/// Any (0x718): An unknown error has occurred.
  5705. -void char_delete2_ack(int fd, int char_id, uint32 result, time_t delete_date)
  5706. -{// HC: <0828>.W <char id>.L <Msg:0-5>.L <deleteDate>.L
  5707. -	WFIFOHEAD(fd,14);
  5708. -	WFIFOW(fd,0) = 0x828;
  5709. -	WFIFOL(fd,2) = char_id;
  5710. -	WFIFOL(fd,6) = result;
  5711. -	WFIFOL(fd,10) = TOL(delete_date);
  5712. -	WFIFOSET(fd,14);
  5713. -}
  5714.  
  5715. -
  5716. -/// @param result
  5717. -/// 0 (0x718): An unknown error has occurred.
  5718. -/// 1: none/success
  5719. -/// 2 (0x71c): Due to system settings can not be deleted.
  5720. -/// 3 (0x719): A database error occurred.
  5721. -/// 4 (0x71d): Deleting not yet possible time.
  5722. -/// 5 (0x71e): Date of birth do not match.
  5723. -/// Any (0x718): An unknown error has occurred.
  5724. -void char_delete2_accept_ack(int fd, int char_id, uint32 result)
  5725. -{// HC: <082a>.W <char id>.L <Msg:0-5>.L
  5726. -	WFIFOHEAD(fd,10);
  5727. -	WFIFOW(fd,0) = 0x82a;
  5728. -	WFIFOL(fd,2) = char_id;
  5729. -	WFIFOL(fd,6) = result;
  5730. -	WFIFOSET(fd,10);
  5731. -}
  5732. -
  5733. -
  5734. -/// @param result
  5735. -/// 1 (0x718): none/success, (if char id not in deletion process): An unknown error has occurred.
  5736. -/// 2 (0x719): A database error occurred.
  5737. -/// Any (0x718): An unknown error has occurred.
  5738. -void char_delete2_cancel_ack(int fd, int char_id, uint32 result)
  5739. -{// HC: <082c>.W <char id>.L <Msg:1-2>.L
  5740. -	WFIFOHEAD(fd,10);
  5741. -	WFIFOW(fd,0) = 0x82c;
  5742. -	WFIFOL(fd,2) = char_id;
  5743. -	WFIFOL(fd,6) = result;
  5744. -	WFIFOSET(fd,10);
  5745. -}
  5746. -
  5747. -
  5748. -static void char_delete2_req(int fd, struct char_session_data* sd)
  5749. -{// CH: <0827>.W <char id>.L
  5750. -	int char_id, i;
  5751. -	char* data;
  5752. -	time_t delete_date;
  5753. -
  5754. -	char_id = RFIFOL(fd,2);
  5755. -
  5756. -	ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == char_id );
  5757. -	if( i == MAX_CHARS )
  5758. -	{// character not found
  5759. -		char_delete2_ack(fd, char_id, 3, 0);
  5760. -		return;
  5761. -	}
  5762. -
  5763. -	if( SQL_SUCCESS != Sql_Query(sql_handle, "SELECT `delete_date` FROM `%s` WHERE `char_id`='%d'", char_db, char_id) || SQL_SUCCESS != Sql_NextRow(sql_handle) )
  5764. -	{
  5765. -		Sql_ShowDebug(sql_handle);
  5766. -		char_delete2_ack(fd, char_id, 3, 0);
  5767. -		return;
  5768. -	}
  5769. -
  5770. -	Sql_GetData(sql_handle, 0, &data, NULL); delete_date = strtoul(data, NULL, 10);
  5771. -
  5772. -	if( delete_date ) {// character already queued for deletion
  5773. -		char_delete2_ack(fd, char_id, 0, 0);
  5774. -		return;
  5775. -	}
  5776. -
  5777. -/*
  5778. -	// Aegis imposes these checks probably to avoid dead member
  5779. -	// entries in guilds/parties, otherwise they are not required.
  5780. -	// TODO: Figure out how these are enforced during waiting.
  5781. -	if( guild_id )
  5782. -	{// character in guild
  5783. -		char_delete2_ack(fd, char_id, 4, 0);
  5784. -		return;
  5785. -	}
  5786. -
  5787. -	if( party_id )
  5788. -	{// character in party
  5789. -		char_delete2_ack(fd, char_id, 5, 0);
  5790. -		return;
  5791. -	}
  5792. -*/
  5793. -
  5794. -	// success
  5795. -	delete_date = time(NULL)+char_del_delay;
  5796. -
  5797. -	if( SQL_SUCCESS != Sql_Query(sql_handle, "UPDATE `%s` SET `delete_date`='%lu' WHERE `char_id`='%d'", char_db, (unsigned long)delete_date, char_id) )
  5798. -	{
  5799. -		Sql_ShowDebug(sql_handle);
  5800. -		char_delete2_ack(fd, char_id, 3, 0);
  5801. -		return;
  5802. -	}
  5803. -
  5804. -	char_delete2_ack(fd, char_id, 1, delete_date);
  5805. -}
  5806. -
  5807. -
  5808. -static void char_delete2_accept(int fd, struct char_session_data* sd)
  5809. -{// CH: <0829>.W <char id>.L <birth date:YYMMDD>.6B
  5810. -	char birthdate[8+1];
  5811. -	int char_id, i, k;
  5812. -	unsigned int base_level;
  5813. -	char* data;
  5814. -	time_t delete_date;
  5815. -
  5816. -	char_id = RFIFOL(fd,2);
  5817. -
  5818. -	ShowInfo(CL_RED"Request Char Deletion: "CL_GREEN"%d (%d)"CL_RESET"\n", sd->account_id, char_id);
  5819. -
  5820. -	// construct "YY-MM-DD"
  5821. -	birthdate[0] = RFIFOB(fd,6);
  5822. -	birthdate[1] = RFIFOB(fd,7);
  5823. -	birthdate[2] = '-';
  5824. -	birthdate[3] = RFIFOB(fd,8);
  5825. -	birthdate[4] = RFIFOB(fd,9);
  5826. -	birthdate[5] = '-';
  5827. -	birthdate[6] = RFIFOB(fd,10);
  5828. -	birthdate[7] = RFIFOB(fd,11);
  5829. -	birthdate[8] = 0;
  5830. -
  5831. -	ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == char_id );
  5832. -	if( i == MAX_CHARS )
  5833. -	{// character not found
  5834. -		char_delete2_accept_ack(fd, char_id, 3);
  5835. -		return;
  5836. -	}
  5837. -
  5838. -	if( SQL_SUCCESS != Sql_Query(sql_handle, "SELECT `base_level`,`delete_date` FROM `%s` WHERE `char_id`='%d'", char_db, char_id) || SQL_SUCCESS != Sql_NextRow(sql_handle) )
  5839. -	{// data error
  5840. -		Sql_ShowDebug(sql_handle);
  5841. -		char_delete2_accept_ack(fd, char_id, 3);
  5842. -		return;
  5843. -	}
  5844. -
  5845. -	Sql_GetData(sql_handle, 0, &data, NULL); base_level = (unsigned int)strtoul(data, NULL, 10);
  5846. -	Sql_GetData(sql_handle, 1, &data, NULL); delete_date = strtoul(data, NULL, 10);
  5847. -
  5848. -	if( !delete_date || delete_date>time(NULL) )
  5849. -	{// not queued or delay not yet passed
  5850. -		char_delete2_accept_ack(fd, char_id, 4);
  5851. -		return;
  5852. -	}
  5853. -
  5854. -	if( strcmp(sd->birthdate+2, birthdate) )  // +2 to cut off the century
  5855. -	{// birth date is wrong
  5856. -		char_delete2_accept_ack(fd, char_id, 5);
  5857. -		return;
  5858. -	}
  5859. -
  5860. -	if( ( char_del_level > 0 && base_level >= (unsigned int)char_del_level ) || ( char_del_level < 0 && base_level <= (unsigned int)(-char_del_level) ) )
  5861. -	{// character level config restriction
  5862. -		char_delete2_accept_ack(fd, char_id, 2);
  5863. -		return;
  5864. -	}
  5865. -
  5866. -	// success
  5867. -	if( delete_char_sql(char_id) < 0 )
  5868. -	{
  5869. -		char_delete2_accept_ack(fd, char_id, 3);
  5870. -		return;
  5871. -	}
  5872. -
  5873. -	// refresh character list cache
  5874. -	for(k = i; k < MAX_CHARS-1; k++)
  5875. -	{
  5876. -		sd->found_char[k] = sd->found_char[k+1];
  5877. -	}
  5878. -	sd->found_char[MAX_CHARS-1] = -1;
  5879. -
  5880. -	char_delete2_accept_ack(fd, char_id, 1);
  5881. -}
  5882. -
  5883. -
  5884. -static void char_delete2_cancel(int fd, struct char_session_data* sd)
  5885. -{// CH: <082b>.W <char id>.L
  5886. -	int char_id, i;
  5887. -
  5888. -	char_id = RFIFOL(fd,2);
  5889. -
  5890. -	ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == char_id );
  5891. -	if( i == MAX_CHARS )
  5892. -	{// character not found
  5893. -		char_delete2_cancel_ack(fd, char_id, 2);
  5894. -		return;
  5895. -	}
  5896. -
  5897. -	// there is no need to check, whether or not the character was
  5898. -	// queued for deletion, as the client prints an error message by
  5899. -	// itself, if it was not the case (@see char_delete2_cancel_ack)
  5900. -	if( SQL_SUCCESS != Sql_Query(sql_handle, "UPDATE `%s` SET `delete_date`='0' WHERE `char_id`='%d'", char_db, char_id) )
  5901. -	{
  5902. -		Sql_ShowDebug(sql_handle);
  5903. -		char_delete2_cancel_ack(fd, char_id, 2);
  5904. -		return;
  5905. -	}
  5906. -
  5907. -	char_delete2_cancel_ack(fd, char_id, 1);
  5908. -}
  5909. -
  5910. -
  5911. -int parse_char(int fd)
  5912. -{
  5913. -	int i, ch;
  5914. -	char email[40];
  5915. -	unsigned short cmd;
  5916. -	int map_fd;
  5917. -	struct char_session_data* sd;
  5918. -	uint32 ipl = session[fd]->client_addr;
  5919. -
  5920. -	sd = (struct char_session_data*)session[fd]->session_data;
  5921. -
  5922. -	// disconnect any player if no login-server.
  5923. -	if(login_fd < 0)
  5924. -		set_eof(fd);
  5925. -
  5926. -	if(session[fd]->flag.eof)
  5927. -	{
  5928. -		if( sd != NULL && sd->auth )
  5929. -		{	// already authed client
  5930. -			struct online_char_data* data = (struct online_char_data*)idb_get(online_char_db, sd->account_id);
  5931. -			if( data != NULL && data->fd == fd)
  5932. -				data->fd = -1;
  5933. -			if( data == NULL || data->server == -1) //If it is not in any server, send it offline. [Skotlex]
  5934. -				set_char_offline(-1,sd->account_id);
  5935. -		}
  5936. -		do_close(fd);
  5937. -		return 0;
  5938. -	}
  5939. -
  5940. -	while( RFIFOREST(fd) >= 2 )
  5941. -	{
  5942. -		//For use in packets that depend on an sd being present [Skotlex]
  5943. -		#define FIFOSD_CHECK(rest) { if(RFIFOREST(fd) < rest) return 0; if (sd==NULL || !sd->auth) { RFIFOSKIP(fd,rest); return 0; } }
  5944. -
  5945. -		cmd = RFIFOW(fd,0);
  5946. -		switch( cmd )
  5947. -		{
  5948. -
  5949. -		// request to connect
  5950. -		// 0065 <account id>.L <login id1>.L <login id2>.L <???>.W <sex>.B
  5951. -		case 0x65:
  5952. -			if( RFIFOREST(fd) < 17 )
  5953. -				return 0;
  5954. -		{
  5955. -			struct auth_node* node;
  5956. -
  5957. -			int account_id = RFIFOL(fd,2);
  5958. -			uint32 login_id1 = RFIFOL(fd,6);
  5959. -			uint32 login_id2 = RFIFOL(fd,10);
  5960. -			int sex = RFIFOB(fd,16);
  5961. -			RFIFOSKIP(fd,17);
  5962. -
  5963. -			ShowInfo("request connect - account_id:%d/login_id1:%d/login_id2:%d\n", account_id, login_id1, login_id2);
  5964. -
  5965. -			if (sd) {
  5966. -				//Received again auth packet for already authentified account?? Discard it.
  5967. -				//TODO: Perhaps log this as a hack attempt?
  5968. -				//TODO: and perhaps send back a reply?
  5969. -				break;
  5970. -			}
  5971. -
  5972. -			CREATE(session[fd]->session_data, struct char_session_data, 1);
  5973. -			sd = (struct char_session_data*)session[fd]->session_data;
  5974. -			sd->account_id = account_id;
  5975. -			sd->login_id1 = login_id1;
  5976. -			sd->login_id2 = login_id2;
  5977. -			sd->sex = sex;
  5978. -			sd->auth = false; // not authed yet
  5979. -
  5980. -			// send back account_id
  5981. -			WFIFOHEAD(fd,4);
  5982. -			WFIFOL(fd,0) = account_id;
  5983. -			WFIFOSET(fd,4);
  5984. -
  5985. -			if( runflag != CHARSERVER_ST_RUNNING )
  5986. -			{
  5987. -				WFIFOHEAD(fd,3);
  5988. -				WFIFOW(fd,0) = 0x6c;
  5989. -				WFIFOB(fd,2) = 0;// rejected from server
  5990. -				WFIFOSET(fd,3);
  5991. -				break;
  5992. -			}
  5993. -
  5994. -			// search authentification
  5995. -			node = (struct auth_node*)idb_get(auth_db, account_id);
  5996. -			if( node != NULL &&
  5997. -			    node->account_id == account_id &&
  5998. -				node->login_id1  == login_id1 &&
  5999. -				node->login_id2  == login_id2 /*&&
  6000. -				node->ip         == ipl*/ )
  6001. -			{// authentication found (coming from map server)
  6002. -				idb_remove(auth_db, account_id);
  6003. -				char_auth_ok(fd, sd);
  6004. -			}
  6005. -			else
  6006. -			{// authentication not found (coming from login server)
  6007. -				if (login_fd > 0) { // don't send request if no login-server
  6008. -					WFIFOHEAD(login_fd,23);
  6009. -					WFIFOW(login_fd,0) = 0x2712; // ask login-server to authentify an account
  6010. -					WFIFOL(login_fd,2) = sd->account_id;
  6011. -					WFIFOL(login_fd,6) = sd->login_id1;
  6012. -					WFIFOL(login_fd,10) = sd->login_id2;
  6013. -					WFIFOB(login_fd,14) = sd->sex;
  6014. -					WFIFOL(login_fd,15) = htonl(ipl);
  6015. -					WFIFOL(login_fd,19) = fd;
  6016. -					WFIFOSET(login_fd,23);
  6017. -				} else { // if no login-server, we must refuse connection
  6018. -					WFIFOHEAD(fd,3);
  6019. -					WFIFOW(fd,0) = 0x6c;
  6020. -					WFIFOB(fd,2) = 0;
  6021. -					WFIFOSET(fd,3);
  6022. -				}
  6023. -			}
  6024. -		}
  6025. -		break;
  6026. -
  6027. -		// char select
  6028. -		case 0x66:
  6029. -			FIFOSD_CHECK(3);
  6030. -		{
  6031. -			struct mmo_charstatus char_dat;
  6032. -			struct mmo_charstatus *cd;
  6033. -			char* data;
  6034. -			int char_id;
  6035. -			uint32 subnet_map_ip;
  6036. -			struct auth_node* node;
  6037. -
  6038. -			int slot = RFIFOB(fd,2);
  6039. -			RFIFOSKIP(fd,3);
  6040. -
  6041. -			if ( SQL_SUCCESS != Sql_Query(sql_handle, "SELECT `char_id` FROM `%s` WHERE `account_id`='%d' AND `char_num`='%d'", char_db, sd->account_id, slot)
  6042. -			  || SQL_SUCCESS != Sql_NextRow(sql_handle)
  6043. -			  || SQL_SUCCESS != Sql_GetData(sql_handle, 0, &data, NULL) )
  6044. -			{	//Not found?? May be forged packet.
  6045. -				Sql_ShowDebug(sql_handle);
  6046. -				Sql_FreeResult(sql_handle);
  6047. -				WFIFOHEAD(fd,3);
  6048. -				WFIFOW(fd,0) = 0x6c;
  6049. -				WFIFOB(fd,2) = 0; // rejected from server
  6050. -				WFIFOSET(fd,3);
  6051. -				break;
  6052. -			}
  6053. -
  6054. -			char_id = atoi(data);
  6055. -			Sql_FreeResult(sql_handle);
  6056. -
  6057. -			/* set char as online prior to loading its data so 3rd party applications will realise the sql data is not reliable */
  6058. -			set_char_online(-2,char_id,sd->account_id);
  6059. -			if( !mmo_char_fromsql(char_id, &char_dat, true) ) { /* failed? set it back offline */
  6060. -				set_char_offline(char_id, sd->account_id);
  6061. -				/* failed to load something. REJECT! */
  6062. -				WFIFOHEAD(fd,3);
  6063. -				WFIFOW(fd,0) = 0x6c;
  6064. -				WFIFOB(fd,2) = 0;
  6065. -				WFIFOSET(fd,3);
  6066. -				break;/* jump off this boat */
  6067. -			}
  6068. -
  6069. -			//Have to switch over to the DB instance otherwise data won't propagate [Kevin]
  6070. -			cd = (struct mmo_charstatus *)idb_get(char_db_, char_id);
  6071. -			cd->sex = sd->sex;
  6072. -
  6073. -			if (log_char) {
  6074. -				char esc_name[NAME_LENGTH*2+1];
  6075. -
  6076. -				Sql_EscapeStringLen(sql_handle, esc_name, char_dat.name, strnlen(char_dat.name, NAME_LENGTH));
  6077. -				if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s`(`time`, `account_id`,`char_num`,`name`) VALUES (NOW(), '%d', '%d', '%s')",
  6078. -					charlog_db, sd->account_id, slot, esc_name) )
  6079. -					Sql_ShowDebug(sql_handle);
  6080. -			}
  6081. -			ShowInfo("Selected char: (Account %d: %d - %s)\n", sd->account_id, slot, char_dat.name);
  6082. -
  6083. -			// searching map server
  6084. -			i = search_mapserver(cd->last_point.map, -1, -1);
  6085. -
  6086. -			// if map is not found, we check major cities
  6087. -			if (i < 0 || !cd->last_point.map) {
  6088. -				unsigned short j;
  6089. -				//First check that there's actually a map server online.
  6090. -				ARR_FIND( 0, ARRAYLENGTH(server), j, server[j].fd >= 0 && server[j].map[0] );
  6091. -				if (j == ARRAYLENGTH(server)) {
  6092. -					ShowInfo("Connection Closed. No map servers available.\n");
  6093. -					WFIFOHEAD(fd,3);
  6094. -					WFIFOW(fd,0) = 0x81;
  6095. -					WFIFOB(fd,2) = 1; // 01 = Server closed
  6096. -					WFIFOSET(fd,3);
  6097. -					break;
  6098. -				}
  6099. -				if ((i = search_mapserver((j=mapindex_name2id(MAP_PRONTERA)),-1,-1)) >= 0) {
  6100. -					cd->last_point.x = 273;
  6101. -					cd->last_point.y = 354;
  6102. -				} else if ((i = search_mapserver((j=mapindex_name2id(MAP_GEFFEN)),-1,-1)) >= 0) {
  6103. -					cd->last_point.x = 120;
  6104. -					cd->last_point.y = 100;
  6105. -				} else if ((i = search_mapserver((j=mapindex_name2id(MAP_MORROC)),-1,-1)) >= 0) {
  6106. -					cd->last_point.x = 160;
  6107. -					cd->last_point.y = 94;
  6108. -				} else if ((i = search_mapserver((j=mapindex_name2id(MAP_ALBERTA)),-1,-1)) >= 0) {
  6109. -					cd->last_point.x = 116;
  6110. -					cd->last_point.y = 57;
  6111. -				} else if ((i = search_mapserver((j=mapindex_name2id(MAP_PAYON)),-1,-1)) >= 0) {
  6112. -					cd->last_point.x = 87;
  6113. -					cd->last_point.y = 117;
  6114. -				} else if ((i = search_mapserver((j=mapindex_name2id(MAP_IZLUDE)),-1,-1)) >= 0) {
  6115. -					cd->last_point.x = 94;
  6116. -					cd->last_point.y = 103;
  6117. -				} else {
  6118. -					ShowInfo("Connection Closed. No map server available that has a major city, and unable to find map-server for '%s'.\n", mapindex_id2name(cd->last_point.map));
  6119. -					WFIFOHEAD(fd,3);
  6120. -					WFIFOW(fd,0) = 0x81;
  6121. -					WFIFOB(fd,2) = 1; // 01 = Server closed
  6122. -					WFIFOSET(fd,3);
  6123. -					break;
  6124. -				}
  6125. -				ShowWarning("Unable to find map-server for '%s', sending to major city '%s'.\n", mapindex_id2name(cd->last_point.map), mapindex_id2name(j));
  6126. -				cd->last_point.map = j;
  6127. -			}
  6128. -
  6129. -			//Send NEW auth packet [Kevin]
  6130. -			//FIXME: is this case even possible? [ultramage]
  6131. -			if ((map_fd = server[i].fd) < 1 || session[map_fd] == NULL)
  6132. -			{
  6133. -				ShowError("parse_char: Attempting to write to invalid session %d! Map Server #%d disconnected.\n", map_fd, i);
  6134. -				server[i].fd = -1;
  6135. -				memset(&server[i], 0, sizeof(struct mmo_map_server));
  6136. -				//Send server closed.
  6137. -				WFIFOHEAD(fd,3);
  6138. -				WFIFOW(fd,0) = 0x81;
  6139. -				WFIFOB(fd,2) = 1; // 01 = Server closed
  6140. -				WFIFOSET(fd,3);
  6141. -				break;
  6142. -			}
  6143. -
  6144. -			//Send player to map
  6145. -			WFIFOHEAD(fd,28);
  6146. -			WFIFOW(fd,0) = 0x71;
  6147. -			WFIFOL(fd,2) = cd->char_id;
  6148. -			mapindex_getmapname_ext(mapindex_id2name(cd->last_point.map), (char*)WFIFOP(fd,6));
  6149. -			subnet_map_ip = lan_subnetcheck(ipl); // Advanced subnet check [LuzZza]
  6150. -			WFIFOL(fd,22) = htonl((subnet_map_ip) ? subnet_map_ip : server[i].ip);
  6151. -			WFIFOW(fd,26) = ntows(htons(server[i].port)); // [!] LE byte order here [!]
  6152. -			WFIFOSET(fd,28);
  6153. -
  6154. -			// create temporary auth entry
  6155. -			CREATE(node, struct auth_node, 1);
  6156. -			node->account_id = sd->account_id;
  6157. -			node->char_id = cd->char_id;
  6158. -			node->login_id1 = sd->login_id1;
  6159. -			node->login_id2 = sd->login_id2;
  6160. -			node->sex = sd->sex;
  6161. -			node->expiration_time = sd->expiration_time;
  6162. -			node->group_id = sd->group_id;
  6163. -			node->ip = ipl;
  6164. -			idb_put(auth_db, sd->account_id, node);
  6165. -
  6166. -		}
  6167. -		break;
  6168. -
  6169. -		// create new char
  6170. -#if PACKETVER >= 20120307
  6171. -		// S 0970 <name>.24B <slot>.B <hair color>.W <hair style>.W
  6172. -		case 0x970:
  6173. -			FIFOSD_CHECK(31);
  6174. -#else
  6175. -		// S 0067 <name>.24B <str>.B <agi>.B <vit>.B <int>.B <dex>.B <luk>.B <slot>.B <hair color>.W <hair style>.W
  6176. -		case 0x67:
  6177. -			FIFOSD_CHECK(37);
  6178. -#endif
  6179. -
  6180. -			if( !char_new ) //turn character creation on/off [Kevin]
  6181. -				i = -2;
  6182. -			else
  6183. -#if PACKETVER >= 20120307
  6184. -				i = make_new_char_sql(sd, (char*)RFIFOP(fd,2),RFIFOB(fd,26),RFIFOW(fd,27),RFIFOW(fd,29));
  6185. -#else
  6186. -				i = make_new_char_sql(sd, (char*)RFIFOP(fd,2),RFIFOB(fd,26),RFIFOB(fd,27),RFIFOB(fd,28),RFIFOB(fd,29),RFIFOB(fd,30),RFIFOB(fd,31),RFIFOB(fd,32),RFIFOW(fd,33),RFIFOW(fd,35));
  6187. -#endif
  6188. -
  6189. -			//'Charname already exists' (-1), 'Char creation denied' (-2) and 'You are underaged' (-3)
  6190. -			if (i < 0) {
  6191. -				WFIFOHEAD(fd,3);
  6192. -				WFIFOW(fd,0) = 0x6e;
  6193. -				/* Others I found [Ind] */
  6194. -				/* 0x02 = Symbols in Character Names are forbidden */
  6195. -				/* 0x03 = You are not elegible to open the Character Slot. */
  6196. -				switch (i) {
  6197. -					case -1: WFIFOB(fd,2) = 0x00; break;
  6198. -					case -2: WFIFOB(fd,2) = 0xFF; break;
  6199. -					case -3: WFIFOB(fd,2) = 0x01; break;
  6200. -					case -4: WFIFOB(fd,2) = 0x03; break;
  6201. -				}
  6202. -				WFIFOSET(fd,3);
  6203. -			} else {
  6204. -				int len;
  6205. -				// retrieve data
  6206. -				struct mmo_charstatus char_dat;
  6207. -				mmo_char_fromsql(i, &char_dat, false); //Only the short data is needed.
  6208. -
  6209. -				// send to player
  6210. -				WFIFOHEAD(fd,2+MAX_CHAR_BUF);
  6211. -				WFIFOW(fd,0) = 0x6d;
  6212. -				len = 2 + mmo_char_tobuf(WFIFOP(fd,2), &char_dat);
  6213. -				WFIFOSET(fd,len);
  6214. -
  6215. -				// add new entry to the chars list
  6216. -				ARR_FIND( 0, MAX_CHARS, ch, sd->found_char[ch] == -1 );
  6217. -				if( ch < MAX_CHARS )
  6218. -					sd->found_char[ch] = i; // the char_id of the new char
  6219. -			}
  6220. -#if PACKETVER >= 20120307
  6221. -			RFIFOSKIP(fd,31);
  6222. -#else
  6223. -			RFIFOSKIP(fd,37);
  6224. -#endif
  6225. -		break;
  6226. -
  6227. -		// delete char
  6228. -		case 0x68:
  6229. -		// 2004-04-19aSakexe+ langtype 12 char deletion packet
  6230. -		case 0x1fb:
  6231. -			if (cmd == 0x68) FIFOSD_CHECK(46);
  6232. -			if (cmd == 0x1fb) FIFOSD_CHECK(56);
  6233. -		{
  6234. -			int cid = RFIFOL(fd,2);
  6235. -
  6236. -			ShowInfo(CL_RED"Request Char Deletion: "CL_GREEN"%d (%d)"CL_RESET"\n", sd->account_id, cid);
  6237. -			memcpy(email, RFIFOP(fd,6), 40);
  6238. -			RFIFOSKIP(fd,( cmd == 0x68) ? 46 : 56);
  6239. -
  6240. -			// Check if e-mail is correct
  6241. -			if(strcmpi(email, sd->email) && //email does not matches and
  6242. -			(
  6243. -				strcmp("[email protected]", sd->email) || //it is not default email, or
  6244. -				(strcmp("[email protected]", email) && strcmp("", email)) //email sent does not matches default
  6245. -			)) {	//Fail
  6246. -				WFIFOHEAD(fd,3);
  6247. -				WFIFOW(fd,0) = 0x70;
  6248. -				WFIFOB(fd,2) = 0; // 00 = Incorrect Email address
  6249. -				WFIFOSET(fd,3);
  6250. -				break;
  6251. -			}
  6252. -
  6253. -			// check if this char exists
  6254. -			ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == cid );
  6255. -			if( i == MAX_CHARS )
  6256. -			{ // Such a character does not exist in the account
  6257. -				WFIFOHEAD(fd,3);
  6258. -				WFIFOW(fd,0) = 0x70;
  6259. -				WFIFOB(fd,2) = 0;
  6260. -				WFIFOSET(fd,3);
  6261. -				break;
  6262. -			}
  6263. -
  6264. -			// remove char from list and compact it
  6265. -			for(ch = i; ch < MAX_CHARS-1; ch++)
  6266. -				sd->found_char[ch] = sd->found_char[ch+1];
  6267. -			sd->found_char[MAX_CHARS-1] = -1;
  6268. -
  6269. -			/* Delete character */
  6270. -			if(delete_char_sql(cid)<0){
  6271. -				//can't delete the char
  6272. -				//either SQL error or can't delete by some CONFIG conditions
  6273. -				//del fail
  6274. -				WFIFOHEAD(fd,3);
  6275. -				WFIFOW(fd, 0) = 0x70;
  6276. -				WFIFOB(fd, 2) = 0;
  6277. -				WFIFOSET(fd, 3);
  6278. -				break;
  6279. -			}
  6280. -			/* Char successfully deleted.*/
  6281. -			WFIFOHEAD(fd,2);
  6282. -			WFIFOW(fd,0) = 0x6f;
  6283. -			WFIFOSET(fd,2);
  6284. -		}
  6285. -		break;
  6286. -
  6287. -		// client keep-alive packet (every 12 seconds)
  6288. -		// R 0187 <account ID>.l
  6289. -		case 0x187:
  6290. -			if (RFIFOREST(fd) < 6)
  6291. -				return 0;
  6292. -			RFIFOSKIP(fd,6);
  6293. -		break;
  6294. -		// char rename request
  6295. -		// R 08fc <char ID>.l <new name>.24B
  6296. -		case 0x8fc:
  6297. -			FIFOSD_CHECK(30);
  6298. -			{
  6299. -				int i, cid =RFIFOL(fd,2);
  6300. -				char name[NAME_LENGTH];
  6301. -				char esc_name[NAME_LENGTH*2+1];
  6302. -				safestrncpy(name, (char *)RFIFOP(fd,6), NAME_LENGTH);
  6303. -				RFIFOSKIP(fd,30);
  6304. -
  6305. -				ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == cid );
  6306. -				if( i == MAX_CHARS )
  6307. -					break;
  6308. -
  6309. -				normalize_name(name,TRIM_CHARS);
  6310. -				Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
  6311. -				if( !check_char_name(name,esc_name) ) {
  6312. -					i = 1;
  6313. -					safestrncpy(sd->new_name, name, NAME_LENGTH);
  6314. -				} else
  6315. -					i = 0;
  6316. -
  6317. -				WFIFOHEAD(fd, 4);
  6318. -				WFIFOW(fd,0) = 0x28e;
  6319. -				WFIFOW(fd,2) = i;
  6320. -				WFIFOSET(fd,4);
  6321. -			}
  6322. -			break;
  6323. -
  6324. -		// char rename request
  6325. -		// R 028d <account ID>.l <char ID>.l <new name>.24B
  6326. -		case 0x28d:
  6327. -			FIFOSD_CHECK(34);
  6328. -			{
  6329. -				int i, aid = RFIFOL(fd,2), cid =RFIFOL(fd,6);
  6330. -				char name[NAME_LENGTH];
  6331. - 				char esc_name[NAME_LENGTH*2+1];
  6332. -				safestrncpy(name, (char *)RFIFOP(fd,10), NAME_LENGTH);
  6333. -				RFIFOSKIP(fd,34);
  6334. -
  6335. -				if( aid != sd->account_id )
  6336. -					break;
  6337. -				ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == cid );
  6338. -				if( i == MAX_CHARS )
  6339. -					break;
  6340. -
  6341. -				normalize_name(name,TRIM_CHARS);
  6342. -				Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
  6343. -				if( !check_char_name(name,esc_name) )
  6344. -				{
  6345. -					i = 1;
  6346. -					safestrncpy(sd->new_name, name, NAME_LENGTH);
  6347. -				}
  6348. -				else
  6349. -					i = 0;
  6350. -
  6351. -				WFIFOHEAD(fd, 4);
  6352. -				WFIFOW(fd,0) = 0x28e;
  6353. -				WFIFOW(fd,2) = i;
  6354. -				WFIFOSET(fd,4);
  6355. -			}
  6356. -			break;
  6357. -		//Confirm change name.
  6358. -		// 0x28f <char_id>.L
  6359. -		case 0x28f:
  6360. -			// 0: Sucessfull
  6361. -			// 1: This character's name has already been changed. You cannot change a character's name more than once.
  6362. -			// 2: User information is not correct.
  6363. -			// 3: You have failed to change this character's name.
  6364. -			// 4: Another user is using this character name, so please select another one.
  6365. -			FIFOSD_CHECK(6);
  6366. -			{
  6367. -				int i;
  6368. -				int cid = RFIFOL(fd,2);
  6369. -				RFIFOSKIP(fd,6);
  6370. -
  6371. -				ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == cid );
  6372. -				if( i == MAX_CHARS )
  6373. -					break;
  6374. -				i = rename_char_sql(sd, cid);
  6375. -
  6376. -				WFIFOHEAD(fd, 4);
  6377. -				WFIFOW(fd,0) = 0x290;
  6378. -				WFIFOW(fd,2) = i;
  6379. -				WFIFOSET(fd,4);
  6380. -			}
  6381. -			break;
  6382. -
  6383. -		// captcha code request (not implemented)
  6384. -		// R 07e5 <?>.w <aid>.l
  6385. -		case 0x7e5:
  6386. -			WFIFOHEAD(fd,5);
  6387. -			WFIFOW(fd,0) = 0x7e9;
  6388. -			WFIFOW(fd,2) = 5;
  6389. -			WFIFOB(fd,4) = 1;
  6390. -			WFIFOSET(fd,5);
  6391. -			RFIFOSKIP(fd,8);
  6392. -			break;
  6393. -
  6394. -		// captcha code check (not implemented)
  6395. -		// R 07e7 <len>.w <aid>.l <code>.b10 <?>.b14
  6396. -		case 0x7e7:
  6397. -			WFIFOHEAD(fd,5);
  6398. -			WFIFOW(fd,0) = 0x7e9;
  6399. -			WFIFOW(fd,2) = 5;
  6400. -			WFIFOB(fd,4) = 1;
  6401. -			WFIFOSET(fd,5);
  6402. -			RFIFOSKIP(fd,32);
  6403. -		break;
  6404. -
  6405. -		// deletion timer request
  6406. -		case 0x827:
  6407. -			FIFOSD_CHECK(6);
  6408. -			char_delete2_req(fd, sd);
  6409. -			RFIFOSKIP(fd,6);
  6410. -		break;
  6411. -
  6412. -		// deletion accept request
  6413. -		case 0x829:
  6414. -			FIFOSD_CHECK(12);
  6415. -			char_delete2_accept(fd, sd);
  6416. -			RFIFOSKIP(fd,12);
  6417. -		break;
  6418. -
  6419. -		// deletion cancel request
  6420. -		case 0x82b:
  6421. -			FIFOSD_CHECK(6);
  6422. -			char_delete2_cancel(fd, sd);
  6423. -			RFIFOSKIP(fd,6);
  6424. -		break;
  6425. -
  6426. -		// login as map-server
  6427. -		case 0x2af8:
  6428. -			if (RFIFOREST(fd) < 60)
  6429. -				return 0;
  6430. -			else {
  6431. -				char* l_user = (char*)RFIFOP(fd,2);
  6432. -				char* l_pass = (char*)RFIFOP(fd,26);
  6433. -				l_user[23] = '\0';
  6434. -				l_pass[23] = '\0';
  6435. -				ARR_FIND( 0, ARRAYLENGTH(server), i, server[i].fd <= 0 );
  6436. -				if( runflag != CHARSERVER_ST_RUNNING ||
  6437. -					i == ARRAYLENGTH(server) ||
  6438. -					strcmp(l_user, userid) != 0 ||
  6439. -					strcmp(l_pass, passwd) != 0 )
  6440. -				{
  6441. -					WFIFOHEAD(fd,3);
  6442. -					WFIFOW(fd,0) = 0x2af9;
  6443. -					WFIFOB(fd,2) = 3;
  6444. -					WFIFOSET(fd,3);
  6445. -				} else {
  6446. -					WFIFOHEAD(fd,3);
  6447. -					WFIFOW(fd,0) = 0x2af9;
  6448. -					WFIFOB(fd,2) = 0;
  6449. -					WFIFOSET(fd,3);
  6450. -
  6451. -					server[i].fd = fd;
  6452. -					server[i].ip = ntohl(RFIFOL(fd,54));
  6453. -					server[i].port = ntohs(RFIFOW(fd,58));
  6454. -					server[i].users = 0;
  6455. -					memset(server[i].map, 0, sizeof(server[i].map));
  6456. -					session[fd]->func_parse = parse_frommap;
  6457. -					session[fd]->flag.server = 1;
  6458. -					realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
  6459. -					char_mapif_init(fd);
  6460. -				}
  6461. -				RFIFOSKIP(fd,60);
  6462. -			}
  6463. -			return 0; // avoid processing of followup packets here
  6464. -
  6465. -		// checks the entered pin
  6466. -		case 0x8b8:
  6467. -			if( RFIFOREST(fd) < 10 )
  6468. -				return 0;
  6469. -			if( pincode_enabled && RFIFOL(fd,2) == sd->account_id )
  6470. -				pincode_check( fd, sd );
  6471. -			RFIFOSKIP(fd,10);
  6472. -		break;
  6473. -
  6474. -		// request for PIN window
  6475. -		case 0x8c5:
  6476. -			if( RFIFOREST(fd) < 6 )
  6477. -				return 0;
  6478. -			if( pincode_enabled && RFIFOL(fd,2) == sd->account_id ){
  6479. -				if( strlen( sd->pincode ) <= 0 ){
  6480. -					pincode_sendstate( fd, sd, PINCODE_NEW );
  6481. -				}else{
  6482. -					pincode_sendstate( fd, sd, PINCODE_ASK );
  6483. -				}
  6484. -			}
  6485. -			RFIFOSKIP(fd,6);
  6486. -		break;
  6487. -
  6488. -		// pincode change request
  6489. -		case 0x8be:
  6490. -			if( RFIFOREST(fd) < 14 )
  6491. -				return 0;
  6492. -
  6493. -			if( pincode_enabled && RFIFOL(fd,2) == sd->account_id )
  6494. -				pincode_change( fd, sd );
  6495. -
  6496. -			RFIFOSKIP(fd,14);
  6497. -		break;
  6498. -
  6499. -		// activate PIN system and set first PIN
  6500. -		case 0x8ba:
  6501. -			if( RFIFOREST(fd) < 10 )
  6502. -				return 0;
  6503. -			if( pincode_enabled && RFIFOL(fd,2) == sd->account_id )
  6504. -				pincode_setnew( fd, sd );
  6505. -			RFIFOSKIP(fd,10);
  6506. -		break;
  6507. -
  6508. -		// character movement request
  6509. -		case 0x8d4:
  6510. -			if( RFIFOREST(fd) < 8 )
  6511. -				return 0;
  6512. -
  6513. -			moveCharSlot( fd, sd, RFIFOW(fd, 2), RFIFOW(fd, 4) );
  6514. -			mmo_char_send(fd, sd);
  6515. -			RFIFOSKIP(fd,8);
  6516. -		break;
  6517. -
  6518. -		case 0x9a1:
  6519. -			if( RFIFOREST(fd) < 2 )
  6520. -				return 0;
  6521. -			char_parse_req_charlist(fd,sd);
  6522. -			RFIFOSKIP(fd,2);
  6523. -			break;
  6524. -
  6525. -		// unknown packet received
  6526. -		default:
  6527. -			ShowError("parse_char: Received unknown packet "CL_WHITE"0x%x"CL_RESET" from ip '"CL_WHITE"%s"CL_RESET"'! Disconnecting!\n", RFIFOW(fd,0), ip2str(ipl, NULL));
  6528. -			set_eof(fd);
  6529. -			return 0;
  6530. -		}
  6531. -	}
  6532. -
  6533. -	RFIFOFLUSH(fd);
  6534. -	return 0;
  6535. -}
  6536. -
  6537. -// Console Command Parser [Wizputer]
  6538. -int parse_console(const char* buf)
  6539. -{
  6540. -	char type[64];
  6541. -	char command[64];
  6542. -	int n=0;
  6543. -
  6544. -	if( ( n = sscanf(buf, "%63[^:]:%63[^\n]", type, command) ) < 2 ){
  6545. -		if((n = sscanf(buf, "%63[^\n]", type))<1) return -1; //nothing to do no arg
  6546. -	}
  6547. -	if( n != 2 ){ //end string
  6548. -		ShowNotice("Type: '%s'\n",type);
  6549. -		command[0] = '\0';
  6550. -	}
  6551. -	else
  6552. -		ShowNotice("Type of command: '%s' || Command: '%s'\n",type,command);
  6553. -
  6554. -	if( n == 2 && strcmpi("server", type) == 0 ){
  6555. -		if( strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0 ){
  6556. -			runflag = 0;
  6557. -		}
  6558. -		else if( strcmpi("alive", command) == 0 || strcmpi("status", command) == 0 )
  6559. -			ShowInfo(CL_CYAN"Console: "CL_BOLD"I'm Alive."CL_RESET"\n");
  6560. -	}
  6561. -	else if( strcmpi("ers_report", type) == 0 ){
  6562. -		ers_report();
  6563. -	}
  6564. -	else if( strcmpi("help", type) == 0 ){
  6565. -		ShowInfo("Available commands:\n");
  6566. -		ShowInfo("\t server:shutdown => Stops the server.\n");
  6567. -		ShowInfo("\t server:alive => Checks if the server is running.\n");
  6568. -		ShowInfo("\t ers_report => Displays database usage.\n");
  6569. -	}
  6570. -
  6571. -	return 0;
  6572. -}
  6573. -
  6574. -int mapif_sendall(unsigned char *buf, unsigned int len)
  6575. -{
  6576. -	int i, c;
  6577. -
  6578. -	c = 0;
  6579. -	for(i = 0; i < ARRAYLENGTH(server); i++) {
  6580. -		int fd;
  6581. -		if ((fd = server[i].fd) > 0) {
  6582. -			WFIFOHEAD(fd,len);
  6583. -			memcpy(WFIFOP(fd,0), buf, len);
  6584. -			WFIFOSET(fd,len);
  6585. -			c++;
  6586. -		}
  6587. -	}
  6588. -
  6589. -	return c;
  6590. -}
  6591. -
  6592. -int mapif_sendallwos(int sfd, unsigned char *buf, unsigned int len)
  6593. -{
  6594. -	int i, c;
  6595. -
  6596. -	c = 0;
  6597. -	for(i = 0; i < ARRAYLENGTH(server); i++) {
  6598. -		int fd;
  6599. -		if ((fd = server[i].fd) > 0 && fd != sfd) {
  6600. -			WFIFOHEAD(fd,len);
  6601. -			memcpy(WFIFOP(fd,0), buf, len);
  6602. -			WFIFOSET(fd,len);
  6603. -			c++;
  6604. -		}
  6605. -	}
  6606. -
  6607. -	return c;
  6608. -}
  6609. -
  6610. -int mapif_send(int fd, unsigned char *buf, unsigned int len)
  6611. -{
  6612. -	if (fd >= 0) {
  6613. -		int i;
  6614. -		ARR_FIND( 0, ARRAYLENGTH(server), i, fd == server[i].fd );
  6615. -		if( i < ARRAYLENGTH(server) )
  6616. -		{
  6617. -			WFIFOHEAD(fd,len);
  6618. -			memcpy(WFIFOP(fd,0), buf, len);
  6619. -			WFIFOSET(fd,len);
  6620. -			return 1;
  6621. -		}
  6622. -	}
  6623. -	return 0;
  6624. -}
  6625. -
  6626. -int broadcast_user_count(int tid, unsigned int tick, int id, intptr_t data)
  6627. -{
  6628. -	uint8 buf[6];
  6629. +int broadcast_user_count(int tid, unsigned int tick, int id, intptr_t data){
  6630.  	int users = count_users();
  6631.  
  6632.  	// only send an update when needed
  6633. @@ -4517,192 +1965,12 @@
  6634.  		return 0;
  6635.  	prev_users = users;
  6636.  
  6637. -	if( login_fd > 0 && session[login_fd] )
  6638. -	{
  6639. -		// send number of user to login server
  6640. -		WFIFOHEAD(login_fd,6);
  6641. -		WFIFOW(login_fd,0) = 0x2714;
  6642. -		WFIFOL(login_fd,2) = users;
  6643. -		WFIFOSET(login_fd,6);
  6644. -	}
  6645. -
  6646. -	// send number of players to all map-servers
  6647. -	WBUFW(buf,0) = 0x2b00;
  6648. -	WBUFL(buf,2) = users;
  6649. -	mapif_sendall(buf,6);
  6650. -
  6651. +	char_send_usercount(users);
  6652. +	char_sendall_playercount(users);
  6653.  	return 0;
  6654.  }
  6655.  
  6656. -/**
  6657. - * Load this character's account id into the 'online accounts' packet
  6658. - * @see DBApply
  6659. - */
  6660. -static int send_accounts_tologin_sub(DBKey key, DBData *data, va_list ap)
  6661. -{
  6662. -	struct online_char_data* character = db_data2ptr(data);
  6663. -	int* i = va_arg(ap, int*);
  6664.  
  6665. -	if(character->server > -1)
  6666. -	{
  6667. -		WFIFOL(login_fd,8+(*i)*4) = character->account_id;
  6668. -		(*i)++;
  6669. -		return 1;
  6670. -	}
  6671. -	return 0;
  6672. -}
  6673. -
  6674. -int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data)
  6675. -{
  6676. -	if (login_fd > 0 && session[login_fd])
  6677. -	{
  6678. -		// send account list to login server
  6679. -		int users = online_char_db->size(online_char_db);
  6680. -		int i = 0;
  6681. -
  6682. -		WFIFOHEAD(login_fd,8+users*4);
  6683. -		WFIFOW(login_fd,0) = 0x272d;
  6684. -		online_char_db->foreach(online_char_db, send_accounts_tologin_sub, &i, users);
  6685. -		WFIFOW(login_fd,2) = 8+ i*4;
  6686. -		WFIFOL(login_fd,4) = i;
  6687. -		WFIFOSET(login_fd,WFIFOW(login_fd,2));
  6688. -	}
  6689. -	return 0;
  6690. -}
  6691. -
  6692. -int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data)
  6693. -{
  6694. -	if (login_fd > 0 && session[login_fd] != NULL)
  6695. -		return 0;
  6696. -
  6697. -	ShowInfo("Attempt to connect to login-server...\n");
  6698. -	login_fd = make_connection(login_ip, login_port, false,10);
  6699. -	if (login_fd == -1)
  6700. -	{	//Try again later. [Skotlex]
  6701. -		login_fd = 0;
  6702. -		return 0;
  6703. -	}
  6704. -	session[login_fd]->func_parse = parse_fromlogin;
  6705. -	session[login_fd]->flag.server = 1;
  6706. -	realloc_fifo(login_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
  6707. -
  6708. -	WFIFOHEAD(login_fd,86);
  6709. -	WFIFOW(login_fd,0) = 0x2710;
  6710. -	memcpy(WFIFOP(login_fd,2), userid, 24);
  6711. -	memcpy(WFIFOP(login_fd,26), passwd, 24);
  6712. -	WFIFOL(login_fd,50) = 0;
  6713. -	WFIFOL(login_fd,54) = htonl(char_ip);
  6714. -	WFIFOW(login_fd,58) = htons(char_port);
  6715. -	memcpy(WFIFOP(login_fd,60), server_name, 20);
  6716. -	WFIFOW(login_fd,80) = 0;
  6717. -	WFIFOW(login_fd,82) = char_maintenance;
  6718. -	WFIFOW(login_fd,84) = char_new_display; //only display (New) if they want to [Kevin]
  6719. -	WFIFOSET(login_fd,86);
  6720. -
  6721. -	return 1;
  6722. -}
  6723. -
  6724. -//------------------------------------------------
  6725. -//Pincode system
  6726. -//------------------------------------------------
  6727. -void pincode_check( int fd, struct char_session_data* sd ){
  6728. -	char pin[PINCODE_LENGTH+1];
  6729. -
  6730. -	memset(pin,0,PINCODE_LENGTH+1);
  6731. -
  6732. -	strncpy((char*)pin, (char*)RFIFOP(fd, 6), PINCODE_LENGTH);
  6733. -
  6734. -	pincode_decrypt(sd->pincode_seed, pin );
  6735. -
  6736. -	if( pincode_compare( fd, sd, pin ) ){
  6737. -		pincode_sendstate( fd, sd, PINCODE_PASSED );
  6738. -	}
  6739. -}
  6740. -
  6741. -int pincode_compare( int fd, struct char_session_data* sd, char* pin ){
  6742. -	if( strcmp( sd->pincode, pin ) == 0 ){
  6743. -		sd->pincode_try = 0;
  6744. -		return 1;
  6745. -	}else{
  6746. -		pincode_sendstate( fd, sd, PINCODE_WRONG );
  6747. -
  6748. -		if( pincode_maxtry && ++sd->pincode_try >= pincode_maxtry ){
  6749. -			pincode_notifyLoginPinError( sd->account_id );
  6750. -		}
  6751. -
  6752. -		return 0;
  6753. -	}
  6754. -}
  6755. -
  6756. -void pincode_change( int fd, struct char_session_data* sd ){
  6757. -	char oldpin[PINCODE_LENGTH+1];
  6758. -	char newpin[PINCODE_LENGTH+1];
  6759. -
  6760. -	memset(oldpin,0,PINCODE_LENGTH+1);
  6761. -	memset(newpin,0,PINCODE_LENGTH+1);
  6762. -
  6763. -	strncpy(oldpin, (char*)RFIFOP(fd,6), PINCODE_LENGTH);
  6764. -	pincode_decrypt(sd->pincode_seed,oldpin);
  6765. -
  6766. -	if( !pincode_compare( fd, sd, oldpin ) )
  6767. -		return;
  6768. -
  6769. -	strncpy(newpin, (char*)RFIFOP(fd,10), PINCODE_LENGTH);
  6770. -	pincode_decrypt(sd->pincode_seed,newpin);
  6771. -
  6772. -	pincode_notifyLoginPinUpdate( sd->account_id, newpin );
  6773. -	strncpy(sd->pincode, newpin, sizeof(newpin));
  6774. -
  6775. -	pincode_sendstate( fd, sd, PINCODE_PASSED );
  6776. -}
  6777. -
  6778. -void pincode_setnew( int fd, struct char_session_data* sd ){
  6779. -	char newpin[PINCODE_LENGTH+1];
  6780. -
  6781. -	memset(newpin,0,PINCODE_LENGTH+1);
  6782. -
  6783. -	strncpy( newpin, (char*)RFIFOP(fd,6), PINCODE_LENGTH );
  6784. -	pincode_decrypt( sd->pincode_seed, newpin );
  6785. -
  6786. -	pincode_notifyLoginPinUpdate( sd->account_id, newpin );
  6787. -	strncpy( sd->pincode, newpin, strlen( newpin ) );
  6788. -
  6789. -	pincode_sendstate( fd, sd, PINCODE_PASSED );
  6790. -}
  6791. -
  6792. -// 0 = disabled / pin is correct
  6793. -// 1 = ask for pin - client sends 0x8b8
  6794. -// 2 = create new pin - client sends 0x8ba
  6795. -// 3 = pin must be changed - client 0x8be
  6796. -// 4 = create new pin - client sends 0x8ba
  6797. -// 5 = client shows msgstr(1896)
  6798. -// 6 = client shows msgstr(1897) Unable to use your KSSN number
  6799. -// 7 = char select window shows a button - client sends 0x8c5
  6800. -// 8 = pincode was incorrect
  6801. -void pincode_sendstate( int fd, struct char_session_data* sd, uint16 state ){
  6802. -	WFIFOHEAD(fd, 12);
  6803. -	WFIFOW(fd, 0) = 0x8b9;
  6804. -	WFIFOL(fd, 2) = sd->pincode_seed = rnd() % 0xFFFF;
  6805. -	WFIFOL(fd, 6) = sd->account_id;
  6806. -	WFIFOW(fd,10) = state;
  6807. -	WFIFOSET(fd,12);
  6808. -}
  6809. -
  6810. -void pincode_notifyLoginPinUpdate( int account_id, char* pin ){
  6811. -	WFIFOHEAD(login_fd,11);
  6812. -	WFIFOW(login_fd,0) = 0x2738;
  6813. -	WFIFOL(login_fd,2) = account_id;
  6814. -	strncpy( (char*)WFIFOP(login_fd,6), pin, PINCODE_LENGTH+1 );
  6815. -	WFIFOSET(login_fd,11);
  6816. -}
  6817. -
  6818. -void pincode_notifyLoginPinError( int account_id ){
  6819. -	WFIFOHEAD(login_fd,6);
  6820. -	WFIFOW(login_fd,0) = 0x2739;
  6821. -	WFIFOL(login_fd,2) = account_id;
  6822. -	WFIFOSET(login_fd,6);
  6823. -}
  6824. -
  6825.  void pincode_decrypt( uint32 userSeed, char* pin ){
  6826.  	int i, pos;
  6827.  	char tab[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  6828. @@ -4728,74 +1996,27 @@
  6829.  	free( buf );
  6830.  }
  6831.  
  6832. -//------------------------------------------------
  6833. -//Add On system
  6834. -//------------------------------------------------
  6835. -void moveCharSlot( int fd, struct char_session_data* sd, unsigned short from, unsigned short to ){
  6836. -	// Have we changed to often or is it disabled?
  6837. -	if( !char_move_enabled || ( !char_moves_unlimited && sd->char_moves[from] <= 0 ) ){
  6838. -		moveCharSlotReply( fd, sd, from, 1 );
  6839. -		return;
  6840. -	}
  6841. +int pincode_compare( int fd, struct char_session_data* sd, char* pin ){
  6842. +	if( strcmp( sd->pincode, pin ) == 0 ){
  6843. +		sd->pincode_try = 0;
  6844. +		return 1;
  6845. +	}else{
  6846. +		pincode_sendstate( fd, sd, PINCODE_WRONG );
  6847.  
  6848. -	// We dont even have a character on the chosen slot?
  6849. -	if( sd->found_char[from] <= 0 ){
  6850. -		moveCharSlotReply( fd, sd, from, 1 );
  6851. -		return;
  6852. -	}
  6853. -
  6854. -	if( sd->found_char[to] > 0 ){
  6855. -		// We want to move to a used position
  6856. -		if( char_movetoused ){ // TODO: check if the target is in deletion process
  6857. -			// Admin is friendly and uses triangle exchange
  6858. -			if(	   SQL_ERROR == Sql_QueryStr(sql_handle, "START TRANSACTION")
  6859. -				|| SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `char_num`='%d' WHERE `char_id` = '%d'", char_db, to, sd->found_char[from] )
  6860. -				|| SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `char_num`='%d' WHERE `char_id` = '%d'", char_db, from, sd->found_char[to] )
  6861. -				|| SQL_ERROR == Sql_QueryStr(sql_handle, "COMMIT")
  6862. -				){
  6863. -				moveCharSlotReply( fd, sd, from, 1 );
  6864. -				Sql_ShowDebug(sql_handle);
  6865. -				Sql_QueryStr(sql_handle,"ROLLBACK");
  6866. -				return;
  6867. -			}
  6868. -		}else{
  6869. -			// Admin doesnt allow us to
  6870. -			moveCharSlotReply( fd, sd, from, 1 );
  6871. -			return;
  6872. +		if( pincode_config.pincode_maxtry && ++sd->pincode_try >= pincode_config.pincode_maxtry ){
  6873. +			pincode_notifyLoginPinError( sd->account_id );
  6874.  		}
  6875. -	}else if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `char_num`='%d' WHERE `char_id`='%d'", char_db, to, sd->found_char[from] ) ){
  6876. -		Sql_ShowDebug(sql_handle);
  6877. -		moveCharSlotReply( fd, sd, from, 1 );
  6878. -		return;
  6879. -	}
  6880.  
  6881. -	if( !char_moves_unlimited ){
  6882. -		sd->char_moves[from]--;
  6883. -		Sql_Query(sql_handle, "UPDATE `%s` SET `moves`='%d' WHERE `char_id`='%d'", char_db, sd->char_moves[from], sd->found_char[from] );
  6884. +		return 0;
  6885.  	}
  6886. -
  6887. -	// We successfully moved the char - time to notify the client
  6888. -	moveCharSlotReply( fd, sd, from, 0 );
  6889. -	mmo_char_send(fd, sd);
  6890.  }
  6891.  
  6892. -// reason
  6893. -// 0: success
  6894. -// 1: failed
  6895. -void moveCharSlotReply( int fd, struct char_session_data* sd, unsigned short index, short reason ){
  6896. -	WFIFOHEAD(fd,8);
  6897. -	WFIFOW(fd,0) = 0x8d5;
  6898. -	WFIFOW(fd,2) = 8;
  6899. -	WFIFOW(fd,4) = reason;
  6900. -	WFIFOW(fd,6) = sd->char_moves[index];
  6901. -	WFIFOSET(fd,8);
  6902. -}
  6903.  
  6904.  //------------------------------------------------
  6905.  //Invoked 15 seconds after mapif_disconnectplayer in case the map server doesn't
  6906.  //replies/disconnect the player we tried to kick. [Skotlex]
  6907.  //------------------------------------------------
  6908. -static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data)
  6909. +int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data)
  6910.  {
  6911.  	struct online_char_data* character;
  6912.  	if ((character = (struct online_char_data*)idb_get(online_char_db, id)) != NULL && character->waiting_disconnect == tid)
  6913. @@ -4828,6 +2049,8 @@
  6914.  	return 0;
  6915.  }
  6916.  
  6917. +
  6918. +
  6919.  //----------------------------------
  6920.  // Reading Lan Support configuration
  6921.  // Rewrote: Anvanced subnet check [LuzZza]
  6922. @@ -4901,63 +2124,63 @@
  6923.  			continue;
  6924.  
  6925.  		if(!strcmpi(w1,"char_db"))
  6926. -			safestrncpy(char_db, w2, sizeof(char_db));
  6927. +			safestrncpy(schema_config.char_db, w2, sizeof(schema_config.char_db));
  6928.  		else if(!strcmpi(w1,"scdata_db"))
  6929. -			safestrncpy(scdata_db, w2, sizeof(scdata_db));
  6930. +			safestrncpy(schema_config.scdata_db, w2, sizeof(schema_config.scdata_db));
  6931.  		else if(!strcmpi(w1,"cart_db"))
  6932. -			safestrncpy(cart_db, w2, sizeof(cart_db));
  6933. +			safestrncpy(schema_config.cart_db, w2, sizeof(schema_config.cart_db));
  6934.  		else if(!strcmpi(w1,"inventory_db"))
  6935. -			safestrncpy(inventory_db, w2, sizeof(inventory_db));
  6936. +			safestrncpy(schema_config.inventory_db, w2, sizeof(schema_config.inventory_db));
  6937.  		else if(!strcmpi(w1,"charlog_db"))
  6938. -			safestrncpy(charlog_db, w2, sizeof(charlog_db));
  6939. +			safestrncpy(schema_config.charlog_db, w2, sizeof(schema_config.charlog_db));
  6940.  		else if(!strcmpi(w1,"storage_db"))
  6941. -			safestrncpy(storage_db, w2, sizeof(storage_db));
  6942. +			safestrncpy(schema_config.storage_db, w2, sizeof(schema_config.storage_db));
  6943.  		else if(!strcmpi(w1,"reg_db"))
  6944. -			safestrncpy(reg_db, w2, sizeof(reg_db));
  6945. +			safestrncpy(schema_config.reg_db, w2, sizeof(schema_config.reg_db));
  6946.  		else if(!strcmpi(w1,"skill_db"))
  6947. -			safestrncpy(skill_db, w2, sizeof(skill_db));
  6948. +			safestrncpy(schema_config.skill_db, w2, sizeof(schema_config.skill_db));
  6949.  		else if(!strcmpi(w1,"interlog_db"))
  6950. -			safestrncpy(interlog_db, w2, sizeof(interlog_db));
  6951. +			safestrncpy(schema_config.interlog_db, w2, sizeof(schema_config.interlog_db));
  6952.  		else if(!strcmpi(w1,"memo_db"))
  6953. -			safestrncpy(memo_db, w2, sizeof(memo_db));
  6954. +			safestrncpy(schema_config.memo_db, w2, sizeof(schema_config.memo_db));
  6955.  		else if(!strcmpi(w1,"guild_db"))
  6956. -			safestrncpy(guild_db, w2, sizeof(guild_db));
  6957. +			safestrncpy(schema_config.guild_db, w2, sizeof(schema_config.guild_db));
  6958.  		else if(!strcmpi(w1,"guild_alliance_db"))
  6959. -			safestrncpy(guild_alliance_db, w2, sizeof(guild_alliance_db));
  6960. +			safestrncpy(schema_config.guild_alliance_db, w2, sizeof(schema_config.guild_alliance_db));
  6961.  		else if(!strcmpi(w1,"guild_castle_db"))
  6962. -			safestrncpy(guild_castle_db, w2, sizeof(guild_castle_db));
  6963. +			safestrncpy(schema_config.guild_castle_db, w2, sizeof(schema_config.guild_castle_db));
  6964.  		else if(!strcmpi(w1,"guild_expulsion_db"))
  6965. -			safestrncpy(guild_expulsion_db, w2, sizeof(guild_expulsion_db));
  6966. +			safestrncpy(schema_config.guild_expulsion_db, w2, sizeof(schema_config.guild_expulsion_db));
  6967.  		else if(!strcmpi(w1,"guild_member_db"))
  6968. -			safestrncpy(guild_member_db, w2, sizeof(guild_member_db));
  6969. +			safestrncpy(schema_config.guild_member_db, w2, sizeof(schema_config.guild_member_db));
  6970.  		else if(!strcmpi(w1,"guild_skill_db"))
  6971. -			safestrncpy(guild_skill_db, w2, sizeof(guild_skill_db));
  6972. +			safestrncpy(schema_config.guild_skill_db, w2, sizeof(schema_config.guild_skill_db));
  6973.  		else if(!strcmpi(w1,"guild_position_db"))
  6974. -			safestrncpy(guild_position_db, w2, sizeof(guild_position_db));
  6975. +			safestrncpy(schema_config.guild_position_db, w2, sizeof(schema_config.guild_position_db));
  6976.  		else if(!strcmpi(w1,"guild_storage_db"))
  6977. -			safestrncpy(guild_storage_db, w2, sizeof(guild_storage_db));
  6978. +			safestrncpy(schema_config.guild_storage_db, w2, sizeof(schema_config.guild_storage_db));
  6979.  		else if(!strcmpi(w1,"party_db"))
  6980. -			safestrncpy(party_db, w2, sizeof(party_db));
  6981. +			safestrncpy(schema_config.party_db, w2, sizeof(schema_config.party_db));
  6982.  		else if(!strcmpi(w1,"pet_db"))
  6983. -			safestrncpy(pet_db, w2, sizeof(pet_db));
  6984. +			safestrncpy(schema_config.pet_db, w2, sizeof(schema_config.pet_db));
  6985.  		else if(!strcmpi(w1,"mail_db"))
  6986. -			safestrncpy(mail_db, w2, sizeof(mail_db));
  6987. +			safestrncpy(schema_config.mail_db, w2, sizeof(schema_config.mail_db));
  6988.  		else if(!strcmpi(w1,"auction_db"))
  6989. -			safestrncpy(auction_db, w2, sizeof(auction_db));
  6990. +			safestrncpy(schema_config.auction_db, w2, sizeof(schema_config.auction_db));
  6991.  		else if(!strcmpi(w1,"friend_db"))
  6992. -			safestrncpy(friend_db, w2, sizeof(friend_db));
  6993. +			safestrncpy(schema_config.friend_db, w2, sizeof(schema_config.friend_db));
  6994.  		else if(!strcmpi(w1,"hotkey_db"))
  6995. -			safestrncpy(hotkey_db, w2, sizeof(hotkey_db));
  6996. +			safestrncpy(schema_config.hotkey_db, w2, sizeof(schema_config.hotkey_db));
  6997.  		else if(!strcmpi(w1,"quest_db"))
  6998. -			safestrncpy(quest_db,w2,sizeof(quest_db));
  6999. +			safestrncpy(schema_config.quest_db,w2,sizeof(schema_config.quest_db));
  7000.  		else if(!strcmpi(w1,"homunculus_db"))
  7001. -			safestrncpy(homunculus_db,w2,sizeof(homunculus_db));
  7002. +			safestrncpy(schema_config.homunculus_db,w2,sizeof(schema_config.homunculus_db));
  7003.  		else if(!strcmpi(w1,"skill_homunculus_db"))
  7004. -			safestrncpy(skill_homunculus_db,w2,sizeof(skill_homunculus_db));
  7005. +			safestrncpy(schema_config.skill_homunculus_db,w2,sizeof(schema_config.skill_homunculus_db));
  7006.  		else if(!strcmpi(w1,"mercenary_db"))
  7007. -			safestrncpy(mercenary_db,w2,sizeof(mercenary_db));
  7008. +			safestrncpy(schema_config.mercenary_db,w2,sizeof(schema_config.mercenary_db));
  7009.  		else if(!strcmpi(w1,"mercenary_owner_db"))
  7010. -			safestrncpy(mercenary_owner_db,w2,sizeof(mercenary_owner_db));
  7011. +			safestrncpy(schema_config.mercenary_owner_db,w2,sizeof(schema_config.mercenary_owner_db));
  7012.  		//support the import command, just like any other config
  7013.  		else if(!strcmpi(w1,"import"))
  7014.  			sql_config_read(w2);
  7015. @@ -4966,6 +2189,93 @@
  7016.  	ShowInfo("Done reading %s.\n", cfgName);
  7017.  }
  7018.  
  7019. +
  7020. +void char_set_default_sql(){
  7021. +//	schema_config.db_use_sqldbs;
  7022. +	safestrncpy(schema_config.db_path,"db",sizeof(schema_config.db_path));
  7023. +	safestrncpy(schema_config.char_db,"char",sizeof(schema_config.char_db));
  7024. +	safestrncpy(schema_config.scdata_db,"sc_data",sizeof(schema_config.scdata_db));
  7025. +	safestrncpy(schema_config.cart_db,"cart_inventory",sizeof(schema_config.cart_db));
  7026. +	safestrncpy(schema_config.inventory_db,"inventory",sizeof(schema_config.inventory_db));
  7027. +	safestrncpy(schema_config.charlog_db,"charlog",sizeof(schema_config.charlog_db));
  7028. +	safestrncpy(schema_config.storage_db,"storage",sizeof(schema_config.storage_db));
  7029. +	safestrncpy(schema_config.interlog_db,"interlog",sizeof(schema_config.interlog_db));
  7030. +	safestrncpy(schema_config.reg_db,"global_reg_value",sizeof(schema_config.reg_db));
  7031. +	safestrncpy(schema_config.skill_db,"skill",sizeof(schema_config.skill_db));
  7032. +	safestrncpy(schema_config.memo_db,"memo",sizeof(schema_config.memo_db));
  7033. +	safestrncpy(schema_config.guild_db,"guild",sizeof(schema_config.guild_db));
  7034. +	safestrncpy(schema_config.guild_alliance_db,"guild_alliance",sizeof(schema_config.guild_alliance_db));
  7035. +	safestrncpy(schema_config.guild_castle_db,"guild_castle",sizeof(schema_config.guild_castle_db));
  7036. +	safestrncpy(schema_config.guild_expulsion_db,"guild_expulsion",sizeof(schema_config.guild_expulsion_db));
  7037. +	safestrncpy(schema_config.guild_member_db,"guild_member",sizeof(schema_config.guild_member_db));
  7038. +	safestrncpy(schema_config.guild_position_db,"guild_position",sizeof(schema_config.guild_position_db));
  7039. +	safestrncpy(schema_config.guild_skill_db,"guild_skill",sizeof(schema_config.guild_skill_db));
  7040. +	safestrncpy(schema_config.guild_storage_db,"guild_storage",sizeof(schema_config.guild_storage_db));
  7041. +	safestrncpy(schema_config.party_db,"party",sizeof(schema_config.party_db));
  7042. +	safestrncpy(schema_config.pet_db,"pet",sizeof(schema_config.pet_db));
  7043. +	safestrncpy(schema_config.mail_db,"mail",sizeof(schema_config.mail_db)); // MAIL SYSTEM
  7044. +	safestrncpy(schema_config.auction_db,"auction",sizeof(schema_config.auction_db)); // Auctions System
  7045. +	safestrncpy(schema_config.friend_db,"friends",sizeof(schema_config.friend_db));
  7046. +	safestrncpy(schema_config.hotkey_db,"hotkey",sizeof(schema_config.hotkey_db));
  7047. +	safestrncpy(schema_config.quest_db,"quest",sizeof(schema_config.quest_db));
  7048. +	safestrncpy(schema_config.homunculus_db,"homunculus",sizeof(schema_config.homunculus_db));
  7049. +	safestrncpy(schema_config.skill_homunculus_db,"skill_homunculus",sizeof(schema_config.skill_homunculus_db));
  7050. +	safestrncpy(schema_config.mercenary_db,"mercenary",sizeof(schema_config.mercenary_db));
  7051. +	safestrncpy(schema_config.mercenary_owner_db,"mercenary_owner",sizeof(schema_config.mercenary_owner_db));
  7052. +	safestrncpy(schema_config.ragsrvinfo_db,"ragsrvinfo",sizeof(schema_config.ragsrvinfo_db));
  7053. +}
  7054. +
  7055. +//set default config
  7056. +void char_set_defaults(){
  7057. +	pincode_config.pincode_enabled = true;
  7058. +	pincode_config.pincode_changetime = 0;
  7059. +	pincode_config.pincode_maxtry = 3;
  7060. +	pincode_config.pincode_force = true;
  7061. +
  7062. +	charmove_config.char_move_enabled = true;
  7063. +	charmove_config.char_movetoused = true;
  7064. +	charmove_config.char_moves_unlimited = false;
  7065. +
  7066. +	char_config.char_per_account = 0; //Maximum chars per account (default unlimited) [Sirius]
  7067. +	char_config.char_del_level = 0; //From which level u can delete character [Lupus]
  7068. +	char_config.char_del_delay = 86400;
  7069. +
  7070. +//	charserv_config.userid[24];
  7071. +//	charserv_config.passwd[24];
  7072. +//	charserv_config.server_name[20];
  7073. +	safestrncpy(charserv_config.wisp_server_name,"Server",sizeof(charserv_config.wisp_server_name));
  7074. +//	charserv_config.login_ip_str[128];
  7075. +	charserv_config.login_ip = 0;
  7076. +	charserv_config.login_port = 6900;
  7077. +//	charserv_config.char_ip_str[128];
  7078. +	charserv_config.char_ip = 0;
  7079. +//	charserv_config.bind_ip_str[128];
  7080. +	charserv_config.bind_ip = INADDR_ANY;
  7081. +	charserv_config.char_port = 6121;
  7082. +	charserv_config.char_maintenance = 0;
  7083. +	charserv_config.char_new = true;
  7084. +	charserv_config.char_new_display = 0;
  7085. +
  7086. +	charserv_config.name_ignoring_case = false; // Allow or not identical name for characters but with a different case by [Yor]
  7087. +	charserv_config.char_name_option = 0; // Option to know which letters/symbols are authorised in the name of a character (0: all, 1: only those in char_name_letters, 2: all EXCEPT those in char_name_letters) by [Yor]
  7088. +	safestrncpy(charserv_config.unknown_char_name,"Unknown",sizeof(charserv_config.unknown_char_name)); // Name to use when the requested name cannot be determined
  7089. +	safestrncpy(charserv_config.char_name_letters,"",sizeof(charserv_config.char_name_letters)); // list of letters/symbols allowed (or not) in a character name. by [Yor]
  7090. +
  7091. +	charserv_config.save_log = 1; // show loading/saving messages
  7092. +	charserv_config.log_char = 1;	// loggin char or not [devil]
  7093. +	charserv_config.log_inter = 1;	// loggin inter or not [devil]
  7094. +
  7095. +	charserv_config.start_point.map = mapindex_name2id("new_zone01"); //mapindex_name2id(MAP_DEFAULT);
  7096. +	charserv_config.start_point.x = 53; //MAP_DEFAULT_X
  7097. +	charserv_config.start_point.y = 111; //MAP_DEFAULT_Y
  7098. +	charserv_config.console = 0;
  7099. +	charserv_config.max_connect_user = -1;
  7100. +	charserv_config.gm_allow_group = -1;
  7101. +	charserv_config.autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
  7102. +	charserv_config.start_zeny = 0;
  7103. +	charserv_config.guild_exp_rate = 100;
  7104. +}
  7105. +
  7106.  int char_config_read(const char* cfgName)
  7107.  {
  7108.  	char line[1024], w1[1024], w2[1024];
  7109. @@ -4994,72 +2304,72 @@
  7110.  		} else if(strcmpi(w1,"stdout_with_ansisequence")==0){
  7111.  			stdout_with_ansisequence = config_switch(w2);
  7112.  		} else if (strcmpi(w1, "userid") == 0) {
  7113. -			safestrncpy(userid, w2, sizeof(userid));
  7114. +			safestrncpy(charserv_config.userid, w2, sizeof(charserv_config.userid));
  7115.  		} else if (strcmpi(w1, "passwd") == 0) {
  7116. -			safestrncpy(passwd, w2, sizeof(passwd));
  7117. +			safestrncpy(charserv_config.passwd, w2, sizeof(charserv_config.passwd));
  7118.  		} else if (strcmpi(w1, "server_name") == 0) {
  7119. -			safestrncpy(server_name, w2, sizeof(server_name));
  7120. +			safestrncpy(charserv_config.server_name, w2, sizeof(charserv_config.server_name));
  7121.  		} else if (strcmpi(w1, "wisp_server_name") == 0) {
  7122.  			if (strlen(w2) >= 4) {
  7123. -				safestrncpy(wisp_server_name, w2, sizeof(wisp_server_name));
  7124. +				safestrncpy(charserv_config.wisp_server_name, w2, sizeof(charserv_config.wisp_server_name));
  7125.  			}
  7126.  		} else if (strcmpi(w1, "login_ip") == 0) {
  7127. -			login_ip = host2ip(w2);
  7128. -			if (login_ip) {
  7129. +			charserv_config.login_ip = host2ip(w2);
  7130. +			if (charserv_config.login_ip) {
  7131.  				char ip_str[16];
  7132. -				safestrncpy(login_ip_str, w2, sizeof(login_ip_str));
  7133. -				ShowStatus("Login server IP address : %s -> %s\n", w2, ip2str(login_ip, ip_str));
  7134. +				safestrncpy(charserv_config.login_ip_str, w2, sizeof(charserv_config.login_ip_str));
  7135. +				ShowStatus("Login server IP address : %s -> %s\n", w2, ip2str(charserv_config.login_ip, ip_str));
  7136.  			}
  7137.  		} else if (strcmpi(w1, "login_port") == 0) {
  7138. -			login_port = atoi(w2);
  7139. +			charserv_config.login_port = atoi(w2);
  7140.  		} else if (strcmpi(w1, "char_ip") == 0) {
  7141. -			char_ip = host2ip(w2);
  7142. -			if (char_ip) {
  7143. +			charserv_config.char_ip = host2ip(w2);
  7144. +			if (charserv_config.char_ip) {
  7145.  				char ip_str[16];
  7146. -				safestrncpy(char_ip_str, w2, sizeof(char_ip_str));
  7147. -				ShowStatus("Character server IP address : %s -> %s\n", w2, ip2str(char_ip, ip_str));
  7148. +				safestrncpy(charserv_config.char_ip_str, w2, sizeof(charserv_config.char_ip_str));
  7149. +				ShowStatus("Character server IP address : %s -> %s\n", w2, ip2str(charserv_config.char_ip, ip_str));
  7150.  			}
  7151.  		} else if (strcmpi(w1, "bind_ip") == 0) {
  7152. -			bind_ip = host2ip(w2);
  7153. -			if (bind_ip) {
  7154. +			charserv_config.bind_ip = host2ip(w2);
  7155. +			if (charserv_config.bind_ip) {
  7156.  				char ip_str[16];
  7157. -				safestrncpy(bind_ip_str, w2, sizeof(bind_ip_str));
  7158. -				ShowStatus("Character server binding IP address : %s -> %s\n", w2, ip2str(bind_ip, ip_str));
  7159. +				safestrncpy(charserv_config.bind_ip_str, w2, sizeof(charserv_config.bind_ip_str));
  7160. +				ShowStatus("Character server binding IP address : %s -> %s\n", w2, ip2str(charserv_config.bind_ip, ip_str));
  7161.  			}
  7162.  		} else if (strcmpi(w1, "char_port") == 0) {
  7163. -			char_port = atoi(w2);
  7164. +			charserv_config.char_port = atoi(w2);
  7165.  		} else if (strcmpi(w1, "char_maintenance") == 0) {
  7166. -			char_maintenance = atoi(w2);
  7167. +			charserv_config.char_maintenance = atoi(w2);
  7168.  		} else if (strcmpi(w1, "char_new") == 0) {
  7169. -			char_new = (bool)atoi(w2);
  7170. +			charserv_config.char_new = (bool)atoi(w2);
  7171.  		} else if (strcmpi(w1, "char_new_display") == 0) {
  7172. -			char_new_display = atoi(w2);
  7173. +			charserv_config.char_new_display = atoi(w2);
  7174.  		} else if (strcmpi(w1, "max_connect_user") == 0) {
  7175. -			max_connect_user = atoi(w2);
  7176. -			if (max_connect_user < -1)
  7177. -				max_connect_user = -1;
  7178. +			charserv_config.max_connect_user = atoi(w2);
  7179. +			if (charserv_config.max_connect_user < -1)
  7180. +				charserv_config.max_connect_user = -1;
  7181.  		} else if(strcmpi(w1, "gm_allow_group") == 0) {
  7182. -			gm_allow_group = atoi(w2);
  7183. +			charserv_config.gm_allow_group = atoi(w2);
  7184.  		} else if (strcmpi(w1, "autosave_time") == 0) {
  7185. -			autosave_interval = atoi(w2)*1000;
  7186. -			if (autosave_interval <= 0)
  7187. -				autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
  7188. +			charserv_config.autosave_interval = atoi(w2)*1000;
  7189. +			if (charserv_config.autosave_interval <= 0)
  7190. +				charserv_config.autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
  7191.  		} else if (strcmpi(w1, "save_log") == 0) {
  7192. -			save_log = config_switch(w2);
  7193. +			charserv_config.save_log = config_switch(w2);
  7194.  		} else if (strcmpi(w1, "start_point") == 0) {
  7195.  			char map[MAP_NAME_LENGTH_EXT];
  7196.  			int x, y;
  7197.  			if (sscanf(w2, "%15[^,],%d,%d", map, &x, &y) < 3)
  7198.  				continue;
  7199. -			start_point.map = mapindex_name2id(map);
  7200. -			if (!start_point.map)
  7201. +			charserv_config.start_point.map = mapindex_name2id(map);
  7202. +			if (!charserv_config.start_point.map)
  7203.  				ShowError("Specified start_point %s not found in map-index cache.\n", map);
  7204. -			start_point.x = x;
  7205. -			start_point.y = y;
  7206. +			charserv_config.start_point.x = x;
  7207. +			charserv_config.start_point.y = y;
  7208.  		} else if (strcmpi(w1, "start_zeny") == 0) {
  7209. -			start_zeny = atoi(w2);
  7210. -			if (start_zeny < 0)
  7211. -				start_zeny = 0;
  7212. +			charserv_config.start_zeny = atoi(w2);
  7213. +			if (charserv_config.start_zeny < 0)
  7214. +				charserv_config.start_zeny = 0;
  7215.  		} else if (strcmpi(w1, "start_items") == 0) {
  7216.  			int i=0, n=0;
  7217.  			char *lineitem, **fields;
  7218. @@ -5086,31 +2396,31 @@
  7219.  			}
  7220.  			aFree(fields);
  7221.  		} else if(strcmpi(w1,"log_char")==0) {		//log char or not [devil]
  7222. -			log_char = atoi(w2);
  7223. +			charserv_config.log_char = atoi(w2);
  7224.  		} else if (strcmpi(w1, "unknown_char_name") == 0) {
  7225. -			safestrncpy(unknown_char_name, w2, sizeof(unknown_char_name));
  7226. -			unknown_char_name[NAME_LENGTH-1] = '\0';
  7227. +			safestrncpy(charserv_config.unknown_char_name, w2, sizeof(charserv_config.unknown_char_name));
  7228. +			charserv_config.unknown_char_name[NAME_LENGTH-1] = '\0';
  7229.  		} else if (strcmpi(w1, "name_ignoring_case") == 0) {
  7230. -			name_ignoring_case = (bool)config_switch(w2);
  7231. +			charserv_config.name_ignoring_case = (bool)config_switch(w2);
  7232.  		} else if (strcmpi(w1, "char_name_option") == 0) {
  7233. -			char_name_option = atoi(w2);
  7234. +			charserv_config.char_name_option = atoi(w2);
  7235.  		} else if (strcmpi(w1, "char_name_letters") == 0) {
  7236. -			safestrncpy(char_name_letters, w2, sizeof(char_name_letters));
  7237. +			safestrncpy(charserv_config.char_name_letters, w2, sizeof(charserv_config.char_name_letters));
  7238.  		} else if (strcmpi(w1, "chars_per_account") == 0) { //maxchars per account [Sirius]
  7239. -			char_per_account = atoi(w2);
  7240. -			if( char_per_account == 0 || char_per_account > MAX_CHARS ) {
  7241. -				if( char_per_account > MAX_CHARS )
  7242. -					ShowWarning("Max chars per account '%d' exceeded limit. Defaulting to '%d'.\n", char_per_account, MAX_CHARS);
  7243. -				char_per_account = MAX_CHARS;
  7244. +			char_config.char_per_account = atoi(w2);
  7245. +			if( char_config.char_per_account == 0 || char_config.char_per_account > MAX_CHARS ) {
  7246. +				if( char_config.char_per_account > MAX_CHARS )
  7247. +					ShowWarning("Max chars per account '%d' exceeded limit. Defaulting to '%d'.\n", char_config.char_per_account, MAX_CHARS);
  7248. +				char_config.char_per_account = MAX_CHARS;
  7249.  			}
  7250.  		} else if (strcmpi(w1, "char_del_level") == 0) { //disable/enable char deletion by its level condition [Lupus]
  7251. -			char_del_level = atoi(w2);
  7252. +			char_config.char_del_level = atoi(w2);
  7253.  		} else if (strcmpi(w1, "char_del_delay") == 0) {
  7254. -			char_del_delay = atoi(w2);
  7255. +			char_config.char_del_delay = atoi(w2);
  7256.  		} else if(strcmpi(w1,"db_path")==0) {
  7257. -			safestrncpy(db_path, w2, sizeof(db_path));
  7258. +			safestrncpy(schema_config.db_path, w2, sizeof(schema_config.db_path));
  7259.  		} else if (strcmpi(w1, "console") == 0) {
  7260. -			console = config_switch(w2);
  7261. +			charserv_config.console = config_switch(w2);
  7262.  		} else if (strcmpi(w1, "fame_list_alchemist") == 0) {
  7263.  			fame_list_size_chemist = atoi(w2);
  7264.  			if (fame_list_size_chemist > MAX_FAME_LIST) {
  7265. @@ -5130,27 +2440,27 @@
  7266.  				fame_list_size_taekwon = MAX_FAME_LIST;
  7267.  			}
  7268.  		} else if (strcmpi(w1, "guild_exp_rate") == 0) {
  7269. -			guild_exp_rate = atoi(w2);
  7270. +			charserv_config.guild_exp_rate = atoi(w2);
  7271.  		} else if (strcmpi(w1, "pincode_enabled") == 0) {
  7272. -			pincode_enabled = config_switch(w2);
  7273. +			pincode_config.pincode_enabled = config_switch(w2);
  7274.  			#if PACKETVER < 20110309
  7275. -			if( pincode_enabled ) {
  7276. +			if( pincode_config.pincode_enabled ) {
  7277.  				ShowWarning("pincode_enabled requires PACKETVER 20110309 or higher. Disabling...\n");
  7278. -				pincode_enabled = false;
  7279. +				pincode_config.pincode_enabled = false;
  7280.  			}
  7281.  			#endif
  7282.  		} else if (strcmpi(w1, "pincode_changetime") == 0) {
  7283. -			pincode_changetime = atoi(w2)*60*60*24;
  7284. +			pincode_config.pincode_changetime = atoi(w2)*60*60*24;
  7285.  		} else if (strcmpi(w1, "pincode_maxtry") == 0) {
  7286. -			pincode_maxtry = atoi(w2);
  7287. +			pincode_config.pincode_maxtry = atoi(w2);
  7288.  		} else if (strcmpi(w1, "pincode_force") == 0) {
  7289. -			pincode_force = config_switch(w2);
  7290. +			pincode_config.pincode_force = config_switch(w2);
  7291.  		} else if (strcmpi(w1, "char_move_enabled") == 0) {
  7292. -			char_move_enabled = config_switch(w2);
  7293. +			charmove_config.char_move_enabled = config_switch(w2);
  7294.  		} else if (strcmpi(w1, "char_movetoused") == 0) {
  7295. -			char_movetoused = config_switch(w2);
  7296. +			charmove_config.char_movetoused = config_switch(w2);
  7297.  		} else if (strcmpi(w1, "char_moves_unlimited") == 0) {
  7298. -			char_moves_unlimited = config_switch(w2);
  7299. +			charmove_config.char_moves_unlimited = config_switch(w2);
  7300.  		} else if (strcmpi(w1, "import") == 0) {
  7301.  			char_config_read(w2);
  7302.  		}
  7303. @@ -5161,6 +2471,21 @@
  7304.  	return 0;
  7305.  }
  7306.  
  7307. +
  7308. +/*
  7309. + * Message conf function
  7310. + */
  7311. +int char_msg_config_read(char *cfgName){
  7312. +	return _msg_config_read(cfgName,CHAR_MAX_MSG,msg_table);
  7313. +}
  7314. +const char* char_msg_txt(int msg_number){
  7315. +	return _msg_txt(msg_number,CHAR_MAX_MSG,msg_table);
  7316. +}
  7317. +void char_do_final_msg(void){
  7318. +	_do_final_msg(CHAR_MAX_MSG,msg_table);
  7319. +}
  7320. +
  7321. +
  7322.  void do_final(void)
  7323.  {
  7324.  	ShowStatus("Terminating...\n");
  7325. @@ -5176,7 +2501,7 @@
  7326.  	do_final_mapif();
  7327.  	do_final_loginif();
  7328.  
  7329. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s`", ragsrvinfo_db) )
  7330. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s`", schema_config.ragsrvinfo_db) )
  7331.  		Sql_ShowDebug(sql_handle);
  7332.  
  7333.  	char_db_->destroy(char_db_, NULL);
  7334. @@ -5195,6 +2520,11 @@
  7335.  	ShowStatus("Finished.\n");
  7336.  }
  7337.  
  7338. +
  7339. +void set_server_type(void){
  7340. +	SERVER_TYPE = ATHENA_SERVER_CHAR;
  7341. +}
  7342. +
  7343.  //------------------------------
  7344.  // Function called when the server
  7345.  // has received a crash signal.
  7346. @@ -5203,12 +2533,6 @@
  7347.  {
  7348.  }
  7349.  
  7350. -void set_server_type(void)
  7351. -{
  7352. -	SERVER_TYPE = ATHENA_SERVER_CHAR;
  7353. -}
  7354. -
  7355. -
  7356.  /// Called when a terminate signal is received.
  7357.  void do_shutdown(void)
  7358.  {
  7359. @@ -5229,23 +2553,29 @@
  7360.  
  7361.  int do_init(int argc, char **argv)
  7362.  {
  7363. +	login_fd=-1;
  7364. +	char_fd=-1;
  7365. +	fame_list_size_chemist = MAX_FAME_LIST;
  7366. +	fame_list_size_smith = MAX_FAME_LIST;
  7367. +	fame_list_size_taekwon = MAX_FAME_LIST;
  7368. +
  7369.  	//Read map indexes
  7370.  	mapindex_init();
  7371. -	start_point.map = mapindex_name2id("new_zone01");
  7372.  
  7373.  	CHAR_CONF_NAME =   "conf/char_athena.conf";
  7374.  	LAN_CONF_NAME =    "conf/subnet_athena.conf";
  7375.  	SQL_CONF_NAME =    "conf/inter_athena.conf";
  7376.  	MSG_CONF_NAME_EN = "conf/msg_conf/char_msg.conf";
  7377.  
  7378. +	char_set_defaults();
  7379.  	cli_get_options(argc,argv);
  7380.  
  7381. -	msg_config_read(MSG_CONF_NAME_EN);
  7382.  	char_config_read(CHAR_CONF_NAME);
  7383.  	char_lan_config_read(LAN_CONF_NAME);
  7384.  	sql_config_read(SQL_CONF_NAME);
  7385. +	msg_config_read(MSG_CONF_NAME_EN);
  7386.  
  7387. -	if (strcmp(userid, "s1")==0 && strcmp(passwd, "p1")==0) {
  7388. +	if (strcmp(charserv_config.userid, "s1")==0 && strcmp(charserv_config.passwd, "p1")==0) {
  7389.  		ShowWarning("Using the default user/password s1/p1 is NOT RECOMMENDED.\n");
  7390.  		ShowNotice("Please edit your 'login' table to create a proper inter-server user/password (gender 'S')\n");
  7391.  		ShowNotice("And then change the user/password to use in conf/char_athena.conf (or conf/import/char_conf.txt)\n");
  7392. @@ -5258,7 +2588,7 @@
  7393.  	mmo_char_sql_init();
  7394.  	char_read_fame_list(); //Read fame lists.
  7395.  
  7396. -	if ((naddr_ != 0) && (!login_ip || !char_ip))
  7397. +	if ((naddr_ != 0) && (!(charserv_config.login_ip) || !(charserv_config.char_ip) ))
  7398.  	{
  7399.  		char ip_str[16];
  7400.  		ip2str(addr_[0], ip_str);
  7401. @@ -5267,13 +2597,13 @@
  7402.  			ShowStatus("Multiple interfaces detected..  using %s as our IP address\n", ip_str);
  7403.  		else
  7404.  			ShowStatus("Defaulting to %s as our IP address\n", ip_str);
  7405. -		if (!login_ip) {
  7406. -			safestrncpy(login_ip_str, ip_str, sizeof(login_ip_str));
  7407. -			login_ip = str2ip(login_ip_str);
  7408. +		if (!(charserv_config.login_ip) ) {
  7409. +			safestrncpy(charserv_config.login_ip_str, ip_str, sizeof(charserv_config.login_ip_str));
  7410. +			charserv_config.login_ip = str2ip(charserv_config.login_ip_str);
  7411.  		}
  7412. -		if (!char_ip) {
  7413. -			safestrncpy(char_ip_str, ip_str, sizeof(char_ip_str));
  7414. -			char_ip = str2ip(char_ip_str);
  7415. +		if (!(charserv_config.char_ip)) {
  7416. +			safestrncpy(charserv_config.char_ip_str, ip_str, sizeof(charserv_config.char_ip_str));
  7417. +			charserv_config.char_ip = str2ip(charserv_config.char_ip_str);
  7418.  		}
  7419.  	}
  7420.  
  7421. @@ -5293,64 +2623,33 @@
  7422.  
  7423.  	//Cleaning the tables for NULL entrys @ startup [Sirius]
  7424.  	//Chardb clean
  7425. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '0'", char_db) )
  7426. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '0'", schema_config.char_db) )
  7427.  		Sql_ShowDebug(sql_handle);
  7428.  
  7429.  	//guilddb clean
  7430. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_lv` = '0' AND `max_member` = '0' AND `exp` = '0' AND `next_exp` = '0' AND `average_lv` = '0'", guild_db) )
  7431. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_lv` = '0' AND `max_member` = '0' AND `exp` = '0' AND `next_exp` = '0' AND `average_lv` = '0'", schema_config.guild_db) )
  7432.  		Sql_ShowDebug(sql_handle);
  7433.  
  7434.  	//guildmemberdb clean
  7435. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '0' AND `account_id` = '0' AND `char_id` = '0'", guild_member_db) )
  7436. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '0' AND `account_id` = '0' AND `char_id` = '0'", schema_config.guild_member_db) )
  7437.  		Sql_ShowDebug(sql_handle);
  7438.  
  7439.  	set_defaultparse(parse_char);
  7440.  
  7441. -	if( (char_fd = make_listen_bind(bind_ip,char_port)) == -1 ) {
  7442. -		ShowFatalError("Failed to bind to port '"CL_WHITE"%d"CL_RESET"'\n",char_port);
  7443. +	if( (char_fd = make_listen_bind(charserv_config.bind_ip,charserv_config.char_port)) == -1 ) {
  7444. +		ShowFatalError("Failed to bind to port '"CL_WHITE"%d"CL_RESET"'\n",charserv_config.char_port);
  7445.  		exit(EXIT_FAILURE);
  7446.  	}
  7447.  
  7448. -	ShowStatus("The char-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %d).\n\n", char_port);
  7449. -
  7450.  	if( runflag != CORE_ST_STOP )
  7451.  	{
  7452.  		shutdown_callback = do_shutdown;
  7453.  		runflag = CHARSERVER_ST_RUNNING;
  7454.  	}
  7455.  
  7456. -	if( console ){ //start listening
  7457. -		add_timer_func_list(parse_console_timer, "parse_console_timer");
  7458. -		add_timer_interval(gettick()+1000, parse_console_timer, 0, 0, 1000); //start in 1s each 1sec
  7459. -	}
  7460. -	return 0;
  7461. -}
  7462. +	do_init_charcnslif();
  7463.  
  7464. -int char_msg_config_read(char *cfgName){
  7465. -	return _msg_config_read(cfgName,CHAR_MAX_MSG,msg_table);
  7466. -}
  7467. -const char* char_msg_txt(int msg_number){
  7468. -	return _msg_txt(msg_number,CHAR_MAX_MSG,msg_table);
  7469. -}
  7470. -void char_do_final_msg(void){
  7471. -	_do_final_msg(CHAR_MAX_MSG,msg_table);
  7472. -}
  7473. +	ShowStatus("The char-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %d).\n\n", charserv_config.char_port);
  7474.  
  7475. -/*======================================================
  7476. - * Login-Server help option info
  7477. - *------------------------------------------------------*/
  7478. -void display_helpscreen(bool do_exit)
  7479. -{
  7480. -	ShowInfo("Usage: %s [options]\n", SERVER_NAME);
  7481. -	ShowInfo("\n");
  7482. -	ShowInfo("Options:\n");
  7483. -	ShowInfo("  -?, -h [--help]\t\tDisplays this help screen.\n");
  7484. -	ShowInfo("  -v [--version]\t\tDisplays the server's version.\n");
  7485. -	ShowInfo("  --run-once\t\t\tCloses server after loading (testing).\n");
  7486. -	ShowInfo("  --char-config <file>\t\tAlternative char-server configuration.\n");
  7487. -	ShowInfo("  --lan-config <file>\t\tAlternative lag configuration.\n");
  7488. -	ShowInfo("  --inter-config <file>\t\tAlternative inter-server configuration.\n");
  7489. -	ShowInfo("  --msg-config <file>\t\tAlternative message configuration.\n");
  7490. -	if( do_exit )
  7491. -		exit(EXIT_SUCCESS);
  7492. +	return 0;
  7493.  }
  7494. Index: src/char/int_storage.c
  7495. ===================================================================
  7496. --- src/char/int_storage.c	(revision 17367)
  7497. +++ src/char/int_storage.c	(working copy)
  7498. @@ -41,7 +41,7 @@
  7499.  	StringBuf_AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`expire_time`,`bound`,`unique_id`");
  7500.  	for( j = 0; j < MAX_SLOTS; ++j )
  7501.  		StringBuf_Printf(&buf, ",`card%d`", j);
  7502. -	StringBuf_Printf(&buf, " FROM `%s` WHERE `account_id`='%d' ORDER BY `nameid`", storage_db, account_id);
  7503. +	StringBuf_Printf(&buf, " FROM `%s` WHERE `account_id`='%d' ORDER BY `nameid`", schema_config.storage_db, account_id);
  7504.  
  7505.  	if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) )
  7506.  		Sql_ShowDebug(sql_handle);
  7507. @@ -99,7 +99,7 @@
  7508.  	StringBuf_AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`bound`,`unique_id`");
  7509.  	for( j = 0; j < MAX_SLOTS; ++j )
  7510.  		StringBuf_Printf(&buf, ",`card%d`", j);
  7511. -	StringBuf_Printf(&buf, " FROM `%s` WHERE `guild_id`='%d' ORDER BY `nameid`", guild_storage_db, guild_id);
  7512. +	StringBuf_Printf(&buf, " FROM `%s` WHERE `guild_id`='%d' ORDER BY `nameid`", schema_config.guild_storage_db, guild_id);
  7513.  
  7514.  	if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) )
  7515.  		Sql_ShowDebug(sql_handle);
  7516. @@ -146,13 +146,13 @@
  7517.  // Delete char storage
  7518.  int inter_storage_delete(int account_id)
  7519.  {
  7520. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id`='%d'", storage_db, account_id) )
  7521. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id`='%d'", schema_config.storage_db, account_id) )
  7522.  		Sql_ShowDebug(sql_handle);
  7523.  	return 0;
  7524.  }
  7525.  int inter_guild_storage_delete(int guild_id)
  7526.  {
  7527. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id`='%d'", guild_storage_db, guild_id) )
  7528. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id`='%d'", schema_config.guild_storage_db, guild_id) )
  7529.  		Sql_ShowDebug(sql_handle);
  7530.  	return 0;
  7531.  }
  7532. @@ -162,7 +162,7 @@
  7533.  
  7534.  int mapif_load_guild_storage(int fd,int account_id,int guild_id, char flag)
  7535.  {
  7536. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id) )
  7537. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", schema_config.guild_db, guild_id) )
  7538.  		Sql_ShowDebug(sql_handle);
  7539.  	else if( Sql_NumRows(sql_handle) > 0 )
  7540.  	{// guild exists
  7541. @@ -222,7 +222,7 @@
  7542.  	}
  7543.  	else
  7544.  	{
  7545. -		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id) )
  7546. +		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", schema_config.guild_db, guild_id) )
  7547.  			Sql_ShowDebug(sql_handle);
  7548.  		else if( Sql_NumRows(sql_handle) > 0 )
  7549.  		{// guild exists
  7550. @@ -266,7 +266,7 @@
  7551.  	StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`");
  7552.  	for( j = 0; j < MAX_SLOTS; ++j )
  7553.  		StringBuf_Printf(&buf, ", `card%d`", j);
  7554. -	StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`='%d'",inventory_db,char_id);
  7555. +	StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`='%d'",schema_config.inventory_db,char_id);
  7556.  
  7557.  	stmt = SqlStmt_Malloc(sql_handle);
  7558.  	if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
  7559. @@ -296,13 +296,13 @@
  7560.  			i++;
  7561.  		}
  7562.  	}
  7563. -	
  7564. +
  7565.  	if(!i) //No items found - No need to continue
  7566.  		return 0;
  7567.  
  7568.  	//First we delete the character's items
  7569.  	StringBuf_Clear(&buf);
  7570. -	StringBuf_Printf(&buf, "DELETE FROM `%s` WHERE",inventory_db);
  7571. +	StringBuf_Printf(&buf, "DELETE FROM `%s` WHERE",schema_config.inventory_db);
  7572.  	for(j=0; j<i; j++) {
  7573.  		if( found )
  7574.  			StringBuf_AppendStr(&buf, " OR");
  7575. @@ -324,11 +324,11 @@
  7576.  	//Now let's update the guild storage with those deleted items
  7577.  	found = false;
  7578.  	StringBuf_Clear(&buf);
  7579. -	StringBuf_Printf(&buf, "INSERT INTO `%s` (`guild_id`, `nameid`, `amount`, `identify`, `refine`, `attribute`, `expire_time`, `bound`", guild_storage_db);
  7580. +	StringBuf_Printf(&buf, "INSERT INTO `%s` (`guild_id`, `nameid`, `amount`, `identify`, `refine`, `attribute`, `expire_time`, `bound`", schema_config.guild_storage_db);
  7581.  	for( j = 0; j < MAX_SLOTS; ++j )
  7582.  		StringBuf_Printf(&buf, ", `card%d`", j);
  7583.  	StringBuf_AppendStr(&buf, ") VALUES ");
  7584. -	
  7585. +
  7586.  	for( j = 0; j < i; ++j ) {
  7587.  		if( found )
  7588.  			StringBuf_AppendStr(&buf, ",");
  7589. Index: src/char/char.h
  7590. ===================================================================
  7591. --- src/char/char.h	(revision 17367)
  7592. +++ src/char/char.h	(working copy)
  7593. @@ -7,27 +7,18 @@
  7594.  #include "../config/core.h"
  7595.  #include "../common/core.h" // CORE_ST_LAST
  7596.  #include "../common/msg_conf.h"
  7597. +#include "../common/mmo.h"
  7598.  
  7599. -enum E_CHARSERVER_ST
  7600. -{
  7601. +
  7602. +int login_fd;
  7603. +int char_fd;
  7604. +
  7605. +enum E_CHARSERVER_ST {
  7606.  	CHARSERVER_ST_RUNNING = CORE_ST_LAST,
  7607.  	CHARSERVER_ST_SHUTDOWN,
  7608.  	CHARSERVER_ST_LAST
  7609.  };
  7610.  
  7611. -struct mmo_charstatus;
  7612. -
  7613. -#define MAX_MAP_SERVERS 30
  7614. -
  7615. -#define DEFAULT_AUTOSAVE_INTERVAL 300*1000
  7616. -
  7617. -#define msg_config_read(cfgName) char_msg_config_read(cfgName)
  7618. -#define msg_txt(msg_number) char_msg_txt(msg_number)
  7619. -#define do_final_msg() char_do_final_msg()
  7620. -int char_msg_config_read(char *cfgName);
  7621. -const char* char_msg_txt(int msg_number);
  7622. -void char_do_final_msg(void);
  7623. -
  7624.  enum {
  7625.  	TABLE_INVENTORY,
  7626.  	TABLE_CART,
  7627. @@ -35,57 +26,225 @@
  7628.  	TABLE_GUILD_STORAGE,
  7629.  };
  7630.  
  7631. +struct Schema_Config {
  7632. +	int db_use_sqldbs;
  7633. +	char db_path[1024];
  7634. +	char char_db[256];
  7635. +	char scdata_db[256];
  7636. +	char cart_db[256];
  7637. +	char inventory_db[256];
  7638. +	char charlog_db[256];
  7639. +	char storage_db[256];
  7640. +	char interlog_db[256];
  7641. +	char reg_db[256];
  7642. +	char skill_db[256];
  7643. +	char memo_db[256];
  7644. +	char guild_db[256];
  7645. +	char guild_alliance_db[256];
  7646. +	char guild_castle_db[256];
  7647. +	char guild_expulsion_db[256];
  7648. +	char guild_member_db[256];
  7649. +	char guild_position_db[256];
  7650. +	char guild_skill_db[256];
  7651. +	char guild_storage_db[256];
  7652. +	char party_db[256];
  7653. +	char pet_db[256];
  7654. +	char mail_db[256]; // MAIL SYSTEM
  7655. +	char auction_db[256]; // Auctions System
  7656. +	char friend_db[256];
  7657. +	char hotkey_db[256];
  7658. +	char quest_db[256];
  7659. +	char homunculus_db[256];
  7660. +	char skill_homunculus_db[256];
  7661. +	char mercenary_db[256];
  7662. +	char mercenary_owner_db[256];
  7663. +	char ragsrvinfo_db[256];
  7664. +} schema_config;
  7665. +
  7666. +// Pincode system
  7667. +enum pincode_state {
  7668. +	PINCODE_OK = 0,
  7669. +	PINCODE_ASK,
  7670. +	PINCODE_NOTSET,
  7671. +	PINCODE_EXPIRED,
  7672. +	PINCODE_NEW,
  7673. +	PINCODE_PASSED,
  7674. +	PINCODE_WRONG,
  7675. +	PINCODE_MAXSTATE
  7676. +};
  7677. +struct Pincode_Config {
  7678. +	bool pincode_enabled;
  7679. +	int pincode_changetime;
  7680. +	int pincode_maxtry;
  7681. +	bool pincode_force;
  7682. +} pincode_config;
  7683. +
  7684. +struct CharMove_Config {
  7685. +	bool char_move_enabled;
  7686. +	bool char_movetoused;
  7687. +	bool char_moves_unlimited;
  7688. +} charmove_config;
  7689. +
  7690. +struct Char_Config {
  7691. +	int char_per_account; //Maximum chars per account (default unlimited) [Sirius]
  7692. +	int char_del_level; //From which level u can delete character [Lupus]
  7693. +	int char_del_delay; //minimum delay before effectly do the deletion
  7694. +} char_config;
  7695. +
  7696. +#define TRIM_CHARS "\255\xA0\032\t\x0A\x0D " //The following characters are trimmed regardless because they cause confusion and problems on the servers. [Skotlex]
  7697. +struct CharServ_Config {
  7698. +	char userid[24];
  7699. +	char passwd[24];
  7700. +	char server_name[20];
  7701. +	char wisp_server_name[NAME_LENGTH];
  7702. +	char login_ip_str[128];
  7703. +	uint32 login_ip;
  7704. +	uint16 login_port;
  7705. +	char char_ip_str[128];
  7706. +	uint32 char_ip;
  7707. +	char bind_ip_str[128];
  7708. +	uint32 bind_ip;
  7709. +	uint16 char_port;
  7710. +	int char_maintenance;
  7711. +	bool char_new;
  7712. +	int char_new_display;
  7713. +
  7714. +	bool name_ignoring_case; // Allow or not identical name for characters but with a different case by [Yor]
  7715. +	int char_name_option; // Option to know which letters/symbols are authorised in the name of a character (0: all, 1: only those in char_name_letters, 2: all EXCEPT those in char_name_letters) by [Yor]
  7716. +	char unknown_char_name[NAME_LENGTH]; // Name to use when the requested name cannot be determined
  7717. +	char char_name_letters[1024]; // list of letters/symbols allowed (or not) in a character name. by [Yor]
  7718. +
  7719. +	int save_log; // show loading/saving messages
  7720. +	int log_char;	// loggin char or not [devil]
  7721. +	int log_inter;	// loggin inter or not [devil]
  7722. +
  7723. +	struct point start_point; // Initial position the player will spawn on server
  7724. +	int console;
  7725. +	int max_connect_user;
  7726. +	int gm_allow_group;
  7727. +	int autosave_interval;
  7728. +	int start_zeny;
  7729. +	int guild_exp_rate;
  7730. +} charserv_config;
  7731. +
  7732. +#define MAX_MAP_SERVERS 30 //how many mapserver a char server can handle
  7733. +struct mmo_map_server {
  7734. +	int fd;
  7735. +	uint32 ip;
  7736. +	uint16 port;
  7737. +	int users;
  7738. +	unsigned short map[MAX_MAP_PER_SERVER];
  7739. +} server[MAX_MAP_SERVERS];
  7740. +
  7741. +#define AUTH_TIMEOUT 30000
  7742. +struct auth_node {
  7743. +	int account_id;
  7744. +	int char_id;
  7745. +	uint32 login_id1;
  7746. +	uint32 login_id2;
  7747. +	uint32 ip;
  7748. +	int sex;
  7749. +	time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
  7750. +	int group_id;
  7751. +	unsigned changing_mapservers : 1;
  7752. +};
  7753. +DBMap* char_get_authdb(); // int account_id -> struct auth_node*
  7754. +
  7755. +struct online_char_data {
  7756. +	int account_id;
  7757. +	int char_id;
  7758. +	int fd;
  7759. +	int waiting_disconnect;
  7760. +	short server; // -2: unknown server, -1: not connected, 0+: id of server
  7761. +	bool pincode_success;
  7762. +	int version;
  7763. +};
  7764. +DBMap* char_get_onlinedb(); // int account_id -> struct online_char_data*
  7765. +
  7766. +struct char_session_data {
  7767. +	bool auth; // whether the session is authed or not
  7768. +	int account_id, login_id1, login_id2, sex;
  7769. +	int found_char[MAX_CHARS]; // ids of chars on this account
  7770. +	char email[40]; // e-mail (default: [email protected]) by [Yor]
  7771. +	time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
  7772. +	int group_id; // permission
  7773. +	uint8 char_slots;
  7774. +	uint32 version;
  7775. +	uint8 clienttype;
  7776. +	char new_name[NAME_LENGTH];
  7777. +	char birthdate[10+1];  // YYYY-MM-DD
  7778. +	// Pincode system
  7779. +	char pincode[PINCODE_LENGTH+1];
  7780. +	uint32 pincode_seed;
  7781. +	time_t pincode_change;
  7782. +	uint16 pincode_try;
  7783. +	// Addon system
  7784. +	unsigned int char_moves[MAX_CHARS]; // character moves left
  7785. +};
  7786. +
  7787. +struct mmo_charstatus;
  7788. +DBMap* char_get_chardb(); // int char_id -> struct mmo_charstatus*
  7789. +
  7790. +//Custom limits for the fame lists. [Skotlex]
  7791. +int fame_list_size_chemist;
  7792. +int fame_list_size_smith;
  7793. +int fame_list_size_taekwon;
  7794. +// Char-server-side stored fame lists [DracoRPG]
  7795. +struct fame_list smith_fame_list[MAX_FAME_LIST];
  7796. +struct fame_list chemist_fame_list[MAX_FAME_LIST];
  7797. +struct fame_list taekwon_fame_list[MAX_FAME_LIST];
  7798. +
  7799. +#define DEFAULT_AUTOSAVE_INTERVAL 300*1000
  7800. +#define MAX_CHAR_BUF 144 //Max size (for WFIFOHEAD calls)
  7801. +
  7802. +int search_mapserver(unsigned short map, uint32 ip, uint16 port);
  7803. +int lan_subnetcheck(uint32 ip);
  7804. +
  7805. +int count_users(void);
  7806. +DBData create_online_char_data(DBKey key, va_list args);
  7807. +int char_db_setoffline(DBKey key, DBData *data, va_list ap);
  7808. +void set_char_online(int map_id, int char_id, int account_id);
  7809. +void set_char_offline(int char_id, int account_id);
  7810. +void set_all_offline(int id);
  7811. +void disconnect_player(int account_id);
  7812. +int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data);
  7813. +
  7814. +int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p);
  7815. +int mmo_char_tosql(int char_id, struct mmo_charstatus* p);
  7816. +int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything);
  7817. +int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf);
  7818. +int delete_char_sql(int char_id);
  7819. +int rename_char_sql(struct char_session_data *sd, int char_id);
  7820. +int divorce_char_sql(int partner_id1, int partner_id2);
  7821.  int memitemdata_to_sql(const struct item items[], int max, int id, int tableswitch);
  7822.  
  7823. -int mapif_sendall(unsigned char *buf,unsigned int len);
  7824. -int mapif_sendallwos(int fd,unsigned char *buf,unsigned int len);
  7825. -int mapif_send(int fd,unsigned char *buf,unsigned int len);
  7826. -
  7827.  int char_married(int pl1,int pl2);
  7828.  int char_child(int parent_id, int child_id);
  7829.  int char_family(int pl1,int pl2,int pl3);
  7830.  
  7831. -int request_accreg2(int account_id, int char_id);
  7832. -int save_accreg2(unsigned char* buf, int len);
  7833. +int char_loadName(int char_id, char* name);
  7834. +int check_char_name(char * name, char * esc_name);
  7835.  
  7836. -extern int char_name_option;
  7837. -extern char char_name_letters[];
  7838. -extern bool char_gm_read;
  7839. -extern int autosave_interval;
  7840. -extern int save_log;
  7841. -extern char db_path[];
  7842. -extern char char_db[256];
  7843. -extern char scdata_db[256];
  7844. -extern char cart_db[256];
  7845. -extern char inventory_db[256];
  7846. -extern char charlog_db[256];
  7847. -extern char storage_db[256];
  7848. -extern char interlog_db[256];
  7849. -extern char reg_db[256];
  7850. -extern char skill_db[256];
  7851. -extern char memo_db[256];
  7852. -extern char guild_db[256];
  7853. -extern char guild_alliance_db[256];
  7854. -extern char guild_castle_db[256];
  7855. -extern char guild_expulsion_db[256];
  7856. -extern char guild_member_db[256];
  7857. -extern char guild_position_db[256];
  7858. -extern char guild_skill_db[256];
  7859. -extern char guild_storage_db[256];
  7860. -extern char party_db[256];
  7861. -extern char pet_db[256];
  7862. -extern char mail_db[256];
  7863. -extern char auction_db[256];
  7864. -extern char quest_db[256];
  7865. -extern char homunculus_db[256];
  7866. -extern char skill_homunculus_db[256];
  7867. -extern char mercenary_db[256];
  7868. -extern char mercenary_owner_db[256];
  7869. -extern char ragsrvinfo_db[256];
  7870. +void pincode_decrypt( uint32 userSeed, char* pin );
  7871. +int pincode_compare( int fd, struct char_session_data* sd, char* pin );
  7872. +void char_auth_ok(int fd, struct char_session_data *sd);
  7873. +void set_char_charselect(int account_id);
  7874. +void char_read_fame_list(void);
  7875.  
  7876. -extern int db_use_sqldbs; // added for sql item_db read for char server [Valaris]
  7877. +#if PACKETVER >= 20120307
  7878. +int make_new_char_sql(struct char_session_data* sd, char* name_, int slot, int hair_color, int hair_style);
  7879. +#else
  7880. +int make_new_char_sql(struct char_session_data* sd, char* name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style);
  7881. +#endif
  7882.  
  7883. -extern int guild_exp_rate;
  7884. -extern int log_inter;
  7885. +//For use in packets that depend on an sd being present [Skotlex]
  7886. +#define FIFOSD_CHECK(rest) { if(RFIFOREST(fd) < rest) return 0; if (sd==NULL || !sd->auth) { RFIFOSKIP(fd,rest); return 0; } }
  7887.  
  7888. +#define msg_config_read(cfgName) char_msg_config_read(cfgName)
  7889. +#define msg_txt(msg_number) char_msg_txt(msg_number)
  7890. +#define do_final_msg() char_do_final_msg()
  7891. +int char_msg_config_read(char *cfgName);
  7892. +const char* char_msg_txt(int msg_number);
  7893. +void char_do_final_msg(void);
  7894. +
  7895.  #endif /* _CHAR_SQL_H_ */
  7896. Index: src/char/int_mail.c
  7897. ===================================================================
  7898. --- src/char/int_mail.c	(revision 17367)
  7899. +++ src/char/int_mail.c	(working copy)
  7900. @@ -9,6 +9,7 @@
  7901.  #include "../common/sql.h"
  7902.  #include "../common/timer.h"
  7903.  #include "char.h"
  7904. +#include "char_mapif.h"
  7905.  #include "inter.h"
  7906.  
  7907.  #include <stdio.h>
  7908. @@ -35,7 +36,7 @@
  7909.  
  7910.  	// I keep the `status` < 3 just in case someone forget to apply the sqlfix
  7911.  	StringBuf_Printf(&buf, " FROM `%s` WHERE `dest_id`='%d' AND `status` < 3 ORDER BY `id` LIMIT %d",
  7912. -		mail_db, char_id, MAIL_MAX_INBOX + 1);
  7913. +		schema_config.mail_db, char_id, MAIL_MAX_INBOX + 1);
  7914.  
  7915.  	if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) )
  7916.  		Sql_ShowDebug(sql_handle);
  7917. @@ -84,7 +85,7 @@
  7918.  		msg = &md->msg[i];
  7919.  		if( msg->status == MAIL_NEW )
  7920.  		{
  7921. -			if ( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `status` = '%d' WHERE `id` = '%d'", mail_db, MAIL_UNREAD, msg->id) )
  7922. +			if ( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `status` = '%d' WHERE `id` = '%d'", schema_config.mail_db, MAIL_UNREAD, msg->id) )
  7923.  				Sql_ShowDebug(sql_handle);
  7924.  
  7925.  			msg->status = MAIL_UNREAD;
  7926. @@ -108,7 +109,7 @@
  7927.  
  7928.  	// build message save query
  7929.  	StringBuf_Init(&buf);
  7930. -	StringBuf_Printf(&buf, "INSERT INTO `%s` (`send_name`, `send_id`, `dest_name`, `dest_id`, `title`, `message`, `time`, `status`, `zeny`, `amount`, `nameid`, `refine`, `attribute`, `identify`, `unique_id`", mail_db);
  7931. +	StringBuf_Printf(&buf, "INSERT INTO `%s` (`send_name`, `send_id`, `dest_name`, `dest_id`, `title`, `message`, `time`, `status`, `zeny`, `amount`, `nameid`, `refine`, `attribute`, `identify`, `unique_id`", schema_config.mail_db);
  7932.  	for (j = 0; j < MAX_SLOTS; j++)
  7933.  		StringBuf_Printf(&buf, ", `card%d`", j);
  7934.  	StringBuf_Printf(&buf, ") VALUES (?, '%d', ?, '%d', ?, ?, '%lu', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%"PRIu64"'",
  7935. @@ -116,7 +117,7 @@
  7936.  	for (j = 0; j < MAX_SLOTS; j++)
  7937.  		StringBuf_Printf(&buf, ", '%d'", msg->item.card[j]);
  7938.  	StringBuf_AppendStr(&buf, ")");
  7939. -	
  7940. +
  7941.  	//Unique Non Stackable Item ID
  7942.  	updateLastUid(msg->item.unique_id);
  7943.  	dbUpdateUid(sql_handle);
  7944. @@ -153,7 +154,7 @@
  7945.  		"`zeny`,`amount`,`nameid`,`refine`,`attribute`,`identify`,`unique_id`");
  7946.  	for( j = 0; j < MAX_SLOTS; j++ )
  7947.  		StringBuf_Printf(&buf, ",`card%d`", j);
  7948. -	StringBuf_Printf(&buf, " FROM `%s` WHERE `id` = '%d'", mail_db, mail_id);
  7949. +	StringBuf_Printf(&buf, " FROM `%s` WHERE `id` = '%d'", schema_config.mail_db, mail_id);
  7950.  
  7951.  	if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf))
  7952.  	||  SQL_SUCCESS != Sql_NextRow(sql_handle) )
  7953. @@ -228,7 +229,7 @@
  7954.  static void mapif_parse_Mail_read(int fd)
  7955.  {
  7956.  	int mail_id = RFIFOL(fd,2);
  7957. -	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `status` = '%d' WHERE `id` = '%d'", mail_db, MAIL_READ, mail_id) )
  7958. +	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `status` = '%d' WHERE `id` = '%d'", schema_config.mail_db, MAIL_READ, mail_id) )
  7959.  		Sql_ShowDebug(sql_handle);
  7960.  }
  7961.  
  7962. @@ -241,7 +242,7 @@
  7963.  	int i;
  7964.  
  7965.  	StringBuf_Init(&buf);
  7966. -	StringBuf_Printf(&buf, "UPDATE `%s` SET `zeny` = '0', `nameid` = '0', `amount` = '0', `refine` = '0', `attribute` = '0', `identify` = '0'", mail_db);
  7967. +	StringBuf_Printf(&buf, "UPDATE `%s` SET `zeny` = '0', `nameid` = '0', `amount` = '0', `refine` = '0', `attribute` = '0', `identify` = '0'", schema_config.mail_db);
  7968.  	for (i = 0; i < MAX_SLOTS; i++)
  7969.  		StringBuf_Printf(&buf, ", `card%d` = '0'", i);
  7970.  	StringBuf_Printf(&buf, " WHERE `id` = '%d'", mail_id);
  7971. @@ -297,7 +298,7 @@
  7972.  static void mapif_Mail_delete(int fd, int char_id, int mail_id)
  7973.  {
  7974.  	bool failed = false;
  7975. -	if ( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", mail_db, mail_id) )
  7976. +	if ( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", schema_config.mail_db, mail_id) )
  7977.  	{
  7978.  		Sql_ShowDebug(sql_handle);
  7979.  		failed = true;
  7980. @@ -322,7 +323,7 @@
  7981.  void mapif_Mail_new(struct mail_message *msg)
  7982.  {
  7983.  	unsigned char buf[74];
  7984. -	
  7985. +
  7986.  	if( !msg || !msg->id )
  7987.  		return;
  7988.  
  7989. @@ -346,7 +347,7 @@
  7990.  	{
  7991.  		if( msg.dest_id != char_id)
  7992.  			return;
  7993. -		else if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", mail_db, mail_id) )
  7994. +		else if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", schema_config.mail_db, mail_id) )
  7995.  			Sql_ShowDebug(sql_handle);
  7996.  		else
  7997.  		{
  7998. @@ -389,7 +390,7 @@
  7999.  static void mapif_Mail_send(int fd, struct mail_message* msg)
  8000.  {
  8001.  	int len = sizeof(struct mail_message) + 4;
  8002. -	
  8003. +
  8004.  	WFIFOHEAD(fd,len);
  8005.  	WFIFOW(fd,0) = 0x384d;
  8006.  	WFIFOW(fd,2) = len;
  8007. @@ -411,7 +412,7 @@
  8008.  
  8009.  	// Try to find the Dest Char by Name
  8010.  	Sql_EscapeStringLen(sql_handle, esc_name, msg.dest_name, strnlen(msg.dest_name, NAME_LENGTH));
  8011. -	if ( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`, `char_id` FROM `%s` WHERE `name` = '%s'", char_db, esc_name) )
  8012. +	if ( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`, `char_id` FROM `%s` WHERE `name` = '%s'", schema_config.char_db, esc_name) )
  8013.  		Sql_ShowDebug(sql_handle);
  8014.  	else
  8015.  	if ( SQL_SUCCESS == Sql_NextRow(sql_handle) )
  8016. Index: src/char/int_homun.c
  8017. ===================================================================
  8018. --- src/char/int_homun.c	(revision 17367)
  8019. +++ src/char/int_homun.c	(working copy)
  8020. @@ -95,7 +95,7 @@
  8021.  		if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
  8022.  			"(`char_id`, `class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`, `rename_flag`, `vaporize`) "
  8023.  			"VALUES ('%d', '%d', '%d', '%s', '%d', '%u', '%u', '%d', '%d', %d, '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
  8024. -			homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
  8025. +			schema_config.homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
  8026.  			hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize) )
  8027.  		{
  8028.  			Sql_ShowDebug(sql_handle);
  8029. @@ -109,7 +109,7 @@
  8030.  	else
  8031.  	{
  8032.  		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `char_id`='%d', `class`='%d',`prev_class`='%d',`name`='%s',`level`='%d',`exp`='%u',`intimacy`='%u',`hunger`='%d', `str`='%d', `agi`='%d', `vit`='%d', `int`='%d', `dex`='%d', `luk`='%d', `hp`='%d',`max_hp`='%d',`sp`='%d',`max_sp`='%d',`skill_point`='%d', `rename_flag`='%d', `vaporize`='%d' WHERE `homun_id`='%d'",
  8033. -			homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
  8034. +			schema_config.homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
  8035.  			hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize, hd->hom_id) )
  8036.  		{
  8037.  			Sql_ShowDebug(sql_handle);
  8038. @@ -121,7 +121,7 @@
  8039.  			int i;
  8040.  
  8041.  			stmt = SqlStmt_Malloc(sql_handle);
  8042. -			if( SQL_ERROR == SqlStmt_Prepare(stmt, "REPLACE INTO `%s` (`homun_id`, `id`, `lv`) VALUES (%d, ?, ?)", skill_homunculus_db, hd->hom_id) )
  8043. +			if( SQL_ERROR == SqlStmt_Prepare(stmt, "REPLACE INTO `%s` (`homun_id`, `id`, `lv`) VALUES (%d, ?, ?)", schema_config.skill_homunculus_db, hd->hom_id) )
  8044.  				SqlStmt_ShowDebug(stmt);
  8045.  			for( i = 0; i < MAX_HOMUNSKILL; ++i )
  8046.  			{
  8047. @@ -156,7 +156,8 @@
  8048.  
  8049.  	memset(hd, 0, sizeof(*hd));
  8050.  
  8051. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `homun_id`,`char_id`,`class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`rename_flag`, `vaporize` FROM `%s` WHERE `homun_id`='%u'", homunculus_db, homun_id) )
  8052. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `homun_id`,`char_id`,`class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`rename_flag`, `vaporize` FROM `%s` WHERE `homun_id`='%u'",
  8053. +		schema_config.homunculus_db, homun_id) )
  8054.  	{
  8055.  		Sql_ShowDebug(sql_handle);
  8056.  		return false;
  8057. @@ -202,7 +203,7 @@
  8058.  	hd->hunger = cap_value(hd->hunger, 0, 100);
  8059.  
  8060.  	// Load Homunculus Skill
  8061. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `id`,`lv` FROM `%s` WHERE `homun_id`=%d", skill_homunculus_db, homun_id) )
  8062. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `id`,`lv` FROM `%s` WHERE `homun_id`=%d", schema_config.skill_homunculus_db, homun_id) )
  8063.  	{
  8064.  		Sql_ShowDebug(sql_handle);
  8065.  		return false;
  8066. @@ -223,7 +224,7 @@
  8067.  	}
  8068.  	Sql_FreeResult(sql_handle);
  8069.  
  8070. -	if( save_log )
  8071. +	if( charserv_config.save_log )
  8072.  		ShowInfo("Homunculus loaded (%d - %s).\n", hd->hom_id, hd->name);
  8073.  
  8074.  	return true;
  8075. @@ -231,8 +232,8 @@
  8076.  
  8077.  bool mapif_homunculus_delete(int homun_id)
  8078.  {
  8079. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%u'", homunculus_db, homun_id)
  8080. -	||	SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%u'", skill_homunculus_db, homun_id)
  8081. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%u'", schema_config.homunculus_db, homun_id)
  8082. +	||	SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%u'", schema_config.skill_homunculus_db, homun_id)
  8083.  	) {
  8084.  		Sql_ShowDebug(sql_handle);
  8085.  		return false;
  8086. @@ -245,16 +246,16 @@
  8087.  	int i;
  8088.  
  8089.  	// Check Authorised letters/symbols in the name of the homun
  8090. -	if( char_name_option == 1 )
  8091. +	if( charserv_config.char_name_option == 1 )
  8092.  	{// only letters/symbols in char_name_letters are authorised
  8093.  		for( i = 0; i < NAME_LENGTH && name[i]; i++ )
  8094. -			if( strchr(char_name_letters, name[i]) == NULL )
  8095. +			if( strchr(charserv_config.char_name_letters, name[i]) == NULL )
  8096.  				return false;
  8097.  	} else
  8098. -	if( char_name_option == 2 )
  8099. +	if( charserv_config.char_name_option == 2 )
  8100.  	{// letters/symbols in char_name_letters are forbidden
  8101.  		for( i = 0; i < NAME_LENGTH && name[i]; i++ )
  8102. -			if( strchr(char_name_letters, name[i]) != NULL )
  8103. +			if( strchr(charserv_config.char_name_letters, name[i]) != NULL )
  8104.  				return false;
  8105.  	}
  8106.  
  8107. Index: src/char/Makefile.in
  8108. ===================================================================
  8109. --- src/char/Makefile.in	(revision 17367)
  8110. +++ src/char/Makefile.in	(working copy)
  8111. @@ -15,12 +15,14 @@
  8112.  COMMON_SQL_OBJ = ../common/obj_sql/sql.o
  8113.  COMMON_H = ../common/sql.h
  8114.  
  8115. -CHAR_OBJ = obj_sql/char.o obj_sql/inter.o obj_sql/int_party.o obj_sql/int_guild.o \
  8116. -	obj_sql/int_storage.o obj_sql/int_pet.o obj_sql/int_homun.o obj_sql/int_mail.o obj_sql/int_auction.o obj_sql/int_quest.o obj_sql/int_mercenary.o obj_sql/int_elemental.o
  8117. -CHAR_H = char.h inter.h int_party.h int_guild.h int_storage.h int_pet.h int_homun.h int_mail.h int_auction.h int_quest.h int_mercenary.h int_elemental.h
  8118. +CHAR_OBJ = char.o char_clif.o char_logif.o char_mapif.o char_cnslif.o\
  8119. +	inter.o int_party.o int_guild.o int_storage.o int_pet.o int_homun.o int_mail.o int_auction.o int_quest.o int_mercenary.o int_elemental.o
  8120. +CHAR_H = char.h \
  8121. +	inter.h int_party.h int_guild.h int_storage.h int_pet.h int_homun.h int_mail.h int_auction.h int_quest.h int_mercenary.h int_elemental.h
  8122. +CHAR_SQL_OBJ = $(CHAR_OBJ:%=obj_sql/%)
  8123.  
  8124.  HAVE_MYSQL=@HAVE_MYSQL@
  8125. -ifeq ($(HAVE_MYSQL),yes)	
  8126. +ifeq ($(HAVE_MYSQL),yes)
  8127.  	SQL_DEPENDS=char-server_sql
  8128.  else
  8129.  	SQL_DEPENDS=needs_mysql
  8130. @@ -49,9 +51,9 @@
  8131.  
  8132.  #####################################################################
  8133.  
  8134. -char-server_sql: obj_sql $(CHAR_OBJ) ../common/obj_sql/common_sql.a ../common/obj_all/common.a $(MT19937AR_OBJ)
  8135. +char-server_sql: obj_sql $(CHAR_SQL_OBJ) ../common/obj_sql/common_sql.a ../common/obj_all/common.a $(MT19937AR_OBJ)
  8136.  	@echo "	LD	$@"
  8137. -	@@CC@ @LDFLAGS@ -o ../../char-server_sql@EXEEXT@ $(CHAR_OBJ) ../common/obj_sql/common_sql.a ../common/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @MYSQL_LIBS@
  8138. +	@@CC@ @LDFLAGS@ -o ../../char-server_sql@EXEEXT@ $(CHAR_SQL_OBJ) ../common/obj_sql/common_sql.a ../common/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @MYSQL_LIBS@
  8139.  
  8140.  needs_mysql:
  8141.  	@echo "MySQL not found or disabled by the configure script"
  8142. Index: src/char/int_pet.c
  8143. ===================================================================
  8144. --- src/char/int_pet.c	(revision 17367)
  8145. +++ src/char/int_pet.c	(working copy)
  8146. @@ -32,7 +32,7 @@
  8147.  		if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
  8148.  			"(`class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`) "
  8149.  			"VALUES ('%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
  8150. -			pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
  8151. +			schema_config.pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
  8152.  			p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate) )
  8153.  		{
  8154.  			Sql_ShowDebug(sql_handle);
  8155. @@ -43,7 +43,7 @@
  8156.  	else
  8157.  	{// Update pet.
  8158.  		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d',`name`='%s',`account_id`='%d',`char_id`='%d',`level`='%d',`egg_id`='%d',`equip`='%d',`intimate`='%d',`hungry`='%d',`rename_flag`='%d',`incuvate`='%d' WHERE `pet_id`='%d'",
  8159. -			pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
  8160. +			schema_config.pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
  8161.  			p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate, p->pet_id) )
  8162.  		{
  8163.  			Sql_ShowDebug(sql_handle);
  8164. @@ -51,7 +51,7 @@
  8165.  		}
  8166.  	}
  8167.  
  8168. -	if (save_log)
  8169. +	if (charserv_config.save_log)
  8170.  		ShowInfo("Pet saved %d - %s.\n", pet_id, p->name);
  8171.  	return 1;
  8172.  }
  8173. @@ -68,7 +68,7 @@
  8174.  
  8175.  	//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`)
  8176.  
  8177. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate` FROM `%s` WHERE `pet_id`='%d'", pet_db, pet_id) )
  8178. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate` FROM `%s` WHERE `pet_id`='%d'", schema_config.pet_db, pet_id) )
  8179.  	{
  8180.  		Sql_ShowDebug(sql_handle);
  8181.  		return 0;
  8182. @@ -94,7 +94,7 @@
  8183.  		p->hungry = cap_value(p->hungry, 0, 100);
  8184.  		p->intimate = cap_value(p->intimate, 0, 1000);
  8185.  
  8186. -		if( save_log )
  8187. +		if( charserv_config.save_log )
  8188.  			ShowInfo("Pet loaded (%d - %s).\n", pet_id, p->name);
  8189.  	}
  8190.  	return 0;
  8191. @@ -114,7 +114,7 @@
  8192.  int inter_pet_delete(int pet_id){
  8193.  	ShowInfo("delete pet request: %d...\n",pet_id);
  8194.  
  8195. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `pet_id`='%d'", pet_db, pet_id) )
  8196. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `pet_id`='%d'", schema_config.pet_db, pet_id) )
  8197.  		Sql_ShowDebug(sql_handle);
  8198.  	return 0;
  8199.  }
  8200. Index: src/char/int_quest.c
  8201. ===================================================================
  8202. --- src/char/int_quest.c	(revision 17367)
  8203. +++ src/char/int_quest.c	(working copy)
  8204. @@ -34,7 +34,7 @@
  8205.  
  8206.  	memset(&tmp_quest, 0, sizeof(struct quest));
  8207.  
  8208. -	if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `quest_id`, `state`, `time`, `count1`, `count2`, `count3` FROM `%s` WHERE `char_id`=? LIMIT %d", quest_db, MAX_QUEST_DB)
  8209. +	if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `quest_id`, `state`, `time`, `count1`, `count2`, `count3` FROM `%s` WHERE `char_id`=? LIMIT %d", schema_config.quest_db, MAX_QUEST_DB)
  8210.  	||	SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
  8211.  	||	SQL_ERROR == SqlStmt_Execute(stmt)
  8212.  	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT,    &tmp_quest.quest_id, 0, NULL, NULL)
  8213. @@ -55,7 +55,7 @@
  8214.  //Delete a quest
  8215.  bool mapif_quest_delete(int char_id, int quest_id)
  8216.  {
  8217. -	if ( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `quest_id` = '%d' AND `char_id` = '%d'", quest_db, quest_id, char_id) )
  8218. +	if ( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `quest_id` = '%d' AND `char_id` = '%d'", schema_config.quest_db, quest_id, char_id) )
  8219.  	{
  8220.  		Sql_ShowDebug(sql_handle);
  8221.  		return false;
  8222. @@ -67,7 +67,7 @@
  8223.  //Add a quest to a questlog
  8224.  bool mapif_quest_add(int char_id, struct quest qd)
  8225.  {
  8226. -	if ( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s`(`quest_id`, `char_id`, `state`, `time`, `count1`, `count2`, `count3`) VALUES ('%d', '%d', '%d','%d', '%d', '%d', '%d')", quest_db, qd.quest_id, char_id, qd.state, qd.time, qd.count[0], qd.count[1], qd.count[2]) ) 
  8227. +	if ( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s`(`quest_id`, `char_id`, `state`, `time`, `count1`, `count2`, `count3`) VALUES ('%d', '%d', '%d','%d', '%d', '%d', '%d')", schema_config.quest_db, qd.quest_id, char_id, qd.state, qd.time, qd.count[0], qd.count[1], qd.count[2]) )
  8228.  	{
  8229.  		Sql_ShowDebug(sql_handle);
  8230.  		return false;
  8231. @@ -79,7 +79,7 @@
  8232.  //Update a questlog
  8233.  bool mapif_quest_update(int char_id, struct quest qd)
  8234.  {
  8235. -	if ( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `state`='%d', `count1`='%d', `count2`='%d', `count3`='%d' WHERE `quest_id` = '%d' AND `char_id` = '%d'", quest_db, qd.state, qd.count[0], qd.count[1], qd.count[2], qd.quest_id, char_id) ) 
  8236. +	if ( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `state`='%d', `count1`='%d', `count2`='%d', `count3`='%d' WHERE `quest_id` = '%d' AND `char_id` = '%d'", schema_config.quest_db, qd.state, qd.count[0], qd.count[1], qd.count[2], qd.quest_id, char_id) )
  8237.  	{
  8238.  		Sql_ShowDebug(sql_handle);
  8239.  		return false;
  8240. Index: src/char/int_auction.c
  8241. ===================================================================
  8242. --- src/char/int_auction.c	(revision 17367)
  8243. +++ src/char/int_auction.c	(working copy)
  8244. @@ -10,6 +10,7 @@
  8245.  #include "../common/sql.h"
  8246.  #include "../common/timer.h"
  8247.  #include "char.h"
  8248. +#include "char_mapif.h"
  8249.  #include "inter.h"
  8250.  #include "int_mail.h"
  8251.  #include "int_auction.h"
  8252. @@ -50,7 +51,7 @@
  8253.  
  8254.  	StringBuf_Init(&buf);
  8255.  	StringBuf_Printf(&buf, "UPDATE `%s` SET `seller_id` = '%d', `seller_name` = ?, `buyer_id` = '%d', `buyer_name` = ?, `price` = '%d', `buynow` = '%d', `hours` = '%d', `timestamp` = '%lu', `nameid` = '%d', `item_name` = ?, `type` = '%d', `refine` = '%d', `attribute` = '%d'",
  8256. -		auction_db, auction->seller_id, auction->buyer_id, auction->price, auction->buynow, auction->hours, (unsigned long)auction->timestamp, auction->item.nameid, auction->type, auction->item.refine, auction->item.attribute);
  8257. +		schema_config.auction_db, auction->seller_id, auction->buyer_id, auction->price, auction->buynow, auction->hours, (unsigned long)auction->timestamp, auction->item.nameid, auction->type, auction->item.refine, auction->item.attribute);
  8258.  	for( j = 0; j < MAX_SLOTS; j++ )
  8259.  		StringBuf_Printf(&buf, ", `card%d` = '%d'", j, auction->item.card[j]);
  8260.  	StringBuf_Printf(&buf, " WHERE `auction_id` = '%d'", auction->auction_id);
  8261. @@ -81,7 +82,7 @@
  8262.  	auction->timestamp = time(NULL) + (auction->hours * 3600);
  8263.  
  8264.  	StringBuf_Init(&buf);
  8265. -	StringBuf_Printf(&buf, "INSERT INTO `%s` (`seller_id`,`seller_name`,`buyer_id`,`buyer_name`,`price`,`buynow`,`hours`,`timestamp`,`nameid`,`item_name`,`type`,`refine`,`attribute`,`unique_id`", auction_db);
  8266. +	StringBuf_Printf(&buf, "INSERT INTO `%s` (`seller_id`,`seller_name`,`buyer_id`,`buyer_name`,`price`,`buynow`,`hours`,`timestamp`,`nameid`,`item_name`,`type`,`refine`,`attribute`,`unique_id`", schema_config.auction_db);
  8267.  	for( j = 0; j < MAX_SLOTS; j++ )
  8268.  		StringBuf_Printf(&buf, ",`card%d`", j);
  8269.  	StringBuf_Printf(&buf, ") VALUES ('%d',?,'%d',?,'%d','%d','%d','%lu','%d',?,'%d','%d','%d','%"PRIu64"'",
  8270. @@ -165,7 +166,7 @@
  8271.  {
  8272.  	unsigned int auction_id = auction->auction_id;
  8273.  
  8274. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `auction_id` = '%d'", auction_db, auction_id) )
  8275. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `auction_id` = '%d'", schema_config.auction_db, auction_id) )
  8276.  		Sql_ShowDebug(sql_handle);
  8277.  
  8278.  	if( auction->auction_end_timer != INVALID_TIMER )
  8279. @@ -189,7 +190,7 @@
  8280.  		"`price`,`buynow`,`hours`,`timestamp`,`nameid`,`item_name`,`type`,`refine`,`attribute`,`unique_id`");
  8281.  	for( i = 0; i < MAX_SLOTS; i++ )
  8282.  		StringBuf_Printf(&buf, ",`card%d`", i);
  8283. -	StringBuf_Printf(&buf, " FROM `%s` ORDER BY `auction_id` DESC", auction_db);
  8284. +	StringBuf_Printf(&buf, " FROM `%s` ORDER BY `auction_id` DESC", schema_config.auction_db);
  8285.  
  8286.  	if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) )
  8287.  		Sql_ShowDebug(sql_handle);
  8288. Index: src/char/int_guild.c
  8289. ===================================================================
  8290. --- src/char/int_guild.c	(revision 17367)
  8291. +++ src/char/int_guild.c	(working copy)
  8292. @@ -10,6 +10,7 @@
  8293.  #include "../common/strlib.h"
  8294.  #include "../common/timer.h"
  8295.  #include "char.h"
  8296. +#include "char_mapif.h"
  8297.  #include "inter.h"
  8298.  #include "int_guild.h"
  8299.  
  8300. @@ -72,7 +73,7 @@
  8301.  
  8302.  		if( g->save_flag == GS_REMOVE )
  8303.  		{// Nothing to save, guild is ready for removal.
  8304. -			if (save_log)
  8305. +			if (charserv_config.save_log)
  8306.  				ShowInfo("Guild Unloaded (%d - %s)\n", g->guild_id, g->name);
  8307.  			db_remove(guild_db_, key);
  8308.  		}
  8309. @@ -84,15 +85,15 @@
  8310.  
  8311.  	state = guild_db_->size(guild_db_);
  8312.  	if( state < 1 ) state = 1; //Calculate the time slot for the next save.
  8313. -	add_timer(tick  + autosave_interval/state, guild_save_timer, 0, 0);
  8314. +	add_timer(tick  + (charserv_config.autosave_interval)/state, guild_save_timer, 0, 0);
  8315.  	return 0;
  8316.  }
  8317.  
  8318.  int inter_guild_removemember_tosql(int account_id, int char_id)
  8319.  {
  8320. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE from `%s` where `account_id` = '%d' and `char_id` = '%d'", guild_member_db, account_id, char_id) )
  8321. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE from `%s` where `account_id` = '%d' and `char_id` = '%d'", schema_config.guild_member_db, account_id, char_id) )
  8322.  		Sql_ShowDebug(sql_handle);
  8323. -	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `guild_id` = '0' WHERE `char_id` = '%d'", char_db, char_id) )
  8324. +	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `guild_id` = '0' WHERE `char_id` = '%d'", schema_config.char_db, char_id) )
  8325.  		Sql_ShowDebug(sql_handle);
  8326.  	return 0;
  8327.  }
  8328. @@ -140,7 +141,7 @@
  8329.  		if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
  8330.  			"(`name`,`master`,`guild_lv`,`max_member`,`average_lv`,`char_id`) "
  8331.  			"VALUES ('%s', '%s', '%d', '%d', '%d', '%d')",
  8332. -			guild_db, esc_name, esc_master, g->guild_lv, g->max_member, g->average_lv, g->member[0].char_id) )
  8333. +			schema_config.guild_db, esc_name, esc_master, g->guild_lv, g->max_member, g->average_lv, g->member[0].char_id) )
  8334.  		{
  8335.  			Sql_ShowDebug(sql_handle);
  8336.  			if (g->guild_id == -1)
  8337. @@ -160,7 +161,7 @@
  8338.  		bool add_comma = false;
  8339.  
  8340.  		StringBuf_Init(&buf);
  8341. -		StringBuf_Printf(&buf, "UPDATE `%s` SET ", guild_db);
  8342. +		StringBuf_Printf(&buf, "UPDATE `%s` SET ", schema_config.guild_db);
  8343.  
  8344.  		if (flag & GS_EMBLEM)
  8345.  		{
  8346. @@ -240,14 +241,14 @@
  8347.  				Sql_EscapeStringLen(sql_handle, esc_name, m->name, strnlen(m->name, NAME_LENGTH));
  8348.  				if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`guild_id`,`account_id`,`char_id`,`hair`,`hair_color`,`gender`,`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`name`) "
  8349.  					"VALUES ('%d','%d','%d','%d','%d','%d','%d','%d','%"PRIu64"','%d','%d','%d','%s')",
  8350. -					guild_member_db, g->guild_id, m->account_id, m->char_id,
  8351. +					schema_config.guild_member_db, g->guild_id, m->account_id, m->char_id,
  8352.  					m->hair, m->hair_color, m->gender,
  8353.  					m->class_, m->lv, m->exp, m->exp_payper, m->online, m->position, esc_name) )
  8354.  					Sql_ShowDebug(sql_handle);
  8355.  				if (m->modified&GS_MEMBER_NEW || new_guild == 1)
  8356.  				{
  8357.  					if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `guild_id` = '%d' WHERE `char_id` = '%d'",
  8358. -						char_db, g->guild_id, m->char_id) )
  8359. +						schema_config.char_db, g->guild_id, m->char_id) )
  8360.  						Sql_ShowDebug(sql_handle);
  8361.  				}
  8362.  				m->modified = GS_MEMBER_UNMODIFIED;
  8363. @@ -264,7 +265,7 @@
  8364.  				continue;
  8365.  			Sql_EscapeStringLen(sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH));
  8366.  			if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`guild_id`,`position`,`name`,`mode`,`exp_mode`) VALUES ('%d','%d','%s','%d','%d')",
  8367. -				guild_position_db, g->guild_id, i, esc_name, p->mode, p->exp_mode) )
  8368. +				schema_config.guild_position_db, g->guild_id, i, esc_name, p->mode, p->exp_mode) )
  8369.  				Sql_ShowDebug(sql_handle);
  8370.  			p->modified = GS_POSITION_UNMODIFIED;
  8371.  		}
  8372. @@ -277,7 +278,7 @@
  8373.  		// their info changed, not to mention this would also mess up oppositions!
  8374.  		// [Skotlex]
  8375.  		//if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id`='%d' OR `alliance_id`='%d'", guild_alliance_db, g->guild_id, g->guild_id) )
  8376. -		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id`='%d'", guild_alliance_db, g->guild_id) )
  8377. +		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id`='%d'", schema_config.guild_alliance_db, g->guild_id) )
  8378.  		{
  8379.  			Sql_ShowDebug(sql_handle);
  8380.  		}
  8381. @@ -292,7 +293,7 @@
  8382.  					Sql_EscapeStringLen(sql_handle, esc_name, a->name, strnlen(a->name, NAME_LENGTH));
  8383.  					if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`guild_id`,`opposition`,`alliance_id`,`name`) "
  8384.  						"VALUES ('%d','%d','%d','%s')",
  8385. -						guild_alliance_db, g->guild_id, a->opposition, a->guild_id, esc_name) )
  8386. +						schema_config.guild_alliance_db, g->guild_id, a->opposition, a->guild_id, esc_name) )
  8387.  						Sql_ShowDebug(sql_handle);
  8388.  				}
  8389.  			}
  8390. @@ -310,7 +311,7 @@
  8391.  				Sql_EscapeStringLen(sql_handle, esc_name, e->name, strnlen(e->name, NAME_LENGTH));
  8392.  				Sql_EscapeStringLen(sql_handle, esc_mes, e->mes, strnlen(e->mes, sizeof(e->mes)));
  8393.  				if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`guild_id`,`account_id`,`name`,`mes`) "
  8394. -					"VALUES ('%d','%d','%s','%s')", guild_expulsion_db, g->guild_id, e->account_id, esc_name, esc_mes) )
  8395. +					"VALUES ('%d','%d','%s','%s')", schema_config.guild_expulsion_db, g->guild_id, e->account_id, esc_name, esc_mes) )
  8396.  					Sql_ShowDebug(sql_handle);
  8397.  			}
  8398.  		}
  8399. @@ -322,13 +323,13 @@
  8400.  		for(i=0;i<MAX_GUILDSKILL;i++){
  8401.  			if (g->skill[i].id>0 && g->skill[i].lv>0){
  8402.  				if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`guild_id`,`id`,`lv`) VALUES ('%d','%d','%d')",
  8403. -					guild_skill_db, g->guild_id, g->skill[i].id, g->skill[i].lv) )
  8404. +					schema_config.guild_skill_db, g->guild_id, g->skill[i].id, g->skill[i].lv) )
  8405.  					Sql_ShowDebug(sql_handle);
  8406.  			}
  8407.  		}
  8408.  	}
  8409.  
  8410. -	if (save_log)
  8411. +	if (charserv_config.save_log)
  8412.  		ShowInfo("Saved guild (%d - %s):%s\n",g->guild_id,g->name,t_info);
  8413.  	return 1;
  8414.  }
  8415. @@ -354,7 +355,7 @@
  8416.  #endif
  8417.  
  8418.  	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT g.`name`,c.`name`,g.`guild_lv`,g.`connect_member`,g.`max_member`,g.`average_lv`,g.`exp`,g.`next_exp`,g.`skill_point`,g.`mes1`,g.`mes2`,g.`emblem_len`,g.`emblem_id`,g.`emblem_data` "
  8419. -		"FROM `%s` g LEFT JOIN `%s` c ON c.`char_id` = g.`char_id` WHERE g.`guild_id`='%d'", guild_db, char_db, guild_id) )
  8420. +		"FROM `%s` g LEFT JOIN `%s` c ON c.`char_id` = g.`char_id` WHERE g.`guild_id`='%d'", schema_config.guild_db, schema_config.char_db, guild_id) )
  8421.  	{
  8422.  		Sql_ShowDebug(sql_handle);
  8423.  		return NULL;
  8424. @@ -409,7 +410,7 @@
  8425.  
  8426.  	// load guild member info
  8427.  	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`char_id`,`hair`,`hair_color`,`gender`,`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`name` "
  8428. -		"FROM `%s` WHERE `guild_id`='%d' ORDER BY `position`", guild_member_db, guild_id) )
  8429. +		"FROM `%s` WHERE `guild_id`='%d' ORDER BY `position`", schema_config.guild_member_db, guild_id) )
  8430.  	{
  8431.  		Sql_ShowDebug(sql_handle);
  8432.  		aFree(g);
  8433. @@ -437,7 +438,7 @@
  8434.  	}
  8435.  
  8436.  	//printf("- Read guild_position %d from sql \n",guild_id);
  8437. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `position`,`name`,`mode`,`exp_mode` FROM `%s` WHERE `guild_id`='%d'", guild_position_db, guild_id) )
  8438. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `position`,`name`,`mode`,`exp_mode` FROM `%s` WHERE `guild_id`='%d'", schema_config.guild_position_db, guild_id) )
  8439.  	{
  8440.  		Sql_ShowDebug(sql_handle);
  8441.  		aFree(g);
  8442. @@ -459,7 +460,7 @@
  8443.  	}
  8444.  
  8445.  	//printf("- Read guild_alliance %d from sql \n",guild_id);
  8446. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `opposition`,`alliance_id`,`name` FROM `%s` WHERE `guild_id`='%d'", guild_alliance_db, guild_id) )
  8447. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `opposition`,`alliance_id`,`name` FROM `%s` WHERE `guild_id`='%d'", schema_config.guild_alliance_db, guild_id) )
  8448.  	{
  8449.  		Sql_ShowDebug(sql_handle);
  8450.  		aFree(g);
  8451. @@ -475,7 +476,7 @@
  8452.  	}
  8453.  
  8454.  	//printf("- Read guild_expulsion %d from sql \n",guild_id);
  8455. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name`,`mes` FROM `%s` WHERE `guild_id`='%d'", guild_expulsion_db, guild_id) )
  8456. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name`,`mes` FROM `%s` WHERE `guild_id`='%d'", schema_config.guild_expulsion_db, guild_id) )
  8457.  	{
  8458.  		Sql_ShowDebug(sql_handle);
  8459.  		aFree(g);
  8460. @@ -491,7 +492,7 @@
  8461.  	}
  8462.  
  8463.  	//printf("- Read guild_skill %d from sql \n",guild_id);
  8464. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `id`,`lv` FROM `%s` WHERE `guild_id`='%d' ORDER BY `id`", guild_skill_db, guild_id) )
  8465. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `id`,`lv` FROM `%s` WHERE `guild_id`='%d' ORDER BY `id`", schema_config.guild_skill_db, guild_id) )
  8466.  	{
  8467.  		Sql_ShowDebug(sql_handle);
  8468.  		aFree(g);
  8469. @@ -516,7 +517,7 @@
  8470.  	idb_put(guild_db_, guild_id, g); //Add to cache
  8471.  	g->save_flag |= GS_REMOVE; //But set it to be removed, in case it is not needed for long.
  8472.  
  8473. -	if (save_log)
  8474. +	if (charserv_config.save_log)
  8475.  		ShowInfo("Guild loaded (%d - %s)\n", guild_id, g->name);
  8476.  
  8477.  	return g;
  8478. @@ -530,15 +531,15 @@
  8479.  
  8480.  	StringBuf_Init(&buf);
  8481.  	StringBuf_Printf(&buf, "REPLACE INTO `%s` SET `castle_id`='%d', `guild_id`='%d', `economy`='%d', `defense`='%d', "
  8482. -	                 "`triggerE`='%d', `triggerD`='%d', `nextTime`='%d', `payTime`='%d', `createTime`='%d', `visibleC`='%d'",
  8483. -	                 guild_castle_db, gc->castle_id, gc->guild_id, gc->economy, gc->defense,
  8484. -	                 gc->triggerE, gc->triggerD, gc->nextTime, gc->payTime, gc->createTime, gc->visibleC);
  8485. +	    "`triggerE`='%d', `triggerD`='%d', `nextTime`='%d', `payTime`='%d', `createTime`='%d', `visibleC`='%d'",
  8486. +	    schema_config.guild_castle_db, gc->castle_id, gc->guild_id, gc->economy, gc->defense,
  8487. +	    gc->triggerE, gc->triggerD, gc->nextTime, gc->payTime, gc->createTime, gc->visibleC);
  8488.  	for (i = 0; i < MAX_GUARDIANS; ++i)
  8489.  		StringBuf_Printf(&buf, ", `visibleG%d`='%d'", i, gc->guardian[i].visible);
  8490.  
  8491.  	if (SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)))
  8492.  		Sql_ShowDebug(sql_handle);
  8493. -	else if(save_log)
  8494. +	else if(charserv_config.save_log)
  8495.  		ShowInfo("Saved guild castle (%d)\n", gc->castle_id);
  8496.  
  8497.  	StringBuf_Destroy(&buf);
  8498. @@ -561,7 +562,7 @@
  8499.  	                    "`triggerD`, `nextTime`, `payTime`, `createTime`, `visibleC`");
  8500.  	for (i = 0; i < MAX_GUARDIANS; ++i)
  8501.  		StringBuf_Printf(&buf, ", `visibleG%d`", i);
  8502. -	StringBuf_Printf(&buf, " FROM `%s` WHERE `castle_id`='%d'", guild_castle_db, castle_id);
  8503. +	StringBuf_Printf(&buf, " FROM `%s` WHERE `castle_id`='%d'", schema_config.guild_castle_db, castle_id);
  8504.  	if (SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf))) {
  8505.  		Sql_ShowDebug(sql_handle);
  8506.  		StringBuf_Destroy(&buf);
  8507. @@ -590,7 +591,7 @@
  8508.  
  8509.  	idb_put(castle_db, castle_id, gc);
  8510.  
  8511. -	if (save_log)
  8512. +	if (charserv_config.save_log)
  8513.  		ShowInfo("Loaded guild castle (%d - guild %d)\n", castle_id, gc->guild_id);
  8514.  
  8515.  	return gc;
  8516. @@ -619,7 +620,7 @@
  8517.  
  8518.  	if (guild_id == -1) {
  8519.  		//Get guild_id from the database
  8520. -		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT guild_id FROM `%s` WHERE char_id='%d'", char_db, char_id) )
  8521. +		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT guild_id FROM `%s` WHERE char_id='%d'", schema_config.char_db, char_id) )
  8522.  		{
  8523.  			Sql_ShowDebug(sql_handle);
  8524.  			return 0;
  8525. @@ -670,7 +671,7 @@
  8526.  	if (guild_id == -1)
  8527.  	{
  8528.  		//Get guild_id from the database
  8529. -		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT guild_id FROM `%s` WHERE char_id='%d'", char_db, char_id) )
  8530. +		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT guild_id FROM `%s` WHERE char_id='%d'", schema_config.char_db, char_id) )
  8531.  		{
  8532.  			Sql_ShowDebug(sql_handle);
  8533.  			return 0;
  8534. @@ -760,7 +761,7 @@
  8535.  
  8536.  	Sql_EscapeStringLen(sql_handle, esc_name, str, safestrnlen(str, NAME_LENGTH));
  8537.  	//Lookup guilds with the same name
  8538. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT guild_id FROM `%s` WHERE name='%s'", guild_db, esc_name) )
  8539. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT guild_id FROM `%s` WHERE name='%s'", schema_config.guild_db, esc_name) )
  8540.  	{
  8541.  		Sql_ShowDebug(sql_handle);
  8542.  		return -1;
  8543. @@ -1142,15 +1143,15 @@
  8544.  		return 0;
  8545.  	}
  8546.  	// Check Authorised letters/symbols in the name of the character
  8547. -	if (char_name_option == 1) { // only letters/symbols in char_name_letters are authorised
  8548. +	if (charserv_config.char_name_option == 1) { // only letters/symbols in char_name_letters are authorised
  8549.  		for (i = 0; i < NAME_LENGTH && name[i]; i++)
  8550. -			if (strchr(char_name_letters, name[i]) == NULL) {
  8551. +			if (strchr(charserv_config.char_name_letters, name[i]) == NULL) {
  8552.  				mapif_guild_created(fd,account_id,NULL);
  8553.  				return 0;
  8554.  			}
  8555. -	} else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
  8556. +	} else if (charserv_config.char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
  8557.  		for (i = 0; i < NAME_LENGTH && name[i]; i++)
  8558. -			if (strchr(char_name_letters, name[i]) != NULL) {
  8559. +			if (strchr(charserv_config.char_name_letters, name[i]) != NULL) {
  8560.  				mapif_guild_created(fd,account_id,NULL);
  8561.  				return 0;
  8562.  			}
  8563. @@ -1200,7 +1201,7 @@
  8564.  	mapif_guild_created(fd,account_id,g);
  8565.  	mapif_guild_info(fd,g);
  8566.  
  8567. -	if(log_inter)
  8568. +	if(charserv_config.log_inter)
  8569.  		inter_log("guild %s (id=%d) created by master %s (id=%d)\n",
  8570.  			name, g->guild_id, master->name, master->account_id );
  8571.  
  8572. @@ -1266,7 +1267,7 @@
  8573.  	if( g == NULL )
  8574.  	{
  8575.  		// Unknown guild, just update the player
  8576. -		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `guild_id`='0' WHERE `account_id`='%d' AND `char_id`='%d'", char_db, account_id, char_id) )
  8577. +		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `guild_id`='0' WHERE `account_id`='%d' AND `char_id`='%d'", schema_config.char_db, account_id, char_id) )
  8578.  			Sql_ShowDebug(sql_handle);
  8579.  		// mapif_guild_withdraw(guild_id,account_id,char_id,flag,g->member[i].name,mes);
  8580.  		return 0;
  8581. @@ -1379,37 +1380,37 @@
  8582.  
  8583.  	// Delete guild from sql
  8584.  	//printf("- Delete guild %d from guild\n",guild_id);
  8585. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_db, guild_id) )
  8586. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", schema_config.guild_db, guild_id) )
  8587.  		Sql_ShowDebug(sql_handle);
  8588.  
  8589. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_member_db, guild_id) )
  8590. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", schema_config.guild_member_db, guild_id) )
  8591.  		Sql_ShowDebug(sql_handle);
  8592.  
  8593. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_castle_db, guild_id) )
  8594. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", schema_config.guild_castle_db, guild_id) )
  8595.  		Sql_ShowDebug(sql_handle);
  8596.  
  8597. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_storage_db, guild_id) )
  8598. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", schema_config.guild_storage_db, guild_id) )
  8599.  		Sql_ShowDebug(sql_handle);
  8600.  
  8601. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d' OR `alliance_id` = '%d'", guild_alliance_db, guild_id, guild_id) )
  8602. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d' OR `alliance_id` = '%d'", schema_config.guild_alliance_db, guild_id, guild_id) )
  8603.  		Sql_ShowDebug(sql_handle);
  8604.  
  8605. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_position_db, guild_id) )
  8606. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", schema_config.guild_position_db, guild_id) )
  8607.  		Sql_ShowDebug(sql_handle);
  8608.  
  8609. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_skill_db, guild_id) )
  8610. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", schema_config.guild_skill_db, guild_id) )
  8611.  		Sql_ShowDebug(sql_handle);
  8612.  
  8613. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_expulsion_db, guild_id) )
  8614. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", schema_config.guild_expulsion_db, guild_id) )
  8615.  		Sql_ShowDebug(sql_handle);
  8616.  
  8617.  	//printf("- Update guild %d of char\n",guild_id);
  8618. -	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `guild_id`='0' WHERE `guild_id`='%d'", char_db, guild_id) )
  8619. +	if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `guild_id`='0' WHERE `guild_id`='%d'", schema_config.char_db, guild_id) )
  8620.  		Sql_ShowDebug(sql_handle);
  8621.  
  8622.  	mapif_guild_broken(guild_id,0);
  8623.  
  8624. -	if(log_inter)
  8625. +	if(charserv_config.log_inter)
  8626.  		inter_log("guild %s (id=%d) broken\n",g->name,guild_id);
  8627.  
  8628.  	//Remove the guild from memory. [Skotlex]
  8629. @@ -1497,8 +1498,8 @@
  8630.  				exp = g->member[i].exp - old_exp;
  8631.  
  8632.  				// Compute gained exp
  8633. -				if (guild_exp_rate != 100)
  8634. -					exp = exp*guild_exp_rate/100;
  8635. +				if (charserv_config.guild_exp_rate != 100)
  8636. +					exp = exp*(charserv_config.guild_exp_rate)/100;
  8637.  
  8638.  				// Update guild exp
  8639.  				if (exp > UINT64_MAX - g->exp)
  8640. @@ -1759,7 +1760,7 @@
  8641.  
  8642.  	switch (index) {
  8643.  		case 1:
  8644. -			if (log_inter && gc->guild_id != value) {
  8645. +			if (charserv_config.log_inter && gc->guild_id != value) {
  8646.  				int gid = (value) ? value : gc->guild_id;
  8647.  				struct guild *g = idb_get(guild_db_, gid);
  8648.  				inter_log("guild %s (id=%d) %s castle id=%d\n",
  8649. Index: src/char/int_elemental.c
  8650. ===================================================================
  8651. --- src/char/int_elemental.c	(revision 17367)
  8652. +++ src/char/int_elemental.c	(working copy)
  8653. @@ -17,7 +17,7 @@
  8654.  
  8655.  bool mapif_elemental_save(struct s_elemental* ele) {
  8656.  	bool flag = true;
  8657. -	
  8658. +
  8659.  	if( ele->elemental_id == 0 ) { // Create new DB entry
  8660.  		if( SQL_ERROR == Sql_Query(sql_handle,
  8661.  								   "INSERT INTO `elemental` (`char_id`,`class`,`mode`,`hp`,`sp`,`max_hp`,`max_sp`,`atk1`,`atk2`,`matk`,`aspd`,`def`,`mdef`,`flee`,`hit`,`life_time`)"
  8662. @@ -44,23 +44,23 @@
  8663.  
  8664.  bool mapif_elemental_load(int ele_id, int char_id, struct s_elemental *ele) {
  8665.  	char* data;
  8666. -	
  8667. +
  8668.  	memset(ele, 0, sizeof(struct s_elemental));
  8669.  	ele->elemental_id = ele_id;
  8670.  	ele->char_id = char_id;
  8671. -	
  8672. +
  8673.  	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `class`, `mode`, `hp`, `sp`, `max_hp`, `max_sp`, `atk1`, `atk2`, `matk`, `aspd`,"
  8674.  							   "`def`, `mdef`, `flee`, `hit`, `life_time` FROM `elemental` WHERE `ele_id` = '%d' AND `char_id` = '%d'",
  8675.  							   ele_id, char_id) ) {
  8676.  		Sql_ShowDebug(sql_handle);
  8677.  		return false;
  8678.  	}
  8679. -	
  8680. +
  8681.  	if( SQL_SUCCESS != Sql_NextRow(sql_handle) ) {
  8682.  		Sql_FreeResult(sql_handle);
  8683.  		return false;
  8684.  	}
  8685. -	
  8686. +
  8687.  	Sql_GetData(sql_handle,  0, &data, NULL); ele->class_ = atoi(data);
  8688.  	Sql_GetData(sql_handle,  1, &data, NULL); ele->mode = atoi(data);
  8689.  	Sql_GetData(sql_handle,  2, &data, NULL); ele->hp = atoi(data);
  8690. @@ -77,9 +77,9 @@
  8691.  	Sql_GetData(sql_handle, 13, &data, NULL); ele->hit = atoi(data);
  8692.  	Sql_GetData(sql_handle, 14, &data, NULL); ele->life_time = atoi(data);
  8693.  	Sql_FreeResult(sql_handle);
  8694. -	if( save_log )
  8695. +	if( charserv_config.save_log )
  8696.  		ShowInfo("Elemental loaded (%d - %d).\n", ele->elemental_id, ele->char_id);
  8697. -	
  8698. +
  8699.  	return true;
  8700.  }
  8701.  
  8702. @@ -88,13 +88,13 @@
  8703.  		Sql_ShowDebug(sql_handle);
  8704.  		return false;
  8705.  	}
  8706. -	
  8707. +
  8708.  	return true;
  8709.  }
  8710.  
  8711.  static void mapif_elemental_send(int fd, struct s_elemental *ele, unsigned char flag) {
  8712.  	int size = sizeof(struct s_elemental) + 5;
  8713. -	
  8714. +
  8715.  	WFIFOHEAD(fd,size);
  8716.  	WFIFOW(fd,0) = 0x387c;
  8717.  	WFIFOW(fd,2) = size;
  8718. @@ -150,7 +150,7 @@
  8719.   *------------------------------------------*/
  8720.  int inter_elemental_parse_frommap(int fd) {
  8721.  	unsigned short cmd = RFIFOW(fd,0);
  8722. -	
  8723. +
  8724.  	switch( cmd ) {
  8725.  		case 0x307c: mapif_parse_elemental_create(fd, (struct s_elemental*)RFIFOP(fd,4)); break;
  8726.  		case 0x307d: mapif_parse_elemental_load(fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6)); break;
  8727. Index: src/char/inter.c
  8728. ===================================================================
  8729. --- src/char/inter.c	(revision 17367)
  8730. +++ src/char/inter.c	(working copy)
  8731. @@ -9,6 +9,8 @@
  8732.  #include "../common/socket.h"
  8733.  #include "../common/timer.h"
  8734.  #include "char.h"
  8735. +#include "char_logif.h"
  8736. +#include "char_mapif.h"
  8737.  #include "inter.h"
  8738.  #include "int_party.h"
  8739.  #include "int_guild.h"
  8740. @@ -389,7 +391,7 @@
  8741.  	account_id = atoi(query);
  8742.  
  8743.  	if (account_id < START_ACCOUNT_NUM) {	// is string
  8744. -		if ( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name`,`class`,`base_level`,`job_level`,`online` FROM `%s` WHERE `name` LIKE '%s' LIMIT 10", char_db, query_esq)
  8745. +		if ( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name`,`class`,`base_level`,`job_level`,`online` FROM `%s` WHERE `name` LIKE '%s' LIMIT 10", schema_config.char_db, query_esq)
  8746.  				|| Sql_NumRows(sql_handle) == 0 ) {
  8747.  			if( Sql_NumRows(sql_handle) == 0 ) {
  8748.  				inter_to_fd(fd, u_fd, aid, "No matches were found for your criteria, '%s'",query);
  8749. @@ -523,12 +525,12 @@
  8750.  	switch( type )
  8751.  	{
  8752.  	case 3: //Char Reg
  8753. -		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) )
  8754. +		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", schema_config.reg_db, char_id) )
  8755.  			Sql_ShowDebug(sql_handle);
  8756.  		account_id = 0;
  8757.  		break;
  8758.  	case 2: //Account Reg
  8759. -		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id) )
  8760. +		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`=2 AND `account_id`='%d'", schema_config.reg_db, account_id) )
  8761.  			Sql_ShowDebug(sql_handle);
  8762.  		char_id = 0;
  8763.  		break;
  8764. @@ -544,7 +546,7 @@
  8765.  		return 0;
  8766.  
  8767.  	StringBuf_Init(&buf);
  8768. -	StringBuf_Printf(&buf, "INSERT INTO `%s` (`type`,`account_id`,`char_id`,`str`,`value`) VALUES ", reg_db);
  8769. +	StringBuf_Printf(&buf, "INSERT INTO `%s` (`type`,`account_id`,`char_id`,`str`,`value`) VALUES ", schema_config.reg_db);
  8770.  
  8771.  	for( i = 0; i < reg->reg_num; ++i ) {
  8772.  		r = &reg->reg[i];
  8773. @@ -590,11 +592,11 @@
  8774.  	switch( type )
  8775.  	{
  8776.  	case 3: //char reg
  8777. -		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) )
  8778. +		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=3 AND `char_id`='%d'", schema_config.reg_db, char_id) )
  8779.  			Sql_ShowDebug(sql_handle);
  8780.  		break;
  8781.  	case 2: //account reg
  8782. -		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id) )
  8783. +		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=2 AND `account_id`='%d'", schema_config.reg_db, account_id) )
  8784.  			Sql_ShowDebug(sql_handle);
  8785.  		break;
  8786.  	case 1: //account2 reg
  8787. @@ -669,7 +671,7 @@
  8788.  		else if(!strcmpi(w1,"party_share_level"))
  8789.  			party_share_level = atoi(w2);
  8790.  		else if(!strcmpi(w1,"log_inter"))
  8791. -			log_inter = atoi(w2);
  8792. +			charserv_config.log_inter = atoi(w2);
  8793.  		else if(!strcmpi(w1,"import"))
  8794.  			inter_config_read(w2);
  8795.  	}
  8796. @@ -692,7 +694,7 @@
  8797.  	va_end(ap);
  8798.  
  8799.  	Sql_EscapeStringLen(sql_handle, esc_str, str, strnlen(str, sizeof(str)));
  8800. -	if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`time`, `log`) VALUES (NOW(),  '%s')", interlog_db, esc_str) )
  8801. +	if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`time`, `log`) VALUES (NOW(),  '%s')", schema_config.interlog_db, esc_str) )
  8802.  		Sql_ShowDebug(sql_handle);
  8803.  
  8804.  	return 0;
  8805. @@ -934,7 +936,7 @@
  8806.  	safestrncpy(name, (char*)RFIFOP(fd,28), NAME_LENGTH); //Received name may be too large and not contain \0! [Skotlex]
  8807.  
  8808.  	Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
  8809. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `name` FROM `%s` WHERE `name`='%s'", char_db, esc_name) )
  8810. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `name` FROM `%s` WHERE `name`='%s'", schema_config.char_db, esc_name) )
  8811.  		Sql_ShowDebug(sql_handle);
  8812.  
  8813.  	// search if character exists before to ask all map-servers
  8814. @@ -1088,15 +1090,15 @@
  8815.  	name = (char*)RFIFOP(fd,11);
  8816.  
  8817.  	// Check Authorised letters/symbols in the name
  8818. -	if (char_name_option == 1) { // only letters/symbols in char_name_letters are authorised
  8819. +	if (charserv_config.char_name_option == 1) { // only letters/symbols in char_name_letters are authorised
  8820.  		for (i = 0; i < NAME_LENGTH && name[i]; i++)
  8821. -		if (strchr(char_name_letters, name[i]) == NULL) {
  8822. +		if (strchr(charserv_config.char_name_letters, name[i]) == NULL) {
  8823.  			mapif_namechange_ack(fd, account_id, char_id, type, 0, name);
  8824.  			return 0;
  8825.  		}
  8826. -	} else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
  8827. +	} else if (charserv_config.char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
  8828.  		for (i = 0; i < NAME_LENGTH && name[i]; i++)
  8829. -		if (strchr(char_name_letters, name[i]) != NULL) {
  8830. +		if (strchr(charserv_config.char_name_letters, name[i]) != NULL) {
  8831.  			mapif_namechange_ack(fd, account_id, char_id, type, 0, name);
  8832.  			return 0;
  8833.  		}
  8834. Index: src/char/CMakeLists.txt
  8835. ===================================================================
  8836. --- src/char/CMakeLists.txt	(revision 17367)
  8837. +++ src/char/CMakeLists.txt	(working copy)
  8838. @@ -12,6 +12,10 @@
  8839.  message( STATUS "Creating target char-server_sql" )
  8840.  set( SQL_CHAR_HEADERS
  8841.  	"${CMAKE_CURRENT_SOURCE_DIR}/char.h"
  8842. +	"${CMAKE_CURRENT_SOURCE_DIR}/char_clif.h"
  8843. +	"${CMAKE_CURRENT_SOURCE_DIR}/char_cnslif.h"
  8844. +	"${CMAKE_CURRENT_SOURCE_DIR}/char_logif.h"
  8845. +	"${CMAKE_CURRENT_SOURCE_DIR}/char_mapif.h"
  8846.  	"${CMAKE_CURRENT_SOURCE_DIR}/int_auction.h"
  8847.  	"${CMAKE_CURRENT_SOURCE_DIR}/int_elemental.h"
  8848.  	"${CMAKE_CURRENT_SOURCE_DIR}/int_guild.h"
  8849. @@ -26,6 +30,10 @@
  8850.  	)
  8851.  set( SQL_CHAR_SOURCES
  8852.  	"${CMAKE_CURRENT_SOURCE_DIR}/char.c"
  8853. +	"${CMAKE_CURRENT_SOURCE_DIR}/char_clif.c"
  8854. +	"${CMAKE_CURRENT_SOURCE_DIR}/char_cnslif.c"
  8855. +	"${CMAKE_CURRENT_SOURCE_DIR}/char_logif.c"
  8856. +	"${CMAKE_CURRENT_SOURCE_DIR}/char_mapif.c"
  8857.  	"${CMAKE_CURRENT_SOURCE_DIR}/int_auction.c"
  8858.  	"${CMAKE_CURRENT_SOURCE_DIR}/int_elemental.c"
  8859.  	"${CMAKE_CURRENT_SOURCE_DIR}/int_guild.c"
  8860. Index: src/char/int_mercenary.c
  8861. ===================================================================
  8862. --- src/char/int_mercenary.c	(revision 17367)
  8863. +++ src/char/int_mercenary.c	(working copy)
  8864. @@ -19,7 +19,7 @@
  8865.  {
  8866.  	char* data;
  8867.  
  8868. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `merc_id`, `arch_calls`, `arch_faith`, `spear_calls`, `spear_faith`, `sword_calls`, `sword_faith` FROM `%s` WHERE `char_id` = '%d'", mercenary_owner_db, char_id) )
  8869. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `merc_id`, `arch_calls`, `arch_faith`, `spear_calls`, `spear_faith`, `sword_calls`, `sword_faith` FROM `%s` WHERE `char_id` = '%d'", schema_config.mercenary_owner_db, char_id) )
  8870.  	{
  8871.  		Sql_ShowDebug(sql_handle);
  8872.  		return false;
  8873. @@ -46,7 +46,7 @@
  8874.  bool mercenary_owner_tosql(int char_id, struct mmo_charstatus *status)
  8875.  {
  8876.  	if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`char_id`, `merc_id`, `arch_calls`, `arch_faith`, `spear_calls`, `spear_faith`, `sword_calls`, `sword_faith`) VALUES ('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
  8877. -		mercenary_owner_db, char_id, status->mer_id, status->arch_calls, status->arch_faith, status->spear_calls, status->spear_faith, status->sword_calls, status->sword_faith) )
  8878. +		schema_config.mercenary_owner_db, char_id, status->mer_id, status->arch_calls, status->arch_faith, status->spear_calls, status->spear_faith, status->sword_calls, status->sword_faith) )
  8879.  	{
  8880.  		Sql_ShowDebug(sql_handle);
  8881.  		return false;
  8882. @@ -57,10 +57,10 @@
  8883.  
  8884.  bool mercenary_owner_delete(int char_id)
  8885.  {
  8886. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d'", mercenary_owner_db, char_id) )
  8887. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d'", schema_config.mercenary_owner_db, char_id) )
  8888.  		Sql_ShowDebug(sql_handle);
  8889.  
  8890. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d'", mercenary_db, char_id) )
  8891. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d'", schema_config.mercenary_db, char_id) )
  8892.  		Sql_ShowDebug(sql_handle);
  8893.  
  8894.  	return true;
  8895. @@ -74,7 +74,7 @@
  8896.  	{ // Create new DB entry
  8897.  		if( SQL_ERROR == Sql_Query(sql_handle,
  8898.  			"INSERT INTO `%s` (`char_id`,`class`,`hp`,`sp`,`kill_counter`,`life_time`) VALUES ('%d','%d','%d','%d','%u','%u')",
  8899. -			mercenary_db, merc->char_id, merc->class_, merc->hp, merc->sp, merc->kill_count, merc->life_time) )
  8900. +			schema_config.mercenary_db, merc->char_id, merc->class_, merc->hp, merc->sp, merc->kill_count, merc->life_time) )
  8901.  		{
  8902.  			Sql_ShowDebug(sql_handle);
  8903.  			flag = false;
  8904. @@ -84,7 +84,7 @@
  8905.  	}
  8906.  	else if( SQL_ERROR == Sql_Query(sql_handle,
  8907.  		"UPDATE `%s` SET `char_id` = '%d', `class` = '%d', `hp` = '%d', `sp` = '%d', `kill_counter` = '%u', `life_time` = '%u' WHERE `mer_id` = '%d'",
  8908. -		mercenary_db, merc->char_id, merc->class_, merc->hp, merc->sp, merc->kill_count, merc->life_time, merc->mercenary_id) )
  8909. +		schema_config.mercenary_db, merc->char_id, merc->class_, merc->hp, merc->sp, merc->kill_count, merc->life_time, merc->mercenary_id) )
  8910.  	{ // Update DB entry
  8911.  		Sql_ShowDebug(sql_handle);
  8912.  		flag = false;
  8913. @@ -101,7 +101,7 @@
  8914.  	merc->mercenary_id = merc_id;
  8915.  	merc->char_id = char_id;
  8916.  
  8917. -	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `class`, `hp`, `sp`, `kill_counter`, `life_time` FROM `%s` WHERE `mer_id` = '%d' AND `char_id` = '%d'", mercenary_db, merc_id, char_id) )
  8918. +	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `class`, `hp`, `sp`, `kill_counter`, `life_time` FROM `%s` WHERE `mer_id` = '%d' AND `char_id` = '%d'", schema_config.mercenary_db, merc_id, char_id) )
  8919.  	{
  8920.  		Sql_ShowDebug(sql_handle);
  8921.  		return false;
  8922. @@ -119,15 +119,15 @@
  8923.  	Sql_GetData(sql_handle,  3, &data, NULL); merc->kill_count = atoi(data);
  8924.  	Sql_GetData(sql_handle,  4, &data, NULL); merc->life_time = atoi(data);
  8925.  	Sql_FreeResult(sql_handle);
  8926. -	if( save_log )
  8927. +	if( charserv_config.save_log )
  8928.  		ShowInfo("Mercenary loaded (%d - %d).\n", merc->mercenary_id, merc->char_id);
  8929. -	
  8930. +
  8931.  	return true;
  8932.  }
  8933.  
  8934.  bool mapif_mercenary_delete(int merc_id)
  8935.  {
  8936. -	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `mer_id` = '%d'", mercenary_db, merc_id) )
  8937. +	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `mer_id` = '%d'", schema_config.mercenary_db, merc_id) )
  8938.  	{
  8939.  		Sql_ShowDebug(sql_handle);
  8940.  		return false;
  8941. Index: src/common/mmo.h
  8942. ===================================================================
  8943. --- src/common/mmo.h	(revision 17367)
  8944. +++ src/common/mmo.h	(working copy)
  8945. @@ -8,52 +8,19 @@
  8946.  #include "../common/db.h"
  8947.  #include <time.h>
  8948.  
  8949. -// server->client protocol version
  8950. -//        0 - pre-?
  8951. -//        1 - ?                    - 0x196
  8952. -//        2 - ?                    - 0x78, 0x79
  8953. -//        3 - ?                    - 0x1c8, 0x1c9, 0x1de
  8954. -//        4 - ?                    - 0x1d7, 0x1d8, 0x1d9, 0x1da
  8955. -//        5 - 2003-12-18aSakexe+   - 0x1ee, 0x1ef, 0x1f0, ?0x1c4, 0x1c5?
  8956. -//        6 - 2004-03-02aSakexe+   - 0x1f4, 0x1f5
  8957. -//        7 - 2005-04-11aSakexe+   - 0x229, 0x22a, 0x22b, 0x22c
  8958. -// 20061023 - 2006-10-23aSakexe+   - 0x6b, 0x6d
  8959. -// 20070521 - 2007-05-21aSakexe+   - 0x283
  8960. -// 20070821 - 2007-08-21aSakexe+   - 0x2c5
  8961. -// 20070918 - 2007-09-18aSakexe+   - 0x2d7, 0x2d9, 0x2da
  8962. -// 20071106 - 2007-11-06aSakexe+   - 0x78, 0x7c, 0x22c
  8963. -// 20080102 - 2008-01-02aSakexe+   - 0x2ec, 0x2ed , 0x2ee
  8964. -// 20081126 - 2008-11-26aSakexe+   - 0x1a2
  8965. -// 20090408 - 2009-04-08aSakexe+   - 0x44a (dont use as it overlaps with RE client packets)
  8966. -// 20080827 - 2008-08-27aRagexeRE+ - First RE Client
  8967. -// 20081217 - 2008-12-17aRagexeRE+ - 0x6d (Note: This one still use old Char Info Packet Structure)
  8968. -// 20081218 - 2008-12-17bRagexeRE+ - 0x6d (Note: From this one client use new Char Info Packet Structure)
  8969. -// 20090603 - 2009-06-03aRagexeRE+ - 0x7d7, 0x7d8, 0x7d9, 0x7da
  8970. -// 20090617 - 2009-06-17aRagexeRE+ - 0x7d9
  8971. -// 20090922 - 2009-09-22aRagexeRE+ - 0x7e5, 0x7e7, 0x7e8, 0x7e9
  8972. -// 20091103 - 2009-11-03aRagexeRE+ - 0x7f7, 0x7f8, 0x7f9
  8973. -// 20100105 - 2010-01-05aRagexeRE+ - 0x133, 0x800, 0x801
  8974. -// 20100126 - 2010-01-26aRagexeRE+ - 0x80e
  8975. -// 20100223 - 2010-02-23aRagexeRE+ - 0x80f
  8976. -// 20100413 - 2010-04-13aRagexeRE+ - 0x6b
  8977. -// 20100629 - 2010-06-29aRagexeRE+ - 0x2d0, 0xaa, 0x2d1, 0x2d2
  8978. -// 20100721 - 2010-07-21aRagexeRE+ - 0x6b, 0x6d
  8979. -// 20100727 - 2010-07-27aRagexeRE+ - 0x6b, 0x6d
  8980. -// 20100803 - 2010-08-03aRagexeRE+ - 0x6b, 0x6d, 0x827, 0x828, 0x829, 0x82a, 0x82b, 0x82c, 0x842, 0x843
  8981. -// 20101124 - 2010-11-24aRagexeRE+ - 0x856, 0x857, 0x858
  8982. -// 20110111 - 2011-01-11aRagexeRE+ - 0x6b, 0x6d
  8983. -// 20110928 - 2011-09-28aRagexeRE+ - 0x6b, 0x6d
  8984. -// 20111025 - 2011-10-25aRagexeRE+ - 0x6b, 0x6d
  8985. -// 20120307 - 2012-03-07aRagexeRE+ - 0x970
  8986. -
  8987.  #ifndef PACKETVER
  8988. -	#define PACKETVER 20120410
  8989. -	//#define PACKETVER 20130320
  8990. +	//#define PACKETVER 20120410
  8991. +	#define PACKETVER 20130320
  8992.  	//#define PACKETVER 20111116
  8993.  #endif
  8994.  
  8995.  //Remove/Comment this line to disable sc_data saving. [Skotlex]
  8996. -#define ENABLE_SC_SAVING
  8997. +//#define ENABLE_SC_SAVING
  8998. +#ifndef ENABLE_SC_SAVING
  8999. +	#ifdef NEW_CARTS
  9000. +	 #warning "Cart won't be able to be saved for relog\n"
  9001. +	#endif
  9002. +#endif
  9003.  //Remove/Comment this line to disable server-side hot-key saving support [Skotlex]
  9004.  //Note that newer clients no longer save hotkeys in the registry!
  9005.  #define HOTKEY_SAVING
  9006. Index: src/common/cli.c
  9007. ===================================================================
  9008. --- src/common/cli.c	(revision 17367)
  9009. +++ src/common/cli.c	(working copy)
  9010. @@ -53,12 +53,12 @@
  9011.   */
  9012.  void display_versionscreen(bool do_exit)
  9013.  {
  9014. -    ShowInfo(CL_WHITE"rAthena SVN version: %s" CL_RESET"\n", get_svn_revision());
  9015. -    ShowInfo(CL_GREEN"Website/Forum:"CL_RESET"\thttp://rathena.org/\n");
  9016. -    ShowInfo(CL_GREEN"IRC Channel:"CL_RESET"\tirc://irc.rizon.net/#rathena\n");
  9017. -    ShowInfo("Open "CL_WHITE"readme.txt"CL_RESET" for more information.\n");
  9018. -    if (do_exit)
  9019. -	exit(EXIT_SUCCESS);
  9020. +	ShowInfo(CL_WHITE"rAthena SVN version: %s" CL_RESET"\n", get_svn_revision());
  9021. +	ShowInfo(CL_GREEN"Website/Forum:"CL_RESET"\thttp://rathena.org/\n");
  9022. +	ShowInfo(CL_GREEN"IRC Channel:"CL_RESET"\tirc://irc.rizon.net/#rathena\n");
  9023. +	ShowInfo("Open "CL_WHITE"readme.txt"CL_RESET" for more information.\n");
  9024. +	if (do_exit)
  9025. +		exit(EXIT_SUCCESS);
  9026.  }
  9027.  
  9028.  /*
  9029. Index: src/common/cli.h
  9030. ===================================================================
  9031. --- src/common/cli.h	(revision 17367)
  9032. +++ src/common/cli.h	(working copy)
  9033. @@ -32,6 +32,8 @@
  9034.   extern char* MSG_CONF_NAME_EN; //all
  9035.  
  9036.  extern void display_helpscreen(bool exit);
  9037. +void display_versionscreen(bool do_exit);
  9038. +bool opt_has_next_value(const char* option, int i, int argc);
  9039.  int cli_get_options(int argc, char ** argv);
  9040.  int parse_console_timer(int tid, unsigned int tick, int id, intptr_t data);
  9041.  extern int parse_console(const char* buf); //particular for each serv
  9042. Index: src/common/timer.c
  9043. ===================================================================
  9044. --- src/common/timer.c	(revision 17367)
  9045. +++ src/common/timer.c	(working copy)
  9046. @@ -109,28 +109,28 @@
  9047.  	} t;
  9048.  
  9049.  	asm volatile("rdtsc":"=a"(t.dw[0]), "=d"(t.dw[1]) );
  9050. -	
  9051. +
  9052.  	return t.qw;
  9053.  }
  9054.  
  9055.  static void rdtsc_calibrate(){
  9056.  	uint64 t1, t2;
  9057.  	int32 i;
  9058. -	
  9059. +
  9060.  	ShowStatus("Calibrating Timer Source, please wait... ");
  9061. -	
  9062. +
  9063.  	RDTSC_CLOCK = 0;
  9064. -	
  9065. +
  9066.  	for(i = 0; i < 5; i++){
  9067.  		t1 = _rdtsc();
  9068.  		usleep(1000000); //1000 MS
  9069.  		t2 = _rdtsc();
  9070. -		RDTSC_CLOCK += (t2 - t1) / 1000; 
  9071. +		RDTSC_CLOCK += (t2 - t1) / 1000;
  9072.  	}
  9073.  	RDTSC_CLOCK /= 5;
  9074. -	
  9075. +
  9076.  	RDTSC_BEGINTICK = _rdtsc();
  9077. -	
  9078. +
  9079.  	ShowMessage(" done. (Frequency: %u Mhz)\n", (uint32)(RDTSC_CLOCK/1000) );
  9080.  }
  9081.  
  9082. @@ -243,7 +243,7 @@
  9083.  int add_timer(unsigned int tick, TimerFunc func, int id, intptr_t data)
  9084.  {
  9085.  	int tid;
  9086. -	
  9087. +
  9088.  	tid = acquire_timer();
  9089.  	timer_data[tid].tick     = tick;
  9090.  	timer_data[tid].func     = func;
  9091. @@ -267,7 +267,7 @@
  9092.  		ShowError("add_timer_interval: invalid interval (tick=%u %p[%s] id=%d data=%d diff_tick=%d)\n", tick, func, search_timer_func_list(func), id, data, DIFF_TICK(tick, gettick()));
  9093.  		return INVALID_TIMER;
  9094.  	}
  9095. -	
  9096. +
  9097.  	tid = acquire_timer();
  9098.  	timer_data[tid].tick     = tick;
  9099.  	timer_data[tid].func     = func;
  9100. @@ -320,7 +320,7 @@
  9101.  int settick_timer(int tid, unsigned int tick)
  9102.  {
  9103.  	size_t i;
  9104. -	
  9105. +
  9106.  	// search timer position
  9107.  	ARR_FIND(0, BHEAP_LENGTH(timer_heap), i, BHEAP_DATA(timer_heap)[i] == tid);
  9108.  	if( i == BHEAP_LENGTH(timer_heap) )
  9109. @@ -406,6 +406,16 @@
  9110.  	return (unsigned long)difftime(time(NULL), start_time);
  9111.  }
  9112.  
  9113. +//-----------------------------------------------------
  9114. +// custom timestamp formatting (from eApp)
  9115. +//-----------------------------------------------------
  9116. +const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format)
  9117. +{
  9118. +	size_t len = strftime(str, size, format, localtime(&timestamp));
  9119. +	memset(str + len, '\0', size - len);
  9120. +	return str;
  9121. +}
  9122. +
  9123.  void timer_init(void)
  9124.  {
  9125.  #if defined(ENABLE_RDTSC)
  9126. Index: src/common/timer.h
  9127. ===================================================================
  9128. --- src/common/timer.h	(revision 17367)
  9129. +++ src/common/timer.h	(working copy)
  9130. @@ -5,6 +5,7 @@
  9131.  #define	_TIMER_H_
  9132.  
  9133.  #include "../common/cbasetypes.h"
  9134. +#include <time.h>
  9135.  
  9136.  #define DIFF_TICK(a,b) ((int)((a)-(b)))
  9137.  
  9138. @@ -51,6 +52,9 @@
  9139.  
  9140.  unsigned long get_uptime(void);
  9141.  
  9142. +//transform a timestamp to string
  9143. +const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format);
  9144. +
  9145.  int do_timer(unsigned int tick);
  9146.  void timer_init(void);
  9147.  void timer_final(void);
  9148. Index: src/common/socket.c
  9149. ===================================================================
  9150. --- src/common/socket.c	(revision 17367)
  9151. +++ src/common/socket.c	(working copy)
  9152. @@ -18,7 +18,7 @@
  9153.  	#include "../common/winapi.h"
  9154.  #else
  9155.  	#include <errno.h>
  9156. -	#include <sys/socket.h>
  9157. +	#include <sys/select.h>
  9158.  	#include <netinet/in.h>
  9159.  	#include <netinet/tcp.h>
  9160.  	#include <net/if.h>
  9161. @@ -637,7 +637,7 @@
  9162.  /// advance the RFIFO cursor (marking 'len' bytes as processed)
  9163.  int RFIFOSKIP(int fd, size_t len)
  9164.  {
  9165. -    struct socket_data *s;
  9166. +	struct socket_data *s;
  9167.  
  9168.  	if ( !session_isActive(fd) )
  9169.  		return 0;
  9170. Index: conf/login_athena.conf
  9171. ===================================================================
  9172. --- conf/login_athena.conf	(revision 17367)
  9173. +++ conf/login_athena.conf	(working copy)
  9174. @@ -82,8 +82,21 @@
  9175.  check_client_version: no
  9176.  
  9177.  // What version we would allow to connect? (if the options above is enabled..)
  9178. -client_version_to_connect: 20
  9179. +client_version_to_connect: 30
  9180.  
  9181. +// Client MD5 hash check
  9182. +// If turned on, the login server will check if the client's hash matches
  9183. +// the value below, and will not connect tampered clients.
  9184. +// Note: see doc\md5_hashcheck.txt for more details.
  9185. +client_hash_check: no
  9186. +
  9187. +// Client MD5 hashes
  9188. +// A player can login with a client hash at or below the account group_id.
  9189. +// Format: group_id, hash
  9190. +client_hash: 0, 113e195e6c051bb1cfb12a644bb084c5
  9191. +client_hash: 98, cb1ea78023d337c38e8ba5124e2338ae
  9192. +client_hash: 99, any
  9193. +
  9194.  // Store passwords as MD5 hashes instead of plaintext ?
  9195.  // NOTE: Will not work with clients that use <passwordencrypt>
  9196.  use_MD5_passwords: no
  9197. @@ -145,17 +158,5 @@
  9198.  //account.sql.account_db: login
  9199.  //account.sql.accreg_db: global_reg_value
  9200.  
  9201. -// Client MD5 hash check
  9202. -// If turned on, the login server will check if the client's hash matches
  9203. -// the value below, and will not connect tampered clients.
  9204. -// Note: see doc\md5_hashcheck.txt for more details.
  9205. -client_hash_check: off
  9206. -
  9207. -// Client MD5 hashes
  9208. -// A player can login with a client hash at or below the account group_id.
  9209. -// Format: group_id, hash
  9210. -client_hash: 0, 113e195e6c051bb1cfb12a644bb084c5
  9211. -client_hash: 99, cb1ea78023d337c38e8ba5124e2338ae
  9212. -
  9213.  import: conf/inter_athena.conf
  9214.  import: conf/import/login_conf.txt
  9215.  
Viewed 2239 times, submitted by lighta.