mirror of
https://github.com/barkeser2002/CatServer.git
synced 2026-09-25 01:39:52 +03:00
217 lines
8.7 KiB
Diff
217 lines
8.7 KiB
Diff
--- ../src-base/minecraft/net/minecraft/tileentity/TileEntitySkull.java
|
|
+++ ../src-work/minecraft/net/minecraft/tileentity/TileEntitySkull.java
|
|
@@ -1,15 +1,32 @@
|
|
package net.minecraft.tileentity;
|
|
|
|
+import catserver.server.CatServer;
|
|
+import com.google.common.base.Predicate;
|
|
+import com.google.common.cache.CacheBuilder;
|
|
+import com.google.common.cache.CacheLoader;
|
|
+import com.google.common.cache.LoadingCache;
|
|
import com.google.common.collect.Iterables;
|
|
+import com.google.common.util.concurrent.Futures;
|
|
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
|
+import com.mojang.authlib.Agent;
|
|
import com.mojang.authlib.GameProfile;
|
|
+import com.mojang.authlib.ProfileLookupCallback;
|
|
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
|
import com.mojang.authlib.properties.Property;
|
|
import java.util.UUID;
|
|
+import java.util.concurrent.Callable;
|
|
+import java.util.concurrent.ExecutorService;
|
|
+import java.util.concurrent.Executors;
|
|
+import java.util.concurrent.Future;
|
|
+import java.util.concurrent.TimeUnit;
|
|
+
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.block.BlockSkull;
|
|
+import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.nbt.NBTUtil;
|
|
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
|
|
+import net.minecraft.server.MinecraftServer;
|
|
import net.minecraft.server.management.PlayerProfileCache;
|
|
import net.minecraft.util.EnumFacing;
|
|
import net.minecraft.util.ITickable;
|
|
@@ -22,13 +39,66 @@
|
|
public class TileEntitySkull extends TileEntity implements ITickable
|
|
{
|
|
private int skullType;
|
|
- private int skullRotation;
|
|
+ public int skullRotation;
|
|
private GameProfile playerProfile;
|
|
private int dragonAnimatedTicks;
|
|
private boolean dragonAnimated;
|
|
private static PlayerProfileCache profileCache;
|
|
private static MinecraftSessionService sessionService;
|
|
+ // Spigot start
|
|
+ public static final ExecutorService executor = Executors.newFixedThreadPool(3,
|
|
+ new ThreadFactoryBuilder()
|
|
+ .setNameFormat("Head Conversion Thread - %1$d")
|
|
+ .build()
|
|
+ );
|
|
+ public static final LoadingCache<String, GameProfile> skinCache = CacheBuilder.newBuilder()
|
|
+ .maximumSize( 5000 )
|
|
+ .expireAfterAccess( 60, TimeUnit.MINUTES )
|
|
+ .build( new CacheLoader<String, GameProfile>()
|
|
+ {
|
|
+ @Override
|
|
+ public GameProfile load(String key) throws Exception
|
|
+ {
|
|
+ final GameProfile[] profiles = new GameProfile[1];
|
|
+ ProfileLookupCallback gameProfileLookup = new ProfileLookupCallback() {
|
|
|
|
+ @Override
|
|
+ public void onProfileLookupSucceeded(GameProfile gp) {
|
|
+ profiles[0] = gp;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void onProfileLookupFailed(GameProfile gp, Exception excptn) {
|
|
+ profiles[0] = gp;
|
|
+ }
|
|
+ };
|
|
+
|
|
+ if (! CatServer.getConfig().disableUpdateGameProfile)
|
|
+ MinecraftServer.getServerInst().getGameProfileRepository().findProfilesByNames(new String[] { key }, Agent.MINECRAFT, gameProfileLookup);
|
|
+
|
|
+ GameProfile profile = profiles[ 0 ];
|
|
+ if (profile == null) {
|
|
+ UUID uuid = EntityPlayer.getUUID(new GameProfile(null, key));
|
|
+ profile = new GameProfile(uuid, key);
|
|
+
|
|
+ gameProfileLookup.onProfileLookupSucceeded(profile);
|
|
+ } else
|
|
+ {
|
|
+
|
|
+ Property property = Iterables.getFirst( profile.getProperties().get( "textures" ), null );
|
|
+
|
|
+ if ( property == null )
|
|
+ {
|
|
+ profile = MinecraftServer.getServerInst().getMinecraftSessionService().fillProfileProperties( profile, true );
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
+ return profile;
|
|
+ }
|
|
+ } );
|
|
+ // Spigot end
|
|
+
|
|
public static void setProfileCache(PlayerProfileCache profileCacheIn)
|
|
{
|
|
profileCache = profileCacheIn;
|
|
@@ -134,49 +204,90 @@
|
|
|
|
private void updatePlayerProfile()
|
|
{
|
|
- this.playerProfile = updateGameprofile(this.playerProfile);
|
|
- this.markDirty();
|
|
+ // Spigot start
|
|
+ GameProfile profile = this.playerProfile;
|
|
+ setType( 0 ); // Work around client bug
|
|
+ updateGameprofile(profile, new Predicate<GameProfile>() {
|
|
+
|
|
+ @Override
|
|
+ public boolean apply(GameProfile input) {
|
|
+ setType(3); // Work around client bug
|
|
+ playerProfile = input;
|
|
+ markDirty();
|
|
+ if (world != null) {
|
|
+ world.notifyLightSet(pos); // PAIL: notify
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+ }, false);
|
|
+ // Spigot end
|
|
+
|
|
}
|
|
|
|
- public static GameProfile updateGameprofile(GameProfile input)
|
|
+ // Spigot start - Support async lookups
|
|
+ public static Future<GameProfile> updateGameprofile(final GameProfile input, final Predicate<GameProfile> callback, boolean sync)
|
|
{
|
|
if (input != null && !StringUtils.isNullOrEmpty(input.getName()))
|
|
{
|
|
if (input.isComplete() && input.getProperties().containsKey("textures"))
|
|
{
|
|
- return input;
|
|
- }
|
|
- else if (profileCache != null && sessionService != null)
|
|
- {
|
|
- GameProfile gameprofile = profileCache.getGameProfileForUsername(input.getName());
|
|
+ callback.apply(input);
|
|
+ } else if (MinecraftServer.getServerInst() == null) {
|
|
+ callback.apply(input);
|
|
+ } else {
|
|
+ GameProfile profile = skinCache.getIfPresent(input.getName().toLowerCase(java.util.Locale.ROOT));
|
|
+ if (profile != null && Iterables.getFirst(profile.getProperties().get("textures"), (Object) null) != null) {
|
|
+ callback.apply(profile);
|
|
|
|
- if (gameprofile == null)
|
|
- {
|
|
- return input;
|
|
+ return Futures.immediateFuture(profile);
|
|
}
|
|
else
|
|
{
|
|
- Property property = (Property)Iterables.getFirst(gameprofile.getProperties().get("textures"), (Object)null);
|
|
-
|
|
- if (property == null)
|
|
- {
|
|
- gameprofile = sessionService.fillProfileProperties(gameprofile, true);
|
|
+ Callable<GameProfile> callable = new Callable<GameProfile>() {
|
|
+ @Override
|
|
+ public GameProfile call() {
|
|
+ final GameProfile profile = skinCache.getUnchecked(input.getName().toLowerCase(java.util.Locale.ROOT));
|
|
+ MinecraftServer.getServerInst().processQueue.add(new Runnable() {
|
|
+ @Override
|
|
+ public void run() {
|
|
+ if (profile == null) {
|
|
+ callback.apply(input);
|
|
+ } else {
|
|
+ callback.apply(profile);
|
|
+ }
|
|
+ }
|
|
+ });
|
|
+ return profile;
|
|
+ }
|
|
+ };
|
|
+ if (sync) {
|
|
+ try {
|
|
+ return Futures.immediateFuture(callable.call());
|
|
+ } catch (Exception ex) {
|
|
+ com.google.common.base.Throwables.throwIfUnchecked(ex);
|
|
+ throw new RuntimeException(ex); // Not possible
|
|
+ }
|
|
+ } else {
|
|
+ return executor.submit(callable);
|
|
}
|
|
|
|
- return gameprofile;
|
|
}
|
|
}
|
|
- else
|
|
- {
|
|
- return input;
|
|
- }
|
|
}
|
|
else
|
|
{
|
|
- return input;
|
|
+ callback.apply(input);
|
|
}
|
|
+
|
|
+ return Futures.immediateFuture(input);
|
|
}
|
|
+ // Spigot end
|
|
|
|
+ public static GameProfile updateGameprofile(GameProfile input)
|
|
+ {
|
|
+ return com.google.common.util.concurrent.Futures.getUnchecked(updateGameprofile(input, com.google.common.base.Predicates.alwaysTrue(), true)); // CatServer
|
|
+ }
|
|
+
|
|
public int getSkullType()
|
|
{
|
|
return this.skullType;
|