mirror of
https://github.com/BX-Team/DivineMC.git
synced 2025-12-22 08:19:19 +00:00
update PlayerAdvancements with synchronized map + remove ConcurrentReferenceHashMap
This commit is contained in:
@@ -1,11 +1,26 @@
|
||||
--- a/net/minecraft/server/PlayerAdvancements.java
|
||||
+++ b/net/minecraft/server/PlayerAdvancements.java
|
||||
@@ -60,7 +_,7 @@
|
||||
@@ -51,16 +_,18 @@
|
||||
private final PlayerList playerList;
|
||||
private final Path playerSavePath;
|
||||
private AdvancementTree tree;
|
||||
- private final Map<AdvancementHolder, AdvancementProgress> progress = new LinkedHashMap<>();
|
||||
- private final Set<AdvancementHolder> visible = new HashSet<>();
|
||||
- private final Set<AdvancementHolder> progressChanged = new HashSet<>();
|
||||
- private final Set<AdvancementNode> rootsToUpdate = new HashSet<>();
|
||||
+ // DivineMC start - Use synchronized map
|
||||
+ private final Map<AdvancementHolder, AdvancementProgress> progress = java.util.Collections.synchronizedMap(new LinkedHashMap<>());
|
||||
+ private final Set<AdvancementHolder> visible = com.google.common.collect.Sets.newConcurrentHashSet();
|
||||
+ private final Set<AdvancementHolder> progressChanged = com.google.common.collect.Sets.newConcurrentHashSet();
|
||||
+ private final Set<AdvancementNode> rootsToUpdate = com.google.common.collect.Sets.newConcurrentHashSet();
|
||||
+ // DivineMC end - Use synchronized map
|
||||
private ServerPlayer player;
|
||||
@Nullable
|
||||
private AdvancementHolder lastSelectedTab;
|
||||
private boolean isFirstPacket = true;
|
||||
private final Codec<PlayerAdvancements.Data> codec;
|
||||
- public final Map<net.minecraft.advancements.critereon.SimpleCriterionTrigger<?>, Set<CriterionTrigger.Listener<?>>> criterionData = new java.util.IdentityHashMap<>(); // Paper - fix advancement data player leakage
|
||||
+ public final Map<net.minecraft.advancements.critereon.SimpleCriterionTrigger<?>, Set<CriterionTrigger.Listener<?>>> criterionData = new org.bxteam.divinemc.util.map.ConcurrentReferenceHashMap<>(); // Paper - fix advancement data player leakage // DivineMC - Use ConcurrentReferenceHashMap
|
||||
+ public final Map<net.minecraft.advancements.critereon.SimpleCriterionTrigger<?>, Set<CriterionTrigger.Listener<?>>> criterionData = java.util.Collections.synchronizedMap(new java.util.IdentityHashMap<>()); // Paper - fix advancement data player leakage // DivineMC - Use synchronized map
|
||||
|
||||
public PlayerAdvancements(DataFixer dataFixer, PlayerList playerList, ServerAdvancementManager manager, Path playerSavePath, ServerPlayer player) {
|
||||
this.playerList = playerList;
|
||||
|
||||
@@ -1,421 +0,0 @@
|
||||
package org.bxteam.divinemc.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Assertion utility class that assists in validating arguments.
|
||||
*
|
||||
* <p>Useful for identifying programmer errors early and clearly at runtime.
|
||||
*
|
||||
* <p>For example, if the contract of a public method states it does not
|
||||
* allow {@code null} arguments, {@code Assert} can be used to validate that
|
||||
* contract. Doing this clearly indicates a contract violation when it
|
||||
* occurs and protects the class's invariants.
|
||||
*
|
||||
* <p>Typically used to validate method arguments rather than configuration
|
||||
* properties, to check for cases that are usually programmer errors rather
|
||||
* than configuration errors. In contrast to configuration initialization
|
||||
* code, there is usually no point in falling back to defaults in such methods.
|
||||
*
|
||||
* <p>This class is similar to JUnit's assertion library. If an argument value is
|
||||
* deemed invalid, an {@link IllegalArgumentException} is thrown (typically).
|
||||
* For example:
|
||||
*
|
||||
* <pre class="code">
|
||||
* Assert.notNull(clazz, "The class must not be null");
|
||||
* Assert.isTrue(i > 0, "The value must be greater than zero");</pre>
|
||||
*
|
||||
* <p>Mainly for internal use within the framework; for a more comprehensive suite
|
||||
* of assertion utilities consider {@code org.apache.commons.lang3.Validate} from
|
||||
* <a href="https://commons.apache.org/proper/commons-lang/">Apache Commons Lang</a>,
|
||||
* Google Guava's
|
||||
* <a href="https://github.com/google/guava/wiki/PreconditionsExplained">Preconditions</a>,
|
||||
* or similar third-party libraries.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @author Colin Sampaleanu
|
||||
* @author Rob Harrop
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public abstract class Assert {
|
||||
/**
|
||||
* Assert a boolean expression, throwing an {@code IllegalStateException}
|
||||
* if the expression evaluates to {@code false}.
|
||||
* <p>Call {@link #isTrue} if you wish to throw an {@code IllegalArgumentException}
|
||||
* on an assertion failure.
|
||||
* <pre class="code">Assert.state(id == null, "The id property must not already be initialized");</pre>
|
||||
* @param expression a boolean expression
|
||||
* @param message the exception message to use if the assertion fails
|
||||
* @throws IllegalStateException if {@code expression} is {@code false}
|
||||
*/
|
||||
@Contract("false, _ -> fail")
|
||||
public static void state(boolean expression, String message) {
|
||||
if (!expression) {
|
||||
throw new IllegalStateException(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert a boolean expression, throwing an {@code IllegalStateException}
|
||||
* if the expression evaluates to {@code false}.
|
||||
* <p>Call {@link #isTrue} if you wish to throw an {@code IllegalArgumentException}
|
||||
* on an assertion failure.
|
||||
* <pre class="code">
|
||||
* Assert.state(entity.getId() == null,
|
||||
* () -> "ID for entity " + entity.getName() + " must not already be initialized");
|
||||
* </pre>
|
||||
* @param expression a boolean expression
|
||||
* @param messageSupplier a supplier for the exception message to use if the
|
||||
* assertion fails
|
||||
* @throws IllegalStateException if {@code expression} is {@code false}
|
||||
* @since 5.0
|
||||
*/
|
||||
@Contract("false, _ -> fail")
|
||||
public static void state(boolean expression, Supplier<String> messageSupplier) {
|
||||
if (!expression) {
|
||||
throw new IllegalStateException(nullSafeGet(messageSupplier));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert a boolean expression, throwing an {@code IllegalArgumentException}
|
||||
* if the expression evaluates to {@code false}.
|
||||
* <pre class="code">Assert.isTrue(i > 0, "The value must be greater than zero");</pre>
|
||||
* @param expression a boolean expression
|
||||
* @param message the exception message to use if the assertion fails
|
||||
* @throws IllegalArgumentException if {@code expression} is {@code false}
|
||||
*/
|
||||
@Contract("false, _ -> fail")
|
||||
public static void isTrue(boolean expression, String message) {
|
||||
if (!expression) {
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert a boolean expression, throwing an {@code IllegalArgumentException}
|
||||
* if the expression evaluates to {@code false}.
|
||||
* <pre class="code">
|
||||
* Assert.isTrue(i > 0, () -> "The value '" + i + "' must be greater than zero");
|
||||
* </pre>
|
||||
* @param expression a boolean expression
|
||||
* @param messageSupplier a supplier for the exception message to use if the
|
||||
* assertion fails
|
||||
* @throws IllegalArgumentException if {@code expression} is {@code false}
|
||||
* @since 5.0
|
||||
*/
|
||||
@Contract("false, _ -> fail")
|
||||
public static void isTrue(boolean expression, Supplier<String> messageSupplier) {
|
||||
if (!expression) {
|
||||
throw new IllegalArgumentException(nullSafeGet(messageSupplier));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that an object is {@code null}.
|
||||
* <pre class="code">Assert.isNull(value, "The value must be null");</pre>
|
||||
* @param object the object to check
|
||||
* @param message the exception message to use if the assertion fails
|
||||
* @throws IllegalArgumentException if the object is not {@code null}
|
||||
*/
|
||||
@Contract("!null, _ -> fail")
|
||||
public static void isNull(@Nullable Object object, String message) {
|
||||
if (object != null) {
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that an object is {@code null}.
|
||||
* <pre class="code">
|
||||
* Assert.isNull(value, () -> "The value '" + value + "' must be null");
|
||||
* </pre>
|
||||
* @param object the object to check
|
||||
* @param messageSupplier a supplier for the exception message to use if the
|
||||
* assertion fails
|
||||
* @throws IllegalArgumentException if the object is not {@code null}
|
||||
* @since 5.0
|
||||
*/
|
||||
@Contract("!null, _ -> fail")
|
||||
public static void isNull(@Nullable Object object, Supplier<String> messageSupplier) {
|
||||
if (object != null) {
|
||||
throw new IllegalArgumentException(nullSafeGet(messageSupplier));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that an object is not {@code null}.
|
||||
* <pre class="code">Assert.notNull(clazz, "The class must not be null");</pre>
|
||||
* @param object the object to check
|
||||
* @param message the exception message to use if the assertion fails
|
||||
* @throws IllegalArgumentException if the object is {@code null}
|
||||
*/
|
||||
@Contract("null, _ -> fail")
|
||||
public static void notNull(@Nullable Object object, String message) {
|
||||
if (object == null) {
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that an object is not {@code null}.
|
||||
* <pre class="code">
|
||||
* Assert.notNull(entity.getId(),
|
||||
* () -> "ID for entity " + entity.getName() + " must not be null");
|
||||
* </pre>
|
||||
* @param object the object to check
|
||||
* @param messageSupplier a supplier for the exception message to use if the
|
||||
* assertion fails
|
||||
* @throws IllegalArgumentException if the object is {@code null}
|
||||
* @since 5.0
|
||||
*/
|
||||
@Contract("null, _ -> fail")
|
||||
public static void notNull(@Nullable Object object, Supplier<String> messageSupplier) {
|
||||
if (object == null) {
|
||||
throw new IllegalArgumentException(nullSafeGet(messageSupplier));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that an array contains no {@code null} elements.
|
||||
* <p>Note: Does not complain if the array is empty!
|
||||
* <pre class="code">Assert.noNullElements(array, "The array must contain non-null elements");</pre>
|
||||
* @param array the array to check
|
||||
* @param message the exception message to use if the assertion fails
|
||||
* @throws IllegalArgumentException if the object array contains a {@code null} element
|
||||
*/
|
||||
public static void noNullElements(Object @Nullable [] array, String message) {
|
||||
if (array != null) {
|
||||
for (Object element : array) {
|
||||
if (element == null) {
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that an array contains no {@code null} elements.
|
||||
* <p>Note: Does not complain if the array is empty!
|
||||
* <pre class="code">
|
||||
* Assert.noNullElements(array, () -> "The " + arrayType + " array must contain non-null elements");
|
||||
* </pre>
|
||||
* @param array the array to check
|
||||
* @param messageSupplier a supplier for the exception message to use if the
|
||||
* assertion fails
|
||||
* @throws IllegalArgumentException if the object array contains a {@code null} element
|
||||
* @since 5.0
|
||||
*/
|
||||
public static void noNullElements(Object @Nullable [] array, Supplier<String> messageSupplier) {
|
||||
if (array != null) {
|
||||
for (Object element : array) {
|
||||
if (element == null) {
|
||||
throw new IllegalArgumentException(nullSafeGet(messageSupplier));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that a collection contains no {@code null} elements.
|
||||
* <p>Note: Does not complain if the collection is empty!
|
||||
* <pre class="code">Assert.noNullElements(collection, "Collection must contain non-null elements");</pre>
|
||||
* @param collection the collection to check
|
||||
* @param message the exception message to use if the assertion fails
|
||||
* @throws IllegalArgumentException if the collection contains a {@code null} element
|
||||
* @since 5.2
|
||||
*/
|
||||
public static void noNullElements(@Nullable Collection<?> collection, String message) {
|
||||
if (collection != null) {
|
||||
for (Object element : collection) {
|
||||
if (element == null) {
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that a collection contains no {@code null} elements.
|
||||
* <p>Note: Does not complain if the collection is empty!
|
||||
* <pre class="code">
|
||||
* Assert.noNullElements(collection, () -> "Collection " + collectionName + " must contain non-null elements");
|
||||
* </pre>
|
||||
* @param collection the collection to check
|
||||
* @param messageSupplier a supplier for the exception message to use if the
|
||||
* assertion fails
|
||||
* @throws IllegalArgumentException if the collection contains a {@code null} element
|
||||
* @since 5.2
|
||||
*/
|
||||
public static void noNullElements(@Nullable Collection<?> collection, Supplier<String> messageSupplier) {
|
||||
if (collection != null) {
|
||||
for (Object element : collection) {
|
||||
if (element == null) {
|
||||
throw new IllegalArgumentException(nullSafeGet(messageSupplier));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the provided object is an instance of the provided class.
|
||||
* <pre class="code">Assert.instanceOf(Foo.class, foo, "Foo expected");</pre>
|
||||
* @param type the type to check against
|
||||
* @param obj the object to check
|
||||
* @param message a message which will be prepended to provide further context.
|
||||
* If it is empty or ends in ":" or ";" or "," or ".", a full exception message
|
||||
* will be appended. If it ends in a space, the name of the offending object's
|
||||
* type will be appended. In any other case, a ":" with a space and the name
|
||||
* of the offending object's type will be appended.
|
||||
* @throws IllegalArgumentException if the object is not an instance of type
|
||||
*/
|
||||
@Contract("_, null, _ -> fail")
|
||||
public static void isInstanceOf(Class<?> type, @Nullable Object obj, String message) {
|
||||
notNull(type, "Type to check against must not be null");
|
||||
if (!type.isInstance(obj)) {
|
||||
instanceCheckFailed(type, obj, message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the provided object is an instance of the provided class.
|
||||
* <pre class="code">
|
||||
* Assert.instanceOf(Foo.class, foo, () -> "Processing " + Foo.class.getSimpleName() + ":");
|
||||
* </pre>
|
||||
* @param type the type to check against
|
||||
* @param obj the object to check
|
||||
* @param messageSupplier a supplier for the exception message to use if the
|
||||
* assertion fails. See {@link #isInstanceOf(Class, Object, String)} for details.
|
||||
* @throws IllegalArgumentException if the object is not an instance of type
|
||||
* @since 5.0
|
||||
*/
|
||||
@Contract("_, null, _ -> fail")
|
||||
public static void isInstanceOf(Class<?> type, @Nullable Object obj, Supplier<String> messageSupplier) {
|
||||
notNull(type, "Type to check against must not be null");
|
||||
if (!type.isInstance(obj)) {
|
||||
instanceCheckFailed(type, obj, nullSafeGet(messageSupplier));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the provided object is an instance of the provided class.
|
||||
* <pre class="code">Assert.instanceOf(Foo.class, foo);</pre>
|
||||
* @param type the type to check against
|
||||
* @param obj the object to check
|
||||
* @throws IllegalArgumentException if the object is not an instance of type
|
||||
*/
|
||||
@Contract("_, null -> fail")
|
||||
public static void isInstanceOf(Class<?> type, @Nullable Object obj) {
|
||||
isInstanceOf(type, obj, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that {@code superType.isAssignableFrom(subType)} is {@code true}.
|
||||
* <pre class="code">Assert.isAssignable(Number.class, myClass, "Number expected");</pre>
|
||||
* @param superType the supertype to check against
|
||||
* @param subType the subtype to check
|
||||
* @param message a message which will be prepended to provide further context.
|
||||
* If it is empty or ends in ":" or ";" or "," or ".", a full exception message
|
||||
* will be appended. If it ends in a space, the name of the offending subtype
|
||||
* will be appended. In any other case, a ":" with a space and the name of the
|
||||
* offending subtype will be appended.
|
||||
* @throws IllegalArgumentException if the classes are not assignable
|
||||
*/
|
||||
@Contract("_, null, _ -> fail")
|
||||
public static void isAssignable(Class<?> superType, @Nullable Class<?> subType, String message) {
|
||||
notNull(superType, "Supertype to check against must not be null");
|
||||
if (subType == null || !superType.isAssignableFrom(subType)) {
|
||||
assignableCheckFailed(superType, subType, message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that {@code superType.isAssignableFrom(subType)} is {@code true}.
|
||||
* <pre class="code">
|
||||
* Assert.isAssignable(Number.class, myClass, () -> "Processing " + myAttributeName + ":");
|
||||
* </pre>
|
||||
* @param superType the supertype to check against
|
||||
* @param subType the subtype to check
|
||||
* @param messageSupplier a supplier for the exception message to use if the
|
||||
* assertion fails. See {@link #isAssignable(Class, Class, String)} for details.
|
||||
* @throws IllegalArgumentException if the classes are not assignable
|
||||
* @since 5.0
|
||||
*/
|
||||
@Contract("_, null, _ -> fail")
|
||||
public static void isAssignable(Class<?> superType, @Nullable Class<?> subType, Supplier<String> messageSupplier) {
|
||||
notNull(superType, "Supertype to check against must not be null");
|
||||
if (subType == null || !superType.isAssignableFrom(subType)) {
|
||||
assignableCheckFailed(superType, subType, nullSafeGet(messageSupplier));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that {@code superType.isAssignableFrom(subType)} is {@code true}.
|
||||
* <pre class="code">Assert.isAssignable(Number.class, myClass);</pre>
|
||||
* @param superType the supertype to check
|
||||
* @param subType the subtype to check
|
||||
* @throws IllegalArgumentException if the classes are not assignable
|
||||
*/
|
||||
@Contract("_, null -> fail")
|
||||
public static void isAssignable(Class<?> superType, @Nullable Class<?> subType) {
|
||||
isAssignable(superType, subType, "");
|
||||
}
|
||||
|
||||
|
||||
private static void instanceCheckFailed(Class<?> type, @Nullable Object obj, @Nullable String msg) {
|
||||
String className = (obj != null ? obj.getClass().getName() : "null");
|
||||
String result = "";
|
||||
boolean defaultMessage = true;
|
||||
if (StringUtil.hasLength(msg)) {
|
||||
if (endsWithSeparator(msg)) {
|
||||
result = msg + " ";
|
||||
}
|
||||
else {
|
||||
result = messageWithTypeName(msg, className);
|
||||
defaultMessage = false;
|
||||
}
|
||||
}
|
||||
if (defaultMessage) {
|
||||
result = result + ("Object of class [" + className + "] must be an instance of " + type);
|
||||
}
|
||||
throw new IllegalArgumentException(result);
|
||||
}
|
||||
|
||||
private static void assignableCheckFailed(Class<?> superType, @Nullable Class<?> subType, @Nullable String msg) {
|
||||
String result = "";
|
||||
boolean defaultMessage = true;
|
||||
if (StringUtil.hasLength(msg)) {
|
||||
if (endsWithSeparator(msg)) {
|
||||
result = msg + " ";
|
||||
}
|
||||
else {
|
||||
result = messageWithTypeName(msg, subType);
|
||||
defaultMessage = false;
|
||||
}
|
||||
}
|
||||
if (defaultMessage) {
|
||||
result = result + (subType + " is not assignable to " + superType);
|
||||
}
|
||||
throw new IllegalArgumentException(result);
|
||||
}
|
||||
|
||||
private static boolean endsWithSeparator(@NotNull String msg) {
|
||||
return (msg.endsWith(":") || msg.endsWith(";") || msg.endsWith(",") || msg.endsWith("."));
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
private static @NotNull String messageWithTypeName(@NotNull String msg, @Nullable Object typeName) {
|
||||
return msg + (msg.endsWith(" ") ? "" : ": ") + typeName;
|
||||
}
|
||||
|
||||
private static @Nullable String nullSafeGet(@Nullable Supplier<String> messageSupplier) {
|
||||
return (messageSupplier != null ? messageSupplier.get() : null);
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
package org.bxteam.divinemc.util;
|
||||
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ObjectUtil {
|
||||
@Contract("null, null -> true; null, _ -> false; _, null -> false")
|
||||
public static boolean nullSafeEquals(@Nullable Object o1, @Nullable Object o2) {
|
||||
if (o1 == o2) {
|
||||
return true;
|
||||
}
|
||||
if (o1 == null || o2 == null) {
|
||||
return false;
|
||||
}
|
||||
if (o1.equals(o2)) {
|
||||
return true;
|
||||
}
|
||||
if (o1.getClass().isArray() && o2.getClass().isArray()) {
|
||||
return arrayEquals(o1, o2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the given arrays with {@code Arrays.equals}, performing an equality
|
||||
* check based on the array elements rather than the array reference.
|
||||
* @param o1 first array to compare
|
||||
* @param o2 second array to compare
|
||||
* @return whether the given objects are equal
|
||||
* @see #nullSafeEquals(Object, Object)
|
||||
* @see java.util.Arrays#equals
|
||||
*/
|
||||
private static boolean arrayEquals(Object o1, Object o2) {
|
||||
if (o1 instanceof Object[] objects1 && o2 instanceof Object[] objects2) {
|
||||
return Arrays.equals(objects1, objects2);
|
||||
}
|
||||
if (o1 instanceof boolean[] booleans1 && o2 instanceof boolean[] booleans2) {
|
||||
return Arrays.equals(booleans1, booleans2);
|
||||
}
|
||||
if (o1 instanceof byte[] bytes1 && o2 instanceof byte[] bytes2) {
|
||||
return Arrays.equals(bytes1, bytes2);
|
||||
}
|
||||
if (o1 instanceof char[] chars1 && o2 instanceof char[] chars2) {
|
||||
return Arrays.equals(chars1, chars2);
|
||||
}
|
||||
if (o1 instanceof double[] doubles1 && o2 instanceof double[] doubles2) {
|
||||
return Arrays.equals(doubles1, doubles2);
|
||||
}
|
||||
if (o1 instanceof float[] floats1 && o2 instanceof float[] floats2) {
|
||||
return Arrays.equals(floats1, floats2);
|
||||
}
|
||||
if (o1 instanceof int[] ints1 && o2 instanceof int[] ints2) {
|
||||
return Arrays.equals(ints1, ints2);
|
||||
}
|
||||
if (o1 instanceof long[] longs1 && o2 instanceof long[] longs2) {
|
||||
return Arrays.equals(longs1, longs2);
|
||||
}
|
||||
if (o1 instanceof short[] shorts1 && o2 instanceof short[] shorts2) {
|
||||
return Arrays.equals(shorts1, shorts2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a hash code for the given object; typically the value of
|
||||
* {@code Object#hashCode()}}. If the object is an array,
|
||||
* this method will delegate to any of the {@code Arrays.hashCode}
|
||||
* methods. If the object is {@code null}, this method returns 0.
|
||||
* @see Object#hashCode()
|
||||
* @see Arrays
|
||||
*/
|
||||
public static int nullSafeHashCode(@Nullable Object obj) {
|
||||
if (obj == null) {
|
||||
return 0;
|
||||
}
|
||||
if (obj.getClass().isArray()) {
|
||||
if (obj instanceof Object[] objects) {
|
||||
return Arrays.hashCode(objects);
|
||||
}
|
||||
if (obj instanceof boolean[] booleans) {
|
||||
return Arrays.hashCode(booleans);
|
||||
}
|
||||
if (obj instanceof byte[] bytes) {
|
||||
return Arrays.hashCode(bytes);
|
||||
}
|
||||
if (obj instanceof char[] chars) {
|
||||
return Arrays.hashCode(chars);
|
||||
}
|
||||
if (obj instanceof double[] doubles) {
|
||||
return Arrays.hashCode(doubles);
|
||||
}
|
||||
if (obj instanceof float[] floats) {
|
||||
return Arrays.hashCode(floats);
|
||||
}
|
||||
if (obj instanceof int[] ints) {
|
||||
return Arrays.hashCode(ints);
|
||||
}
|
||||
if (obj instanceof long[] longs) {
|
||||
return Arrays.hashCode(longs);
|
||||
}
|
||||
if (obj instanceof short[] shorts) {
|
||||
return Arrays.hashCode(shorts);
|
||||
}
|
||||
}
|
||||
return obj.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package org.bxteam.divinemc.util;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class StringUtil {
|
||||
public static boolean hasLength(@Nullable String str) {
|
||||
return (str != null && !str.isEmpty());
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user