Browse Source

Storage types optimization clean ups
* Removed char_inventory_to_sql and merged differences with char_memitemdata_to_sql.
Thanks to @Jeybla's suggestion!

aleos89 8 năm trước cách đây
mục cha
commit
cb252ded85
3 tập tin đã thay đổi với 38 bổ sung187 xóa
  1. 37 185
      src/char/char.c
  2. 0 1
      src/char/char.h
  3. 1 1
      src/char/int_storage.c

+ 37 - 185
src/char/char.c

@@ -261,8 +261,6 @@ static DBData char_create_charstatus(DBKey key, va_list args) {
 	return db_ptr2data(cp);
 }
 
-int char_inventory_to_sql(const struct item items[], int max, int id);
-
 int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
 	int i = 0;
 	int count = 0;
@@ -520,24 +518,35 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
 int char_memitemdata_to_sql(const struct item items[], int max, int id, int tableswitch) {
 	StringBuf buf;
 	SqlStmt* stmt;
-	int i,j;
-	const char* tablename;
-	const char* selectoption;
+	int i, j, offset = 0;
+	const char* tablename, *selectoption;
 	struct item item; // temp storage variable
 	bool* flag; // bit array for inventory matching
 	bool found;
 	int errors = 0;
 
 	switch (tableswitch) {
-		case TABLE_CART:			tablename = schema_config.cart_db;			selectoption = "char_id";		break;
-		case TABLE_STORAGE:			tablename = schema_config.storage_db;		selectoption = "account_id";	break;
-		case TABLE_GUILD_STORAGE:	tablename = schema_config.guild_storage_db;	selectoption = "guild_id";		break;
+		case TABLE_INVENTORY:
+			tablename = schema_config.inventory_db;
+			selectoption = "char_id";
+			break;
+		case TABLE_CART:
+			tablename = schema_config.cart_db;
+			selectoption = "char_id";
+			break;
+		case TABLE_STORAGE:
+			tablename = schema_config.storage_db;
+			selectoption = "account_id";
+			break;
+		case TABLE_GUILD_STORAGE:
+			tablename = schema_config.guild_storage_db;
+			selectoption = "guild_id";
+			break;
 		default:
 			ShowError("Invalid table name!\n");
 			return 1;
 	}
 
-
 	// The following code compares inventory with current database values
 	// and performs modification/deletion/insertion only on relevant rows.
 	// This approach is more complicated than a trivial delete&insert, but
@@ -545,6 +554,10 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
 
 	StringBuf_Init(&buf);
 	StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`");
+	if (tableswitch == TABLE_INVENTORY) {
+		StringBuf_Printf(&buf, ", `favorite`");
+		offset = 1;
+	}
 
 	for( i = 0; i < MAX_SLOTS; ++i )
 		StringBuf_Printf(&buf, ", `card%d`", i);
@@ -575,12 +588,14 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
 	SqlStmt_BindColumn(stmt, 7, SQLDT_UINT,      &item.expire_time, 0, NULL, NULL);
 	SqlStmt_BindColumn(stmt, 8, SQLDT_UINT,      &item.bound,       0, NULL, NULL);
 	SqlStmt_BindColumn(stmt, 9, SQLDT_UINT64,    &item.unique_id,   0, NULL, NULL);
+	if (tableswitch == TABLE_INVENTORY)
+		SqlStmt_BindColumn(stmt, 10, SQLDT_CHAR, &item.favorite,    0, NULL, NULL);
 	for( i = 0; i < MAX_SLOTS; ++i )
-		SqlStmt_BindColumn(stmt, 10+i, SQLDT_USHORT, &item.card[i], 0, NULL, NULL);
+		SqlStmt_BindColumn(stmt, 10+offset+i, SQLDT_USHORT, &item.card[i], 0, NULL, NULL);
 	for( i = 0; i < MAX_ITEM_RDM_OPT; ++i ) {
-		SqlStmt_BindColumn(stmt, 10+MAX_SLOTS+i*3, SQLDT_SHORT, &item.option[i].id, 0, NULL, NULL);
-		SqlStmt_BindColumn(stmt, 11+MAX_SLOTS+i*3, SQLDT_SHORT, &item.option[i].value, 0, NULL, NULL);
-		SqlStmt_BindColumn(stmt, 12+MAX_SLOTS+i*3, SQLDT_CHAR, &item.option[i].param, 0, NULL, NULL);
+		SqlStmt_BindColumn(stmt, 10+offset+MAX_SLOTS+i*3, SQLDT_SHORT, &item.option[i].id, 0, NULL, NULL);
+		SqlStmt_BindColumn(stmt, 11+offset+MAX_SLOTS+i*3, SQLDT_SHORT, &item.option[i].value, 0, NULL, NULL);
+		SqlStmt_BindColumn(stmt, 12+offset+MAX_SLOTS+i*3, SQLDT_CHAR, &item.option[i].param, 0, NULL, NULL);
 	}
 	// bit array indicating which inventory items have already been matched
 	flag = (bool*) aCalloc(max, sizeof(bool));
@@ -614,7 +629,8 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
 				    items[i].attribute == item.attribute &&
 				    items[i].expire_time == item.expire_time &&
 				    items[i].bound == item.bound &&
-					items[i].unique_id == item.unique_id )
+					items[i].unique_id == item.unique_id &&
+					(tableswitch != TABLE_INVENTORY || items[i].favorite == item.favorite) )
 				;	//Do nothing.
 				else
 				{
@@ -622,6 +638,8 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
 					StringBuf_Clear(&buf);
 					StringBuf_Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u', `bound`='%d', `unique_id`='%"PRIu64"'",
 						tablename, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].bound, items[i].unique_id);
+					if (tableswitch == TABLE_INVENTORY)
+						StringBuf_Printf(&buf, ", `favorite`='%d'", items[i].favorite);
 					for( j = 0; j < MAX_SLOTS; ++j )
 						StringBuf_Printf(&buf, ", `card%d`=%hu", j, items[i].card[j]);
 					for( j = 0; j < MAX_ITEM_RDM_OPT; ++j ) {
@@ -655,6 +673,8 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
 
 	StringBuf_Clear(&buf);
 	StringBuf_Printf(&buf, "INSERT INTO `%s`(`%s`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`", tablename, selectoption);
+	if (tableswitch == TABLE_INVENTORY)
+		StringBuf_Printf(&buf, ", `favorite`");
 	for( j = 0; j < MAX_SLOTS; ++j )
 		StringBuf_Printf(&buf, ", `card%d`", j);
 	for( j = 0; j < MAX_ITEM_RDM_OPT; ++j ) {
@@ -679,6 +699,8 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
 
 		StringBuf_Printf(&buf, "('%d', '%hu', '%d', '%d', '%d', '%d', '%d', '%u', '%d', '%"PRIu64"'",
 			id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].bound, items[i].unique_id);
+		if (tableswitch == TABLE_INVENTORY)
+			StringBuf_Printf(&buf, ", '%d'", items[i].favorite);
 		for( j = 0; j < MAX_SLOTS; ++j )
 			StringBuf_Printf(&buf, ", '%hu'", items[i].card[j]);
 		for( j = 0; j < MAX_ITEM_RDM_OPT; ++j ) {
@@ -695,177 +717,7 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
 		errors++;
 	}
 
-	ShowInfo("Saved %s data for %s: %d\n", (tableswitch == TABLE_CART ? "Cart" : (tableswitch == TABLE_STORAGE ? "Storage" : "Guild Storage") ), selectoption, id);
-
-	StringBuf_Destroy(&buf);
-	aFree(flag);
-
-	return errors;
-}
-/* pretty much a copy of memitemdata_to_sql except it handles inventory_db exclusively,
- * - this is required because inventory db is the only one with the 'favorite' column. */
-int char_inventory_to_sql(const struct item items[], int max, int char_id) {
-	StringBuf buf;
-	SqlStmt* stmt;
-	int i, j;
-	struct item item; // temp storage variable
-	bool* flag; // bit array for inventory matching
-	bool found;
-	int errors = 0;
-
-
-	// The following code compares inventory with current database values
-	// and performs modification/deletion/insertion only on relevant rows.
-	// This approach is more complicated than a trivial delete&insert, but
-	// it significantly reduces cpu load on the database server.
-
-	StringBuf_Init(&buf);
-	StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`, `unique_id`");
-	for( i = 0; i < MAX_SLOTS; ++i )
-		StringBuf_Printf(&buf, ", `card%d`", i);
-	for( i = 0; i < MAX_ITEM_RDM_OPT; ++i ) {
-		StringBuf_Printf(&buf, ", `option_id%d`", i);
-		StringBuf_Printf(&buf, ", `option_val%d`", i);
-		StringBuf_Printf(&buf, ", `option_parm%d`", i);
-	}
-	StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`='%d'", schema_config.inventory_db, char_id);
-
-	stmt = SqlStmt_Malloc(sql_handle);
-	if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) ||
-		SQL_ERROR == SqlStmt_Execute(stmt) )
-	{
-		SqlStmt_ShowDebug(stmt);
-		SqlStmt_Free(stmt);
-		StringBuf_Destroy(&buf);
-		return 1;
-	}
-
-	SqlStmt_BindColumn(stmt, 0, SQLDT_INT,       &item.id,          0, NULL, NULL);
-	SqlStmt_BindColumn(stmt, 1, SQLDT_USHORT,    &item.nameid,      0, NULL, NULL);
-	SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT,     &item.amount,      0, NULL, NULL);
-	SqlStmt_BindColumn(stmt, 3, SQLDT_UINT,      &item.equip,       0, NULL, NULL);
-	SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR,      &item.identify,    0, NULL, NULL);
-	SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR,      &item.refine,      0, NULL, NULL);
-	SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR,      &item.attribute,   0, NULL, NULL);
-	SqlStmt_BindColumn(stmt, 7, SQLDT_UINT,      &item.expire_time, 0, NULL, NULL);
-	SqlStmt_BindColumn(stmt, 8, SQLDT_CHAR,      &item.favorite,    0, NULL, NULL);
-	SqlStmt_BindColumn(stmt, 9, SQLDT_CHAR,      &item.bound,       0, NULL, NULL);
-	SqlStmt_BindColumn(stmt, 10,SQLDT_UINT64,    &item.unique_id,   0, NULL, NULL);
-	for( i = 0; i < MAX_SLOTS; ++i )
-		SqlStmt_BindColumn(stmt, 11+i, SQLDT_USHORT, &item.card[i], 0, NULL, NULL);
-	for( i = 0; i < MAX_ITEM_RDM_OPT; ++i ) {
-		SqlStmt_BindColumn(stmt, 11+MAX_SLOTS+i*3, SQLDT_SHORT, &item.option[i].id, 0, NULL, NULL);
-		SqlStmt_BindColumn(stmt, 12+MAX_SLOTS+i*3, SQLDT_SHORT, &item.option[i].value, 0, NULL, NULL);
-		SqlStmt_BindColumn(stmt, 13+MAX_SLOTS+i*3, SQLDT_CHAR, &item.option[i].param, 0, NULL, NULL);
-	}
-
-	// bit array indicating which inventory items have already been matched
-	flag = (bool*) aCalloc(max, sizeof(bool));
-
-	while( SQL_SUCCESS == SqlStmt_NextRow(stmt) ) {
-		found = false;
-		// search for the presence of the item in the char's inventory
-		for( i = 0; i < max; ++i ) {
-			// skip empty and already matched entries
-			if( items[i].nameid == 0 || flag[i] )
-				continue;
-
-			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.
-				int k;
-				
-				ARR_FIND( 0, MAX_SLOTS, j, items[i].card[j] != item.card[j] );
-				ARR_FIND( 0, MAX_ITEM_RDM_OPT, k, items[i].option[k].id != item.option[k].id || items[i].option[k].value != item.option[k].value || items[i].option[k].param != item.option[k].param );
-				
-				if( j == MAX_SLOTS &&
-					k == MAX_ITEM_RDM_OPT &&
-					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 &&
-					items[i].expire_time == item.expire_time &&
-					items[i].favorite == item.favorite &&
-					items[i].bound == item.bound &&
-					items[i].unique_id == item.unique_id )
-					;	//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', `expire_time`='%u', `favorite`='%d', `bound`='%d', `unique_id`='%"PRIu64"'",
-					    schema_config.inventory_db, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite, items[i].bound, items[i].unique_id);
-					for( j = 0; j < MAX_SLOTS; ++j )
-						StringBuf_Printf(&buf, ", `card%d`=%hu", j, items[i].card[j]);
-					for( j = 0; j < MAX_ITEM_RDM_OPT; ++j ) {
-						StringBuf_Printf(&buf, ", `option_id%d`=%d", j, items[i].option[j].id);
-						StringBuf_Printf(&buf, ", `option_val%d`=%d", j, items[i].option[j].value);
-						StringBuf_Printf(&buf, ", `option_parm%d`=%d", j, items[i].option[j].param);
-					}
-					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,
-				break; //skip to next item in the db.
-			}
-		}
-		if( !found ) {// Item not present in inventory, remove it.
-			if( SQL_ERROR == Sql_Query(sql_handle, "DELETE from `%s` where `id`='%d' LIMIT 1", schema_config.inventory_db, item.id) ) {
-				Sql_ShowDebug(sql_handle);
-				errors++;
-			}
-		}
-	}
-	SqlStmt_Free(stmt);
-
-	StringBuf_Clear(&buf);
-	StringBuf_Printf(&buf, "INSERT INTO `%s` (`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`, `unique_id`", schema_config.inventory_db);
-	for( i = 0; i < MAX_SLOTS; ++i )
-		StringBuf_Printf(&buf, ", `card%d`", i);
-	for( i = 0; i < MAX_ITEM_RDM_OPT; ++i ) {
-		StringBuf_Printf(&buf, ", `option_id%d`", i);
-		StringBuf_Printf(&buf, ", `option_val%d`", i);
-		StringBuf_Printf(&buf, ", `option_parm%d`", i);
-	}
-	StringBuf_AppendStr(&buf, ") VALUES ");
-
-	found = false;
-	// insert non-matched items into the db as new items
-	for( i = 0; i < max; ++i ) {
-		// skip empty and already matched entries
-		if( items[i].nameid == 0 || flag[i] )
-			continue;
-
-		if( found )
-			StringBuf_AppendStr(&buf, ",");
-		else
-			found = true;
-
-		StringBuf_Printf(&buf, "('%d', '%hu', '%d', '%d', '%d', '%d', '%d', '%u', '%d', '%d', '%"PRIu64"'",
-						 char_id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite, items[i].bound, items[i].unique_id);
-		for( j = 0; j < MAX_SLOTS; ++j )
-			StringBuf_Printf(&buf, ", '%hu'", items[i].card[j]);
-		for( j = 0; j < MAX_ITEM_RDM_OPT; ++j ) {
-			StringBuf_Printf(&buf, ", '%d'", items[i].option[j].id);
-			StringBuf_Printf(&buf, ", '%d'", items[i].option[j].value);
-			StringBuf_Printf(&buf, ", '%d'", items[i].option[j].param);
-		}
-		StringBuf_AppendStr(&buf, ")");
-	}
-
-	if( found && SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) ) {
-		Sql_ShowDebug(sql_handle);
-		errors++;
-	}
-
-	ShowInfo("Saved Inventory data for char_id: %d.\n", char_id);
+	ShowInfo("Saved %s data for %s: %d\n", (tableswitch == TABLE_INVENTORY ? "Inventory" : (tableswitch == TABLE_CART ? "Cart" : (tableswitch == TABLE_STORAGE ? "Storage" : "Guild Storage"))), selectoption, id);
 
 	StringBuf_Destroy(&buf);
 	aFree(flag);

+ 0 - 1
src/char/char.h

@@ -257,7 +257,6 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf);
 int char_delete_char_sql(uint32 char_id);
 int char_rename_char_sql(struct char_session_data *sd, uint32 char_id);
 int char_divorce_char_sql(int partner_id1, int partner_id2);
-int char_inventory_to_sql(const struct item items[], int max, int char_id);
 int char_memitemdata_to_sql(const struct item items[], int max, int id, int tableswitch);
 
 void disconnect_player(uint32 account_id);

+ 1 - 1
src/char/int_storage.c

@@ -22,7 +22,7 @@
  */
 static int inventory_tosql(uint32 char_id, struct s_storage* p)
 {
-	return char_inventory_to_sql(p->u.items_inventory, MAX_INVENTORY, char_id);
+	return char_memitemdata_to_sql(p->u.items_inventory, MAX_INVENTORY, char_id, TABLE_INVENTORY);
 }
 
 /**