Bladeren bron

Minor bug fix

If a player did not meet the requirements to reopen the buyingstore/vending for whatever reason the character is now set offline.

A possible examples I have tested with is to change the area where the player's shop was to novending, which will not allow him to open the shop in this area.
Lemongrass3110 11 jaren geleden
bovenliggende
commit
ff9b6253c2
4 gewijzigde bestanden met toevoegingen van 85 en 74 verwijderingen
  1. 46 40
      src/map/buyingstore.c
  2. 1 1
      src/map/buyingstore.h
  3. 37 32
      src/map/vending.c
  4. 1 1
      src/map/vending.h

+ 46 - 40
src/map/buyingstore.c

@@ -107,21 +107,21 @@ bool buyingstore_setup(struct map_session_data* sd, unsigned char slots){
 }
 
 
-void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count)
+bool buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count)
 {
 	unsigned int i, weight, listidx;
 	char message_sql[MESSAGE_SIZE*2];
 
 	if( !result || count == 0 )
 	{// canceled, or no items
-		return;
+		return false;
 	}
 
 	if( !battle_config.feature_buying_store || pc_istrading(sd) || sd->buyingstore.slots == 0 || count > sd->buyingstore.slots || zenylimit <= 0 || zenylimit > sd->status.zeny || !storename[0] )
 	{// disabled or invalid input
 		sd->buyingstore.slots = 0;
 		clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
-		return;
+		return false;
 	}
 
 	if( !pc_can_give_items(sd) )
@@ -129,24 +129,24 @@ void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
 		sd->buyingstore.slots = 0;
 		clif_displaymessage(sd->fd, msg_txt(sd,246));
 		clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
-		return;
+		return false;
 	}
 
 	if( sd->sc.data[SC_NOCHAT] && (sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM) )
 	{// custom: mute limitation
-		return;
+		return false;
 	}
 
 	if( map[sd->bl.m].flag.novending )
 	{// custom: no vending maps
 		clif_displaymessage(sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map"
-		return;
+		return false;
 	}
 
 	if( map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKNOVENDING) )
 	{// custom: no vending cells
 		clif_displaymessage(sd->fd, msg_txt(sd,204)); // "You can't open a shop on this cell."
-		return;
+		return false;
 	}
 
 	weight = sd->weight;
@@ -202,14 +202,14 @@ void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
 	{// invalid item/amount/price
 		sd->buyingstore.slots = 0;
 		clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
-		return;
+		return false;
 	}
 
 	if( (sd->max_weight*90)/100 < weight )
 	{// not able to carry all wanted items without getting overweight (90%)
 		sd->buyingstore.slots = 0;
 		clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE_OVERWEIGHT, weight);
-		return;
+		return false;
 	}
 
 	// success
@@ -233,6 +233,8 @@ void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
 
 	clif_buyingstore_myitemlist(sd);
 	clif_buyingstore_entry(sd);
+
+	return true;
 }
 
 
@@ -538,13 +540,12 @@ bool buyingstore_searchall(struct map_session_data* sd, const struct s_search_st
 	return true;
 }
 
-/** Open vending for Autotrader
+/** Open buyingstore for Autotrader
 * @param sd Player as autotrader
 */
 void buyingstore_reopen( struct map_session_data* sd ){
-	if (!sd || !autotrader_count || !autotraders)
-		return;
-	else { // Ready to open vending for this char
+	// Ready to open buyingstore for this char
+	if ( sd && autotrader_count > 0 && autotraders){
 		uint16 i;
 		uint8 *data, *p;
 		uint16 j, count;
@@ -554,7 +555,7 @@ void buyingstore_reopen( struct map_session_data* sd ){
 			return;
 		}
 		
-		// Init vending data for autotrader
+		// Init buyingstore data for autotrader
 		CREATE(data, uint8, autotraders[i]->count * 8);
 
 		for (j = 0, p = data, count = autotraders[i]->count; j < autotraders[i]->count; j++) {
@@ -570,26 +571,33 @@ void buyingstore_reopen( struct map_session_data* sd ){
 			p += 8;
 		}
 
-		// Open the shop again
-		buyingstore_setup( sd, (unsigned char)autotraders[i]->count );
-		buyingstore_create( sd, autotraders[i]->limit, 1, autotraders[i]->title, data, autotraders[i]->count );
-		aFree(data);
+		// Open the buyingstore again
+		if( buyingstore_setup( sd, (unsigned char)autotraders[i]->count ) &&
+			buyingstore_create( sd, autotraders[i]->limit, 1, autotraders[i]->title, data, autotraders[i]->count ) )
+		{
+			ShowInfo("Loaded autotrade buyingstore data 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);
 
-		ShowInfo("Loaded autotrade buyingstore data 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);
+			// Set him to autotrade
+			if (Sql_Query( mmysql_handle, "UPDATE `%s` SET `autotrade` = 1 WHERE `id` = %d;",
+				buyingstore_db, sd->buyer_id ) != SQL_SUCCESS )
+			{
+				Sql_ShowDebug( mmysql_handle );
+			}
 
-		// Set him to autotrade
-		if (Sql_Query( mmysql_handle, "UPDATE `%s` SET `autotrade` = 1 WHERE `id` = %d;",
-			buyingstore_db, sd->buyer_id ) != SQL_SUCCESS )
-		{
-			Sql_ShowDebug( mmysql_handle );
-		}
+			// Make him look perfect
+			unit_setdir(&sd->bl,battle_config.feature_autotrade_direction);
 
-		// Make him look perfect
-		unit_setdir(&sd->bl,battle_config.feature_autotrade_direction);
+			if( battle_config.feature_autotrade_sit )
+				pc_setsit(sd);
+		}else{
+			// Failed to open the buyingstore, set him offline
+			ShowWarning("Failed to load autotrade buyingstore data for '"CL_WHITE"%s"CL_RESET"' with '"CL_WHITE"%d"CL_RESET"' items\n", sd->status.name, count );
 
-		if( battle_config.feature_autotrade_sit )
-			pc_setsit(sd);
+			map_quit( sd );
+		}
+
+		aFree(data);
 
 		//If the last autotrade is loaded, clear autotraders [Cydh]
 		if (i+1 >= autotrader_count)
@@ -606,7 +614,7 @@ void do_init_buyingstore_autotrade( void ) {
 		autotrader_count = 0;
 
 		// Get autotrader from table. `map`, `x`, and `y`, aren't used here
-		// Just read player that has data at vending_items [Cydh]
+		// Just read player that has data at buyingstore_items [Cydh]
 		if (Sql_Query(mmysql_handle,
 			"SELECT `id`, `account_id`, `char_id`, `sex`, `title`, `limit` "
 			"FROM `%s` "
@@ -623,6 +631,12 @@ void do_init_buyingstore_autotrade( void ) {
 		// Init autotraders
 		CREATE(autotraders, struct s_autotrade *, autotrader_count);
 
+		if (autotraders == NULL) { //This is shouldn't happen [Cydh]
+			ShowError("Failed to initialize buyingstore autotraders!\n");
+			Sql_FreeResult(mmysql_handle);
+			return;
+		}
+
 		// Init each autotrader data
 		i = 0;
 		while (SQL_SUCCESS == Sql_NextRow(mmysql_handle) && i < autotrader_count) {
@@ -650,12 +664,6 @@ void do_init_buyingstore_autotrade( void ) {
 		}
 		Sql_FreeResult(mmysql_handle);
 
-		if (autotraders == NULL) { //This is shouldn't happen [Cydh]
-			ShowError("Failed to initialize autotraders!\n");
-			do_final_buyingstore_autotrade();
-			return;
-		}
-
 		//Init items on vending list each autotrader
 		for (i = 0; i < autotrader_count; i++){
 			struct s_autotrade *at = NULL;
@@ -714,9 +722,7 @@ void do_init_buyingstore_autotrade( void ) {
 * @author [Cydh]
 */
 void do_final_buyingstore_autotrade(void) {
-	if (!autotrader_count || !autotraders)
-		return;
-	else {
+	if (autotrader_count && autotraders){
 		uint16 i = 0;
 		while (i < autotrader_count) { //Free the autotrader
 			if (autotraders[i] == NULL)

+ 1 - 1
src/map/buyingstore.h

@@ -23,7 +23,7 @@ struct s_buyingstore
 };
 
 bool buyingstore_setup(struct map_session_data* sd, unsigned char slots);
-void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count);
+bool buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count);
 void buyingstore_close(struct map_session_data* sd);
 void buyingstore_open(struct map_session_data* sd, int account_id);
 void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int buyer_id, const uint8* itemlist, unsigned int count);

+ 37 - 32
src/map/vending.c

@@ -297,7 +297,7 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
  *	data := {<index>.w <amount>.w <value>.l}[count]
  * @param count : number of different items
  */
-void vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count) {
+bool vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count) {
 	int i, j;
 	int vending_skill_lvl;
 	char message_sql[MESSAGE_SIZE*2];
@@ -305,21 +305,21 @@ void vending_openvending(struct map_session_data* sd, const char* message, const
 	nullpo_retv(sd);
 
 	if ( pc_isdead(sd) || !sd->state.prevend || pc_istrading(sd))
-		return; // can't open vendings lying dead || didn't use via the skill (wpe/hack) || can't have 2 shops at once
+		return false; // can't open vendings lying dead || didn't use via the skill (wpe/hack) || can't have 2 shops at once
 
 	vending_skill_lvl = pc_checkskill(sd, MC_VENDING);
 	
 	// skill level and cart check
 	if( !vending_skill_lvl || !pc_iscarton(sd) ) {
 		clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
-		return;
+		return false;
 	}
 
 	// check number of items in shop
 	if( count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl )
 	{	// invalid item count
 		clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
-		return;
+		return false;
 	}
 
 	// filter out invalid items
@@ -353,7 +353,7 @@ void vending_openvending(struct map_session_data* sd, const char* message, const
 
 	if( i == 0 ) { // no valid item found
 		clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); // custom reply packet
-		return;
+		return false;
 	}
 	sd->state.prevend = 0;
 	sd->state.vending = true;
@@ -377,6 +377,8 @@ void vending_openvending(struct map_session_data* sd, const char* message, const
 	clif_showvendingboard(&sd->bl,message,0);
 
 	idb_put(vending_db, sd->status.char_id, sd);
+
+	return true;
 }
 
 /**
@@ -463,9 +465,8 @@ bool vending_searchall(struct map_session_data* sd, const struct s_search_store_
 * @param sd Player as autotrader
 */
 void vending_reopen( struct map_session_data* sd ){
-	if (!sd || !autotrader_count || !autotraders)
-		return;
-	else { // Ready to open vending for this char
+	// Ready to open vending for this char
+	if ( sd && autotrader_count > 0 && autotraders){
 		uint16 i;
 		uint8 *data, *p;
 		uint16 j, count;
@@ -502,25 +503,31 @@ void vending_reopen( struct map_session_data* sd ){
 		// Set him into a hacked prevend state
 		sd->state.prevend = 1;
 
-		// Open the shop again
-		vending_openvending(sd, autotraders[i]->title, data, count);
-		aFree(data);
+		// Open the vending again
+		if( vending_openvending(sd, autotraders[i]->title, data, count) ){
+			// Set him to autotrade
+			if (Sql_Query( mmysql_handle, "UPDATE `%s` SET `autotrade` = 1 WHERE `id` = %d;",
+				vendings_db, sd->vender_id ) != SQL_SUCCESS )
+			{
+				Sql_ShowDebug( mmysql_handle );
+			}
 
-		ShowInfo("Loaded autotrade vending data 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);
+			// Make him look perfect
+			unit_setdir(&sd->bl,battle_config.feature_autotrade_direction);
 
-		// Set him to autotrade
-		if (Sql_Query( mmysql_handle, "UPDATE `%s` SET `autotrade` = 1 WHERE `id` = %d;",
-			vendings_db, sd->vender_id ) != SQL_SUCCESS )
-		{
-			Sql_ShowDebug( mmysql_handle );
-		}
+			if( battle_config.feature_autotrade_sit )
+				pc_setsit(sd);
 
-		// Make him look perfect
-		unit_setdir(&sd->bl,battle_config.feature_autotrade_direction);
+			ShowInfo("Loaded autotrade vending data 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);
+		}else{
+			// Failed to open the vending, set him offline
+			ShowWarning("Failed to load autotrade vending data for '"CL_WHITE"%s"CL_RESET"' with '"CL_WHITE"%d"CL_RESET"' items\n", sd->status.name, count );
+
+			map_quit( sd );
+		}
 
-		if( battle_config.feature_autotrade_sit )
-			pc_setsit(sd);
+		aFree(data);
 
 		//If the last autotrade is loaded, clear autotraders [Cydh]
 		if (i+1 >= autotrader_count)
@@ -554,6 +561,12 @@ void do_init_vending_autotrade( void ) {
 		// Init autotraders
 		CREATE(autotraders, struct s_autotrade *, autotrader_count);
 
+		if (autotraders == NULL) { //This is shouldn't happen [Cydh]
+			ShowError("Failed to initialize vending autotraders!\n");
+			Sql_FreeResult(mmysql_handle);
+			return;
+		}
+
 		// Init each autotrader data
 		i = 0;
 		while (SQL_SUCCESS == Sql_NextRow(mmysql_handle) && i < autotrader_count) {
@@ -580,12 +593,6 @@ void do_init_vending_autotrade( void ) {
 		}
 		Sql_FreeResult(mmysql_handle);
 
-		if (autotraders == NULL) { //This is shouldn't happen [Cydh]
-			ShowError("Failed to initialize autotraders!\n");
-			do_final_vending_autotrade();
-			return;
-		}
-
 		//Init items on vending list each autotrader
 		for (i = 0; i < autotrader_count; i++){
 			struct s_autotrade *at = NULL;
@@ -644,9 +651,7 @@ void do_init_vending_autotrade( void ) {
 * @author [Cydh]
 */
 void do_final_vending_autotrade(void) {
-	if (!autotrader_count || !autotraders)
-		return;
-	else {
+	if (autotrader_count && autotraders){
 		uint16 i = 0;
 		while (i < autotrader_count) { //Free the autotrader
 			if (autotraders[i] == NULL)

+ 1 - 1
src/map/vending.h

@@ -22,7 +22,7 @@ void do_init_vending_autotrade( void );
  
 void vending_reopen( struct map_session_data* sd );
 void vending_closevending(struct map_session_data* sd);
-void vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count);
+bool vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count);
 void vending_vendinglistreq(struct map_session_data* sd, int id);
 void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const uint8* data, int count);
 bool vending_search(struct map_session_data* sd, unsigned short nameid);