mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 15:06:20 +00:00
fix(inventory): drop leaking badge pending-counter; trust server active set
sendActiveBadges incremented pendingUpdatesRef on every edit, and the BadgesEvent handler skipped applying the server's active badges while the counter was > 0, decrementing once per BadgesEvent. The assumption was "one BadgesEvent echo per SetActivatedBadges" — but the emulator's UserWearBadgeEvent answers with a UserBadgesComposer room broadcast, NOT a BadgesEvent, so nothing ever decrements the counter. It leaks upward with every toggle/reorder/swap and then silently drops legitimate later BadgesEvent updates (the server-authoritative active set never reapplies). Remove the counter and always apply the server's active badges on BadgesEvent (edits are already persisted server-side, so this is correct).
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { BadgeReceivedEvent, BadgesEvent, RequestBadgesComposer, SetActivatedBadgesComposer } from '@nitrots/nitro-renderer';
|
import { BadgeReceivedEvent, BadgesEvent, RequestBadgesComposer, SetActivatedBadgesComposer } from '@nitrots/nitro-renderer';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useBetween } from 'use-between';
|
import { useBetween } from 'use-between';
|
||||||
import { GetConfigurationValue, SendMessageComposer, UnseenItemCategory } from '../../api';
|
import { GetConfigurationValue, SendMessageComposer, UnseenItemCategory } from '../../api';
|
||||||
import { useMessageEvent } from '../events';
|
import { useMessageEvent } from '../events';
|
||||||
@@ -17,7 +17,6 @@ const useInventoryBadgesState = () =>
|
|||||||
const { isUnseen = null, resetCategory = null } = useInventoryUnseenTracker();
|
const { isUnseen = null, resetCategory = null } = useInventoryUnseenTracker();
|
||||||
|
|
||||||
const maxBadgeCount = GetConfigurationValue<number>('user.badges.max.slots', 5);
|
const maxBadgeCount = GetConfigurationValue<number>('user.badges.max.slots', 5);
|
||||||
const pendingUpdatesRef = useRef(0);
|
|
||||||
const isWearingBadge = (badgeCode: string) => activeBadgeCodes.some(code => code === badgeCode);
|
const isWearingBadge = (badgeCode: string) => activeBadgeCodes.some(code => code === badgeCode);
|
||||||
const canWearBadges = () => (activeBadgeCodes.filter(Boolean).length < maxBadgeCount);
|
const canWearBadges = () => (activeBadgeCodes.filter(Boolean).length < maxBadgeCount);
|
||||||
|
|
||||||
@@ -35,7 +34,6 @@ const useInventoryBadgesState = () =>
|
|||||||
|
|
||||||
const sendActiveBadges = (badges: (string | null)[]) =>
|
const sendActiveBadges = (badges: (string | null)[]) =>
|
||||||
{
|
{
|
||||||
pendingUpdatesRef.current++;
|
|
||||||
const composer = new SetActivatedBadgesComposer();
|
const composer = new SetActivatedBadgesComposer();
|
||||||
for(let i = 0; i < maxBadgeCount; i++) composer.addActivatedBadge(badges[i] ?? '');
|
for(let i = 0; i < maxBadgeCount; i++) composer.addActivatedBadge(badges[i] ?? '');
|
||||||
SendMessageComposer(composer);
|
SendMessageComposer(composer);
|
||||||
@@ -93,16 +91,14 @@ const useInventoryBadgesState = () =>
|
|||||||
return newValue;
|
return newValue;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Skip overwriting activeBadgeCodes if we have pending local changes
|
// The emulator answers SetActivatedBadges (UserWearBadgeEvent) with a
|
||||||
if(pendingUpdatesRef.current > 0)
|
// UserBadgesComposer room broadcast, NOT a BadgesEvent — so there is no
|
||||||
{
|
// echo to suppress and the old pendingUpdatesRef counter only ever
|
||||||
pendingUpdatesRef.current--;
|
// leaked (incremented on every edit, never decremented), which then
|
||||||
}
|
// silently dropped legitimate later BadgesEvent updates. The server is
|
||||||
else
|
// authoritative here (edits are already persisted), so always apply it.
|
||||||
{
|
const serverBadges = parser.getActiveBadgeCodes();
|
||||||
const serverBadges = parser.getActiveBadgeCodes();
|
setActiveBadgeCodes(toFixedSlots(serverBadges));
|
||||||
setActiveBadgeCodes(toFixedSlots(serverBadges));
|
|
||||||
}
|
|
||||||
|
|
||||||
setBadgeCodes(allBadgeCodes);
|
setBadgeCodes(allBadgeCodes);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user