Add optional api getter to avoid NullPointer on metadata

This commit is contained in:
Tofaa 2024-05-01 16:34:31 +04:00
parent 3721878d4a
commit f7b5bd6246
15 changed files with 502 additions and 39 deletions

View file

@ -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>

View file

@ -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 @@
&quot;Gradle.EntityLib [publish].executor&quot;: &quot;Run&quot;,
&quot;Gradle.EntityLib:code-gen [:code-gen:Main.main()].executor&quot;: &quot;Run&quot;,
&quot;Gradle.EntityLib:test-plugin [publish].executor&quot;: &quot;Run&quot;,
&quot;Gradle.EntityLib:test-plugin [runServer].executor&quot;: &quot;Debug&quot;,
&quot;Gradle.EntityLib:test-plugin [runServer].executor&quot;: &quot;Run&quot;,
&quot;Gradle.EntityLib:test-plugin [shadowJar].executor&quot;: &quot;Run&quot;,
&quot;Repository.Attach.Annotations&quot;: &quot;false&quot;,
&quot;Repository.Attach.JavaDocs&quot;: &quot;false&quot;,
@ -110,7 +107,7 @@
&quot;ignore.virus.scanning.warn.message&quot;: &quot;true&quot;,
&quot;jdk.selected.JAVA_MODULE&quot;: &quot;corretto-17&quot;,
&quot;kotlin-language-version-configured&quot;: &quot;true&quot;,
&quot;last_opened_file_path&quot;: &quot;D:/Github/EntityLib/api/src/main/java/me/tofaa/entitylib/extras&quot;,
&quot;last_opened_file_path&quot;: &quot;/mnt/sda2/Github/EntityLib&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
@ -121,6 +118,11 @@
&quot;project.structure.side.proportion&quot;: &quot;0.2&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;preferences.pluginManager&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
},
&quot;keyToStringList&quot;: {
&quot;kotlin-gradle-user-dirs&quot;: [
&quot;/home/tofaa/.gradle&quot;
]
}
}</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">

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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;
}
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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();
}
}

View file

@ -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) {

View file

@ -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));