diff --git a/package-lock.json b/package-lock.json index 72d413db8..584408bf2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -98,11 +98,21 @@ "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", "dev": true }, + "@runejs/byte-buffer": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@runejs/byte-buffer/-/byte-buffer-1.0.8.tgz", + "integrity": "sha512-tThSPAOlXbyukIEAvgv1nIzZsiP7MjfxIjMTmvnjMUmrlaVHmZowR3woXKtD7h/D1iEEQ333brw7RPi6x4bqjA==", + "requires": { + "@runejs/logger": "^1.0.0", + "typescript": "^3.7.2" + } + }, "@runejs/cache-parser": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@runejs/cache-parser/-/cache-parser-0.5.0.tgz", - "integrity": "sha512-BMGyshWyNDSQewYAzjRrykDrTKb6OqsJ4R6169G8Mhf0I+AN4XdfquV9NnV8HFJAeIpl6dZphjp7eTnMiyIC+w==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@runejs/cache-parser/-/cache-parser-0.6.3.tgz", + "integrity": "sha512-vIYz0PkPqKUbIDedpJ8JDFkHHcOSvzim/+97l0yMswcOZt5Tp+G2OA1zo8y9Nngs0OBw12bYUkhQ2d4ObqvlNQ==", "requires": { + "@runejs/byte-buffer": "^1.0.8", "@runejs/logger": "^1.0.0", "pngjs": "^3.4.0", "seek-bzip": "^1.0.5", diff --git a/package.json b/package.json index 77333d412..4e0061efa 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,8 @@ "license": "GPL-3.0", "dependencies": { "@hapi/joi": "^16.1.8", - "@runejs/cache-parser": "0.5.0", + "@runejs/cache-parser": "0.6.3", + "@runejs/byte-buffer": "1.0.8", "@runejs/logger": "^1.0.0", "bigi": "^1.4.2", "body-parser": "^1.19.0", diff --git a/src/game-server.ts b/src/game-server.ts index 0908fa2a5..ae88638d1 100644 --- a/src/game-server.ts +++ b/src/game-server.ts @@ -2,12 +2,12 @@ import * as net from 'net'; import { watch } from 'chokidar'; import * as CRC32 from 'crc-32'; -import { RsBuffer } from './net/rs-buffer'; import { World } from './world/world'; import { ClientConnection } from './net/client-connection'; import { logger } from '@runejs/logger'; import { Cache } from '@runejs/cache-parser'; import { parseServerConfig, ServerConfig } from '@server/world/config/server-config'; +import { ByteBuffer } from '@runejs/byte-buffer'; import { loadPlugins } from '@server/plugins/plugin-loader'; import { ActionPlugin, ActionType, sort } from '@server/plugins/plugin'; @@ -30,7 +30,7 @@ import { setQuestPlugins } from '@server/world/config/quests'; export let serverConfig: ServerConfig; export let cache: Cache; export let world: World; -export let crcTable: Buffer; +export let crcTable: ByteBuffer; export async function injectPlugins(): Promise { const actionTypes: { [key: string]: ActionPlugin[] } = {}; @@ -63,16 +63,16 @@ export async function injectPlugins(): Promise { function generateCrcTable(): void { const index = cache.metaChannel; - const indexLength = index.getBuffer().length; - const buffer = RsBuffer.create(4048); - buffer.writeByte(0); - buffer.writeIntBE(indexLength); + const indexLength = index.length; + const buffer = new ByteBuffer(4048); + buffer.put(0, 'BYTE'); + buffer.put(indexLength, 'INT'); for(let file = 0; file < (indexLength / 6); file++) { - const crcValue = CRC32.buf(cache.getRawFile(255, file).getBuffer()); - buffer.writeIntBE(crcValue); + const crcValue = CRC32.buf(cache.getRawFile(255, file)); + buffer.put(crcValue, 'INT'); } - crcTable = buffer.getBuffer(); + crcTable = buffer; } export function runGameServer(): void { @@ -107,7 +107,7 @@ export function runGameServer(): void { socket.on('data', data => { if(clientConnection) { - clientConnection.parseIncomingData(new RsBuffer(data)); + clientConnection.parseIncomingData(new ByteBuffer(data)); } }); diff --git a/src/net/client-connection.ts b/src/net/client-connection.ts index 887e4cff0..e217c750e 100644 --- a/src/net/client-connection.ts +++ b/src/net/client-connection.ts @@ -1,13 +1,13 @@ import { Socket } from 'net'; import { Player } from '@server/world/actor/player/player'; import { world } from '@server/game-server'; -import { RsBuffer } from './rs-buffer'; import { LoginHandshakeParser } from './data-parser/login-handshake-parser'; import { ClientLoginParser } from './data-parser/client-login-parser'; import { ClientPacketDataParser } from './data-parser/client-packet-data-parser'; import { DataParser } from './data-parser/data-parser'; import { VersionHandshakeParser } from '@server/net/data-parser/version-handshake-parser'; import { UpdateServerParser } from '@server/net/data-parser/update-server-parser'; +import { ByteBuffer } from '@runejs/byte-buffer'; enum ConnectionStage { VERSION_HANDSHAKE = 'VERSION_HANDSHAKE', @@ -35,10 +35,10 @@ export class ClientConnection { this.dataParser = null; } - public parseIncomingData(buffer?: RsBuffer): void { + public parseIncomingData(buffer?: ByteBuffer): void { try { if(!this.connectionStage) { - const packetId = buffer.readUnsignedByte(); + const packetId = buffer.get('BYTE', 'UNSIGNED'); if(packetId === 15) { this.connectionStage = ConnectionStage.VERSION_HANDSHAKE; diff --git a/src/net/data-parser/client-login-parser.ts b/src/net/data-parser/client-login-parser.ts index 440b2198c..22d2411d2 100644 --- a/src/net/data-parser/client-login-parser.ts +++ b/src/net/data-parser/client-login-parser.ts @@ -1,10 +1,10 @@ import BigInteger from 'bigi'; -import { RsBuffer } from '@server/net/rs-buffer'; import { Player } from '@server/world/actor/player/player'; import { Isaac } from '@server/net/isaac'; import { serverConfig, world } from '@server/game-server'; import { DataParser } from './data-parser'; import { logger } from '@runejs/logger/dist/logger'; +import { ByteBuffer } from '@runejs/byte-buffer'; const VALID_CHARS = ['_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', @@ -32,61 +32,61 @@ export class ClientLoginParser extends DataParser { private readonly rsaModulus = BigInteger(serverConfig.rsaMod); private readonly rsaExponent = BigInteger(serverConfig.rsaExp); - public parse(buffer?: RsBuffer): void { + public parse(buffer?: ByteBuffer): void { if(!buffer) { throw new Error('No data supplied for login'); } - const loginType = buffer.readUnsignedByte(); + const loginType = buffer.get('BYTE', 'UNSIGNED'); if(loginType !== 16 && loginType !== 18) { throw new Error('Invalid login type ' + loginType); } - let loginEncryptedSize = buffer.readUnsignedByte() - (36 + 1 + 1 + 2); + let loginEncryptedSize = buffer.get('BYTE', 'UNSIGNED') - (36 + 1 + 1 + 2); if(loginEncryptedSize <= 0) { throw new Error('Invalid login packet length ' + loginEncryptedSize); } - const gameVersion = buffer.readIntBE(); + const gameVersion = buffer.get('INT'); if(gameVersion !== 435) { throw new Error('Invalid game version ' + gameVersion); } - const isLowDetail: boolean = buffer.readByte() === 1; + const isLowDetail: boolean = buffer.get('BYTE') === 1; for(let i = 0; i < 13; i++) { - buffer.readIntBE(); // Cache indices + buffer.get('INT'); // Cache indices } loginEncryptedSize--; - const rsaBytes = buffer.readUnsignedByte(); + const rsaBytes = buffer.get('BYTE', 'UNSIGNED'); const encryptedBytes: Buffer = Buffer.alloc(rsaBytes); - buffer.getBuffer().copy(encryptedBytes, 0, buffer.getReaderIndex()); - const decrypted: RsBuffer = new RsBuffer(BigInteger.fromBuffer(encryptedBytes).modPow(this.rsaExponent, this.rsaModulus).toBuffer()); + buffer.copy(encryptedBytes, 0, buffer.readerIndex); + const decrypted = new ByteBuffer(BigInteger.fromBuffer(encryptedBytes).modPow(this.rsaExponent, this.rsaModulus).toBuffer()); - const blockId = decrypted.readByte(); + const blockId = decrypted.get('BYTE'); if(blockId !== 10) { throw new Error('Invalid block id ' + blockId); } - const clientKey1 = decrypted.readIntBE(); - const clientKey2 = decrypted.readIntBE(); - const incomingServerKey = decrypted.readLongBE(); + const clientKey1 = decrypted.get('INT'); + const clientKey2 = decrypted.get('INT'); + const incomingServerKey = BigInt(decrypted.get('LONG')); if(this.clientConnection.serverKey !== incomingServerKey) { throw new Error(`Server key mismatch - ${this.clientConnection.serverKey} != ${incomingServerKey}`); } - const clientUuid = decrypted.readIntBE(); - const usernameLong = decrypted.readLongBE(); + const clientUuid = decrypted.get('INT'); + const usernameLong = BigInt(decrypted.get('LONG')); const username = longToName(usernameLong); - const password = decrypted.readNewString(); + const password = decrypted.getString(); logger.info(`Login request: ${username}/${password}`); @@ -106,13 +106,13 @@ export class ClientLoginParser extends DataParser { world.registerPlayer(player); - const outputBuffer = RsBuffer.create(); - outputBuffer.writeByte(2); // login response code - outputBuffer.writeByte(player.rights.valueOf()); - outputBuffer.writeByte(0); // ??? - outputBuffer.writeShortBE(player.worldIndex + 1); - outputBuffer.writeByte(0); // ??? - this.clientConnection.socket.write(outputBuffer.getData()); + const outputBuffer = new ByteBuffer(6); + outputBuffer.put(2, 'BYTE'); // login response code + outputBuffer.put(player.rights.valueOf(), 'BYTE'); + outputBuffer.put(0, 'BYTE'); // ??? + outputBuffer.put(player.worldIndex + 1, 'SHORT'); + outputBuffer.put(0, 'BYTE'); // ??? + this.clientConnection.socket.write(outputBuffer); player.init(); diff --git a/src/net/data-parser/client-packet-data-parser.ts b/src/net/data-parser/client-packet-data-parser.ts index 9d8d0d1d6..6d5cf7251 100644 --- a/src/net/data-parser/client-packet-data-parser.ts +++ b/src/net/data-parser/client-packet-data-parser.ts @@ -1,7 +1,7 @@ -import { RsBuffer } from '@server/net/rs-buffer'; import { incomingPacketSizes } from '@server/net/incoming-packet-sizes'; import { handlePacket } from '@server/net/incoming-packet-directory'; import { DataParser } from './data-parser'; +import { ByteBuffer } from '@runejs/byte-buffer'; /** * Parses incoming packet data from the game client once the user is fully authenticated. @@ -10,16 +10,16 @@ export class ClientPacketDataParser extends DataParser { private activePacketId: number = null; private activePacketSize: number = null; - private activeBuffer: RsBuffer; + private activeBuffer: ByteBuffer; - public parse(buffer?: RsBuffer): void { + public parse(buffer?: ByteBuffer): void { if(!this.activeBuffer) { this.activeBuffer = buffer; } else if(buffer) { - const newBuffer = new RsBuffer(this.activeBuffer.getUnreadData()); - const activeLength = newBuffer.getBuffer().length; - newBuffer.ensureCapacity(activeLength + buffer.getBuffer().length); - buffer.getBuffer().copy(newBuffer.getBuffer(), activeLength, 0); + const readable = this.activeBuffer.readable; + const newBuffer = new ByteBuffer(readable + buffer.length); + this.activeBuffer.copy(newBuffer, 0, this.activeBuffer.readerIndex); + buffer.copy(newBuffer, readable, 0); this.activeBuffer = newBuffer; } @@ -34,41 +34,46 @@ export class ClientPacketDataParser extends DataParser { const inCipher = this.clientConnection.player.inCipher; if(this.activePacketId === -1) { - if(this.activeBuffer.getReadable() < 1) { + if(this.activeBuffer.readable < 1) { return; } - this.activePacketId = this.activeBuffer.readByte() & 0xff; + this.activePacketId = this.activeBuffer.get('BYTE', 'UNSIGNED'); this.activePacketId = (this.activePacketId - inCipher.rand()) & 0xff; this.activePacketSize = incomingPacketSizes[this.activePacketId]; } // Packet will provide the size if(this.activePacketSize === -1) { - if(this.activeBuffer.getReadable() < 1) { + if(this.activeBuffer.readable < 1) { return; } - this.activePacketSize = this.activeBuffer.readUnsignedByte(); + this.activePacketSize = this.activeBuffer.get('BYTE', 'UNSIGNED'); } // Packet has no set size let clearBuffer = false; if(this.activePacketSize === -3) { - if(this.activeBuffer.getReadable() < 1) { + if(this.activeBuffer.readable < 1) { return; } - this.activePacketSize = this.activeBuffer.getReadable(); + this.activePacketSize = this.activeBuffer.readable; clearBuffer = true; } - if(this.activeBuffer.getReadable() < this.activePacketSize) { + if(this.activeBuffer.readable < this.activePacketSize) { return; } // read packet data - const packetData = this.activePacketSize !== 0 ? this.activeBuffer.readBytes(this.activePacketSize) : null; + let packetData = null; + if(this.activePacketSize !== 0) { + packetData = new ByteBuffer(this.activePacketSize); + this.activeBuffer.copy(packetData, 0, this.activeBuffer.readerIndex, this.activeBuffer.readerIndex + this.activePacketSize); + this.activeBuffer.readerIndex += this.activePacketSize; + } handlePacket(this.clientConnection.player, this.activePacketId, this.activePacketSize, packetData); if(clearBuffer) { @@ -78,7 +83,7 @@ export class ClientPacketDataParser extends DataParser { this.activePacketId = null; this.activePacketSize = null; - if(this.activeBuffer !== null && this.activeBuffer.getReadable() > 0) { + if(this.activeBuffer !== null && this.activeBuffer.readable > 0) { this.parse(); } } diff --git a/src/net/data-parser/data-parser.ts b/src/net/data-parser/data-parser.ts index 448e5e508..b84128d6a 100644 --- a/src/net/data-parser/data-parser.ts +++ b/src/net/data-parser/data-parser.ts @@ -1,11 +1,11 @@ import { ClientConnection } from '@server/net/client-connection'; -import { RsBuffer } from '@server/net/rs-buffer'; +import { ByteBuffer } from '@runejs/byte-buffer'; export abstract class DataParser { public constructor(protected readonly clientConnection: ClientConnection) { } - public abstract parse(buffer?: RsBuffer, packetId?: number): void | boolean; + public abstract parse(buffer?: ByteBuffer, packetId?: number): void | boolean; } diff --git a/src/net/data-parser/login-handshake-parser.ts b/src/net/data-parser/login-handshake-parser.ts index df554cc5a..81c6154a7 100644 --- a/src/net/data-parser/login-handshake-parser.ts +++ b/src/net/data-parser/login-handshake-parser.ts @@ -1,25 +1,25 @@ -import { RsBuffer } from '@server/net/rs-buffer'; import { DataParser } from './data-parser'; +import { ByteBuffer } from '@runejs/byte-buffer'; /** * Controls the initial login handshake with the server. */ export class LoginHandshakeParser extends DataParser { - public parse(buffer: RsBuffer, packetId: number): void { + public parse(buffer: ByteBuffer, packetId: number): void { if(!buffer) { throw new Error('No data supplied for login handshake'); } if(packetId === 14) { - buffer.readUnsignedByte(); // Name hash + buffer.get('BYTE', 'UNSIGNED'); // Name hash const serverKey = BigInt(13371337); // TODO generate server_key - const outputBuffer = RsBuffer.create(); - outputBuffer.writeByte(0); // Initial server login response -> 0 for OK - outputBuffer.writeLongBE(serverKey); - this.clientConnection.socket.write(outputBuffer.getData()); + const outputBuffer = new ByteBuffer(9); + outputBuffer.put(0, 'BYTE'); // Initial server login response -> 0 for OK + outputBuffer.put(serverKey, 'LONG'); + this.clientConnection.socket.write(outputBuffer); this.clientConnection.serverKey = serverKey; } else { diff --git a/src/net/data-parser/update-server-parser.ts b/src/net/data-parser/update-server-parser.ts index 3dbcd8329..61e5e17b2 100644 --- a/src/net/data-parser/update-server-parser.ts +++ b/src/net/data-parser/update-server-parser.ts @@ -1,4 +1,4 @@ -import { RsBuffer } from '@server/net/rs-buffer'; +import { ByteBuffer } from '@runejs/byte-buffer'; import { DataParser } from './data-parser'; import { crcTable, cache } from '@server/game-server'; @@ -9,15 +9,15 @@ export class UpdateServerParser extends DataParser { private files: { file: number, index: number }[] = []; - public parse(buffer?: RsBuffer): void { + public parse(buffer?: ByteBuffer): void { if(!buffer) { return; } - while(buffer.getReadable() >= 4) { - const type = buffer.readUnsignedByte(); - const index = buffer.readUnsignedByte(); - const file = buffer.readUnsignedShortBE(); + while(buffer.readable >= 4) { + const type = buffer.get('BYTE', 'UNSIGNED'); + const index = buffer.get('BYTE', 'UNSIGNED'); + const file = buffer.get('SHORT', 'UNSIGNED'); switch(type) { case 0: // queue @@ -42,43 +42,40 @@ export class UpdateServerParser extends DataParser { } private generateFile(index: number, file: number): Buffer { - let cacheFile; + let cacheFile: ByteBuffer; if(index === 255 && file === 255) { - const crcBuffer = Buffer.alloc(crcTable.length); - crcTable.copy(crcBuffer, 0, 0); - cacheFile = new RsBuffer(crcBuffer); + cacheFile = new ByteBuffer(crcTable.length); + crcTable.copy(cacheFile, 0, 0); } else { cacheFile = cache.getRawFile(index, file); } - if(!cacheFile || cacheFile.getBuffer().length === 0) { + if(!cacheFile || cacheFile.length === 0) { throw new Error(`Cache file not found; file(${file}) with index(${index})`); } - const cacheFileBuffer = cacheFile.getBuffer(); + const buffer = new ByteBuffer((cacheFile.length - 2) + ((cacheFile.length - 2) / 511) + 8); + buffer.put(index, 'BYTE'); + buffer.put(file, 'SHORT'); - const buffer = RsBuffer.create((cacheFileBuffer.length - 2) + ((cacheFileBuffer.length - 2) / 511) + 8); - buffer.writeUnsignedByte(index); - buffer.writeUnsignedShortBE(file); - - let length: number = ((cacheFileBuffer.readUInt8(1) << 24) + (cacheFileBuffer.readUInt8(2) << 16) + - (cacheFileBuffer.readUInt8(3) << 8) + cacheFileBuffer.readUInt8(4)) + 9; - if(cacheFileBuffer[0] == 0) { + let length: number = ((cacheFile.at(1, 'UNSIGNED') << 24) + (cacheFile.at(2, 'UNSIGNED') << 16) + + (cacheFile.at(3, 'UNSIGNED') << 8) + cacheFile.at(4, 'UNSIGNED')) + 9; + if(cacheFile.at(0) === 0) { length -= 4; } let c = 3; for(let i = 0; i < length; i++) { - if(c == 512) { - buffer.writeUnsignedByte(255); + if(c === 512) { + buffer.put(255, 'BYTE'); c = 1; } - buffer.writeByte(cacheFileBuffer.readInt8(i)); + buffer.put(cacheFile.at(i), 'BYTE'); c++; } - return buffer.getData(); + return Buffer.from(buffer.flipWriter()); } } diff --git a/src/net/data-parser/version-handshake-parser.ts b/src/net/data-parser/version-handshake-parser.ts index 78843875d..39b0308cb 100644 --- a/src/net/data-parser/version-handshake-parser.ts +++ b/src/net/data-parser/version-handshake-parser.ts @@ -1,22 +1,22 @@ -import { RsBuffer } from '@server/net/rs-buffer'; import { DataParser } from './data-parser'; +import { ByteBuffer } from '@runejs/byte-buffer'; /** * Controls the version handshake with the server. */ export class VersionHandshakeParser extends DataParser { - public parse(buffer: RsBuffer, packetId: number): void { + public parse(buffer: ByteBuffer, packetId: number): void { if(!buffer) { throw new Error('No data supplied for version handshake'); } if(packetId === 15) { - const gameVersion = buffer.readIntBE(); + const gameVersion = buffer.get('INT'); - const outputBuffer = RsBuffer.create(); - outputBuffer.writeByte(gameVersion === 435 ? 0 : 6); - this.clientConnection.socket.write(outputBuffer.getData()); + const outputBuffer = new ByteBuffer(1); + outputBuffer.put(gameVersion === 435 ? 0 : 6, 'BYTE'); + this.clientConnection.socket.write(outputBuffer); } else { throw new Error('Invalid version handshake packet id.'); } diff --git a/src/net/incoming-packet-directory.ts b/src/net/incoming-packet-directory.ts index 6f674db1b..e45261004 100644 --- a/src/net/incoming-packet-directory.ts +++ b/src/net/incoming-packet-directory.ts @@ -1,6 +1,6 @@ import { Player } from '../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; import { logger } from '@runejs/logger'; +import { ByteBuffer } from '@runejs/byte-buffer'; import { incomingPacket } from './incoming-packet'; import { characterDesignPacket } from './incoming-packets/character-design-packet'; @@ -41,6 +41,8 @@ const packets: { [key: number]: incomingPacket } = { 83: itemSwapPacket, 40: itemOnItemPacket, + 24: itemOnObjectPacket, + 208: itemOnNpcPacket, 102: itemEquipPacket, 38: itemInteractionPacket, 98: itemInteractionPacket, @@ -52,8 +54,6 @@ const packets: { [key: number]: incomingPacket } = { 63: npcInteractionPacket, 116: npcInteractionPacket, - 24: itemOnObjectPacket, - 208: itemOnNpcPacket, 30: objectInteractionPacket, 164: objectInteractionPacket, @@ -73,7 +73,7 @@ export function handlePacket(player: Player, packetId: number, packetSize: numbe } new Promise(resolve => { - packetFunction(player, packetId, packetSize, new RsBuffer(buffer)); + packetFunction(player, packetId, packetSize, new ByteBuffer(buffer)); resolve(); }).catch(error => logger.error(`Error handling inbound packet: ${error}`)); } diff --git a/src/net/incoming-packet.ts b/src/net/incoming-packet.ts index eb50d2405..929635713 100644 --- a/src/net/incoming-packet.ts +++ b/src/net/incoming-packet.ts @@ -1,4 +1,4 @@ -import { RsBuffer } from '@server/net/rs-buffer'; import { Player } from '../world/actor/player/player'; +import { ByteBuffer } from '@runejs/byte-buffer'; -export type incomingPacket = (player: Player, packetId: number, packetSize: number, buffer: RsBuffer) => void; +export type incomingPacket = (player: Player, packetId: number, packetSize: number, buffer: ByteBuffer) => void; diff --git a/src/net/incoming-packets/button-click-packet.ts b/src/net/incoming-packets/button-click-packet.ts index 197421bbe..ce9393862 100644 --- a/src/net/incoming-packets/button-click-packet.ts +++ b/src/net/incoming-packets/button-click-packet.ts @@ -1,15 +1,15 @@ import { incomingPacket } from '../incoming-packet'; +import { ByteBuffer } from '@runejs/byte-buffer'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; import { buttonAction } from '@server/world/actor/player/action/button-action'; const ignoreButtons: string[] = [ '269:99' // character design accept button ]; -export const buttonClickPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { - const widgetId = packet.readShortBE(); - const buttonId = packet.readShortBE(); +export const buttonClickPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { + const widgetId = packet.get('SHORT'); + const buttonId = packet.get('SHORT'); if(ignoreButtons.indexOf(`${widgetId}:${buttonId}`) === -1) { buttonAction(player, widgetId, buttonId); diff --git a/src/net/incoming-packets/camera-turn-packet.ts b/src/net/incoming-packets/camera-turn-packet.ts index 584094df1..e766590cf 100644 --- a/src/net/incoming-packets/camera-turn-packet.ts +++ b/src/net/incoming-packets/camera-turn-packet.ts @@ -1,7 +1,7 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; +import { ByteBuffer } from '@runejs/byte-buffer'; -export const cameraTurnPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { +export const cameraTurnPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { // Do nothing }; diff --git a/src/net/incoming-packets/character-design-packet.ts b/src/net/incoming-packets/character-design-packet.ts index aaf66e5a4..e368a96ce 100644 --- a/src/net/incoming-packets/character-design-packet.ts +++ b/src/net/incoming-packets/character-design-packet.ts @@ -1,25 +1,25 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; import { widgets } from '../../world/config/widget'; +import { ByteBuffer } from '@runejs/byte-buffer'; -export const characterDesignPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { +export const characterDesignPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { if(!player.activeWidget || player.activeWidget.widgetId !== widgets.characterDesign) { return; } // @TODO verify validity of selections - const gender: number = packet.readByte(); + const gender: number = packet.get(); const models: number[] = new Array(7); const colors: number[] = new Array(5); for(let i = 0; i < models.length; i++) { - models[i] = packet.readByte(); + models[i] = packet.get(); } for(let i = 0; i < colors.length; i++) { - colors[i] = packet.readByte(); + colors[i] = packet.get(); } player.appearance = { diff --git a/src/net/incoming-packets/chat-packet.ts b/src/net/incoming-packets/chat-packet.ts index f356d3111..62668df14 100644 --- a/src/net/incoming-packets/chat-packet.ts +++ b/src/net/incoming-packets/chat-packet.ts @@ -1,11 +1,11 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; +import { ByteBuffer } from '@runejs/byte-buffer'; -export const chatPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { - packet.readByte(); - const color: number = packet.readByte(); - const effects: number = packet.readByte(); - const data: Buffer = packet.getUnreadData(); +export const chatPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { + packet.get(); + const color: number = packet.get(); + const effects: number = packet.get(); + const data: Buffer = Buffer.from(packet.getSlice(packet.readerIndex, packet.length - packet.readerIndex)); player.updateFlags.addChatMessage({ color, effects, data }); }; diff --git a/src/net/incoming-packets/command-packet.ts b/src/net/incoming-packets/command-packet.ts index 666f9c134..225ced06d 100644 --- a/src/net/incoming-packets/command-packet.ts +++ b/src/net/incoming-packets/command-packet.ts @@ -1,10 +1,10 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; import { inputCommandAction } from '../../world/actor/player/action/input-command-action'; +import { ByteBuffer } from '@runejs/byte-buffer'; -export const commandPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { - const input = packet.readNewString(); +export const commandPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { + const input = packet.getString(); if(!input || input.trim().length === 0) { return; diff --git a/src/net/incoming-packets/drop-item-packet.ts b/src/net/incoming-packets/drop-item-packet.ts index 2c849ad84..b93107600 100644 --- a/src/net/incoming-packets/drop-item-packet.ts +++ b/src/net/incoming-packets/drop-item-packet.ts @@ -1,13 +1,13 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; import { itemAction } from '@server/world/actor/player/action/item-action'; +import { ByteBuffer } from '@runejs/byte-buffer'; -export const dropItemPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { - const widgetId = packet.readUnsignedShortLE(); - const containerId = packet.readUnsignedShortLE(); - const slot = packet.readNegativeOffsetShortBE(); - const itemId = packet.readUnsignedShortLE(); +export const dropItemPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { + const widgetId = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const containerId = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const slot = packet.get('SHORT', 'UNSIGNED'); + const itemId = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); itemAction(player, itemId, slot, widgetId, containerId, 'drop'); }; diff --git a/src/net/incoming-packets/interface-click-packet.ts b/src/net/incoming-packets/interface-click-packet.ts index 5d706d9d1..82706afaf 100644 --- a/src/net/incoming-packets/interface-click-packet.ts +++ b/src/net/incoming-packets/interface-click-packet.ts @@ -1,7 +1,7 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; +import { ByteBuffer } from '@runejs/byte-buffer'; -export const interfaceClickPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { +export const interfaceClickPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { // Do nothing }; diff --git a/src/net/incoming-packets/item-equip-packet.ts b/src/net/incoming-packets/item-equip-packet.ts index e51a7a877..449156284 100644 --- a/src/net/incoming-packets/item-equip-packet.ts +++ b/src/net/incoming-packets/item-equip-packet.ts @@ -1,13 +1,13 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; import { itemAction } from '@server/world/actor/player/action/item-action'; +import { ByteBuffer } from '@runejs/byte-buffer'; -export const itemEquipPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { - const containerId = packet.readShortLE(); - const widgetId = packet.readShortLE(); - const slot = packet.readNegativeOffsetShortLE(); - const itemId = packet.readShortBE(); +export const itemEquipPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { + const containerId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); + const widgetId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); + const slot = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const itemId = packet.get('SHORT', 'UNSIGNED'); itemAction(player, itemId, slot, widgetId, containerId, 'equip'); }; diff --git a/src/net/incoming-packets/item-interaction-packet.ts b/src/net/incoming-packets/item-interaction-packet.ts index 3d20391f6..a98ac8887 100644 --- a/src/net/incoming-packets/item-interaction-packet.ts +++ b/src/net/incoming-packets/item-interaction-packet.ts @@ -1,8 +1,8 @@ import { incomingPacket } from '../incoming-packet'; -import { RsBuffer } from '@server/net/rs-buffer'; import { Player } from '../../world/actor/player/player'; import { itemAction } from '@server/world/actor/player/action/item-action'; import { getItemOption } from '@server/world/items/item'; +import { ByteBuffer } from '@runejs/byte-buffer'; interface ItemInteraction { widgetId: number; @@ -11,47 +11,47 @@ interface ItemInteraction { slot: number; } -const option1 = (packet: RsBuffer): ItemInteraction => { - const itemId = packet.readNegativeOffsetShortBE(); - const slot = packet.readShortLE(); - const widgetId = packet.readShortLE(); - const containerId = packet.readShortLE(); +const option1 = (packet: ByteBuffer): ItemInteraction => { + const itemId = packet.get('SHORT', 'UNSIGNED'); + const slot = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const widgetId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); + const containerId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); return { widgetId, containerId, itemId, slot }; }; -const option2 = (packet: RsBuffer): ItemInteraction => { - const itemId = packet.readUnsignedShortLE(); - const containerId = packet.readShortLE(); - const widgetId = packet.readShortLE(); - const slot = packet.readUnsignedShortLE(); +const option2 = (packet: ByteBuffer): ItemInteraction => { + const itemId = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const containerId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); + const widgetId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); + const slot = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); return { widgetId, containerId, itemId, slot }; }; -const option3 = (packet: RsBuffer): ItemInteraction => { - const slot = packet.readNegativeOffsetShortBE(); - const containerId = packet.readShortLE(); - const widgetId = packet.readShortLE(); - const itemId = packet.readNegativeOffsetShortBE(); +const option3 = (packet: ByteBuffer): ItemInteraction => { + const slot = packet.get('SHORT', 'UNSIGNED'); + const containerId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); + const widgetId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); + const itemId = packet.get('SHORT', 'UNSIGNED'); return { widgetId, containerId, itemId, slot }; }; -const option4 = (packet: RsBuffer): ItemInteraction => { - const itemId = packet.readNegativeOffsetShortBE(); - const slot = packet.readUnsignedShortLE(); - const containerId = packet.readShortLE(); - const widgetId = packet.readShortLE(); +const option4 = (packet: ByteBuffer): ItemInteraction => { + const itemId = packet.get('SHORT', 'UNSIGNED'); + const slot = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const containerId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); + const widgetId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); return { widgetId, containerId, itemId, slot }; }; -const inventoryOption4 = (packet: RsBuffer): ItemInteraction => { - const slot = packet.readShortBE(); - const widgetId = packet.readShortLE(); - const containerId = packet.readShortLE(); - const itemId = packet.readShortBE(); +const inventoryOption4 = (packet: ByteBuffer): ItemInteraction => { + const slot = packet.get('SHORT', 'UNSIGNED'); + const widgetId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); + const containerId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); + const itemId = packet.get('SHORT', 'UNSIGNED'); return { widgetId, containerId, itemId, slot }; }; -export const itemInteractionPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { +export const itemInteractionPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { const packets = { 38: { packetDef: option1, optionNumber: 1 }, 228: { packetDef: option2, optionNumber: 2 }, diff --git a/src/net/incoming-packets/item-on-item-packet.ts b/src/net/incoming-packets/item-on-item-packet.ts index 29729c4a6..7784b4307 100644 --- a/src/net/incoming-packets/item-on-item-packet.ts +++ b/src/net/incoming-packets/item-on-item-packet.ts @@ -1,19 +1,19 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; import { widgets } from '@server/world/config/widget'; import { logger } from '@runejs/logger/dist/logger'; import { itemOnItemAction } from '@server/world/actor/player/action/item-on-item-action'; +import { ByteBuffer } from '@runejs/byte-buffer'; -export const itemOnItemPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { - const usedWithItemId = packet.readNegativeOffsetShortLE(); - const usedWithSlot = packet.readNegativeOffsetShortLE(); - const usedWithContainerId = packet.readUnsignedShortLE(); - const usedWithWidgetId = packet.readUnsignedShortLE(); - const usedContainerId = packet.readUnsignedShortLE(); - const usedWidgetId = packet.readUnsignedShortLE(); - const usedItemId = packet.readUnsignedShortLE(); - const usedSlot = packet.readNegativeOffsetShortBE(); +export const itemOnItemPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { + const usedWithItemId = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const usedWithSlot = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const usedWithContainerId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); + const usedWithWidgetId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); + const usedContainerId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); + const usedWidgetId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); + const usedItemId = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const usedSlot = packet.get('SHORT', 'UNSIGNED'); if(usedWidgetId === widgets.inventory.widgetId && usedContainerId === widgets.inventory.containerId && usedWithWidgetId === widgets.inventory.widgetId && usedWithContainerId === widgets.inventory.containerId) { diff --git a/src/net/incoming-packets/item-on-npc-packet.ts b/src/net/incoming-packets/item-on-npc-packet.ts index d1f1acf26..9b4954f1d 100644 --- a/src/net/incoming-packets/item-on-npc-packet.ts +++ b/src/net/incoming-packets/item-on-npc-packet.ts @@ -1,18 +1,18 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; import { widgets } from '@server/world/config/widget'; import { logger } from '@runejs/logger/dist/logger'; import { world } from '@server/game-server'; import { World } from '@server/world/world'; import { itemOnNpcAction } from '@server/world/actor/player/action/item-on-npc-action'; - -export const itemOnNpcPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { - const npcIndex = packet.readNegativeOffsetShortBE(); - const itemId = packet.readNegativeOffsetShortBE(); - const itemSlot = packet.readNegativeOffsetShortLE(); - const itemWidgetId = packet.readShortBE(); - const itemContainerId = packet.readShortBE(); +import { ByteBuffer } from '@runejs/byte-buffer'; + +export const itemOnNpcPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { + const npcIndex = packet.get('SHORT', 'UNSIGNED'); + const itemId = packet.get('SHORT', 'UNSIGNED'); + const itemSlot = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const itemWidgetId = packet.get('SHORT'); + const itemContainerId = packet.get('SHORT'); let usedItem; if(itemWidgetId === widgets.inventory.widgetId && itemContainerId === widgets.inventory.containerId) { diff --git a/src/net/incoming-packets/item-on-object-packet.ts b/src/net/incoming-packets/item-on-object-packet.ts index d6ad357e7..605bacd7a 100644 --- a/src/net/incoming-packets/item-on-object-packet.ts +++ b/src/net/incoming-packets/item-on-object-packet.ts @@ -1,20 +1,20 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; import { widgets } from '@server/world/config/widget'; import { logger } from '@runejs/logger/dist/logger'; import { Position } from '@server/world/position'; import { cache, world } from '@server/game-server'; import { itemOnObjectAction } from '@server/world/actor/player/action/item-on-object-action'; - -export const itemOnObjectPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { - const objectY = packet.readNegativeOffsetShortLE(); - const itemId = packet.readNegativeOffsetShortBE(); - const objectId = packet.readUnsignedShortLE(); - const itemSlot = packet.readNegativeOffsetShortLE(); - const itemWidgetId = packet.readShortLE(); - const itemContainerId = packet.readShortLE(); - const objectX = packet.readNegativeOffsetShortLE(); +import { ByteBuffer } from '@runejs/byte-buffer'; + +export const itemOnObjectPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { + const objectY = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const itemId = packet.get('SHORT', 'UNSIGNED'); + const objectId = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const itemSlot = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const itemWidgetId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); + const itemContainerId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); + const objectX = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); let usedItem; if (itemWidgetId === widgets.inventory.widgetId && itemContainerId === widgets.inventory.containerId) { diff --git a/src/net/incoming-packets/item-swap-packet.ts b/src/net/incoming-packets/item-swap-packet.ts index 033bf5fbc..5731ae4e2 100644 --- a/src/net/incoming-packets/item-swap-packet.ts +++ b/src/net/incoming-packets/item-swap-packet.ts @@ -1,14 +1,14 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; import { swapItemAction } from '../../world/actor/player/action/swap-item-action'; +import { ByteBuffer } from '@runejs/byte-buffer'; -export const itemSwapPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { - const swapType = packet.readPostNegativeOffsetByte(); - const fromSlot = packet.readNegativeOffsetShortBE(); - const toSlot = packet.readNegativeOffsetShortLE(); - const containerId = packet.readShortBE(); - const widgetId = packet.readShortBE(); +export const itemSwapPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { + const swapType = packet.get(); + const fromSlot = packet.get('SHORT', 'UNSIGNED'); + const toSlot = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const containerId = packet.get('SHORT'); + const widgetId = packet.get('SHORT'); if(toSlot < 0 || fromSlot < 0) { return; diff --git a/src/net/incoming-packets/npc-interaction-packet.ts b/src/net/incoming-packets/npc-interaction-packet.ts index fe0202345..eaf5ac290 100644 --- a/src/net/incoming-packets/npc-interaction-packet.ts +++ b/src/net/incoming-packets/npc-interaction-packet.ts @@ -1,20 +1,20 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; import { world } from '@server/game-server'; import { World } from '@server/world/world'; import { npcAction } from '@server/world/actor/player/action/npc-action'; import { logger } from '@runejs/logger/dist/logger'; +import { ByteBuffer } from '@runejs/byte-buffer'; -export const npcInteractionPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { - const methods = { - 63: 'readNegativeOffsetShortLE', - 116: 'readUnsignedShortLE', +export const npcInteractionPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { + const args = { + 63: [ 'SHORT', 'UNSIGNED', 'LITTLE_ENDIAN' ], + 116: [ 'SHORT', 'UNSIGNED', 'LITTLE_ENDIAN' ], /*13: 'readNegativeOffsetShortLE', 42: 'readUnsignedShortLE', 8: 'readUnsignedShortLE'*/ }; - const npcIndex = packet[methods[packetId]](); + const npcIndex = packet.get(...args[packetId]); if(npcIndex < 0 || npcIndex > World.MAX_NPCS - 1) { return; diff --git a/src/net/incoming-packets/number-input-packet.ts b/src/net/incoming-packets/number-input-packet.ts index 2a3b4904a..2a707d63c 100644 --- a/src/net/incoming-packets/number-input-packet.ts +++ b/src/net/incoming-packets/number-input-packet.ts @@ -1,8 +1,8 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; +import { ByteBuffer } from '@runejs/byte-buffer'; -export const numberInputPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { - const input = packet.readUnsignedIntBE(); +export const numberInputPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { + const input = packet.get('INT', 'UNSIGNED'); player.numericInputEvent.next(input); }; diff --git a/src/net/incoming-packets/object-interaction-packet.ts b/src/net/incoming-packets/object-interaction-packet.ts index 28daed58a..a1fa0e2fe 100644 --- a/src/net/incoming-packets/object-interaction-packet.ts +++ b/src/net/incoming-packets/object-interaction-packet.ts @@ -1,10 +1,10 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; import { Position } from '@server/world/position'; import { cache, world } from '@server/game-server'; import { objectAction } from '@server/world/actor/player/action/object-action'; import { logger } from '@runejs/logger/dist/logger'; +import { ByteBuffer } from '@runejs/byte-buffer'; interface ObjectInteraction { objectId: number; @@ -12,42 +12,44 @@ interface ObjectInteraction { y: number; } -const option1 = (packet: RsBuffer): ObjectInteraction => { - const objectId = packet.readNegativeOffsetShortBE(); - const y = packet.readNegativeOffsetShortBE(); - const x = packet.readNegativeOffsetShortLE(); +const option1 = (packet: ByteBuffer): ObjectInteraction => { + const objectId = packet.get('SHORT', 'UNSIGNED'); + const y = packet.get('SHORT', 'UNSIGNED'); + const x = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); return { objectId, x, y }; }; -const option2 = (packet: RsBuffer): ObjectInteraction => { - const x = packet.readNegativeOffsetShortLE(); - const y = packet.readNegativeOffsetShortLE(); - const objectId = packet.readNegativeOffsetShortLE(); +const option2 = (packet: ByteBuffer): ObjectInteraction => { + const x = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const y = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const objectId = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); return { objectId, x, y }; }; -const option3 = (packet: RsBuffer): ObjectInteraction => { - const y = packet.readNegativeOffsetShortBE(); - const objectId = packet.readUnsignedShortBE(); - const x = packet.readNegativeOffsetShortBE(); +const option3 = (packet: ByteBuffer): ObjectInteraction => { + const y = packet.get('SHORT', 'UNSIGNED'); + const objectId = packet.get('SHORT', 'UNSIGNED'); + const x = packet.get('SHORT', 'UNSIGNED'); return { objectId, x, y }; }; -const option4 = (packet: RsBuffer): ObjectInteraction => { - const x = packet.readUnsignedShortBE(); - const y = packet.readUnsignedShortLE(); - const objectId = packet.readUnsignedShortBE(); +// @TODO +const option4 = (packet: ByteBuffer): ObjectInteraction => { + const x = null; + const y = null; + const objectId = null; return { objectId, x, y }; }; -const option5 = (packet: RsBuffer): ObjectInteraction => { - const objectId = packet.readUnsignedShortLE(); - const y = packet.readUnsignedShortLE(); - const x = packet.readUnsignedShortBE(); +// @TODO +const option5 = (packet: ByteBuffer): ObjectInteraction => { + const objectId = null; + const y = null; + const x = null; return { objectId, x, y }; }; -export const objectInteractionPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { +export const objectInteractionPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { const options = { 30: { packetDef: option1, index: 0 }, 164: { packetDef: option2, index: 1 }, diff --git a/src/net/incoming-packets/pickup-item-packet.ts b/src/net/incoming-packets/pickup-item-packet.ts index 8225edf6a..977615a26 100644 --- a/src/net/incoming-packets/pickup-item-packet.ts +++ b/src/net/incoming-packets/pickup-item-packet.ts @@ -1,14 +1,14 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; import { world } from '@server/game-server'; import { Position } from '@server/world/position'; import { worldItemAction } from '@server/world/actor/player/action/world-item-action'; +import { ByteBuffer } from '@runejs/byte-buffer'; -export const pickupItemPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { - const y = packet.readNegativeOffsetShortBE(); - const itemId = packet.readNegativeOffsetShortBE(); - const x = packet.readUnsignedShortLE(); +export const pickupItemPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { + const y = packet.get('SHORT', 'UNSIGNED'); + const itemId = packet.get('SHORT', 'UNSIGNED'); + const x = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); const level = player.position.level; const worldItemPosition = new Position(x, y, level); diff --git a/src/net/incoming-packets/walk-packet.ts b/src/net/incoming-packets/walk-packet.ts index a7ef7dadb..dc9372661 100644 --- a/src/net/incoming-packets/walk-packet.ts +++ b/src/net/incoming-packets/walk-packet.ts @@ -1,8 +1,8 @@ import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; import { incomingPacket } from '../incoming-packet'; +import { ByteBuffer } from '@runejs/byte-buffer'; -export const walkPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { +export const walkPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { let size = packetSize; if(packetId == 236) { size -= 14; @@ -10,9 +10,9 @@ export const walkPacket: incomingPacket = (player: Player, packetId: number, pac const totalSteps = Math.floor((size - 5) / 2); - const firstY = packet.readUnsignedShortLE(); - const runSteps = packet.readUnsignedByteInverted() === 1; // @TODO forced running - const firstX = packet.readUnsignedShortLE(); + const firstY = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); + const runSteps = packet.get() === 1; // @TODO forced running + const firstX = packet.get('SHORT', 'UNSIGNED', 'LITTLE_ENDIAN'); const walkingQueue = player.walkingQueue; @@ -22,8 +22,8 @@ export const walkPacket: incomingPacket = (player: Player, packetId: number, pac walkingQueue.add(firstX, firstY); for(let i = 0; i < totalSteps; i++) { - const x = packet.readPostNegativeOffsetByte(); - const y = packet.readByteInverted(); + const x = packet.get(); + const y = packet.get(); walkingQueue.add(x + firstX, y + firstY); } }; diff --git a/src/net/incoming-packets/widget-interaction-packet.ts b/src/net/incoming-packets/widget-interaction-packet.ts index ec0ecfa77..9ca6b6de7 100644 --- a/src/net/incoming-packets/widget-interaction-packet.ts +++ b/src/net/incoming-packets/widget-interaction-packet.ts @@ -1,12 +1,12 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; import { widgetAction } from '@server/world/actor/player/action/widget-action'; +import { ByteBuffer } from '@runejs/byte-buffer'; -export const widgetInteractionPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { - const childId = packet.readShortBE(); - const widgetId = packet.readShortBE(); - const optionId = packet.readShortLE(); +export const widgetInteractionPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { + const childId = packet.get('SHORT'); + const widgetId = packet.get('SHORT'); + const optionId = packet.get('SHORT', 'SIGNED', 'LITTLE_ENDIAN'); widgetAction(player, widgetId, childId, optionId); }; diff --git a/src/net/incoming-packets/widgets-closed-packet.ts b/src/net/incoming-packets/widgets-closed-packet.ts index 2ebea7a94..310390245 100644 --- a/src/net/incoming-packets/widgets-closed-packet.ts +++ b/src/net/incoming-packets/widgets-closed-packet.ts @@ -1,7 +1,7 @@ import { incomingPacket } from '../incoming-packet'; import { Player } from '../../world/actor/player/player'; -import { RsBuffer } from '@server/net/rs-buffer'; +import { ByteBuffer } from '@runejs/byte-buffer'; -export const widgetsClosedPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { +export const widgetsClosedPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: ByteBuffer): void => { player.closeActiveWidgets(false); }; diff --git a/src/net/outgoing-packets.ts b/src/net/outgoing-packets.ts index ef7822716..851cdd48e 100644 --- a/src/net/outgoing-packets.ts +++ b/src/net/outgoing-packets.ts @@ -27,24 +27,24 @@ export class OutgoingPackets { public playSong(songId: number): void { const packet = new Packet(217); - packet.writeShortLE(songId); + packet.put(songId, 'SHORT', 'LITTLE_ENDIAN'); this.queue(packet); } public playQuickSong(songId: number, previousSongId: number): void { const packet = new Packet(40); - packet.writeMediumBE(previousSongId); - packet.writeOffsetShortBE(songId); + packet.put(previousSongId, 'INT24'); + packet.put(songId, 'SHORT'); this.queue(packet); } public playSound(soundId: number, volume: number, delay: number = 0): void { const packet = new Packet(131); - packet.writeShortBE(soundId); - packet.writeByte(volume); - packet.writeShortBE(delay); + packet.put(soundId, 'SHORT'); + packet.put(volume); + packet.put(delay, 'SHORT'); this.queue(packet); } @@ -52,10 +52,10 @@ export class OutgoingPackets { public playSoundAtPosition(soundId: number, soundX: number, soundY: number, volume: number, radius: number = 5, delay: number = 0): void { const packet = new Packet(9); const offset = 0; - packet.writeUnsignedByte(offset); - packet.writeUnsignedShortBE(soundId); - packet.writeUnsignedByte((volume & 7) + (radius << 4)); - packet.writeUnsignedByte(delay); + packet.put(offset, 'BYTE'); + packet.put(soundId, 'SHORT'); + packet.put((volume & 7) + (radius << 4), 'BYTE'); + packet.put(delay, 'BYTE'); this.queue(packet); } @@ -79,29 +79,29 @@ export class OutgoingPackets { const { offsetX, offsetY } = this.getChunkOffset(chunk); const packet = new Packet(63, PacketType.DYNAMIC_LARGE); - packet.writeByteInverted(offsetX); - packet.writeNegativeOffsetByte(offsetY); + packet.put(offsetX); + packet.put(offsetY); chunkUpdates.forEach(update => { if(update.type === 'ADD') { if(update.object) { const offset = this.getChunkPositionOffset(update.object.x, update.object.y, chunk); - packet.writeUnsignedByte(241); - packet.writeByteInverted((update.object.type << 2) + (update.object.orientation & 3)); - packet.writeUnsignedShortBE(update.object.objectId); - packet.writeUnsignedOffsetByte(offset); + packet.put(241, 'BYTE'); + packet.put((update.object.type << 2) + (update.object.orientation & 3)); + packet.put(update.object.objectId, 'SHORT'); + packet.put(offset); } else if(update.worldItem) { const offset = this.getChunkPositionOffset(update.worldItem.position.x, update.worldItem.position.y, chunk); - packet.writeUnsignedByte(175); - packet.writeUnsignedShortLE(update.worldItem.itemId); - packet.writeUnsignedShortBE(update.worldItem.amount); - packet.writeUnsignedByte(offset); + packet.put(175, 'BYTE'); + packet.put(update.worldItem.itemId, 'SHORT', 'LITTLE_ENDIAN'); + packet.put(update.worldItem.amount, 'SHORT'); + packet.put(offset, 'BYTE'); } } else if(update.type === 'REMOVE') { const offset = this.getChunkPositionOffset(update.object.x, update.object.y, chunk); - packet.writeUnsignedByte(143); - packet.writeUnsignedOffsetByte(offset); - packet.writeByteInverted((update.object.type << 2) + (update.object.orientation & 3)); + packet.put(143, 'BYTE'); + packet.put(offset); + packet.put((update.object.type << 2) + (update.object.orientation & 3)); } }); @@ -112,8 +112,8 @@ export class OutgoingPackets { const { offsetX, offsetY } = this.getChunkOffset(chunk); const packet = new Packet(64); - packet.writeUnsignedByte(offsetY); - packet.writeUnsignedOffsetByte(offsetX); + packet.put(offsetY, 'BYTE'); + packet.put(offsetX); this.queue(packet); } @@ -122,9 +122,9 @@ export class OutgoingPackets { this.updateReferencePosition(position); const packet = new Packet(175); - packet.writeUnsignedShortLE(worldItem.itemId); - packet.writeUnsignedShortBE(worldItem.amount); - packet.writeUnsignedByte(offset); + packet.put(worldItem.itemId, 'SHORT', 'LITTLE_ENDIAN'); + packet.put(worldItem.amount, 'SHORT'); + packet.put(offset, 'BYTE'); this.queue(packet); } @@ -133,8 +133,8 @@ export class OutgoingPackets { this.updateReferencePosition(position); const packet = new Packet(74); - packet.writeUnsignedByte(offset); - packet.writeUnsignedOffsetShortBE(worldItem.itemId); + packet.put(offset, 'BYTE'); + packet.put(worldItem.itemId, 'SHORT'); this.queue(packet); } @@ -143,9 +143,9 @@ export class OutgoingPackets { this.updateReferencePosition(position); const packet = new Packet(241); - packet.writeByteInverted((locationObject.type << 2) + (locationObject.orientation & 3)); - packet.writeUnsignedShortBE(locationObject.objectId); - packet.writeUnsignedOffsetByte(offset); + packet.put((locationObject.type << 2) + (locationObject.orientation & 3)); + packet.put(locationObject.objectId, 'SHORT'); + packet.put(offset); this.queue(packet); } @@ -154,8 +154,8 @@ export class OutgoingPackets { this.updateReferencePosition(position); const packet = new Packet(143); - packet.writeUnsignedOffsetByte(offset); - packet.writeByteInverted((locationObject.type << 2) + (locationObject.orientation & 3)); + packet.put(offset); + packet.put((locationObject.type << 2) + (locationObject.orientation & 3)); this.queue(packet); } @@ -165,8 +165,8 @@ export class OutgoingPackets { const offsetY = position.y - (this.player.lastMapRegionUpdatePosition.chunkY * 8); const packet = new Packet(254); - packet.writeNegativeOffsetByte(offsetY); - packet.writeByteInverted(offsetX); + packet.put(offsetY); + packet.put(offsetX); this.queue(packet); } @@ -176,38 +176,38 @@ export class OutgoingPackets { // Statements (no click to continue) = 210, 211, 212, 213, 214 public showChatboxWidget(widgetId: number): void { const packet = new Packet(208); - packet.writeUnsignedOffsetShortBE(widgetId); + packet.put(widgetId, 'SHORT'); this.queue(packet); } public setWidgetNpcHead(widgetId: number, childId: number, modelId: number): void { const packet = new Packet(160); - packet.writeUnsignedShortLE(modelId); - packet.writeIntLE(widgetId << 16 | childId); + packet.put(modelId, 'SHORT', 'LITTLE_ENDIAN'); + packet.put(widgetId << 16 | childId, 'INT', 'LITTLE_ENDIAN'); this.queue(packet); } public setWidgetPlayerHead(widgetId: number, childId: number): void { const packet = new Packet(210); - packet.writeIntLE(widgetId << 16 | childId); + packet.put(widgetId << 16 | childId, 'INT', 'LITTLE_ENDIAN'); this.queue(packet); } public playWidgetAnimation(widgetId: number, childId: number, animationId: number): void { const packet = new Packet(24); - packet.writeShortBE(animationId); - packet.writeIntBE(widgetId << 16 | childId); + packet.put(animationId, 'SHORT'); + packet.put(widgetId << 16 | childId, 'INT'); this.queue(packet); } public showScreenAndTabWidgets(widgetId: number, tabWidgetId: number): void { const packet = new Packet(84); - packet.writeUnsignedShortBE(tabWidgetId); - packet.writeUnsignedOffsetShortLE(widgetId); + packet.put(tabWidgetId, 'SHORT'); + packet.put(widgetId, 'SHORT', 'LITTLE_ENDIAN'); this.queue(packet); } @@ -216,12 +216,12 @@ export class OutgoingPackets { if(value > 128) { packet = new Packet(2); - packet.writeIntME2(value); - packet.writeUnsignedShortBE(configId); + packet.put(value, 'INT'); + packet.put(configId, 'SHORT'); } else { packet = new Packet(222); - packet.writeNegativeOffsetByte(value); - packet.writeUnsignedOffsetShortBE(configId); + packet.put(value); + packet.put(configId, 'SHORT'); } this.queue(packet); @@ -229,43 +229,43 @@ export class OutgoingPackets { public setWidgetModelRotationAndZoom(widgetId: number, childId: number, rotationX: number, rotationY: number, zoom: number): void { const packet = new Packet(142); - packet.writeUnsignedShortBE(rotationX); - packet.writeUnsignedShortLE(zoom); - packet.writeUnsignedShortBE(rotationY); - packet.writeIntLE(widgetId << 16 | childId); + packet.put(rotationX, 'SHORT'); + packet.put(zoom, 'SHORT', 'LITTLE_ENDIAN'); + packet.put(rotationY, 'SHORT'); + packet.put(widgetId << 16 | childId, 'INT', 'LITTLE_ENDIAN'); this.queue(packet); } public updateWidgetModel1(widgetId: number, childId: number, modelId: number): void { const packet = new Packet(250); - packet.writeUnsignedShortLE(modelId); - packet.writeIntME2(widgetId << 16 | childId); + packet.put(modelId, 'SHORT', 'LITTLE_ENDIAN'); + packet.put(widgetId << 16 | childId, 'INT', 'LITTLE_ENDIAN'); this.queue(packet); } public updateWidgetItemModel(widgetId: number, itemId: number, scale?: number): void { const packet = new Packet(21); - packet.writeShortBE(scale); - packet.writeShortLE(itemId); - packet.writeOffsetShortLE(widgetId); + packet.put(scale, 'SHORT'); + packet.put(itemId, 'SHORT', 'LITTLE_ENDIAN'); + packet.put(widgetId, 'SHORT', 'LITTLE_ENDIAN'); this.queue(packet); } public updateWidgetString(widgetId: number, childId: number, value: string): void { const packet = new Packet(110, PacketType.DYNAMIC_LARGE); - packet.writeIntLE(widgetId << 16 | childId); - packet.writeNewString(value); + packet.put(widgetId << 16 | childId, 'INT', 'LITTLE_ENDIAN'); + packet.putString(value); this.queue(packet); } public updateWidgetColor(widgetId: number, childId: number, color: number): void { const packet = new Packet(231); - packet.writeOffsetShortBE(color); - packet.writeIntLE(widgetId << 16 | childId); + packet.put(color, 'SHORT'); + packet.put(widgetId << 16 | childId, 'INT', 'LITTLE_ENDIAN'); this.queue(packet); } @@ -276,7 +276,7 @@ export class OutgoingPackets { public showScreenWidget(widgetId: number): void { const packet = new Packet(118); - packet.writeUnsignedShortBE(widgetId); + packet.put(widgetId, 'SHORT'); this.queue(packet); } @@ -284,19 +284,19 @@ export class OutgoingPackets { // @TODO this can support multiple items/slots !!! public sendUpdateSingleWidgetItem(widget: { widgetId: number, containerId: number }, slot: number, item: Item): void { const packet = new Packet(214, PacketType.DYNAMIC_LARGE); - packet.writeIntBE(widget.widgetId << 16 | widget.containerId); - packet.writeSmart(slot); + packet.put(widget.widgetId << 16 | widget.containerId, 'INT'); + packet.put(slot, 'SMART'); if(!item) { - packet.writeUnsignedShortBE(0); + packet.put(0, 'SHORT'); } else { - packet.writeUnsignedShortBE(item.itemId + 1); // +1 because 0 means an empty slot + packet.put(item.itemId + 1, 'SHORT'); // +1 because 0 means an empty slot if(item.amount >= 255) { - packet.writeUnsignedByte(255); - packet.writeIntBE(item.amount); + packet.put(255, 'BYTE'); + packet.put(item.amount, 'INT'); } else { - packet.writeUnsignedByte(item.amount); + packet.put(item.amount, 'BYTE'); } } @@ -305,24 +305,24 @@ export class OutgoingPackets { public sendUpdateAllWidgetItems(widget: { widgetId: number, containerId: number }, container: ItemContainer): void { const packet = new Packet(12, PacketType.DYNAMIC_LARGE); - packet.writeIntBE(widget.widgetId << 16 | widget.containerId); - packet.writeShortBE(container.size); + packet.put(widget.widgetId << 16 | widget.containerId, 'INT'); + packet.put(container.size, 'SHORT'); const items = container.items; items.forEach(item => { if(!item) { // Empty slot - packet.writeUnsignedOffsetByte(0); - packet.writeOffsetShortBE(0); + packet.put(0); + packet.put(0, 'SHORT'); } else { if(item.amount >= 255) { - packet.writeUnsignedByteOffset(255); - packet.writeIntBE(item.amount); + packet.put(255); + packet.put(item.amount, 'INT'); } else { - packet.writeUnsignedOffsetByte(item.amount); + packet.put(item.amount); } - packet.writeOffsetShortBE(item.itemId + 1); // +1 because 0 means an empty slot + packet.put(item.itemId + 1, 'SHORT'); // +1 because 0 means an empty slot } }); @@ -331,17 +331,17 @@ export class OutgoingPackets { public sendUpdateAllWidgetItemsById(widget: { widgetId: number, containerId: number }, itemIds: number[]): void { const packet = new Packet(12, PacketType.DYNAMIC_LARGE); - packet.writeIntBE(widget.widgetId << 16 | widget.containerId); - packet.writeShortBE(itemIds.length); + packet.put(widget.widgetId << 16 | widget.containerId, 'INT'); + packet.put(itemIds.length, 'SHORT'); itemIds.forEach(itemId => { if(!itemId) { // Empty slot - packet.writeUnsignedOffsetByte(0); - packet.writeOffsetShortBE(0); + packet.put(0); + packet.put(0, 'SHORT'); } else { - packet.writeUnsignedOffsetByte(1); - packet.writeOffsetShortBE(itemId + 1); // +1 because 0 means an empty slot + packet.put(1); + packet.put(itemId + 1, 'SHORT'); // +1 because 0 means an empty slot } }); @@ -350,42 +350,42 @@ export class OutgoingPackets { public setItemOnWidget(widgetId: number, childId: number, itemId: number, zoom: number): void { const packet = new Packet(120); - packet.writeUnsignedShortBE(zoom); - packet.writeUnsignedShortLE(itemId); - packet.writeIntLE(widgetId << 16 | childId); + packet.put(zoom, 'SHORT'); + packet.put(itemId, 'SHORT', 'LITTLE_ENDIAN'); + packet.put(widgetId << 16 | childId, 'INT', 'LITTLE_ENDIAN'); this.queue(packet); } public toggleWidgetVisibility(widgetId: number, childId: number, hidden: boolean): void { const packet = new Packet(115); - packet.writeUnsignedByte(hidden ? 1 : 0); - packet.writeIntME2(widgetId << 16 | childId); + packet.put(hidden ? 1 : 0, 'BYTE'); + packet.put(widgetId << 16 | childId, 'INT', 'LITTLE_ENDIAN'); this.queue(packet); } public moveWidgetChild(widgetId: number, childId: number, offsetX: number, offsetY: number): void { const packet = new Packet(3); - packet.writeIntBE(widgetId << 16 | childId); - packet.writeUnsignedOffsetShortLE(offsetY); - packet.writeUnsignedOffsetShortLE(offsetX); + packet.put(widgetId << 16 | childId, 'INT'); + packet.put(offsetY, 'SHORT', 'LITTLE_ENDIAN'); + packet.put(offsetX, 'SHORT', 'LITTLE_ENDIAN'); this.queue(packet); } public sendTabWidget(tabIndex: number, widgetId: number): void { const packet = new Packet(140); - packet.writeShortBE(widgetId); - packet.writeByte(tabIndex); + packet.put(widgetId, 'SHORT'); + packet.put(tabIndex); this.queue(packet); } public showFullscreenWidget(widgetId: number, secondaryWidgetId: number): void { const packet = new Packet(195); - packet.writeUnsignedOffsetShortBE(secondaryWidgetId); - packet.writeUnsignedShortBE(widgetId); + packet.put(secondaryWidgetId, 'SHORT'); + packet.put(widgetId, 'SHORT'); this.queue(packet); } @@ -402,30 +402,30 @@ export class OutgoingPackets { public updateCarryWeight(weight: number): void { const packet = new Packet(171); - packet.writeShortBE(weight); + packet.put(weight, 'SHORT'); this.queue(packet); } public showHintIcon(iconType: 2 | 3 | 4 | 5 | 6, position: Position, offset: number = 0): void { const packet = new Packet(199); - packet.writeUnsignedByte(iconType); - packet.writeUnsignedShortBE(position.x); - packet.writeUnsignedShortBE(position.y); - packet.writeUnsignedByte(offset); + packet.put(iconType, 'BYTE'); + packet.put(position.x, 'SHORT'); + packet.put(position.y, 'SHORT'); + packet.put(offset, 'BYTE'); this.queue(packet); } public showPlayerHintIcon(player: Player): void { const packet = new Packet(199); - packet.writeUnsignedByte(10); - packet.writeUnsignedShortBE(player.worldIndex); + packet.put(10, 'BYTE'); + packet.put(player.worldIndex, 'SHORT'); // Packet requires a length of 6, so send some extra junk - packet.writeByte(0); - packet.writeByte(0); - packet.writeByte(0); + packet.put(0); + packet.put(0); + packet.put(0); this.queue(packet); } @@ -439,32 +439,32 @@ export class OutgoingPackets { public chatboxMessage(message: string): void { const packet = new Packet(82, PacketType.DYNAMIC_SMALL); - packet.writeNewString(message); + packet.putString(message); this.queue(packet); } public updateSkill(skillId: number, level: number, exp: number): void { const packet = new Packet(34); - packet.writeUnsignedOffsetByte(level); - packet.writeByte(skillId); - packet.writeIntME2(exp); + packet.put(level); + packet.put(skillId); + packet.put(exp, 'INT', 'LITTLE_ENDIAN'); this.queue(packet); } public updateCurrentMapChunk(): void { const packet = new Packet(166, PacketType.DYNAMIC_LARGE); - packet.writeShortBE(this.player.position.chunkLocalY); - packet.writeShortLE(this.player.position.chunkX + 6); - packet.writeOffsetShortBE(this.player.position.chunkLocalX); - packet.writeOffsetShortLE(this.player.position.chunkY + 6); - packet.writeByteInverted(this.player.position.level); + packet.put(this.player.position.chunkLocalY, 'SHORT'); + packet.put(this.player.position.chunkX + 6, 'SHORT', 'LITTLE_ENDIAN'); + packet.put(this.player.position.chunkLocalX, 'SHORT'); + packet.put(this.player.position.chunkY + 6, 'SHORT', 'LITTLE_ENDIAN'); + packet.put(this.player.position.level); for(let xCalc = Math.floor(this.player.position.chunkX / 8); xCalc <= Math.floor((this.player.position.chunkX + 12) / 8); xCalc++) { for(let yCalc = Math.floor(this.player.position.chunkY / 8); yCalc <= Math.floor((this.player.position.chunkY + 12) / 8); yCalc++) { for(let seeds = 0; seeds < 4; seeds++) { - packet.writeIntME1(0); + packet.put(0, 'INT'); } } } diff --git a/src/net/packet.ts b/src/net/packet.ts index 2c7eabee8..2babfe6d5 100644 --- a/src/net/packet.ts +++ b/src/net/packet.ts @@ -1,5 +1,5 @@ -import { RsBuffer } from './rs-buffer'; import { Isaac } from './isaac'; +import { ByteBuffer } from '@runejs/byte-buffer'; /** * The type of packet; Fixed, Dynamic Small (sized byte), or Dynamic Large (sized short) @@ -13,47 +13,47 @@ export enum PacketType { /** * A single packet to be sent to the game client. */ -export class Packet extends RsBuffer { +export class Packet extends ByteBuffer { private readonly _packetId: number; private readonly _type: PacketType = PacketType.FIXED; public constructor(packetId: number, type: PacketType = PacketType.FIXED, allocatedSize: number = 5000) { - super(Buffer.alloc(allocatedSize)); + super(allocatedSize); this._packetId = packetId; this._type = type; } public toBuffer(cipher: Isaac): Buffer { - const packetSize = this.getWriterIndex(); + const packetSize = this.writerIndex; let bufferSize = packetSize + 1; // +1 for the packet id if(this.type !== PacketType.FIXED) { bufferSize += this.type === PacketType.DYNAMIC_SMALL ? 1 : 2; } - const buffer = RsBuffer.create(bufferSize); - buffer.writeUnsignedByte((this.packetId + (cipher !== null ? cipher.rand() : 0)) & 0xff); + const buffer = new ByteBuffer(bufferSize); + buffer.put((this.packetId + (cipher !== null ? cipher.rand() : 0)) & 0xff, 'BYTE'); let copyStart = 1; if(this.type === PacketType.DYNAMIC_SMALL) { - buffer.writeUnsignedByte(packetSize); + buffer.put(packetSize, 'BYTE'); copyStart = 2; } else if(this.type === PacketType.DYNAMIC_LARGE) { - buffer.writeShortBE(packetSize); + buffer.put(packetSize, 'SHORT'); copyStart = 3; } - this.getBuffer().copy(buffer.getBuffer(), copyStart, 0, packetSize); - return buffer.getBuffer(); + this.copy(buffer, copyStart, 0, packetSize); + return Buffer.from(buffer); } - get packetId(): number { + public get packetId(): number { return this._packetId; } - get type(): PacketType { + public get type(): PacketType { return this._type; } } diff --git a/src/net/rs-buffer.ts b/src/net/rs-buffer.ts deleted file mode 100644 index 35303bd15..000000000 --- a/src/net/rs-buffer.ts +++ /dev/null @@ -1,453 +0,0 @@ -const BIT_MASKS: number[] = []; - -for(let i = 0; i < 32; i++) { - BIT_MASKS.push((1 << i) - 1); -} - -export function stringToLong(s: string): bigint { - let l: bigint = BigInt(0); - - for(let i = 0; i < s.length && i < 12; i++) { - const c = s.charAt(i); - const cc = s.charCodeAt(i); - l *= BigInt(37); - if(c >= 'A' && c <= 'Z') l += BigInt((1 + cc) - 65); - else if(c >= 'a' && c <= 'z') l += BigInt((1 + cc) - 97); - else if(c >= '0' && c <= '9') l += BigInt((27 + cc) - 48); - } - while(l % BigInt(37) == BigInt(0) && l != BigInt(0)) l /= BigInt(37); - return l; -} - -/** - * Special snowflake byte buffer. - */ -export class RsBuffer { - - private buffer: Buffer; - private writerIndex: number = 0; - private readerIndex: number = 0; - private bitIndex: number; - - public constructor(buffer: Buffer) { - this.buffer = buffer; - } - - public static create(size: number = 5000): RsBuffer { - const buffer = Buffer.alloc(size); - return new RsBuffer(buffer); - } - - /** - * Enables the writing of specific bits to the buffer. - */ - public openBitChannel(): void { - this.bitIndex = this.writerIndex * 8; - } - - /** - * Disables the writing of specific bits to the buffer. - */ - public closeBitChannel(): void { - this.writerIndex = Math.floor((this.bitIndex + 7) / 8); - } - - /** - * Makes sure the current buffer has the specified space left within it. - * If not, a new buffer is created that contains the old buffer's data with the required space available at the end. - * @param remaining The required size remaining. - */ - public ensureCapacity(remaining: number): void { - if(this.getReadable() < remaining) { - const newBuffer = Buffer.alloc(remaining); - this.buffer.copy(newBuffer, 0, 0); - this.buffer = newBuffer; - } - } - - public ensureWritableCapacity(space: number): void { - if(this.getWritable() < this.writerIndex + space) { - const newBuffer = Buffer.alloc(this.writerIndex + space); - this.buffer.copy(newBuffer, 0, 0); - this.buffer = newBuffer; - } - } - - public writeBytes(fromBuffer: RsBuffer | Buffer): void { - if(fromBuffer instanceof RsBuffer) { - fromBuffer = fromBuffer.getData(); - } - - this.ensureCapacity(this.writerIndex + fromBuffer.length); - fromBuffer.copy(this.getBuffer(), this.getWriterIndex(), 0); - this.setWriterIndex(this.getWriterIndex() + fromBuffer.length); - } - - public writeBits(bitCount: number, value: number): void { - const byteCount: number = Math.ceil(bitCount / 8) + 1; - - this.ensureWritableCapacity((this.bitIndex + 7) / 8 + byteCount); - - let byteIndex: number = this.bitIndex >> 3; - let bitOffset: number = 8 - (this.bitIndex & 7); - - this.bitIndex += bitCount; - - for(; bitCount > bitOffset; bitOffset = 8) { - this.buffer[byteIndex] &= ~BIT_MASKS[bitOffset]; - this.buffer[byteIndex++] |= (value >> (bitCount - bitOffset)) & BIT_MASKS[bitOffset]; - bitCount -= bitOffset; - } - - if(bitCount == bitOffset) { - this.buffer[byteIndex] &= ~BIT_MASKS[bitOffset]; - this.buffer[byteIndex] |= value & BIT_MASKS[bitOffset]; - } else { - this.buffer[byteIndex] &= ~(BIT_MASKS[bitCount] << (bitOffset - bitCount)); - this.buffer[byteIndex] |= (value & BIT_MASKS[bitCount]) << (bitOffset - bitCount); - } - } - - public readUnsignedByte(): number { - return this.buffer.readUInt8(this.readerIndex++); - } - - public readByte(): number { - return this.buffer.readInt8(this.readerIndex++); - } - - public readUnsignedByteInverted(): number { - return -this.buffer.readUInt8(this.readerIndex++); - } - - public readByteInverted(): number { - return -this.buffer.readInt8(this.readerIndex++); - } - - public readPreNegativeOffsetByte(): number { - return 128 - (this.readByte() & 0xff); - } - - public readPostNegativeOffsetByte(): number { - return (this.readByte() & 0xff) - 128; - } - - public readShortBE(): number { - const value = this.buffer.readInt16BE(this.readerIndex); - this.readerIndex += 2; - return value; - } - - public readShortLE(): number { - const value = this.buffer.readInt16LE(this.readerIndex); - this.readerIndex += 2; - return value; - } - - public readUnsignedShortBE(): number { - const value = this.buffer.readUInt16BE(this.readerIndex); - this.readerIndex += 2; - return value; - } - - public readUnsignedShortLE(): number { - const value = this.buffer.readUInt16LE(this.readerIndex); - this.readerIndex += 2; - return value; - } - - public readNegativeOffsetShortLE(): number { - let value = (this.readByte() - 128 & 0xff) | ((this.readByte() & 0xff) << 8); - if(value > 32767) { - value -= 0x10000; - } - - return value; - } - - public readNegativeOffsetShortBE(): number { - let value = ((this.readByte() & 0xff) << 8) | (this.readByte() - 128 & 0xff); - if(value > 32767) { - value -= 0x10000; - } - - return value; - } - - public readIntME2(): number { - let value = ((this.readByte() & 0xff) << 8) | (this.readByte() & 0xff) | ((this.readByte() & 0xff) << 24) | ((this.readByte() & 0xff) << 16); - if(value > 32767) { - value -= 0x10000; - } - - return value; - } - - public readIntLE(): number { - const value = this.buffer.readInt32LE(this.readerIndex); - this.readerIndex += 4; - return value; - } - - public readUnsignedIntBE(): number { - const value = this.buffer.readUInt32BE(this.readerIndex); - this.readerIndex += 4; - return value; - } - - public readIntBE(): number { - const value = this.buffer.readInt32BE(this.readerIndex); - this.readerIndex += 4; - return value; - } - - public readLongBE(): bigint { - const value = this.buffer.readBigInt64BE(this.readerIndex); - this.readerIndex += 8; - return value; - } - - public readSmart(): number { - const peek = this.buffer.readUInt8(this.readerIndex); - if(peek < 128) { - return this.readUnsignedByte(); - } else { - return this.readUnsignedShortBE() - 32768; - } - } - - public readString(): string { - const bytes: number[] = []; - let b: number; - - while((b = this.readByte()) !== 10) { - bytes.push(b); - } - - return Buffer.from(bytes).toString(); - } - - public readNewString(): string { - const bytes: number[] = []; - let b: number; - - while((b = this.readByte()) !== 0) { - bytes.push(b); - } - - return Buffer.from(bytes).toString(); - } - - public readBytes(length: number): Buffer { - const result = this.buffer.slice(this.readerIndex, this.readerIndex + length + 1); - this.readerIndex += length; - return result; - } - - public writeByte(value: number): void { - this.buffer.writeInt8(value, this.writerIndex++); - } - - public writeByteInverted(value: number): void { - this.writeByte(-value); - } - - public writeOffsetByte(value: number): void { - this.writeByte(0xff & value + 128); - } - - public writeUnsignedOffsetByte(value: number): void { - this.writeUnsignedByte(value + 128); - } - - public writeUnsignedByteOffset(value: number): void { - this.writeUnsignedByte(0xff & value + 128); - } - - public writeNegativeOffsetByte(value: number): void { - this.writeUnsignedByte(128 - value); - } - - public writeUnsignedByte(value: number): void { - this.buffer.writeUInt8(value, this.writerIndex++); - } - - public writeUnsignedByteInverted(value: number): void { - this.writeUnsignedByte(~value & 0xff); - } - - public writeUnsignedShortBE(value: number): void { - this.buffer.writeUInt16BE(value, this.writerIndex); - this.writerIndex += 2; - } - - public writeShortBE(value: number): void { - this.buffer.writeInt16BE(value, this.writerIndex); - this.writerIndex += 2; - } - - public writeShortLE(value: number): void { - this.buffer.writeInt16LE(value, this.writerIndex); - this.writerIndex += 2; - } - - public writeUnsignedShortLE(value: number): void { - this.buffer.writeUInt16LE(value, this.writerIndex); - this.writerIndex += 2; - } - - public writeOffsetShortBE(value: number): void { - this.writeUnsignedByte(value >> 8); - this.writeUnsignedByte(value + 128 & 0xff); - } - - public writeUnsignedOffsetShortBE(value: number): void { - this.writeUnsignedByte((value >> 8) & 0xff); - this.writeUnsignedByte(value + 128 & 0xff); - } - - public writeNegativeOffsetShortBE(value: number): void { - this.writeUnsignedByte(value >> 8); - this.writeUnsignedByte(value - 128 & 0xff); - } - - public writeOffsetShortLE(value: number): void { - this.writeUnsignedByte(value + 128 & 0xff); - this.writeUnsignedByte(value >> 8); - } - - public writeUnsignedOffsetShortLE(value: number): void { - this.writeUnsignedByte(value + 128 & 0xff); - this.writeUnsignedByte((value >> 8) & 0xff); - } - - public writeNegativeOffsetShortLE(value: number): void { - this.writeUnsignedByte(value - 128 & 0xff); - this.writeUnsignedByte(value >> 8); - } - - public writeMediumBE(value: number): void { - this.writeUnsignedByte(value >> 16); - this.writeUnsignedByte(value >> 8); - this.writeUnsignedByte(value); - } - - public writeMediumME(value: number): void { - this.writeUnsignedByte(value >> 8); - this.writeUnsignedByte(value >> 16); - this.writeUnsignedByte(value); - } - - public writeIntLE(value: number): void { - this.buffer.writeInt32LE(value, this.writerIndex); - this.writerIndex += 4; - } - - public writeIntBE(value: number): void { - this.buffer.writeInt32BE(value, this.writerIndex); - this.writerIndex += 4; - } - - public writeIntME1(value: number): void { - this.writeUnsignedByte((value >> 8) & 0xff); - this.writeUnsignedByte(value & 0xff); - this.writeUnsignedByte((value >> 24) & 0xff); - this.writeUnsignedByte((value >> 16) & 0xff); - } - - public writeIntME2(value: number): void { - this.writeUnsignedByte((value >> 16) & 0xff); - this.writeUnsignedByte((value >> 24) & 0xff); - this.writeUnsignedByte(value & 0xff); - this.writeUnsignedByte((value >> 8) & 0xff); - } - - public writeLongBE(value: bigint): void { - this.buffer.writeBigInt64BE(value, this.writerIndex); - this.writerIndex += 8; - } - - // Old format string (300-era) - public writeString(value: string): void { - const encoder = new TextEncoder(); - const bytes = encoder.encode(value); - - for(const byte of bytes) { - this.writeByte(byte); - } - - this.writeByte(10); // end of line - } - - // New format string (400-era) - public writeNewString(value: string): void { - const encoder = new TextEncoder(); - const bytes = encoder.encode(value); - - for(const byte of bytes) { - this.writeByte(byte); - } - - this.writeByte(0); // end of line - } - - public writeSmart(value: number): void { - if(value >= 128) { - this.writeShortBE(value); - } else { - this.writeByte(value); - } - } - - public getReadable(): number { - if(this.buffer.length === 0) { - return 0; - } - - return this.buffer.length - this.readerIndex; - } - - public getWritable(): number { - return this.buffer.length - this.writerIndex; - } - - public getBuffer(): Buffer { - return this.buffer; - } - - /** - * Gets all of the data currently in the buffer, excluding past the current writer index. - */ - public getData(): Buffer { - return this.buffer.slice(0, this.writerIndex); - } - - public getUnreadData(): Buffer { - return this.buffer.slice(this.readerIndex, this.buffer.length + 1); - } - - public getSlice(position: number, length: number): RsBuffer { - return new RsBuffer(this.buffer.slice(position, position + length)); - } - - public flip(): RsBuffer { - this.buffer = this.getData().reverse(); - return this; - } - - public getWriterIndex(): number { - return this.writerIndex; - } - - public getReaderIndex(): number { - return this.readerIndex; - } - - public setWriterIndex(position: number): void { - this.writerIndex = position; - } - - public setReaderIndex(position: number): void { - this.readerIndex = position; - } -} diff --git a/src/util/strings.ts b/src/util/strings.ts index 954da89b2..921fff832 100644 --- a/src/util/strings.ts +++ b/src/util/strings.ts @@ -63,3 +63,18 @@ export function wrapText(text: string, maxWidth: number): string[] { return lines; } + +export function stringToLong(s: string): bigint { + let l: bigint = BigInt(0); + + for(let i = 0; i < s.length && i < 12; i++) { + const c = s.charAt(i); + const cc = s.charCodeAt(i); + l *= BigInt(37); + if(c >= 'A' && c <= 'Z') l += BigInt((1 + cc) - 65); + else if(c >= 'a' && c <= 'z') l += BigInt((1 + cc) - 97); + else if(c >= '0' && c <= '9') l += BigInt((27 + cc) - 48); + } + while(l % BigInt(37) == BigInt(0) && l != BigInt(0)) l /= BigInt(37); + return l; +} diff --git a/src/world/actor/player/player.ts b/src/world/actor/player/player.ts index ed6c93627..ae1f03c7c 100644 --- a/src/world/actor/player/player.ts +++ b/src/world/actor/player/player.ts @@ -29,7 +29,7 @@ import { ActionPlugin } from '@server/plugins/plugin'; import { songs } from '@server/world/config/songs'; import { colors, hexToRgb, rgbTo16Bit } from '@server/util/colors'; import { quests } from '@server/world/config/quests'; -import { NewFormatItemDefinition } from '@runejs/cache-parser'; +import { ItemDefinition } from '@runejs/cache-parser'; const DEFAULT_TAB_WIDGET_IDS = [ 92, widgets.skillsTab, 274, widgets.inventory.widgetId, widgets.equipment.widgetId, 271, 192, -1, 131, 148, @@ -456,7 +456,7 @@ export class Player extends Actor { if(questData.completion.itemId) { this.outgoingPackets.updateWidgetModel1(widgets.questReward, 3, - (cache.itemDefinitions.get(questData.completion.itemId) as NewFormatItemDefinition).inventoryModelId); + (cache.itemDefinitions.get(questData.completion.itemId) as ItemDefinition).inventoryModelId); } else if(questData.completion.modelId) { this.outgoingPackets.updateWidgetModel1(widgets.questReward, 3, questData.completion.modelId); } diff --git a/src/world/actor/player/updating/actor-updating.ts b/src/world/actor/player/updating/actor-updating.ts index 3a6adcdb0..bbe9fdb84 100644 --- a/src/world/actor/player/updating/actor-updating.ts +++ b/src/world/actor/player/updating/actor-updating.ts @@ -1,4 +1,3 @@ -import { RsBuffer } from '@server/net/rs-buffer'; import { world } from '@server/game-server'; import { Packet } from '@server/net/packet'; import { Npc } from '@server/world/actor/npc/npc'; @@ -6,11 +5,13 @@ import { Player } from '../player'; import { Position } from '@server/world/position'; import { QuadtreeKey } from '@server/world/world'; import { Actor } from '@server/world/actor/actor'; +import { ByteBuffer } from '@runejs/byte-buffer'; /** * Handles the registration of nearby NPCs or Players for the specified player. */ -export function registerNewActors(packet: Packet, player: Player, trackedActors: Actor[], nearbyActors: QuadtreeKey[], registerActor: (actor: Actor) => void): void { +export function registerNewActors(packet: Packet, player: Player, trackedActors: Actor[], nearbyActors: QuadtreeKey[], + registerActor: (actor: Actor) => void): void { if(trackedActors.length >= 255) { return; } @@ -69,8 +70,9 @@ export function registerNewActors(packet: Packet, player: Player, trackedActors: /** * Handles updating of nearby NPCs or Players for the specified player. */ -export function updateTrackedActors(packet: Packet, playerPosition: Position, appendUpdateMaskData: (actor: Actor) => void, trackedActors: Actor[], nearbyActors: QuadtreeKey[]): Actor[] { - packet.writeBits(8, trackedActors.length); // Tracked actor count +export function updateTrackedActors(packet: Packet, playerPosition: Position, appendUpdateMaskData: (actor: Actor) => void, + trackedActors: Actor[], nearbyActors: QuadtreeKey[]): Actor[] { + packet.putBits(8, trackedActors.length); // Tracked actor count if(trackedActors.length === 0) { return []; @@ -98,8 +100,9 @@ export function updateTrackedActors(packet: Packet, playerPosition: Position, ap appendUpdateMaskData(trackedActor); existingTrackedActors.push(trackedActor); } else { - packet.writeBits(1, 1); - packet.writeBits(2, 3); + // De-register the actor if they are no longer nearby + packet.putBits(1, 1); + packet.putBits(2, 3); } } @@ -109,30 +112,30 @@ export function updateTrackedActors(packet: Packet, playerPosition: Position, ap /** * Applends movement data of a player or NPC to the specified updating packet. */ -export function appendMovement(actor: Actor, packet: RsBuffer): void { +export function appendMovement(actor: Actor, packet: ByteBuffer): void { if(actor.walkDirection !== -1) { // Actor is walking/running - packet.writeBits(1, 1); // Update required + packet.putBits(1, 1); // Update required if(actor.runDirection === -1) { // Actor is walking - packet.writeBits(2, 1); // Actor walking - packet.writeBits(3, actor.walkDirection); + packet.putBits(2, 1); // Actor walking + packet.putBits(3, actor.walkDirection); } else { // Actor is running - packet.writeBits(2, 2); // Actor running - packet.writeBits(3, actor.walkDirection); - packet.writeBits(3, actor.runDirection); + packet.putBits(2, 2); // Actor running + packet.putBits(3, actor.walkDirection); + packet.putBits(3, actor.runDirection); } - packet.writeBits(1, actor.updateFlags.updateBlockRequired ? 1 : 0); // Whether or not an update flag block follows + packet.putBits(1, actor.updateFlags.updateBlockRequired ? 1 : 0); // Whether or not an update flag block follows } else { // Did not move if(actor.updateFlags.updateBlockRequired) { - packet.writeBits(1, 1); // Update required - packet.writeBits(2, 0); // Signify the player did not move + packet.putBits(1, 1); // Update required + packet.putBits(2, 0); // Signify the player did not move } else { - packet.writeBits(1, 0); // No update required + packet.putBits(1, 0); // No update required } } } diff --git a/src/world/actor/player/updating/npc-update-task.ts b/src/world/actor/player/updating/npc-update-task.ts index e35419a1a..bec77555a 100644 --- a/src/world/actor/player/updating/npc-update-task.ts +++ b/src/world/actor/player/updating/npc-update-task.ts @@ -1,11 +1,10 @@ import { Task } from '@server/task/task'; import { Player } from '../player'; import { Packet, PacketType } from '@server/net/packet'; -import { RsBuffer } from '@server/net/rs-buffer'; import { Npc } from '@server/world/actor/npc/npc'; import { world } from '@server/game-server'; import { registerNewActors, updateTrackedActors } from './actor-updating'; -import { directionData } from '@server/world/direction'; +import { ByteBuffer } from '@runejs/byte-buffer'; /** * Handles the chonky npc updating packet for a specific player. @@ -22,9 +21,9 @@ export class NpcUpdateTask extends Task { public async execute(): Promise { return new Promise(resolve => { const npcUpdatePacket: Packet = new Packet(128, PacketType.DYNAMIC_LARGE); - npcUpdatePacket.openBitChannel(); + npcUpdatePacket.openBitBuffer(); - const updateMaskData = RsBuffer.create(); + const updateMaskData = new ByteBuffer(5000); const nearbyNpcs = world.npcTree.colliding({ x: this.player.position.x - 15, @@ -45,25 +44,25 @@ export class NpcUpdateTask extends Task { this.player.trackedNpcs.push(newNpc); // Notify the client of the new npc and their worldIndex - npcUpdatePacket.writeBits(15, newNpc.worldIndex); - npcUpdatePacket.writeBits(3, newNpc.faceDirection); - npcUpdatePacket.writeBits(5, positionOffsetX); // World Position X axis offset relative to the player - npcUpdatePacket.writeBits(5, positionOffsetY); // World Position Y axis offset relative to the player - npcUpdatePacket.writeBits(1, newNpc.updateFlags.updateBlockRequired ? 1 : 0); // Update is required - npcUpdatePacket.writeBits(1, 1); // Discard client walking queues - npcUpdatePacket.writeBits(13, newNpc.id); + npcUpdatePacket.putBits(15, newNpc.worldIndex); + npcUpdatePacket.putBits(3, newNpc.faceDirection); + npcUpdatePacket.putBits(5, positionOffsetX); // World Position X axis offset relative to the player + npcUpdatePacket.putBits(5, positionOffsetY); // World Position Y axis offset relative to the player + npcUpdatePacket.putBits(1, newNpc.updateFlags.updateBlockRequired ? 1 : 0); // Update is required + npcUpdatePacket.putBits(1, 1); // Discard client walking queues + npcUpdatePacket.putBits(13, newNpc.id); this.appendUpdateMaskData(newNpc, updateMaskData); }); - if(updateMaskData.getWriterIndex() !== 0) { - npcUpdatePacket.writeBits(15, 32767); - npcUpdatePacket.closeBitChannel(); + if(updateMaskData.writerIndex !== 0) { + npcUpdatePacket.putBits(15, 32767); + npcUpdatePacket.closeBitBuffer(); - npcUpdatePacket.writeBytes(updateMaskData); + npcUpdatePacket.putBytes(updateMaskData.flipWriter()); } else { // No npc updates were appended, so just end the packet here - npcUpdatePacket.closeBitChannel(); + npcUpdatePacket.closeBitBuffer(); } this.player.outgoingPackets.queue(npcUpdatePacket, true); @@ -71,7 +70,7 @@ export class NpcUpdateTask extends Task { }); } - private appendUpdateMaskData(npc: Npc, updateMaskData: RsBuffer): void { + private appendUpdateMaskData(npc: Npc, updateMaskData: ByteBuffer): void { const updateFlags = npc.updateFlags; if(!updateFlags.updateBlockRequired) { return; @@ -95,14 +94,14 @@ export class NpcUpdateTask extends Task { mask |= 0x10; } - updateMaskData.writeUnsignedByte(mask); + updateMaskData.put(mask, 'BYTE'); if(updateFlags.faceActor !== undefined) { const actor = updateFlags.faceActor; if(actor === null) { // Reset faced actor - updateMaskData.writeUnsignedOffsetShortBE(65535); + updateMaskData.put(65535, 'SHORT'); } else { let worldIndex = actor.worldIndex; @@ -113,7 +112,7 @@ export class NpcUpdateTask extends Task { worldIndex += 32768 + 1; } - updateMaskData.writeUnsignedOffsetShortBE(worldIndex); + updateMaskData.put(worldIndex, 'SHORT'); } } @@ -121,20 +120,20 @@ export class NpcUpdateTask extends Task { const message = updateFlags.chatMessages[0]; if(message.message) { - updateMaskData.writeNewString(message.message); + updateMaskData.putString(message.message); } else { - updateMaskData.writeNewString('Undefined Message'); + updateMaskData.putString('Undefined Message'); } } if(updateFlags.appearanceUpdateRequired) { - updateMaskData.writeOffsetShortBE(npc.id); + updateMaskData.put(npc.id, 'SHORT'); } if(updateFlags.facePosition) { const position = updateFlags.facePosition; - updateMaskData.writeOffsetShortBE(position.x * 2 + 1); - updateMaskData.writeShortLE(position.y * 2 + 1); + updateMaskData.put(position.x * 2 + 1, 'SHORT'); + updateMaskData.put(position.y * 2 + 1, 'SHORT', 'LITTLE_ENDIAN'); } if(updateFlags.animation) { @@ -142,12 +141,12 @@ export class NpcUpdateTask extends Task { if(animation === null || animation.id === -1) { // Reset animation - updateMaskData.writeOffsetShortBE(-1); - updateMaskData.writeByteInverted(0); + updateMaskData.put(65535, 'SHORT'); + updateMaskData.put(0); } else { const delay = updateFlags.animation.delay || 0; - updateMaskData.writeOffsetShortBE(animation.id); - updateMaskData.writeByteInverted(delay); + updateMaskData.put(animation.id, 'SHORT'); + updateMaskData.put(delay); } } } diff --git a/src/world/actor/player/updating/player-update-task.ts b/src/world/actor/player/updating/player-update-task.ts index 1492a0afb..0d51fe6f7 100644 --- a/src/world/actor/player/updating/player-update-task.ts +++ b/src/world/actor/player/updating/player-update-task.ts @@ -1,5 +1,4 @@ import { Player } from '../player'; -import { RsBuffer, stringToLong } from '@server/net/rs-buffer'; import { Task } from '@server/task/task'; import { UpdateFlags } from '@server/world/actor/update-flags'; import { Packet, PacketType } from '@server/net/packet'; @@ -7,6 +6,8 @@ import { world } from '@server/game-server'; import { EquipmentSlot, HelmetType, ItemDetails, TorsoType } from '@server/world/config/item-data'; import { ItemContainer } from '@server/world/items/item-container'; import { appendMovement, updateTrackedActors, registerNewActors } from './actor-updating'; +import { ByteBuffer } from '@runejs/byte-buffer'; +import { stringToLong } from '@server/util/strings'; /** * Handles the chonky player updating packet. @@ -23,19 +24,19 @@ export class PlayerUpdateTask extends Task { public async execute(): Promise { return new Promise(resolve => { const updateFlags: UpdateFlags = this.player.updateFlags; - const playerUpdatePacket: Packet = new Packet(92, PacketType.DYNAMIC_LARGE); - playerUpdatePacket.openBitChannel(); + let playerUpdatePacket: Packet = new Packet(92, PacketType.DYNAMIC_LARGE); + playerUpdatePacket.openBitBuffer(); - const updateMaskData = RsBuffer.create(); + const updateMaskData = new ByteBuffer(5000); if(updateFlags.mapRegionUpdateRequired || this.player.metadata['teleporting']) { - playerUpdatePacket.writeBits(1, 1); // Update Required - playerUpdatePacket.writeBits(2, 3); // Map Region changed - playerUpdatePacket.writeBits(1, this.player.metadata['teleporting'] ? 1 : 0); // Whether or not the client should discard the current walking queue (1 if teleporting, 0 if not) - playerUpdatePacket.writeBits(2, this.player.position.level); // Player Height - playerUpdatePacket.writeBits(1, updateFlags.updateBlockRequired ? 1 : 0); // Whether or not an update flag block follows - playerUpdatePacket.writeBits(7, this.player.position.chunkLocalX); // Player Local Chunk X - playerUpdatePacket.writeBits(7, this.player.position.chunkLocalY); // Player Local Chunk Y + playerUpdatePacket.putBits(1, 1); // Update Required + playerUpdatePacket.putBits(2, 3); // Map Region changed + playerUpdatePacket.putBits(1, this.player.metadata['teleporting'] ? 1 : 0); // Whether or not the client should discard the current walking queue (1 if teleporting, 0 if not) + playerUpdatePacket.putBits(2, this.player.position.level); // Player Height + playerUpdatePacket.putBits(1, updateFlags.updateBlockRequired ? 1 : 0); // Whether or not an update flag block follows + playerUpdatePacket.putBits(7, this.player.position.chunkLocalX); // Player Local Chunk X + playerUpdatePacket.putBits(7, this.player.position.chunkLocalY); // Player Local Chunk Y } else { appendMovement(this.player, playerUpdatePacket); } @@ -70,25 +71,25 @@ export class PlayerUpdateTask extends Task { this.player.trackedPlayers.push(newPlayer); // Notify the client of the new player and their worldIndex - playerUpdatePacket.writeBits(11, newPlayer.worldIndex + 1); + playerUpdatePacket.putBits(11, newPlayer.worldIndex + 1); - playerUpdatePacket.writeBits(5, positionOffsetX); // World Position X axis offset relative to the main player - playerUpdatePacket.writeBits(5, positionOffsetY); // World Position Y axis offset relative to the main player - playerUpdatePacket.writeBits(3, newPlayer.faceDirection); - playerUpdatePacket.writeBits(1, 1); // Update is required - playerUpdatePacket.writeBits(1, 1); // Discard client walking queues + playerUpdatePacket.putBits(5, positionOffsetX); // World Position X axis offset relative to the main player + playerUpdatePacket.putBits(5, positionOffsetY); // World Position Y axis offset relative to the main player + playerUpdatePacket.putBits(3, newPlayer.faceDirection); + playerUpdatePacket.putBits(1, 1); // Update is required + playerUpdatePacket.putBits(1, 1); // Discard client walking queues this.appendUpdateMaskData(newPlayer, updateMaskData, true); }); - if(updateMaskData.getWriterIndex() !== 0) { - playerUpdatePacket.writeBits(11, 2047); - playerUpdatePacket.closeBitChannel(); + if(updateMaskData.writerIndex !== 0) { + playerUpdatePacket.putBits(11, 2047); + playerUpdatePacket.closeBitBuffer(); - playerUpdatePacket.writeBytes(updateMaskData); + playerUpdatePacket.putBytes(updateMaskData.flipWriter()); } else { // No player updates were appended, so just end the packet here - playerUpdatePacket.closeBitChannel(); + playerUpdatePacket.closeBitBuffer(); } this.player.outgoingPackets.queue(playerUpdatePacket, true); @@ -96,7 +97,7 @@ export class PlayerUpdateTask extends Task { }); } - private appendUpdateMaskData(player: Player, updateMaskData: RsBuffer, forceUpdate?: boolean): void { + private appendUpdateMaskData(player: Player, updateMaskData: ByteBuffer, forceUpdate?: boolean): void { const updateFlags = player.updateFlags; if(!updateFlags.updateBlockRequired && !forceUpdate) { @@ -126,16 +127,16 @@ export class PlayerUpdateTask extends Task { if(mask >= 0x100) { mask |= 0x2; - updateMaskData.writeByte(mask & 0xff); - updateMaskData.writeByte(mask >> 8); + updateMaskData.put(mask & 0xff); + updateMaskData.put(mask >> 8); } else { - updateMaskData.writeByte(mask); + updateMaskData.put(mask); } if(updateFlags.facePosition) { const position = updateFlags.facePosition; - updateMaskData.writeUnsignedShortBE(position.x * 2 + 1); - updateMaskData.writeUnsignedShortLE(position.y * 2 + 1); + updateMaskData.put(position.x * 2 + 1, 'SHORT'); + updateMaskData.put(position.y * 2 + 1, 'SHORT', 'LITTLE_ENDIAN'); } if(updateFlags.animation !== undefined) { @@ -143,12 +144,12 @@ export class PlayerUpdateTask extends Task { if(animation === null || animation.id === -1) { // Reset animation - updateMaskData.writeShortLE(-1); - updateMaskData.writeUnsignedByteInverted(0); + updateMaskData.put(-1, 'SHORT', 'LITTLE_ENDIAN'); + updateMaskData.put(0, 'BYTE'); } else { const delay = updateFlags.animation.delay || 0; - updateMaskData.writeUnsignedShortLE(updateFlags.animation.id); - updateMaskData.writeUnsignedByteInverted(delay); + updateMaskData.put(updateFlags.animation.id, 'SHORT', 'LITTLE_ENDIAN'); + updateMaskData.put(delay, 'BYTE'); } } @@ -157,7 +158,7 @@ export class PlayerUpdateTask extends Task { if(actor === null) { // Reset faced actor - updateMaskData.writeOffsetShortBE(65535); + updateMaskData.put(65535, 'SHORT'); } else { let worldIndex = actor.worldIndex; @@ -168,34 +169,34 @@ export class PlayerUpdateTask extends Task { worldIndex += 32768 + 1; } - updateMaskData.writeOffsetShortBE(worldIndex); + updateMaskData.put(worldIndex, 'SHORT'); } } if(updateFlags.chatMessages.length !== 0) { const message = updateFlags.chatMessages[0]; - updateMaskData.writeUnsignedShortBE(((message.color & 0xFF) << 8) + (message.effects & 0xFF)); - updateMaskData.writeUnsignedOffsetByte(player.rights.valueOf()); - updateMaskData.writeByteInverted(message.data.length); + updateMaskData.put(((message.color & 0xFF) << 8) + (message.effects & 0xFF), 'SHORT'); + updateMaskData.put(player.rights.valueOf(), 'BYTE'); + updateMaskData.put(message.data.length, 'BYTE'); for(let i = 0; i < message.data.length; i++) { - updateMaskData.writeUnsignedOffsetByte(message.data.readInt8(i)); + updateMaskData.put(message.data.readInt8(i), 'BYTE'); } } if(updateFlags.appearanceUpdateRequired || forceUpdate) { const equipment = player.equipment; - const appearanceData: RsBuffer = RsBuffer.create(); - appearanceData.writeByte(player.appearance.gender); // Gender - appearanceData.writeByte(-1); // Skull Icon - appearanceData.writeByte(-1); // Prayer Icon + const appearanceData = new ByteBuffer(500); + appearanceData.put(player.appearance.gender); // Gender + appearanceData.put(-1); // Skull Icon + appearanceData.put(-1); // Prayer Icon for(let i = 0; i < 4; i++) { const item = equipment.items[i]; if(item) { - appearanceData.writeShortBE(0x200 + item.itemId); + appearanceData.put(0x200 + item.itemId, 'SHORT'); } else { - appearanceData.writeByte(0); + appearanceData.put(0); } } @@ -203,22 +204,22 @@ export class PlayerUpdateTask extends Task { let torsoItemData: ItemDetails = null; if(torsoItem) { torsoItemData = world.itemData.get(torsoItem.itemId); - appearanceData.writeShortBE(0x200 + torsoItem.itemId); + appearanceData.put(0x200 + torsoItem.itemId, 'SHORT'); } else { - appearanceData.writeShortBE(0x100 + player.appearance.torso); + appearanceData.put(0x100 + player.appearance.torso, 'SHORT'); } const offHandItem = equipment.items[EquipmentSlot.OFF_HAND]; if(offHandItem) { - appearanceData.writeShortBE(0x200 + offHandItem.itemId); + appearanceData.put(0x200 + offHandItem.itemId, 'SHORT'); } else { - appearanceData.writeByte(0); + appearanceData.put(0); } if(torsoItemData && torsoItemData.equipment && torsoItemData.equipment.torsoType && torsoItemData.equipment.torsoType === TorsoType.FULL) { - appearanceData.writeByte(0); + appearanceData.put(0); } else { - appearanceData.writeShortBE(0x100 + player.appearance.arms); + appearanceData.put(0x100 + player.appearance.arms, 'SHORT'); } this.appendBasicAppearanceItem(appearanceData, equipment, player.appearance.legs, EquipmentSlot.LEGS); @@ -240,18 +241,18 @@ export class PlayerUpdateTask extends Task { } if(!helmetType || helmetType === HelmetType.HAT) { - appearanceData.writeShortBE(0x100 + player.appearance.head); + appearanceData.put(0x100 + player.appearance.head, 'SHORT'); } else { - appearanceData.writeByte(0); + appearanceData.put(0); } this.appendBasicAppearanceItem(appearanceData, equipment, player.appearance.hands, EquipmentSlot.GLOVES); this.appendBasicAppearanceItem(appearanceData, equipment, player.appearance.feet, EquipmentSlot.BOOTS); if(player.appearance.gender === 1 || fullHelmet) { - appearanceData.writeByte(0); + appearanceData.put(0); } else { - appearanceData.writeShortBE(0x100 + player.appearance.facialHair); + appearanceData.put(0x100 + player.appearance.facialHair, 'SHORT'); } [ @@ -260,7 +261,7 @@ export class PlayerUpdateTask extends Task { player.appearance.legColor, player.appearance.feetColor, player.appearance.skinColor, - ].forEach(color => appearanceData.writeByte(color)); + ].forEach(color => appearanceData.put(color)); [ 0x328, // stand @@ -270,31 +271,31 @@ export class PlayerUpdateTask extends Task { 0x335, // turn 90 0x336, // turn 90 reverse 0x338, // run - ].forEach(animationId => appearanceData.writeShortBE(animationId)); + ].forEach(animationId => appearanceData.put(animationId, 'SHORT')); - appearanceData.writeLongBE(stringToLong(player.username)); // Username - appearanceData.writeByte(3); // Combat Level - appearanceData.writeShortBE(0); // Skill Level (Total Level) + appearanceData.put(stringToLong(player.username), 'LONG'); // Username + appearanceData.put(3); // Combat Level + appearanceData.put(0, 'SHORT'); // Skill Level (Total Level) - const appearanceDataSize = appearanceData.getWriterIndex(); + const appearanceDataSize = appearanceData.writerIndex; - updateMaskData.writeByte(appearanceDataSize); - updateMaskData.writeBytes(appearanceData.getData()); + updateMaskData.put(appearanceDataSize); + updateMaskData.putBytes(appearanceData.flipWriter()); } if(updateFlags.graphics) { const delay = updateFlags.graphics.delay || 0; - updateMaskData.writeUnsignedShortLE(updateFlags.graphics.id); - updateMaskData.writeIntME2(updateFlags.graphics.height << 16 | delay & 0xffff); + updateMaskData.put(updateFlags.graphics.id, 'SHORT', 'LITTLE_ENDIAN'); + updateMaskData.put(updateFlags.graphics.height << 16 | delay & 0xffff, 'INT'); } } - private appendBasicAppearanceItem(buffer: RsBuffer, equipment: ItemContainer, appearanceInfo: number, equipmentSlot: EquipmentSlot): void { + private appendBasicAppearanceItem(buffer: ByteBuffer, equipment: ItemContainer, appearanceInfo: number, equipmentSlot: EquipmentSlot): void { const item = equipment.items[equipmentSlot]; if(item) { - buffer.writeShortBE(0x200 + item.itemId); + buffer.put(0x200 + item.itemId, 'SHORT'); } else { - buffer.writeShortBE(0x100 + appearanceInfo); + buffer.put(0x100 + appearanceInfo, 'SHORT'); } } diff --git a/src/world/config/item-data.ts b/src/world/config/item-data.ts index 68d7cb4db..259e965ee 100644 --- a/src/world/config/item-data.ts +++ b/src/world/config/item-data.ts @@ -1,5 +1,5 @@ import { readFileSync, writeFileSync } from 'fs'; -import { ItemDefinition, NewFormatItemDefinition } from '@runejs/cache-parser'; +import { ItemDefinition } from '@runejs/cache-parser'; import { logger } from '@runejs/logger/dist/logger'; import { JSON_SCHEMA, safeLoad, safeDump } from 'js-yaml'; @@ -77,7 +77,7 @@ export interface ItemData { }; } -export interface ItemDetails extends NewFormatItemDefinition, ItemData { +export interface ItemDetails extends ItemDefinition, ItemData { } function checkField(origin: ItemDetails, destination: ItemData, fieldName: string): void { @@ -127,7 +127,7 @@ export function parseItemData(itemDefinitions: Map): Map } const itemDetailsMap: Map = new Map(); - itemDefinitions.forEach((itemDefinition: NewFormatItemDefinition) => { + itemDefinitions.forEach((itemDefinition: ItemDefinition) => { let itemData = itemDataList.find(i => i.id === itemDefinition.id); if(!itemData) { diff --git a/src/world/map/chunk.ts b/src/world/map/chunk.ts index 1697b2ad2..27a2f529b 100644 --- a/src/world/map/chunk.ts +++ b/src/world/map/chunk.ts @@ -143,10 +143,6 @@ export class Chunk { const objectOrientation = locationObject.orientation; const objectDetails: LocationObjectDefinition = cache.locationObjectDefinitions.get(locationObject.objectId); - if(x === 3223 && y === 3217) { - console.log(`${x},${y} is type ${objectType} with orientation ${objectOrientation}`); - } - if(objectDetails.solid) { if(objectType === 22) { if(objectDetails.hasOptions) {