mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-31 00:20:44 +01:00
131 lines
9 KiB
Diff
131 lines
9 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
Date: Tue, 2 Jan 2018 00:31:26 -0500
|
|
Subject: [PATCH] Fill Profile Property Events
|
|
|
|
Allows plugins to populate profile properties from local sources to avoid calls out to Mojang API
|
|
to fill in textures for example.
|
|
|
|
If Mojang API does need to be hit, event fire so you can get the results.
|
|
|
|
This is useful for implementing a ProfileCache for Player Skulls
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/profile/PaperMinecraftSessionService.java b/src/main/java/com/destroystokyo/paper/profile/PaperMinecraftSessionService.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/com/destroystokyo/paper/profile/PaperMinecraftSessionService.java
|
|
+++ b/src/main/java/com/destroystokyo/paper/profile/PaperMinecraftSessionService.java
|
|
@@ -0,0 +0,0 @@
|
|
package com.destroystokyo.paper.profile;
|
|
|
|
import com.mojang.authlib.Environment;
|
|
+import com.mojang.authlib.GameProfile;
|
|
import com.mojang.authlib.yggdrasil.ProfileResult;
|
|
import com.mojang.authlib.yggdrasil.ServicesKeySet;
|
|
import com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService;
|
|
@@ -0,0 +0,0 @@ public class PaperMinecraftSessionService extends YggdrasilMinecraftSessionServi
|
|
super(servicesKeySet, proxy, environment);
|
|
}
|
|
|
|
- @Override
|
|
+ public @Nullable ProfileResult fetchProfile(GameProfile profile, final boolean requireSecure) {
|
|
+ CraftPlayerProfile playerProfile = (CraftPlayerProfile) CraftPlayerProfile.asBukkitMirror(profile);
|
|
+ new com.destroystokyo.paper.event.profile.PreFillProfileEvent(playerProfile).callEvent();
|
|
+ profile = playerProfile.getGameProfile();
|
|
+ if (profile.getProperties().containsKey("textures")) {
|
|
+ return new ProfileResult(profile, java.util.Collections.emptySet());
|
|
+ }
|
|
+ ProfileResult result = super.fetchProfile(profile.getId(), requireSecure);
|
|
+ if (result != null) {
|
|
+ new com.destroystokyo.paper.event.profile.FillProfileEvent(CraftPlayerProfile.asBukkitMirror(result.profile())).callEvent();
|
|
+ }
|
|
+ return result;
|
|
+ }
|
|
+
|
|
+ @Override @io.papermc.paper.annotation.DoNotUse @Deprecated
|
|
public @Nullable ProfileResult fetchProfile(final UUID profileId, final boolean requireSecure) {
|
|
return super.fetchProfile(profileId, requireSecure);
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/world/item/component/ResolvableProfile.java b/src/main/java/net/minecraft/world/item/component/ResolvableProfile.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/world/item/component/ResolvableProfile.java
|
|
+++ b/src/main/java/net/minecraft/world/item/component/ResolvableProfile.java
|
|
@@ -0,0 +0,0 @@ public record ResolvableProfile(Optional<String> name, Optional<UUID> id, Proper
|
|
if (this.isResolved()) {
|
|
return CompletableFuture.completedFuture(this);
|
|
} else {
|
|
- return this.id.isPresent() ? SkullBlockEntity.fetchGameProfile(this.id.get()).thenApply(optional -> {
|
|
+ return this.id.isPresent() ? SkullBlockEntity.fetchGameProfile(this.id.get(), this.name.orElse(null)).thenApply(optional -> { // Paper - player profile events
|
|
GameProfile gameProfile = optional.orElseGet(() -> new GameProfile(this.id.get(), this.name.orElse("")));
|
|
return new ResolvableProfile(gameProfile);
|
|
}) : SkullBlockEntity.fetchGameProfile(this.name.orElseThrow()).thenApply(profile -> {
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
|
@@ -0,0 +0,0 @@ public class SkullBlockEntity extends BlockEntity {
|
|
@Nullable
|
|
private static LoadingCache<String, CompletableFuture<Optional<GameProfile>>> profileCacheByName;
|
|
@Nullable
|
|
- private static LoadingCache<UUID, CompletableFuture<Optional<GameProfile>>> profileCacheById;
|
|
+ private static LoadingCache<com.mojang.datafixers.util.Pair<java.util.UUID, @org.jetbrains.annotations.Nullable GameProfile>, CompletableFuture<Optional<GameProfile>>> profileCacheById; // Paper - player profile events
|
|
public static final Executor CHECKED_MAIN_THREAD_EXECUTOR = runnable -> {
|
|
Executor executor = mainThreadExecutor;
|
|
if (executor != null) {
|
|
@@ -0,0 +0,0 @@ public class SkullBlockEntity extends BlockEntity {
|
|
profileCacheById = CacheBuilder.newBuilder()
|
|
.expireAfterAccess(Duration.ofMinutes(10L))
|
|
.maximumSize(256L)
|
|
- .build(new CacheLoader<UUID, CompletableFuture<Optional<GameProfile>>>() {
|
|
+ .build(new CacheLoader<>() { // Paper - player profile events
|
|
@Override
|
|
- public CompletableFuture<Optional<GameProfile>> load(UUID uUID) {
|
|
+ public CompletableFuture<Optional<GameProfile>> load(com.mojang.datafixers.util.Pair<java.util.UUID, @org.jetbrains.annotations.Nullable GameProfile> uUID) { // Paper - player profile events
|
|
return SkullBlockEntity.fetchProfileById(uUID, apiServices, booleanSupplier);
|
|
}
|
|
});
|
|
@@ -0,0 +0,0 @@ public class SkullBlockEntity extends BlockEntity {
|
|
.getAsync(name)
|
|
.thenCompose(
|
|
optional -> {
|
|
- LoadingCache<UUID, CompletableFuture<Optional<GameProfile>>> loadingCache = profileCacheById;
|
|
+ LoadingCache<com.mojang.datafixers.util.Pair<java.util.UUID, @org.jetbrains.annotations.Nullable GameProfile>, CompletableFuture<Optional<GameProfile>>> loadingCache = profileCacheById; // Paper - player profile events
|
|
return loadingCache != null && !optional.isEmpty()
|
|
- ? loadingCache.getUnchecked(optional.get().getId()).thenApply(optional2 -> optional2.or(() -> optional))
|
|
+ ? loadingCache.getUnchecked(new com.mojang.datafixers.util.Pair<>(optional.get().getId(), optional.get())).thenApply(optional2 -> optional2.or(() -> optional)) // Paper - player profile events
|
|
: CompletableFuture.completedFuture(Optional.empty());
|
|
}
|
|
);
|
|
}
|
|
|
|
- static CompletableFuture<Optional<GameProfile>> fetchProfileById(UUID uuid, Services apiServices, BooleanSupplier booleanSupplier) {
|
|
+ static CompletableFuture<Optional<GameProfile>> fetchProfileById(com.mojang.datafixers.util.Pair<java.util.UUID, @org.jetbrains.annotations.Nullable GameProfile> pair, Services apiServices, BooleanSupplier booleanSupplier) { // Paper
|
|
return CompletableFuture.supplyAsync(() -> {
|
|
if (booleanSupplier.getAsBoolean()) {
|
|
return Optional.empty();
|
|
} else {
|
|
- ProfileResult profileResult = apiServices.sessionService().fetchProfile(uuid, true);
|
|
+ // Paper start - fill player profile events
|
|
+ if (apiServices.sessionService() instanceof com.destroystokyo.paper.profile.PaperMinecraftSessionService paperService) {
|
|
+ final GameProfile profile = pair.getSecond() != null ? pair.getSecond() : new com.mojang.authlib.GameProfile(pair.getFirst(), "");
|
|
+ return Optional.ofNullable(paperService.fetchProfile(profile, true)).map(ProfileResult::profile);
|
|
+ }
|
|
+ ProfileResult profileResult = apiServices.sessionService().fetchProfile(pair.getFirst(), true);
|
|
+ // Paper end - fill player profile events
|
|
return Optional.ofNullable(profileResult).map(ProfileResult::profile);
|
|
}
|
|
}, Util.PROFILE_EXECUTOR); // Paper - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread
|
|
@@ -0,0 +0,0 @@ public class SkullBlockEntity extends BlockEntity {
|
|
: CompletableFuture.completedFuture(Optional.empty());
|
|
}
|
|
|
|
- public static CompletableFuture<Optional<GameProfile>> fetchGameProfile(UUID uuid) {
|
|
- LoadingCache<UUID, CompletableFuture<Optional<GameProfile>>> loadingCache = profileCacheById;
|
|
- return loadingCache != null ? loadingCache.getUnchecked(uuid) : CompletableFuture.completedFuture(Optional.empty());
|
|
+ // Paper start - player profile events
|
|
+ public static CompletableFuture<Optional<GameProfile>> fetchGameProfile(UUID uuid, @Nullable String name) {
|
|
+ LoadingCache<com.mojang.datafixers.util.Pair<java.util.UUID, @org.jetbrains.annotations.Nullable GameProfile>, CompletableFuture<Optional<GameProfile>>> loadingCache = profileCacheById;
|
|
+ return loadingCache != null ? loadingCache.getUnchecked(new com.mojang.datafixers.util.Pair<>(uuid, name != null ? new com.mojang.authlib.GameProfile(uuid, name) : null)) : CompletableFuture.completedFuture(Optional.empty());
|
|
+ // Paper end - player profile events
|
|
}
|
|
|
|
@Override
|