* Fixes to char-server.

- Removed unnecessary #includes from TXT and synchronized them with SQL.
- Fixed TXT having start Zeny of 500 instead of 0 by default (follow up to r4409 and r8420).
- Fixed TXT using 1024 instead of NAME_LENGTH for 'unknown_char_name' (follow up to r2191).
- Fixed SQL potentionally attempting to disconnect a player for account_id == 0 in changesex packet.
- Fixed SQL looking for option 'db_path' in 'inter_athena.conf' instead of 'char_athena.conf'.
- Fixed char select not sending a reply packet, when selected character was not found.
- Made use of safestrncpy instead of strcpy, strncpy and memset for copying strings where appropriate.
- Removed unused function 'chardb_final' in TXT (since r4878).
- Removed unnecessary WFIFOHEAD in char deletion in SQL (since r11245, related r9307 and r10909).

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@14618 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
ai4rei 2010-12-24 23:04:35 +00:00
parent a45a6400e3
commit adb8fd5aa3
3 changed files with 106 additions and 112 deletions

View File

@ -1,5 +1,16 @@
Date Added Date Added
2010/12/24
* Fixes to char-server. [Ai4rei]
- Removed unnecessary #includes from TXT and synchronized them with SQL.
- Fixed TXT having start Zeny of 500 instead of 0 by default (follow up to r4409 and r8420).
- Fixed TXT using 1024 instead of NAME_LENGTH for 'unknown_char_name' (follow up to r2191).
- Fixed SQL potentionally attempting to disconnect a player for account_id == 0 in changesex packet.
- Fixed SQL looking for option 'db_path' in 'inter_athena.conf' instead of 'char_athena.conf'.
- Fixed char select not sending a reply packet, when selected character was not found.
- Made use of safestrncpy instead of strcpy, strncpy and memset for copying strings where appropriate.
- Removed unused function 'chardb_final' in TXT (since r4878).
- Removed unnecessary WFIFOHEAD in char deletion in SQL (since r11245, related r9307 and r10909).
2010/12/23 2010/12/23
* Fixed server processing the sell list (deleting items and giving zeny) for script-controlled shops (OnSellItem), causing the controller script to fail (bugreport:4656, since r6557). [Ai4rei] * Fixed server processing the sell list (deleting items and giving zeny) for script-controlled shops (OnSellItem), causing the controller script to fail (bugreport:4656, since r6557). [Ai4rei]
- This also makes the server first check the sell list and only continue, if all items can be processed, thus no longer causing incomplete deals and the need for client disconnection in such case (since r6557). - This also makes the server first check the sell list and only continue, if all items can be processed, thus no longer causing incomplete deals and the need for client disconnection in such case (since r6557).

View File

@ -2,19 +2,16 @@
// For more information, see LICENCE in the main folder // For more information, see LICENCE in the main folder
#include "../common/cbasetypes.h" #include "../common/cbasetypes.h"
#include "../common/mmo.h" #include "../common/core.h"
#include "../common/db.h" #include "../common/db.h"
#include "../common/lock.h" #include "../common/lock.h"
#include "../common/malloc.h" #include "../common/malloc.h"
#include "../common/core.h" #include "../common/mapindex.h"
#include "../common/mmo.h"
#include "../common/showmsg.h"
#include "../common/socket.h" #include "../common/socket.h"
#include "../common/strlib.h" #include "../common/strlib.h"
#include "../common/showmsg.h"
#include "../common/timer.h" #include "../common/timer.h"
#include "../common/lock.h"
#include "../common/malloc.h"
#include "../common/mapindex.h"
#include "../common/showmsg.h"
#include "../common/utils.h" #include "../common/utils.h"
#include "../common/version.h" #include "../common/version.h"
#include "inter.h" #include "inter.h"
@ -27,16 +24,8 @@
#include "char.h" #include "char.h"
#include <sys/types.h> #include <sys/types.h>
#ifdef WIN32
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include <time.h> #include <time.h>
#include <signal.h> #include <signal.h>
#include <fcntl.h>
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
@ -85,7 +74,7 @@ int email_creation = 0; // disabled by default
bool name_ignoring_case = false; // Allow or not identical name for characters but with a different case by [Yor] bool name_ignoring_case = false; // Allow or not identical name for characters but with a different case by [Yor]
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] 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]
char unknown_char_name[1024] = "Unknown"; // Name to use when the requested name cannot be determined char unknown_char_name[NAME_LENGTH] = "Unknown"; // Name to use when the requested name cannot be determined
#define TRIM_CHARS "\032\t\x0A\x0D " //The following characters are trimmed regardless because they cause confusion and problems on the servers. [Skotlex] #define TRIM_CHARS "\032\t\x0A\x0D " //The following characters are trimmed regardless because they cause confusion and problems on the servers. [Skotlex]
char char_name_letters[1024] = ""; // list of letters/symbols authorised (or not) in a character name. by [Yor] char char_name_letters[1024] = ""; // list of letters/symbols authorised (or not) in a character name. by [Yor]
@ -118,7 +107,7 @@ int char_num, char_max;
int max_connect_user = 0; int max_connect_user = 0;
int gm_allow_level = 99; int gm_allow_level = 99;
int autosave_interval = DEFAULT_AUTOSAVE_INTERVAL; int autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
int start_zeny = 500; int start_zeny = 0;
int start_weapon = 1201; int start_weapon = 1201;
int start_armor = 2301; int start_armor = 2301;
int guild_exp_rate = 100; int guild_exp_rate = 100;
@ -678,7 +667,7 @@ int mmo_char_fromstr(char *str, struct mmo_charstatus *p, struct global_reg *reg
tmp_int[46] = mapindex_name2id(tmp_str[2]); tmp_int[46] = mapindex_name2id(tmp_str[2]);
} // Char structure of version 1500 (homun + mapindex maps) } // Char structure of version 1500 (homun + mapindex maps)
memcpy(p->name, tmp_str[0], NAME_LENGTH); //Overflow protection [Skotlex] safestrncpy(p->name, tmp_str[0], NAME_LENGTH); //Overflow protection [Skotlex]
p->char_id = tmp_int[0]; p->char_id = tmp_int[0];
p->account_id = tmp_int[1]; p->account_id = tmp_int[1];
p->slot = tmp_int[2]; p->slot = tmp_int[2];
@ -1561,7 +1550,7 @@ void create_online_files(void)
j = id[i]; j = id[i];
// displaying the character name // displaying the character name
if ((online_display_option & 1) || (online_display_option & 64)) { // without/with 'GM' display if ((online_display_option & 1) || (online_display_option & 64)) { // without/with 'GM' display
strcpy(temp, char_dat[j].status.name); safestrncpy(temp, char_dat[j].status.name, sizeof(temp));
//l = isGM(char_dat[j].status.account_id); //l = isGM(char_dat[j].status.account_id);
l = 0; //FIXME: how to get the gm level? l = 0; //FIXME: how to get the gm level?
if (online_display_option & 64) { if (online_display_option & 64) {
@ -1609,7 +1598,7 @@ void create_online_files(void)
// displaying of the map // displaying of the map
if (online_display_option & 24) { // 8 or 16 if (online_display_option & 24) { // 8 or 16
// prepare map name // prepare map name
memcpy(temp, mapindex_id2name(char_dat[j].status.last_point.map), MAP_NAME_LENGTH); safestrncpy(temp, mapindex_id2name(char_dat[j].status.last_point.map), sizeof(temp));
// write map name // write map name
if (online_display_option & 16) { // map-name AND coordinates if (online_display_option & 16) { // map-name AND coordinates
fprintf(fp2, " <td>%s (%d, %d)</td>\n", temp, char_dat[j].status.last_point.x, char_dat[j].status.last_point.y); fprintf(fp2, " <td>%s (%d, %d)</td>\n", temp, char_dat[j].status.last_point.x, char_dat[j].status.last_point.y);
@ -2105,7 +2094,7 @@ int parse_fromlogin(int fd)
RFIFOSKIP(fd,7); RFIFOSKIP(fd,7);
if( acc > 0 ) if( acc > 0 )
{ {// TODO: Is this even possible?
struct auth_node* node = (struct auth_node*)idb_get(auth_db, acc); struct auth_node* node = (struct auth_node*)idb_get(auth_db, acc);
if( node != NULL ) if( node != NULL )
node->sex = sex; node->sex = sex;
@ -2496,7 +2485,7 @@ void char_read_fame_list(void)
{ {
fame_item.id = char_dat[id[i]].status.char_id; fame_item.id = char_dat[id[i]].status.char_id;
fame_item.fame = char_dat[id[i]].status.fame; fame_item.fame = char_dat[id[i]].status.fame;
strncpy(fame_item.name, char_dat[id[i]].status.name, NAME_LENGTH); safestrncpy(fame_item.name, char_dat[id[i]].status.name, NAME_LENGTH);
memcpy(&smith_fame_list[j],&fame_item,sizeof(struct fame_list)); memcpy(&smith_fame_list[j],&fame_item,sizeof(struct fame_list));
j++; j++;
@ -2511,7 +2500,7 @@ void char_read_fame_list(void)
{ {
fame_item.id = char_dat[id[i]].status.char_id; fame_item.id = char_dat[id[i]].status.char_id;
fame_item.fame = char_dat[id[i]].status.fame; fame_item.fame = char_dat[id[i]].status.fame;
strncpy(fame_item.name, char_dat[id[i]].status.name, NAME_LENGTH); safestrncpy(fame_item.name, char_dat[id[i]].status.name, NAME_LENGTH);
memcpy(&chemist_fame_list[j],&fame_item,sizeof(struct fame_list)); memcpy(&chemist_fame_list[j],&fame_item,sizeof(struct fame_list));
@ -2525,7 +2514,7 @@ void char_read_fame_list(void)
{ {
fame_item.id = char_dat[id[i]].status.char_id; fame_item.id = char_dat[id[i]].status.char_id;
fame_item.fame = char_dat[id[i]].status.fame; fame_item.fame = char_dat[id[i]].status.fame;
strncpy(fame_item.name, char_dat[id[i]].status.name, NAME_LENGTH); safestrncpy(fame_item.name, char_dat[id[i]].status.name, NAME_LENGTH);
memcpy(&taekwon_fame_list[j],&fame_item,sizeof(struct fame_list)); memcpy(&taekwon_fame_list[j],&fame_item,sizeof(struct fame_list));
@ -2589,9 +2578,9 @@ int char_loadName(int char_id, char* name)
for( j = 0; j < char_num && char_dat[j].status.char_id != char_id; ++j ) for( j = 0; j < char_num && char_dat[j].status.char_id != char_id; ++j )
;// find char ;// find char
if( j < char_num ) if( j < char_num )
strncpy(name, char_dat[j].status.name, NAME_LENGTH); safestrncpy(name, char_dat[j].status.name, NAME_LENGTH);
else else
strncpy(name, unknown_char_name, NAME_LENGTH); safestrncpy(name, unknown_char_name, NAME_LENGTH);
return (j < char_num) ? 1 : 0; return (j < char_num) ? 1 : 0;
} }
@ -3375,6 +3364,10 @@ int parse_char(int fd)
ARR_FIND( 0, MAX_CHARS, ch, sd->found_char[ch] >= 0 && char_dat[sd->found_char[ch]].status.slot == slot ); ARR_FIND( 0, MAX_CHARS, ch, sd->found_char[ch] >= 0 && char_dat[sd->found_char[ch]].status.slot == slot );
if (ch == MAX_CHARS) if (ch == MAX_CHARS)
{ //Not found?? May be forged packet. { //Not found?? May be forged packet.
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x6c;
WFIFOB(fd,2) = 0; // rejected from server
WFIFOSET(fd,3);
break; break;
} }
cd = &char_dat[sd->found_char[ch]].status; cd = &char_dat[sd->found_char[ch]].status;
@ -3522,7 +3515,7 @@ int parse_char(int fd)
RFIFOSKIP(fd,RFIFOREST(fd)); // hack to make the other deletion packet work RFIFOSKIP(fd,RFIFOREST(fd)); // hack to make the other deletion packet work
if (e_mail_check(email) == 0) if (e_mail_check(email) == 0)
strncpy(email, "a@a.com", 40); // default e-mail safestrncpy(email, "a@a.com", sizeof(email)); // default e-mail
// BEGIN HACK: "change email using the char deletion 'confirm email' menu" // BEGIN HACK: "change email using the char deletion 'confirm email' menu"
// if we activated email creation and email is default email // if we activated email creation and email is default email
@ -4026,7 +4019,7 @@ int char_config_read(const char *cfgName)
remove_control_chars(w1); remove_control_chars(w1);
remove_control_chars(w2); remove_control_chars(w2);
if(strcmpi(w1,"timestamp_format") == 0) { if(strcmpi(w1,"timestamp_format") == 0) {
strncpy(timestamp_format, w2, 20); safestrncpy(timestamp_format, w2, sizeof(timestamp_format));
} else if(strcmpi(w1,"console_silent")==0){ } else if(strcmpi(w1,"console_silent")==0){
ShowInfo("Console Silent Setting: %d\n", atoi(w2)); ShowInfo("Console Silent Setting: %d\n", atoi(w2));
msg_silent = atoi(w2); msg_silent = atoi(w2);
@ -4034,23 +4027,21 @@ int char_config_read(const char *cfgName)
} else if(strcmpi(w1,"stdout_with_ansisequence")==0){ } else if(strcmpi(w1,"stdout_with_ansisequence")==0){
stdout_with_ansisequence = config_switch(w2); stdout_with_ansisequence = config_switch(w2);
} else if (strcmpi(w1, "userid") == 0) { } else if (strcmpi(w1, "userid") == 0) {
strncpy(userid, w2, 24); safestrncpy(userid, w2, sizeof(userid));
} else if (strcmpi(w1, "passwd") == 0) { } else if (strcmpi(w1, "passwd") == 0) {
strncpy(passwd, w2, 24); safestrncpy(passwd, w2, sizeof(passwd));
} else if (strcmpi(w1, "server_name") == 0) { } else if (strcmpi(w1, "server_name") == 0) {
strncpy(server_name, w2, 20); safestrncpy(server_name, w2, sizeof(server_name));
server_name[sizeof(server_name) - 1] = '\0';
ShowStatus("%s server has been initialized\n", w2); ShowStatus("%s server has been initialized\n", w2);
} else if (strcmpi(w1, "wisp_server_name") == 0) { } else if (strcmpi(w1, "wisp_server_name") == 0) {
if (strlen(w2) >= 4) { if (strlen(w2) >= 4) {
memcpy(wisp_server_name, w2, sizeof(wisp_server_name)); safestrncpy(wisp_server_name, w2, sizeof(wisp_server_name));
wisp_server_name[sizeof(wisp_server_name) - 1] = '\0';
} }
} else if (strcmpi(w1, "login_ip") == 0) { } else if (strcmpi(w1, "login_ip") == 0) {
char ip_str[16]; char ip_str[16];
login_ip = host2ip(w2); login_ip = host2ip(w2);
if (login_ip) { if (login_ip) {
strncpy(login_ip_str, w2, sizeof(login_ip_str)); safestrncpy(login_ip_str, w2, sizeof(login_ip_str));
ShowStatus("Login server IP address : %s -> %s\n", w2, ip2str(login_ip, ip_str)); ShowStatus("Login server IP address : %s -> %s\n", w2, ip2str(login_ip, ip_str));
} }
} else if (strcmpi(w1, "login_port") == 0) { } else if (strcmpi(w1, "login_port") == 0) {
@ -4059,14 +4050,14 @@ int char_config_read(const char *cfgName)
char ip_str[16]; char ip_str[16];
char_ip = host2ip(w2); char_ip = host2ip(w2);
if (char_ip){ if (char_ip){
strncpy(char_ip_str, w2, sizeof(char_ip_str)); safestrncpy(char_ip_str, w2, sizeof(char_ip_str));
ShowStatus("Character server IP address : %s -> %s\n", w2, ip2str(char_ip, ip_str)); ShowStatus("Character server IP address : %s -> %s\n", w2, ip2str(char_ip, ip_str));
} }
} else if (strcmpi(w1, "bind_ip") == 0) { } else if (strcmpi(w1, "bind_ip") == 0) {
char ip_str[16]; char ip_str[16];
bind_ip = host2ip(w2); bind_ip = host2ip(w2);
if (bind_ip) { if (bind_ip) {
strncpy(bind_ip_str, w2, sizeof(bind_ip_str)); safestrncpy(bind_ip_str, w2, sizeof(bind_ip_str));
ShowStatus("Character server binding IP address : %s -> %s\n", w2, ip2str(bind_ip, ip_str)); ShowStatus("Character server binding IP address : %s -> %s\n", w2, ip2str(bind_ip, ip_str));
} }
} else if (strcmpi(w1, "char_port") == 0) { } else if (strcmpi(w1, "char_port") == 0) {
@ -4080,14 +4071,14 @@ int char_config_read(const char *cfgName)
} else if (strcmpi(w1, "email_creation") == 0) { } else if (strcmpi(w1, "email_creation") == 0) {
email_creation = config_switch(w2); email_creation = config_switch(w2);
} else if (strcmpi(w1, "scdata_txt") == 0) { //By Skotlex } else if (strcmpi(w1, "scdata_txt") == 0) { //By Skotlex
strcpy(scdata_txt, w2); safestrncpy(scdata_txt, w2, sizeof(scdata_txt));
#endif #endif
} else if (strcmpi(w1, "char_txt") == 0) { } else if (strcmpi(w1, "char_txt") == 0) {
strcpy(char_txt, w2); safestrncpy(char_txt, w2, sizeof(char_txt));
} else if (strcmpi(w1, "friends_txt") == 0) { //By davidsiaw } else if (strcmpi(w1, "friends_txt") == 0) { //By davidsiaw
strcpy(friends_txt, w2); safestrncpy(friends_txt, w2, sizeof(friends_txt));
} else if (strcmpi(w1, "hotkeys_txt") == 0) { //By davidsiaw } else if (strcmpi(w1, "hotkeys_txt") == 0) { //By davidsiaw
strcpy(hotkeys_txt, w2); safestrncpy(hotkeys_txt, w2, sizeof(hotkeys_txt));
#ifndef TXT_SQL_CONVERT #ifndef TXT_SQL_CONVERT
} else if (strcmpi(w1, "max_connect_user") == 0) { } else if (strcmpi(w1, "max_connect_user") == 0) {
max_connect_user = atoi(w2); max_connect_user = atoi(w2);
@ -4130,21 +4121,21 @@ int char_config_read(const char *cfgName)
} else if(strcmpi(w1,"log_char")==0) { //log char or not [devil] } else if(strcmpi(w1,"log_char")==0) { //log char or not [devil]
log_char = atoi(w2); log_char = atoi(w2);
} else if (strcmpi(w1, "unknown_char_name") == 0) { } else if (strcmpi(w1, "unknown_char_name") == 0) {
strcpy(unknown_char_name, w2); safestrncpy(unknown_char_name, w2, sizeof(unknown_char_name));
unknown_char_name[NAME_LENGTH-1] = '\0'; unknown_char_name[NAME_LENGTH-1] = '\0';
} else if (strcmpi(w1, "char_log_filename") == 0) { } else if (strcmpi(w1, "char_log_filename") == 0) {
strcpy(char_log_filename, w2); safestrncpy(char_log_filename, w2, sizeof(char_log_filename));
} else if (strcmpi(w1, "name_ignoring_case") == 0) { } else if (strcmpi(w1, "name_ignoring_case") == 0) {
name_ignoring_case = (bool)config_switch(w2); name_ignoring_case = (bool)config_switch(w2);
} else if (strcmpi(w1, "char_name_option") == 0) { } else if (strcmpi(w1, "char_name_option") == 0) {
char_name_option = atoi(w2); char_name_option = atoi(w2);
} else if (strcmpi(w1, "char_name_letters") == 0) { } else if (strcmpi(w1, "char_name_letters") == 0) {
strcpy(char_name_letters, w2); safestrncpy(char_name_letters, w2, sizeof(char_name_letters));
// online files options // online files options
} else if (strcmpi(w1, "online_txt_filename") == 0) { } else if (strcmpi(w1, "online_txt_filename") == 0) {
strcpy(online_txt_filename, w2); safestrncpy(online_txt_filename, w2, sizeof(online_txt_filename));
} else if (strcmpi(w1, "online_html_filename") == 0) { } else if (strcmpi(w1, "online_html_filename") == 0) {
strcpy(online_html_filename, w2); safestrncpy(online_html_filename, w2, sizeof(online_html_filename));
} else if (strcmpi(w1, "online_sorting_option") == 0) { } else if (strcmpi(w1, "online_sorting_option") == 0) {
online_sorting_option = atoi(w2); online_sorting_option = atoi(w2);
} else if (strcmpi(w1, "online_display_option") == 0) { } else if (strcmpi(w1, "online_display_option") == 0) {
@ -4158,7 +4149,7 @@ int char_config_read(const char *cfgName)
if (online_refresh_html < 1) if (online_refresh_html < 1)
online_refresh_html = 1; online_refresh_html = 1;
} else if(strcmpi(w1,"db_path")==0) { } else if(strcmpi(w1,"db_path")==0) {
strcpy(db_path,w2); safestrncpy(db_path, w2, sizeof(db_path));
} else if (strcmpi(w1, "console") == 0) { } else if (strcmpi(w1, "console") == 0) {
console = config_switch(w2); console = config_switch(w2);
} else if (strcmpi(w1, "fame_list_alchemist") == 0) { } else if (strcmpi(w1, "fame_list_alchemist") == 0) {
@ -4193,11 +4184,6 @@ int char_config_read(const char *cfgName)
} }
#ifndef TXT_SQL_CONVERT #ifndef TXT_SQL_CONVERT
int chardb_final(int key, void* data, va_list va)
{
aFree(data);
return 0;
}
void do_final(void) void do_final(void)
{ {
ShowStatus("Terminating server.\n"); ShowStatus("Terminating server.\n");
@ -4292,11 +4278,11 @@ int do_init(int argc, char **argv)
else else
ShowStatus("Defaulting to %s as our IP address\n", ip_str); ShowStatus("Defaulting to %s as our IP address\n", ip_str);
if (!login_ip) { if (!login_ip) {
strcpy(login_ip_str, ip_str); safestrncpy(login_ip_str, ip_str, sizeof(login_ip_str));
login_ip = str2ip(login_ip_str); login_ip = str2ip(login_ip_str);
} }
if (!char_ip) { if (!char_ip) {
strcpy(char_ip_str, ip_str); safestrncpy(char_ip_str, ip_str, sizeof(char_ip_str));
char_ip = str2ip(char_ip_str); char_ip = str2ip(char_ip_str);
} }
} }

View File

@ -2,17 +2,17 @@
// For more information, see LICENCE in the main folder // For more information, see LICENCE in the main folder
#include "../common/cbasetypes.h" #include "../common/cbasetypes.h"
#include "../common/strlib.h"
#include "../common/core.h" #include "../common/core.h"
#include "../common/timer.h"
#include "../common/mmo.h"
#include "../common/db.h" #include "../common/db.h"
#include "../common/malloc.h" #include "../common/malloc.h"
#include "../common/mapindex.h" #include "../common/mapindex.h"
#include "../common/mmo.h"
#include "../common/showmsg.h" #include "../common/showmsg.h"
#include "../common/socket.h" #include "../common/socket.h"
#include "../common/version.h" #include "../common/strlib.h"
#include "../common/timer.h"
#include "../common/utils.h" #include "../common/utils.h"
#include "../common/version.h"
#include "inter.h" #include "inter.h"
#include "int_guild.h" #include "int_guild.h"
#include "int_homun.h" #include "int_homun.h"
@ -1879,7 +1879,7 @@ int parse_fromlogin(int fd)
RFIFOSKIP(fd,7); RFIFOSKIP(fd,7);
if( acc > 0 ) if( acc > 0 )
{ {// TODO: Is this even possible?
int char_id[MAX_CHARS]; int char_id[MAX_CHARS];
int class_[MAX_CHARS]; int class_[MAX_CHARS];
int guild_id[MAX_CHARS]; int guild_id[MAX_CHARS];
@ -1933,12 +1933,12 @@ int parse_fromlogin(int fd)
inter_guild_sex_changed(guild_id[i], acc, char_id[i], sex); inter_guild_sex_changed(guild_id[i], acc, char_id[i], sex);
} }
Sql_FreeResult(sql_handle); Sql_FreeResult(sql_handle);
}
// disconnect player if online on char-server // disconnect player if online on char-server
ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == acc ); ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == acc );
if( i < fd_max ) if( i < fd_max )
set_eof(i); set_eof(i);
}
// notify all mapservers about this change // notify all mapservers about this change
WBUFW(buf,0) = 0x2b0d; WBUFW(buf,0) = 0x2b0d;
@ -2203,13 +2203,12 @@ int char_loadName(int char_id, char* name)
else if( SQL_SUCCESS == Sql_NextRow(sql_handle) ) else if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
{ {
Sql_GetData(sql_handle, 0, &data, &len); Sql_GetData(sql_handle, 0, &data, &len);
memset(name, 0, NAME_LENGTH); safestrncpy(name, data, NAME_LENGTH);
memcpy(name, data, min(len, NAME_LENGTH));
return 1; return 1;
} }
else else
{ {
memcpy(name, unknown_char_name, NAME_LENGTH); safestrncpy(name, unknown_char_name, NAME_LENGTH);
} }
return 0; return 0;
} }
@ -3081,7 +3080,10 @@ int parse_char(int fd)
//Not found?? May be forged packet. //Not found?? May be forged packet.
Sql_ShowDebug(sql_handle); Sql_ShowDebug(sql_handle);
Sql_FreeResult(sql_handle); Sql_FreeResult(sql_handle);
//TODO: perhaps add some reply? (otherwise it hangs the client) WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x6c;
WFIFOB(fd,2) = 0; // rejected from server
WFIFOSET(fd,3);
break; break;
} }
@ -3246,7 +3248,6 @@ int parse_char(int fd)
{ {
int cid = RFIFOL(fd,2); int cid = RFIFOL(fd,2);
WFIFOHEAD(fd,46);
ShowInfo(CL_RED"Request Char Deletion: "CL_GREEN"%d (%d)"CL_RESET"\n", sd->account_id, cid); ShowInfo(CL_RED"Request Char Deletion: "CL_GREEN"%d (%d)"CL_RESET"\n", sd->account_id, cid);
memcpy(email, RFIFOP(fd,6), 40); memcpy(email, RFIFOP(fd,6), 40);
RFIFOSKIP(fd,RFIFOREST(fd)); // hack to make the other deletion packet work RFIFOSKIP(fd,RFIFOREST(fd)); // hack to make the other deletion packet work
@ -3751,59 +3752,55 @@ void sql_config_read(const char* cfgName)
continue; continue;
if(!strcmpi(w1,"char_db")) if(!strcmpi(w1,"char_db"))
strcpy(char_db,w2); safestrncpy(char_db, w2, sizeof(char_db));
else if(!strcmpi(w1,"scdata_db")) else if(!strcmpi(w1,"scdata_db"))
strcpy(scdata_db,w2); safestrncpy(scdata_db, w2, sizeof(scdata_db));
else if(!strcmpi(w1,"cart_db")) else if(!strcmpi(w1,"cart_db"))
strcpy(cart_db,w2); safestrncpy(cart_db, w2, sizeof(cart_db));
else if(!strcmpi(w1,"inventory_db")) else if(!strcmpi(w1,"inventory_db"))
strcpy(inventory_db, w2); safestrncpy(inventory_db, w2, sizeof(inventory_db));
else if(!strcmpi(w1,"charlog_db")) else if(!strcmpi(w1,"charlog_db"))
strcpy(charlog_db,w2); safestrncpy(charlog_db, w2, sizeof(charlog_db));
else if(!strcmpi(w1,"storage_db")) else if(!strcmpi(w1,"storage_db"))
strcpy(storage_db,w2); safestrncpy(storage_db, w2, sizeof(storage_db));
else if(!strcmpi(w1,"reg_db")) else if(!strcmpi(w1,"reg_db"))
strcpy(reg_db,w2); safestrncpy(reg_db, w2, sizeof(reg_db));
else if(!strcmpi(w1,"skill_db")) else if(!strcmpi(w1,"skill_db"))
strcpy(skill_db,w2); safestrncpy(skill_db, w2, sizeof(skill_db));
else if(!strcmpi(w1,"interlog_db")) else if(!strcmpi(w1,"interlog_db"))
strcpy(interlog_db,w2); safestrncpy(interlog_db, w2, sizeof(interlog_db));
else if(!strcmpi(w1,"memo_db")) else if(!strcmpi(w1,"memo_db"))
strcpy(memo_db,w2); safestrncpy(memo_db, w2, sizeof(memo_db));
else if(!strcmpi(w1,"guild_db")) else if(!strcmpi(w1,"guild_db"))
strcpy(guild_db,w2); safestrncpy(guild_db, w2, sizeof(guild_db));
else if(!strcmpi(w1,"guild_alliance_db")) else if(!strcmpi(w1,"guild_alliance_db"))
strcpy(guild_alliance_db,w2); safestrncpy(guild_alliance_db, w2, sizeof(guild_alliance_db));
else if(!strcmpi(w1,"guild_castle_db")) else if(!strcmpi(w1,"guild_castle_db"))
strcpy(guild_castle_db,w2); safestrncpy(guild_castle_db, w2, sizeof(guild_castle_db));
else if(!strcmpi(w1,"guild_expulsion_db")) else if(!strcmpi(w1,"guild_expulsion_db"))
strcpy(guild_expulsion_db,w2); safestrncpy(guild_expulsion_db, w2, sizeof(guild_expulsion_db));
else if(!strcmpi(w1,"guild_member_db")) else if(!strcmpi(w1,"guild_member_db"))
strcpy(guild_member_db,w2); safestrncpy(guild_member_db, w2, sizeof(guild_member_db));
else if(!strcmpi(w1,"guild_skill_db")) else if(!strcmpi(w1,"guild_skill_db"))
strcpy(guild_skill_db,w2); safestrncpy(guild_skill_db, w2, sizeof(guild_skill_db));
else if(!strcmpi(w1,"guild_position_db")) else if(!strcmpi(w1,"guild_position_db"))
strcpy(guild_position_db,w2); safestrncpy(guild_position_db, w2, sizeof(guild_position_db));
else if(!strcmpi(w1,"guild_storage_db")) else if(!strcmpi(w1,"guild_storage_db"))
strcpy(guild_storage_db,w2); safestrncpy(guild_storage_db, w2, sizeof(guild_storage_db));
else if(!strcmpi(w1,"party_db")) else if(!strcmpi(w1,"party_db"))
strcpy(party_db,w2); safestrncpy(party_db, w2, sizeof(party_db));
else if(!strcmpi(w1,"pet_db")) else if(!strcmpi(w1,"pet_db"))
strcpy(pet_db,w2); safestrncpy(pet_db, w2, sizeof(pet_db));
else if(!strcmpi(w1,"mail_db")) else if(!strcmpi(w1,"mail_db"))
strcpy(mail_db,w2); safestrncpy(mail_db, w2, sizeof(mail_db));
else if(!strcmpi(w1,"auction_db")) else if(!strcmpi(w1,"auction_db"))
strcpy(auction_db,w2); safestrncpy(auction_db, w2, sizeof(auction_db));
else if(!strcmpi(w1,"friend_db")) else if(!strcmpi(w1,"friend_db"))
strcpy(friend_db,w2); safestrncpy(friend_db, w2, sizeof(friend_db));
else if(!strcmpi(w1,"hotkey_db")) else if(!strcmpi(w1,"hotkey_db"))
strcpy(hotkey_db,w2); safestrncpy(hotkey_db, w2, sizeof(hotkey_db));
else if(!strcmpi(w1,"quest_db")) else if(!strcmpi(w1,"quest_db"))
strcpy(quest_db,w2); safestrncpy(quest_db,w2,sizeof(quest_db));
#ifndef TXT_SQL_CONVERT
else if(!strcmpi(w1,"db_path"))
strcpy(db_path,w2);
#endif
//support the import command, just like any other config //support the import command, just like any other config
else if(!strcmpi(w1,"import")) else if(!strcmpi(w1,"import"))
sql_config_read(w2); sql_config_read(w2);
@ -3835,30 +3832,28 @@ int char_config_read(const char* cfgName)
remove_control_chars(w1); remove_control_chars(w1);
remove_control_chars(w2); remove_control_chars(w2);
if(strcmpi(w1,"timestamp_format") == 0) { if(strcmpi(w1,"timestamp_format") == 0) {
strncpy(timestamp_format, w2, 20); safestrncpy(timestamp_format, w2, sizeof(timestamp_format));
} else if(strcmpi(w1,"console_silent")==0){ } else if(strcmpi(w1,"console_silent")==0){
ShowInfo("Console Silent Setting: %d\n", atoi(w2)); ShowInfo("Console Silent Setting: %d\n", atoi(w2));
msg_silent = atoi(w2); msg_silent = atoi(w2);
} else if(strcmpi(w1,"stdout_with_ansisequence")==0){ } else if(strcmpi(w1,"stdout_with_ansisequence")==0){
stdout_with_ansisequence = config_switch(w2); stdout_with_ansisequence = config_switch(w2);
} else if (strcmpi(w1, "userid") == 0) { } else if (strcmpi(w1, "userid") == 0) {
strncpy(userid, w2, 24); safestrncpy(userid, w2, sizeof(userid));
} else if (strcmpi(w1, "passwd") == 0) { } else if (strcmpi(w1, "passwd") == 0) {
strncpy(passwd, w2, 24); safestrncpy(passwd, w2, sizeof(passwd));
} else if (strcmpi(w1, "server_name") == 0) { } else if (strcmpi(w1, "server_name") == 0) {
strncpy(server_name, w2, 20); safestrncpy(server_name, w2, sizeof(server_name));
server_name[sizeof(server_name) - 1] = '\0';
ShowStatus("%s server has been initialized\n", w2); ShowStatus("%s server has been initialized\n", w2);
} else if (strcmpi(w1, "wisp_server_name") == 0) { } else if (strcmpi(w1, "wisp_server_name") == 0) {
if (strlen(w2) >= 4) { if (strlen(w2) >= 4) {
memcpy(wisp_server_name, w2, sizeof(wisp_server_name)); safestrncpy(wisp_server_name, w2, sizeof(wisp_server_name));
wisp_server_name[sizeof(wisp_server_name) - 1] = '\0';
} }
} else if (strcmpi(w1, "login_ip") == 0) { } else if (strcmpi(w1, "login_ip") == 0) {
char ip_str[16]; char ip_str[16];
login_ip = host2ip(w2); login_ip = host2ip(w2);
if (login_ip) { if (login_ip) {
strncpy(login_ip_str, w2, sizeof(login_ip_str)); safestrncpy(login_ip_str, w2, sizeof(login_ip_str));
ShowStatus("Login server IP address : %s -> %s\n", w2, ip2str(login_ip, ip_str)); ShowStatus("Login server IP address : %s -> %s\n", w2, ip2str(login_ip, ip_str));
} }
} else if (strcmpi(w1, "login_port") == 0) { } else if (strcmpi(w1, "login_port") == 0) {
@ -3867,14 +3862,14 @@ int char_config_read(const char* cfgName)
char ip_str[16]; char ip_str[16];
char_ip = host2ip(w2); char_ip = host2ip(w2);
if (char_ip){ if (char_ip){
strncpy(char_ip_str, w2, sizeof(char_ip_str)); safestrncpy(char_ip_str, w2, sizeof(char_ip_str));
ShowStatus("Character server IP address : %s -> %s\n", w2, ip2str(char_ip, ip_str)); ShowStatus("Character server IP address : %s -> %s\n", w2, ip2str(char_ip, ip_str));
} }
} else if (strcmpi(w1, "bind_ip") == 0) { } else if (strcmpi(w1, "bind_ip") == 0) {
char ip_str[16]; char ip_str[16];
bind_ip = host2ip(w2); bind_ip = host2ip(w2);
if (bind_ip) { if (bind_ip) {
strncpy(bind_ip_str, w2, sizeof(bind_ip_str)); safestrncpy(bind_ip_str, w2, sizeof(bind_ip_str));
ShowStatus("Character server binding IP address : %s -> %s\n", w2, ip2str(bind_ip, ip_str)); ShowStatus("Character server binding IP address : %s -> %s\n", w2, ip2str(bind_ip, ip_str));
} }
} else if (strcmpi(w1, "char_port") == 0) { } else if (strcmpi(w1, "char_port") == 0) {
@ -3924,18 +3919,20 @@ int char_config_read(const char* cfgName)
} else if(strcmpi(w1,"log_char")==0) { //log char or not [devil] } else if(strcmpi(w1,"log_char")==0) { //log char or not [devil]
log_char = atoi(w2); log_char = atoi(w2);
} else if (strcmpi(w1, "unknown_char_name") == 0) { } else if (strcmpi(w1, "unknown_char_name") == 0) {
strcpy(unknown_char_name, w2); safestrncpy(unknown_char_name, w2, sizeof(unknown_char_name));
unknown_char_name[NAME_LENGTH-1] = '\0'; unknown_char_name[NAME_LENGTH-1] = '\0';
} else if (strcmpi(w1, "name_ignoring_case") == 0) { } else if (strcmpi(w1, "name_ignoring_case") == 0) {
name_ignoring_case = config_switch(w2); name_ignoring_case = config_switch(w2);
} else if (strcmpi(w1, "char_name_option") == 0) { } else if (strcmpi(w1, "char_name_option") == 0) {
char_name_option = atoi(w2); char_name_option = atoi(w2);
} else if (strcmpi(w1, "char_name_letters") == 0) { } else if (strcmpi(w1, "char_name_letters") == 0) {
strcpy(char_name_letters, w2); safestrncpy(char_name_letters, w2, sizeof(char_name_letters));
} else if (strcmpi(w1, "chars_per_account") == 0) { //maxchars per account [Sirius] } else if (strcmpi(w1, "chars_per_account") == 0) { //maxchars per account [Sirius]
char_per_account = atoi(w2); char_per_account = atoi(w2);
} else if (strcmpi(w1, "char_del_level") == 0) { //disable/enable char deletion by its level condition [Lupus] } else if (strcmpi(w1, "char_del_level") == 0) { //disable/enable char deletion by its level condition [Lupus]
char_del_level = atoi(w2); char_del_level = atoi(w2);
} else if(strcmpi(w1,"db_path")==0) {
safestrncpy(db_path, w2, sizeof(db_path));
} else if (strcmpi(w1, "console") == 0) { } else if (strcmpi(w1, "console") == 0) {
console = config_switch(w2); console = config_switch(w2);
} else if (strcmpi(w1, "fame_list_alchemist") == 0) { } else if (strcmpi(w1, "fame_list_alchemist") == 0) {
@ -4059,11 +4056,11 @@ int do_init(int argc, char **argv)
else else
ShowStatus("Defaulting to %s as our IP address\n", ip_str); ShowStatus("Defaulting to %s as our IP address\n", ip_str);
if (!login_ip) { if (!login_ip) {
strcpy(login_ip_str, ip_str); safestrncpy(login_ip_str, ip_str, sizeof(login_ip_str));
login_ip = str2ip(login_ip_str); login_ip = str2ip(login_ip_str);
} }
if (!char_ip) { if (!char_ip) {
strcpy(char_ip_str, ip_str); safestrncpy(char_ip_str, ip_str, sizeof(char_ip_str));
char_ip = str2ip(char_ip_str); char_ip = str2ip(char_ip_str);
} }
} }