Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 30 additions & 24 deletions src/net/outgoing-packets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import { Position } from '@server/world/position';
import { LandscapeObject } from '@runejs/cache-parser';
import { Chunk, ChunkUpdateItem } from '@server/world/map/chunk';
import { WorldItem } from '@server/world/items/world-item';
import { rsTime } from '@server/util/time';
import { addressToInt } from '@server/util/address';

/**
* A helper class for sending various network packets back to the game client.
Expand All @@ -35,9 +33,9 @@ export class OutgoingPackets {
}

public playQuickSong(songId: number, previousSongId: number): void {
const packet = new Packet(249);
packet.writeShortLE(songId);
packet.writeMediumME(previousSongId);
const packet = new Packet(40);
packet.writeMediumBE(previousSongId);
packet.writeOffsetShortBE(songId);

this.queue(packet);
}
Expand Down Expand Up @@ -74,32 +72,32 @@ export class OutgoingPackets {
offsetX -= (this.player.lastMapRegionUpdatePosition.chunkX * 8);
offsetY -= (this.player.lastMapRegionUpdatePosition.chunkY * 8);

return {offsetX, offsetY};
return { offsetX, offsetY };
}

public updateChunk(chunk: Chunk, chunkUpdates: ChunkUpdateItem[]): void {
const {offsetX, offsetY} = this.getChunkOffset(chunk);
const { offsetX, offsetY } = this.getChunkOffset(chunk);

const packet = new Packet(63, PacketType.DYNAMIC_LARGE);
packet.writeByteInverted(offsetX);
packet.writeNegativeOffsetByte(offsetY);

chunkUpdates.forEach(update => {
if (update.type === 'ADD') {
if (update.object) {
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.rotation & 3));
packet.writeUnsignedShortBE(update.object.objectId);
packet.writeUnsignedOffsetByte(offset);
} else if (update.worldItem) {
} 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);
}
} else if (update.type === 'REMOVE') {
} else if(update.type === 'REMOVE') {
const offset = this.getChunkPositionOffset(update.object.x, update.object.y, chunk);
packet.writeUnsignedByte(143);
packet.writeUnsignedOffsetByte(offset);
Expand All @@ -111,7 +109,7 @@ export class OutgoingPackets {
}

public clearChunk(chunk: Chunk): void {
const {offsetX, offsetY} = this.getChunkOffset(chunk);
const { offsetX, offsetY } = this.getChunkOffset(chunk);

const packet = new Packet(64);
packet.writeUnsignedByte(offsetY);
Expand Down Expand Up @@ -216,7 +214,7 @@ export class OutgoingPackets {
public updateClientConfig(configId: number, value: number): void {
let packet: Packet;

if (value > 128) {
if(value > 128) {
packet = new Packet(2);
packet.writeIntME2(value);
packet.writeUnsignedShortBE(configId);
Expand Down Expand Up @@ -246,6 +244,14 @@ export class OutgoingPackets {
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);

this.queue(packet);
}

public closeActiveWidgets(): void {
this.queue(new Packet(180));
}
Expand All @@ -263,12 +269,12 @@ export class OutgoingPackets {
packet.writeIntBE(widget.widgetId << 16 | widget.containerId);
packet.writeSmart(slot);

if (!item) {
if(!item) {
packet.writeUnsignedShortBE(0);
} else {
packet.writeUnsignedShortBE(item.itemId + 1); // +1 because 0 means an empty slot

if (item.amount >= 255) {
if(item.amount >= 255) {
packet.writeUnsignedByte(255);
packet.writeIntBE(item.amount);
} else {
Expand All @@ -286,12 +292,12 @@ export class OutgoingPackets {

const items = container.items;
items.forEach(item => {
if (!item) {
if(!item) {
// Empty slot
packet.writeUnsignedOffsetByte(0);
packet.writeOffsetShortBE(0);
} else {
if (item.amount >= 255) {
if(item.amount >= 255) {
packet.writeUnsignedByteOffset(255);
packet.writeIntBE(item.amount);
} else {
Expand All @@ -311,7 +317,7 @@ export class OutgoingPackets {
packet.writeShortBE(itemIds.length);

itemIds.forEach(itemId => {
if (!itemId) {
if(!itemId) {
// Empty slot
packet.writeUnsignedOffsetByte(0);
packet.writeOffsetShortBE(0);
Expand Down Expand Up @@ -437,9 +443,9 @@ export class OutgoingPackets {
packet.writeOffsetShortLE(this.player.position.chunkY + 6);
packet.writeByteInverted(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++) {
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);
}
}
Expand All @@ -449,12 +455,12 @@ export class OutgoingPackets {
}

public flushQueue(): void {
if (!this.socket || this.socket.destroyed) {
if(!this.socket || this.socket.destroyed) {
return;
}

const buffer = Buffer.concat([...this.packetQueue, ...this.updatingQueue]);
if (buffer.length !== 0) {
if(buffer.length !== 0) {
this.socket.write(buffer);
}

Expand All @@ -463,7 +469,7 @@ export class OutgoingPackets {
}

public queue(packet: Packet, updateTask: boolean = false): void {
if (!this.socket || this.socket.destroyed) {
if(!this.socket || this.socket.destroyed) {
return;
}

Expand Down
6 changes: 6 additions & 0 deletions src/net/rs-buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,12 @@ export class RsBuffer {
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);
Expand Down
9 changes: 9 additions & 0 deletions src/plugins/commands/text-color-test-command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ActionType, RunePlugin } from '@server/plugins/plugin';
import { commandAction } from '@server/world/actor/player/action/input-command-action';

const action: commandAction = (details) => {
const { player } = details;
player.modifyWidget(239, { childId: 82, textColor: 0x0000ff });
};

export default new RunePlugin({ type: ActionType.COMMAND, commands: 'textcolortest', action });
16 changes: 16 additions & 0 deletions src/util/colors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export function hexToRgb(hex: number): { r: number, b: number, g: number } {
return {
r: (hex >> 16) & 0xff,
g: (hex >> 8) & 0xff,
b: hex & 0xff
};
}

export function rgbTo16Bit(r: number, g: number, b: number): number {
return ((r & 0x1f) << 11) | ((g & 0x3f) << 5) | (b & 0x1f) << 0;
}

export const colors = {
green: 0x00ff00,
yellow: 0xffff00
};
26 changes: 21 additions & 5 deletions src/world/actor/player/player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import { daysSinceLastLogin } from '@server/util/time';
import { itemIds } from '@server/world/config/item-ids';
import { dialogueAction } from '@server/world/actor/player/action/dialogue-action';
import { ActionPlugin } from '@server/plugins/plugin';
import { songs } from '@server/world/config/songs';
import { colors, hexToRgb, rgbTo16Bit } from '@server/util/colors';

const DEFAULT_TAB_WIDGET_IDS = [
92, widgets.skillsTab, 274, widgets.inventory.widgetId, widgets.equipment.widgetId, 271, 192, -1, 131, 148,
Expand Down Expand Up @@ -224,6 +226,8 @@ export class Player extends Actor {

this.updateBonuses();
this.updateCarryWeight(true);
this.modifyWidget(widgets.musicPlayerTab, { childId: 82, textColor: colors.green }); // Set "Harmony" to green/unlocked on the music tab
this.playSong(songs.harmony);

this.inventory.containerUpdated.subscribe(event => this.inventoryUpdated(event));

Expand All @@ -242,7 +246,6 @@ export class Player extends Actor {
resolve();
}).then(() => {
this.outgoingPackets.flushQueue();

logger.info(`${this.username}:${this.worldIndex} has logged in.`);
});
}
Expand Down Expand Up @@ -359,18 +362,31 @@ export class Player extends Actor {
* @param widgetId The widget id of the widget to modify.
* @param options The options with which to modify the widget.
*/
public modifyWidget(widgetId: number, options: { childId?: number, text?: string, hidden?: boolean }): void {
const { childId, text, hidden } = options;
public modifyWidget(widgetId: number, options: { childId?: number, text?: string, hidden?: boolean, textColor?: number }): void {
const { childId, text, hidden, textColor } = options;

if(childId) {
if(text) {
if(text !== undefined) {
this.outgoingPackets.updateWidgetString(widgetId, childId, text);
} else if(hidden !== undefined) {
}
if(hidden !== undefined) {
this.outgoingPackets.toggleWidgetVisibility(widgets.skillGuide, childId, hidden);
}
if(textColor !== undefined) {
const { r, g, b } = hexToRgb(textColor);
this.outgoingPackets.updateWidgetColor(widgetId, childId, rgbTo16Bit(r, g, b));
}
}
}

/**
* Plays the given song for the player.
* @param songId The id of the song to play.
*/
public playSong(songId: number): void {
this.outgoingPackets.playSong(songId);
}

/**
* Plays a sound for this specific player.
* @param soundId The id of the sound effect.
Expand Down
3 changes: 3 additions & 0 deletions src/world/config/songs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const songs = {
harmony: 76
};
1 change: 1 addition & 0 deletions src/world/config/widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const widgets: any = {
logoutTab: 182,
settingsTab: 261,
emotesTab: 464,
musicPlayerTab: 239,
shop: {
widgetId: 300,
containerId: 75,
Expand Down