summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt9
-rw-r--r--src/char_sql/char.c104
2 files changed, 51 insertions, 62 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 61e5d399f..f43f917a3 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -4,10 +4,7 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2007/09/22
- * Updated sql files [Playtester]
- * Added a sanity check for MAX_ZENY (doesn't compile if too big).
- * Redid the buildin_query_sql function. (fixes bugreport:81). [FlavioJS]
-2007/09/21
+ * Fixed a severe bug in inventory saving code (caused by r11192)
* Applied changes to clif_parse_globalmessage() from my WiP code
- clearer processing of the individual packet components
- proper code ordering, some more integrity checks
@@ -15,6 +12,10 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
- global chat logging no longer logs the entire string (w/ player name)
* Fixed global chat logging always crashing on a null pointer
* Added 'safestrnlen' to prevent null pointer crashes [ultramage]
+ * Updated sql files [Playtester]
+ * Added a sanity check for MAX_ZENY (doesn't compile if too big).
+ * Redid the buildin_query_sql function. (fixes bugreport:81). [FlavioJS]
+2007/09/21
* itemdb.c/h using a static array of 32k struct item_data* entries (faster
itemdb loockup and a first step to remove map_session_data->inventory_data).
* Fixed a typo in the configure script that replaced CFLAGS with CPPFLAGS
diff --git a/src/char_sql/char.c b/src/char_sql/char.c
index b493028b8..5579719c4 100644
--- a/src/char_sql/char.c
+++ b/src/char_sql/char.c
@@ -410,26 +410,7 @@ void read_gm_account(void)
mapif_send_gmaccounts();
}
-#endif //TXT_SQL_CONVERT
-int compare_item(const struct item* a, const struct item* b)
-{
-
- if(a->id == b->id &&
- a->nameid == b->nameid &&
- a->amount == b->amount &&
- a->equip == b->equip &&
- a->identify == b->identify &&
- a->refine == b->refine &&
- a->attribute == b->attribute)
- {
- int i;
- for (i=0; i<MAX_SLOTS && a->card[i]==b->card[i]; i++);
- return (i == MAX_SLOTS);
- }
- return 0;
-}
-#ifndef TXT_SQL_CONVERT
static void* create_charstatus(DBKey key, va_list args)
{
struct mmo_charstatus *cp;
@@ -750,38 +731,44 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit
while( SQL_SUCCESS == SqlStmt_NextRow(stmt) )
{
- bool found = false;
+ found = false;
// search for the presence of the item in the char's inventory
for( i = 0; i < max; ++i )
{
- if( flag[i] )
- continue; // this item was matched already, skip it
-
- if( items[i].id == 0 )
- { // to make skipping empty entries faster and to prevent saving them later
- flag[i] = true;
+ // skip empty and already matched entries
+ if( items[i].nameid == 0 || flag[i] )
continue;
- }
-
- if( compare_item(&items[i], &item) )
- ; // Equal - do nothing.
- else
- {
- // update all fields.
- StringBuf_Clear(&buf);
- StringBuf_Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d'",
- tablename, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute);
- for( j = 0; j < MAX_SLOTS; ++j )
- StringBuf_Printf(&buf, ", `card%d`=%d", j, items[i].card[j]);
- StringBuf_Printf(&buf, ", `amount`='%d' WHERE `id`='%d' LIMIT 1", items[i].amount, item.id);
-
- if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
- Sql_ShowDebug(sql_handle);
+ if( items[i].nameid == item.nameid
+ && items[i].card[0] == item.card[0]
+ && items[i].card[2] == item.card[2]
+ && items[i].card[3] == item.card[3]
+ ) { //They are the same item.
+ ARR_FIND( 0, MAX_SLOTS, j, items[i].card[j] != item.card[j] );
+ if( j == MAX_SLOTS &&
+ items[i].amount == item.amount &&
+ items[i].equip == item.equip &&
+ items[i].identify == item.identify &&
+ items[i].refine == item.refine &&
+ items[i].attribute == item.attribute )
+ ; //Do nothing.
+ else
+ {
+ // update all fields.
+ StringBuf_Clear(&buf);
+ StringBuf_Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d'",
+ tablename, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute);
+ for( j = 0; j < MAX_SLOTS; ++j )
+ StringBuf_Printf(&buf, ", `card%d`=%d", j, items[i].card[j]);
+ StringBuf_Printf(&buf, ", `amount`='%d' WHERE `id`='%d' LIMIT 1", items[i].amount, item.id);
+
+ if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
+ Sql_ShowDebug(sql_handle);
+ }
+
+ found = flag[i] = true; //Item dealt with,
+ break; //skip to next item in the db.
}
-
- found = flag[i] = true; //Item dealt with,
- break; //skip to next item in the db.
}
if( !found )
{// Item not present in inventory, remove it.
@@ -799,21 +786,22 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit
found = false;
// insert non-matched items into the db as new items
- for( i = 0, found = 0; i < max; ++i )
+ for( i = 0; i < max; ++i )
{
- if( !flag[i] )
- {
- if( found )
- StringBuf_AppendStr(&buf, ",");
- else
- found = true;
+ // skip empty and already matched entries
+ if( items[i].nameid == 0 || flag[i] )
+ continue;
- StringBuf_Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d'",
- id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute);
- for( j = 0; j < MAX_SLOTS; ++j )
- StringBuf_Printf(&buf, ", '%d'", items[i].card[j]);
- StringBuf_AppendStr(&buf, ")");
- }
+ if( found )
+ StringBuf_AppendStr(&buf, ",");
+ else
+ found = true;
+
+ StringBuf_Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d'",
+ id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute);
+ for( j = 0; j < MAX_SLOTS; ++j )
+ StringBuf_Printf(&buf, ", '%d'", items[i].card[j]);
+ StringBuf_AppendStr(&buf, ")");
}
if( found && SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )