Ver Fonte

Added support for really big cashshops (#7763)

Added some malloc reporting
Forward socket allocation information
Forward WFIFOHEAD allocation information
Cleanup to clif_cashshop_show
Cleanup to clif_cashshop_result
Cleanup to clif_cashshop_list

Fixes #7757

Thanks to @ChiesaV
Lemongrass3110 há 1 ano atrás
pai
commit
6f5706a945
6 ficheiros alterados com 43 adições e 28 exclusões
  1. 4 7
      src/common/malloc.cpp
  2. 2 0
      src/common/malloc.hpp
  3. 5 7
      src/common/socket.cpp
  4. 11 3
      src/common/socket.hpp
  5. 20 11
      src/map/clif.cpp
  6. 1 0
      src/map/packets.hpp

+ 4 - 7
src/common/malloc.cpp

@@ -234,14 +234,11 @@ void* _mmalloc(size_t size, const char *file, int line, const char *func )
 	short size_hash = size2hash( size );
 	struct unit_head *head;
 
-	if (((long) size) < 0) {
-		ShowError("_mmalloc: %" PRIuPTR "\n", size);
-		return NULL;
-	}
-	
-	if(size == 0) {
-		return NULL;
+	if( static_cast<long>( size ) < 0 || size == 0 ){
+		ShowError( "_mmalloc: Invalid allocation size %" PRIuPTR " bytes at %s:%d\n", size, file, line );
+		return nullptr;
 	}
+
 	memmgr_usage_bytes += size;
 
 	/* To ensure the area that exceeds the length of the block, using malloc () to */

+ 2 - 0
src/common/malloc.hpp

@@ -94,6 +94,8 @@
 // should be merged with any of above later
 #define CREATE(result, type, number) (result) = (type *) aCalloc ((number), sizeof(type))
 #define RECREATE(result, type, number) (result) = (type *) aRealloc ((result), sizeof(type) * (number))
+#define CREATE2( result, type, number, file, line, func ) (result) = (type*)aCalloc2( ( number ), sizeof( type ), ( file ), ( line ), ( func ) )
+#define RECREATE2( result, type, number, file, line, func ) (result) = (type*)aRealloc2( ( result ), sizeof( type ) * ( number ), ( file ), ( line ), ( func ) )
 
 ////////////////////////////////////////////////
 

+ 5 - 7
src/common/socket.cpp

@@ -750,25 +750,23 @@ static void delete_session(int fd)
 	}
 }
 
-int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size)
-{
+int _realloc_fifo( int fd, unsigned int rfifo_size, unsigned int wfifo_size, const char* file, int line, const char* func ){
 	if( !session_isValid(fd) )
 		return 0;
 
 	if( session[fd]->max_rdata != rfifo_size && session[fd]->rdata_size < rfifo_size) {
-		RECREATE(session[fd]->rdata, unsigned char, rfifo_size);
+		RECREATE2( session[fd]->rdata, unsigned char, rfifo_size, file, line, func );
 		session[fd]->max_rdata  = rfifo_size;
 	}
 
 	if( session[fd]->max_wdata != wfifo_size && session[fd]->wdata_size < wfifo_size) {
-		RECREATE(session[fd]->wdata, unsigned char, wfifo_size);
+		RECREATE2( session[fd]->wdata, unsigned char, wfifo_size, file, line, func );
 		session[fd]->max_wdata  = wfifo_size;
 	}
 	return 0;
 }
 
-int realloc_writefifo(int fd, size_t addition)
-{
+int _realloc_writefifo( int fd, size_t addition, const char* file, int line, const char* func ){
 	size_t newsize;
 
 	if( !session_isValid(fd) ) // might not happen
@@ -788,7 +786,7 @@ int realloc_writefifo(int fd, size_t addition)
 	else // no change
 		return 0;
 
-	RECREATE(session[fd]->wdata, unsigned char, newsize);
+	RECREATE2( session[fd]->wdata, unsigned char, newsize, file, line, func );
 	session[fd]->max_wdata  = newsize;
 
 	return 0;

+ 11 - 3
src/common/socket.hpp

@@ -17,6 +17,7 @@
 #include <time.h>
 
 #include "cbasetypes.hpp"
+#include "malloc.hpp"
 #include "timer.hpp" // t_tick
 
 #ifndef MAXCONN
@@ -27,7 +28,12 @@
 
 // socket I/O macros
 #define RFIFOHEAD(fd)
-#define WFIFOHEAD(fd, size) do{ if((fd) && session[fd]->wdata_size + (size) > session[fd]->max_wdata ) realloc_writefifo(fd, size); }while(0)
+#define WFIFOHEAD( fd, size ) \
+	do{ \
+		if( ( fd ) && session[( fd )]->wdata_size + ( size ) > session[( fd )]->max_wdata ){ \
+			_realloc_writefifo( ( fd ), ( size ), ALC_MARK ); \
+		} \
+	}while( false )
 #define RFIFOP(fd,pos) (session[fd]->rdata + session[fd]->rdata_pos + (pos))
 #define WFIFOP(fd,pos) (session[fd]->wdata + session[fd]->wdata_size + (pos))
 
@@ -127,8 +133,10 @@ extern bool session_isActive(int fd);
 
 int make_listen_bind(uint32 ip, uint16 port);
 int make_connection(uint32 ip, uint16 port, bool silent, int timeout);
-int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size);
-int realloc_writefifo(int fd, size_t addition);
+#define realloc_fifo( fd, rfifo_size, wfifo_size ) _realloc_fifo( ( fd ), ( rfifo_size ), ( wfifo_size ), ALC_MARK )
+#define realloc_writefifo( fd, addition ) _realloc_writefifo( ( fd ), ( addition ), ALC_MARK )
+int _realloc_fifo( int fd, unsigned int rfifo_size, unsigned int wfifo_size, const char* file, int line, const char* func );
+int _realloc_writefifo( int fd, size_t addition, const char* file, int line, const char* func );
 int WFIFOSET(int fd, size_t len);
 int RFIFOSKIP(int fd, size_t len);
 

+ 20 - 11
src/map/clif.cpp

@@ -17245,6 +17245,7 @@ void clif_cashshop_list( map_session_data* sd ){
 		struct PACKET_ZC_ACK_SCHEDULER_CASHITEM *p = (struct PACKET_ZC_ACK_SCHEDULER_CASHITEM *)packet_buffer;
 
 		p->packetType = HEADER_ZC_ACK_SCHEDULER_CASHITEM;
+		p->packetLength = sizeof( struct PACKET_ZC_ACK_SCHEDULER_CASHITEM );
 		p->count = 0;
 		p->tabNum = tab->tab;
 
@@ -17263,9 +17264,17 @@ void clif_cashshop_list( map_session_data* sd ){
 			}
 #endif
 			p->count++;
-		}
+			p->packetLength += sizeof( p->items[0] );
 
-		p->packetLength = sizeof( struct PACKET_ZC_ACK_SCHEDULER_CASHITEM ) + p->count * sizeof( struct PACKET_ZC_ACK_SCHEDULER_CASHITEM_sub );
+			if( ( static_cast<size_t>( p->packetLength ) + sizeof( p->items[0] ) ) >= INT16_MAX ){
+				// Send current data
+				clif_send( p, p->packetLength, &sd->bl, SELF );
+
+				// Start a new packet
+				p->count = 0;
+				p->packetLength = sizeof( struct PACKET_ZC_ACK_SCHEDULER_CASHITEM );
+			}
+		}
 
 		clif_send( p, p->packetLength, &sd->bl, SELF );
 	}
@@ -17300,12 +17309,10 @@ void clif_cashshop_show( map_session_data *sd, struct npc_data *nd ){
 
 	npc_shop_currency_type( sd, nd, cost, true );
 
-	uint16 len = sizeof( struct PACKET_ZC_PC_CASH_POINT_ITEMLIST ) + nd->u.shop.count * sizeof( struct PACKET_ZC_PC_CASH_POINT_ITEMLIST_sub );
-	WFIFOHEAD( fd, len );
-	struct PACKET_ZC_PC_CASH_POINT_ITEMLIST* p = (struct PACKET_ZC_PC_CASH_POINT_ITEMLIST *)WFIFOP( fd, 0 );
+	struct PACKET_ZC_PC_CASH_POINT_ITEMLIST* p = (struct PACKET_ZC_PC_CASH_POINT_ITEMLIST*)packet_buffer;
 
-	p->packetType = 0x287;
-	p->packetLength = len;
+	p->packetType = HEADER_ZC_PC_CASH_POINT_ITEMLIST;
+	p->packetLength = sizeof( *p );
 	p->cashPoints = cost[0];
 #if PACKETVER >= 20070711
 	p->kafraPoints = cost[1];
@@ -17323,9 +17330,11 @@ void clif_cashshop_show( map_session_data *sd, struct npc_data *nd ){
 		p->items[i].viewSprite = id->look;
 		memset( p->items[i].unused, 0, sizeof( p->items[i].unused ) );
 #endif
+
+		p->packetLength += sizeof( p->items[0] );
 	}
 
-	WFIFOSET( fd, len );
+	clif_send( p, p->packetLength, &sd->bl, SELF );
 }
 
 /// Cashshop Buy Ack (ZC_PC_CASH_POINT_UPDATE).
@@ -17369,9 +17378,9 @@ void clif_cashshop_result( map_session_data *sd, t_itemid item_id, uint16 result
 #if PACKETVER_MAIN_NUM >= 20101123 || PACKETVER_RE_NUM >= 20120328 || defined( PACKETVER_ZERO )
 	nullpo_retv( sd );
 
-	struct PACKET_ZC_SE_PC_BUY_CASHITEM_RESULT packet;
+	struct PACKET_ZC_SE_PC_BUY_CASHITEM_RESULT packet = {};
 
-	packet.packetType = 0x849;
+	packet.packetType = HEADER_ZC_SE_PC_BUY_CASHITEM_RESULT;
 	if( item_id != 0 ){
 		packet.itemId = client_nameid( item_id );
 	}else{
@@ -17381,7 +17390,7 @@ void clif_cashshop_result( map_session_data *sd, t_itemid item_id, uint16 result
 	packet.cashPoints = sd->cashPoints;
 	packet.kafraPoints = sd->kafraPoints;
 
-	clif_send( &packet, sizeof( struct PACKET_ZC_SE_PC_BUY_CASHITEM_RESULT ), &sd->bl, SELF );
+	clif_send( &packet, sizeof( packet ), &sd->bl, SELF );
 #endif
 }
 

+ 1 - 0
src/map/packets.hpp

@@ -506,6 +506,7 @@ DEFINE_PACKET_HEADER(ZC_FRIENDS_LIST, 0x201)
 DEFINE_PACKET_HEADER(ZC_NOTIFY_WEAPONITEMLIST, 0x221)
 DEFINE_PACKET_HEADER(ZC_ACK_WEAPONREFINE, 0x223)
 DEFINE_PACKET_HEADER(CZ_REQ_MAKINGITEM, 0x25b)
+DEFINE_PACKET_HEADER(ZC_PC_CASH_POINT_ITEMLIST, 0x287)
 DEFINE_PACKET_HEADER(ZC_CASH_TIME_COUNTER, 0x298)
 DEFINE_PACKET_HEADER(ZC_CASH_ITEM_DELETE, 0x299)
 DEFINE_PACKET_HEADER(ZC_NOTIFY_BIND_ON_EQUIP, 0x2d3)