mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2024-11-25 13:57:59 +01:00
Implement server-side functionality for getting pony data from a texture
This commit is contained in:
parent
95b32fca23
commit
0e57e62f5a
5 changed files with 166 additions and 4 deletions
|
@ -7,6 +7,8 @@ import net.minecraft.util.Identifier;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.server.ServerPonyManager;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -71,6 +73,6 @@ public interface PonyManager {
|
|||
interface ForcedPony {}
|
||||
|
||||
final class Instance {
|
||||
public static PonyManager instance;
|
||||
public static PonyManager instance = new ServerPonyManager();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
package com.minelittlepony.api.pony;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.cache.*;
|
||||
import com.minelittlepony.server.MineLittlePonyServer;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.minecraft.MinecraftProfileTextures;
|
||||
|
||||
/**
|
||||
* Proxy handler for getting player skin data from HDSkins
|
||||
|
@ -18,6 +22,13 @@ public class SkinsProxy {
|
|||
public static SkinsProxy INSTANCE = new SkinsProxy();
|
||||
private static final SkinsProxy DEFAULT = INSTANCE;
|
||||
|
||||
private final LoadingCache<GameProfile, GameProfile> profileCache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(30, TimeUnit.SECONDS)
|
||||
.build(CacheLoader.from(profile -> {
|
||||
var result = MineLittlePonyServer.getServer().getSessionService().fetchProfile(profile.getId(), false);
|
||||
return result == null ? profile : result.profile();
|
||||
}));
|
||||
|
||||
public static SkinsProxy getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
@ -30,6 +41,16 @@ public class SkinsProxy {
|
|||
|
||||
@Nullable
|
||||
public Identifier getSkinTexture(GameProfile profile) {
|
||||
MinecraftServer server = MineLittlePonyServer.getServer();
|
||||
if (server != null) {
|
||||
profile = profileCache.getUnchecked(profile);
|
||||
|
||||
MinecraftProfileTextures textures = server.getSessionService().getTextures(profile);
|
||||
|
||||
if (textures != MinecraftProfileTextures.EMPTY) {
|
||||
return Identifier.of(textures.skin().getUrl());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
40
src/main/java/com/minelittlepony/api/pony/meta/Mats.java
Normal file
40
src/main/java/com/minelittlepony/api/pony/meta/Mats.java
Normal file
|
@ -0,0 +1,40 @@
|
|||
package com.minelittlepony.api.pony.meta;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.common.util.Color;
|
||||
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.Raster;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
|
||||
public interface Mats {
|
||||
static TriggerPixel.Mat createMat(MinecraftProfileTexture texture) throws IOException {
|
||||
return createMat(URI.create(texture.getUrl()).toURL());
|
||||
}
|
||||
|
||||
static TriggerPixel.Mat createMat(URL url) throws IOException {
|
||||
try {
|
||||
@Nullable
|
||||
BufferedImage image = ImageIO.read(url);
|
||||
if (image == null) {
|
||||
throw new IOException("Unable to read image from url " + url);
|
||||
}
|
||||
Raster raster = image.getData();
|
||||
return (x, y) -> {
|
||||
if (x < 0 || y < 0 || x > raster.getWidth() || y > raster.getHeight()) {
|
||||
return 0;
|
||||
}
|
||||
int[] color = raster.getPixel(x, y, new int[] {0, 0, 0, 0});
|
||||
return Color.argbToHex(color[3], color[0], color[1], color[2]);
|
||||
};
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new IOException("Could not create mat from image", e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +1,35 @@
|
|||
package com.minelittlepony.server;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.api.events.CommonChannel;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class MineLittlePonyServer implements ModInitializer {
|
||||
|
||||
private static WeakReference<MinecraftServer> server = new WeakReference<>(null);
|
||||
|
||||
public static Identifier id(String name) {
|
||||
return Identifier.of("minelittlepony", name);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static MinecraftServer getServer() {
|
||||
return server.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
CommonChannel.bootstrap();
|
||||
}
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTING.register(server -> {
|
||||
MineLittlePonyServer.server = new WeakReference<>(server);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
package com.minelittlepony.server;
|
||||
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.cache.*;
|
||||
import com.minelittlepony.api.pony.*;
|
||||
import com.minelittlepony.api.pony.meta.Mats;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ServerPonyManager implements PonyManager {
|
||||
static final Pony NULL_PONY = new Pony(Identifier.ofVanilla("null"), () -> Optional.of(PonyData.NULL));
|
||||
|
||||
private final LoadingCache<Identifier, Pony> poniesCache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(30, TimeUnit.SECONDS)
|
||||
.build(CacheLoader.from(resource -> {
|
||||
return new Pony(resource, load(consumer -> {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
consumer.accept(new PonyData(Mats.createMat(URI.create(resource.toString()).toURL()), false));
|
||||
} catch (IOException e) {
|
||||
consumer.accept(PonyData.NULL);
|
||||
}
|
||||
});
|
||||
}));
|
||||
}));
|
||||
|
||||
private static <T> Supplier<Optional<T>> load(Consumer<Consumer<T>> factory) {
|
||||
return new Supplier<Optional<T>>() {
|
||||
Optional<T> value = Optional.empty();
|
||||
boolean loadRequested;
|
||||
@Override
|
||||
public Optional<T> get() {
|
||||
synchronized (this) {
|
||||
if (!loadRequested) {
|
||||
loadRequested = true;
|
||||
factory.accept(value -> {
|
||||
this.value = Optional.ofNullable(value);
|
||||
});
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Pony> getPony(LivingEntity entity) {
|
||||
if (entity instanceof PlayerEntity player) {
|
||||
return Optional.ofNullable(getPony(player));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pony getBackgroundPony(UUID uuid) {
|
||||
return NULL_PONY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pony getPony(PlayerEntity player) {
|
||||
return getPony(SkinsProxy.getInstance().getSkinTexture(player.getGameProfile()), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pony getPony(@Nullable Identifier resource, @Nullable UUID uuid) {
|
||||
if (resource != null && (resource.getNamespace().equals("http") || resource.getNamespace().equals("https"))) {
|
||||
return poniesCache.getUnchecked(resource);
|
||||
}
|
||||
return NULL_PONY;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue