Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Autotrade persistance cleanup
* Moved redundant structs for vending & buyingstore, move it to vending.h * Removed redundant query to update autotrade info (autotrade state, head, body direction, & sit state) that previously executed in vending_reopen & vending_openvending, buyingstore_reopen & buyingstore_create. * Removed lines to execute queries each iteration to insert vending/buyingstore list, now using StringBuf and just being executed once after the item listing. (in vending_openvending & buyingstore_create) * Revert the ways initializing autotrader list by using DBMap (vending_autotrader_db & buyingstore_autotrader_db) Signed-off-by: Cydh Ramdh <house.bad@gmail.com>
- Loading branch information
Showing
with
227 additions
and 265 deletions.
- +93 −126 src/map/buyingstore.c
- +2 −2 src/map/buyingstore.h
- +2 −2 src/map/clif.c
- +4 −2 src/map/pc.c
- +1 −1 src/map/pc.h
- +96 −131 src/map/vending.c
- +29 −1 src/map/vending.h
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @@ -14,35 +14,14 @@ | ||
| #include "log.h" // log_pick_pc, log_zeny | ||
| #include "pc.h" // struct map_session_data | ||
| #include "chrif.h" | ||
| #include "vending.h" // struct s_autotrade_entry, struct s_autotrader | ||
|
|
||
| #include <stdlib.h> // atoi | ||
|
|
||
| //Autotrader | ||
| static DBMap *buyingstore_autotrader_db; /// Holds autotrader info: char_id -> struct s_autotrader | ||
| static void buyingstore_autotrader_remove(struct s_autotrader *at, bool remove); | ||
| static int buyingstore_autotrader_free(DBKey key, DBData *data, va_list ap); | ||
|
|
||
| /// constants (client-side restrictions) | ||
| #define BUYINGSTORE_MAX_PRICE 99990000 | ||
| @@ -84,7 +63,7 @@ static unsigned int buyingstore_getuid(void) | ||
| * @param slots Number of item on the list | ||
| * @return 0 If success, 1 - Cannot open, 2 - Manner penalty, 3 - Mapflag restiction, 4 - Cell restriction | ||
| */ | ||
| int8 buyingstore_setup(struct map_session_data* sd, unsigned char slots){ | ||
| nullpo_retr(1, sd); | ||
|
|
||
| if (!battle_config.feature_buying_store || sd->state.vending || sd->state.buyingstore || sd->state.trading || slots == 0) { | ||
| @@ -128,12 +107,14 @@ char buyingstore_setup(struct map_session_data* sd, unsigned char slots){ | ||
| * @param storename | ||
| * @param *itemlist { <nameid>.W, <amount>.W, <price>.L }* | ||
| * @param count Number of item on the itemlist | ||
| * @param at Autotrader info, or NULL if requetsed not from autotrade persistance | ||
| * @return 0 If success, 1 - Cannot open, 2 - Manner penalty, 3 - Mapflag restiction, 4 - Cell restriction, 5 - Invalid count/result, 6 - Cannot give item, 7 - Will be overweight | ||
| */ | ||
| int8 buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count, struct s_autotrader *at) | ||
| { | ||
| unsigned int i, weight, listidx; | ||
| char message_sql[MESSAGE_SIZE*2]; | ||
| StringBuf buf; | ||
|
|
||
| nullpo_retr(1, sd); | ||
|
|
||
| @@ -246,17 +227,22 @@ char buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha | ||
|
|
||
| Sql_EscapeString( mmysql_handle, message_sql, sd->message ); | ||
|
|
||
| if( Sql_Query( mmysql_handle, "INSERT INTO `%s`(`id`, `account_id`, `char_id`, `sex`, `map`, `x`, `y`, `title`, `limit`, `autotrade`, `body_direction`, `head_direction`, `sit`) " | ||
| "VALUES( %d, %d, %d, '%c', '%s', %d, %d, '%s', %d, %d, '%d', '%d', '%d' );", | ||
| buyingstores_db, sd->buyer_id, sd->status.account_id, sd->status.char_id, sd->status.sex == 0 ? 'F' : 'M', map[sd->bl.m].name, sd->bl.x, sd->bl.y, message_sql, sd->buyingstore.zenylimit, sd->state.autotrade, at ? at->dir : sd->ud.dir, at ? at->head_dir : sd->head_dir, at ? at->sit : pc_issit(sd) ) != SQL_SUCCESS ){ | ||
| Sql_ShowDebug(mmysql_handle); | ||
| } | ||
|
|
||
| StringBuf_Init(&buf); | ||
| StringBuf_Printf(&buf, "INSERT INTO `%s`(`buyingstore_id`,`index`,`item_id`,`amount`,`price`) VALUES", buyingstore_items_db); | ||
| for (i = 0; i < sd->buyingstore.slots; i++){ | ||
| StringBuf_Printf(&buf, "(%d,%d,%hu,%d,%d)", sd->buyer_id, i, sd->buyingstore.items[i].nameid, sd->buyingstore.items[i].amount, sd->buyingstore.items[i].price); | ||
| if (i < sd->buyingstore.slots-1) | ||
| StringBuf_AppendStr(&buf, ","); | ||
| } | ||
| if (SQL_ERROR == Sql_QueryStr(mmysql_handle, StringBuf_Value(&buf))) | ||
| Sql_ShowDebug(mmysql_handle); | ||
| StringBuf_Destroy(&buf); | ||
|
|
||
| clif_buyingstore_myitemlist(sd); | ||
| clif_buyingstore_entry(sd); | ||
| @@ -595,24 +581,21 @@ bool buyingstore_searchall(struct map_session_data* sd, const struct s_search_st | ||
| * @param sd Player as autotrader | ||
| */ | ||
| void buyingstore_reopen( struct map_session_data* sd ){ | ||
| struct s_autotrader *at = NULL; | ||
| int8 fail = -1; | ||
|
|
||
| nullpo_retv(sd); | ||
|
|
||
| // Ready to open buyingstore for this char | ||
| if ((at = uidb_get(buyingstore_autotrader_db, sd->status.char_id)) && at->count && at->entries) { | ||
| uint8 *data, *p; | ||
| uint16 j, count; | ||
|
|
||
| // Init buyingstore data for autotrader | ||
| CREATE(data, uint8, at->count * 8); | ||
|
|
||
| for (j = 0, p = data, count = at->count; j < at->count; j++) { | ||
| struct s_autotrade_entry *entry = at->entries[j]; | ||
| unsigned short *item_id = (uint16*)(p + 0); | ||
| uint16 *amount = (uint16*)(p + 2); | ||
| uint32 *price = (uint32*)(p + 4); | ||
| @@ -624,61 +607,52 @@ void buyingstore_reopen( struct map_session_data* sd ){ | ||
| p += 8; | ||
| } | ||
|
|
||
| sd->state.autotrade = 1; | ||
|
|
||
| // Make sure abort all NPCs | ||
| npc_event_dequeue(sd); | ||
| pc_cleareventtimer(sd); | ||
|
|
||
| // Open the buyingstore again | ||
| if( (fail = buyingstore_setup( sd, (unsigned char)at->count )) == 0 && | ||
| (fail = buyingstore_create( sd, at->limit, 1, at->title, data, at->count, at )) == 0 ) | ||
| { | ||
| // Make buyer look perfect | ||
| pc_setdir(sd, at->dir, at->head_dir); | ||
| clif_changed_dir(&sd->bl, AREA_WOS); | ||
| if( at->sit ) { | ||
| pc_setsit(sd); | ||
| skill_sit(sd, 1); | ||
| clif_sitting(&sd->bl); | ||
| } | ||
|
|
||
| // Immediate save | ||
| chrif_save(sd, 3); | ||
|
|
||
| ShowInfo("Buyingstore loaded for '"CL_WHITE"%s"CL_RESET"' with '"CL_WHITE"%d"CL_RESET"' items at "CL_WHITE"%s (%d,%d)"CL_RESET"\n", | ||
| sd->status.name, count, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y); | ||
| } | ||
| aFree(data); | ||
| } | ||
|
|
||
| if (at) { | ||
| buyingstore_autotrader_remove(at, true); | ||
| if (db_size(buyingstore_autotrader_db) == 0) | ||
| buyingstore_autotrader_db->clear(buyingstore_autotrader_db, buyingstore_autotrader_free); | ||
| } | ||
|
|
||
| if (fail != 0) { | ||
| ShowError("buyingstore_reopen: (Error:%d) Load failed for autotrader '"CL_WHITE"%s"CL_RESET"' (CID=%/AID=%d)\n", fail, sd->status.name, sd->status.char_id, sd->status.account_id); | ||
| map_quit(sd); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Initializing autotraders from table | ||
| * TODO: Make this support for multi map-server | ||
This comment has been minimized.
This comment has been minimized.
cydh
Author
Contributor
|
||
| */ | ||
| void do_init_buyingstore_autotrade( void ) { | ||
| if(battle_config.feature_autotrade) { | ||
| if (Sql_Query(mmysql_handle, | ||
| "SELECT `id`, `account_id`, `char_id`, `sex`, `title`, `limit`, `body_direction`, `head_direction`, `sit` " | ||
| "FROM `%s` " | ||
| @@ -690,27 +664,19 @@ void do_init_buyingstore_autotrade( void ) { | ||
| return; | ||
| } | ||
|
|
||
| if( Sql_NumRows(mmysql_handle) > 0 ) { | ||
| uint16 items = 0; | ||
| DBIterator *iter = NULL; | ||
| struct s_autotrader *at = NULL; | ||
|
|
||
| // Init each autotrader data | ||
| while (SQL_SUCCESS == Sql_NextRow(mmysql_handle)) { | ||
| size_t len; | ||
| char* data; | ||
|
|
||
| at = NULL; | ||
| CREATE(at, struct s_autotrader, 1); | ||
| Sql_GetData(mmysql_handle, 0, &data, NULL); at->id = atoi(data); | ||
| Sql_GetData(mmysql_handle, 1, &data, NULL); at->account_id = atoi(data); | ||
| Sql_GetData(mmysql_handle, 2, &data, NULL); at->char_id = atoi(data); | ||
| Sql_GetData(mmysql_handle, 3, &data, NULL); at->sex = (data[0] == 'F') ? 0 : 1; | ||
| @@ -731,34 +697,32 @@ void do_init_buyingstore_autotrade( void ) { | ||
| // initialize player | ||
| CREATE(at->sd, struct map_session_data, 1); | ||
| pc_setnewpc(at->sd, at->account_id, at->char_id, 0, gettick(), at->sex, 0); | ||
| at->sd->state.autotrade = 1|4; | ||
| at->sd->state.monster_ignore = (battle_config.autotrade_monsterignore); | ||
| chrif_authreq(at->sd, true); | ||
| uidb_put(buyingstore_autotrader_db, at->char_id, at); | ||
| } | ||
| Sql_FreeResult(mmysql_handle); | ||
|
|
||
| // Init items for each autotraders | ||
| iter = db_iterator(buyingstore_autotrader_db); | ||
| for (at = dbi_first(iter); dbi_exists(iter); at = dbi_next(iter)) { | ||
| uint16 j = 0; | ||
|
|
||
| if (SQL_ERROR == Sql_Query(mmysql_handle, | ||
| "SELECT `item_id`, `amount`, `price` " | ||
| "FROM `%s` " | ||
| "WHERE `buyingstore_id` = %d " | ||
| "ORDER BY `index` ASC;", | ||
| buyingstore_items_db, at->id ) ) | ||
| { | ||
| Sql_ShowDebug(mmysql_handle); | ||
| continue; | ||
| } | ||
|
|
||
| if (!(at->count = (uint16)Sql_NumRows(mmysql_handle))) { | ||
| map_quit(at->sd); | ||
| buyingstore_autotrader_remove(at, true); | ||
| continue; | ||
| } | ||
|
|
||
| @@ -768,9 +732,8 @@ void do_init_buyingstore_autotrade( void ) { | ||
| //Add the item into list | ||
| j = 0; | ||
| while (SQL_SUCCESS == Sql_NextRow(mmysql_handle) && j < at->count) { | ||
| char *data; | ||
| CREATE(at->entries[j], struct s_autotrade_entry, 1); | ||
| Sql_GetData(mmysql_handle, 0, &data, NULL); at->entries[j]->item_id = atoi(data); | ||
| Sql_GetData(mmysql_handle, 1, &data, NULL); at->entries[j]->amount = atoi(data); | ||
| Sql_GetData(mmysql_handle, 2, &data, NULL); at->entries[j]->price = atoi(data); | ||
| @@ -779,8 +742,9 @@ void do_init_buyingstore_autotrade( void ) { | ||
| items += j; | ||
| Sql_FreeResult(mmysql_handle); | ||
| } | ||
| dbi_destroy(iter); | ||
|
|
||
| ShowStatus("Done loading '"CL_WHITE"%d"CL_RESET"' buyingstore autotraders with '"CL_WHITE"%d"CL_RESET"' items.\n", db_size(buyingstore_autotrader_db), items); | ||
| } | ||
| } | ||
|
|
||
| @@ -793,32 +757,34 @@ void do_init_buyingstore_autotrade( void ) { | ||
| } | ||
|
|
||
| /** | ||
| * Remove an autotrader's data | ||
| * @param at Autotrader | ||
| * @param remove If true will removes from buyingstore_autotrader_db | ||
| **/ | ||
| static void buyingstore_autotrader_remove(struct s_autotrader *at, bool remove) { | ||
| nullpo_retv(at); | ||
| if (at->count && at->entries) { | ||
| uint16 i = 0; | ||
| for (i = 0; i < at->count; i++) { | ||
| if (at->entries[i]) | ||
| aFree(at->entries[i]); | ||
| } | ||
| aFree(at->entries); | ||
| } | ||
| if (remove) | ||
| uidb_remove(buyingstore_autotrader_db, at->char_id); | ||
| aFree(at); | ||
| } | ||
|
|
||
| /** | ||
| * Clear all autotraders | ||
| * @author [Cydh] | ||
| */ | ||
| static int buyingstore_autotrader_free(DBKey key, DBData *data, va_list ap) { | ||
| struct s_autotrader *at = db_data2ptr(data); | ||
| if (at) | ||
| buyingstore_autotrader_remove(at, false); | ||
| return 0; | ||
| } | ||
|
|
||
| /** | ||
| @@ -827,7 +793,7 @@ void do_final_buyingstore_autotrade(void) { | ||
| */ | ||
| void do_final_buyingstore(void) { | ||
| db_destroy(buyingstore_db); | ||
| buyingstore_autotrader_db->destroy(buyingstore_autotrader_db, buyingstore_autotrader_free); | ||
| } | ||
|
|
||
| /** | ||
| @@ -836,5 +802,6 @@ void do_final_buyingstore(void) { | ||
| */ | ||
| void do_init_buyingstore(void) { | ||
| buyingstore_db = idb_alloc(DB_OPT_BASE); | ||
| buyingstore_autotrader_db = uidb_alloc(DB_OPT_BASE); | ||
| buyingstore_nextid = 0; | ||
| } | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
This already supports multi map server, since each map-server should have his own database table. The only problem could be if you switch one map from one map-server to another.