Skip to content

Commit 7570466

Browse files
committed
[Update] Fix damage breakdown modal infinitely reloading in Monster UI & Misc
1 parent cf2ef7f commit 7570466

File tree

6 files changed

+86
-82
lines changed

6 files changed

+86
-82
lines changed

algo/packet.ts

Lines changed: 53 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,8 @@ const isUuidPlayer = (uuid: Long) => {
247247
};
248248

249249
const isUuidMonster = (uuid: Long) => {
250-
return (uuid.toBigInt() & 0xffffn) === 64n;
250+
const low = uuid.toBigInt() & 0xffffn;
251+
return low === 64n || low === 32832n;
251252
};
252253

253254
const doesStreamHaveIdentifier = (reader: BinaryReader) => {
@@ -310,6 +311,7 @@ class PacketProcessor {
310311

311312
let targetUuid = aoiSyncDelta.Uuid;
312313
if (!targetUuid) return;
314+
const tgtUuid = targetUuid.toString();
313315
const isTargetPlayer = isUuidPlayer(targetUuid);
314316
const isTargetMonster = isUuidMonster(targetUuid);
315317
targetUuid = targetUuid.shiftRight(16);
@@ -320,8 +322,8 @@ class PacketProcessor {
320322
this.#processPlayerAttrs(targetUuid.toNumber(), attrCollection.Attrs);
321323
this.#processPositionAttrs(targetUuid.toNumber(), 'player', attrCollection.Attrs);
322324
} else if (isTargetMonster) {
323-
this.#processEnemyAttrs(targetUuid.toNumber(), attrCollection.Attrs);
324-
this.#processPositionAttrs(targetUuid.toNumber(), 'monster', attrCollection.Attrs);
325+
this.#processEnemyAttrs(tgtUuid, targetUuid.toNumber(), attrCollection.Attrs);
326+
this.#processPositionAttrs(tgtUuid, 'monster', attrCollection.Attrs);
325327
}
326328
}
327329

@@ -338,6 +340,11 @@ class PacketProcessor {
338340
const isAttackerPlayer = isUuidPlayer(attackerUuid);
339341
attackerUuid = attackerUuid.shiftRight(16);
340342

343+
let damageTargetUuid = syncDamageInfo.TargetUuid || Long.fromString(tgtUuid);
344+
const tgtUuidStr = damageTargetUuid.toString();
345+
const isTargetPlayerDmg = isUuidPlayer(damageTargetUuid);
346+
damageTargetUuid = damageTargetUuid.shiftRight(16);
347+
341348
const value = syncDamageInfo.Value;
342349
const luckyValue = syncDamageInfo.LuckyValue;
343350
const damage = value ?? luckyValue ?? Long.ZERO;
@@ -358,7 +365,7 @@ class PacketProcessor {
358365
const damageElement = getDamageElement(syncDamageInfo.Property);
359366
const damageSource = syncDamageInfo.DamageSource ?? 0;
360367

361-
if (isTargetPlayer) {
368+
if (isTargetPlayerDmg) {
362369
//Player target
363370
//玩家目标
364371
if (isHeal) {
@@ -372,15 +379,15 @@ class PacketProcessor {
372379
isCrit,
373380
isLucky,
374381
isCauseLucky,
375-
targetUuid.toNumber(),
382+
damageTargetUuid.toNumber(),
376383
);
377384
} else {
378385
//Player received damage
379386
//玩家受到伤害
380-
this.userDataManager.addTakenDamage(targetUuid.toNumber(), damage.toNumber(), isDead);
387+
this.userDataManager.addTakenDamage(damageTargetUuid.toNumber(), damage.toNumber(), isDead);
381388
}
382389
if (isDead) {
383-
this.userDataManager.setAttrKV(targetUuid.toNumber(), 'hp', 0);
390+
this.userDataManager.setAttrKV(damageTargetUuid.toNumber(), 'hp', 0);
384391
}
385392
} else {
386393
//Non-player target
@@ -403,17 +410,15 @@ class PacketProcessor {
403410
isLucky,
404411
isCauseLucky,
405412
hpLessenValue.toNumber(),
406-
targetUuid.toNumber(),
413+
tgtUuidStr, // Use UUID string instead of number
407414
);
408415
}
409416

410417
if (isDead) {
411-
const enemyUid = targetUuid.toNumber();
412-
413-
if (!this.userDataManager.enemyCache.isDead.get(enemyUid)) {
414-
this.userDataManager.enemyCache.isDead.set(enemyUid, true);
415-
this.userDataManager.enemyCache.hp.set(enemyUid, 0);
416-
this.userDataManager.enemyCache.deathTime.set(enemyUid, Date.now());
418+
if (!this.userDataManager.enemyCache.isDead.get(tgtUuidStr)) {
419+
this.userDataManager.enemyCache.isDead.set(tgtUuidStr, true);
420+
this.userDataManager.enemyCache.hp.set(tgtUuidStr, 0);
421+
this.userDataManager.enemyCache.deathTime.set(tgtUuidStr, Date.now());
417422
}
418423
}
419424
}
@@ -636,7 +641,7 @@ class PacketProcessor {
636641
// this.logger.debug(syncContainerDirtyData.VData.Buffer.toString('hex'));
637642
}
638643

639-
#processPositionAttrs(targetUID: number, targetType: 'monster' | 'player', attrs: any[]) {
644+
#processPositionAttrs(targetID: number | string, targetType: 'monster' | 'player', attrs: any[]) {
640645
for (const attr of attrs) {
641646
if (!attr.Id || !attr.RawData) continue;
642647

@@ -650,8 +655,8 @@ class PacketProcessor {
650655
const z = position.Z ?? 0;
651656

652657
if (targetType === 'monster') {
653-
this.userDataManager.enemyCache.position.set(targetUID, { x, y, z });
654-
} else if (targetType === 'player' && targetUID === this.userDataManager.localPlayerUid) {
658+
this.userDataManager.enemyCache.position.set(targetID as string, { x, y, z });
659+
} else if (targetType === 'player' && targetID === this.userDataManager.localPlayerUid) {
655660
this.userDataManager.setLocalPlayerPosition({ x, y, z });
656661
}
657662
break;
@@ -725,80 +730,80 @@ class PacketProcessor {
725730
}
726731
}
727732

728-
#processEnemyAttrs(enemyUid: number, attrs: any[]) {
733+
#processEnemyAttrs(enemyUuid: string, enemyUid: number, attrs: any[]) {
729734
for (const attr of attrs) {
730735
if (!attr.Id || !attr.RawData) continue;
731736
const reader = pbjs.Reader.create(attr.RawData);
732737

733738
switch (attr.Id) {
734739
case AttrType.AttrName:
735740
const enemyName = reader.string();
736-
this.userDataManager.enemyCache.name.set(enemyUid, enemyName);
737-
this.userDataManager.enemyCache.lastSeen.set(enemyUid, Date.now());
738-
this.logger.debug(`Found monster name ${enemyName} for id ${enemyUid}`);
741+
this.userDataManager.enemyCache.name.set(enemyUuid, enemyName);
742+
this.userDataManager.enemyCache.lastSeen.set(enemyUuid, Date.now());
743+
this.logger.debug(`Found monster name ${enemyName} for id ${enemyUid} uuid ${enemyUuid}`);
739744
break;
740745
case AttrType.AttrId:
741746
const attrId = reader.int32();
742-
this.logger.debug(`Found monster attrId ${attrId} for id ${enemyUid}`);
743-
this.userDataManager.enemyCache.monsterId.set(enemyUid, attrId);
744-
this.userDataManager.enemyCache.lastSeen.set(enemyUid, Date.now());
747+
this.logger.debug(`Found monster attrId ${attrId} for id ${enemyUid} uuid ${enemyUuid}`);
748+
this.userDataManager.enemyCache.monsterId.set(enemyUuid, attrId);
749+
this.userDataManager.enemyCache.lastSeen.set(enemyUuid, Date.now());
745750

746751
const translatedName = monsterNames[String(attrId)];
747-
if (translatedName && !this.userDataManager.enemyCache.name.has(enemyUid)) {
748-
this.userDataManager.enemyCache.name.set(enemyUid, translatedName);
749-
this.logger.debug(`Set monster name from translation: ${translatedName} for id ${enemyUid}`);
752+
if (translatedName && !this.userDataManager.enemyCache.name.has(enemyUuid)) {
753+
this.userDataManager.enemyCache.name.set(enemyUuid, translatedName);
754+
this.logger.debug(`Set monster name from translation: ${translatedName} for id ${enemyUid} uuid ${enemyUuid}`);
750755
}
751756
break;
752757
case AttrType.AttrHp:
753758
const enemyHp = reader.int32();
754-
this.userDataManager.enemyCache.hp.set(enemyUid, enemyHp);
755-
this.userDataManager.enemyCache.lastSeen.set(enemyUid, Date.now());
756-
757-
if (enemyHp > 0 && this.userDataManager.enemyCache.isDead.get(enemyUid)) {
758-
this.userDataManager.enemyCache.isDead.delete(enemyUid);
759-
this.userDataManager.enemyCache.damageDealt.delete(enemyUid);
760-
this.userDataManager.enemyCache.firstHitTime.delete(enemyUid);
761-
this.userDataManager.enemyCache.deathTime.delete(enemyUid);
762-
this.userDataManager.enemyCache.playerDamage.delete(enemyUid);
759+
this.userDataManager.enemyCache.hp.set(enemyUuid, enemyHp);
760+
this.userDataManager.enemyCache.lastSeen.set(enemyUuid, Date.now());
761+
762+
if (enemyHp > 0 && this.userDataManager.enemyCache.isDead.get(enemyUuid)) {
763+
this.userDataManager.enemyCache.isDead.delete(enemyUuid);
764+
this.userDataManager.enemyCache.damageDealt.delete(enemyUuid);
765+
this.userDataManager.enemyCache.firstHitTime.delete(enemyUuid);
766+
this.userDataManager.enemyCache.deathTime.delete(enemyUuid);
767+
this.userDataManager.enemyCache.playerDamage.delete(enemyUuid);
763768
}
764769

765-
this.#reportBossHpThreshold(enemyUid, enemyHp);
770+
this.#reportBossHpThreshold(enemyUuid, enemyUid, enemyHp);
766771
break;
767772
case AttrType.AttrMaxHp:
768773
const enemyMaxHp = reader.int32();
769-
this.userDataManager.enemyCache.maxHp.set(enemyUid, enemyMaxHp);
770-
this.userDataManager.enemyCache.lastSeen.set(enemyUid, Date.now());
774+
this.userDataManager.enemyCache.maxHp.set(enemyUuid, enemyMaxHp);
775+
this.userDataManager.enemyCache.lastSeen.set(enemyUuid, Date.now());
771776
break;
772777
default:
773778
break;
774779
}
775780
}
776781
}
777782

778-
#reportBossHpThreshold(enemyUid: number, currentHp: number) {
783+
#reportBossHpThreshold(enemyUuid: string, enemyUid: number, currentHp: number) {
779784
try {
780785
// Check if BPTimer submission is enabled
781786
if (this.userDataManager.globalSettings?.enableBPTimerSubmission === false) {
782787
return;
783788
}
784789

785790
// Don't report if monster is already marked as dead
786-
if (this.userDataManager.enemyCache.isDead.get(enemyUid)) {
791+
if (this.userDataManager.enemyCache.isDead.get(enemyUuid)) {
787792
return;
788793
}
789794

790-
const monsterId = this.userDataManager.enemyCache.monsterId.get(enemyUid);
791-
const maxHp = this.userDataManager.enemyCache.maxHp.get(enemyUid);
795+
const monsterId = this.userDataManager.enemyCache.monsterId.get(enemyUuid);
796+
const maxHp = this.userDataManager.enemyCache.maxHp.get(enemyUuid);
792797

793798
if (!monsterId || !maxHp || maxHp === 0) {
794799
return;
795800
}
796801

797802
if (currentHp === 0 || currentHp <= maxHp * 0.001) {
798-
if (!this.userDataManager.enemyCache.isDead.get(enemyUid)) {
799-
this.userDataManager.enemyCache.deathTime.set(enemyUid, Date.now());
803+
if (!this.userDataManager.enemyCache.isDead.get(enemyUuid)) {
804+
this.userDataManager.enemyCache.deathTime.set(enemyUuid, Date.now());
800805
}
801-
this.userDataManager.enemyCache.isDead.set(enemyUid, true);
806+
this.userDataManager.enemyCache.isDead.set(enemyUuid, true);
802807
return;
803808
}
804809

@@ -832,13 +837,14 @@ class PacketProcessor {
832837
for (const entity of syncNearEntities.Appear) {
833838
const entityUuid = entity.Uuid;
834839
if (!entityUuid) continue;
840+
const entityUuidStr = entityUuid.toString(); // Store full UUID string before shifting
835841
const entityUid = entityUuid.shiftRight(16).toNumber();
836842
const attrCollection = entity.Attrs;
837843

838844
if (attrCollection && attrCollection.Attrs) {
839845
switch (entity.EntType) {
840846
case pb.EEntityType.EntMonster:
841-
this.#processEnemyAttrs(entityUid, attrCollection.Attrs);
847+
this.#processEnemyAttrs(entityUuidStr, entityUid, attrCollection.Attrs);
842848
break;
843849
case pb.EEntityType.EntChar:
844850
this.#processPlayerAttrs(entityUid, attrCollection.Attrs);

package-lock.json

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "bpsr-meter",
3-
"version": "0.4.1",
3+
"version": "0.4.2",
44
"description": "BPSR Meter",
55
"author": "Denoder",
66
"type": "module",

src/renderer/src/monsters/BossDamageBreakdown.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ export default function BossDamageBreakdown({
132132
};
133133

134134
fetchBreakdown();
135-
}, [monsterId, translateSkill]);
135+
}, [monsterId]);
136136

137137
const togglePlayer = (uid: number) => {
138138
setExpandedPlayers((prev) => {

src/server/api.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,7 @@ function initializeApi(
8585

8686
app.get("/api/monster-damage/:monsterId", (req: Request, res: Response) => {
8787
const { monsterId } = req.params;
88-
const breakdown = userDataManager.getMonsterDamageBreakdown(
89-
Number(monsterId),
90-
);
88+
const breakdown = userDataManager.getMonsterDamageBreakdown(monsterId);
9189
const data: ApiResponse = {
9290
code: 0,
9391
data: breakdown,

0 commit comments

Comments
 (0)