@@ -7,6 +7,7 @@ import { Position } from '@server/world/position';
7
7
import { LocationObject } from '@runejs/cache-parser' ;
8
8
import { Chunk , ChunkUpdateItem } from '@server/world/map/chunk' ;
9
9
import { WorldItem } from '@server/world/items/world-item' ;
10
+ import { ByteBuffer } from '@runejs/byte-buffer' ;
10
11
11
12
/**
12
13
* A helper class for sending various network packets back to the game client.
@@ -303,49 +304,79 @@ export class OutgoingPackets {
303
304
this . queue ( packet ) ;
304
305
}
305
306
306
- public sendUpdateAllWidgetItems ( widget : { widgetId : number , containerId : number } , container : ItemContainer ) : void {
307
- const packet = new Packet ( 12 , PacketType . DYNAMIC_LARGE ) ;
308
- packet . put ( widget . widgetId << 16 | widget . containerId , 'INT' ) ;
309
- packet . put ( container . size , 'SHORT' ) ;
310
-
311
- const items = container . items ;
312
- items . forEach ( item => {
313
- if ( ! item ) {
314
- // Empty slot
315
- packet . put ( 0 ) ;
316
- packet . put ( 0 , 'SHORT' ) ;
317
- } else {
318
- if ( item . amount >= 255 ) {
319
- packet . put ( 255 ) ;
320
- packet . put ( item . amount , 'INT' ) ;
321
- } else {
322
- packet . put ( item . amount ) ;
323
- }
307
+ public update ( packet : Packet , widget : { widgetId : number , containerId : number } , container : ItemContainer ) : void {
308
+ const packed = widget . widgetId << 16 | widget . containerId ;
309
+ packet . put ( packed , 'INT' ) ;
310
+
311
+ const size = container . size ;
312
+ packet . put ( size , 'SHORT' ) ;
324
313
325
- packet . put ( item . itemId + 1 , 'SHORT' ) ; // +1 because 0 means an empty slot
314
+ const bound = container . items . length * 7 ;
315
+ const payload = new Packet ( - 1 , PacketType . FIXED , bound ) ; //TODO: change default value of allocatedSize from 5000 to something reasonable (64 - 256 as most RS packets are quite small)
316
+
317
+ for ( let index = 0 ; index < size ; index += 8 ) {
318
+ const { bitset, buffer } = this . segment ( container , index ) ;
319
+
320
+ payload . put ( bitset , 'BYTE' ) ;
321
+
322
+ if ( bitset == 0 ) {
323
+ continue ;
326
324
}
327
- } ) ;
325
+
326
+ payload . putBytes ( buffer ) ;
327
+ }
328
+
329
+ packet . putBytes ( this . strip ( payload ) ) ;
328
330
329
331
this . queue ( packet ) ;
330
332
}
331
333
332
- public sendUpdateAllWidgetItemsById ( widget : { widgetId : number , containerId : number } , itemIds : number [ ] ) : void {
333
- const packet = new Packet ( 12 , PacketType . DYNAMIC_LARGE ) ;
334
- packet . put ( widget . widgetId << 16 | widget . containerId , 'INT' ) ;
335
- packet . put ( itemIds . length , 'SHORT' ) ;
334
+ private strip ( packet : Packet ) : Buffer {
335
+ const size = packet . writerIndex ;
336
+ const buffer = new ByteBuffer ( size ) ;
337
+ packet . copy ( buffer , 0 , 0 , size ) ;
338
+ return Buffer . from ( buffer ) ;
339
+ }
336
340
337
- itemIds . forEach ( itemId => {
338
- if ( ! itemId ) {
339
- // Empty slot
340
- packet . put ( 0 ) ;
341
- packet . put ( 0 , 'SHORT' ) ;
342
- } else {
343
- packet . put ( 1 ) ;
344
- packet . put ( itemId + 1 , 'SHORT' ) ; // +1 because 0 means an empty slot
341
+ private segment ( container : ItemContainer , start : number ) : { bitset : number , buffer : Buffer } {
342
+ const bound = 7 * 8 ;
343
+ const payload = new Packet ( - 1 , PacketType . FIXED , bound ) ;
344
+
345
+ let bitset : number = 0 ;
346
+
347
+ for ( let offset = 0 ; offset < 8 ; offset ++ ) {
348
+ const item = container . items [ start + offset ] ;
349
+
350
+ if ( ! item ) {
351
+ continue ;
345
352
}
346
- } ) ;
347
353
348
- this . queue ( packet ) ;
354
+ bitset |= 1 << offset ;
355
+
356
+ const large = item . amount >= 255 ;
357
+
358
+ if ( large ) {
359
+ payload . put ( 255 , 'BYTE' ) ;
360
+ }
361
+
362
+ payload . put ( item . amount , large ? 'INT' : 'BYTE' ) ;
363
+ payload . put ( item . itemId + 1 , 'SHORT' ) ;
364
+ }
365
+
366
+ return { bitset, buffer : this . strip ( payload ) } ;
367
+ }
368
+
369
+ public sendUpdateAllWidgetItems ( widget : { widgetId : number , containerId : number } , container : ItemContainer ) : void {
370
+ const packet = new Packet ( 12 , PacketType . DYNAMIC_LARGE ) ;
371
+ this . update ( packet , widget , container ) ;
372
+ }
373
+
374
+ public sendUpdateAllWidgetItemsById ( widget : { widgetId : number , containerId : number } , itemIds : number [ ] ) : void {
375
+ const container = new ItemContainer ( itemIds . length ) ;
376
+ const items = itemIds . map ( id => ( ! id ? null : { itemId : id , amount : 1 } ) ) ;
377
+ container . setAll ( items , false ) ;
378
+
379
+ this . sendUpdateAllWidgetItems ( widget , container ) ;
349
380
}
350
381
351
382
public setItemOnWidget ( widgetId : number , childId : number , itemId : number , zoom : number ) : void {
@@ -444,6 +475,13 @@ export class OutgoingPackets {
444
475
this . queue ( packet ) ;
445
476
}
446
477
478
+ public consoleMessage ( message : string ) : void {
479
+ const packet = new Packet ( 83 , PacketType . DYNAMIC_SMALL ) ;
480
+ packet . putString ( message ) ;
481
+
482
+ this . queue ( packet ) ;
483
+ }
484
+
447
485
public updateSkill ( skillId : number , level : number , exp : number ) : void {
448
486
const packet = new Packet ( 34 ) ;
449
487
packet . put ( level ) ;
0 commit comments