From 1ebe37e5a3460ffa230eb19c5225e42672accea6 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 17 Jun 2017 17:15:25 -0400 Subject: [PATCH] Profile Lookup Events Adds a Pre Lookup Event and a Post Lookup Event so that plugins may prefill in profile data, and cache the responses from profiles that had to be looked up. --- ... 0058-Shoulder-Entities-Release-API.patch} | 2 +- .../0059-Profile-Lookup-Events.patch | 237 ++++++++++++++++++ .../0218-Add-UnknownCommandEvent.patch | 5 +- ... 0219-Shoulder-Entities-Release-API.patch} | 6 +- .../0220-Profile-Lookup-Events.patch | 23 ++ 5 files changed, 267 insertions(+), 6 deletions(-) rename Spigot-API-Patches/{0057-Shoulder-Entities-Release-API.patch => 0058-Shoulder-Entities-Release-API.patch} (95%) create mode 100644 Spigot-API-Patches/0059-Profile-Lookup-Events.patch rename Spigot-Server-Patches/{0218-Shoulder-Entities-Release-API.patch => 0219-Shoulder-Entities-Release-API.patch} (95%) create mode 100644 Spigot-Server-Patches/0220-Profile-Lookup-Events.patch diff --git a/Spigot-API-Patches/0057-Shoulder-Entities-Release-API.patch b/Spigot-API-Patches/0058-Shoulder-Entities-Release-API.patch similarity index 95% rename from Spigot-API-Patches/0057-Shoulder-Entities-Release-API.patch rename to Spigot-API-Patches/0058-Shoulder-Entities-Release-API.patch index 9842dbf3b..55f5ba6d9 100644 --- a/Spigot-API-Patches/0057-Shoulder-Entities-Release-API.patch +++ b/Spigot-API-Patches/0058-Shoulder-Entities-Release-API.patch @@ -1,4 +1,4 @@ -From 0f4372eeeb3c321f531296efa2fd42ca7cde3205 Mon Sep 17 00:00:00 2001 +From 6404a253627d07f4b1bb7be54371e459c6c8ad64 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 17 Jun 2017 15:04:51 -0400 Subject: [PATCH] Shoulder Entities Release API diff --git a/Spigot-API-Patches/0059-Profile-Lookup-Events.patch b/Spigot-API-Patches/0059-Profile-Lookup-Events.patch new file mode 100644 index 000000000..58a393587 --- /dev/null +++ b/Spigot-API-Patches/0059-Profile-Lookup-Events.patch @@ -0,0 +1,237 @@ +From e9962451b7d9b18132004f808364cb76fc3fe0cb Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sat, 17 Jun 2017 16:30:44 -0400 +Subject: [PATCH] Profile Lookup Events + +Adds a Pre Lookup Event and a Post Lookup Event so that plugins may prefill in profile data, and cache the responses from +profiles that had to be looked up. + +diff --git a/pom.xml b/pom.xml +index 862910e0..c2922a7b 100644 +--- a/pom.xml ++++ b/pom.xml +@@ -60,6 +60,13 @@ + + provided + ++ ++ ++ com.mojang ++ authlib ++ 1.5.25 ++ compile ++ + + co.aikar + fastutil-lite +diff --git a/src/main/java/com/destroystokyo/paper/event/profile/LookupProfileEvent.java b/src/main/java/com/destroystokyo/paper/event/profile/LookupProfileEvent.java +new file mode 100644 +index 00000000..b46a1878 +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/event/profile/LookupProfileEvent.java +@@ -0,0 +1,44 @@ ++package com.destroystokyo.paper.event.profile; ++ ++import com.mojang.authlib.GameProfile; ++import org.bukkit.Bukkit; ++import org.bukkit.event.Event; ++import org.bukkit.event.HandlerList; ++ ++import javax.annotation.Nonnull; ++ ++/** ++ * Allows a plugin to be notified anytime AFTER a Profile has been looked up from the Mojang API ++ * ++ * This is an opportunity to view the response and potentially cache things. ++ * ++ * No guarantees are made about thread execution context for this event. If you need to know, check ++ * event.isAsync() ++ */ ++public class LookupProfileEvent extends Event { ++ ++ private static final HandlerList handlers = new HandlerList(); ++ ++ private final GameProfile profile; ++ ++ public LookupProfileEvent(@Nonnull GameProfile profile) { ++ super(!Bukkit.isPrimaryThread()); ++ this.profile = profile; ++ } ++ ++ /** ++ * The profile that was recently looked up. This profile can be mutated ++ */ ++ @Nonnull ++ public GameProfile getProfile() { ++ return profile; ++ } ++ ++ public HandlerList getHandlers() { ++ return handlers; ++ } ++ ++ public static HandlerList getHandlerList() { ++ return handlers; ++ } ++} +diff --git a/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java b/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java +new file mode 100644 +index 00000000..16f43b0f +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java +@@ -0,0 +1,152 @@ ++package com.destroystokyo.paper.event.profile; ++ ++import com.google.common.collect.Multimap; ++import com.google.common.collect.Sets; ++import com.mojang.authlib.GameProfile; ++import com.mojang.authlib.GameProfileRepository; ++import com.mojang.authlib.ProfileLookupCallback; ++import com.mojang.authlib.properties.Property; ++import com.mojang.authlib.properties.PropertyMap; ++import org.bukkit.Bukkit; ++import org.bukkit.event.Event; ++import org.bukkit.event.HandlerList; ++ ++import javax.annotation.Nonnull; ++import javax.annotation.Nullable; ++import java.util.Set; ++import java.util.UUID; ++ ++/** ++ * Allows a plugin to intercept a Profile Lookup for a Profile by name ++ * ++ * At the point of event fire, the UUID and properties are unset. ++ * ++ * If a plugin sets the UUID, and optionally the properties, the API call to look up the profile may be skipped. ++ * ++ * No guarantees are made about thread execution context for this event. If you need to know, check ++ * event.isAsync() ++ */ ++public class PreLookupProfileEvent extends Event { ++ ++ private static final HandlerList handlers = new HandlerList(); ++ ++ private final String name; ++ ++ private UUID uuid; ++ private PropertyMap properties = new PropertyMap(); ++ ++ public PreLookupProfileEvent(@Nonnull String name) { ++ super(!Bukkit.isPrimaryThread()); ++ this.name = name; ++ } ++ ++ /** ++ * Name of the player to look up a profile for ++ * @return ++ */ ++ @Nonnull ++ public String getName() { ++ return name; ++ } ++ ++ /** ++ * The UUID of the profile if it has already been provided by a plugin ++ * ++ * If this value is left null by the completion of the event call, then the server will ++ * trigger a call to the Mojang API to look up the UUID (Network Request), and subsequently, fire a ++ * {@link LookupProfileEvent} ++ */ ++ @Nullable ++ public UUID getUUID() { ++ return uuid; ++ } ++ ++ /** ++ * Sets the UUID for this player name. This will skip the initial API call to find the players UUID. ++ * ++ * However, if Profile Properties are needed by the server, you must also set them or else an API call will still be made. ++ */ ++ public void setUUID(@Nullable UUID uuid) { ++ this.uuid = uuid; ++ } ++ ++ /** ++ * Get the properties for this profile ++ */ ++ @Nonnull ++ public Multimap getProperties() { ++ return properties; ++ } ++ ++ /** ++ * Completely replaces all Properties with the new provided properties ++ * @param properties ++ */ ++ public void setProperties(Multimap properties) { ++ this.properties = new PropertyMap(); ++ this.properties.putAll(properties); ++ } ++ ++ /** ++ * Adds additional properties, without removing the original properties ++ * @param properties ++ */ ++ public void addProperties(Multimap properties) { ++ this.properties.putAll(properties); ++ } ++ ++ public HandlerList getHandlers() { ++ return handlers; ++ } ++ ++ public static HandlerList getHandlerList() { ++ return handlers; ++ } ++ ++ /** ++ * Wraps the Profile Repository so we can intercept all lookups ++ */ ++ public static GameProfileRepository wrapProfileRepository(final GameProfileRepository orig) { ++ return (names, agent, callback) -> { ++ Set unfoundNames = Sets.newHashSet(); ++ for (String name : names) { ++ PreLookupProfileEvent event = new PreLookupProfileEvent(name); ++ event.callEvent(); ++ if (event.getUUID() != null) { ++ // Plugin provided UUI, we can skip network call. ++ GameProfile gameprofile = new GameProfile(event.getUUID(), name); ++ // We might even have properties! ++ gameprofile.getProperties().putAll(event.getProperties()); ++ callback.onProfileLookupSucceeded(gameprofile); ++ } else { ++ unfoundNames.add(name); ++ } ++ } ++ ++ // Some things were not found.... Proceed to look up. ++ if (!unfoundNames.isEmpty() && orig != null) { ++ String[] namesArr = unfoundNames.toArray(new String[unfoundNames.size()]); ++ orig.findProfilesByNames(namesArr, agent, new PreProfileLookupCallback(callback)); ++ } ++ }; ++ } ++ ++ private static class PreProfileLookupCallback implements ProfileLookupCallback { ++ private final ProfileLookupCallback callback; ++ ++ PreProfileLookupCallback(ProfileLookupCallback callback) { ++ this.callback = callback; ++ } ++ ++ @Override ++ public void onProfileLookupSucceeded(GameProfile gameProfile) { ++ new LookupProfileEvent(gameProfile).callEvent(); ++ callback.onProfileLookupSucceeded(gameProfile); ++ } ++ ++ @Override ++ public void onProfileLookupFailed(GameProfile gameProfile, Exception e) { ++ callback.onProfileLookupFailed(gameProfile, e); ++ } ++ } ++} +-- +2.13.0 + diff --git a/Spigot-Server-Patches/0218-Add-UnknownCommandEvent.patch b/Spigot-Server-Patches/0218-Add-UnknownCommandEvent.patch index 15c8f2648..6afa438e5 100644 --- a/Spigot-Server-Patches/0218-Add-UnknownCommandEvent.patch +++ b/Spigot-Server-Patches/0218-Add-UnknownCommandEvent.patch @@ -1,4 +1,4 @@ -From 32caa989fcdb514b6a23096fc52a6a45b3b126d6 Mon Sep 17 00:00:00 2001 +From b49e6ad34f34bbf18fb376323760bfa955275aa5 Mon Sep 17 00:00:00 2001 From: Sweepyoface Date: Sat, 17 Jun 2017 18:48:21 -0400 Subject: [PATCH] Add UnknownCommandEvent @@ -32,4 +32,5 @@ index df6a75b05..2a5107f66 100644 // Spigot end -- -2.13.1 +2.13.0 + diff --git a/Spigot-Server-Patches/0218-Shoulder-Entities-Release-API.patch b/Spigot-Server-Patches/0219-Shoulder-Entities-Release-API.patch similarity index 95% rename from Spigot-Server-Patches/0218-Shoulder-Entities-Release-API.patch rename to Spigot-Server-Patches/0219-Shoulder-Entities-Release-API.patch index eb6f8299a..7f2f0f347 100644 --- a/Spigot-Server-Patches/0218-Shoulder-Entities-Release-API.patch +++ b/Spigot-Server-Patches/0219-Shoulder-Entities-Release-API.patch @@ -1,11 +1,11 @@ -From a45a01185dfcb1c4c70a6d8428852ffa20673043 Mon Sep 17 00:00:00 2001 +From e30f915fc361a40fa46b2eee407144439076699d Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 17 Jun 2017 15:18:30 -0400 Subject: [PATCH] Shoulder Entities Release API diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java -index f5e25e63d..8f3cefaa8 100644 +index f5e25e63d..c74095554 100644 --- a/src/main/java/net/minecraft/server/EntityHuman.java +++ b/src/main/java/net/minecraft/server/EntityHuman.java @@ -1717,21 +1717,48 @@ public abstract class EntityHuman extends EntityLiving { @@ -35,7 +35,7 @@ index f5e25e63d..8f3cefaa8 100644 + private boolean spawnEntityFromShoulder(@Nullable NBTTagCompound nbttagcompound) { + return spawnEntityFromShoulder0(nbttagcompound) != null; + } -+ // Paper - Moved to new method that now returns entiy, and properly null checks ++ // Paper - Moved to new method that now returns entity, and properly null checks + private Entity spawnEntityFromShoulder0(@Nullable NBTTagCompound nbttagcompound) { // CraftBukkit void->boolean - Paper - return Entity + if (!this.world.isClientSide && nbttagcompound != null && !nbttagcompound.isEmpty()) { // Paper - null check Entity entity = EntityTypes.a(nbttagcompound, this.world); diff --git a/Spigot-Server-Patches/0220-Profile-Lookup-Events.patch b/Spigot-Server-Patches/0220-Profile-Lookup-Events.patch new file mode 100644 index 000000000..f105ed94b --- /dev/null +++ b/Spigot-Server-Patches/0220-Profile-Lookup-Events.patch @@ -0,0 +1,23 @@ +From 6bfc9bd9aa12221cd1fdfda4403d792d69373195 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sat, 17 Jun 2017 17:00:32 -0400 +Subject: [PATCH] Profile Lookup Events + +Adds a Pre Lookup Event and a Post Lookup Event so that plugins may prefill in profile data, and cache the responses from +profiles that had to be looked up. + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 8ca8fdceb..ab8703106 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -1018,6 +1018,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs + YggdrasilAuthenticationService yggdrasilauthenticationservice = new YggdrasilAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString()); + MinecraftSessionService minecraftsessionservice = yggdrasilauthenticationservice.createMinecraftSessionService(); + GameProfileRepository gameprofilerepository = yggdrasilauthenticationservice.createProfileRepository(); ++ gameprofilerepository = com.destroystokyo.paper.event.profile.PreLookupProfileEvent.wrapProfileRepository(gameprofilerepository); // Paper + UserCache usercache = new UserCache(gameprofilerepository, new File(s1, MinecraftServer.a.getName())); + final DedicatedServer dedicatedserver = new DedicatedServer(options, DataConverterRegistry.a(), yggdrasilauthenticationservice, minecraftsessionservice, gameprofilerepository, usercache); + +-- +2.13.0 +