fix/swarm-review-p0-p1-p2 #15
@@ -83,16 +83,16 @@ public class StruggleSessionManager {
|
|||||||
) {
|
) {
|
||||||
UUID playerId = player.getUUID();
|
UUID playerId = player.getUUID();
|
||||||
|
|
||||||
// Remove any existing continuous session
|
// RISK-002 fix: reject if active session exists (prevents direction re-roll exploit)
|
||||||
ContinuousStruggleMiniGameState existing = continuousSessions.get(
|
ContinuousStruggleMiniGameState existing = continuousSessions.get(
|
||||||
playerId
|
playerId
|
||||||
);
|
);
|
||||||
if (existing != null) {
|
if (existing != null) {
|
||||||
TiedUpMod.LOGGER.debug(
|
TiedUpMod.LOGGER.debug(
|
||||||
"[StruggleSessionManager] Replacing existing continuous struggle session for {}",
|
"[StruggleSessionManager] Rejected continuous session: active session already exists for {}",
|
||||||
player.getName().getString()
|
player.getName().getString()
|
||||||
);
|
);
|
||||||
continuousSessions.remove(playerId);
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new session with configurable rate
|
// Create new session with configurable rate
|
||||||
@@ -146,12 +146,16 @@ public class StruggleSessionManager {
|
|||||||
) {
|
) {
|
||||||
UUID playerId = player.getUUID();
|
UUID playerId = player.getUUID();
|
||||||
|
|
||||||
// Remove any existing session
|
// RISK-002 fix: reject if active session exists (prevents direction re-roll exploit)
|
||||||
ContinuousStruggleMiniGameState existing = continuousSessions.get(
|
ContinuousStruggleMiniGameState existing = continuousSessions.get(
|
||||||
playerId
|
playerId
|
||||||
);
|
);
|
||||||
if (existing != null) {
|
if (existing != null) {
|
||||||
continuousSessions.remove(playerId);
|
TiedUpMod.LOGGER.debug(
|
||||||
|
"[StruggleSessionManager] Rejected accessory session: active session already exists for {}",
|
||||||
|
player.getName().getString()
|
||||||
|
);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new session with target slot and configurable rate
|
// Create new session with target slot and configurable rate
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.tiedup.remake.v2.bondage;
|
package com.tiedup.remake.v2.bondage;
|
||||||
|
|
||||||
import com.tiedup.remake.core.TiedUpMod;
|
import com.tiedup.remake.core.TiedUpMod;
|
||||||
|
import com.tiedup.remake.items.base.ILockable;
|
||||||
import com.tiedup.remake.v2.BodyRegionV2;
|
import com.tiedup.remake.v2.BodyRegionV2;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
@@ -149,7 +150,14 @@ public final class V2EquipmentManager {
|
|||||||
return V2EquipResult.swapped(conflictStack);
|
return V2EquipResult.swapped(conflictStack);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Non-V2 item in region — log warning and remove
|
// Non-V2 item in region — RISK-003 fix: check if locked before removing
|
||||||
|
if (conflictStack.getItem() instanceof ILockable lockable && lockable.isLocked(conflictStack)) {
|
||||||
|
TiedUpMod.LOGGER.warn(
|
||||||
|
"V2EquipmentManager: blocked swap of locked non-V2 item {} from equipment",
|
||||||
|
conflictStack
|
||||||
|
);
|
||||||
|
return V2EquipResult.BLOCKED;
|
||||||
|
}
|
||||||
TiedUpMod.LOGGER.warn(
|
TiedUpMod.LOGGER.warn(
|
||||||
"V2EquipmentManager: swapping out non-V2 item {} from equipment",
|
"V2EquipmentManager: swapping out non-V2 item {} from equipment",
|
||||||
conflictStack
|
conflictStack
|
||||||
|
|||||||
@@ -41,9 +41,10 @@ public class PacketV2SelfLock {
|
|||||||
if (player == null) return;
|
if (player == null) return;
|
||||||
if (!PacketRateLimiter.allowPacket(player, "action")) return;
|
if (!PacketRateLimiter.allowPacket(player, "action")) return;
|
||||||
|
|
||||||
// Arms must be free to self-lock
|
// Arms and hands must be free to self-lock (RISK-006: mittens bypass)
|
||||||
if (
|
if (
|
||||||
V2EquipmentHelper.isRegionOccupied(player, BodyRegionV2.ARMS)
|
V2EquipmentHelper.isRegionOccupied(player, BodyRegionV2.ARMS) ||
|
||||||
|
V2EquipmentHelper.isRegionOccupied(player, BodyRegionV2.HANDS)
|
||||||
) return;
|
) return;
|
||||||
|
|
||||||
ItemStack equipped = V2EquipmentHelper.getInRegion(
|
ItemStack equipped = V2EquipmentHelper.getInRegion(
|
||||||
|
|||||||
@@ -42,9 +42,10 @@ public class PacketV2SelfUnlock {
|
|||||||
if (player == null) return;
|
if (player == null) return;
|
||||||
if (!PacketRateLimiter.allowPacket(player, "action")) return;
|
if (!PacketRateLimiter.allowPacket(player, "action")) return;
|
||||||
|
|
||||||
// Arms must be free to self-unlock
|
// Arms and hands must be free to self-unlock (RISK-006: mittens bypass)
|
||||||
if (
|
if (
|
||||||
V2EquipmentHelper.isRegionOccupied(player, BodyRegionV2.ARMS)
|
V2EquipmentHelper.isRegionOccupied(player, BodyRegionV2.ARMS) ||
|
||||||
|
V2EquipmentHelper.isRegionOccupied(player, BodyRegionV2.HANDS)
|
||||||
) return;
|
) return;
|
||||||
|
|
||||||
ItemStack equipped = V2EquipmentHelper.getInRegion(
|
ItemStack equipped = V2EquipmentHelper.getInRegion(
|
||||||
|
|||||||
Reference in New Issue
Block a user