From 38d5fdfdbacbedd2c29dac06f01965bbb539f4a1 Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Sat, 9 Aug 2025 23:40:43 +0200 Subject: [PATCH] Use filtered subscriptions to save data --- plugins/minimap/controller.ts | 16 +++---- plugins/minimap/web/CanvasMinimapPage.tsx | 7 +++ plugins/minimap/web/MinimapPage.tsx | 7 +++ plugins/minimap/web/index.tsx | 53 +++++++++++++++++++---- 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/plugins/minimap/controller.ts b/plugins/minimap/controller.ts index bdbebd4c..1187759d 100644 --- a/plugins/minimap/controller.ts +++ b/plugins/minimap/controller.ts @@ -759,8 +759,8 @@ export class ControllerPlugin extends BaseControllerPlugin { const updateEvent = new ChartTagDataEvent(instance_id, tag_data); - // Broadcast to subscribed web clients only - this.controller.subscriptions.broadcast(updateEvent); + // Broadcast to subscribed web clients only with instance/surface filter + this.controller.subscriptions.broadcast(updateEvent, `${instance_id}:${tag_data.surface}`); } catch (err) { this.logger.error(`Error processing chart tag data: ${err}`); @@ -796,8 +796,8 @@ export class ControllerPlugin extends BaseControllerPlugin { chunk ); - // Broadcast to subscribed web clients only - this.controller.subscriptions.broadcast(updateEvent); + // Broadcast to subscribed web clients only with instance/surface filter + this.controller.subscriptions.broadcast(updateEvent, `${instance_id}:${surface}`); } catch (err) { this.logger.error(`Error processing tile data: ${err}`); @@ -1014,8 +1014,8 @@ export class ControllerPlugin extends BaseControllerPlugin { } this.recipeSavingQueue.get(tileKey)!.push(...buffersToWrite); - // Broadcast live update to subscribed web clients only - this.controller.subscriptions.broadcast(event); + // Broadcast live update to subscribed web clients only with instance/surface filter + this.controller.subscriptions.broadcast(event, `${instance_id}:${event.recipe_data.surface}`); } catch (err) { this.logger.error(`Error processing recipe data: ${err}`); @@ -1085,8 +1085,8 @@ export class ControllerPlugin extends BaseControllerPlugin { const updateEvent = new PlayerPositionEvent(instance_id, player_data); - // Broadcast to subscribed web clients only - this.controller.subscriptions.broadcast(updateEvent); + // Broadcast to subscribed web clients only with instance/surface filter + this.controller.subscriptions.broadcast(updateEvent, `${instance_id}:${player_data.surface}`); } catch (err) { this.logger.error(`Error processing player position data: ${err}`); diff --git a/plugins/minimap/web/CanvasMinimapPage.tsx b/plugins/minimap/web/CanvasMinimapPage.tsx index 6a97977c..b07ca9c1 100644 --- a/plugins/minimap/web/CanvasMinimapPage.tsx +++ b/plugins/minimap/web/CanvasMinimapPage.tsx @@ -852,6 +852,13 @@ export default function CanvasMinimapPage() { loadSurfaceForceData(); }, []); + // Keep the minimap subscription filters in sync with current selection + useEffect(() => { + const plugin = control.plugins.get("minimap") as import("./index").WebPlugin; + if (!plugin) { return; } + plugin.setInstanceSurfaceFilter(selectedInstance, selectedSurface || null); + }, [control, selectedInstance, selectedSurface]); + // Set up keyboard and mouse event listeners (one-time setup) useEffect(() => { const isTypingInInput = (): boolean => { diff --git a/plugins/minimap/web/MinimapPage.tsx b/plugins/minimap/web/MinimapPage.tsx index b073b92b..31d7c20f 100644 --- a/plugins/minimap/web/MinimapPage.tsx +++ b/plugins/minimap/web/MinimapPage.tsx @@ -37,6 +37,13 @@ export default function MinimapPage() { loadSurfaceForceData(); }, []); + // Keep subscription filters in sync with selection even on the legacy page + useEffect(() => { + const plugin = control.plugins.get("minimap") as import("./index").WebPlugin; + if (!plugin) { return; } + plugin.setInstanceSurfaceFilter(selectedInstance, selectedSurface || null); + }, [control, selectedInstance, selectedSurface]); + const loadSurfaceForceData = async () => { const response = await fetch(`${window.location.origin}/api/minimap/surfaces`); const data = await response.json(); diff --git a/plugins/minimap/web/index.tsx b/plugins/minimap/web/index.tsx index 2f8c2315..25177a15 100644 --- a/plugins/minimap/web/index.tsx +++ b/plugins/minimap/web/index.tsx @@ -13,6 +13,7 @@ export class WebPlugin extends BaseWebPlugin { // Track subscription state private subscribed = false; + private currentFilters: string[] | undefined = undefined; async init() { this.pages = [ @@ -32,11 +33,45 @@ export class WebPlugin extends BaseWebPlugin { } onControllerConnectionEvent(event: "connect" | "drop" | "resume" | "close") { - if (event === "connect") { + if (event === "connect" || event === "resume") { this.updateSubscriptions(); } } + // Update instance/surface filter used for subscriptions. + async setInstanceSurfaceFilter(instanceId: number | null, surface: string | null) { + const newFilters = (instanceId !== null && surface) ? [`${instanceId}:${surface}`] : undefined; + + // No change + const prev = this.currentFilters; + const same = ( + (prev === undefined && newFilters === undefined) + || (Array.isArray(prev) && Array.isArray(newFilters) + && prev.length === newFilters.length + && prev.every((v, i) => v === newFilters[i])) + ); + if (same) { return; } + + // If we had previous filters and callbacks active, remove those filters first + if (this.hasActiveCallbacks() && prev && prev.length > 0) { + try { + await this.control.send(new lib.SubscriptionRequest("minimap:TileDataEvent", false, 0, prev)); + await this.control.send(new lib.SubscriptionRequest("minimap:ChartTagDataEvent", false, 0, prev)); + await this.control.send(new lib.SubscriptionRequest("minimap:RecipeDataEvent", false, 0, prev)); + await this.control.send(new lib.SubscriptionRequest("minimap:PlayerPositionEvent", false, 0, prev)); + } catch (err) { + this.logger.error(`Failed to remove previous minimap filters: ${err}`); + } + } + + this.currentFilters = newFilters; + + // Apply new filters if we have active callbacks + if (this.hasActiveCallbacks()) { + await this.updateSubscriptions(); + } + } + private async updateSubscriptions() { if (!this.control.connector.connected) { return; @@ -44,18 +79,20 @@ export class WebPlugin extends BaseWebPlugin { const shouldSubscribe = this.hasActiveCallbacks(); - if (shouldSubscribe && !this.subscribed) { - // Subscribe to all minimap events + // Only subscribe if we both have active callbacks and a specific filter set + if (shouldSubscribe && this.currentFilters && this.currentFilters.length > 0) { + // Always (re)send with current filters when we have active callbacks + const filters = this.currentFilters; try { - await this.control.send(new lib.SubscriptionRequest("minimap:TileDataEvent", true)); - await this.control.send(new lib.SubscriptionRequest("minimap:ChartTagDataEvent", true)); - await this.control.send(new lib.SubscriptionRequest("minimap:RecipeDataEvent", true)); - await this.control.send(new lib.SubscriptionRequest("minimap:PlayerPositionEvent", true)); + await this.control.send(new lib.SubscriptionRequest("minimap:TileDataEvent", true, 0, filters)); + await this.control.send(new lib.SubscriptionRequest("minimap:ChartTagDataEvent", true, 0, filters)); + await this.control.send(new lib.SubscriptionRequest("minimap:RecipeDataEvent", true, 0, filters)); + await this.control.send(new lib.SubscriptionRequest("minimap:PlayerPositionEvent", true, 0, filters)); this.subscribed = true; } catch (err) { this.logger.error(`Failed to subscribe to minimap events: ${err}`); } - } else if (!shouldSubscribe && this.subscribed) { + } else if ((!shouldSubscribe || !this.currentFilters || this.currentFilters.length === 0) && this.subscribed) { // Unsubscribe from all minimap events try { await this.control.send(new lib.SubscriptionRequest("minimap:TileDataEvent", false));