diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/char/char.c | 29 | ||||
-rw-r--r-- | src/common/core.c | 7 | ||||
-rw-r--r-- | src/common/sql.c | 79 | ||||
-rw-r--r-- | src/common/sql.h | 6 | ||||
-rw-r--r-- | src/map/battle.c | 7 | ||||
-rw-r--r-- | src/map/clif.c | 5 | ||||
-rw-r--r-- | src/map/pc.c | 79 | ||||
-rw-r--r-- | src/map/skill.c | 5 | ||||
-rw-r--r-- | src/map/status.c | 5 |
9 files changed, 161 insertions, 61 deletions
diff --git a/src/char/char.c b/src/char/char.c index 83b58a0a7..d454e8bd0 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -3991,6 +3991,35 @@ int parse_char(int fd) return 0; RFIFOSKIP(fd,6); break; + // char rename request + // R 08fc <char ID>.l <new name>.24B + case 0x8fc: + FIFOSD_CHECK(30); + { + int i, cid =RFIFOL(fd,2); + char name[NAME_LENGTH]; + char esc_name[NAME_LENGTH*2+1]; + safestrncpy(name, (char *)RFIFOP(fd,6), NAME_LENGTH); + RFIFOSKIP(fd,30); + + ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == cid ); + if( i == MAX_CHARS ) + break; + + normalize_name(name,TRIM_CHARS); + Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH)); + if( !check_char_name(name,esc_name) ) { + i = 1; + safestrncpy(sd->new_name, name, NAME_LENGTH); + } else + i = 0; + + WFIFOHEAD(fd, 4); + WFIFOW(fd,0) = 0x28e; + WFIFOW(fd,2) = i; + WFIFOSET(fd,4); + } + break; // char rename request // R 028d <account ID>.l <char ID>.l <new name>.24B diff --git a/src/common/core.c b/src/common/core.c index 1e3dbb3d7..b1714b7a5 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #include "../common/mmo.h" #include "../common/showmsg.h" @@ -11,6 +12,7 @@ #include "../common/timer.h" #include "../common/thread.h" #include "../common/mempool.h" +#include "../common/sql.h" #endif #include <stdio.h> @@ -319,6 +321,7 @@ int main (int argc, char **argv) display_title(); usercheck(); + Sql_Init(); rathread_init(); mempool_init(); db_init(); diff --git a/src/common/sql.c b/src/common/sql.c index 800aa89b0..d00b51694 100644 --- a/src/common/sql.c +++ b/src/common/sql.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #include "../common/cbasetypes.h" #include "../common/malloc.h" @@ -15,7 +16,10 @@ #include <string.h>// strlen/strnlen/memcpy/memset #include <stdlib.h>// strtoul +void hercules_mysql_error_handler(unsigned int ecode); +int mysql_reconnect_type; +int mysql_reconnect_count; /// Sql handle struct Sql @@ -74,7 +78,7 @@ Sql* Sql_Malloc(void) self->lengths = NULL; self->result = NULL; self->keepalive = INVALID_TIMER; - + self->handle.reconnect = 1; return self; } @@ -266,12 +270,14 @@ int Sql_QueryV(Sql* self, const char* query, va_list args) if( mysql_real_query(&self->handle, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); + hercules_mysql_error_handler(mysql_errno(&self->handle)); return SQL_ERROR; } self->result = mysql_store_result(&self->handle); if( mysql_errno(&self->handle) != 0 ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); + hercules_mysql_error_handler(mysql_errno(&self->handle)); return SQL_ERROR; } return SQL_SUCCESS; @@ -291,12 +297,14 @@ int Sql_QueryStr(Sql* self, const char* query) if( mysql_real_query(&self->handle, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); + hercules_mysql_error_handler(mysql_errno(&self->handle)); return SQL_ERROR; } self->result = mysql_store_result(&self->handle); if( mysql_errno(&self->handle) != 0 ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); + hercules_mysql_error_handler(mysql_errno(&self->handle)); return SQL_ERROR; } return SQL_SUCCESS; @@ -639,6 +647,7 @@ int SqlStmt_PrepareV(SqlStmt* self, const char* query, va_list args) if( mysql_stmt_prepare(self->stmt, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); + hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } self->bind_params = false; @@ -660,6 +669,7 @@ int SqlStmt_PrepareStr(SqlStmt* self, const char* query) if( mysql_stmt_prepare(self->stmt, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); + hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } self->bind_params = false; @@ -721,12 +731,14 @@ int SqlStmt_Execute(SqlStmt* self) mysql_stmt_execute(self->stmt) ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); + hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } self->bind_columns = false; if( mysql_stmt_store_result(self->stmt) )// store all the data { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); + hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } @@ -868,6 +880,7 @@ int SqlStmt_NextRow(SqlStmt* self) if( err ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); + hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } @@ -946,3 +959,63 @@ void SqlStmt_Free(SqlStmt* self) aFree(self); } } +/* receives mysql error codes during runtime (not on first-time-connects) */ +void hercules_mysql_error_handler(unsigned int ecode) { + static unsigned int retry = 1; + switch( ecode ) { + case 2003:/* Can't connect to MySQL (this error only happens here when failing to reconnect) */ + if( mysql_reconnect_type == 1 ) { + if( ++retry > mysql_reconnect_count ) { + ShowFatalError("MySQL has been unreachable for too long, %d reconnects were attempted. Shutting Down\n", retry); + exit(EXIT_FAILURE); + } + } + break; + } +} +void Sql_inter_server_read(const char* cfgName, bool first) { + int i; + char line[1024], w1[1024], w2[1024]; + FILE* fp; + + fp = fopen(cfgName, "r"); + if(fp == NULL) { + if( first ) { + ShowFatalError("File not found: %s\n", cfgName); + exit(EXIT_FAILURE); + } else + ShowError("File not found: %s\n", cfgName); + return; + } + + while(fgets(line, sizeof(line), fp)) { + i = sscanf(line, "%[^:]: %[^\r\n]", w1, w2); + if(i != 2) + continue; + + if(!strcmpi(w1,"mysql_reconnect_type")) { + mysql_reconnect_type = atoi(w2); + switch( mysql_reconnect_type ) { + case 1: + case 2: + break; + default: + ShowError("%s::mysql_reconnect_type is set to %d which is not valid, defaulting to 1...\n", cfgName, mysql_reconnect_type); + mysql_reconnect_type = 1; + break; + } + } else if(!strcmpi(w1,"mysql_reconnect_count")) { + mysql_reconnect_count = atoi(w2); + if( mysql_reconnect_count < 1 ) + mysql_reconnect_count = 1; + } else if(!strcmpi(w1,"import")) + Sql_inter_server_read(w2,false); + } + fclose(fp); + + return; +} + +void Sql_Init(void) { + Sql_inter_server_read("conf/inter-server.conf",true); +} diff --git a/src/common/sql.h b/src/common/sql.h index 898e2c778..5ac92665e 100644 --- a/src/common/sql.h +++ b/src/common/sql.h @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #ifndef _COMMON_SQL_H_ #define _COMMON_SQL_H_ @@ -339,6 +340,7 @@ void SqlStmt_ShowDebug_(SqlStmt* self, const char* debug_file, const unsigned lo /// Frees a SqlStmt returned by SqlStmt_Malloc. void SqlStmt_Free(SqlStmt* self); +void Sql_Init(void); #endif /* _COMMON_SQL_H_ */ diff --git a/src/map/battle.c b/src/map/battle.c index 2198b25ec..4505b6a63 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -808,13 +808,12 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag * in RE, SW possesses a lifetime equal to 3 times the caster's health **/ #ifdef RENEWAL + d->dmg_lv = ATK_BLOCK; if ( ( group->val2 - damage) > 0 ) { group->val2 -= damage; - d->dmg_lv = ATK_BLOCK; - return 0; } else - damage -= group->val2; - skill_delunitgroup(group); + skill_delunitgroup(group); + return 0; #else if (--group->val2<=0) skill_delunitgroup(group); diff --git a/src/map/clif.c b/src/map/clif.c index f8b5119eb..e04941336 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -9358,6 +9358,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) } map_iwall_get(sd); // Updates Walls Info on this Map to Client + status_calc_pc(sd, false);/* some conditions are map-dependent so we must recalculate */ sd->state.changemap = false; } @@ -11112,13 +11113,13 @@ void clif_parse_NpcSelectMenu(int fd,struct map_session_data *sd) uint8 select = RFIFOB(fd,6); if( (select > sd->npc_menu && select != 0xff) || select == 0 ) { -#ifdef SECURE_NPCTIMEOUT +#if SECURE_NPCTIMEOUT if( sd->npc_idle_timer != INVALID_TIMER ) { #endif TBL_NPC* nd = map_id2nd(npc_id); ShowWarning("Invalid menu selection on npc %d:'%s' - got %d, valid range is [%d..%d] (player AID:%d, CID:%d, name:'%s')!\n", npc_id, (nd)?nd->name:"invalid npc id", select, 1, sd->npc_menu, sd->bl.id, sd->status.char_id, sd->status.name); clif_GM_kick(NULL,sd); -#ifdef SECURE_NPCTIMEOUT +#if SECURE_NPCTIMEOUT } #endif return; diff --git a/src/map/pc.c b/src/map/pc.c index abfbbcc12..49b905c0d 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #include "../common/cbasetypes.h" #include "../common/core.h" // get_svn_revision() @@ -700,24 +701,24 @@ int pc_setequipindex(struct map_session_data *sd) return 0; } +//static int pc_isAllowedCardOn(struct map_session_data *sd,int s,int eqindex,int flag) +//{ +// int i; +// struct item *item = &sd->status.inventory[eqindex]; +// struct item_data *data; +// +// //Crafted/made/hatched items. +// if (itemdb_isspecial(item->card[0])) +// return 1; +// +// /* scan for enchant armor gems */ +// if( item->card[MAX_SLOTS - 1] && s < MAX_SLOTS - 1 ) +// s = MAX_SLOTS - 1; +// +// ARR_FIND( 0, s, i, item->card[i] && (data = itemdb_exists(item->card[i])) != NULL && data->flag.no_equip&flag ); +// return( i < s ) ? 0 : 1; +//} -static int pc_isAllowedCardOn(struct map_session_data *sd,int s,int eqindex,int flag) -{ - int i; - struct item *item = &sd->status.inventory[eqindex]; - struct item_data *data; - - //Crafted/made/hatched items. - if (itemdb_isspecial(item->card[0])) - return 1; - - /* scan for enchant armor gems */ - if( item->card[MAX_SLOTS - 1] && s < MAX_SLOTS - 1 ) - s = MAX_SLOTS - 1; - - ARR_FIND( 0, s, i, item->card[i] && (data = itemdb_exists(item->card[i])) != NULL && data->flag.no_equip&flag ); - return( i < s ) ? 0 : 1; -} bool pc_isequipped(struct map_session_data *sd, int nameid) { @@ -860,18 +861,18 @@ int pc_isequip(struct map_session_data *sd,int n) #endif if(item->sex != 2 && sd->status.sex != item->sex) return 0; - if(!map_flag_vs(sd->bl.m) && ((item->flag.no_equip&1) || !pc_isAllowedCardOn(sd,item->slot,n,1))) + if(!map_flag_vs(sd->bl.m) && ((item->flag.no_equip&1))) return 0; - if(map[sd->bl.m].flag.pvp && ((item->flag.no_equip&2) || !pc_isAllowedCardOn(sd,item->slot,n,2))) + if(map[sd->bl.m].flag.pvp && ((item->flag.no_equip&2))) return 0; - if(map_flag_gvg(sd->bl.m) && ((item->flag.no_equip&4) || !pc_isAllowedCardOn(sd,item->slot,n,4))) + if(map_flag_gvg(sd->bl.m) && ((item->flag.no_equip&4))) return 0; - if(map[sd->bl.m].flag.battleground && ((item->flag.no_equip&8) || !pc_isAllowedCardOn(sd,item->slot,n,8))) + if(map[sd->bl.m].flag.battleground && ((item->flag.no_equip&8))) return 0; if(map[sd->bl.m].flag.restricted) { int flag =8*map[sd->bl.m].zone; - if (item->flag.no_equip&flag || !pc_isAllowedCardOn(sd,item->slot,n,flag)) + if (item->flag.no_equip&flag) return 0; } @@ -8618,33 +8619,27 @@ int pc_checkitem(struct map_session_data *sd) if( sd->state.vending ) //Avoid reorganizing items when we are vending, as that leads to exploits (pointed out by End of Exam) return 0; - if( battle_config.item_check ) - {// check for invalid(ated) items - for( i = 0; i < MAX_INVENTORY; i++ ) - { + if( battle_config.item_check ) { // check for invalid(ated) items + for( i = 0; i < MAX_INVENTORY; i++ ) { id = sd->status.inventory[i].nameid; - if( id && !itemdb_available(id) ) - { + if( id && !itemdb_available(id) ) { ShowWarning("Removed invalid/disabled item id %d from inventory (amount=%d, char_id=%d).\n", id, sd->status.inventory[i].amount, sd->status.char_id); pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER); } } - for( i = 0; i < MAX_CART; i++ ) - { + for( i = 0; i < MAX_CART; i++ ) { id = sd->status.cart[i].nameid; - if( id && !itemdb_available(id) ) - { + if( id && !itemdb_available(id) ) { ShowWarning("Removed invalid/disabled item id %d from cart (amount=%d, char_id=%d).\n", id, sd->status.cart[i].amount, sd->status.char_id); pc_cart_delitem(sd, i, sd->status.cart[i].amount, 0, LOG_TYPE_OTHER); } } } - for( i = 0; i < MAX_INVENTORY; i++) - { + for( i = 0; i < MAX_INVENTORY; i++) { it = sd->inventory_data[i]; if( sd->status.inventory[i].nameid == 0 ) @@ -8653,31 +8648,27 @@ int pc_checkitem(struct map_session_data *sd) if( !sd->status.inventory[i].equip ) continue; - if( sd->status.inventory[i].equip&~pc_equippoint(sd,i) ) - { + if( sd->status.inventory[i].equip&~pc_equippoint(sd,i) ) { pc_unequipitem(sd, i, 2); calc_flag = 1; continue; } - if( it ) - { // check for forbiden items. + if( it ) { // check for forbiden items. int flag = (map[sd->bl.m].flag.restricted?(8*map[sd->bl.m].zone):0) | (!map_flag_vs(sd->bl.m)?1:0) | (map[sd->bl.m].flag.pvp?2:0) | (map_flag_gvg(sd->bl.m)?4:0) | (map[sd->bl.m].flag.battleground?8:0); - if( flag && (it->flag.no_equip&flag || !pc_isAllowedCardOn(sd,it->slot,i,flag)) ) - { + if( flag && (it->flag.no_equip&flag) ) { pc_unequipitem(sd, i, 2); calc_flag = 1; } } } - if( calc_flag && sd->state.active ) - { + if( calc_flag && sd->state.active ) { pc_checkallowskill(sd); status_calc_pc(sd,0); } diff --git a/src/map/skill.c b/src/map/skill.c index 448f54406..f806c4ec5 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #include "../common/cbasetypes.h" #include "../common/timer.h" diff --git a/src/map/status.c b/src/map/status.c index 0379d05d2..8171f20ec 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules dev team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena dev team #include "../common/cbasetypes.h" #include "../common/timer.h" |