From f67097257b4328c04e553b4b651d6d637359e88e Mon Sep 17 00:00:00 2001 From: bbassie <17990055+bbassie@users.noreply.github.com> Date: Sat, 17 Oct 2026 15:32:20 +0000 Subject: [PATCH] Ignore player data responses for an earlier selection A request for one player could resolve after the drawer switched to another and show its inventory, and export it, under the wrong name. Co-Authored-By: Claude Opus 5.5 --- plugins/player_sync/web/index.tsx | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/plugins/player_sync/web/index.tsx b/plugins/player_sync/web/index.tsx index 1d14c190..49535e6a 100644 --- a/plugins/player_sync/web/index.tsx +++ b/plugins/player_sync/web/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useContext, useEffect, useState } from "react"; +import React, { useCallback, useContext, useEffect, useRef, useState } from "react"; import { Alert, Button, Descriptions, Drawer, Popconfirm, Space, Table, Typography, Upload } from "antd"; import * as lib from "@clusterio/lib"; @@ -89,17 +89,27 @@ function PlayerDrawer(props: { playerName?: string, onClose: () => void, onChang const instanceName = useInstanceName(); const [response, setResponse] = useState(); const { playerName } = props; + // Only the latest request may set the response, older ones may be for another player + const requestId = useRef(0); const reload = useCallback(() => { + requestId.current += 1; + let id = requestId.current; if (playerName === undefined) { - setResponse(undefined); return; } - control.send(new GetPlayerDataRequest(playerName)).then(setResponse).catch( + control.send(new GetPlayerDataRequest(playerName)).then(result => { + if (id === requestId.current) { + setResponse(result); + } + }).catch( notifyErrorHandler("Error loading player data") ); }, [control, playerName]); - useEffect(reload, [reload]); + useEffect(() => { + setResponse(undefined); + reload(); + }, [reload]); function changed() { reload();