Skip to content

Commit 89c8d49

Browse files
Merge pull request #144 from Hc747/master
Optimise container updating
2 parents f061ea8 + b31e26b commit 89c8d49

File tree

1 file changed

+61
-19
lines changed

1 file changed

+61
-19
lines changed

src/net/outgoing-packets.ts

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Position } from '@server/world/position';
77
import { LocationObject } from '@runejs/cache-parser';
88
import { Chunk, ChunkUpdateItem } from '@server/world/map/chunk';
99
import { WorldItem } from '@server/world/items/world-item';
10+
import { ByteBuffer } from '@runejs/byte-buffer';
1011

1112
/**
1213
* A helper class for sending various network packets back to the game client.
@@ -303,32 +304,73 @@ export class OutgoingPackets {
303304
this.queue(packet);
304305
}
305306

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');
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');
310310

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-
}
311+
const size = container.size;
312+
packet.put(size, 'SHORT');
313+
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)
324316

325-
packet.put(item.itemId + 1, 'SHORT'); // +1 because 0 means an empty slot
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;
326324
}
327-
});
325+
326+
payload.putBytes(buffer);
327+
}
328+
329+
packet.putBytes(this.strip(payload));
328330

329331
this.queue(packet);
330332
}
331333

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+
}
340+
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;
352+
}
353+
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+
332374
public sendUpdateAllWidgetItemsById(widget: { widgetId: number, containerId: number }, itemIds: number[]): void {
333375
const packet = new Packet(12, PacketType.DYNAMIC_LARGE);
334376
packet.put(widget.widgetId << 16 | widget.containerId, 'INT');

0 commit comments

Comments
 (0)