mirror of
https://github.com/StarWishsama/Slimefun4.git
synced 2024-09-19 19:25:48 +00:00
Added AsyncProfileLoadEvent
This commit is contained in:
parent
f2a80fc04f
commit
17fd2ec570
@ -29,6 +29,7 @@
|
|||||||
#### Additions
|
#### Additions
|
||||||
* Added a new language: Bulgarian
|
* Added a new language: Bulgarian
|
||||||
* Added a new language: Hebrew
|
* Added a new language: Hebrew
|
||||||
|
* (API) Added AsyncProfileLoadEvent
|
||||||
|
|
||||||
#### Changes
|
#### Changes
|
||||||
* Massive performance improvements to holograms/armorstands
|
* Massive performance improvements to holograms/armorstands
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
package io.github.thebusybiscuit.slimefun4.api.events;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This {@link Event} is called when the {@link PlayerProfile} of a {@link Player}
|
||||||
|
* is loaded into memory.
|
||||||
|
* The {@link AsyncProfileLoadEvent} is called asynchronously and can be used to "inject"
|
||||||
|
* a custom {@link PlayerProfile} if necessary.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
*
|
||||||
|
* @see PlayerProfile
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class AsyncProfileLoadEvent extends Event {
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
|
||||||
|
private final UUID uniqueId;
|
||||||
|
private PlayerProfile profile;
|
||||||
|
|
||||||
|
public AsyncProfileLoadEvent(@Nonnull PlayerProfile profile) {
|
||||||
|
super(true);
|
||||||
|
|
||||||
|
Validate.notNull(profile, "The Profile cannot be null");
|
||||||
|
|
||||||
|
this.uniqueId = profile.getUUID();
|
||||||
|
this.profile = profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public UUID getPlayerUUID() {
|
||||||
|
return uniqueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public PlayerProfile getProfile() {
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method can be used to inject your custom {@link PlayerProfile} implementations.
|
||||||
|
* However, the passed {@link PlayerProfile} must have the same {@link UUID} as the original one!
|
||||||
|
*
|
||||||
|
* @param profile
|
||||||
|
* The {@link PlayerProfile}
|
||||||
|
*/
|
||||||
|
public void setProfile(@Nonnull PlayerProfile profile) {
|
||||||
|
Validate.notNull(profile, "The PlayerProfile cannot be null!");
|
||||||
|
Validate.isTrue(profile.getUUID().equals(uniqueId), "Cannot inject a PlayerProfile with a different UUID");
|
||||||
|
|
||||||
|
this.profile = profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return getHandlerList();
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.api.player;
|
package io.github.thebusybiscuit.slimefun4.api.player;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -33,6 +32,7 @@ import com.google.common.collect.ImmutableSet;
|
|||||||
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
|
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
|
||||||
import io.github.thebusybiscuit.cscorelib2.config.Config;
|
import io.github.thebusybiscuit.cscorelib2.config.Config;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.events.AsyncProfileLoadEvent;
|
||||||
import io.github.thebusybiscuit.slimefun4.api.gps.Waypoint;
|
import io.github.thebusybiscuit.slimefun4.api.gps.Waypoint;
|
||||||
import io.github.thebusybiscuit.slimefun4.api.items.HashedArmorpiece;
|
import io.github.thebusybiscuit.slimefun4.api.items.HashedArmorpiece;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType;
|
||||||
@ -56,7 +56,7 @@ import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
|
|||||||
* @see HashedArmorpiece
|
* @see HashedArmorpiece
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class PlayerProfile {
|
public class PlayerProfile {
|
||||||
|
|
||||||
private final UUID uuid;
|
private final UUID uuid;
|
||||||
private final String name;
|
private final String name;
|
||||||
@ -74,13 +74,17 @@ public final class PlayerProfile {
|
|||||||
|
|
||||||
private final HashedArmorpiece[] armor = { new HashedArmorpiece(), new HashedArmorpiece(), new HashedArmorpiece(), new HashedArmorpiece() };
|
private final HashedArmorpiece[] armor = { new HashedArmorpiece(), new HashedArmorpiece(), new HashedArmorpiece(), new HashedArmorpiece() };
|
||||||
|
|
||||||
private PlayerProfile(@Nonnull OfflinePlayer p) {
|
protected PlayerProfile(@Nonnull OfflinePlayer p) {
|
||||||
this.uuid = p.getUniqueId();
|
this.uuid = p.getUniqueId();
|
||||||
this.name = p.getName();
|
this.name = p.getName();
|
||||||
|
|
||||||
configFile = new Config(new File("data-storage/Slimefun/Players/" + uuid.toString() + ".yml"));
|
configFile = new Config("data-storage/Slimefun/Players/" + uuid.toString() + ".yml");
|
||||||
waypointsFile = new Config("data-storage/Slimefun/waypoints/" + uuid.toString() + ".yml");
|
waypointsFile = new Config("data-storage/Slimefun/waypoints/" + uuid.toString() + ".yml");
|
||||||
|
|
||||||
|
loadProfileData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadProfileData() {
|
||||||
for (Research research : SlimefunPlugin.getRegistry().getResearches()) {
|
for (Research research : SlimefunPlugin.getRegistry().getResearches()) {
|
||||||
if (configFile.contains("researches." + research.getID())) {
|
if (configFile.contains("researches." + research.getID())) {
|
||||||
researches.add(research);
|
researches.add(research);
|
||||||
@ -95,7 +99,7 @@ public final class PlayerProfile {
|
|||||||
waypoints.add(new Waypoint(this, key, loc, waypointName));
|
waypoints.add(new Waypoint(this, key, loc, waypointName));
|
||||||
}
|
}
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
SlimefunPlugin.logger().log(Level.WARNING, x, () -> "Could not load Waypoint \"" + key + "\" for Player \"" + p.getName() + '"');
|
SlimefunPlugin.logger().log(Level.WARNING, x, () -> "Could not load Waypoint \"" + key + "\" for Player \"" + name + '"');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -268,14 +272,14 @@ public final class PlayerProfile {
|
|||||||
* Call this method if the Player has left.
|
* Call this method if the Player has left.
|
||||||
* The profile can then be removed from RAM.
|
* The profile can then be removed from RAM.
|
||||||
*/
|
*/
|
||||||
public void markForDeletion() {
|
public final void markForDeletion() {
|
||||||
markedForDeletion = true;
|
markedForDeletion = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this method if this Profile has unsaved changes.
|
* Call this method if this Profile has unsaved changes.
|
||||||
*/
|
*/
|
||||||
public void markDirty() {
|
public final void markDirty() {
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,9 +386,11 @@ public final class PlayerProfile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(SlimefunPlugin.instance(), () -> {
|
Bukkit.getScheduler().runTaskAsynchronously(SlimefunPlugin.instance(), () -> {
|
||||||
PlayerProfile pp = new PlayerProfile(p);
|
AsyncProfileLoadEvent event = new AsyncProfileLoadEvent(new PlayerProfile(p));
|
||||||
SlimefunPlugin.getRegistry().getPlayerProfiles().put(uuid, pp);
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
callback.accept(pp);
|
|
||||||
|
SlimefunPlugin.getRegistry().getPlayerProfiles().put(uuid, event.getProfile());
|
||||||
|
callback.accept(event.getProfile());
|
||||||
});
|
});
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
package io.github.thebusybiscuit.slimefun4.testing.tests.profiles;
|
||||||
|
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
|
||||||
|
|
||||||
|
class MockProfile extends PlayerProfile {
|
||||||
|
|
||||||
|
MockProfile(OfflinePlayer p) {
|
||||||
|
super(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
package io.github.thebusybiscuit.slimefun4.testing.tests.profiles;
|
||||||
|
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import be.seeseemelk.mockbukkit.MockBukkit;
|
||||||
|
import be.seeseemelk.mockbukkit.ServerMock;
|
||||||
|
import be.seeseemelk.mockbukkit.entity.OfflinePlayerMock;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.events.AsyncProfileLoadEvent;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.testing.TestUtilities;
|
||||||
|
|
||||||
|
class TestAsyncProfileLoadEvent {
|
||||||
|
|
||||||
|
private static ServerMock server;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public static void load() {
|
||||||
|
server = MockBukkit.mock();
|
||||||
|
MockBukkit.load(SlimefunPlugin.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
public static void unload() {
|
||||||
|
MockBukkit.unmock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Test AsyncProfileLoadEvent being thrown")
|
||||||
|
void testEventFired() throws InterruptedException {
|
||||||
|
server.getPluginManager().clearEvents();
|
||||||
|
|
||||||
|
OfflinePlayer player = new OfflinePlayerMock("EventFire");
|
||||||
|
TestUtilities.awaitProfile(player);
|
||||||
|
|
||||||
|
server.getPluginManager().assertEventFired(AsyncProfileLoadEvent.class, Event::isAsynchronous);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Test AsyncProfileLoadEvent#getProfile()")
|
||||||
|
void testEventGetter() throws InterruptedException {
|
||||||
|
server.getPluginManager().clearEvents();
|
||||||
|
|
||||||
|
OfflinePlayer player = new OfflinePlayerMock("GetProfile");
|
||||||
|
PlayerProfile profile = TestUtilities.awaitProfile(player);
|
||||||
|
|
||||||
|
server.getPluginManager().assertEventFired(AsyncProfileLoadEvent.class, e -> e.getProfile().equals(profile));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Test Profile Injection")
|
||||||
|
void testProfileInjection() throws InterruptedException {
|
||||||
|
OfflinePlayer player = new OfflinePlayerMock("SomePlayer");
|
||||||
|
PlayerProfile profile = TestUtilities.awaitProfile(player);
|
||||||
|
PlayerProfile mockProfile = new MockProfile(player);
|
||||||
|
|
||||||
|
AsyncProfileLoadEvent event = new AsyncProfileLoadEvent(profile);
|
||||||
|
|
||||||
|
Assertions.assertEquals(player.getUniqueId(), event.getPlayerUUID());
|
||||||
|
Assertions.assertEquals(profile, event.getProfile());
|
||||||
|
Assertions.assertFalse(event.getProfile() instanceof MockProfile);
|
||||||
|
|
||||||
|
event.setProfile(mockProfile);
|
||||||
|
|
||||||
|
Assertions.assertEquals(mockProfile, event.getProfile());
|
||||||
|
Assertions.assertTrue(event.getProfile() instanceof MockProfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Test Profile Mismatch")
|
||||||
|
void testProfileMismatch() throws InterruptedException {
|
||||||
|
OfflinePlayer player = new OfflinePlayerMock("ValidProfile");
|
||||||
|
OfflinePlayer player2 = new OfflinePlayerMock("UnrelatedProfile");
|
||||||
|
|
||||||
|
PlayerProfile profile = TestUtilities.awaitProfile(player);
|
||||||
|
PlayerProfile profile2 = TestUtilities.awaitProfile(player2);
|
||||||
|
|
||||||
|
AsyncProfileLoadEvent event = new AsyncProfileLoadEvent(profile);
|
||||||
|
|
||||||
|
// Profile is null
|
||||||
|
Assertions.assertThrows(IllegalArgumentException.class, () -> event.setProfile(null));
|
||||||
|
|
||||||
|
// UUID mismatch
|
||||||
|
Assertions.assertThrows(IllegalArgumentException.class, () -> event.setProfile(profile2));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user