Skip to content

Commit

Permalink
Refactor XSkull API
Browse files Browse the repository at this point in the history
- Fix `XSkull.TEXTURES` constant (old clients require the HTTP protocol to render properly).
- Add 1.8 remap for MinecraftServer getter.
- Deprecate `XSkull.applySkin` in favor of `XSkull#of`
- Remove cache for profiles generated from base64 (#254).
- Log exceptions using debug level.
  • Loading branch information
Condordito committed May 26, 2024
1 parent 14cece6 commit 715d905
Show file tree
Hide file tree
Showing 8 changed files with 307 additions and 293 deletions.
1 change: 1 addition & 0 deletions src/main/java/com/cryptomorin/xseries/XItemStack.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/
package com.cryptomorin.xseries;

import com.cryptomorin.xseries.skull.XSkull;
import com.google.common.base.Enums;
import com.google.common.base.Strings;
import com.google.common.collect.Multimap;
Expand Down
48 changes: 48 additions & 0 deletions src/main/java/com/cryptomorin/xseries/skull/Action.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.cryptomorin.xseries.skull;

import com.mojang.authlib.GameProfile;

import javax.annotation.Nonnull;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

public class Action<T> {
private static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(2, new ThreadFactory() {
private final AtomicInteger count = new AtomicInteger();
@Override
public Thread newThread(final @Nonnull Runnable run) {
final Thread thread = new Thread(run);
thread.setName("Profile Lookup Executor #" + this.count.getAndIncrement());
thread.setUncaughtExceptionHandler((t, throwable) ->
XSkull.LOGGER.debug("Uncaught exception in thread {}", t.getName(), throwable));
return thread;
}
});

private final Instruction<T> inputHandle;

protected Action(Instruction<T> handle) {
this.inputHandle = handle;
}

public T setter() {
return inputHandle.setter.setProfile(getter());
}

public GameProfile getter() {
return inputHandle.type == null
? XSkull.profileFromString(inputHandle.input)
: XSkull.profileFromValueType(inputHandle.type, inputHandle.input);
}

public CompletableFuture<T> asyncSetter() {
return CompletableFuture.supplyAsync(this::setter, EXECUTOR);
}

public CompletableFuture<GameProfile> asyncGetter() {
return CompletableFuture.supplyAsync(this::getter, EXECUTOR);
}
}
49 changes: 49 additions & 0 deletions src/main/java/com/cryptomorin/xseries/skull/Instruction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.cryptomorin.xseries.skull;

import java.util.UUID;

public class Instruction<T> {

protected String input;
protected ValueType type;
protected Setter<T> setter;

protected Instruction(Setter<T> setter) {
this.setter = setter;
}

public Action<T> from(String input) {
this.input = input;
return new Action<>(this);
}

public Action<T> fromUUID(UUID input) {
this.input = input.toString();
this.type = ValueType.UUID;
return new Action<>(this);
}

public Action<T> fromUsername(String input) {
this.input = input;
this.type = ValueType.USERNAME;
return new Action<>(this);
}

public Action<T> fromBase64(String input) {
this.input = input;
this.type = ValueType.BASE64;
return new Action<>(this);
}

public Action<T> fromURL(String input) {
this.input = input;
this.type = ValueType.TEXTURE_URL;
return new Action<>(this);
}

public Action<T> fromHash(String input) {
this.input = input;
this.type = ValueType.TEXTURE_HASH;
return new Action<>(this);
}
}
8 changes: 8 additions & 0 deletions src/main/java/com/cryptomorin/xseries/skull/Setter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.cryptomorin.xseries.skull;

import com.mojang.authlib.GameProfile;

@FunctionalInterface
public interface Setter<T> {
T setProfile(GameProfile profile);
}
28 changes: 28 additions & 0 deletions src/main/java/com/cryptomorin/xseries/skull/ValueType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.cryptomorin.xseries.skull;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.regex.Pattern;

public enum ValueType {

TEXTURE_HASH(Pattern.compile("[0-9a-z]{55,70}")),
TEXTURE_URL(Pattern.compile(Pattern.quote(XSkull.TEXTURES) + TEXTURE_HASH.pattern)),
BASE64(Pattern.compile("[-A-Za-z0-9+/]{100,}={0,3}")),
UUID(Pattern.compile("[A-F\\d]{8}-[A-F\\d]{4}-4[A-F\\d]{3}-([89AB])[A-F\\d]{3}-[A-F\\d]{12}", Pattern.CASE_INSENSITIVE)),
USERNAME(Pattern.compile("[A-Za-z0-9_]{1,16}"));

private final Pattern pattern;

ValueType(Pattern compile) {
this.pattern = compile;
}

@Nullable
public static ValueType get(@Nonnull String identifier) {
return Arrays.stream(ValueType.values())
.filter(value -> value.pattern.matcher(identifier).matches())
.findFirst().orElse(null);
}
}
Loading

0 comments on commit 715d905

Please sign in to comment.