diff options
| author | Roman / Linnea Gräf <roman.graef@gmail.com> | 2022-08-26 13:24:35 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-26 21:24:35 +1000 |
| commit | dfd2f6b05bce74d7feb5d28e7a388dbb871ecf6a (patch) | |
| tree | 001913c4f1dd391831da26e4398f75e6731c88e1 /src/main/java/io/github/moulberry/notenoughupdates/util | |
| parent | c3845685bbb3a2a7fde25476eed0f788e038dc93 (diff) | |
| download | notenoughupdates-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')
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; } |
