diff --git a/build.gradle.kts b/build.gradle.kts index f6449dc..258076f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,78 +13,87 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import dev.architectury.pack200.java.Pack200Adapter - plugins { id("java") - alias(libs.plugins.ggEssentialLoom) alias(libs.plugins.spotless) + alias(libs.plugins.ggEssentialLoom) apply false } -val modId = providers.gradleProperty("mod_id") -val versionText = providers.gradleProperty("mod_version") -val mavenGroup = providers.gradleProperty("maven_group") +val groupTextProvider = providers.gradleProperty("maven_group") +val versionTextProvider = providers.gradleProperty("mod_version") +val modIdProvider = providers.gradleProperty("mod_id") -version = versionText.get() -group = mavenGroup.get() +allprojects { + group = groupTextProvider.get() + version = versionTextProvider.get() -base { - archivesName.set(modId) + repositories { + mavenCentral() + } } -repositories { - mavenCentral() -} +subprojects { + apply(plugin = "java") + apply(plugin = rootProject.libs.plugins.spotless.get().pluginId) -dependencies { - minecraft(libs.minecraft) - mappings(libs.mcpMappings) - forge(libs.forge) -} - -loom { - forge { - pack200Provider.set(Pack200Adapter()) - // accessTransformer("src/main/resources/META-INF/${modId.get()}_at.cfg") + val computedVersion = if (path.startsWith(":versions:")) { + "${versionTextProvider.get()}+$name" + } else { + versionTextProvider.get() } -} -java { - toolchain.languageVersion.set(JavaLanguageVersion.of(8)) -} + version = computedVersion -tasks { - withType { - options.encoding = Charsets.UTF_8.name() + extra["versionText"] = computedVersion + extra["modIdText"] = modIdProvider.get() + + base { + archivesName.set(modIdProvider.get()) } - withType { - // https://github.com/gradle/gradle/issues/861 - inputs.property("version", versionText.get()) - inputs.property("mc_version", libs.versions.minecraft.get()) - inputs.property("mod_id", modId.get()) - - filesMatching("mcmod.info") { - expand( - mapOf( - "version" to versionText.get(), - "mc_version" to libs.versions.minecraft.get(), - "mod_id" to modId.get() - ) - ) - } + project(":versions").childProjects.values.forEach { versionProject -> + versionProject.apply(plugin = rootProject.libs.plugins.ggEssentialLoom.get().pluginId) } - jar { - from(layout.projectDirectory) { - include("LICENSE", "NOTICE") + java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(8)) } } -} -sourceSets { - main { - output.setResourcesDir(java.classesDirectory) + tasks { + withType { + options.encoding = Charsets.UTF_8.name() + } + + withType { + from(rootProject.layout.projectDirectory) { + include("LICENSE", "NOTICE") + } + + manifest { + attributes( + "Specification-Title" to rootProject.name, + "Specification-Version" to versionTextProvider.get(), + "Implementation-Title" to rootProject.name, + "Implementation-Version" to versionTextProvider.get() + ) + } + + plugins.withId(rootProject.libs.plugins.ggEssentialLoom.get().pluginId) { + val remapJarTask = named("remapJar") + + register("copyRemappedJars") { + dependsOn(remapJarTask) + from(remapJarTask.map { it.outputs.files }) + into(rootProject.layout.buildDirectory.dir("libs")) + } + + named("build") { + finalizedBy("copyRemappedJars") + } + } + } } } @@ -103,3 +112,9 @@ spotless { trimTrailingWhitespace() } } + +tasks { + named("jar").configure { + enabled = false + } +} diff --git a/common/build.gradle.kts b/common/build.gradle.kts new file mode 100644 index 0000000..72e971a --- /dev/null +++ b/common/build.gradle.kts @@ -0,0 +1,13 @@ +import org.gradle.kotlin.dsl.libs + +base { + archivesName.set("common") +} + +@Suppress("VulnerableLibrariesLocal") // some libs need to stay at the game versions +dependencies { + compileOnly(rootProject.libs.jetbrainsJavaAnnotations) + compileOnly(rootProject.libs.gson) + compileOnly(rootProject.libs.log4j) + compileOnly(rootProject.libs.guava) +} diff --git a/common/src/main/java/io/github/communityradargg/forgemod/command/CheckSubcommand.java b/common/src/main/java/io/github/communityradargg/forgemod/command/CheckSubcommand.java new file mode 100644 index 0000000..e2c72b8 --- /dev/null +++ b/common/src/main/java/io/github/communityradargg/forgemod/command/CheckSubcommand.java @@ -0,0 +1,134 @@ +/* + * Copyright 2024 - present CommunityRadarGG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.communityradargg.forgemod.command; + +import io.github.communityradargg.forgemod.list.RadarListEntry; +import io.github.communityradargg.forgemod.util.CommonHandler; +import io.github.communityradargg.forgemod.util.Messages; +import io.github.communityradargg.forgemod.util.PlayerInfo; +import io.github.communityradargg.forgemod.util.RadarMessage; +import java.util.Optional; +import org.jetbrains.annotations.NotNull; + +/** + * Holds the logic of the check subcommand. + */ +public class CheckSubcommand implements Subcommand { + private final CommonHandler commonHandler; + private final String[] args; + + /** + * Constructs a {@link CheckSubcommand}. + * + * @param commonHandler The common handler. + * @param args The args. + */ + public CheckSubcommand(final @NotNull CommonHandler commonHandler, final @NotNull String[] args) { + this.commonHandler = commonHandler; + this.args = args; + } + + @Override + public void run() { + if (args.length != 2) { + // missing arguments + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) + .build().getMessage()); + return; + } + + if (args[1].equalsIgnoreCase("*")) { + // check all argument + handleCheckAllSubcommand(); + return; + } + handleCheckPlayerSubcommand(args); + } + + /** + * Handles the check - player subcommand. + * + * @param args The arguments passed to the main command. + */ + private void handleCheckPlayerSubcommand(final @NotNull String[] args) { + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.INPUT_PROCESSING) + .build().getMessage()); + commonHandler.getUuidByPlayerName(commonHandler, args[1]).thenAccept(checkPlayerOptional -> { + if (!checkPlayerOptional.isPresent()) { + // player uuid could not be fetched + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.Check.FAILED) + .build().getMessage()); + return; + } + + final Optional entryOptional = commonHandler.getListManager().getRadarListEntry(checkPlayerOptional.get()); + if (!entryOptional.isPresent()) { + // player uuid is on no list + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.Check.FAILED) + .build().getMessage()); + return; + } + + final RadarListEntry entry = entryOptional.get(); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.Check.FOUND + "\n" + Messages.Check.CHECK_ENTRY) + .replaceWithColorCodes("{prefix}", commonHandler.getListManager().getPrefix(entry.uuid())) + .replace("{name}", entry.name()) + .replace("{cause}", entry.cause()) + .replace("{entryCreationDate}", commonHandler.formatDateTime(entry.entryCreationDate())) + .replace("{entryUpdateDate}", commonHandler.formatDateTime(entry.entryUpdateDate())) + .build().getMessage()); + }); + } + + /** + * Handles the check - all subcommand. + */ + private void handleCheckAllSubcommand() { + boolean anyPlayerFound = false; + for (final PlayerInfo playerInfo : commonHandler.getWorldPlayers()) { + if (playerInfo.getUuid() == null) { + continue; + } + + final Optional listEntryOptional = commonHandler.getListManager() + .getRadarListEntry(playerInfo.getUuid()); + if (!listEntryOptional.isPresent()) { + // player uuid is on no list + continue; + } + + if (!anyPlayerFound) { + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.Check.EVERYONE) + .build().getMessage()); + anyPlayerFound = true; + } + + final RadarListEntry entry = listEntryOptional.get(); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.Check.CHECK_ENTRY) + .replaceWithColorCodes("{prefix}", commonHandler.getListManager().getPrefix(entry.uuid())) + .replace("{name}", entry.name()) + .replace("{cause}", entry.cause()) + .replace("{entryCreationDate}", commonHandler.formatDateTime(entry.entryCreationDate())) + .replace("{entryUpdateDate}", commonHandler.formatDateTime(entry.entryUpdateDate())) + .build().getMessage()); + } + + if (!anyPlayerFound) { + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.Check.NOT_FOUND) + .build().getMessage()); + } + } +} diff --git a/src/main/java/io/github/communityradargg/forgemod/command/HelpSubcommand.java b/common/src/main/java/io/github/communityradargg/forgemod/command/HelpSubcommand.java similarity index 62% rename from src/main/java/io/github/communityradargg/forgemod/command/HelpSubcommand.java rename to common/src/main/java/io/github/communityradargg/forgemod/command/HelpSubcommand.java index d697516..79b0f13 100644 --- a/src/main/java/io/github/communityradargg/forgemod/command/HelpSubcommand.java +++ b/common/src/main/java/io/github/communityradargg/forgemod/command/HelpSubcommand.java @@ -15,35 +15,31 @@ */ package io.github.communityradargg.forgemod.command; -import io.github.communityradargg.forgemod.CommunityRadarMod; +import io.github.communityradargg.forgemod.util.CommonHandler; import io.github.communityradargg.forgemod.util.Messages; import io.github.communityradargg.forgemod.util.RadarMessage; -import net.minecraft.entity.player.EntityPlayer; import org.jetbrains.annotations.NotNull; /** * Holds the logic of the help subcommand. */ public class HelpSubcommand implements Subcommand { - private final CommunityRadarMod communityRadarMod; - private final EntityPlayer player; + private final CommonHandler commonHandler; /** * Constructs a {@link HelpSubcommand}. * - * @param communityRadarMod The mod main class instance. - * @param player The player. + * @param commonHandler The common handler */ - public HelpSubcommand(final @NotNull CommunityRadarMod communityRadarMod, final @NotNull EntityPlayer player) { - this.communityRadarMod = communityRadarMod; - this.player = player; + public HelpSubcommand(final @NotNull CommonHandler commonHandler) { + this.commonHandler = commonHandler; } @Override public void run() { - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.HELP) - .replace("{code_version}", communityRadarMod.getVersion()) + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.HELP) + .replace("{code_version}", commonHandler.getVersion()) .excludePrefix() - .build().toChatComponentText()); + .build().getMessage()); } } diff --git a/src/main/java/io/github/communityradargg/forgemod/command/ListSubcommand.java b/common/src/main/java/io/github/communityradargg/forgemod/command/ListSubcommand.java similarity index 54% rename from src/main/java/io/github/communityradargg/forgemod/command/ListSubcommand.java rename to common/src/main/java/io/github/communityradargg/forgemod/command/ListSubcommand.java index da5cf47..3e3c1da 100644 --- a/src/main/java/io/github/communityradargg/forgemod/command/ListSubcommand.java +++ b/common/src/main/java/io/github/communityradargg/forgemod/command/ListSubcommand.java @@ -15,13 +15,11 @@ */ package io.github.communityradargg.forgemod.command; -import io.github.communityradargg.forgemod.CommunityRadarMod; -import io.github.communityradargg.forgemod.radarlistmanager.RadarList; -import io.github.communityradargg.forgemod.radarlistmanager.RadarListManager; +import io.github.communityradargg.forgemod.list.ListManager; +import io.github.communityradargg.forgemod.list.RadarList; +import io.github.communityradargg.forgemod.util.CommonHandler; import io.github.communityradargg.forgemod.util.Messages; import io.github.communityradargg.forgemod.util.RadarMessage; -import io.github.communityradargg.forgemod.util.Utils; -import net.minecraft.entity.player.EntityPlayer; import org.jetbrains.annotations.NotNull; import java.util.Collections; import java.util.Locale; @@ -33,20 +31,17 @@ * Holds the logic of the list subcommand. */ public class ListSubcommand implements Subcommand { - private final CommunityRadarMod communityRadarMod; - private final EntityPlayer player; + private final CommonHandler commonHandler; private final String[] args; /** * Constructs a {@link ListSubcommand}. * - * @param communityRadarMod The mod main class instance. - * @param player The player. + * @param commonHandler The common handler. * @param args The args. */ - public ListSubcommand(final @NotNull CommunityRadarMod communityRadarMod, final @NotNull EntityPlayer player, final @NotNull String[] args) { - this.communityRadarMod = communityRadarMod; - this.player = player; + public ListSubcommand(final @NotNull CommonHandler commonHandler, final @NotNull String[] args) { + this.commonHandler = commonHandler; this.args = args; } @@ -54,26 +49,26 @@ public ListSubcommand(final @NotNull CommunityRadarMod communityRadarMod, final public void run() { if (args.length < 2) { // missing arguments - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) + .build().getMessage()); return; } switch (args[1].toUpperCase(Locale.ENGLISH)) { case "ADD": - handleListAddSubcommand(player, args); + handleListAddSubcommand(args); break; case "PREFIX": - handleListPrefixSubcommand(player, args); + handleListPrefixSubcommand(args); break; case "DELETE": - handleListDeleteSubcommand(player, args); + handleListDeleteSubcommand(args); break; case "SHOW": - handleListShowSubcommand(player, args); + handleListShowSubcommand(args); break; default: - new HelpSubcommand(communityRadarMod, player).run(); + new HelpSubcommand(commonHandler).run(); break; } } @@ -81,50 +76,48 @@ public void run() { /** * Handles the list - add subcommand. * - * @param player The player, which executed the subcommand. * @param args The arguments passed to the main command. */ - private void handleListAddSubcommand(final @NotNull EntityPlayer player, final @NotNull String[] args) { + private void handleListAddSubcommand(final @NotNull String[] args) { if (args.length != 4) { // missing arguments - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) + .build().getMessage()); return; } - if (communityRadarMod.getListManager().getRadarList(args[2]).isPresent()) { + if (commonHandler.getListManager().getRadarList(args[2]).isPresent()) { // list already existing - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.List.CREATE_FAILED) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.List.CREATE_FAILED) + .build().getMessage()); return; } - if (!communityRadarMod.getListManager().registerPrivateList(args[2], args[3])) { + if (!commonHandler.getListManager().registerPrivateList(args[2], args[3])) { // list could not be registered - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.List.CREATE_FAILED) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.List.CREATE_FAILED) + .build().getMessage()); return; } - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.List.CREATE_SUCCESS) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.List.CREATE_SUCCESS) + .build().getMessage()); } /** * Handles the list - delete subcommand. * - * @param player The player, which executed the subcommand. * @param args The arguments passed to the main command. */ - private void handleListDeleteSubcommand(final @NotNull EntityPlayer player, final @NotNull String[] args) { + private void handleListDeleteSubcommand(final @NotNull String[] args) { if (args.length != 3) { // missing arguments - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) + .build().getMessage()); return; } - final RadarListManager listManager = communityRadarMod.getListManager(); + final ListManager listManager = commonHandler.getListManager(); final Set oldPrefixes = listManager.getExistingPrefixes(); final Set oldUuids = listManager.getRadarList(args[2]) .map(radarList -> radarList.getPlayerMap().keySet()) @@ -132,75 +125,73 @@ private void handleListDeleteSubcommand(final @NotNull EntityPlayer player, fina if (!listManager.unregisterList(args[2])) { // list is not existing, list is not private, file cannot be deleted - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.List.DELETE_FAILED) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.List.DELETE_FAILED) + .build().getMessage()); return; } - oldUuids.forEach(uuid -> Utils.updatePlayerByUuid(communityRadarMod, uuid, oldPrefixes)); - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.List.DELETE_SUCCESS) - .build().toChatComponentText()); + oldUuids.forEach(uuid -> commonHandler.updatePlayerByUuid(uuid, oldPrefixes)); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.List.DELETE_SUCCESS) + .build().getMessage()); } /** * Handles the list - show subcommand. * - * @param player The player, which executed the subcommand. * @param args The arguments passed to the main command. */ - private void handleListShowSubcommand(final @NotNull EntityPlayer player, final @NotNull String[] args) { + private void handleListShowSubcommand(final @NotNull String[] args) { if (args.length != 3) { // missing arguments - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) + .build().getMessage()); return; } - final Optional listOptional = communityRadarMod.getListManager().getRadarList(args[2]); + final Optional listOptional = commonHandler.getListManager().getRadarList(args[2]); if (!listOptional.isPresent()) { // list is not existing - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.List.SHOW_FAILED) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.List.SHOW_FAILED) + .build().getMessage()); return; } final RadarList list = listOptional.get(); if (list.getPlayerMap().isEmpty()) { // list is empty - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.List.SHOW_EMPTY) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.List.SHOW_EMPTY) + .build().getMessage()); return; } final StringBuilder players = new StringBuilder(); list.getPlayerMap().values().forEach(value -> players.append(value.name()).append(", ")); - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.List.SHOW_SUCCESS) + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.List.SHOW_SUCCESS) .replace("{list}", list.getNamespace()) .replaceWithColorCodes("{prefix}", listOptional.get().getPrefix()) .replace("{players}", players.substring(0, players.length() - 2)) - .build().toChatComponentText()); + .build().getMessage()); } /** * Handles the list - prefix subcommand. * - * @param player The player, which executed the subcommand. * @param args The arguments passed to the main command. */ - private void handleListPrefixSubcommand(final @NotNull EntityPlayer player, final @NotNull String[] args) { + private void handleListPrefixSubcommand(final @NotNull String[] args) { if (args.length != 4) { // missing arguments - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) + .build().getMessage()); return; } - final RadarListManager listManager = communityRadarMod.getListManager(); + final ListManager listManager = commonHandler.getListManager(); final Optional listOptional = listManager.getRadarList(args[2]); if (!listOptional.isPresent()) { // list is not existing - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.List.PREFIX_FAILED) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.List.PREFIX_FAILED) + .build().getMessage()); return; } @@ -208,10 +199,10 @@ private void handleListPrefixSubcommand(final @NotNull EntityPlayer player, fina final Set oldPrefixes = listManager.getExistingPrefixes(); list.setPrefix(args[3]); list.saveList(); - list.getPlayerMap().keySet().forEach(uuid -> Utils.updatePlayerByUuid(communityRadarMod, uuid, oldPrefixes)); + list.getPlayerMap().keySet().forEach(uuid -> commonHandler.updatePlayerByUuid(uuid, oldPrefixes)); - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.List.PREFIX_SUCCESS) + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.List.PREFIX_SUCCESS) .replaceWithColorCodes("{prefix}", args[3]) - .build().toChatComponentText()); + .build().getMessage()); } } diff --git a/src/main/java/io/github/communityradargg/forgemod/command/ListsSubcommand.java b/common/src/main/java/io/github/communityradargg/forgemod/command/ListsSubcommand.java similarity index 64% rename from src/main/java/io/github/communityradargg/forgemod/command/ListsSubcommand.java rename to common/src/main/java/io/github/communityradargg/forgemod/command/ListsSubcommand.java index 6ecb7a7..9bfe5cd 100644 --- a/src/main/java/io/github/communityradargg/forgemod/command/ListsSubcommand.java +++ b/common/src/main/java/io/github/communityradargg/forgemod/command/ListsSubcommand.java @@ -15,36 +15,32 @@ */ package io.github.communityradargg.forgemod.command; -import io.github.communityradargg.forgemod.CommunityRadarMod; -import io.github.communityradargg.forgemod.radarlistmanager.RadarListVisibility; +import io.github.communityradargg.forgemod.list.RadarListVisibility; +import io.github.communityradargg.forgemod.util.CommonHandler; import io.github.communityradargg.forgemod.util.Messages; import io.github.communityradargg.forgemod.util.RadarMessage; -import net.minecraft.entity.player.EntityPlayer; import org.jetbrains.annotations.NotNull; /** * Holds the logic of the lists subcommand. */ public class ListsSubcommand implements Subcommand { - private final CommunityRadarMod communityRadarMod; - private final EntityPlayer player; + private final CommonHandler commonHandler; /** * Constructs a {@link ListsSubcommand}. * - * @param communityRadarMod The mod main class instance. - * @param player The player. + * @param commonHandler The common handler. */ - public ListsSubcommand(final @NotNull CommunityRadarMod communityRadarMod, final @NotNull EntityPlayer player) { - this.communityRadarMod = communityRadarMod; - this.player = player; + public ListsSubcommand(final @NotNull CommonHandler commonHandler) { + this.commonHandler = commonHandler; } @Override public void run() { final StringBuilder listsText = new StringBuilder(); - for (final String namespace : communityRadarMod.getListManager().getNamespaces()) { - communityRadarMod.getListManager().getRadarList(namespace) + for (final String namespace : commonHandler.getListManager().getNamespaces()) { + commonHandler.getListManager().getRadarList(namespace) .ifPresent(radarList -> listsText.append("§e").append(namespace).append(" §7(§c") .append(radarList.getRadarListVisibility() == RadarListVisibility.PRIVATE ? Messages.Lists.PRIVATE : Messages.Lists.PUBLIC) .append("§7)").append(", ")); @@ -52,13 +48,13 @@ public void run() { if (listsText.length() > 0) { // players on the list - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.Lists.FOUND) + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.Lists.FOUND) .replace("{lists}", listsText.substring(0, listsText.length() - 2)) - .build().toChatComponentText()); + .build().getMessage()); } else { // list is empty - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.Lists.EMPTY) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.Lists.EMPTY) + .build().getMessage()); } } } diff --git a/src/main/java/io/github/communityradargg/forgemod/command/PlayerSubcommand.java b/common/src/main/java/io/github/communityradargg/forgemod/command/PlayerSubcommand.java similarity index 53% rename from src/main/java/io/github/communityradargg/forgemod/command/PlayerSubcommand.java rename to common/src/main/java/io/github/communityradargg/forgemod/command/PlayerSubcommand.java index e621150..becb0d5 100644 --- a/src/main/java/io/github/communityradargg/forgemod/command/PlayerSubcommand.java +++ b/common/src/main/java/io/github/communityradargg/forgemod/command/PlayerSubcommand.java @@ -15,13 +15,11 @@ */ package io.github.communityradargg.forgemod.command; -import io.github.communityradargg.forgemod.CommunityRadarMod; -import io.github.communityradargg.forgemod.radarlistmanager.RadarList; -import io.github.communityradargg.forgemod.radarlistmanager.RadarListManager; +import io.github.communityradargg.forgemod.list.ListManager; +import io.github.communityradargg.forgemod.list.RadarList; +import io.github.communityradargg.forgemod.util.CommonHandler; import io.github.communityradargg.forgemod.util.Messages; import io.github.communityradargg.forgemod.util.RadarMessage; -import io.github.communityradargg.forgemod.util.Utils; -import net.minecraft.entity.player.EntityPlayer; import org.jetbrains.annotations.NotNull; import java.util.Locale; import java.util.Optional; @@ -31,20 +29,17 @@ * Holds the logic of the player subcommand. */ public class PlayerSubcommand implements Subcommand { - private final CommunityRadarMod communityRadarMod; - private final EntityPlayer player; + private final CommonHandler commonHandler; private final String[] args; /** * Constructs a {@link PlayerSubcommand}. * - * @param communityRadarMod The mod main class instance. - * @param player The player. + * @param commonHandler The common handler. * @param args The args. */ - public PlayerSubcommand(final @NotNull CommunityRadarMod communityRadarMod, final @NotNull EntityPlayer player, final @NotNull String[] args) { - this.communityRadarMod = communityRadarMod; - this.player = player; + public PlayerSubcommand(final @NotNull CommonHandler commonHandler, final @NotNull String[] args) { + this.commonHandler = commonHandler; this.args = args; } @@ -52,20 +47,20 @@ public PlayerSubcommand(final @NotNull CommunityRadarMod communityRadarMod, fina public void run() { if (args.length < 2) { // missing arguments - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) + .build().getMessage()); return; } switch (args[1].toUpperCase(Locale.ENGLISH)) { case "ADD": - handlePlayerAddSubcommand(player, args); + handlePlayerAddSubcommand(args); break; case "REMOVE": - handlePlayerRemoveSubcommand(player, args); + handlePlayerRemoveSubcommand(args); break; default: - new HelpSubcommand(communityRadarMod, player).run(); + new HelpSubcommand(commonHandler).run(); break; } } @@ -73,41 +68,40 @@ public void run() { /** * Handles the player - add subcommand. * - * @param player The player, which executed the subcommand. * @param args The arguments passed to the main command. */ - private void handlePlayerAddSubcommand(final @NotNull EntityPlayer player, final @NotNull String[] args) { + private void handlePlayerAddSubcommand(final @NotNull String[] args) { if (args.length < 5) { // missing arguments - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) + .build().getMessage()); return; } - final RadarListManager listManager = communityRadarMod.getListManager(); + final ListManager listManager = commonHandler.getListManager(); final Optional listOptional = listManager.getRadarList(args[2]); if (!listOptional.isPresent()) { // list not existing - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.Player.ADD_FAILED) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.Player.ADD_FAILED) + .build().getMessage()); return; } - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.INPUT_PROCESSING) - .build().toChatComponentText()); - Utils.getUUID(communityRadarMod, args[3]).thenAccept(uuidOptional -> { + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.INPUT_PROCESSING) + .build().getMessage()); + commonHandler.getUuidByPlayerName(commonHandler, args[3]).thenAccept(uuidOptional -> { if (!uuidOptional.isPresent()) { // player uuid could not be fetched - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(args[3].startsWith("!") ? Messages.Player.NAME_INVALID_BEDROCK : Messages.Player.NAME_INVALID) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(args[3].startsWith("!") ? Messages.Player.NAME_INVALID_BEDROCK : Messages.Player.NAME_INVALID) + .build().getMessage()); return; } final UUID uuid = uuidOptional.get(); if (listOptional.get().isInList(uuid)) { // player already on list - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.Player.ADD_IN_LIST) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.Player.ADD_IN_LIST) + .build().getMessage()); return; } @@ -116,65 +110,64 @@ private void handlePlayerAddSubcommand(final @NotNull EntityPlayer player, final notes.append(args[i]).append(" "); } - if (!communityRadarMod.getListManager().addRadarListEntry(args[2], uuid, args[3], notes.substring(0, notes.length() - 1))) { + if (!commonHandler.getListManager().addRadarListEntry(args[2], uuid, args[3], notes.substring(0, notes.length() - 1))) { // list is not private - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.Player.ADD_FAILED) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.Player.ADD_FAILED) + .build().getMessage()); return; } - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.Player.ADD_SUCCESS) - .build().toChatComponentText()); - Utils.updatePlayerByUuid(communityRadarMod, uuid, listManager.getExistingPrefixes()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.Player.ADD_SUCCESS) + .build().getMessage()); + commonHandler.updatePlayerByUuid(uuid, listManager.getExistingPrefixes()); }); } /** * Handles the player - remove subcommand. * - * @param player The player, which executed the subcommand. * @param args The arguments passed to the main command. */ - private void handlePlayerRemoveSubcommand(final @NotNull EntityPlayer player, final @NotNull String[] args) { + private void handlePlayerRemoveSubcommand(final @NotNull String[] args) { if (args.length != 4) { // missing arguments - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) + .build().getMessage()); return; } - final RadarListManager listManager = communityRadarMod.getListManager(); + final ListManager listManager = commonHandler.getListManager(); final Optional listOptional = listManager.getRadarList(args[2]); if (!listOptional.isPresent()) { // list is not existing - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.Player.REMOVE_FAILED) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.Player.REMOVE_FAILED) + .build().getMessage()); return; } - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.INPUT_PROCESSING) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.INPUT_PROCESSING) + .build().getMessage()); final RadarList list = listOptional.get(); - Utils.getUUID(communityRadarMod, args[3]).thenAccept(uuidOptional -> { + commonHandler.getUuidByPlayerName(commonHandler, args[3]).thenAccept(uuidOptional -> { if (!uuidOptional.isPresent()) { // player uuid could not be fetched - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(args[3].startsWith("!") ? Messages.Player.NAME_INVALID_BEDROCK : Messages.Player.NAME_INVALID) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(args[3].startsWith("!") ? Messages.Player.NAME_INVALID_BEDROCK : Messages.Player.NAME_INVALID) + .build().getMessage()); return; } final UUID uuid = uuidOptional.get(); if (!list.isInList(uuid)) { // player uuid not on list - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.Player.REMOVE_NOT_IN_LIST) - .build().toChatComponentText()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.Player.REMOVE_NOT_IN_LIST) + .build().getMessage()); return; } list.getPlayerMap().remove(uuid); - Utils.updatePlayerByUuid(communityRadarMod, uuid, listManager.getExistingPrefixes()); - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.Player.REMOVE_SUCCESS) - .build().toChatComponentText()); + commonHandler.updatePlayerByUuid(uuid, listManager.getExistingPrefixes()); + commonHandler.addMessageToChat(new RadarMessage.RadarMessageBuilder(Messages.Player.REMOVE_SUCCESS) + .build().getMessage()); }); } } diff --git a/common/src/main/java/io/github/communityradargg/forgemod/command/RootRadarCommand.java b/common/src/main/java/io/github/communityradargg/forgemod/command/RootRadarCommand.java new file mode 100644 index 0000000..3c986d8 --- /dev/null +++ b/common/src/main/java/io/github/communityradargg/forgemod/command/RootRadarCommand.java @@ -0,0 +1,59 @@ +package io.github.communityradargg.forgemod.command; + +import io.github.communityradargg.forgemod.util.CommonHandler; +import org.jetbrains.annotations.NotNull; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; + +/** + * The root radar command. + */ +public class RootRadarCommand { + public static final String COMMAND_NAME = "radar"; + public static final List COMMAND_ALIASES = Arrays.asList("communityradar", "scammer", "trustedmm", "mm"); + private final CommonHandler commonHandler; + + /** + * Constructs as {@link RootRadarCommand}. + * + * @param commonHandler The common handler. + */ + public RootRadarCommand(final @NotNull CommonHandler commonHandler) { + this.commonHandler = commonHandler; + } + + /** + * Executes the root command with the given arguments. + * + * @param args The arguments. + */ + public void execute(final String[] args) { + Subcommand subcommand = null; + if (args.length == 0) { + subcommand = new HelpSubcommand(commonHandler); + } + + if (subcommand == null) { + switch (args[0].toUpperCase(Locale.ENGLISH)) { + case "CHECK": + subcommand = new CheckSubcommand(commonHandler, args); + break; + case "LIST": + subcommand = new ListSubcommand(commonHandler, args); + break; + case "PLAYER": + subcommand = new PlayerSubcommand(commonHandler, args); + break; + case "LISTS": + subcommand = new ListsSubcommand(commonHandler); + break; + default: + subcommand = new HelpSubcommand(commonHandler); + break; + } + } + + subcommand.run(); + } +} diff --git a/src/main/java/io/github/communityradargg/forgemod/command/Subcommand.java b/common/src/main/java/io/github/communityradargg/forgemod/command/Subcommand.java similarity index 100% rename from src/main/java/io/github/communityradargg/forgemod/command/Subcommand.java rename to common/src/main/java/io/github/communityradargg/forgemod/command/Subcommand.java diff --git a/src/main/java/io/github/communityradargg/forgemod/radarlistmanager/RadarListManager.java b/common/src/main/java/io/github/communityradargg/forgemod/list/ListManager.java similarity index 86% rename from src/main/java/io/github/communityradargg/forgemod/radarlistmanager/RadarListManager.java rename to common/src/main/java/io/github/communityradargg/forgemod/list/ListManager.java index 233b216..c6ae2b0 100644 --- a/src/main/java/io/github/communityradargg/forgemod/radarlistmanager/RadarListManager.java +++ b/common/src/main/java/io/github/communityradargg/forgemod/list/ListManager.java @@ -13,21 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.github.communityradargg.forgemod.radarlistmanager; +package io.github.communityradargg.forgemod.list; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonIOException; import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; -import io.github.communityradargg.forgemod.CommunityRadarMod; -import io.github.communityradargg.forgemod.radarlistmanager.adapters.GsonLocalDateTimeAdapter; -import io.github.communityradargg.forgemod.radarlistmanager.adapters.GsonRadarListPlayerMapAdapter; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - +import io.github.communityradargg.forgemod.list.adapters.GsonLocalDateTimeAdapter; +import io.github.communityradargg.forgemod.list.adapters.GsonRadarListPlayerMapAdapter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; @@ -45,31 +39,53 @@ import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; +import io.github.communityradargg.forgemod.util.CommonHandler; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * A class containing the methods to manage lists. */ -public class RadarListManager { - private static final Logger LOGGER = LogManager.getLogger(RadarListManager.class); - private static final Gson GSON = new GsonBuilder() +public class ListManager { + private static final Logger LOGGER = LogManager.getLogger(ListManager.class); + protected static final Gson GSON = new GsonBuilder() .setPrettyPrinting() .registerTypeAdapter(LocalDateTime.class, new GsonLocalDateTimeAdapter()) .registerTypeAdapter(Map.class, new GsonRadarListPlayerMapAdapter()) .create(); - private final CommunityRadarMod communityRadarMod; + private final CommonHandler commonHandler; private final List lists; private final String directoryPath; /** - * Constructs a {@link RadarListManager} + * Constructs a {@link ListManager} * - * @param communityRadarMod The mod main class instance. - * @param directoryPath The directory path of the list the manager manages. + * @param commonHandler The common handler. */ - public RadarListManager(final @NotNull CommunityRadarMod communityRadarMod, final @NotNull String directoryPath) { + public ListManager(final @NotNull CommonHandler commonHandler) { this.lists = new ArrayList<>(); - this.communityRadarMod = communityRadarMod; - this.directoryPath = directoryPath; + this.commonHandler = commonHandler; + + directoryPath = createDirectoryPath(); + } + + /** + * Creates the list directory path. + * + * @return Returns the list directory path. + */ + private String createDirectoryPath() { + final File directoryFilePath = Paths.get(new File("") + .getAbsolutePath(), "communityradar", "lists") + .toFile(); + + if (!directoryFilePath.exists() && !directoryFilePath.mkdirs()) { + LOGGER.error("Could not create directory: {}", directoryPath); + } + + return directoryFilePath.getAbsolutePath() + "/"; } /** @@ -193,7 +209,7 @@ public boolean registerPrivateList(final @NotNull String namespace, final @NotNu return false; } - lists.add(new RadarList(communityRadarMod, namespace, prefix, directoryPath + namespace + ".json", RadarListVisibility.PRIVATE)); + lists.add(new RadarList(commonHandler, namespace, prefix, directoryPath + namespace + ".json", RadarListVisibility.PRIVATE)); final Optional listOptional = getRadarList(namespace); if (!listOptional.isPresent()) { @@ -219,7 +235,7 @@ public boolean registerPublicList(final @NotNull String namespace, final @NotNul return false; } - lists.add(new RadarList(communityRadarMod, namespace, prefix, url, RadarListVisibility.PUBLIC)); + lists.add(new RadarList(commonHandler, namespace, prefix, url, RadarListVisibility.PUBLIC)); return true; } @@ -278,6 +294,7 @@ public void loadPrivateLists() { private @NotNull Optional loadRadarListFromFile(final @NotNull String filePath) { try (final FileReader reader = new FileReader(filePath)) { final RadarList list = GSON.fromJson(reader, new TypeToken() {}.getType()); + list.setCommonHandler(commonHandler); list.setUrl(filePath); if (list.validateList()) { return Optional.of(list); @@ -307,15 +324,6 @@ public void loadPrivateLists() { return new HashSet<>(); } - /** - * Gets the {@link Gson} instance with project relevant settings. - * - * @return Returns the pre-configured {@link Gson} instance. - */ - public static @NotNull Gson getGson() { - return GSON; - } - /** * Gets all existing prefixes. * diff --git a/src/main/java/io/github/communityradargg/forgemod/radarlistmanager/RadarList.java b/common/src/main/java/io/github/communityradargg/forgemod/list/RadarList.java similarity index 86% rename from src/main/java/io/github/communityradargg/forgemod/radarlistmanager/RadarList.java rename to common/src/main/java/io/github/communityradargg/forgemod/list/RadarList.java index 6685429..249627d 100644 --- a/src/main/java/io/github/communityradargg/forgemod/radarlistmanager/RadarList.java +++ b/common/src/main/java/io/github/communityradargg/forgemod/list/RadarList.java @@ -13,17 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.github.communityradargg.forgemod.radarlistmanager; +package io.github.communityradargg.forgemod.list; import com.google.gson.JsonIOException; import com.google.gson.JsonSyntaxException; import com.google.gson.annotations.SerializedName; import com.google.gson.reflect.TypeToken; -import io.github.communityradargg.forgemod.CommunityRadarMod; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.NotNull; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -33,13 +28,16 @@ import java.util.Map; import java.util.Optional; import java.util.UUID; +import io.github.communityradargg.forgemod.util.CommonHandler; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; /** * A class representing a radar list. */ public class RadarList { private static final Logger LOGGER = LogManager.getLogger(RadarList.class); - private transient final CommunityRadarMod communityRadarMod; @SerializedName("VERSION") @SuppressWarnings("unused") // needed in future private final int version = 1; @@ -52,18 +50,19 @@ public class RadarList { @SerializedName("prefix") private String prefix; private transient String url; + private transient CommonHandler commonHandler; /** * Constructs a {@link RadarList}. * - * @param communityRadarMod The mod main class instance. + * @param commonHandler The common handler. * @param namespace The namespace for the list. * @param prefix The prefix for the list. * @param url The url for the list. * @param visibility The visibility of the list. */ - public RadarList(final @NotNull CommunityRadarMod communityRadarMod, final @NotNull String namespace, final @NotNull String prefix, final @NotNull String url, final @NotNull RadarListVisibility visibility) { - this.communityRadarMod = communityRadarMod; + public RadarList(final @NotNull CommonHandler commonHandler, final @NotNull String namespace, final @NotNull String prefix, final @NotNull String url, final @NotNull RadarListVisibility visibility) { + this.commonHandler = commonHandler; this.namespace = namespace; this.prefix = prefix; this.visibility = visibility; @@ -181,7 +180,7 @@ private void loadRadarListEntry(final @NotNull RadarListEntry radarListEntry) { */ public void saveList() { if (visibility == RadarListVisibility.PRIVATE) { - communityRadarMod.getListManager().saveRadarList(this); + commonHandler.getListManager().saveRadarList(this); } } @@ -190,7 +189,7 @@ public void saveList() { */ private void loadPublicList() { try (final BufferedReader reader = new BufferedReader(new InputStreamReader(new URL(this.url).openStream()))) { - final List players = RadarListManager.getGson() + final List players = ListManager.GSON .fromJson(reader, new TypeToken>() {}.getType()); players.forEach(this::loadRadarListEntry); } catch (final IOException | JsonIOException | JsonSyntaxException e) { @@ -215,4 +214,13 @@ public void load() { loadPublicList(); } } + + /** + * Sets the common handler. Only use this method in combination with for example {@link com.google.gson.Gson}. + * + * @param commonHandler The common handler. + */ + public void setCommonHandler(final @NotNull CommonHandler commonHandler) { + this.commonHandler = commonHandler; + } } diff --git a/src/main/java/io/github/communityradargg/forgemod/radarlistmanager/RadarListEntry.java b/common/src/main/java/io/github/communityradargg/forgemod/list/RadarListEntry.java similarity index 98% rename from src/main/java/io/github/communityradargg/forgemod/radarlistmanager/RadarListEntry.java rename to common/src/main/java/io/github/communityradargg/forgemod/list/RadarListEntry.java index 5732790..892bcdd 100644 --- a/src/main/java/io/github/communityradargg/forgemod/radarlistmanager/RadarListEntry.java +++ b/common/src/main/java/io/github/communityradargg/forgemod/list/RadarListEntry.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.github.communityradargg.forgemod.radarlistmanager; +package io.github.communityradargg.forgemod.list; import com.google.gson.annotations.SerializedName; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/io/github/communityradargg/forgemod/radarlistmanager/RadarListVisibility.java b/common/src/main/java/io/github/communityradargg/forgemod/list/RadarListVisibility.java similarity index 93% rename from src/main/java/io/github/communityradargg/forgemod/radarlistmanager/RadarListVisibility.java rename to common/src/main/java/io/github/communityradargg/forgemod/list/RadarListVisibility.java index b972288..0aa3c2d 100644 --- a/src/main/java/io/github/communityradargg/forgemod/radarlistmanager/RadarListVisibility.java +++ b/common/src/main/java/io/github/communityradargg/forgemod/list/RadarListVisibility.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.github.communityradargg.forgemod.radarlistmanager; +package io.github.communityradargg.forgemod.list; /** * An enum representing the visibility state of a radar list. diff --git a/src/main/java/io/github/communityradargg/forgemod/radarlistmanager/adapters/GsonLocalDateTimeAdapter.java b/common/src/main/java/io/github/communityradargg/forgemod/list/adapters/GsonLocalDateTimeAdapter.java similarity index 96% rename from src/main/java/io/github/communityradargg/forgemod/radarlistmanager/adapters/GsonLocalDateTimeAdapter.java rename to common/src/main/java/io/github/communityradargg/forgemod/list/adapters/GsonLocalDateTimeAdapter.java index 3e671ad..e8ed55d 100644 --- a/src/main/java/io/github/communityradargg/forgemod/radarlistmanager/adapters/GsonLocalDateTimeAdapter.java +++ b/common/src/main/java/io/github/communityradargg/forgemod/list/adapters/GsonLocalDateTimeAdapter.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.github.communityradargg.forgemod.radarlistmanager.adapters; +package io.github.communityradargg.forgemod.list.adapters; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; diff --git a/src/main/java/io/github/communityradargg/forgemod/radarlistmanager/adapters/GsonRadarListPlayerMapAdapter.java b/common/src/main/java/io/github/communityradargg/forgemod/list/adapters/GsonRadarListPlayerMapAdapter.java similarity index 93% rename from src/main/java/io/github/communityradargg/forgemod/radarlistmanager/adapters/GsonRadarListPlayerMapAdapter.java rename to common/src/main/java/io/github/communityradargg/forgemod/list/adapters/GsonRadarListPlayerMapAdapter.java index 877d1f4..65df13a 100644 --- a/src/main/java/io/github/communityradargg/forgemod/radarlistmanager/adapters/GsonRadarListPlayerMapAdapter.java +++ b/common/src/main/java/io/github/communityradargg/forgemod/list/adapters/GsonRadarListPlayerMapAdapter.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.github.communityradargg.forgemod.radarlistmanager.adapters; +package io.github.communityradargg.forgemod.list.adapters; import com.google.gson.JsonArray; import com.google.gson.JsonDeserializationContext; @@ -22,7 +22,7 @@ import com.google.gson.JsonParseException; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; -import io.github.communityradargg.forgemod.radarlistmanager.RadarListEntry; +import io.github.communityradargg.forgemod.list.RadarListEntry; import java.lang.reflect.Type; import java.util.HashMap; diff --git a/common/src/main/java/io/github/communityradargg/forgemod/util/CommonHandler.java b/common/src/main/java/io/github/communityradargg/forgemod/util/CommonHandler.java new file mode 100644 index 0000000..6f1a556 --- /dev/null +++ b/common/src/main/java/io/github/communityradargg/forgemod/util/CommonHandler.java @@ -0,0 +1,314 @@ +package io.github.communityradargg.forgemod.util; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import io.github.communityradargg.forgemod.list.ListManager; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.net.URL; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Locale; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.regex.Pattern; + +/** + * A class for handling many utility and central tasks and holds the version bridge. + */ +public class CommonHandler { + public static final String MOD_ID = "communityradar"; + private static final Logger LOGGER = LogManager.getLogger(MOD_ID); + private static final String MOJANG_API_NAME_TO_UUID = "https://api.mojang.com/users/profiles/minecraft/"; + private static final Pattern UUID_MOJANG_API_PATTERN = Pattern.compile("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})"); + private final DateTimeFormatter readableDateTimeFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"); + private final PlayerNameUuidCache playerNameUuidCache = new PlayerNameUuidCache(); + private final VersionBridge versionBridge; + private final ListManager listManager; + private boolean onGrieferGames = false; + + /** + * Constructs a {@link CommonHandler}. + * + * @param versionBridge A version bridge implementation + */ + public CommonHandler(final @NotNull VersionBridge versionBridge) { + this.versionBridge = versionBridge; + + listManager = new ListManager(this); + registerPublicLists(); + // Needs to be after loading public lists + listManager.loadPrivateLists(); + } + + /** + * Registers the public lists. + */ + private void registerPublicLists() { + if (!listManager.registerPublicList("scammer", "&7[&cScammer&7]", "https://lists.community-radar.de/versions/v1/scammer.json")) { + LOGGER.error("Could not register public list 'scammers'!"); + } + + if (!listManager.registerPublicList("trusted", "&7[&aTrusted&7]", "https://lists.community-radar.de/versions/v1/trusted.json")) { + LOGGER.error("Could not register public list 'verbvllert_trusted'!"); + } + } + + /** + * Checks if a given hostname is a hostname of GrieferGames. + *

+ * Following domains are taken into account: + *
+ * - griefergames.net + *
+ * - griefergames.de + *
+ * - griefergames.live + * + * @param hostName The hostname to check. + * @return Returns, whether the given hostname is one of the GrieferGames hostnames. + */ + public boolean isGrieferGamesHostName(final @NotNull String hostName) { + final String filteredHostName = Optional.of(hostName) + .filter(host -> host.endsWith(".")) + .map(host -> host.substring(0, host.length() - 1).toLowerCase(Locale.ENGLISH)) + .orElse(hostName.toLowerCase(Locale.ENGLISH)); + return filteredHostName.endsWith("griefergames.net") || filteredHostName.endsWith("griefergames.de") || filteredHostName.endsWith("griefergames.live"); + } + + /** + * Formats a given date time in a human-readable form. + * + * @param localDateTime The local date time to format. + * @return Returns the formatted date time. + */ + public @NotNull String formatDateTime(final @NotNull LocalDateTime localDateTime) { + return localDateTime.format(readableDateTimeFormatter); + } + + /** + * Gets the GrieferGames connection state. + * + * @return Returns the GrieferGames connection state. + */ + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + public boolean isOnGrieferGames() { + return onGrieferGames; + } + + /** + * Sets the GrieferGames connection state. + * + * @param onGrieferGames The GrieferGames connection state to set. + */ + public void setOnGrieferGames(final boolean onGrieferGames) { + this.onGrieferGames = onGrieferGames; + } + + /** + * Sets the GrieferGames connection state. + * + * @param isLocal The state, whether the connection is local. + * @param socketAddress The socket address. + */ + public void setOnGrieferGames(final boolean isLocal, final @Nullable SocketAddress socketAddress) { + if (isLocal) { + return; + } + + if (!(socketAddress instanceof InetSocketAddress)) { + return; + } + + final String hostname = ((InetSocketAddress) socketAddress).getHostName(); + if (isGrieferGamesHostName(hostname)) { + onGrieferGames = true; + return; + } + onGrieferGames = false; + } + + /** + * Tries to get the uuid to the player name from the world. + * + * @param commonHandler The common handler. + * @param playerName The player name to get the corresponding uuid. + * @return Returns a CompletableFuture with an optional with the player uuid. + */ + public @NotNull CompletableFuture> getUuidByPlayerName(final @NotNull CommonHandler commonHandler, final @NotNull String playerName) { + // user has to be in a world + if (versionBridge.isNotInWorld()) { + return CompletableFuture.completedFuture(Optional.empty()); + } + + // If the UUID has been cached, returning from the map. + final Optional uuidFromInitialCache = playerNameUuidCache.get(playerName); + if (uuidFromInitialCache.isPresent()) { + return CompletableFuture.completedFuture(uuidFromInitialCache); + } + + // Checking if there is a player with same name in the loaded world. If so, returning UUID from EntityPlayer. + final List playerInfos = versionBridge.getWorldPlayers(); + playerNameUuidCache.putAll(playerInfos); + + final Optional uuidFromWorldLookup = playerNameUuidCache.get(playerName); + if (uuidFromWorldLookup.isPresent()) { + return CompletableFuture.completedFuture(uuidFromWorldLookup); + } + + if (playerName.startsWith("!") || playerName.startsWith("~")) { + return CompletableFuture.completedFuture(Optional.empty()); + } + + // If no player with same name is in the world, try fetching the UUID from the Mojang-API. + return commonHandler.requestUuidForName(playerName); + } + + /** + * Requests an uuid to a player name, from the Mojang API. + * + * @param playerName The player name to get the uuid for. + * @return Returns a CompletableFuture with an optional with the requested uuid, it will be empty if an error occurred on requesting. + */ + private @NotNull CompletableFuture> requestUuidForName(final @NotNull String playerName) { + final String urlText = MOJANG_API_NAME_TO_UUID + playerName; + return CompletableFuture.supplyAsync(() -> { + HttpURLConnection connection = null; + try { + final URL url = new URL(urlText); + connection = (HttpURLConnection) url.openConnection(); + connection.setConnectTimeout(3000); + connection.setReadTimeout(3000); + connection.setRequestMethod("GET"); + connection.setRequestProperty("User-Agent", CommonHandler.MOD_ID + "/" + versionBridge.getVersion()); + + if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { + LOGGER.warn("Requesting data from '{}' resulted in following status code: {}", urlText, connection.getResponseCode()); + return Optional.empty(); + } + + try (final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + final JsonObject json = new Gson().fromJson(reader, JsonObject.class); + if (json == null || !json.has("id") || !json.has("name")) { + connection.disconnect(); + return Optional.empty(); + } + + final UUID uuid = UUID.fromString(UUID_MOJANG_API_PATTERN.matcher(json.get("id").getAsString()).replaceAll("$1-$2-$3-$4-$5")); + playerNameUuidCache.put(playerName, uuid); + connection.disconnect(); + return Optional.of(uuid); + } + } catch (final Exception e) { + if (connection != null) { + connection.disconnect(); + } + LOGGER.error("Trying to request data from '{}' resulted in an exception", urlText, e); + return Optional.empty(); + } + }); + } + + /** + * Gets the mod version. + * + * @return Returns the mod version. + */ + public @NotNull String getVersion() { + return versionBridge.getVersion(); + } + + /** + * Adds a chat message to the player chat. + * + * @param message The message. + */ + public void addMessageToChat(final @NotNull String message) { + versionBridge.addMessageToChat(message); + } + + /** + * Gets the player info data for all players in the current world. + * + * @return Returns the player info data. + */ + public @NotNull List<@NotNull PlayerInfo> getWorldPlayers() { + return versionBridge.getWorldPlayers(); + } + + /** + * Updates a player display name and name tag by its uuid. + * + * @param uuid The uuid to update the corresponding player. + * @param oldPrefixes The old prefixes. + */ + public void updatePlayerByUuid(final @NotNull UUID uuid, final @NotNull Set oldPrefixes) { + versionBridge.updatePlayerByUuid(this, uuid, oldPrefixes); + } + + /** + * Adds all world players to the player name UUID cache. + */ + public void updatePlayerNameUuidCache() { + playerNameUuidCache.putAll(versionBridge.getWorldPlayers()); + } + + /** + * Handles the key input event. + */ + public void handleKeyInputEvent() { + if (onGrieferGames && versionBridge.isPlayerListKeyPressed()) { + versionBridge.updatePrefixes(this, listManager.getExistingPrefixes()); + } + } + + /** + * Formats a prefix by replacing {@literal &} with {@literal §} and adding a space to the end. + * + * @param rawText The raw input text. + * @return Returns the formatted prefix. + */ + public String formatPrefix(final @NotNull String rawText) { + return rawText.replace("&", "§") + " "; + } + + /** + * Formats the text, wraps it into the version specific text component and gets the unformatted text from it for the possibility of comparison of texts. + * + * @param rawText The raw input text. + * @return Returns the unformatted text + */ + public String unformatPrefixForCompare(final @NotNull String rawText) { + return versionBridge.wrapAndUnformatText(formatPrefix(rawText)); + } + + /** + * Checks if the given prefix candidate is matching with any of the old prefixes. + * + * @param prefixCandidate The possible prefix candidate. + * @param oldPrefixes The old prefixes. + * @return Returns {@code true} if there is a match, else {@code false}. + */ + public boolean isPrefixMatching(final @NotNull String prefixCandidate, final @NotNull Set<@NotNull String> oldPrefixes) { + return oldPrefixes.stream().anyMatch(old -> unformatPrefixForCompare(old).equals(prefixCandidate)); + } + + /** + * Gets the list manager. + * + * @return Returns the list manager. + */ + public ListManager getListManager() { + return listManager; + } +} diff --git a/src/main/java/io/github/communityradargg/forgemod/util/Messages.java b/common/src/main/java/io/github/communityradargg/forgemod/util/Messages.java similarity index 98% rename from src/main/java/io/github/communityradargg/forgemod/util/Messages.java rename to common/src/main/java/io/github/communityradargg/forgemod/util/Messages.java index f308a60..e394947 100644 --- a/src/main/java/io/github/communityradargg/forgemod/util/Messages.java +++ b/common/src/main/java/io/github/communityradargg/forgemod/util/Messages.java @@ -21,9 +21,7 @@ public class Messages { public static final String PREFIX = "§8[§cCommunityRadar§8]§r "; public static final String MISSING_ARGS = "§cNicht genug Argumente. Gib '/radar' für den korrekten Syntax ein."; - public static final String NOT_PLAYER = "§cDieser Befehl kann nur von Spielern ausgeführt werden."; public static final String INPUT_PROCESSING = "§7Deine Eingabe wird verarbeitet. Dies kann einige Augenblicke benötigen."; - public static final String HELP = "§7§l--------- §eRadar-Hilfe §7§l---------§r\n" + "§e/radar lists §7-> Zeigt die vorhandenen Listen an.\n" + diff --git a/common/src/main/java/io/github/communityradargg/forgemod/util/PlayerInfo.java b/common/src/main/java/io/github/communityradargg/forgemod/util/PlayerInfo.java new file mode 100644 index 0000000..bf8fa0a --- /dev/null +++ b/common/src/main/java/io/github/communityradargg/forgemod/util/PlayerInfo.java @@ -0,0 +1,42 @@ +package io.github.communityradargg.forgemod.util; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.util.UUID; + +/** + * Holds the general player info. + */ +public class PlayerInfo { + private final UUID uuid; + private final String playerName; + + /** + * Constructs a {@link PlayerInfo}. + * + * @param uuid The uuid. + * @param playerName The player name. + */ + public PlayerInfo(final @Nullable UUID uuid, final @NotNull String playerName) { + this.uuid = uuid; + this.playerName = playerName; + } + + /** + * Gets the uuid. + * + * @return Returns the uuid. + */ + public @Nullable UUID getUuid() { + return uuid; + } + + /** + * Gets the player name. + * + * @return Returns the player name. + */ + public @NotNull String getPlayerName() { + return playerName; + } +} diff --git a/common/src/main/java/io/github/communityradargg/forgemod/util/PlayerNameUuidCache.java b/common/src/main/java/io/github/communityradargg/forgemod/util/PlayerNameUuidCache.java new file mode 100644 index 0000000..24939a0 --- /dev/null +++ b/common/src/main/java/io/github/communityradargg/forgemod/util/PlayerNameUuidCache.java @@ -0,0 +1,55 @@ +package io.github.communityradargg.forgemod.util; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import org.jetbrains.annotations.NotNull; +import java.util.List; +import java.util.Locale; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +/** + * Represents a cache to cache a player name to UUID mapping. + */ +@SuppressWarnings("UnstableApiUsage") +public class PlayerNameUuidCache { + private final Cache CACHE = CacheBuilder.newBuilder() + .expireAfterWrite(1, TimeUnit.DAYS) + .build(); + + /** + * Gets a UUID by a player name out of the cache. The method is case-insensitive. + * + * @param playerName The player name to lookup. + * @return Returns a Optional with the found UUID. + */ + public Optional get(final @NotNull String playerName) { + return Optional.ofNullable(CACHE.getIfPresent(playerName.toLowerCase(Locale.ENGLISH))); + } + + /** + * Puts a player name UUID mapping into the cache. + * + * @param playerName The player name. + * @param uuid The UUID. + */ + public void put(final @NotNull String playerName, final UUID uuid) { + CACHE.put(playerName.toLowerCase(Locale.ENGLISH), uuid); + } + + /** + * Puts a list of {@link PlayerInfo} into the cache. + * + * @param playerInfos The player infos to put in the cache. + */ + public void putAll(final @NotNull List<@NotNull PlayerInfo> playerInfos) { + for (final PlayerInfo playerInfo : playerInfos) { + if (playerInfo.getUuid() == null) { + continue; + } + + put(playerInfo.getPlayerName().toLowerCase(Locale.ENGLISH), playerInfo.getUuid()); + } + } +} diff --git a/src/main/java/io/github/communityradargg/forgemod/util/RadarMessage.java b/common/src/main/java/io/github/communityradargg/forgemod/util/RadarMessage.java similarity index 64% rename from src/main/java/io/github/communityradargg/forgemod/util/RadarMessage.java rename to common/src/main/java/io/github/communityradargg/forgemod/util/RadarMessage.java index de77a08..e44e05f 100644 --- a/src/main/java/io/github/communityradargg/forgemod/util/RadarMessage.java +++ b/common/src/main/java/io/github/communityradargg/forgemod/util/RadarMessage.java @@ -15,72 +15,71 @@ */ package io.github.communityradargg.forgemod.util; -import net.minecraft.util.ChatComponentText; import org.jetbrains.annotations.NotNull; /** * A class representing a message that can be shown to a player. */ public class RadarMessage { - private final String text; + private final String message; /** * Constructs a {@link RadarMessage}. * - * @param text The text for the message. + * @param message The message. * @param includePrefix Whether a prefix should be included in the message. */ - private RadarMessage(final @NotNull String text, final boolean includePrefix) { - this.text = (includePrefix ? Messages.PREFIX : "") + text; + private RadarMessage(final @NotNull String message, final boolean includePrefix) { + this.message = (includePrefix ? Messages.PREFIX : "") + message; } /** - * Converts this class instance to a {@link ChatComponentText}. + * Gets the message. * - * @return Returns the text converted to a {@link ChatComponentText}. + * @return Returns the message. */ - public @NotNull ChatComponentText toChatComponentText() { - return new ChatComponentText(this.text); + public @NotNull String getMessage() { + return message; } /** * A class that serves as a builder for the class {@link RadarMessage}. */ public static class RadarMessageBuilder { - private String text; + private String message; private boolean includePrefix; /** * Constructs a {@link RadarMessageBuilder}. * - * @param text The text for the builder. + * @param message The message for the builder. */ - public RadarMessageBuilder(final @NotNull String text) { - this.text = text; + public RadarMessageBuilder(final @NotNull String message) { + this.message = message; this.includePrefix = true; } /** - * Replaces old text with a new one in the text stored in this builder. + * Replaces an old message part with a new one in the message stored in this builder. * - * @param oldText The old text to replace. - * @param newText The replacement text. + * @param oldMessagePart The old message part. + * @param newMessagePart The new message part. * @return Returns the builder after replacing the text. */ - public @NotNull RadarMessageBuilder replace(final @NotNull String oldText, final @NotNull String newText) { - this.text = this.text.replace(oldText, newText); + public @NotNull RadarMessageBuilder replace(final @NotNull String oldMessagePart, final @NotNull String newMessagePart) { + this.message = this.message.replace(oldMessagePart, newMessagePart); return this; } /** * Replaces old text with a new one in the text stored in this builder by considering color codes. * - * @param oldText The old text to replace. - * @param newText The replacement text. + * @param oldMessagePart The old message part. + * @param newMessagePart The new message part. * @return Returns the builder after replacing the text and color codes. */ - public @NotNull RadarMessageBuilder replaceWithColorCodes(final @NotNull String oldText, final @NotNull String newText) { - this.text = this.text.replace(oldText, newText.replace("&", "§")); + public @NotNull RadarMessageBuilder replaceWithColorCodes(final @NotNull String oldMessagePart, final @NotNull String newMessagePart) { + this.message = this.message.replace(oldMessagePart, newMessagePart.replace("&", "§")); return this; } @@ -100,7 +99,7 @@ public RadarMessageBuilder(final @NotNull String text) { * @return Returns the build {@link RadarMessage}. */ public @NotNull RadarMessage build() { - return new RadarMessage(text, includePrefix); + return new RadarMessage(message, includePrefix); } } } diff --git a/common/src/main/java/io/github/communityradargg/forgemod/util/VersionBridge.java b/common/src/main/java/io/github/communityradargg/forgemod/util/VersionBridge.java new file mode 100644 index 0000000..ef09ea3 --- /dev/null +++ b/common/src/main/java/io/github/communityradargg/forgemod/util/VersionBridge.java @@ -0,0 +1,71 @@ +package io.github.communityradargg.forgemod.util; + +import org.jetbrains.annotations.NotNull; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +/** + * An interface holding all methods, which need a version specific implementation. + */ +public interface VersionBridge { + /** + * Gets the mod version. + * + * @return Returns the mod version. + */ + @NotNull String getVersion(); + + /** + * Adds a message to the player chat. + * + * @param message The message. + */ + void addMessageToChat(final @NotNull String message); + + /** + * Checks if the player is not in a world. + * + * @return Returns {@code true} if the player is not in a world, else {@code false}. + */ + boolean isNotInWorld(); + + /** + * Gets a list with player wrappers with their game profile UUID and name for all players in the current world. + * + * @return Returns the list with player wrappers with all players in the world. + */ + @NotNull List<@NotNull PlayerInfo> getWorldPlayers(); + + /** + * Updates a player by its UUID. + * + * @param commonHandler The common handler. + * @param uuid The player UUID. + * @param oldPrefixes A Set with old prefixes. + */ + void updatePlayerByUuid(final @NotNull CommonHandler commonHandler, final @NotNull UUID uuid, final @NotNull Set<@NotNull String> oldPrefixes); + + /** + * Updates the prefixes for all players. + * + * @param commonHandler The common handler. + * @param oldPrefixes A Set with old prefixes. + */ + void updatePrefixes(final @NotNull CommonHandler commonHandler, final @NotNull Set oldPrefixes); + + /** + * Checks is the player list key is pressed. + * + * @return Returns {@code true} if the key is pressed, else {@code false}. + */ + boolean isPlayerListKeyPressed(); + + /** + * Wraps a given text in the version specific text component and unformat it for later possible comparison. + * + * @param text The text. + * @return Returns the unformatted text. + */ + @NotNull String wrapAndUnformatText(final @NotNull String text); +} diff --git a/src/main/resources/assets/communityradar/icon.png b/common/src/main/resources/assets/communityradar/icon.png similarity index 100% rename from src/main/resources/assets/communityradar/icon.png rename to common/src/main/resources/assets/communityradar/icon.png diff --git a/gradle.properties b/gradle.properties index 14a8ce7..f0d4068 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,6 @@ org.gradle.configuration-cache=false loom.platform=forge -# When increasing the version, also increase it in the 'CommunityRadarMod' class -mod_version=1.1.3-1.8.9-SNAPSHOT +mod_version=1.2.0-SNAPSHOT maven_group=io.github.communityradargg mod_id=communityradar diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1f20b44..01e30e9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,14 +4,38 @@ ggEssentialLoom = "1.11.37" spotless = "7.2.1" # libraries -minecraft = "1.8.9" -mcpMappings = "22-1.8.9" -forge = "1.8.9-11.15.1.2318-1.8.9" +# general libs +jetbrainsJavaAnnotations = "26.0.2-1" +gson = "2.2.4" # needs to stay on 1.8.9 version +log4j = "2.0-beta9" # needs to stay on 1.8.9 version +guava = "17.0" + +# 1.8.9 (Forge) +minecraft189 = "1.8.9" +mcpMappings189 = "22-1.8.9" +forge189 = "1.8.9-11.15.1.2318-1.8.9" + +# 1.12.2 (Forge) +minecraft1122 = "1.12.2" +mcpMappings1122 = "39-1.12" +forge1122 = "1.12.2-14.23.5.2847" [libraries] -minecraft = { group = "com.mojang", name = "minecraft", version.ref = "minecraft" } -mcpMappings = { group = "de.oceanlabs.mcp", name = "mcp_stable", version.ref = "mcpMappings" } -forge = { group = "net.minecraftforge", name = "forge", version.ref = "forge" } +# general libraries +jetbrainsJavaAnnotations = { group = "org.jetbrains", name = "annotations", version.ref = "jetbrainsJavaAnnotations" } +gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } +log4j = { group = "org.apache.logging.log4j", name = "log4j-core", version.ref = "log4j" } +guava = { group = "com.google.guava", name = "guava", version.ref = "guava" } + +# 1.8.9 (Forge) +minecraft189 = { group = "com.mojang", name = "minecraft", version.ref = "minecraft189" } +mcpMappings189 = { group = "de.oceanlabs.mcp", name = "mcp_stable", version.ref = "mcpMappings189" } +forge189 = { group = "net.minecraftforge", name = "forge", version.ref = "forge189" } + +# 1.12.2 (Forge) +minecraft1122 = { group = "com.mojang", name = "minecraft", version.ref = "minecraft1122" } +mcpMappings1122 = { group = "de.oceanlabs.mcp", name = "mcp_stable", version.ref = "mcpMappings1122" } +forge1122 = { group = "net.minecraftforge", name = "forge", version.ref = "forge1122" } [plugins] ggEssentialLoom = { id = "gg.essential.loom", version.ref = "ggEssentialLoom" } diff --git a/settings.gradle.kts b/settings.gradle.kts index 5a071a1..96787bb 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -40,3 +40,10 @@ pluginManagement { plugins { id("org.gradle.toolchains.foojay-resolver-convention") version("0.8.0") } + +include("common") + +listOf("1.8.9", "1.12.2").forEach { version -> + include("versions:$version") + project(":versions:$version").projectDir = file("versions/$version") +} diff --git a/src/main/java/io/github/communityradargg/forgemod/CommunityRadarMod.java b/src/main/java/io/github/communityradargg/forgemod/CommunityRadarMod.java deleted file mode 100644 index c879975..0000000 --- a/src/main/java/io/github/communityradargg/forgemod/CommunityRadarMod.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2024 - present CommunityRadarGG - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.github.communityradargg.forgemod; - -import io.github.communityradargg.forgemod.command.RadarCommand; -import io.github.communityradargg.forgemod.event.ClientChatReceivedListener; -import io.github.communityradargg.forgemod.event.ClientConnectionDisconnectListener; -import io.github.communityradargg.forgemod.event.KeyInputListener; -import io.github.communityradargg.forgemod.event.PlayerNameFormatListener; -import io.github.communityradargg.forgemod.radarlistmanager.RadarListManager; -import net.minecraftforge.client.ClientCommandHandler; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.Mod.EventHandler; -import net.minecraftforge.fml.common.ModContainer; -import net.minecraftforge.fml.common.event.FMLInitializationEvent; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.nio.file.Paths; - -/** - * This class represents the main class of the mod. - */ -@Mod(modid = CommunityRadarMod.MOD_ID) -public class CommunityRadarMod { - public static final String MOD_ID = "communityradar"; - private static final Logger LOGGER = LogManager.getLogger(CommunityRadarMod.class); - private RadarListManager listManager; - private String version; - private boolean onGrieferGames = false; - - /** - * The listener for the {@link FMLInitializationEvent} event. - * - * @param event The event. - */ - @EventHandler - public void init(final FMLInitializationEvent event) { - LOGGER.info("Loading the mod '{}'", MOD_ID); - - final ModContainer modContainer = Loader.instance().getIndexedModList().get(MOD_ID); - version = modContainer == null ? "UNKNOWN" : modContainer.getVersion(); - - final File directoryPath = Paths.get(new File("") - .getAbsolutePath(),"communityradar", "lists") - .toFile(); - if (!directoryPath.exists() && !directoryPath.mkdirs()) { - LOGGER.error("Could not create directory: {}", directoryPath); - } - - listManager = new RadarListManager(this, directoryPath.getAbsolutePath() + "/"); - registerPublicLists(); - // Needs to be after loading public lists - listManager.loadPrivateLists(); - registerEvents(); - registerCommands(); - LOGGER.info("Successfully loaded the mod '{}'", MOD_ID); - } - - /** - * Registers the events. - */ - private void registerEvents() { - MinecraftForge.EVENT_BUS.register(new ClientChatReceivedListener(this)); - MinecraftForge.EVENT_BUS.register(new PlayerNameFormatListener(this)); - MinecraftForge.EVENT_BUS.register(new KeyInputListener(this)); - MinecraftForge.EVENT_BUS.register(new ClientConnectionDisconnectListener(this)); - } - - /** - * Registers the commands. - */ - private void registerCommands() { - ClientCommandHandler.instance.registerCommand(new RadarCommand(this)); - } - - /** - * Registers the public lists. - */ - private void registerPublicLists() { - if (!listManager.registerPublicList("scammer", "&7[&cScammer&7]", "https://lists.community-radar.de/versions/v1/scammer.json")) { - LOGGER.error("Could not register public list 'scammers'!"); - } - - if (!listManager.registerPublicList("trusted", "&7[&aTrusted&7]", "https://lists.community-radar.de/versions/v1/trusted.json")) { - LOGGER.error("Could not register public list 'verbvllert_trusted'!"); - } - } - - /** - * Gets the {@link RadarListManager} instance. - * - * @return Returns the radar list manager instance. - */ - public @NotNull RadarListManager getListManager() { - return listManager; - } - - /** - * Gets the GrieferGames connection state. - * - * @return Returns the GrieferGames connection state. - */ - @SuppressWarnings("BooleanMethodIsAlwaysInverted") - public boolean isOnGrieferGames() { - return onGrieferGames; - } - - /** - * Sets the GrieferGames connection state. - * - * @param onGrieferGames The GrieferGames connection state to set. - */ - public void setOnGrieferGames(final boolean onGrieferGames) { - this.onGrieferGames = onGrieferGames; - } - - /** - * Gets the version. - * - * @return Returns the version. - */ - public String getVersion() { - return version; - } -} diff --git a/src/main/java/io/github/communityradargg/forgemod/command/CheckSubcommand.java b/src/main/java/io/github/communityradargg/forgemod/command/CheckSubcommand.java deleted file mode 100644 index 16ad84a..0000000 --- a/src/main/java/io/github/communityradargg/forgemod/command/CheckSubcommand.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2024 - present CommunityRadarGG - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.github.communityradargg.forgemod.command; - -import io.github.communityradargg.forgemod.CommunityRadarMod; -import io.github.communityradargg.forgemod.radarlistmanager.RadarListEntry; -import io.github.communityradargg.forgemod.util.Messages; -import io.github.communityradargg.forgemod.util.RadarMessage; -import io.github.communityradargg.forgemod.util.Utils; -import net.minecraft.client.Minecraft; -import net.minecraft.client.network.NetworkPlayerInfo; -import net.minecraft.entity.player.EntityPlayer; -import org.jetbrains.annotations.NotNull; -import java.util.Optional; - -/** - * Holds the logic of the check subcommand. - */ -public class CheckSubcommand implements Subcommand { - private final CommunityRadarMod communityRadarMod; - private final EntityPlayer player; - private final String[] args; - - /** - * Constructs a {@link CheckSubcommand}. - * - * @param communityRadarMod The mod main class instance. - * @param player The player. - * @param args The args. - */ - public CheckSubcommand(final @NotNull CommunityRadarMod communityRadarMod, final @NotNull EntityPlayer player, final @NotNull String[] args) { - this.communityRadarMod = communityRadarMod; - this.player = player; - this.args = args; - } - - @Override - public void run() { - if (args.length != 2) { - // missing arguments - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.MISSING_ARGS) - .build().toChatComponentText()); - return; - } - - if (args[1].equalsIgnoreCase("*")) { - // check all argument - handleCheckAllSubcommand(player); - return; - } - handleCheckPlayerSubcommand(player, args); - } - - /** - * Handles the check - player subcommand. - * - * @param player The player, which executed the subcommand. - * @param args The arguments passed to the main command. - */ - private void handleCheckPlayerSubcommand(final @NotNull EntityPlayer player, final @NotNull String[] args) { - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.INPUT_PROCESSING) - .build().toChatComponentText()); - Utils.getUUID(communityRadarMod, args[1]).thenAccept(checkPlayerOptional -> { - if (!checkPlayerOptional.isPresent()) { - // player uuid could not be fetched - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.Check.FAILED) - .build().toChatComponentText()); - return; - } - - final Optional entryOptional = communityRadarMod.getListManager().getRadarListEntry(checkPlayerOptional.get()); - if (!entryOptional.isPresent()) { - // player uuid is on no list - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.Check.FAILED) - .build().toChatComponentText()); - return; - } - - final RadarListEntry entry = entryOptional.get(); - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.Check.FOUND + "\n" + Messages.Check.CHECK_ENTRY) - .replaceWithColorCodes("{prefix}", communityRadarMod.getListManager().getPrefix(entry.uuid())) - .replace("{name}", entry.name()) - .replace("{cause}", entry.cause()) - .replace("{entryCreationDate}", Utils.formatDateTime(entry.entryCreationDate())) - .replace("{entryUpdateDate}", Utils.formatDateTime(entry.entryUpdateDate())) - .build().toChatComponentText()); - }); - } - - /** - * Handles the check - all subcommand. - * - * @param player The player, which executed the subcommand. - */ - private void handleCheckAllSubcommand(final @NotNull EntityPlayer player) { - boolean anyPlayerFound = false; - for (final NetworkPlayerInfo networkPlayer : Minecraft.getMinecraft().getNetHandler().getPlayerInfoMap()) { - if (networkPlayer.getGameProfile().getId() == null) { - continue; - } - - final Optional listEntryOptional = communityRadarMod.getListManager() - .getRadarListEntry(networkPlayer.getGameProfile().getId()); - if (!listEntryOptional.isPresent()) { - // player uuid is on no list - continue; - } - - if (!anyPlayerFound) { - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.Check.EVERYONE) - .build().toChatComponentText()); - anyPlayerFound = true; - } - - final RadarListEntry entry = listEntryOptional.get(); - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.Check.CHECK_ENTRY) - .replaceWithColorCodes("{prefix}", communityRadarMod.getListManager().getPrefix(entry.uuid())) - .replace("{name}", entry.name()) - .replace("{cause}", entry.cause()) - .replace("{entryCreationDate}", Utils.formatDateTime(entry.entryCreationDate())) - .replace("{entryUpdateDate}", Utils.formatDateTime(entry.entryUpdateDate())) - .build().toChatComponentText()); - } - - if (!anyPlayerFound) { - player.addChatComponentMessage(new RadarMessage.RadarMessageBuilder(Messages.Check.NOT_FOUND) - .build().toChatComponentText()); - } - } -} diff --git a/src/main/java/io/github/communityradargg/forgemod/command/RadarCommand.java b/src/main/java/io/github/communityradargg/forgemod/command/RadarCommand.java deleted file mode 100644 index 698ff72..0000000 --- a/src/main/java/io/github/communityradargg/forgemod/command/RadarCommand.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2024 - present CommunityRadarGG - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.github.communityradargg.forgemod.command; - -import io.github.communityradargg.forgemod.CommunityRadarMod; -import io.github.communityradargg.forgemod.util.Messages; -import io.github.communityradargg.forgemod.util.RadarMessage; -import net.minecraft.command.CommandBase; -import net.minecraft.command.ICommandSender; -import net.minecraft.entity.player.EntityPlayer; -import org.jetbrains.annotations.NotNull; - -import java.util.Arrays; -import java.util.List; -import java.util.Locale; - -/** - * The class containing all logic for the main radar command. - */ -public class RadarCommand extends CommandBase { - private final CommunityRadarMod communityRadarMod; - - /** - * Constructs a {@link RadarCommand}. - * - * @param communityRadarMod The mod main class instance. - */ - public RadarCommand(final CommunityRadarMod communityRadarMod) { - this.communityRadarMod = communityRadarMod; - } - - @Override - public @NotNull String getCommandName() { - return "radar"; - } - - @Override - public String getCommandUsage(final @NotNull ICommandSender sender) { - return "/radar"; - } - - @Override - public List getCommandAliases() { - return Arrays.asList("communityradar", "scammer", "trustedmm", "mm"); - } - - @Override - public int getRequiredPermissionLevel() { - return 0; - } - - @Override - public boolean canCommandSenderUseCommand(final ICommandSender sender) { - return sender instanceof EntityPlayer; - } - - @Override - public void processCommand(final ICommandSender sender, final String[] args) { - if (!(sender instanceof EntityPlayer)) { - sender.addChatMessage(new RadarMessage.RadarMessageBuilder(Messages.NOT_PLAYER) - .build().toChatComponentText()); - return; - } - - final EntityPlayer player = (EntityPlayer) sender; - Subcommand subcommand = null; - if (args.length == 0) { - subcommand = new HelpSubcommand(communityRadarMod, player); - } - - if (subcommand == null) { - switch (args[0].toUpperCase(Locale.ENGLISH)) { - case "CHECK": - subcommand = new CheckSubcommand(communityRadarMod, player, args); - break; - case "LIST": - subcommand = new ListSubcommand(communityRadarMod, player, args); - break; - case "PLAYER": - subcommand = new PlayerSubcommand(communityRadarMod, player, args); - break; - case "LISTS": - subcommand = new ListsSubcommand(communityRadarMod, player); - break; - default: - subcommand = new HelpSubcommand(communityRadarMod, player); - break; - } - } - - subcommand.run(); - } -} diff --git a/src/main/java/io/github/communityradargg/forgemod/util/Utils.java b/src/main/java/io/github/communityradargg/forgemod/util/Utils.java deleted file mode 100644 index bbb4b05..0000000 --- a/src/main/java/io/github/communityradargg/forgemod/util/Utils.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright 2024 - present CommunityRadarGG - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.github.communityradargg.forgemod.util; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import io.github.communityradargg.forgemod.CommunityRadarMod; -import net.minecraft.client.Minecraft; -import net.minecraft.client.network.NetworkPlayerInfo; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.ChatComponentText; -import net.minecraft.util.IChatComponent; -import net.minecraft.world.World; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.NotNull; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.regex.Pattern; - -/** - * A class with some util methods. - */ -public class Utils { - private static final Logger LOGGER = LogManager.getLogger(Utils.class); - private static final String MOJANG_API_NAME_TO_UUID = "https://api.mojang.com/users/profiles/minecraft/"; - private static final Pattern UUID_MOJANG_API_PATTERN = Pattern.compile("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})"); - private static final DateTimeFormatter readableDateTimeFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"); - private static final Map uuidNameCache = new HashMap<>(); - - /** - * Tries to get the uuid to the player name from the world. - * - * @param mod The mod main class instance. - * @param playerName The player name to get the corresponding uuid. - * @return Returns a CompletableFuture with an optional with the player uuid. - */ - public static @NotNull CompletableFuture> getUUID(final CommunityRadarMod mod, final @NotNull String playerName) { - // user has to be in a world - if (Minecraft.getMinecraft().theWorld == null) { - return CompletableFuture.completedFuture(Optional.empty()); - } - - // If the UUID has been cached, returning from the map. - if (uuidNameCache.containsKey(playerName)) { - return CompletableFuture.completedFuture(Optional.of(uuidNameCache.get(playerName))); - } - - // Checking if there is a player with same name in the loaded world. If so, returning UUID from EntityPlayer. - for (final NetworkPlayerInfo networkPlayerInfo : Minecraft.getMinecraft().getNetHandler().getPlayerInfoMap()) { - if (networkPlayerInfo.getGameProfile().getName().equalsIgnoreCase(playerName)) { - uuidNameCache.put(playerName, networkPlayerInfo.getGameProfile().getId()); - return CompletableFuture.completedFuture(Optional.of(networkPlayerInfo.getGameProfile().getId())); - } - } - - if (playerName.startsWith("!") || playerName.startsWith("~")) { - return CompletableFuture.completedFuture(Optional.empty()); - } - - // If no player with same name is in the world, try fetching the UUID from the Mojang-API. - return requestUuidForName(mod, playerName); - } - - /** - * Requests an uuid to a player name, from the Mojang API. - * - * @param mod The mod main class instance. - * @param playerName The player name to get the uuid for. - * @return Returns a CompletableFuture with an optional with the requested uuid, it will be empty if an error occurred on requesting. - */ - private static @NotNull CompletableFuture> requestUuidForName(final CommunityRadarMod mod, final @NotNull String playerName) { - final String urlText = MOJANG_API_NAME_TO_UUID + playerName; - return CompletableFuture.supplyAsync(() -> { - HttpURLConnection connection = null; - try { - final URL url = new URL(urlText); - connection = (HttpURLConnection) url.openConnection(); - connection.setConnectTimeout(3000); - connection.setReadTimeout(3000); - connection.setRequestMethod("GET"); - connection.setRequestProperty("User-Agent", CommunityRadarMod.MOD_ID + "/" + mod.getVersion()); - - if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { - LOGGER.warn("Requesting data from '{}' resulted in following status code: {}", urlText, connection.getResponseCode()); - return Optional.empty(); - } - - try (final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { - final JsonObject json = new Gson().fromJson(reader, JsonObject.class); - if (json == null || !json.has("id") || !json.has("name")) { - connection.disconnect(); - return Optional.empty(); - } - - final UUID uuid = UUID.fromString(UUID_MOJANG_API_PATTERN.matcher(json.get("id").getAsString()).replaceAll("$1-$2-$3-$4-$5")); - uuidNameCache.put(playerName, uuid); - connection.disconnect(); - return Optional.of(uuid); - } - } catch (final Exception e) { - if (connection != null) { - connection.disconnect(); - } - LOGGER.error("Trying to request data from '{}' resulted in an exception", urlText, e); - return Optional.empty(); - } - }); - } - - /** - * Formats a given date time in a human-readable form. - * - * @param localDateTime The local date time to format. - * @return Returns the formatted date time. - */ - public static @NotNull String formatDateTime(final @NotNull LocalDateTime localDateTime) { - return localDateTime.format(readableDateTimeFormatter); - } - - /** - * Checks if a given hostname is a hostname of GrieferGames. - *

- * Following domains are taken into account: - *
- * - griefergames.net - *
- * - griefergames.de - *
- * - griefergames.live - * - * @param hostName The hostname to check. - * @return Returns, whether the given hostname is one of the GrieferGames hostnames. - */ - public static boolean isGrieferGamesHostName(final @NotNull String hostName) { - final String filteredHostName = Optional.of(hostName) - .filter(host -> host.endsWith(".")) - .map(host -> host.substring(0, host.length() - 1).toLowerCase(Locale.ENGLISH)) - .orElse(hostName.toLowerCase(Locale.ENGLISH)); - return filteredHostName.endsWith("griefergames.net") || filteredHostName.endsWith("griefergames.de") || filteredHostName.endsWith("griefergames.live"); - } - - /** - * Gets a {@link NetworkPlayerInfo} by the uuid of a player. - * - * @param uuid The uuid to get the network player info for. - * @return Returns an optional with the network player info of an online player to the uuid. - */ - private static @NotNull Optional getNetworkPlayerInfoByUuid(final @NotNull UUID uuid) { - return Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap().stream() - .filter(player -> player.getGameProfile() != null && uuid.equals(player.getGameProfile().getId())) - .findFirst(); - } - - /** - * Gets a {@link EntityPlayer} by the uuid of a player. - * - * @param uuid The uuid to get the entity player for. - * @return Returns an optional with the entity player to the uuid. - */ - private static @NotNull Optional getEntityPlayerByUuid(final @NotNull UUID uuid) { - final World world = Minecraft.getMinecraft().theWorld; - if (world == null) { - return Optional.empty(); - } - - return world.playerEntities.stream() - .filter(player -> player.getGameProfile() != null && uuid.equals(player.getGameProfile().getId())) - .findFirst(); - } - - /** - * Updates a player display name and name tag by its uuid. - * - * @param communityRadarMod The mod main class instance. - * @param uuid The uuid to update the corresponding player. - */ - public static void updatePlayerByUuid(final @NotNull CommunityRadarMod communityRadarMod, final @NotNull UUID uuid, final @NotNull Set oldPrefixes) { - getEntityPlayerByUuid(uuid).ifPresent(player -> updatePlayerNameTag(communityRadarMod, player, oldPrefixes)); - getNetworkPlayerInfoByUuid(uuid).ifPresent(networkPlayerInfo -> updatePlayerPrefix(communityRadarMod, networkPlayerInfo, oldPrefixes)); - } - - /** - * Handles updating the name tag of a player entity. - * - * @param communityRadarMod The mod main class instance. - * @param player The player entity to update the name tag. - * @param oldPrefixes The old prefixes that need to be removed before adding the new one. - */ - public static void updatePlayerNameTag(final @NotNull CommunityRadarMod communityRadarMod, final @NotNull EntityPlayer player, final @NotNull Set oldPrefixes) { - player.getPrefixes().removeIf(prefix -> oldPrefixes.stream().anyMatch(oldPrefix -> new ChatComponentText(oldPrefix.replace("&", "§") + " ").getUnformattedText().equals(prefix.getUnformattedText()))); - final String addonPrefix = communityRadarMod.getListManager() - .getPrefix(player.getGameProfile().getId()) - .replace("&", "§"); - - if (!addonPrefix.isEmpty()) { - player.addPrefix(new ChatComponentText(addonPrefix + " ")); - } - } - - /** - * Handles updating the player prefixes in the display name. - * - * @param communityRadarMod The mod main class instance. - * @param oldPrefixes The old prefixes that need to be removed before adding the new one. - */ - public static void updatePrefixes(final @NotNull CommunityRadarMod communityRadarMod, final @NotNull Set oldPrefixes) { - Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap() - .forEach(player -> updatePlayerPrefix(communityRadarMod, player, oldPrefixes)); - } - - /** - * Handles updating the player prefix in the display name of a single player. - * - * @param communityRadarMod The mod main class instance. - * @param player The player to update. - * @param oldPrefixes The old prefixes that need to be removed before adding the new one. - */ - private static void updatePlayerPrefix(final @NotNull CommunityRadarMod communityRadarMod, final @NotNull NetworkPlayerInfo player, final @NotNull Set oldPrefixes) { - if (player.getGameProfile() == null || player.getGameProfile().getId() == null || player.getDisplayName() == null) { - return; - } - - final IChatComponent displayName = player.getDisplayName(); - IChatComponent newDisplayName = displayName; - for (final String prefix : oldPrefixes) { - if (!displayName.getUnformattedText().startsWith(new ChatComponentText(prefix.replace("&", "§") + " ").getUnformattedText())) { - continue; - } - newDisplayName = displayName.getSiblings().get(displayName.getSiblings().size() - 1); - } - - final String addonPrefix = communityRadarMod.getListManager() - .getPrefix(player.getGameProfile().getId()) - .replace("&", "§"); - if (!addonPrefix.isEmpty()) { - newDisplayName = new ChatComponentText(addonPrefix.replace("&", "§") + " ").appendSibling(newDisplayName); - } - player.setDisplayName(newDisplayName); - } -} diff --git a/versions/1.12.2/build.gradle.kts b/versions/1.12.2/build.gradle.kts new file mode 100644 index 0000000..3beb05d --- /dev/null +++ b/versions/1.12.2/build.gradle.kts @@ -0,0 +1,41 @@ +import dev.architectury.pack200.java.Pack200Adapter + +val versionText: String by extra +val modIdText: String by extra + +dependencies { + implementation(project(":common")) + + minecraft(rootProject.libs.minecraft1122) + mappings(rootProject.libs.mcpMappings1122) + forge(rootProject.libs.forge1122) +} + +loom { + forge { + pack200Provider.set(Pack200Adapter()) + } +} + +tasks { + named("jar") { + from(project(":common").sourceSets.main.get().output) + } + + withType { + // https://github.com/gradle/gradle/issues/861 + inputs.property("version", versionText) + inputs.property("mc_version", rootProject.libs.versions.minecraft1122.get()) + inputs.property("mod_id", modIdText) + + filesMatching("mcmod.info") { + expand( + mapOf( + "version" to versionText, + "mc_version" to rootProject.libs.versions.minecraft1122.get(), + "mod_id" to modIdText + ) + ) + } + } +} diff --git a/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/CommunityRadarMod.java b/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/CommunityRadarMod.java new file mode 100644 index 0000000..71d0825 --- /dev/null +++ b/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/CommunityRadarMod.java @@ -0,0 +1,72 @@ +/* + * Copyright 2024 - present CommunityRadarGG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.communityradargg.forgemod; + +import io.github.communityradargg.forgemod.command.RadarCommand; +import io.github.communityradargg.forgemod.event.ClientChatReceivedListener; +import io.github.communityradargg.forgemod.event.ClientConnectionDisconnectListener; +import io.github.communityradargg.forgemod.event.KeyInputListener; +import io.github.communityradargg.forgemod.event.PlayerNameFormatListener; +import io.github.communityradargg.forgemod.util.CommonHandler; +import io.github.communityradargg.forgemod.util.VersionBridgeImpl; +import net.minecraftforge.client.ClientCommandHandler; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.Mod.EventHandler; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * This class represents the main class of the mod. + */ +@Mod(modid = CommonHandler.MOD_ID) +public class CommunityRadarMod { + private static final Logger LOGGER = LogManager.getLogger(CommunityRadarMod.class); + private final CommonHandler commonHandler = new CommonHandler(new VersionBridgeImpl()); + + /** + * The listener for the {@link FMLInitializationEvent} event. + * + * @param event The event. + */ + @EventHandler + public void init(FMLInitializationEvent event) { + LOGGER.info("Loading the mod '{}'", CommonHandler.MOD_ID); + + registerEvents(); + registerCommands(); + + LOGGER.info("Successfully loaded the mod '{}'", CommonHandler.MOD_ID); + } + + /** + * Registers the events. + */ + private void registerEvents() { + MinecraftForge.EVENT_BUS.register(new ClientChatReceivedListener(commonHandler)); + MinecraftForge.EVENT_BUS.register(new PlayerNameFormatListener(commonHandler)); + MinecraftForge.EVENT_BUS.register(new KeyInputListener(commonHandler)); + MinecraftForge.EVENT_BUS.register(new ClientConnectionDisconnectListener(commonHandler)); + } + + /** + * Registers the commands. + */ + private void registerCommands() { + ClientCommandHandler.instance.registerCommand(new RadarCommand(commonHandler)); + } +} diff --git a/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/command/RadarCommand.java b/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/command/RadarCommand.java new file mode 100644 index 0000000..08411e1 --- /dev/null +++ b/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/command/RadarCommand.java @@ -0,0 +1,71 @@ +/* + * Copyright 2024 - present CommunityRadarGG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.communityradargg.forgemod.command; + +import io.github.communityradargg.forgemod.util.CommonHandler; +import net.minecraft.command.CommandBase; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.server.MinecraftServer; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * The class containing all logic for the radar command. + */ +public class RadarCommand extends CommandBase { + private final RootRadarCommand rootRadarCommand; + + /** + * Constructs a {@link RadarCommand}. + * + * @param commonHandler The common handler. + */ + public RadarCommand(final @NotNull CommonHandler commonHandler) { + rootRadarCommand = new RootRadarCommand(commonHandler); + } + + @Override + public @NotNull String getName() { + return RootRadarCommand.COMMAND_NAME; + } + + @Override + public @NotNull String getUsage(final @NotNull ICommandSender sender) { + return "/" + RootRadarCommand.COMMAND_NAME; + } + + @Override + public @NotNull List getAliases() { + return RootRadarCommand.COMMAND_ALIASES; + } + + @Override + public int getRequiredPermissionLevel() { + return 0; + } + + @Override + public boolean checkPermission(final @NotNull MinecraftServer server, final @NotNull ICommandSender sender) { + return sender instanceof EntityPlayer; + } + + @Override + public void execute(final @NotNull MinecraftServer server, final @NotNull ICommandSender sender, final String @NotNull [] args) { + rootRadarCommand.execute(args); + } +} diff --git a/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/event/ClientChatReceivedListener.java b/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/event/ClientChatReceivedListener.java new file mode 100644 index 0000000..45b38a3 --- /dev/null +++ b/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/event/ClientChatReceivedListener.java @@ -0,0 +1,76 @@ +/* + * Copyright 2024 - present CommunityRadarGG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.communityradargg.forgemod.event; + +import io.github.communityradargg.forgemod.util.CommonHandler; +import net.minecraft.util.text.TextComponentString; +import net.minecraftforge.client.event.ClientChatReceivedEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import org.jetbrains.annotations.NotNull; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * A class containing a listener for client chat receiving. + */ +public class ClientChatReceivedListener { + /** + * A pattern matching private messages (in and out) and payments (in and out) as well as global and plot chat messages with the player name (nicked, bedrock and java) as only group. + */ + private static final Pattern PATTERN = Pattern.compile("[A-Za-z\\-+]+\\s\\u2503\\s(~?!?\\w{1,16})"); + private final CommonHandler commonHandler; + + /** + * Constructs the class {@link ClientChatReceivedListener}. + * + * @param commonHandler The common handler. + */ + public ClientChatReceivedListener(final @NotNull CommonHandler commonHandler) { + this.commonHandler = commonHandler; + } + + /** + * The listener for the {@link ClientChatReceivedEvent} event. + * + * @param event The event. + */ + @SubscribeEvent + public void onClientChatReceived(final ClientChatReceivedEvent event) { + if (!commonHandler.isOnGrieferGames()) { + return; + } + + final Matcher matcher = PATTERN.matcher(event.getMessage().getUnformattedText()); + if (!matcher.find()) { + return; + } + + final String playerName = matcher.group(1); + if (playerName.startsWith("~")) { + // nicked player + return; + } + + commonHandler.getUuidByPlayerName(commonHandler, playerName).thenAccept(uuid -> { + if (uuid.isPresent() && commonHandler.getListManager().isInList(uuid.get())) { + event.setMessage(new TextComponentString(commonHandler.getListManager().getPrefix(uuid.get()).replace("&", "§")) + .appendText(" §r") + .appendText(event.getMessage().getFormattedText())); + } + }); + } +} diff --git a/src/main/java/io/github/communityradargg/forgemod/event/ClientConnectionDisconnectListener.java b/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/event/ClientConnectionDisconnectListener.java similarity index 61% rename from src/main/java/io/github/communityradargg/forgemod/event/ClientConnectionDisconnectListener.java rename to versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/event/ClientConnectionDisconnectListener.java index b89d2a3..a541839 100644 --- a/src/main/java/io/github/communityradargg/forgemod/event/ClientConnectionDisconnectListener.java +++ b/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/event/ClientConnectionDisconnectListener.java @@ -15,28 +15,24 @@ */ package io.github.communityradargg.forgemod.event; -import io.github.communityradargg.forgemod.CommunityRadarMod; -import io.github.communityradargg.forgemod.util.Utils; +import io.github.communityradargg.forgemod.util.CommonHandler; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.network.FMLNetworkEvent; import org.jetbrains.annotations.NotNull; -import java.net.InetSocketAddress; -import java.net.SocketAddress; - /** * A class containing listeners for player connect and disconnect from and to servers. */ public class ClientConnectionDisconnectListener { - private final CommunityRadarMod communityRadarMod; + private final CommonHandler commonHandler; /** - * Constructs the class {@link ClientConnectionDisconnectListener}. + * Constructs a {@link ClientConnectionDisconnectListener}. * - * @param communityRadarMod An instance of the {@link CommunityRadarMod} class. + * @param commonHandler The common handler. */ - public ClientConnectionDisconnectListener(final @NotNull CommunityRadarMod communityRadarMod) { - this.communityRadarMod = communityRadarMod; + public ClientConnectionDisconnectListener(final @NotNull CommonHandler commonHandler) { + this.commonHandler = commonHandler; } /** @@ -46,21 +42,8 @@ public ClientConnectionDisconnectListener(final @NotNull CommunityRadarMod commu */ @SubscribeEvent public void onFMLNetworkClientConnectedToServer(final FMLNetworkEvent.ClientConnectedToServerEvent event) { - if (event.isLocal) { - return; - } - - final SocketAddress socketAddress = event.manager.getRemoteAddress(); - if (!(socketAddress instanceof InetSocketAddress)) { - return; - } - - final String hostname = ((InetSocketAddress) socketAddress).getHostName(); - if (Utils.isGrieferGamesHostName(hostname)) { - communityRadarMod.setOnGrieferGames(true); - return; - } - communityRadarMod.setOnGrieferGames(false); + commonHandler.setOnGrieferGames(event.isLocal(), event.getManager().getRemoteAddress()); + commonHandler.updatePlayerNameUuidCache(); } /** @@ -70,6 +53,6 @@ public void onFMLNetworkClientConnectedToServer(final FMLNetworkEvent.ClientConn */ @SubscribeEvent public void onFMLNetworkClientDisconnectionFromServer(final FMLNetworkEvent.ClientDisconnectionFromServerEvent event) { - communityRadarMod.setOnGrieferGames(false); + commonHandler.setOnGrieferGames(false); } } diff --git a/src/main/java/io/github/communityradargg/forgemod/event/KeyInputListener.java b/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/event/KeyInputListener.java similarity index 61% rename from src/main/java/io/github/communityradargg/forgemod/event/KeyInputListener.java rename to versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/event/KeyInputListener.java index bd3253c..1461ed3 100644 --- a/src/main/java/io/github/communityradargg/forgemod/event/KeyInputListener.java +++ b/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/event/KeyInputListener.java @@ -15,9 +15,7 @@ */ package io.github.communityradargg.forgemod.event; -import io.github.communityradargg.forgemod.CommunityRadarMod; -import io.github.communityradargg.forgemod.util.Utils; -import net.minecraft.client.Minecraft; +import io.github.communityradargg.forgemod.util.CommonHandler; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.InputEvent; import org.jetbrains.annotations.NotNull; @@ -26,15 +24,15 @@ * A class containing a listener for key input. */ public class KeyInputListener { - private final CommunityRadarMod communityRadarMod; + private final CommonHandler commonHandler; /** * Constructs the class {@link KeyInputListener}. * - * @param communityRadarMod An instance of the {@link CommunityRadarMod} class. + * @param commonHandler The common handler. */ - public KeyInputListener(final @NotNull CommunityRadarMod communityRadarMod) { - this.communityRadarMod = communityRadarMod; + public KeyInputListener(final @NotNull CommonHandler commonHandler) { + this.commonHandler = commonHandler; } /** @@ -44,15 +42,6 @@ public KeyInputListener(final @NotNull CommunityRadarMod communityRadarMod) { */ @SubscribeEvent public void onKeyInput(final InputEvent.KeyInputEvent event) { - if (!communityRadarMod.isOnGrieferGames()) { - return; - } - - final Minecraft mc = Minecraft.getMinecraft(); - if (!mc.gameSettings.keyBindPlayerList.isPressed()) { - return; - } - - Utils.updatePrefixes(communityRadarMod, communityRadarMod.getListManager().getExistingPrefixes()); + commonHandler.handleKeyInputEvent(); } } diff --git a/src/main/java/io/github/communityradargg/forgemod/event/PlayerNameFormatListener.java b/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/event/PlayerNameFormatListener.java similarity index 72% rename from src/main/java/io/github/communityradargg/forgemod/event/PlayerNameFormatListener.java rename to versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/event/PlayerNameFormatListener.java index 1aab8c2..85ac799 100644 --- a/src/main/java/io/github/communityradargg/forgemod/event/PlayerNameFormatListener.java +++ b/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/event/PlayerNameFormatListener.java @@ -15,7 +15,7 @@ */ package io.github.communityradargg.forgemod.event; -import io.github.communityradargg.forgemod.CommunityRadarMod; +import io.github.communityradargg.forgemod.util.CommonHandler; import io.github.communityradargg.forgemod.util.Utils; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -25,15 +25,15 @@ * A class containing a listener for player name formatting. */ public class PlayerNameFormatListener { - private final CommunityRadarMod communityRadarMod; + private final CommonHandler commonHandler; /** * Constructs the class {@link PlayerNameFormatListener}. * - * @param communityRadarMod An instance of the {@link CommunityRadarMod} class. + * @param commonHandler The common handler. */ - public PlayerNameFormatListener(final @NotNull CommunityRadarMod communityRadarMod) { - this.communityRadarMod = communityRadarMod; + public PlayerNameFormatListener(final @NotNull CommonHandler commonHandler) { + this.commonHandler = commonHandler; } /** @@ -43,9 +43,9 @@ public PlayerNameFormatListener(final @NotNull CommunityRadarMod communityRadarM */ @SubscribeEvent public void onPlayerNameFormat(final PlayerEvent.NameFormat event) { - if (!communityRadarMod.isOnGrieferGames()) { + if (!commonHandler.isOnGrieferGames()) { return; } - Utils.updatePlayerNameTag(communityRadarMod, event.entityPlayer, communityRadarMod.getListManager().getExistingPrefixes()); + Utils.updatePlayerNameTag(commonHandler, event.getEntityPlayer(), commonHandler.getListManager().getExistingPrefixes()); } } diff --git a/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/util/Utils.java b/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/util/Utils.java new file mode 100644 index 0000000..7203371 --- /dev/null +++ b/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/util/Utils.java @@ -0,0 +1,138 @@ +/* + * Copyright 2024 - present CommunityRadarGG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.communityradargg.forgemod.util; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.network.NetHandlerPlayClient; +import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.world.World; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; +import java.util.Set; +import java.util.UUID; + +/** + * A class with some util methods. + */ +public class Utils { + /** + * Gets a {@link NetworkPlayerInfo} by the uuid of a player. + * + * @param uuid The uuid to get the network player info for. + * @return Returns an optional with the network player info of an online player to the uuid. + */ + private static @NotNull Optional getNetworkPlayerInfoByUuid(final @NotNull UUID uuid) { + final NetHandlerPlayClient connection = Minecraft.getMinecraft().getConnection(); + if (connection == null) { + return Optional.empty(); + } + return connection.getPlayerInfoMap().stream() + .filter(player -> uuid.equals(player.getGameProfile().getId())) + .findFirst(); + } + + /** + * Gets a {@link EntityPlayer} by the uuid of a player. + * + * @param uuid The uuid to get the entity player for. + * @return Returns an optional with the entity player to the uuid. + */ + private static @NotNull Optional getEntityPlayerByUuid(final @NotNull UUID uuid) { + final World world = Minecraft.getMinecraft().world; + if (world == null) { + return Optional.empty(); + } + + return world.playerEntities.stream() + .filter(player -> uuid.equals(player.getGameProfile().getId())) + .findFirst(); + } + + /** + * Updates a player display name and name tag by its uuid. + * + * @param commonHandler The common handler. + * @param uuid The uuid to update the corresponding player. + */ + public static void updatePlayerByUuid(final @NotNull CommonHandler commonHandler, final @NotNull UUID uuid, final @NotNull Set oldPrefixes) { + getEntityPlayerByUuid(uuid).ifPresent(player -> updatePlayerNameTag(commonHandler, player, oldPrefixes)); + getNetworkPlayerInfoByUuid(uuid).ifPresent(networkPlayerInfo -> updatePlayerPrefix(commonHandler, networkPlayerInfo, oldPrefixes)); + } + + /** + * Handles updating the name tag of a player entity. + * + * @param commonHandler The common handler. + * @param player The player entity to update the name tag. + * @param oldPrefixes The old prefixes that need to be removed before adding the new one. + */ + public static void updatePlayerNameTag(final @NotNull CommonHandler commonHandler, final @NotNull EntityPlayer player, final @NotNull Set oldPrefixes) { + player.getPrefixes().removeIf(prefix -> commonHandler.isPrefixMatching(prefix.getUnformattedText(), oldPrefixes)); + final String addonPrefix = commonHandler.getListManager() + .getPrefix(player.getGameProfile().getId()); + + if (!addonPrefix.isEmpty()) { + player.addPrefix(new TextComponentString(commonHandler.formatPrefix(addonPrefix))); + } + } + + /** + * Handles updating the player prefixes in the display name. + * + * @param commonHandler The common handler. + * @param oldPrefixes The old prefixes that need to be removed before adding the new one. + */ + public static void updatePrefixes(final @NotNull CommonHandler commonHandler, final @NotNull Set oldPrefixes) { + final NetHandlerPlayClient connection = Minecraft.getMinecraft().getConnection(); + if (connection == null) { + return; + } + connection.getPlayerInfoMap().forEach(player -> updatePlayerPrefix(commonHandler, player, oldPrefixes)); + } + + /** + * Handles updating the player prefix in the display name of a single player. + * + * @param commonHandler The common handler. + * @param player The player to update. + * @param oldPrefixes The old prefixes that need to be removed before adding the new one. + */ + private static void updatePlayerPrefix(final @NotNull CommonHandler commonHandler, final @NotNull NetworkPlayerInfo player, final @NotNull Set oldPrefixes) { + if (player.getGameProfile().getId() == null || player.getDisplayName() == null) { + return; + } + + final ITextComponent displayName = player.getDisplayName(); + ITextComponent newDisplayName = displayName; + for (final String prefix : oldPrefixes) { + if (!displayName.getUnformattedText().startsWith(commonHandler.unformatPrefixForCompare(prefix))) { + continue; + } + newDisplayName = displayName.getSiblings().get(displayName.getSiblings().size() - 1); + } + + final String addonPrefix = commonHandler.getListManager() + .getPrefix(player.getGameProfile().getId()); + if (!addonPrefix.isEmpty()) { + newDisplayName = new TextComponentString(commonHandler.formatPrefix(addonPrefix)).appendSibling(newDisplayName); + } + player.setDisplayName(newDisplayName); + } +} diff --git a/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/util/VersionBridgeImpl.java b/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/util/VersionBridgeImpl.java new file mode 100644 index 0000000..132888f --- /dev/null +++ b/versions/1.12.2/src/main/java/io/github/communityradargg/forgemod/util/VersionBridgeImpl.java @@ -0,0 +1,83 @@ +package io.github.communityradargg.forgemod.util; + +import com.mojang.authlib.GameProfile; +import net.minecraft.client.Minecraft; +import net.minecraft.client.network.NetHandlerPlayClient; +import net.minecraft.util.text.TextComponentString; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.ModContainer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * The version bridge implementation for the 1.12.2 version. + */ +public class VersionBridgeImpl implements VersionBridge { + private static final Logger LOGGER = LogManager.getLogger(VersionBridgeImpl.class); + + @Override + public @NotNull String getVersion() { + final ModContainer modContainer = Loader.instance().getIndexedModList().get(CommonHandler.MOD_ID); + if (modContainer == null) { + return "UNKNOWN"; + } + + return modContainer.getVersion(); + } + + @Override + public void addMessageToChat(final @NotNull String message) { + if (Minecraft.getMinecraft().player == null) { + LOGGER.warn("Could not add message to chat. Player is null. The message is following: {}", message); + return; + } + + Minecraft.getMinecraft().player.sendMessage(new TextComponentString(message)); + } + + @Override + public boolean isNotInWorld() { + return Minecraft.getMinecraft().world == null; + } + + @Override + public @NotNull List<@NotNull PlayerInfo> getWorldPlayers() { + final NetHandlerPlayClient connection = Minecraft.getMinecraft().getConnection(); + if (connection == null) { + return Collections.emptyList(); + } + + return connection.getPlayerInfoMap().stream() + .map(networkPlayerInfo -> { + final GameProfile gameProfile = networkPlayerInfo.getGameProfile(); + return new PlayerInfo(gameProfile.getId(), gameProfile.getName()); + }) + .collect(Collectors.toList()); + } + + @Override + public void updatePlayerByUuid(final @NotNull CommonHandler commonHandler, final @NotNull UUID uuid, final @NotNull Set<@NotNull String> oldPrefixes) { + Utils.updatePlayerByUuid(commonHandler, uuid, oldPrefixes); + } + + @Override + public void updatePrefixes(final @NotNull CommonHandler commonHandler, final @NotNull Set oldPrefixes) { + Utils.updatePrefixes(commonHandler, oldPrefixes); + } + + @Override + public boolean isPlayerListKeyPressed() { + return Minecraft.getMinecraft().gameSettings.keyBindPlayerList.isPressed(); + } + + @Override + public @NotNull String wrapAndUnformatText(final @NotNull String text) { + return new TextComponentString(text).getUnformattedText(); + } +} diff --git a/versions/1.12.2/src/main/resources/mcmod.info b/versions/1.12.2/src/main/resources/mcmod.info new file mode 100644 index 0000000..0aa4852 --- /dev/null +++ b/versions/1.12.2/src/main/resources/mcmod.info @@ -0,0 +1,19 @@ +[ + { + "modid": "${mod_id}", + "name": "CommunityRadar Mod - Official - 1.12.2", + "description": "The Official CommunityRadar Forge 1.12.2 Mod.", + "version": "${version}", + "mcversion": "${mc_version}", + "url": "https://community-radar.de", + "updateUrl": "", + "authorList": [ + "BlockyTheDev", + "MrMystery" + ], + "credits": "CommunityRadar-Team, BlockyTheDev, MrMystery", + "logoFile": "assets/${mod_id}/icon.png", + "screenshots": [], + "dependencies": [] + } +] diff --git a/versions/1.12.2/src/main/resources/pack.mcmeta b/versions/1.12.2/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..4d007bc --- /dev/null +++ b/versions/1.12.2/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "description": "The Official CommunityRadar Forge 1.12.2 Mod.", + "pack_format": 3 + } +} diff --git a/versions/1.8.9/build.gradle.kts b/versions/1.8.9/build.gradle.kts new file mode 100644 index 0000000..1c9694f --- /dev/null +++ b/versions/1.8.9/build.gradle.kts @@ -0,0 +1,41 @@ +import dev.architectury.pack200.java.Pack200Adapter + +val versionText: String by extra +val modIdText: String by extra + +dependencies { + implementation(project(":common")) + + minecraft(rootProject.libs.minecraft189) + mappings(rootProject.libs.mcpMappings189) + forge(rootProject.libs.forge189) +} + +loom { + forge { + pack200Provider.set(Pack200Adapter()) + } +} + +tasks { + named("jar") { + from(project(":common").sourceSets.main.get().output) + } + + withType { + // https://github.com/gradle/gradle/issues/861 + inputs.property("version", versionText) + inputs.property("mc_version", libs.versions.minecraft189.get()) + inputs.property("mod_id", modIdText) + + filesMatching("mcmod.info") { + expand( + mapOf( + "version" to versionText, + "mc_version" to libs.versions.minecraft189.get(), + "mod_id" to modIdText + ) + ) + } + } +} diff --git a/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/CommunityRadarMod.java b/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/CommunityRadarMod.java new file mode 100644 index 0000000..63d1566 --- /dev/null +++ b/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/CommunityRadarMod.java @@ -0,0 +1,72 @@ +/* + * Copyright 2024 - present CommunityRadarGG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.communityradargg.forgemod; + +import io.github.communityradargg.forgemod.command.RadarCommand; +import io.github.communityradargg.forgemod.event.ClientChatReceivedListener; +import io.github.communityradargg.forgemod.event.ClientConnectionDisconnectListener; +import io.github.communityradargg.forgemod.event.KeyInputListener; +import io.github.communityradargg.forgemod.event.PlayerNameFormatListener; +import io.github.communityradargg.forgemod.util.CommonHandler; +import io.github.communityradargg.forgemod.util.VersionBridgeImpl; +import net.minecraftforge.client.ClientCommandHandler; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.Mod.EventHandler; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * This class represents the main class of the mod. + */ +@Mod(modid = CommonHandler.MOD_ID) +public class CommunityRadarMod { + private static final Logger LOGGER = LogManager.getLogger(CommunityRadarMod.class); + private final CommonHandler commonHandler = new CommonHandler(new VersionBridgeImpl()); + + /** + * The listener for the {@link FMLInitializationEvent} event. + * + * @param event The event. + */ + @EventHandler + public void init(final FMLInitializationEvent event) { + LOGGER.info("Loading the mod '{}'", CommonHandler.MOD_ID); + + registerEvents(); + registerCommands(); + + LOGGER.info("Successfully loaded the mod '{}'", CommonHandler.MOD_ID); + } + + /** + * Registers the events. + */ + private void registerEvents() { + MinecraftForge.EVENT_BUS.register(new ClientChatReceivedListener(commonHandler)); + MinecraftForge.EVENT_BUS.register(new PlayerNameFormatListener(commonHandler)); + MinecraftForge.EVENT_BUS.register(new KeyInputListener(commonHandler)); + MinecraftForge.EVENT_BUS.register(new ClientConnectionDisconnectListener(commonHandler)); + } + + /** + * Registers the commands. + */ + private void registerCommands() { + ClientCommandHandler.instance.registerCommand(new RadarCommand(commonHandler)); + } +} diff --git a/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/command/RadarCommand.java b/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/command/RadarCommand.java new file mode 100644 index 0000000..d69a573 --- /dev/null +++ b/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/command/RadarCommand.java @@ -0,0 +1,70 @@ +/* + * Copyright 2024 - present CommunityRadarGG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.communityradargg.forgemod.command; + +import io.github.communityradargg.forgemod.util.CommonHandler; +import net.minecraft.command.CommandBase; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * The class containing all logic for the main radar command. + */ +public class RadarCommand extends CommandBase { + private final RootRadarCommand rootRadarCommand; + + /** + * Constructs a {@link RadarCommand}. + * + * @param commonHandler The common handler. + */ + public RadarCommand(final CommonHandler commonHandler) { + rootRadarCommand = new RootRadarCommand(commonHandler); + } + + @Override + public @NotNull String getCommandName() { + return RootRadarCommand.COMMAND_NAME; + } + + @Override + public String getCommandUsage(final @NotNull ICommandSender sender) { + return "/" + RootRadarCommand.COMMAND_NAME; + } + + @Override + public List getCommandAliases() { + return RootRadarCommand.COMMAND_ALIASES; + } + + @Override + public int getRequiredPermissionLevel() { + return 0; + } + + @Override + public boolean canCommandSenderUseCommand(final ICommandSender sender) { + return sender instanceof EntityPlayer; + } + + @Override + public void processCommand(final ICommandSender sender, final String[] args) { + rootRadarCommand.execute(args); + } +} diff --git a/src/main/java/io/github/communityradargg/forgemod/event/ClientChatReceivedListener.java b/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/event/ClientChatReceivedListener.java similarity index 74% rename from src/main/java/io/github/communityradargg/forgemod/event/ClientChatReceivedListener.java rename to versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/event/ClientChatReceivedListener.java index bc48f59..516128e 100644 --- a/src/main/java/io/github/communityradargg/forgemod/event/ClientChatReceivedListener.java +++ b/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/event/ClientChatReceivedListener.java @@ -15,8 +15,7 @@ */ package io.github.communityradargg.forgemod.event; -import io.github.communityradargg.forgemod.CommunityRadarMod; -import io.github.communityradargg.forgemod.util.Utils; +import io.github.communityradargg.forgemod.util.CommonHandler; import net.minecraft.util.ChatComponentText; import net.minecraftforge.client.event.ClientChatReceivedEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -33,15 +32,15 @@ public class ClientChatReceivedListener { * A pattern matching private messages (in and out) and payments (in and out) as well as global and plot chat messages with the player name (nicked, bedrock and java) as only group. */ private static final Pattern PATTERN = Pattern.compile("[A-Za-z\\-+]+\\s\\u2503\\s(~?!?\\w{1,16})"); - private final CommunityRadarMod communityRadarMod; + private final CommonHandler commonHandler; /** * Constructs the class {@link ClientChatReceivedListener}. * - * @param communityRadarMod The mod main class instance. + * @param commonHandler The common handler. */ - public ClientChatReceivedListener(final @NotNull CommunityRadarMod communityRadarMod) { - this.communityRadarMod = communityRadarMod; + public ClientChatReceivedListener(final @NotNull CommonHandler commonHandler) { + this.commonHandler = commonHandler; } /** @@ -51,7 +50,7 @@ public ClientChatReceivedListener(final @NotNull CommunityRadarMod communityRada */ @SubscribeEvent public void onClientChatReceived(final ClientChatReceivedEvent event) { - if (!communityRadarMod.isOnGrieferGames()) { + if (!commonHandler.isOnGrieferGames()) { return; } @@ -66,9 +65,9 @@ public void onClientChatReceived(final ClientChatReceivedEvent event) { return; } - Utils.getUUID(communityRadarMod, playerName).thenAccept(uuid -> { - if (uuid.isPresent() && communityRadarMod.getListManager().isInList(uuid.get())) { - event.message = new ChatComponentText(communityRadarMod.getListManager().getPrefix(uuid.get()).replace("&", "§")) + commonHandler.getUuidByPlayerName(commonHandler, playerName).thenAccept(uuid -> { + if (uuid.isPresent() && commonHandler.getListManager().isInList(uuid.get())) { + event.message = new ChatComponentText(commonHandler.getListManager().getPrefix(uuid.get()).replace("&", "§")) .appendText(" §r") .appendText(event.message.getFormattedText()); } diff --git a/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/event/ClientConnectionDisconnectListener.java b/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/event/ClientConnectionDisconnectListener.java new file mode 100644 index 0000000..20cc6cd --- /dev/null +++ b/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/event/ClientConnectionDisconnectListener.java @@ -0,0 +1,58 @@ +/* + * Copyright 2024 - present CommunityRadarGG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.communityradargg.forgemod.event; + +import io.github.communityradargg.forgemod.util.CommonHandler; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.network.FMLNetworkEvent; +import org.jetbrains.annotations.NotNull; + +/** + * A class containing listeners for player connect and disconnect from and to servers. + */ +public class ClientConnectionDisconnectListener { + private final CommonHandler commonHandler; + + /** + * Constructs a {@link CommonHandler}. + * + * @param commonHandler Constructs a common handler. + */ + public ClientConnectionDisconnectListener(final @NotNull CommonHandler commonHandler) { + this.commonHandler = commonHandler; + } + + /** + * The listener for the {@link FMLNetworkEvent.ClientConnectedToServerEvent} event. + * + * @param event The event. + */ + @SubscribeEvent + public void onFMLNetworkClientConnectedToServer(final FMLNetworkEvent.ClientConnectedToServerEvent event) { + commonHandler.setOnGrieferGames(event.isLocal, event.manager.getRemoteAddress()); + commonHandler.updatePlayerNameUuidCache(); + } + + /** + * The listener for the {@link FMLNetworkEvent.ClientDisconnectionFromServerEvent} event. + * + * @param event The event. + */ + @SubscribeEvent + public void onFMLNetworkClientDisconnectionFromServer(final FMLNetworkEvent.ClientDisconnectionFromServerEvent event) { + commonHandler.setOnGrieferGames(false); + } +} diff --git a/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/event/KeyInputListener.java b/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/event/KeyInputListener.java new file mode 100644 index 0000000..1461ed3 --- /dev/null +++ b/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/event/KeyInputListener.java @@ -0,0 +1,47 @@ +/* + * Copyright 2024 - present CommunityRadarGG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.communityradargg.forgemod.event; + +import io.github.communityradargg.forgemod.util.CommonHandler; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.InputEvent; +import org.jetbrains.annotations.NotNull; + +/** + * A class containing a listener for key input. + */ +public class KeyInputListener { + private final CommonHandler commonHandler; + + /** + * Constructs the class {@link KeyInputListener}. + * + * @param commonHandler The common handler. + */ + public KeyInputListener(final @NotNull CommonHandler commonHandler) { + this.commonHandler = commonHandler; + } + + /** + * The listener for the {@link InputEvent.KeyInputEvent} event. + * + * @param event The event. + */ + @SubscribeEvent + public void onKeyInput(final InputEvent.KeyInputEvent event) { + commonHandler.handleKeyInputEvent(); + } +} diff --git a/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/event/PlayerNameFormatListener.java b/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/event/PlayerNameFormatListener.java new file mode 100644 index 0000000..4a66da4 --- /dev/null +++ b/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/event/PlayerNameFormatListener.java @@ -0,0 +1,51 @@ +/* + * Copyright 2024 - present CommunityRadarGG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.communityradargg.forgemod.event; + +import io.github.communityradargg.forgemod.util.CommonHandler; +import io.github.communityradargg.forgemod.util.Utils; +import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import org.jetbrains.annotations.NotNull; + +/** + * A class containing a listener for player name formatting. + */ +public class PlayerNameFormatListener { + private final CommonHandler commonHandler; + + /** + * Constructs the class {@link PlayerNameFormatListener}. + * + * @param commonHandler The common handler. + */ + public PlayerNameFormatListener(final @NotNull CommonHandler commonHandler) { + this.commonHandler = commonHandler; + } + + /** + * The listener for the {@link PlayerEvent.NameFormat} event. + * + * @param event The event. + */ + @SubscribeEvent + public void onPlayerNameFormat(final PlayerEvent.NameFormat event) { + if (!commonHandler.isOnGrieferGames()) { + return; + } + Utils.updatePlayerNameTag(commonHandler, event.entityPlayer, commonHandler.getListManager().getExistingPrefixes()); + } +} diff --git a/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/util/Utils.java b/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/util/Utils.java new file mode 100644 index 0000000..3594902 --- /dev/null +++ b/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/util/Utils.java @@ -0,0 +1,130 @@ +/* + * Copyright 2024 - present CommunityRadarGG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.communityradargg.forgemod.util; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.IChatComponent; +import net.minecraft.world.World; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; +import java.util.Set; +import java.util.UUID; + +/** + * A class with some util methods. + */ +public class Utils { + /** + * Gets a {@link NetworkPlayerInfo} by the uuid of a player. + * + * @param uuid The uuid to get the network player info for. + * @return Returns an optional with the network player info of an online player to the uuid. + */ + private static @NotNull Optional getNetworkPlayerInfoByUuid(final @NotNull UUID uuid) { + return Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap().stream() + .filter(player -> player.getGameProfile() != null && uuid.equals(player.getGameProfile().getId())) + .findFirst(); + } + + /** + * Gets a {@link EntityPlayer} by the uuid of a player. + * + * @param uuid The uuid to get the entity player for. + * @return Returns an optional with the entity player to the uuid. + */ + private static @NotNull Optional getEntityPlayerByUuid(final @NotNull UUID uuid) { + final World world = Minecraft.getMinecraft().theWorld; + if (world == null) { + return Optional.empty(); + } + + return world.playerEntities.stream() + .filter(player -> player.getGameProfile() != null && uuid.equals(player.getGameProfile().getId())) + .findFirst(); + } + + /** + * Updates a player display name and name tag by its uuid. + * + * @param commonHandler The common handler. + * @param uuid The uuid to update the corresponding player. + */ + public static void updatePlayerByUuid(final @NotNull CommonHandler commonHandler, final @NotNull UUID uuid, final @NotNull Set oldPrefixes) { + getEntityPlayerByUuid(uuid).ifPresent(player -> updatePlayerNameTag(commonHandler, player, oldPrefixes)); + getNetworkPlayerInfoByUuid(uuid).ifPresent(networkPlayerInfo -> updatePlayerPrefix(commonHandler, networkPlayerInfo, oldPrefixes)); + } + + /** + * Handles updating the name tag of a player entity. + * + * @param commonHandler The common handler. + * @param player The player entity to update the name tag. + * @param oldPrefixes The old prefixes that need to be removed before adding the new one. + */ + public static void updatePlayerNameTag(final @NotNull CommonHandler commonHandler, final @NotNull EntityPlayer player, final @NotNull Set oldPrefixes) { + player.getPrefixes().removeIf(prefix -> commonHandler.isPrefixMatching(prefix.getUnformattedText(), oldPrefixes)); + final String addonPrefix = commonHandler.getListManager() + .getPrefix(player.getGameProfile().getId()); + + if (!addonPrefix.isEmpty()) { + player.addPrefix(new ChatComponentText(commonHandler.formatPrefix(addonPrefix))); + } + } + + /** + * Handles updating the player prefixes in the display name. + * + * @param commonHandler The common handler. + * @param oldPrefixes The old prefixes that need to be removed before adding the new one. + */ + public static void updatePrefixes(final @NotNull CommonHandler commonHandler, final @NotNull Set oldPrefixes) { + Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap() + .forEach(player -> updatePlayerPrefix(commonHandler, player, oldPrefixes)); + } + + /** + * Handles updating the player prefix in the display name of a single player. + * + * @param commonHandler The common handler. + * @param player The player to update. + * @param oldPrefixes The old prefixes that need to be removed before adding the new one. + */ + private static void updatePlayerPrefix(final @NotNull CommonHandler commonHandler, final @NotNull NetworkPlayerInfo player, final @NotNull Set oldPrefixes) { + if (player.getGameProfile().getId() == null || player.getDisplayName() == null) { + return; + } + + final IChatComponent displayName = player.getDisplayName(); + IChatComponent newDisplayName = displayName; + for (final String prefix : oldPrefixes) { + if (!displayName.getUnformattedText().startsWith(commonHandler.unformatPrefixForCompare(prefix))) { + continue; + } + newDisplayName = displayName.getSiblings().get(displayName.getSiblings().size() - 1); + } + + final String addonPrefix = commonHandler.getListManager() + .getPrefix(player.getGameProfile().getId()); + if (!addonPrefix.isEmpty()) { + newDisplayName = new ChatComponentText(commonHandler.formatPrefix(addonPrefix)).appendSibling(newDisplayName); + } + player.setDisplayName(newDisplayName); + } +} diff --git a/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/util/VersionBridgeImpl.java b/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/util/VersionBridgeImpl.java new file mode 100644 index 0000000..61e7fea --- /dev/null +++ b/versions/1.8.9/src/main/java/io/github/communityradargg/forgemod/util/VersionBridgeImpl.java @@ -0,0 +1,83 @@ +package io.github.communityradargg.forgemod.util; + +import com.mojang.authlib.GameProfile; +import net.minecraft.client.Minecraft; +import net.minecraft.client.network.NetHandlerPlayClient; +import net.minecraft.util.ChatComponentText; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.ModContainer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * The version bridge implementation for the 1.8.9 version. + */ +public class VersionBridgeImpl implements VersionBridge { + private static final Logger LOGGER = LogManager.getLogger(VersionBridgeImpl.class); + + @Override + public @NotNull String getVersion() { + final ModContainer modContainer = Loader.instance().getIndexedModList().get(CommonHandler.MOD_ID); + if (modContainer == null) { + return "UNKNOWN"; + } + + return modContainer.getVersion(); + } + + @Override + public void addMessageToChat(final @NotNull String message) { + if (Minecraft.getMinecraft().thePlayer == null) { + LOGGER.warn("Could not add message to chat. Player is null. The message is following: {}", message); + return; + } + + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(message)); + } + + @Override + public boolean isNotInWorld() { + return Minecraft.getMinecraft().theWorld == null; + } + + @Override + public @NotNull List<@NotNull PlayerInfo> getWorldPlayers() { + final NetHandlerPlayClient connection = Minecraft.getMinecraft().getNetHandler(); + if (connection == null) { + return Collections.emptyList(); + } + + return connection.getPlayerInfoMap().stream() + .map(networkPlayerInfo -> { + final GameProfile gameProfile = networkPlayerInfo.getGameProfile(); + return new PlayerInfo(gameProfile.getId(), gameProfile.getName()); + }) + .collect(Collectors.toList()); + } + + @Override + public void updatePlayerByUuid(final @NotNull CommonHandler commonHandler, final @NotNull UUID uuid, final @NotNull Set<@NotNull String> oldPrefixes) { + Utils.updatePlayerByUuid(commonHandler, uuid, oldPrefixes); + } + + @Override + public void updatePrefixes(final @NotNull CommonHandler commonHandler, final @NotNull Set oldPrefixes) { + Utils.updatePrefixes(commonHandler, oldPrefixes); + } + + @Override + public boolean isPlayerListKeyPressed() { + return Minecraft.getMinecraft().gameSettings.keyBindPlayerList.isPressed(); + } + + @Override + public @NotNull String wrapAndUnformatText(final @NotNull String text) { + return new ChatComponentText(text).getUnformattedText(); + } +} diff --git a/src/main/resources/mcmod.info b/versions/1.8.9/src/main/resources/mcmod.info similarity index 100% rename from src/main/resources/mcmod.info rename to versions/1.8.9/src/main/resources/mcmod.info