diff --git a/pom.xml b/pom.xml index 61ab76e..db8c035 100644 --- a/pom.xml +++ b/pom.xml @@ -15,8 +15,8 @@ 21 UTF-8 full - 2.0.2 - 2.0.1 + 2.16.0 + 2.3.0 diff --git a/src/main/java/net/tfminecraft/gathering/utils/CharacterBridge.java b/src/main/java/net/tfminecraft/gathering/utils/CharacterBridge.java index e0f7174..833866a 100644 --- a/src/main/java/net/tfminecraft/gathering/utils/CharacterBridge.java +++ b/src/main/java/net/tfminecraft/gathering/utils/CharacterBridge.java @@ -7,25 +7,23 @@ import net.tfminecraft.rpcharacters.managers.PlayerManager; import net.tfminecraft.rpcharacters.objects.PlayerData; import net.tfminecraft.rpcharacters.objects.RPCharacter; +import net.tfminecraft.tlibs.character.Characters; public final class CharacterBridge { private CharacterBridge() {} public static RPCharacter getActiveCharacter(Player player) { - if (player == null) return null; + UUID characterId = getActiveCharacterUuid(player); + if (characterId == null) return null; PlayerData pd = PlayerManager.get(player); - if (pd == null || !pd.hasActiveCharacter()) return null; - return pd.getActiveCharacter(); + RPCharacter character = pd == null ? null : pd.getActiveCharacter(); + return character != null && characterId.toString().equalsIgnoreCase(character.getId()) + ? character : null; } public static UUID getActiveCharacterUuid(Player player) { - RPCharacter character = getActiveCharacter(player); - if (character == null || character.getId() == null) return null; - try { - return UUID.fromString(character.getId()); - } catch (IllegalArgumentException ex) { - return null; - } + if (player == null) return null; + return Characters.currentSession(player).map(session -> session.ref().characterId()).orElse(null); } } diff --git a/src/test/java/net/tfminecraft/gathering/IntegrationTest.java b/src/test/java/net/tfminecraft/gathering/IntegrationTest.java index ba7410a..e4316d9 100644 --- a/src/test/java/net/tfminecraft/gathering/IntegrationTest.java +++ b/src/test/java/net/tfminecraft/gathering/IntegrationTest.java @@ -17,35 +17,103 @@ import net.tfminecraft.rpcharacters.objects.*; import net.tfminecraft.rpcharacters.objects.attributes.AttributeModifier; import net.tfminecraft.tlibs.TLibs; +import net.tfminecraft.tlibs.character.CharacterIdentity; +import net.tfminecraft.tlibs.character.CharacterRef; +import net.tfminecraft.tlibs.character.CharacterSession; import net.tfminecraft.tlibs.objects.api.ItemAPI; import org.bukkit.*; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.ServicePriority; import org.junit.jupiter.api.Test; import org.mockbukkit.mockbukkit.MockBukkit; import org.mockito.MockedStatic; class IntegrationTest extends GatheringTestSupport { @Test - void characterBridgeHandlesAbsentInactiveAndMalformedIdentities() { + void characterBridgeWaitsForAProviderAndReadySessionBeforeReadingRpcAttributes() { Player player = server.addPlayer(); try (MockedStatic players = mockStatic(PlayerManager.class)) { assertNull(CharacterBridge.getActiveCharacter(null)); + assertNull(CharacterBridge.getActiveCharacterUuid(null)); assertNull(CharacterBridge.getActiveCharacter(player)); assertNull(CharacterBridge.getActiveCharacterUuid(player)); + CharacterIdentity identity = mock(CharacterIdentity.class); + when(identity.currentSession(player)).thenReturn(Optional.empty()); + server.getServicesManager() + .register(CharacterIdentity.class, identity, plugin, ServicePriority.Normal); + assertNull(CharacterBridge.getActiveCharacter(player)); + assertNull(CharacterBridge.getActiveCharacterUuid(player)); + players.verifyNoInteractions(); + } + } + + @Test + void characterBridgeUsesSharedUuidAndOnlyReturnsTheMatchingRpcAttributeModel() { + Player player = server.addPlayer(); + UUID id = UUID.randomUUID(); + CharacterIdentity identity = mock(CharacterIdentity.class); + when(identity.currentSession(player)) + .thenReturn(Optional.of(new CharacterSession(new CharacterRef(player.getUniqueId(), id), 1))); + server.getServicesManager() + .register(CharacterIdentity.class, identity, plugin, ServicePriority.Normal); + try (MockedStatic players = mockStatic(PlayerManager.class)) { + assertEquals(id, CharacterBridge.getActiveCharacterUuid(player)); + players.verifyNoInteractions(); + assertNull(CharacterBridge.getActiveCharacter(player)); PlayerData data = mock(PlayerData.class); players.when(() -> PlayerManager.get(player)).thenReturn(data); assertNull(CharacterBridge.getActiveCharacter(player)); - when(data.hasActiveCharacter()).thenReturn(true); RPCharacter character = mock(RPCharacter.class); when(data.getActiveCharacter()).thenReturn(character); + assertNull(CharacterBridge.getActiveCharacter(player)); + assertEquals(id, CharacterBridge.getActiveCharacterUuid(player)); + when(character.getId()).thenReturn("invalid"); + assertNull(CharacterBridge.getActiveCharacter(player)); + assertEquals(id, CharacterBridge.getActiveCharacterUuid(player)); + when(character.getId()).thenReturn(UUID.randomUUID().toString()); + assertNull(CharacterBridge.getActiveCharacter(player)); + when(character.getId()).thenReturn(id.toString().toUpperCase(Locale.ROOT)); assertSame(character, CharacterBridge.getActiveCharacter(player)); + assertEquals(id, CharacterBridge.getActiveCharacterUuid(player)); + } + } + + @Test + void characterBridgeRechecksSessionsAndProviderRegistrationWithoutCachingOldIdentity() { + Player player = server.addPlayer(); + UUID aliceId = UUID.randomUUID(), bobId = UUID.randomUUID(); + CharacterIdentity identity = mock(CharacterIdentity.class); + server.getServicesManager() + .register(CharacterIdentity.class, identity, plugin, ServicePriority.Normal); + RPCharacter alice = mock(RPCharacter.class), bob = mock(RPCharacter.class); + when(alice.getId()).thenReturn(aliceId.toString()); + when(bob.getId()).thenReturn(bobId.toString()); + PlayerData data = mock(PlayerData.class); + when(data.getActiveCharacter()).thenReturn(alice); + try (MockedStatic players = mockStatic(PlayerManager.class)) { + players.when(() -> PlayerManager.get(player)).thenReturn(data); + when(identity.currentSession(player)) + .thenReturn(Optional.of(new CharacterSession(new CharacterRef(player.getUniqueId(), aliceId), 1))); + assertSame(alice, CharacterBridge.getActiveCharacter(player)); + when(identity.currentSession(player)) + .thenReturn(Optional.of(new CharacterSession(new CharacterRef(player.getUniqueId(), bobId), 2))); + assertEquals(bobId, CharacterBridge.getActiveCharacterUuid(player)); + assertNull(CharacterBridge.getActiveCharacter(player)); + when(data.getActiveCharacter()).thenReturn(bob); + assertSame(bob, CharacterBridge.getActiveCharacter(player)); + when(identity.currentSession(player)) + .thenReturn(Optional.of(new CharacterSession(new CharacterRef(player.getUniqueId(), aliceId), 3))); + assertEquals(aliceId, CharacterBridge.getActiveCharacterUuid(player)); + assertNull(CharacterBridge.getActiveCharacter(player)); + when(data.getActiveCharacter()).thenReturn(alice); + assertSame(alice, CharacterBridge.getActiveCharacter(player)); + when(identity.currentSession(player)).thenReturn(Optional.empty()); + assertNull(CharacterBridge.getActiveCharacter(player)); assertNull(CharacterBridge.getActiveCharacterUuid(player)); - when(character.getId()).thenReturn("invalid"); + server.getServicesManager().unregister(CharacterIdentity.class, identity); + assertNull(CharacterBridge.getActiveCharacter(player)); assertNull(CharacterBridge.getActiveCharacterUuid(player)); - UUID id = UUID.randomUUID(); - when(character.getId()).thenReturn(id.toString()); - assertEquals(id, CharacterBridge.getActiveCharacterUuid(player)); } }