diff options
-rw-r--r-- | Changelog-Trunk.txt | 2 | ||||
-rw-r--r-- | src/char_sql/char.c | 85 |
2 files changed, 63 insertions, 24 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 13cd831fa..0c62e3882 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -1,5 +1,7 @@ Date Added +2011/08/30 + * Corrected SQL saving so that the server won't update the 'saved' data if there is an SQL error. It should fix possible dupes and other data synch issues when the SQL server is temporarily down during save. [Skotlex] 2011/08/23 * Rewrote the combo logic. Now it uses packet 0x7e1 to signal skill state changes rather than resending the whole skill list. [Skotlex] 2011/08/21 diff --git a/src/char_sql/char.c b/src/char_sql/char.c index 535338177..f7c9e0fa0 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -409,6 +409,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) int diff = 0; char save_status[128]; //For displaying save information. [Skotlex] struct mmo_charstatus *cp; + int errors = 0; //If there are any errors while saving, "cp" will not be updated at the end. StringBuf buf; if (char_id!=p->char_id) return 0; @@ -425,22 +426,28 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) //map inventory data if( memcmp(p->inventory, cp->inventory, sizeof(p->inventory)) ) { - memitemdata_to_sql(p->inventory, MAX_INVENTORY, p->char_id, TABLE_INVENTORY); - strcat(save_status, " inventory"); + if (!memitemdata_to_sql(p->inventory, MAX_INVENTORY, p->char_id, TABLE_INVENTORY)) + strcat(save_status, " inventory"); + else + errors++; } //map cart data if( memcmp(p->cart, cp->cart, sizeof(p->cart)) ) { - memitemdata_to_sql(p->cart, MAX_CART, p->char_id, TABLE_CART); - strcat(save_status, " cart"); + if (!memitemdata_to_sql(p->cart, MAX_CART, p->char_id, TABLE_CART)) + strcat(save_status, " cart"); + else + errors++; } //map storage data if( memcmp(p->storage.items, cp->storage.items, sizeof(p->storage.items)) ) { - memitemdata_to_sql(p->storage.items, MAX_STORAGE, p->account_id, TABLE_STORAGE); - strcat(save_status, " storage"); + if (!memitemdata_to_sql(p->storage.items, MAX_STORAGE, p->account_id, TABLE_STORAGE)) + strcat(save_status, " storage"); + else + errors++; } #ifdef TXT_SQL_CONVERT @@ -452,9 +459,9 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) char_db, p->char_id, p->account_id, p->slot, esc_name) ) { Sql_ShowDebug(sql_handle); - } - - strcat(save_status, " creation"); + errors++; + } else + strcat(save_status, " creation"); } #endif @@ -499,8 +506,9 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) p->account_id, p->char_id) ) { Sql_ShowDebug(sql_handle); - } - strcat(save_status, " status"); + errors++; + } else + strcat(save_status, " status"); } //Values that will seldom change (to speed up saving) @@ -525,9 +533,9 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) p->account_id, p->char_id) ) { Sql_ShowDebug(sql_handle); - } - - strcat(save_status, " status2"); + errors++; + } else + strcat(save_status, " status2"); } /* Mercenary Owner */ @@ -536,8 +544,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) (p->spear_calls != cp->spear_calls) || (p->spear_faith != cp->spear_faith) || (p->sword_calls != cp->sword_calls) || (p->sword_faith != cp->sword_faith) ) { - mercenary_owner_tosql(char_id, p); - strcat(save_status, " mercenary"); + if (mercenary_owner_tosql(char_id, p)) + strcat(save_status, " mercenary"); + else + errors++; } //memo points @@ -547,7 +557,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) //`memo` (`memo_id`,`char_id`,`map`,`x`,`y`) if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", memo_db, p->char_id) ) + { Sql_ShowDebug(sql_handle); + errors++; + } //insert here. StringBuf_Clear(&buf); @@ -566,9 +579,11 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) if( count ) { if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) ) + { Sql_ShowDebug(sql_handle); + errors++; + } } - strcat(save_status, " memo"); } @@ -583,7 +598,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) { //`skill` (`char_id`, `id`, `lv`) if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", skill_db, p->char_id) ) + { Sql_ShowDebug(sql_handle); + errors++; + } StringBuf_Clear(&buf); StringBuf_Printf(&buf, "INSERT INTO `%s`(`char_id`,`id`,`lv`) VALUES ", skill_db); @@ -601,7 +619,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) if( count ) { if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) ) + { Sql_ShowDebug(sql_handle); + errors++; + } } strcat(save_status, " skills"); @@ -619,7 +640,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) if(diff == 1) { //Save friends if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", friend_db, char_id) ) + { Sql_ShowDebug(sql_handle); + errors++; + } StringBuf_Clear(&buf); StringBuf_Printf(&buf, "INSERT INTO `%s` (`char_id`, `friend_account`, `friend_id`) VALUES ", friend_db); @@ -636,12 +660,12 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) if( count ) { if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) ) + { Sql_ShowDebug(sql_handle); - else - strcat(save_status, " friends"); + errors++; + } } - else //Friend list cleared. - strcat(save_status, " friends"); + strcat(save_status, " friends"); } #ifdef HOTKEY_SAVING @@ -660,8 +684,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) } if(diff) { if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) ) + { Sql_ShowDebug(sql_handle); - else + errors++; + } else strcat(save_status, " hotkeys"); } #endif @@ -669,7 +695,8 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) if (save_status[0]!='\0' && save_log) ShowInfo("Saved char %d - %s:%s.\n", char_id, p->name, save_status); #ifndef TXT_SQL_CONVERT - memcpy(cp, p, sizeof(struct mmo_charstatus)); + if (!errors) + memcpy(cp, p, sizeof(struct mmo_charstatus)); #else aFree(cp); #endif @@ -688,6 +715,7 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit struct item item; // temp storage variable bool* flag; // bit array for inventory matching bool found; + int errors = 0; switch (tableswitch) { case TABLE_INVENTORY: tablename = inventory_db; selectoption = "char_id"; break; @@ -770,7 +798,10 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit StringBuf_Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id); if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) ) + { Sql_ShowDebug(sql_handle); + errors++; + } } found = flag[i] = true; //Item dealt with, @@ -780,7 +811,10 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit if( !found ) {// Item not present in inventory, remove it. if( SQL_ERROR == Sql_Query(sql_handle, "DELETE from `%s` where `id`='%d'", tablename, item.id) ) + { Sql_ShowDebug(sql_handle); + errors++; + } } } SqlStmt_Free(stmt); @@ -812,12 +846,15 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit } if( found && SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) ) + { Sql_ShowDebug(sql_handle); + errors++; + } StringBuf_Destroy(&buf); aFree(flag); - return 0; + return errors; } int mmo_char_tobuf(uint8* buf, struct mmo_charstatus* p); |