aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/io/github/moulberry/notenoughupdates/util
diff options
context:
space:
mode:
authorRoman / Linnea Gräf <roman.graef@gmail.com>2022-08-26 13:24:35 +0200
committerGitHub <noreply@github.com>2022-08-26 21:24:35 +1000
commitdfd2f6b05bce74d7feb5d28e7a388dbb871ecf6a (patch)
tree001913c4f1dd391831da26e4398f75e6731c88e1 /src/main/java/io/github/moulberry/notenoughupdates/util
parentc3845685bbb3a2a7fde25476eed0f788e038dc93 (diff)
downloadnotenoughupdates-dfd2f6b05bce74d7feb5d28e7a388dbb871ecf6a.tar.gz
notenoughupdates-dfd2f6b05bce74d7feb5d28e7a388dbb871ecf6a.tar.bz2
notenoughupdates-dfd2f6b05bce74d7feb5d28e7a388dbb871ecf6a.zip
Of course you have pronouns in pv (#234)
Diffstat (limited to 'src/main/java/io/github/moulberry/notenoughupdates/util')
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/AsyncDependencyLoader.java55
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/AsyncDependencyLoaderImpl.java59
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/MinecraftExecutor.java37
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/PronounDB.java221
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java19
5 files changed, 388 insertions, 3 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/AsyncDependencyLoader.java b/src/main/java/io/github/moulberry/notenoughupdates/util/AsyncDependencyLoader.java
new file mode 100644
index 00000000..37b0a187
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/AsyncDependencyLoader.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.util;
+
+import com.google.common.base.Objects;
+
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public interface AsyncDependencyLoader<T> {
+
+ Optional<T> peekValue();
+
+ public static <R, T> AsyncDependencyLoader<T> withObjectIdentity(
+ Supplier<R> supplier,
+ Function<R, CompletableFuture<T>> generator
+ ) {
+ return new AsyncDependencyLoaderImpl<>(supplier, generator, (a, b) -> a != b);
+ }
+
+ public static <R, T> AsyncDependencyLoader<T> withEqualsInvocation(
+ Supplier<R> supplier,
+ Function<R, CompletableFuture<T>> generator
+ ) {
+ return new AsyncDependencyLoaderImpl<>(supplier, generator, (a, b) -> !Objects.equal(a, b));
+ }
+
+ public static <R, T> AsyncDependencyLoader<T> withEqualityFunction(
+ Supplier<R> supplier,
+ Function<R, CompletableFuture<T>> generator,
+ BiFunction<R, R, Boolean> isEqual
+ ) {
+ return new AsyncDependencyLoaderImpl<>(supplier, generator, (a, b) -> !isEqual.apply(a, b));
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/AsyncDependencyLoaderImpl.java b/src/main/java/io/github/moulberry/notenoughupdates/util/AsyncDependencyLoaderImpl.java
new file mode 100644
index 00000000..4b7f2fb8
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/AsyncDependencyLoaderImpl.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.util;
+
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+class AsyncDependencyLoaderImpl<R, T> implements AsyncDependencyLoader<T> {
+
+ private final Supplier<R> supplyDependency;
+ private final Function<R, CompletableFuture<T>> generator;
+ private final BiFunction<R, R, Boolean> isDifferent;
+ private volatile CompletableFuture<T> lastValue;
+ private volatile R lastDependency;
+ private volatile boolean isFirstFire = true;
+
+ @Override
+ public synchronized Optional<T> peekValue() {
+ R nextDependency = supplyDependency.get();
+ if (isFirstFire || isDifferent.apply(nextDependency, lastDependency)) {
+ isFirstFire = false;
+ if (lastValue != null)
+ lastValue.cancel(true);
+ lastValue = generator.apply(nextDependency);
+ }
+ lastDependency = nextDependency;
+ return Optional.ofNullable(lastValue.getNow(null));
+ }
+
+ AsyncDependencyLoaderImpl(
+ Supplier<R> supplyDependency,
+ Function<R, CompletableFuture<T>> generator,
+ BiFunction<R, R, Boolean> isDifferent
+ ) {
+ this.supplyDependency = supplyDependency;
+ this.generator = generator;
+ this.isDifferent = isDifferent;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/MinecraftExecutor.java b/src/main/java/io/github/moulberry/notenoughupdates/util/MinecraftExecutor.java
new file mode 100644
index 00000000..bf973b76
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/MinecraftExecutor.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.util;
+
+import net.minecraft.client.Minecraft;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.concurrent.Executor;
+
+public class MinecraftExecutor implements Executor {
+
+ public static MinecraftExecutor INSTANCE = new MinecraftExecutor();
+
+ private MinecraftExecutor() {}
+
+ @Override
+ public void execute(@NotNull Runnable runnable) {
+ Minecraft.getMinecraft().addScheduledTask(runnable);
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/PronounDB.java b/src/main/java/io/github/moulberry/notenoughupdates/util/PronounDB.java
new file mode 100644
index 00000000..e7286721
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/PronounDB.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.util;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+public class PronounDB {
+
+ static SSLContext ctx;
+
+ static {
+ try {
+ KeyStore ks = KeyStore.getInstance("JKS");
+ ks.load(PronounDB.class.getResourceAsStream("/pronoundb.jks"), "pronoundb".toCharArray());
+ ctx = SSLContext.getInstance("TLS");
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ kmf.init(ks, null);
+ tmf.init(ks);
+ ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+ } catch (KeyStoreException | NoSuchAlgorithmException | KeyManagementException | UnrecoverableKeyException |
+ IOException | CertificateException e) {
+ System.out.println("Failed to load keystore. PronounDB requests will probably not work");
+ e.printStackTrace();
+ }
+ }
+
+ private static boolean isDisabled() {
+ JsonObject disabled = Constants.DISABLE;
+ return disabled != null && disabled.has("pronoundb");
+ }
+
+ /**
+ * Returns an Optional, since JVMs can be *very* funky with KeyStore loading
+ */
+ public static Optional<JsonObject> performPronouning(String platform, String id) {
+ if (isDisabled()) return Optional.empty();
+ try {
+ URL url = new URL("https://pronoundb.org/api/v1/lookup" +
+ "?platform=" + StringUtils.urlEncode(platform) +
+ "&id=" + StringUtils.urlEncode(id));
+ HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
+ urlConnection.setSSLSocketFactory(ctx.getSocketFactory());
+ return Optional.of(NotEnoughUpdates.INSTANCE.manager.gson.fromJson(
+ new InputStreamReader(urlConnection.getInputStream()),
+ JsonObject.class
+ ));
+ } catch (ClassCastException | IOException | JsonParseException e) {
+ System.out.println("Failed to contact PronounDB: " + e);
+ return Optional.empty();
+ }
+ }
+
+ public enum Pronoun {
+ HE("he", "him", "his"),
+ IT("it", "it", "its"),
+ SHE("she", "her", "hers"),
+ THEY("they", "they", "theirs");
+
+ private final String subject;
+ private final String object;
+ private final String possessive;
+
+ Pronoun(String subject, String object, String possessive) {
+ this.subject = subject;
+ this.object = object;
+ this.possessive = possessive;
+ }
+
+ public String getSubject() {
+ return subject;
+ }
+
+ public String getObject() {
+ return object;
+ }
+
+ public String getPossessive() {
+ return possessive;
+ }
+ }
+
+ public enum PronounChoice {
+ UNSPECIFIED("unspecified", "Unspecified"),
+ HE("hh", Pronoun.HE),
+ HEIT("hi", Pronoun.HE, Pronoun.IT),
+ HESHE("hs", Pronoun.HE, Pronoun.SHE),
+ HETHEY("ht", Pronoun.HE, Pronoun.THEY),
+ ITHE("ih", Pronoun.IT, Pronoun.HE),
+ IT("ii", Pronoun.IT),
+ ITSHE("is", Pronoun.IT, Pronoun.SHE),
+ ITTHEY("it", Pronoun.IT, Pronoun.THEY),
+ SHEHE("shh", Pronoun.SHE, Pronoun.HE),
+ SHE("sh", Pronoun.SHE),
+ SHEIT("si", Pronoun.SHE, Pronoun.IT),
+ SHETHEY("st", Pronoun.SHE, Pronoun.THEY),
+ THEYHE("th", Pronoun.THEY, Pronoun.HE),
+ THEYIT("ti", Pronoun.THEY, Pronoun.IT),
+ THEYSHE("ts", Pronoun.THEY, Pronoun.SHE),
+ THEY("tt", Pronoun.THEY),
+ ANY("any", "Any pronouns"),
+ OTHER("other", "Other pronouns"),
+ ASK("ask", "Ask me my pronouns"),
+ AVOID("avoid", "Avoid pronouns, use my name");
+ private final String id;
+ private List<Pronoun> pronouns = null;
+ private String override = null;
+
+ PronounChoice(String id, String override) {
+ this.override = override;
+ this.id = id;
+ }
+
+ PronounChoice(String id, Pronoun... pronouns) {
+ this.id = id;
+ this.pronouns = Arrays.asList(pronouns);
+ }
+
+ public static Optional<PronounChoice> findPronounsForId(String id) {
+ for (PronounChoice value : values()) {
+ if (value.id.equals(id)) return Optional.of(value);
+ }
+ return Optional.empty();
+ }
+
+ public String getOverride() {
+ return override;
+ }
+
+ public List<Pronoun> getPronounsInPreferredOrder() {
+ return pronouns;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public List<String> render() {
+ if (override != null)
+ return Arrays.asList(override);
+ return pronouns
+ .stream()
+ .map(pronoun -> pronoun.getSubject() + "/" + pronoun.getObject())
+ .collect(Collectors.toList());
+ }
+
+ public boolean isConsciousChoice() {
+ return this != UNSPECIFIED;
+ }
+
+ }
+
+ public static Optional<PronounChoice> parsePronouns(JsonObject pronounObject) {
+ if (pronounObject.has("pronouns")) {
+ JsonElement pronouns = pronounObject.get("pronouns");
+ if (pronouns.isJsonPrimitive() && pronouns.getAsJsonPrimitive().isString())
+ return PronounChoice.findPronounsForId(pronouns.getAsString());
+ }
+ return Optional.empty();
+ }
+
+ public static Optional<PronounChoice> getPronounsFor(String platform, String name) {
+ return performPronouning(platform, name).flatMap(PronounDB::parsePronouns);
+ }
+
+ public static Optional<PronounChoice> getPronounsFor(UUID minecraftPlayer) {
+ return performPronouning("minecraft", minecraftPlayer.toString() /* dashed UUID */)
+ .flatMap(PronounDB::parsePronouns);
+ }
+
+ public static void test() {
+ try {
+ System.out.println("Pronouning...");
+ PronounChoice pronounsFor = getPronounsFor(UUID.fromString("842204e6-6880-487b-ae5a-0595394f9948")).get();
+ pronounsFor.render().forEach(System.out::println);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
index 5b3ea853..2267cbea 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
@@ -73,6 +73,7 @@ import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.math.BigInteger;
import java.nio.FloatBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@@ -81,6 +82,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
+import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -1943,9 +1945,13 @@ public class Utils {
if (NotEnoughUpdates.INSTANCE.config.notifications.outdatedRepo) {
NotificationHandler.displayNotification(Lists.newArrayList(
EnumChatFormatting.RED + EnumChatFormatting.BOLD.toString() + "Missing repo data",
- EnumChatFormatting.RED + "Data used for many NEU features is not up to date, this should normally not be the case.",
- EnumChatFormatting.RED + "You can try " + EnumChatFormatting.BOLD + "/neuresetrepo" + EnumChatFormatting.RESET + EnumChatFormatting.RED +" and restart your game" +
- " to see if that fixes the issue.", EnumChatFormatting.RED + "If the problem persists please join " + EnumChatFormatting.BOLD + "discord.gg/moulberry" +
+ EnumChatFormatting.RED +
+ "Data used for many NEU features is not up to date, this should normally not be the case.",
+ EnumChatFormatting.RED + "You can try " + EnumChatFormatting.BOLD + "/neuresetrepo" + EnumChatFormatting.RESET +
+ EnumChatFormatting.RED + " and restart your game" +
+ " to see if that fixes the issue.",
+ EnumChatFormatting.RED + "If the problem persists please join " + EnumChatFormatting.BOLD +
+ "discord.gg/moulberry" +
EnumChatFormatting.RESET + EnumChatFormatting.RED + " and message in " + EnumChatFormatting.BOLD +
"#neu-support" + EnumChatFormatting.RESET + EnumChatFormatting.RED + " to get support"
),
@@ -1979,6 +1985,13 @@ public class Utils {
return -1;
}
+ public static UUID parseDashlessUUID(String dashlessUuid) {
+ // From: https://stackoverflow.com/a/30760478/
+ BigInteger most = new BigInteger(dashlessUuid.substring(0, 16), 16);
+ BigInteger least = new BigInteger(dashlessUuid.substring(16, 32), 16);
+ return new UUID(most.longValue(), least.longValue());
+ }
+
public static String getOpenChestName() {
return SBInfo.getInstance().currentlyOpenChestName;
}