From 3d6e9f0fad8f78e6e240ae475591a29dad29d4f1 Mon Sep 17 00:00:00 2001 From: Henning Berge Date: Wed, 24 Mar 2021 14:58:07 +0100 Subject: [PATCH 1/4] sync shop between connected clients --- src/game-engine/config/shop-config.ts | 32 ++++++++++++++++++- .../world/actor/player/interface-state.ts | 6 ++-- .../npcs/lumbridge/shopkeeper.plugin.ts | 3 +- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/game-engine/config/shop-config.ts b/src/game-engine/config/shop-config.ts index 193304ced..9a04f7c57 100644 --- a/src/game-engine/config/shop-config.ts +++ b/src/game-engine/config/shop-config.ts @@ -1,7 +1,9 @@ -import { ItemContainer } from '@engine/world/items/item-container'; +import { ContainerUpdateEvent, ItemContainer } from '@engine/world/items/item-container'; import { findItem, loadConfigurationFiles, widgets } from '@engine/config/index'; import { Player } from '@engine/world/actor/player/player'; import { ItemDetails } from '@engine/config/item-config'; +import { WidgetClosedEvent } from '@engine/world/actor/player/interface-state'; +import { Subscription } from 'rxjs'; export type ShopStock = [ [ string, number ] ]; @@ -18,6 +20,8 @@ export class Shop { public sellRate: number; public buyRate: number; public rateModifier: number; + private customers: Player[]; + private containerSubscription: Subscription; public constructor(key: string, name: string, generalStore: boolean, stock: ShopStock, sellRate: number, buyRate: number, modifier: number) { this.key = key; @@ -30,6 +34,8 @@ export class Shop { this.rateModifier = modifier; this.originalStock = stock; this.container = new ItemContainer(40); + this.containerSubscription = this.container.containerUpdated.subscribe((_update: ContainerUpdateEvent) => this.updateCustomers()) + this.customers = []; this.resetShopStock(); } @@ -91,6 +97,12 @@ export class Shop { public open(player: Player): void { player.metadata['lastOpenedShop'] = this; + player.metadata['shopCloseListener'] = player.interfaceState.closed.subscribe((whatClosed: WidgetClosedEvent) => { + if(whatClosed && whatClosed.widget && whatClosed.widget.widgetId === widgets.shop.widgetId) { + this.removePlayerFromShop(player); + } + }) + player.outgoingPackets.updateWidgetString(widgets.shop.widgetId, widgets.shop.title, this.name); player.outgoingPackets.sendUpdateAllWidgetItems(widgets.shop, this.container); player.outgoingPackets.sendUpdateAllWidgetItems(widgets.shopPlayerInventory, player.inventory); @@ -103,8 +115,26 @@ export class Shop { slot: 'tabarea', multi: true }); + this.customers.push(player); } + private updateCustomers() { + for (const player of this.customers) { + if(player.metadata['lastOpenedShop'] === this){ + player.outgoingPackets.sendUpdateAllWidgetItems(widgets.shop, this.container); + } else { + this.removePlayerFromShop(player); + } + } + } + + private removePlayerFromShop(player: Player) { + if(player.metadata['lastOpenedShop'] === this) { + player.metadata['lastOpenedShop'] = undefined; + player.metadata['shopCloseListener'].unsubscribe(); + } + this.customers = this.customers.filter((c) => c !== player); + } } export interface ShopConfiguration { diff --git a/src/game-engine/world/actor/player/interface-state.ts b/src/game-engine/world/actor/player/interface-state.ts index 512c5f42d..8ede8f40f 100644 --- a/src/game-engine/world/actor/player/interface-state.ts +++ b/src/game-engine/world/actor/player/interface-state.ts @@ -58,7 +58,7 @@ export class Widget { } -interface WidgetClosedEvent { +export interface WidgetClosedEvent { widget: Widget; data?: number; } @@ -129,12 +129,12 @@ export class InterfaceState { public closeWidget(slot: GameInterfaceSlot, data?: number): void; public closeWidget(i: GameInterfaceSlot | number, data?: number): void { let widget: Widget | null; - if(typeof i === 'number') { widget = this.findWidget(i); } else { widget = this.widgetSlots[i] || null; } + console.log("widget closed", data,widget); if(!widget) { return; @@ -161,6 +161,8 @@ export class InterfaceState { this.widgetSlots[widget.slot] = widget; this.showWidget(widget); + console.log("widget opened"); + } public setTab(type: TabType, widget: Widget | number | null): void { diff --git a/src/plugins/npcs/lumbridge/shopkeeper.plugin.ts b/src/plugins/npcs/lumbridge/shopkeeper.plugin.ts index 182e7bcf5..7a3aa8cf3 100644 --- a/src/plugins/npcs/lumbridge/shopkeeper.plugin.ts +++ b/src/plugins/npcs/lumbridge/shopkeeper.plugin.ts @@ -2,9 +2,10 @@ import { npcInteractionActionHandler } from '@engine/world/action/npc-interactio import { findShop } from '@engine/config'; -const action: npcInteractionActionHandler = ({ player }) => +const action: npcInteractionActionHandler = ({ player }) => { findShop('rs:lumbridge_general_store')?.open(player); +} export default { pluginId: 'rs:lumbridge_general_store', hooks: [ From cc1fe7dfbda85628a3122c024253547df5fefe88 Mon Sep 17 00:00:00 2001 From: Henning Berge Date: Wed, 24 Mar 2021 14:59:23 +0100 Subject: [PATCH 2/4] remove logging --- src/game-engine/world/actor/player/interface-state.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/game-engine/world/actor/player/interface-state.ts b/src/game-engine/world/actor/player/interface-state.ts index 8ede8f40f..94d5ef69d 100644 --- a/src/game-engine/world/actor/player/interface-state.ts +++ b/src/game-engine/world/actor/player/interface-state.ts @@ -134,7 +134,6 @@ export class InterfaceState { } else { widget = this.widgetSlots[i] || null; } - console.log("widget closed", data,widget); if(!widget) { return; @@ -161,8 +160,6 @@ export class InterfaceState { this.widgetSlots[widget.slot] = widget; this.showWidget(widget); - console.log("widget opened"); - } public setTab(type: TabType, widget: Widget | number | null): void { From b5bed412288f9e7ea2cb4b5f0f2bc18b397e66d6 Mon Sep 17 00:00:00 2001 From: Tynarus Date: Wed, 24 Mar 2021 14:22:18 -0500 Subject: [PATCH 3/4] Update shop-config.ts --- src/game-engine/config/shop-config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game-engine/config/shop-config.ts b/src/game-engine/config/shop-config.ts index 9a04f7c57..146cae84d 100644 --- a/src/game-engine/config/shop-config.ts +++ b/src/game-engine/config/shop-config.ts @@ -34,7 +34,7 @@ export class Shop { this.rateModifier = modifier; this.originalStock = stock; this.container = new ItemContainer(40); - this.containerSubscription = this.container.containerUpdated.subscribe((_update: ContainerUpdateEvent) => this.updateCustomers()) + this.containerSubscription = this.container.containerUpdated.subscribe((_update: ContainerUpdateEvent) => this.updateCustomers()); this.customers = []; this.resetShopStock(); } From 918e68210aef4603541e3746d0cf40c607c21921 Mon Sep 17 00:00:00 2001 From: Henning Berge Date: Wed, 24 Mar 2021 20:33:45 +0100 Subject: [PATCH 4/4] linting --- src/game-engine/config/shop-config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game-engine/config/shop-config.ts b/src/game-engine/config/shop-config.ts index 9a04f7c57..4712d5b49 100644 --- a/src/game-engine/config/shop-config.ts +++ b/src/game-engine/config/shop-config.ts @@ -101,7 +101,7 @@ export class Shop { if(whatClosed && whatClosed.widget && whatClosed.widget.widgetId === widgets.shop.widgetId) { this.removePlayerFromShop(player); } - }) + }); player.outgoingPackets.updateWidgetString(widgets.shop.widgetId, widgets.shop.title, this.name); player.outgoingPackets.sendUpdateAllWidgetItems(widgets.shop, this.container); @@ -120,7 +120,7 @@ export class Shop { private updateCustomers() { for (const player of this.customers) { - if(player.metadata['lastOpenedShop'] === this){ + if(player.metadata['lastOpenedShop'] === this) { player.outgoingPackets.sendUpdateAllWidgetItems(widgets.shop, this.container); } else { this.removePlayerFromShop(player);