Browse Source

Fixed Cart save issue for vending (#1551)

* Added check if cart need to be saved first or not before vending
* Removed `id` from item struct when new item added to cart.
  * The `id` value from inventory is never be used, on relog, `id`s for cart are always use 'real' value from table.
  * 0-ing the value also prevent wrong `id` number while inserting records to `vending_items`.
* Ordered by `id` whiel loading cart items from table.
* Initialize `sd->inventory`,  `sd->inventory`, and `sd->storage` to 0 on `pc_authok`

Signed-off-by: Cydh Ramdh <cydh@pservero.com>
Cydh Ramdh 8 years ago
parent
commit
17946ea286
8 changed files with 40 additions and 12 deletions
  1. 2 1
      src/char/char.c
  2. 14 4
      src/char/int_storage.c
  3. 2 1
      src/common/mmo.h
  4. 0 3
      src/map/clif.c
  5. 10 1
      src/map/intif.c
  6. 5 1
      src/map/pc.c
  7. 1 0
      src/map/pc.h
  8. 6 1
      src/map/skill.c

+ 2 - 1
src/char/char.c

@@ -531,6 +531,7 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
 			selectoption = "char_id";
 			break;
 		case TABLE_CART:
+		case TABLE_CART_:
 			tablename = schema_config.cart_db;
 			selectoption = "char_id";
 			break;
@@ -717,7 +718,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_INVENTORY ? "Inventory" : (tableswitch == TABLE_CART ? "Cart" : (tableswitch == TABLE_STORAGE ? "Storage" : "Guild Storage"))), selectoption, id);
+	ShowInfo("Saved %s data for %s: %d\n", (tableswitch == TABLE_INVENTORY ? "Inventory" : (tableswitch == TABLE_GUILD_STORAGE ? "Guild Storage" : (tableswitch == TABLE_STORAGE ? "Storage" : "Cart"))), selectoption, id);
 
 	StringBuf_Destroy(&buf);
 	aFree(flag);

+ 14 - 4
src/char/int_storage.c

@@ -156,7 +156,7 @@ static bool cart_fromsql(uint32 char_id, struct s_storage* p)
 		StringBuf_Printf(&buf, ", `option_val%d`", i);
 		StringBuf_Printf(&buf, ", `option_parm%d`", i);
 	}
-	StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", schema_config.cart_db, MAX_CART);
+	StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`=? ORDER BY `id` LIMIT %d", schema_config.cart_db, MAX_CART);
 
 	if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
 		||	SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
@@ -677,15 +677,22 @@ static void mapif_storage_data_loaded(int fd, uint32 account_id, char type, stru
  * IZ 0x388b <account_id>.L <result>.B <type>.B
  * @param fd
  * @param account_id
+ * @param char_id
  * @param type
  */
-void mapif_storage_saved(int fd, uint32 account_id, bool sucess, char type) {
+void mapif_storage_saved(int fd, uint32 account_id, uint32 char_id, bool sucess, char type) {
 	WFIFOHEAD(fd,8);
 	WFIFOW(fd, 0) = 0x388b;
 	WFIFOL(fd, 2) = account_id;
 	WFIFOB(fd, 6) = sucess;
 	WFIFOB(fd, 7) = type;
 	WFIFOSET(fd,8);
+
+	if (type == TABLE_CART_) {
+		struct s_storage stor;
+		memset(&stor, 0, sizeof(struct s_storage));
+		mapif_storage_data_loaded(fd, account_id, type, stor, cart_fromsql(char_id, &stor));
+	}
 }
 
 /**
@@ -738,10 +745,13 @@ bool mapif_parse_StorageSave(int fd) {
 	switch(type){
 		case TABLE_INVENTORY: inventory_tosql(cid, &stor); break;
 		case TABLE_STORAGE:   storage_tosql(aid, &stor);   break;
-		case TABLE_CART:      cart_tosql(cid, &stor);      break;
+		case TABLE_CART:
+		case TABLE_CART_:
+			cart_tosql(cid, &stor);
+			break;
 		default: return false;
 	}
-	mapif_storage_saved(fd, aid, true, type);
+	mapif_storage_saved(fd, aid, cid, true, type);
 	return false;
 }
 

+ 2 - 1
src/common/mmo.h

@@ -297,8 +297,9 @@ struct skill_cooldown_data {
 };
 
 enum storage_type {
-	TABLE_INVENTORY,
+	TABLE_INVENTORY = 1,
 	TABLE_CART,
+	TABLE_CART_,
 	TABLE_STORAGE,
 	TABLE_GUILD_STORAGE,
 };

+ 0 - 3
src/map/clif.c

@@ -6912,9 +6912,6 @@ void clif_openvendingreq(struct map_session_data* sd, int num)
 
 	nullpo_retv(sd);
 
-	intif_storage_save(sd, TABLE_CART); // Save cart item data
-	intif_storage_request(sd, TABLE_CART); // Update cart item ID information
-
 	fd = sd->fd;
 	WFIFOHEAD(fd,packet_len(0x12d));
 	WFIFOW(fd,0) = 0x12d;

+ 10 - 1
src/map/intif.c

@@ -3160,7 +3160,10 @@ static bool intif_parse_StorageReceived(int fd)
 	switch (type) { 
 		case TABLE_INVENTORY: stor = &sd->inventory; break;
 		case TABLE_STORAGE: stor = &sd->storage; break;
-		case TABLE_CART: stor = &sd->cart; break;
+		case TABLE_CART:
+		case TABLE_CART_:
+			stor = &sd->cart;
+			break;
 		default: return false;
 	}
 
@@ -3214,6 +3217,10 @@ static bool intif_parse_StorageReceived(int fd)
 			}
 			break;
 
+		case TABLE_CART_:
+			clif_openvendingreq(sd, sd->vend_skill_lv+2);
+			break;
+
 		case TABLE_STORAGE:
 			pc_check_available_item(sd, ITMCHK_STORAGE);
 			break;
@@ -3237,6 +3244,7 @@ static void intif_parse_StorageSaved(int fd)
 				//ShowInfo("Storage has been saved (AID: %d).\n", RFIFOL(fd, 2));
 				break;
 			case TABLE_CART: // cart
+			case TABLE_CART_:
 				//ShowInfo("Cart has been saved (AID: %d).\n", RFIFOL(fd, 2));
 				break;
 			default:
@@ -3292,6 +3300,7 @@ bool intif_storage_save(struct map_session_data *sd, enum storage_type type)
 			stor = &sd->storage;
 			break;
 		case TABLE_CART: 
+		case TABLE_CART_:
 			stor = &sd->cart;
 			break;
 		default:

+ 5 - 1
src/map/pc.c

@@ -1148,7 +1148,10 @@ bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_
 	if (!(battle_config.display_skill_fail&2))
 		sd->state.showdelay = 1;
 
-	pc_setequipindex(sd); // required at the moment, to complete auth_ok [lighta]
+	memset(&sd->inventory, 0, sizeof(struct s_storage));
+	memset(&sd->cart, 0, sizeof(struct s_storage));
+	memset(&sd->storage, 0, sizeof(struct s_storage));
+	memset(&sd->equip_index, -1, sizeof(sd->equip_index));
 
 	if( sd->status.option&OPTION_INVISIBLE && !pc_can_use_command( sd, "hide", COMMAND_ATCOMMAND ) ){
 		sd->status.option &= ~OPTION_INVISIBLE;
@@ -5045,6 +5048,7 @@ unsigned char pc_cart_additem(struct map_session_data *sd,struct item *item,int
 			return 2; // no slot
 
 		memcpy(&sd->cart.u.items_cart[i],item,sizeof(sd->cart.u.items_cart[0]));
+		sd->cart.u.items_cart[i].id = 0;
 		sd->cart.u.items_cart[i].amount = amount;
 		sd->cart_num++;
 		clif_cart_additem(sd,i,amount,0);

+ 1 - 0
src/map/pc.h

@@ -519,6 +519,7 @@ struct map_session_data {
 	int vended_id;
 	int vender_id;
 	int vend_num;
+	uint16 vend_skill_lv;
 	char message[MESSAGE_SIZE];
 	struct s_vending vending[MAX_VENDING];
 

+ 6 - 1
src/map/skill.c

@@ -7300,7 +7300,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			else {
 				sd->state.prevend = 1;
 				sd->state.workinprogress = WIP_DISABLE_ALL;
-				clif_openvendingreq(sd,2+skill_lv);
+				sd->vend_skill_lv = skill_lv;
+				ARR_FIND(0, MAX_CART, i, sd->cart.u.items_cart[i].nameid && sd->cart.u.items_cart[i].id == 0);
+				if (i < MAX_CART)
+					intif_storage_save(sd, TABLE_CART_);
+				else
+					clif_openvendingreq(sd,2+skill_lv);
 			}
 		}
 		break;