Add optional api getter to avoid NullPointer on metadata
This commit is contained in:
parent
3721878d4a
commit
f7b5bd6246
15 changed files with 502 additions and 39 deletions
|
@ -4,5 +4,5 @@
|
|||
<component name="FrameworkDetectionExcludesConfiguration">
|
||||
<file type="web" url="file://$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="corretto-17" project-jdk-type="JavaSDK" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="corretto-17" project-jdk-type="JavaSDK" />
|
||||
</project>
|
|
@ -4,7 +4,22 @@
|
|||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="9d5d9b6f-43c8-41a4-bb42-a66ffc96c9b0" name="Changes" comment="" />
|
||||
<list default="true" id="9d5d9b6f-43c8-41a4-bb42-a66ffc96c9b0" name="Changes" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/extras/MojangApiError.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/extras/skin/CSFBImpl.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/extras/skin/CachedSkinFetcherBuilder.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/extras/skin/CachedSkinFetcherImpl.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/extras/skin/ErroredTextureProperties.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/extras/skin/SFBImpl.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/extras/skin/SFUtils.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/extras/skin/SkinFetcher.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/extras/skin/SkinFetcherBuilder.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/extras/skin/SkinFetcherImpl.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/EntityLib.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/EntityLib.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestPlayerCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestPlayerCommand.java" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
|
@ -34,17 +49,6 @@
|
|||
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
|
||||
<item name="EntityLib" type="f1a62948:ProjectNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
|
||||
<item name="EntityLib" type="f1a62948:ProjectNode" />
|
||||
<item name="Tasks" type="e4a08cd1:TasksNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
|
||||
<item name="EntityLib" type="f1a62948:ProjectNode" />
|
||||
<item name="Tasks" type="e4a08cd1:TasksNode" />
|
||||
<item name="publishing" type="c8890929:TasksNode$1" />
|
||||
</path>
|
||||
</expand>
|
||||
<select />
|
||||
</tree_state>
|
||||
|
@ -64,16 +68,9 @@
|
|||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="HighlightingSettingsPerFile">
|
||||
<setting file="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.retrooper.packetevents/api/2.2.1/5aea4193d2dadf2f99523ded56a910c4dd98d23f/api-2.2.1-default.jar!/com/github/retrooper/packetevents/protocol/entity/pose/EntityPose.class" root0="SKIP_INSPECTION" />
|
||||
<setting file="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.retrooper.packetevents/api/2.2.1/5aea4193d2dadf2f99523ded56a910c4dd98d23f/api-2.2.1-default.jar!/com/github/retrooper/packetevents/wrapper/play/server/WrapperPlayServerEntityAnimation.class" root0="SKIP_INSPECTION" />
|
||||
<setting file="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.retrooper.packetevents/api/2.2.1/5aea4193d2dadf2f99523ded56a910c4dd98d23f/api-2.2.1-default.jar!/com/github/retrooper/packetevents/wrapper/play/server/WrapperPlayServerSystemChatMessage.class" root0="SKIP_INSPECTION" />
|
||||
<setting file="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.retrooper.packetevents/api/2.2.1/5aea4193d2dadf2f99523ded56a910c4dd98d23f/api-2.2.1-default.jar!/com/github/retrooper/packetevents/wrapper/play/server/WrapperPlayServerTeams.class" root0="SKIP_INSPECTION" />
|
||||
<setting file="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.retrooper.packetevents/spigot/2.0.2/e1b5c8968213460b6bcf919597ea94de2157cb31/spigot-2.0.2.jar!/com/github/retrooper/packetevents/event/PacketListenerCommon.class" root0="SKIP_INSPECTION" />
|
||||
<setting file="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.retrooper.packetevents/spigot/2.2.0/d8ce06232bdbdec3b31021c84545bd1aff957af0/spigot-2.2.0.jar!/com/github/retrooper/packetevents/wrapper/play/server/WrapperPlayServerTeams.class" root0="SKIP_INSPECTION" />
|
||||
<setting file="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.spigotmc/spigot-api/1.20.1-R0.1-SNAPSHOT/23c0dae3633c3dd31d4503969fa7f9f3d36840fb/spigot-api-1.20.1-R0.1-SNAPSHOT.jar!/org/bukkit/plugin/EventExecutor.class" root0="SKIP_INSPECTION" />
|
||||
<setting file="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.spigotmc/spigot-api/1.20.1-R0.1-SNAPSHOT/23c0dae3633c3dd31d4503969fa7f9f3d36840fb/spigot-api-1.20.1-R0.1-SNAPSHOT.jar!/org/bukkit/plugin/PluginManager.class" root0="SKIP_INSPECTION" />
|
||||
<setting file="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.spigotmc/spigot-api/1.20.1-R0.1-SNAPSHOT/23c0dae3633c3dd31d4503969fa7f9f3d36840fb/spigot-api-1.20.1-R0.1-SNAPSHOT.jar!/org/bukkit/profile/PlayerProfile.class" root0="SKIP_INSPECTION" />
|
||||
<setting file="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.spigotmc/spigot-api/1.20.1-R0.1-SNAPSHOT/23c0dae3633c3dd31d4503969fa7f9f3d36840fb/spigot-api-1.20.1-R0.1-SNAPSHOT.jar!/org/bukkit/profile/PlayerTextures.class" root0="SKIP_INSPECTION" />
|
||||
<setting file="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.retrooper.packetevents/api/2.2.1/c70f2380ee7c60be444e22a10e679577ab9f8afa/api-2.2.1-default.jar!/com/github/retrooper/packetevents/protocol/player/TextureProperty.class" root0="SKIP_INSPECTION" />
|
||||
<setting file="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.8.0/c4ba5371a29ac9b2ad6129b1d39ea38750043eff/gson-2.8.0.jar!/com/google/gson/JsonArray.class" root0="SKIP_INSPECTION" />
|
||||
<setting file="jar://$USER_HOME$/.jdks/corretto-17.0.10/lib/src.zip!/java.base/java/util/List.java" root0="SKIP_INSPECTION" />
|
||||
</component>
|
||||
<component name="MarkdownSettingsMigration">
|
||||
<option name="stateVersion" value="1" />
|
||||
|
@ -98,7 +95,7 @@
|
|||
"Gradle.EntityLib [publish].executor": "Run",
|
||||
"Gradle.EntityLib:code-gen [:code-gen:Main.main()].executor": "Run",
|
||||
"Gradle.EntityLib:test-plugin [publish].executor": "Run",
|
||||
"Gradle.EntityLib:test-plugin [runServer].executor": "Debug",
|
||||
"Gradle.EntityLib:test-plugin [runServer].executor": "Run",
|
||||
"Gradle.EntityLib:test-plugin [shadowJar].executor": "Run",
|
||||
"Repository.Attach.Annotations": "false",
|
||||
"Repository.Attach.JavaDocs": "false",
|
||||
|
@ -110,7 +107,7 @@
|
|||
"ignore.virus.scanning.warn.message": "true",
|
||||
"jdk.selected.JAVA_MODULE": "corretto-17",
|
||||
"kotlin-language-version-configured": "true",
|
||||
"last_opened_file_path": "D:/Github/EntityLib/api/src/main/java/me/tofaa/entitylib/extras",
|
||||
"last_opened_file_path": "/mnt/sda2/Github/EntityLib",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
|
@ -121,6 +118,11 @@
|
|||
"project.structure.side.proportion": "0.2",
|
||||
"settings.editor.selected.configurable": "preferences.pluginManager",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
},
|
||||
"keyToStringList": {
|
||||
"kotlin-gradle-user-dirs": [
|
||||
"/home/tofaa/.gradle"
|
||||
]
|
||||
}
|
||||
}</component>
|
||||
<component name="RecentsManager">
|
||||
|
@ -245,9 +247,8 @@
|
|||
<component name="SharedIndexes">
|
||||
<attachedChunks>
|
||||
<set>
|
||||
<option value="jdk-1.8.0_402-temurin-1.8.0_402-4caba194b151-d4a4326d" />
|
||||
<option value="jdk-17.0.10-temurin-17.0.10-4caba194b151-b3785831" />
|
||||
<option value="jdk-21.0.2-openjdk-21.0.2-4caba194b151-4f524021" />
|
||||
<option value="bundled-jdk-9f38398b9061-18abd8497189-intellij.indexing.shared.core-IU-241.14494.240" />
|
||||
<option value="bundled-js-predefined-1d06a55b98c1-74d2a5396914-JavaScript-IU-241.14494.240" />
|
||||
</set>
|
||||
</attachedChunks>
|
||||
</component>
|
||||
|
@ -322,6 +323,7 @@
|
|||
<workItem from="1709074092924" duration="24000" />
|
||||
<workItem from="1709139306864" duration="1813000" />
|
||||
<workItem from="1709142473633" duration="2565000" />
|
||||
<workItem from="1714477887801" duration="3618000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
|
@ -347,7 +349,7 @@
|
|||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" type="java-line">
|
||||
<url>file://$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestPlayerCommand.java</url>
|
||||
<line>69</line>
|
||||
<line>77</line>
|
||||
<option name="timeStamp" value="4" />
|
||||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" type="java-method">
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package me.tofaa.entitylib;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public final class EntityLib {
|
||||
|
@ -23,13 +24,16 @@ public final class EntityLib {
|
|||
platform.getLogger().log(Level.WARNING, "You are using an outdated version of EntityLib. Please take a look at the Github releases page.");
|
||||
}
|
||||
|
||||
}
|
||||
catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
platform.getLogger().log(Level.WARNING, e, () -> "EntityLib failed to check for updates.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<EntityLibAPI<?>> getOptionalApi() {
|
||||
return Optional.ofNullable(api);
|
||||
}
|
||||
|
||||
public static <T> EntityLibAPI<T> getApi() {
|
||||
return api;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package me.tofaa.entitylib.extras;
|
||||
|
||||
public class MojangApiError extends RuntimeException {
|
||||
|
||||
public MojangApiError() {
|
||||
}
|
||||
|
||||
public MojangApiError(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public MojangApiError(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public MojangApiError(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public MojangApiError(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package me.tofaa.entitylib.extras.skin;
|
||||
|
||||
import me.tofaa.entitylib.extras.MojangApiError;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
final class CSFBImpl implements CachedSkinFetcherBuilder{
|
||||
|
||||
private Consumer<MojangApiError> onErr;
|
||||
private long cacheDuration = -1;
|
||||
|
||||
CSFBImpl(Consumer<MojangApiError> onErr) {
|
||||
this.onErr = onErr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedSkinFetcherBuilder cacheDuration(long duration) {
|
||||
this.cacheDuration = duration;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedSkinFetcherBuilder cached() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedSkinFetcherBuilder onErr(Consumer<MojangApiError> onErr) {
|
||||
this.onErr = onErr;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkinFetcher build() {
|
||||
return new CachedSkinFetcherImpl(onErr, cacheDuration);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package me.tofaa.entitylib.extras.skin;
|
||||
|
||||
import me.tofaa.entitylib.extras.MojangApiError;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface CachedSkinFetcherBuilder extends SkinFetcherBuilder {
|
||||
|
||||
CachedSkinFetcherBuilder cacheDuration(long duration);
|
||||
|
||||
@Override
|
||||
CachedSkinFetcherBuilder onErr(Consumer<MojangApiError> onErr);
|
||||
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
package me.tofaa.entitylib.extras.skin;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.TextureProperty;
|
||||
import me.tofaa.entitylib.extras.MojangApiError;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
final class CachedSkinFetcherImpl implements SkinFetcher {
|
||||
|
||||
private final long cacheDuration;
|
||||
private final Consumer<MojangApiError> onErr;
|
||||
private final Map<String, CachedData> cache = new HashMap<>();
|
||||
private final Map<UUID, CachedData> cacheUUID = new HashMap<>();
|
||||
|
||||
CachedSkinFetcherImpl(Consumer<MojangApiError> onErr, long cacheDuration) {
|
||||
this.onErr = onErr;
|
||||
this.cacheDuration = cacheDuration;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<TextureProperty> getSkin(String playerName) {
|
||||
if (cache.containsKey(playerName)) {
|
||||
CachedData data = cache.get(playerName);
|
||||
if (data.expiration > System.currentTimeMillis()) {
|
||||
return data.skin;
|
||||
}
|
||||
else {
|
||||
cache.remove(playerName);
|
||||
}
|
||||
}
|
||||
return putAndReturn(playerName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TextureProperty> getSkin(UUID uuid) {
|
||||
if (cacheUUID.containsKey(uuid)) {
|
||||
CachedData data = cacheUUID.get(uuid);
|
||||
if (data.expiration > System.currentTimeMillis()) {
|
||||
return data.skin;
|
||||
}
|
||||
else {
|
||||
cacheUUID.remove(uuid);
|
||||
}
|
||||
}
|
||||
return putAndReturn(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TextureProperty> getSkinOrDefault(String playerName, List<TextureProperty> defaults) {
|
||||
if (cache.containsKey(playerName)) {
|
||||
CachedData data = cache.get(playerName);
|
||||
if (data.expiration > System.currentTimeMillis()) {
|
||||
return data.skin;
|
||||
}
|
||||
else {
|
||||
cache.remove(playerName);
|
||||
}
|
||||
}
|
||||
List<TextureProperty> skin = putAndReturn(playerName);
|
||||
if (skin.isEmpty()) {
|
||||
cache.remove(playerName);
|
||||
return defaults;
|
||||
}
|
||||
return skin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TextureProperty> getSkinOrDefault(UUID uuid, List<TextureProperty> defaults) {
|
||||
if (cacheUUID.containsKey(uuid)) {
|
||||
CachedData data = cacheUUID.get(uuid);
|
||||
if (data.expiration > System.currentTimeMillis()) {
|
||||
return data.skin;
|
||||
}
|
||||
else {
|
||||
cacheUUID.remove(uuid);
|
||||
}
|
||||
}
|
||||
List<TextureProperty> skin = putAndReturn(uuid);
|
||||
if (skin.isEmpty()) {
|
||||
cacheUUID.remove(uuid);
|
||||
return defaults;
|
||||
}
|
||||
return skin;
|
||||
}
|
||||
|
||||
private List<TextureProperty> putAndReturn(String playerName) {
|
||||
ErroredTextureProperties p = SFUtils.getTextures(playerName);
|
||||
if (p.didError()) {
|
||||
if (onErr != null) {
|
||||
onErr.accept(new MojangApiError(p.getError()));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<TextureProperty> skin = p.getTextureProperties();
|
||||
CachedData data;
|
||||
if (cacheDuration == -1) {
|
||||
data = new CachedData(skin, Long.MAX_VALUE);
|
||||
}
|
||||
else {
|
||||
data = new CachedData(skin, System.currentTimeMillis() + cacheDuration);
|
||||
}
|
||||
cache.put(playerName, data);
|
||||
if (p.uuid != null) {
|
||||
cacheUUID.put(p.uuid, data);
|
||||
}
|
||||
return skin;
|
||||
}
|
||||
|
||||
private List<TextureProperty> putAndReturn(UUID uuid) {
|
||||
ErroredTextureProperties p = SFUtils.getTextures(uuid);
|
||||
if (p.didError()) {
|
||||
if (onErr != null) {
|
||||
onErr.accept(new MojangApiError(p.getError()));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<TextureProperty> skin = p.getTextureProperties();
|
||||
if (cacheDuration != -1) {
|
||||
cacheUUID.put(uuid, new CachedData(skin, System.currentTimeMillis() + cacheDuration));
|
||||
}
|
||||
else {
|
||||
cacheUUID.put(uuid, new CachedData(skin, Long.MAX_VALUE));
|
||||
}
|
||||
return skin;
|
||||
}
|
||||
static class CachedData {
|
||||
private final List<TextureProperty> skin;
|
||||
private final long expiration;
|
||||
CachedData(List<TextureProperty> skin, long expiration) {
|
||||
this.skin = skin;
|
||||
this.expiration = expiration;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package me.tofaa.entitylib.extras.skin;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.TextureProperty;
|
||||
import me.tofaa.entitylib.extras.MojangApiError;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
final class ErroredTextureProperties {
|
||||
|
||||
UUID uuid;
|
||||
private MojangApiError error;
|
||||
private List<TextureProperty> textureProperties;
|
||||
|
||||
ErroredTextureProperties(MojangApiError error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
ErroredTextureProperties(List<TextureProperty> textureProperties) {
|
||||
this.textureProperties = textureProperties;
|
||||
}
|
||||
|
||||
boolean didError() {
|
||||
return error != null;
|
||||
}
|
||||
|
||||
MojangApiError getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
List<TextureProperty> getTextureProperties() {
|
||||
return textureProperties;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package me.tofaa.entitylib.extras.skin;
|
||||
|
||||
import me.tofaa.entitylib.extras.MojangApiError;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
class SFBImpl implements SkinFetcherBuilder {
|
||||
|
||||
private Consumer<MojangApiError> rateLimitErrorConsumer;
|
||||
|
||||
@Override
|
||||
public CachedSkinFetcherBuilder cached() {
|
||||
return new CSFBImpl(rateLimitErrorConsumer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkinFetcherBuilder onErr(Consumer<MojangApiError> onErr) {
|
||||
this.rateLimitErrorConsumer = onErr;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkinFetcher build() {
|
||||
return new SkinFetcherImpl(rateLimitErrorConsumer);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package me.tofaa.entitylib.extras.skin;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.TextureProperty;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import me.tofaa.entitylib.extras.MojangApiError;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
final class SFUtils {
|
||||
|
||||
public static ErroredTextureProperties getTextures(String username) {
|
||||
try {
|
||||
URL url = new URL("https://api.mojang.com/users/profiles/minecraft/" + username);
|
||||
InputStream stream = url.openStream();
|
||||
InputStreamReader isr = new InputStreamReader(stream);
|
||||
JsonObject root = parse(isr);
|
||||
UUID uuid = UUID.fromString(root.get("id").getAsString());
|
||||
isr.close();
|
||||
stream.close();
|
||||
return getTextures(uuid);
|
||||
}
|
||||
catch (IOException e) {
|
||||
return new ErroredTextureProperties(new MojangApiError(e));
|
||||
}
|
||||
}
|
||||
|
||||
public static ErroredTextureProperties getTextures(UUID uuid) {
|
||||
try {
|
||||
URL url = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid.toString().replace("-", "") + "?unsigned=false");
|
||||
InputStream stream = url.openStream();
|
||||
InputStreamReader isr = new InputStreamReader(stream);
|
||||
JsonObject root = parse(isr);
|
||||
JsonArray textures = getTexturesObject(root);
|
||||
List<TextureProperty> properties = new ArrayList<>(textures.size());
|
||||
for (int i = 0; i < textures.size(); i++) {
|
||||
JsonObject texture = textures.get(i).getAsJsonObject();
|
||||
String name = texture.get("name").getAsString();
|
||||
String value = texture.get("value").getAsString();
|
||||
String signature = texture.has("signature") ? texture.get("signature").getAsString() : null;
|
||||
properties.add(new TextureProperty(name, value, signature));
|
||||
}
|
||||
isr.close();
|
||||
stream.close();
|
||||
ErroredTextureProperties prop = new ErroredTextureProperties(properties);
|
||||
prop.uuid = uuid;
|
||||
return prop;
|
||||
}
|
||||
catch (IOException e) {
|
||||
return new ErroredTextureProperties(new MojangApiError(e));
|
||||
}
|
||||
}
|
||||
|
||||
private SFUtils() {}
|
||||
|
||||
static JsonArray getTexturesObject(JsonObject root) {
|
||||
return root.getAsJsonArray("properties");
|
||||
}
|
||||
|
||||
static JsonObject parse(InputStreamReader isr) {
|
||||
return new JsonParser().parse(isr).getAsJsonObject();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package me.tofaa.entitylib.extras.skin;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.TextureProperty;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents a interface that fetches the skin of a player.
|
||||
* This class is non static, you should create and store an instance of it.
|
||||
* Creating one should be done using the builder. SkinFetcher is synchronous. You must handle that yourself.
|
||||
*/
|
||||
public interface SkinFetcher {
|
||||
|
||||
static SkinFetcherBuilder builder() {
|
||||
return new SFBImpl();
|
||||
}
|
||||
|
||||
|
||||
List<TextureProperty> getSkin(String playerName);
|
||||
|
||||
List<TextureProperty> getSkin(UUID uuid);
|
||||
|
||||
List<TextureProperty> getSkinOrDefault(String playerName, List<TextureProperty> defaults);
|
||||
|
||||
List<TextureProperty> getSkinOrDefault(UUID uuid, List<TextureProperty> defaults);
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package me.tofaa.entitylib.extras.skin;
|
||||
|
||||
import me.tofaa.entitylib.extras.MojangApiError;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface SkinFetcherBuilder {
|
||||
|
||||
CachedSkinFetcherBuilder cached();
|
||||
|
||||
SkinFetcherBuilder onErr(Consumer<MojangApiError> onErr);
|
||||
|
||||
SkinFetcher build();
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package me.tofaa.entitylib.extras.skin;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.TextureProperty;
|
||||
import me.tofaa.entitylib.extras.MojangApiError;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
final class SkinFetcherImpl implements SkinFetcher {
|
||||
|
||||
private final Consumer<MojangApiError> rateLimitErrorConsumer;
|
||||
|
||||
public SkinFetcherImpl(Consumer<MojangApiError> rateLimitErrorConsumer) {
|
||||
this.rateLimitErrorConsumer = rateLimitErrorConsumer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TextureProperty> getSkin(String playerName) {
|
||||
ErroredTextureProperties p = SFUtils.getTextures(playerName);
|
||||
if (p.didError()) {
|
||||
rateLimitErrorConsumer.accept(p.getError());
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return p.getTextureProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TextureProperty> getSkin(UUID uuid) {
|
||||
ErroredTextureProperties p = SFUtils.getTextures(uuid);
|
||||
if (p.didError()) {
|
||||
rateLimitErrorConsumer.accept(p.getError());
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return p.getTextureProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TextureProperty> getSkinOrDefault(String playerName, List<TextureProperty> defaults) {
|
||||
ErroredTextureProperties p = SFUtils.getTextures(playerName);
|
||||
if (p.didError()) {
|
||||
rateLimitErrorConsumer.accept(p.getError());
|
||||
return defaults;
|
||||
}
|
||||
return p.getTextureProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TextureProperty> getSkinOrDefault(UUID uuid, List<TextureProperty> defaults) {
|
||||
ErroredTextureProperties p = SFUtils.getTextures(uuid);
|
||||
if (p.didError()) {
|
||||
rateLimitErrorConsumer.accept(p.getError());
|
||||
return defaults;
|
||||
}
|
||||
return p.getTextureProperties();
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@ import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
|||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata;
|
||||
import me.tofaa.entitylib.EntityLib;
|
||||
import me.tofaa.entitylib.EntityLibAPI;
|
||||
import me.tofaa.entitylib.wrapper.WrapperEntity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
@ -34,7 +35,9 @@ public class Metadata {
|
|||
final EntityData entry = new EntityData(index, dataType, value);
|
||||
this.metadataMap.put(index, entry);
|
||||
|
||||
final WrapperEntity entity = EntityLib.getApi().getEntity(entityId);
|
||||
final Optional<EntityLibAPI<?>> optionalApi = EntityLib.getOptionalApi();
|
||||
if (!optionalApi.isPresent()) return;
|
||||
final WrapperEntity entity = optionalApi.get().getEntity(entityId);
|
||||
if (entity == null || !entity.isSpawned()) return; // Not EntityLib entity then, the user must send the packet manually. OR not spawned.
|
||||
if (!this.notifyAboutChanges) {
|
||||
synchronized (this.notNotifiedChanges) {
|
||||
|
|
|
@ -1,21 +1,16 @@
|
|||
package me.tofaa.testentitylib;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||
import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
import com.github.retrooper.packetevents.protocol.player.TextureProperty;
|
||||
import com.github.retrooper.packetevents.protocol.player.UserProfile;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfo;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
import me.tofaa.entitylib.EntityLib;
|
||||
import me.tofaa.entitylib.extras.skin.SkinFetcher;
|
||||
import me.tofaa.entitylib.spigot.ExtraConversionUtil;
|
||||
import me.tofaa.entitylib.wrapper.WrapperPlayer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.defaults.BukkitCommand;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -26,6 +21,7 @@ import java.util.*;
|
|||
public class TestPlayerCommand extends BukkitCommand {
|
||||
|
||||
private WrapperPlayer p;
|
||||
private SkinFetcher sf;
|
||||
public TestPlayerCommand() {
|
||||
super("testplayer");
|
||||
}
|
||||
|
@ -33,12 +29,24 @@ public class TestPlayerCommand extends BukkitCommand {
|
|||
@Override
|
||||
public boolean execute(@NotNull CommandSender commandSender, @NotNull String s, @NotNull String[] strings) {
|
||||
Player player = (Player) commandSender;
|
||||
if (strings.length != 1) {
|
||||
if (strings.length < 1) {
|
||||
player.sendMessage("Usage: /testplayer <spawn|hello|ping|gamemode|displayname|tablist|remove>");
|
||||
return false;
|
||||
}
|
||||
String arg = strings[0].toLowerCase();
|
||||
switch (arg) {
|
||||
case "skin":
|
||||
String input = strings[1];
|
||||
if (p == null) {
|
||||
player.sendMessage("Spawn an entity first");
|
||||
return false;
|
||||
}
|
||||
if (sf == null) {
|
||||
sf = SkinFetcher.builder()
|
||||
.cached()
|
||||
.build();
|
||||
}
|
||||
p.setTextureProperties(sf.getSkin(input));
|
||||
case "spawn":
|
||||
UserProfile profile = new UserProfile(UUID.randomUUID(), "randomname", new ArrayList<>());
|
||||
p = new WrapperPlayer(profile, EntityLib.getPlatform().getEntityIdProvider().provide(profile.getUUID(), EntityTypes.PLAYER));
|
||||
|
|
Loading…
Reference in a new issue