diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/ers.c | 2 | ||||
-rw-r--r-- | src/config/const.h | 7 | ||||
-rw-r--r-- | src/map/battle.c | 5 | ||||
-rw-r--r-- | src/map/battle.h | 1 | ||||
-rw-r--r-- | src/map/clif.c | 77 | ||||
-rw-r--r-- | src/map/clif.h | 4 | ||||
-rw-r--r-- | src/map/itemdb.c | 86 | ||||
-rw-r--r-- | src/map/itemdb.h | 17 | ||||
-rw-r--r-- | src/map/map.c | 2 | ||||
-rw-r--r-- | src/map/packets.h | 8 | ||||
-rw-r--r-- | src/map/pc.h | 3 | ||||
-rw-r--r-- | src/map/script.c | 13 | ||||
-rw-r--r-- | src/map/script.h | 1 | ||||
-rw-r--r-- | src/plugins/Makefile.in | 6 | ||||
-rw-r--r-- | src/plugins/db2sql.c | 131 |
15 files changed, 308 insertions, 55 deletions
diff --git a/src/common/ers.c b/src/common/ers.c index 27d9222ff..22269a51f 100644 --- a/src/common/ers.c +++ b/src/common/ers.c @@ -293,7 +293,7 @@ static void ers_obj_destroy(ERS self) void ers_cache_size(ERS self, unsigned int new_size) { struct ers_instance_t *instance = (struct ers_instance_t *)self; - if (instance == NULL) { + if (instance == NULL) {//change as per piotrhalaczkiewicz comment ShowError("ers_cache_size: NULL object, skipping...\n"); return; } diff --git a/src/config/const.h b/src/config/const.h index 06a54a76f..f4a2821f8 100644 --- a/src/config/const.h +++ b/src/config/const.h @@ -111,6 +111,13 @@ #undef CONSOLE_INPUT #endif +#ifdef RENEWAL + #define ITEMDB_SQL_COLUMNS 24 +#else + #define ITEMDB_SQL_COLUMNS 22 +#endif + + /** * End of File **/ diff --git a/src/map/battle.c b/src/map/battle.c index f78e4f9a8..31fe502f6 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -6375,7 +6375,7 @@ static const struct _battle_data { { "cashshop_show_points", &battle_config.cashshop_show_points, 0, 0, 1, }, { "mail_show_status", &battle_config.mail_show_status, 0, 0, 2, }, { "client_limit_unit_lv", &battle_config.client_limit_unit_lv, 0, 0, BL_ALL, }, -// BattleGround Settings + // BattleGround Settings { "bg_update_interval", &battle_config.bg_update_interval, 1000, 100, INT_MAX, }, { "bg_flee_penalty", &battle_config.bg_flee_penalty, 20, 0, INT_MAX, }, /** @@ -6400,6 +6400,7 @@ static const struct _battle_data { { "max_walk_path", &battle_config.max_walk_path, 17, 1, MAX_WALKPATH, }, { "item_enabled_npc", &battle_config.item_enabled_npc, 1, 0, 1, }, { "gm_ignore_warpable_area", &battle_config.gm_ignore_warpable_area, 0, 2, 100, }, + { "packet_obfuscation", &battle_config.packet_obfuscation, 1, 0, 3, }, }; #ifndef STATS_OPT_OUT /** @@ -6624,7 +6625,7 @@ void battle_adjust_conf(void) { #ifndef CELL_NOSTACK if (battle_config.cell_stack_limit != 1) - ShowWarning("Battle setting 'cell_stack_limit' takes no effect as this server was compiled without Cell Stack Limit support.\n"); + ShowWarning("Battle setting 'cell_stack_limit' takes no effect as this server was compiled without Cell Stack Limit support (CELL_NOSTACK).\n"); #endif } diff --git a/src/map/battle.h b/src/map/battle.h index 02d21ed69..7d41a02c5 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -449,6 +449,7 @@ struct Battle_Config { int item_restricted_consumption_type; int max_walk_path; int item_enabled_npc; + int packet_obfuscation; int gm_ignore_warpable_area; diff --git a/src/map/clif.c b/src/map/clif.c index 2f8ecd6a4..2feb6f4bf 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -632,6 +632,7 @@ void clif_authfail_fd(int fd, int type) WFIFOB(fd,2) = type; WFIFOSET(fd,packet_len(0x81)); set_eof(fd); + } @@ -9288,6 +9289,7 @@ void clif_parse_WantToConnection(int fd, struct map_session_data* sd) { WFIFOB(fd,2) = 3; // Rejected by server WFIFOSET(fd,packet_len(0x6a)); set_eof(fd); + return; } @@ -9301,6 +9303,8 @@ void clif_parse_WantToConnection(int fd, struct map_session_data* sd) { CREATE(sd, TBL_PC, 1); sd->fd = fd; + sd->cryptKey = (( clif->cryptKey[0] * clif->cryptKey[1] ) + clif->cryptKey[2]) & 0xFFFFFFFF; + session[fd]->session_data = sd; pc->setnewpc(sd, account_id, char_id, login_id1, client_tick, sex, fd); @@ -9819,6 +9823,7 @@ void clif_parse_QuitGame(int fd, struct map_session_data *sd) (!battle_config.prevent_logout || DIFF_TICK(iTimer->gettick(), sd->canlog_tick) > battle_config.prevent_logout) ) { set_eof(fd); + clif->disconnect_ack(sd, 0); } else { clif->disconnect_ack(sd, 1); @@ -17436,6 +17441,47 @@ void clif_scriptclear(struct map_session_data *sd, int npcid) { clif->send(&p,sizeof(p), &sd->bl, SELF); } +unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) { + if( sd ) { + sd->cryptKey = (( sd->cryptKey * clif->cryptKey[1] ) + clif->cryptKey[2]) & 0xFFFFFFFF; + return (cmd ^ ((sd->cryptKey >> 16) & 0x7FFF)); + } + return (cmd ^ (((( clif->cryptKey[0] * clif->cryptKey[1] ) + clif->cryptKey[2]) >> 16) & 0x7FFF)); +} +unsigned short clif_parse_cmd_normal ( int fd, struct map_session_data *sd ) { + unsigned short cmd = RFIFOW(fd,0); + // filter out invalid / unsupported packets + if (cmd > MAX_PACKET_DB || packet_db[cmd].len == 0) + return 0; + + return cmd; +} +unsigned short clif_parse_cmd_optional ( int fd, struct map_session_data *sd ) { + unsigned short cmd = RFIFOW(fd,0); + + // filter out invalid / unsupported packets + if (cmd > MAX_PACKET_DB || packet_db[cmd].len == 0) { + cmd = clif->decrypt_cmd( cmd, sd ); + if( cmd > MAX_PACKET_DB || packet_db[cmd].len == 0 ) + return 0; + RFIFOW(fd, 0) = cmd; + } + + return cmd; +} +unsigned short clif_parse_cmd_decrypt ( int fd, struct map_session_data *sd ) { + unsigned short cmd = RFIFOW(fd,0); + + cmd = clif->decrypt_cmd( cmd, sd ); + + // filter out invalid / unsupported packets + if (cmd > MAX_PACKET_DB || packet_db[cmd].len == 0 ) + return 0; + + RFIFOW(fd, 0) = cmd; + + return cmd; +} /*========================================== * Main client packet processing function @@ -17479,20 +17525,18 @@ int clif_parse(int fd) { if (RFIFOREST(fd) < 2) return 0; - cmd = RFIFOW(fd,0); - - // filter out invalid / unsupported packets - if (cmd > MAX_PACKET_DB || packet_db[cmd].len == 0) { - ShowWarning("clif_parse: Received unsupported packet (packet 0x%04x, %d bytes received), disconnecting session #%d.\n", cmd, RFIFOREST(fd), fd); + if( !( cmd = clif->parse_cmd(fd,sd) ) ) { + ShowWarning("clif_parse: Received unsupported packet (packet 0x%04x, %d bytes received), disconnecting session #%d.\n", RFIFOW(fd,0), RFIFOREST(fd), fd); #ifdef DUMP_INVALID_PACKET ShowDump(RFIFOP(fd,0), RFIFOREST(fd)); #endif set_eof(fd); return 0; } + // determine real packet length - packet_len = packet_db[cmd].len; - if (packet_len == -1) { // variable-length packet + if ( ( packet_len = packet_db[cmd].len ) == -1) { // variable-length packet + if (RFIFOREST(fd) < 4) return 0; @@ -17503,9 +17547,11 @@ int clif_parse(int fd) { ShowDump(RFIFOP(fd,0), RFIFOREST(fd)); #endif set_eof(fd); + return 0; } } + if ((int)RFIFOREST(fd) < packet_len) return 0; // not enough data received to form the packet @@ -17598,14 +17644,29 @@ void packetdb_loaddb(void) { memset(packet_db,0,sizeof(packet_db)); #define packet(id, size, ...) packetdb_addpacket(id, size, ##__VA_ARGS__, 0xFFFF) + #define packetKeys(a,b,c) { clif->cryptKey[0] = a; clif->cryptKey[1] = b; clif->cryptKey[2] = c; } #include "packets.h" /* load structure data */ #undef packet + #undef packetKeys } void clif_bc_ready(void) { if( battle_config.display_status_timers ) clif->status_change = clif_status_change; else clif->status_change = clif_status_change_notick; + + switch( battle_config.packet_obfuscation ) { + case 0: + clif->parse_cmd = clif_parse_cmd_normal; + break; + default: + case 1: + clif->parse_cmd = clif_parse_cmd_optional; + break; + case 2: + clif->parse_cmd = clif_parse_cmd_decrypt; + break; + } } /*========================================== * @@ -17689,6 +17750,8 @@ void clif_defaults(void) { clif->send = clif_send; clif->send_sub = clif_send_sub; clif->parse = clif_parse; + clif->parse_cmd = clif_parse_cmd_optional; + clif->decrypt_cmd = clif_decrypt_cmd; /* auth */ clif->authok = clif_authok; clif->authrefuse = clif_authrefuse; diff --git a/src/map/clif.h b/src/map/clif.h index b447687ea..6e1fa81d3 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -462,6 +462,8 @@ struct clif_interface { struct hCSData **data[CASHSHOP_TAB_MAX]; unsigned int item_count[CASHSHOP_TAB_MAX]; } cs; + /* */ + unsigned int cryptKey[3]; /* core */ int (*init) (void); void (*final) (void); @@ -472,6 +474,8 @@ struct clif_interface { int (*send) (const void* buf, int len, struct block_list* bl, enum send_target type); int (*send_sub) (struct block_list *bl, va_list ap); int (*parse) (int fd); + unsigned short (*parse_cmd) ( int fd, struct map_session_data *sd ); + unsigned short (*decrypt_cmd) ( int cmd, struct map_session_data *sd ); /* auth */ void (*authok) (struct map_session_data *sd); void (*authrefuse) (int fd, uint8 error_code); diff --git a/src/map/itemdb.c b/src/map/itemdb.c index cb845111d..859b19aac 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -296,8 +296,7 @@ static struct item_data* create_item_data(int nameid) /*========================================== * Loads (and creates if not found) an item from the db. *------------------------------------------*/ -struct item_data* itemdb_load(int nameid) -{ +struct item_data* itemdb_load(int nameid) { struct item_data *id; if( nameid >= 0 && nameid < ARRAYLENGTH(itemdb_array) ) @@ -967,7 +966,7 @@ void itemdb_re_split_atoi(char *str, int *atk, int *matk) { /*========================================== * processes one itemdb entry *------------------------------------------*/ -static bool itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt) { +int itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt) { /* +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+ | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | @@ -977,12 +976,12 @@ static bool itemdb_parse_dbrow(char** str, const char* source, int line, int scr */ int nameid; struct item_data* id; + unsigned char offset = 0; nameid = atoi(str[0]); - if( nameid <= 0 ) - { + if( nameid <= 0 ) { ShowWarning("itemdb_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", nameid, line, source); - return false; + return 0; } //ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View @@ -1030,39 +1029,47 @@ static bool itemdb_parse_dbrow(char** str, const char* source, int line, int scr id->weight = atoi(str[6]); #ifdef RENEWAL - itemdb_re_split_atoi(str[7],&id->atk,&id->matk); + if( iMap->db_use_sqldbs ) { + id->atk = atoi(str[7]); + id->matk = atoi(str[8]); + offset += 1; + } else + itemdb_re_split_atoi(str[7],&id->atk,&id->matk); #else id->atk = atoi(str[7]); #endif - id->def = atoi(str[8]); - id->range = atoi(str[9]); - id->slot = atoi(str[10]); + id->def = atoi(str[8+offset]); + id->range = atoi(str[9+offset]); + id->slot = atoi(str[10+offset]); - if (id->slot > MAX_SLOTS) - { + if (id->slot > MAX_SLOTS) { ShowWarning("itemdb_parse_dbrow: Item %d (%s) specifies %d slots, but the server only supports up to %d. Using %d slots.\n", nameid, id->jname, id->slot, MAX_SLOTS, MAX_SLOTS); id->slot = MAX_SLOTS; } - itemdb_jobid2mapid(id->class_base, (unsigned int)strtoul(str[11],NULL,0)); - id->class_upper = atoi(str[12]); - id->sex = atoi(str[13]); - id->equip = atoi(str[14]); + itemdb_jobid2mapid(id->class_base, (unsigned int)strtoul(str[11+offset],NULL,0)); + id->class_upper = atoi(str[12+offset]); + id->sex = atoi(str[13+offset]); + id->equip = atoi(str[14+offset]); - if (!id->equip && itemdb_isequip2(id)) - { + if (!id->equip && itemdb_isequip2(id)) { ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname); id->type = IT_ETC; } - id->wlv = cap_value(atoi(str[15]), REFINE_TYPE_ARMOR, REFINE_TYPE_MAX); + id->wlv = cap_value(atoi(str[15+offset]), REFINE_TYPE_ARMOR, REFINE_TYPE_MAX); #ifdef RENEWAL - itemdb_re_split_atoi(str[16],&id->elv,&id->elvmax); + if( iMap->db_use_sqldbs ) { + id->elv = atoi(str[16+offset]); + id->elvmax = atoi(str[17+offset]); + offset += 1; + } else + itemdb_re_split_atoi(str[16],&id->elv,&id->elvmax); #else id->elv = atoi(str[16]); #endif - id->flag.no_refine = atoi(str[17]) ? 0 : 1; //FIXME: verify this - id->look = atoi(str[18]); + id->flag.no_refine = atoi(str[17+offset]) ? 0 : 1; //FIXME: verify this + id->look = atoi(str[18+offset]); id->flag.available = 1; id->view_id = 0; @@ -1081,14 +1088,14 @@ static bool itemdb_parse_dbrow(char** str, const char* source, int line, int scr id->unequip_script = NULL; } - if (*str[19]) - id->script = parse_script(str[19], source, line, scriptopt); - if (*str[20]) - id->equip_script = parse_script(str[20], source, line, scriptopt); - if (*str[21]) - id->unequip_script = parse_script(str[21], source, line, scriptopt); + if (*str[19+offset]) + id->script = parse_script(str[19+offset], source, line, scriptopt); + if (*str[20+offset]) + id->equip_script = parse_script(str[20+offset], source, line, scriptopt); + if (*str[21+offset]) + id->unequip_script = parse_script(str[21+offset], source, line, scriptopt); - return true; + return id->nameid; } /*========================================== @@ -1205,7 +1212,7 @@ static int itemdb_readdb(void) } } - if (!itemdb_parse_dbrow(str, path, lines, 0)) + if (!itemdb->parse_dbrow(str, path, lines, 0)) continue; count++; @@ -1218,7 +1225,6 @@ static int itemdb_readdb(void) return 0; } - /*====================================== * item_db table reading *======================================*/ @@ -1234,7 +1240,7 @@ static int itemdb_read_sqldb(void) { int fi; for( fi = 0; fi < ARRAYLENGTH(item_db_name); ++fi ) { - uint32 lines = 0, count = 0; + uint32 count = 0; // retrieve all rows from the item database if( SQL_ERROR == SQL->Query(mmysql_handle, "SELECT * FROM `%s`", item_db_name[fi]) ) { @@ -1244,17 +1250,16 @@ static int itemdb_read_sqldb(void) { // process rows one by one while( SQL_SUCCESS == SQL->NextRow(mmysql_handle) ) {// wrap the result into a TXT-compatible format - char* str[22]; + char* str[ITEMDB_SQL_COLUMNS]; char* dummy = ""; int i; - ++lines; - for( i = 0; i < 22; ++i ) { + for( i = 0; i < ITEMDB_SQL_COLUMNS; ++i ) { SQL->GetData(mmysql_handle, i, &str[i], NULL); if( str[i] == NULL ) str[i] = dummy; // get rid of NULL columns } - if (!itemdb_parse_dbrow(str, item_db_name[fi], lines, SCRIPT_IGNORE_EXTERNAL_BRACKETS)) + if (!itemdb->parse_dbrow(str, item_db_name[fi], -(atoi(str[0])), SCRIPT_IGNORE_EXTERNAL_BRACKETS)) continue; ++count; } @@ -1471,3 +1476,12 @@ int do_init_itemdb(void) { return 0; } +/* incomplete */ +void itemdb_defaults(void) { + itemdb = &itemdb_s; + + itemdb->reload = itemdb_reload;//incomplet=e + /* */ + itemdb->parse_dbrow = itemdb_parse_dbrow; + itemdb->exists = itemdb_exists;//incomplete +} diff --git a/src/map/itemdb.h b/src/map/itemdb.h index ea478d135..44b455d80 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.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 Teams #ifndef _ITEMDB_H_ #define _ITEMDB_H_ @@ -239,4 +240,16 @@ void itemdb_reload(void); void do_final_itemdb(void); int do_init_itemdb(void); +/* incomplete */ +struct itemdb_interface { + void (*reload) (void); + /* */ + int (*parse_dbrow) (char** str, const char* source, int line, int scriptopt); + struct item_data* (*exists) (int nameid); +} itemdb_s; + +struct itemdb_interface *itemdb; + +void itemdb_defaults(void); + #endif /* _ITEMDB_H_ */ diff --git a/src/map/map.c b/src/map/map.c index 510f36109..84b4f6bd2 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -5237,6 +5237,7 @@ void map_hp_symbols(void) { HPM->share(guild,"guild"); HPM->share(homun,"homun"); HPM->share(ircbot,"ircbot"); + HPM->share(itemdb,"itemdb"); HPM->share(logs,"logs"); HPM->share(script,"script"); HPM->share(searchstore,"searchstore"); @@ -5266,6 +5267,7 @@ void load_defaults(void) { homunculus_defaults(); instance_defaults(); ircbot_defaults(); + itemdb_defaults(); log_defaults(); npc_defaults(); script_defaults(); diff --git a/src/map/packets.h b/src/map/packets.h index aada5d53f..244f19ed8 100644 --- a/src/map/packets.h +++ b/src/map/packets.h @@ -10,6 +10,10 @@ #define packet(a,b,...) #endif +#ifndef packetKeys + #define packetKeys(a,b,c) +#endif + /* * packet syntax * - packet(packet_id,length) @@ -2017,6 +2021,8 @@ packet(0x020d,-1); packet(0x08E5,41,clif->pPartyBookingRegisterReq,2,4); packet(0x08d2,10); packet(0x0916,26,clif->pGuildInvite2,2); + packetKeys(0x1540e48,0x13041224,0x31247924); + #endif #ifndef PACKETVER_RE @@ -2058,6 +2064,7 @@ packet(0x020d,-1); //2012-07-16aRagExe (special thanks to Yommy!) #if PACKETVER >= 20120716 packet(0x0364,8,clif->pMoveFromKafra,2,4); + packetKeys(0x76052205, 0x22052205, 0x22052205); #endif //2013-03-20Ragexe (Judas + Yommy) @@ -2092,6 +2099,7 @@ packet(0x020d,-1); packet(0x086F,26,clif->pFriendsListAdd,2); packet(0x093F,5,clif->pHomMenu,2,4); packet(0x0947,36,clif->pStoragePassword,0); + packetKeys(0x3F094C49, 0x55F86C1E, 0x58AA359A); // Shuffle End // New Packets diff --git a/src/map/pc.h b/src/map/pc.h index cd2a45a6b..5c585af1c 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -497,6 +497,9 @@ struct map_session_data { int *queues; unsigned int queues_count; + /* Made Possible Thanks to Yommy~! */ + unsigned int cryptKey; + // temporary debugging of bug #3504 const char* delunit_prevfile; int delunit_prevline; diff --git a/src/map/script.c b/src/map/script.c index 26d64726c..60f741d6c 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -2045,7 +2045,11 @@ void script_error(const char* src, const char* file, int start_line, const char* StrBuf->Init(&buf); StrBuf->AppendStr(&buf, "\a\n"); - StrBuf->Printf(&buf, "script error on %s line %d\n", file, line); + if( line >= 0 ) + StrBuf->Printf(&buf, "script error on %s line %d\n", file, line); + else + StrBuf->Printf(&buf, "script error on %s item ID %d\n", file, -line); + StrBuf->Printf(&buf, " %s\n", error_msg); for(j = 0; j < 5; j++ ) { script_print_line(&buf, linestart[j], NULL, line + j - 5); @@ -10176,10 +10180,8 @@ BUILDIN(warpwaitingpc) /// Detaches a character from a script. /// /// @param st Script state to detach the character from. -static void script_detach_rid(struct script_state* st) -{ - if(st->rid) - { +void script_detach_rid(struct script_state* st) { + if(st->rid) { script_detach_state(st, false); st->rid = 0; } @@ -17864,6 +17866,7 @@ void script_defaults(void) { script->conv_num = conv_num; script->conv_str = conv_str; script->rid2sd = script_rid2sd; + script->detach_rid = script_detach_rid; script->push_val = push_val; script->get_val = get_val; script->get_val2 = get_val2; diff --git a/src/map/script.h b/src/map/script.h index 96fcdc23a..92a083556 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -361,6 +361,7 @@ struct script_interface { int (*conv_num) (struct script_state *st,struct script_data *data); const char* (*conv_str) (struct script_state *st,struct script_data *data); TBL_PC *(*rid2sd) (struct script_state *st); + void (*detach_rid) (struct script_state* st); struct script_data* (*push_val)(struct script_stack* stack, enum c_op type, int val, struct DBMap** ref); void (*get_val) (struct script_state* st, struct script_data* data); void* (*get_val2) (struct script_state* st, int uid, struct DBMap** ref); diff --git a/src/plugins/Makefile.in b/src/plugins/Makefile.in index 71b743dca..3c80fa0e1 100644 --- a/src/plugins/Makefile.in +++ b/src/plugins/Makefile.in @@ -1,17 +1,19 @@ COMMON_H = ../common/HPMi.h ../common/cbasetypes.h -PLUGINS = sample +PLUGINS = sample db2sql @SET_MAKE@ ##################################################################### -.PHONY : all $(PLUGINS) sample clean help +.PHONY : all $(PLUGINS) sample db2sql clean help all: $(PLUGINS) sample: sample@DLLEXT@ +db2sql: db2sql@DLLEXT@ + clean: @echo " CLEAN plugins" @rm -rf *.o diff --git a/src/plugins/db2sql.c b/src/plugins/db2sql.c new file mode 100644 index 000000000..e5630ee2d --- /dev/null +++ b/src/plugins/db2sql.c @@ -0,0 +1,131 @@ +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "../config/core.h" +#include "../common/HPMi.h" +#include "../common/strlib.h" +#include "../common/SQL.h" +#include "../common/timer.h" +#include "../map/clif.h" +#include "../map/pc.h" +#include "../map/map.h" +#include "../map/itemdb.h" + + +HPExport struct hplugin_info pinfo = { + "DB2SQL", // Plugin name + SERVER_TYPE_MAP,// Which server types this plugin works with? + "0.1", // Plugin version + HPM_VERSION, // HPM Version (don't change, macro is automatically updated) +}; + +SqlStmt* stmt; + +int (*parse_dbrow)(char** str, const char* source, int line, int scriptopt); + +char* trimbraces(char* str) { + size_t start; + size_t end; + + if( str == NULL ) + return str; + + for( start = 0; str[start] && str[start] == '{'; ++start ) + ; + for( end = strlen(str); start < end && str[end-1] && (str[end-1] == '}' || str[end-1] == '\n'); --end ) + ; + if( start == end ) + *str = '\0'; + else { + str[end] = '\0'; + memmove(str,str+start,end-start+1); + trim(str); + } + return str; +} +int db2sql(char** str, const char* source, int line, int scriptopt) { + struct item_data *it = NULL; + unsigned char offset = 0; +#ifdef RENEWAL + if( iMap->db_use_sqldbs ) offset = 1; +#endif + if( (it = itemdb->exists(parse_dbrow(str,source,line,scriptopt))) ) { + /* renewal has the 'matk' and 'equip_level' is now 'equip_level_min', and there is a new 'equip_level_max' field */ +#ifdef RENEWAL + if( SQL_SUCCESS != SQL->StmtPrepare(stmt, "REPLACE INTO `%s` (`id`,`name_english`,`name_japanese`,`type`,`price_buy`,`price_sell`,`weight`,`atk`,`matk`,`defence`,`range`,`slots`,`equip_jobs`,`equip_upper`,`equip_genders`,`equip_locations`,`weapon_level`,`equip_level_min`,`equip_level_max`,`refineable`,`view`,`script`,`equip_script`,`unequip_script`) VALUES ('%u',?,?,'%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u',?,?,?)",iMap->item_db_re_db, + it->nameid,it->type,it->value_buy,it->value_sell,it->weight,it->atk,it->matk,it->def,it->range,it->slot,(unsigned int)strtoul(str[11+offset],NULL,0),atoi(str[12+offset]),atoi(str[13+offset]),atoi(str[14+offset]),it->wlv,it->elv,it->elvmax,atoi(str[17+offset]),it->look) ) +#else + if( SQL_SUCCESS != SQL->StmtPrepare(stmt, "REPLACE INTO `%s` (`id`,`name_english`,`name_japanese`,`type`,`price_buy`,`price_sell`,`weight`,`atk`,`defence`,`range`,`slots`,`equip_jobs`,`equip_upper`,`equip_genders`,`equip_locations`,`weapon_level`,`equip_level`,`refineable`,`view`,`script`,`equip_script`,`unequip_script`) VALUES ('%u',?,?,'%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u',?,?,?)",iMap->item_db_db, + it->nameid,it->type,it->value_buy,it->value_sell,it->weight,it->atk,it->def,it->range,it->slot,(unsigned int)strtoul(str[11],NULL,0),atoi(str[12]),atoi(str[13]),atoi(str[14]),it->wlv,it->elv,atoi(str[17]),it->look) ) +#endif + SqlStmt_ShowDebug(stmt); + else { + if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 0, SQLDT_STRING, it->name, strlen(it->name)) ) + SqlStmt_ShowDebug(stmt); + else { + if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 1, SQLDT_STRING, it->jname, strlen(it->jname)) ) + SqlStmt_ShowDebug(stmt); + else { + #ifdef RENEWAL + if( iMap->db_use_sqldbs ) offset += 1; + #endif + if( it->script ) trimbraces(str[19+offset]); + if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 2, SQLDT_STRING, it->script?str[19+offset]:"", it->script?strlen(str[19+offset]):0) ) + SqlStmt_ShowDebug(stmt); + else { + if( it->equip_script ) trimbraces(str[20+offset]); + if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 3, SQLDT_STRING, it->equip_script?str[20+offset]:"", it->equip_script?strlen(str[20+offset]):0) ) + SqlStmt_ShowDebug(stmt); + else { + if( it->unequip_script ) trimbraces(str[21+offset]); + if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 4, SQLDT_STRING, it->unequip_script?str[21+offset]:"", it->unequip_script?strlen(str[21+offset]):0) ) + SqlStmt_ShowDebug(stmt); + else { + if( SQL_SUCCESS != SQL->StmtExecute(stmt) ) + SqlStmt_ShowDebug(stmt); + } + } + } + } + } + } + return it->nameid; + } + return 0; +} + +CPCMD(db2sql) { + + stmt = SQL->StmtMalloc(mysql_handle); + if( stmt == NULL ) { + SqlStmt_ShowDebug(stmt); + return; + } + + /* link */ + parse_dbrow = itemdb->parse_dbrow; + itemdb->parse_dbrow = db2sql; + + /* empty table */ + if ( SQL_ERROR == SQL->Query(mysql_handle, "DELETE FROM `%s`", iMap->item_db_db) ) + Sql_ShowDebug(mysql_handle); + else { + itemdb->reload(); + } + /* unlink */ + itemdb->parse_dbrow = parse_dbrow; + + SQL->StmtFree(stmt); +} + +HPExport void plugin_init (void) { + SQL = GET_SYMBOL("SQL"); + itemdb = GET_SYMBOL("itemdb"); + iMap = GET_SYMBOL("iMap"); + strlib = GET_SYMBOL("strlib"); + + HPMi->addCPCommand("server:tools:db2sql",CPCMD_A(db2sql)); +}
\ No newline at end of file |