Skip to content

Commit

Permalink
feat: primitive mod repost finder
Browse files Browse the repository at this point in the history
  • Loading branch information
Jamalam360 committed Feb 4, 2024
1 parent 261474f commit 3ff86e6
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 25 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.20.4 support with no further API changes.
- Functionality to notify the user if we suspect the mod has been downloaded from a repost site such as 9minecraft. See the [docs]().
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ subprojects {
'Implementation-Title' : project.name,
'Implementation-Version': project.jar.archiveVersion,
'Built-On-Java' : "${System.getProperty('java.vm.version')} (${System.getProperty('java.vm.vendor')})",
'Built-On-Minecraft' : minecraft_version
'Built-On-Minecraft' : minecraft_version,
'JamLib-File-Name' : "jamlib-${project.base.archivesName.get()}-${rootProject.version}.jar",
])
}
}
Expand Down
38 changes: 36 additions & 2 deletions common/src/main/java/io/github/jamalam360/jamlib/JamLib.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package io.github.jamalam360.jamlib;

import blue.endless.jankson.Jankson;
import blue.endless.jankson.api.SyntaxError;
import dev.architectury.event.events.client.ClientPlayerEvent;
import dev.architectury.utils.EnvExecutor;
import net.fabricmc.api.EnvType;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.ApiStatus;
import org.slf4j.Logger;
Expand All @@ -12,9 +17,38 @@ public class JamLib {
public static final String MOD_ID = "jamlib";
public static final String MOD_NAME = "JamLib";
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_NAME);
private static final JarRenamingChecker JAR_RENAMING_CHECKER = new JarRenamingChecker();

public static void init() {
LOGGER.info("Initializing JamLib on " + JamLibPlatform.getPlatform());
checkForJarRenaming(JamLib.class);

EnvExecutor.runInEnv(EnvType.CLIENT, () -> () -> ClientPlayerEvent.CLIENT_PLAYER_JOIN.register(JamLib::onPlayerJoin));
}

public static void checkForJarRenaming(Class<?> anyModClass) {
JAR_RENAMING_CHECKER.checkJar(anyModClass);
}

private static void onPlayerJoin(LocalPlayer player) {
if (player != Minecraft.getInstance().player) {
return;
}

if (JAR_RENAMING_CHECKER.getSuspiciousJarsToNotifyAbout().isEmpty()) {
return;
}

player.displayClientMessage(Component.translatable("text.jamlib.renamed_1"), false);

for (String jar : JAR_RENAMING_CHECKER.getSuspiciousJarsToNotifyAbout()) {
player.displayClientMessage(Component.literal(" - " + jar), false);
}

player.displayClientMessage(Component.translatable("text.jamlib.renamed_2"), false);
player.displayClientMessage(Component.translatable("text.jamlib.renamed_3"), false);

JAR_RENAMING_CHECKER.afterNotify();
}

public static ResourceLocation id(String path) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package io.github.jamalam360.jamlib;

import com.google.common.io.Files;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.Manifest;

// 9minecraft and related sites often rename jars.
// This class checks the manifest of a given class to see if it has been renamed.
// For this to work, the jar's manifest file has to have a "JamLib-File-Name" attribute.
@ApiStatus.Internal
public class JarRenamingChecker {
private final List<String> suspiciousJars = new ArrayList<>();
private final File knownSuspiciousJarsFile = new File("config/jamlib/known_suspicious_jars.txt");

public JarRenamingChecker() {
try {
if (!this.knownSuspiciousJarsFile.exists()) {
this.knownSuspiciousJarsFile.getParentFile().mkdirs();
this.knownSuspiciousJarsFile.createNewFile();
}
} catch (IOException ignored) {
JamLib.LOGGER.warn("Failed to create suspicious jar file list, this may cause annoying notifications.");
}
}

public List<String> getSuspiciousJarsToNotifyAbout() {
final List<String> knownSuspiciousJars = new ArrayList<>();

try {
knownSuspiciousJars.addAll(Files.readLines(this.knownSuspiciousJarsFile, Charset.defaultCharset()));
} catch (IOException ignored) {
JamLib.LOGGER.warn("Failed to read known suspicious jar file list, this may cause annoying notifications.");
}

return this.suspiciousJars.stream().filter(jar -> !knownSuspiciousJars.contains(jar)).toList();
}

public void afterNotify() {
try {
Files.asCharSink(this.knownSuspiciousJarsFile, Charset.defaultCharset()).write(String.join("\n", this.suspiciousJars));
} catch (IOException ignored) {
JamLib.LOGGER.warn("Failed to write known suspicious jar file list, this may cause annoying notifications.");
}
}

public void checkJar(Class<?> clazz) {
Manifest manifest = readManifestFromClass(clazz);

if (manifest == null) {
return;
}

String jarName = manifest.getMainAttributes().getValue("JamLib-File-Name");

if (jarName == null) {
return;
}

String[] split = getActualJarPath(clazz).split("/");

if (!jarName.equals(split[split.length - 1])) {
split = getActualJarPath(clazz).split("/");
suspiciousJars.add(split[split.length - 1] + " (should be " + jarName + ")");
}
}

@Nullable
private static Manifest readManifestFromClass(Class<?> clazz) {
try {
String path = getActualJarPath(clazz);
String manifestPath = "jar:file:" + path + "!/META-INF/MANIFEST.MF";
return new Manifest(new URL(manifestPath).openStream());
} catch (Exception ignored) {
// Silently fail, since this functionality is non-critical.
}

return null;
}

private static String getActualJarPath(Class<?> clazz) {
String classFilePath = clazz.getName().replace('.', '/') + ".class";
String path = clazz.getResource("/" + classFilePath).toString();
if (path.startsWith("jar:file:")) {
path = path.substring("jar:file:".length(), path.indexOf("!"));
}

return path;
}
}
6 changes: 5 additions & 1 deletion common/src/main/resources/assets/jamlib/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@
"config.jamlib.reset": "Reset",
"config.jamlib.matches_regex_tooltip": "Value should match the following regular expression: %s",
"config.jamlib.requires_restart_tooltip": "A restart is required for this change to take effect",
"config.jamlib.within_range_tooltip": "Value should be between %d and %d"
"config.jamlib.within_range_tooltip": "Value should be between %d and %d",
"text.jamlib.renamed_1": "The following files seem to have been renamed - this is often a sign of a mod being redistributed without permission.",
"text.jamlib.renamed_2": "Sites such as minecraft harm modders and can be used to distribute malware. Please use official sources such as Curseforge or Modrinth!",
"text.jamlib.renamed_3": "This message will only appear once. If you believe this is a false positive, please contact the mod author."

}
15 changes: 0 additions & 15 deletions common/src/main/resources/jamlib.mixins.json

This file was deleted.

1 change: 0 additions & 1 deletion fabric/src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
]
},
"mixins": [
"jamlib.mixins.json"
],
"depends": {
"fabric": "*",
Expand Down
1 change: 0 additions & 1 deletion forge/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ loom {
convertAccessWideners = true
extraAccessWideners.add loom.accessWidenerPath.get().asFile.name

mixinConfig "jamlib.mixins.json"
mixinConfig "jamlib.forge.mixins.json"
}
}
Expand Down
2 changes: 0 additions & 2 deletions neoforge/src/main/resources/META-INF/mods.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ description = '''
A multi-loader, multi-purpose library for JamCoreModding's mods
'''

[[mixins]]
config = "jamlib.mixins.json"
[[mixins]]
config = "jamlib.neoforge.mixins.json"

Expand Down
1 change: 0 additions & 1 deletion quilt/src/main/resources/quilt.mod.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"schema_version": 1,
"mixin": [
"jamlib.mixins.json"
],
"quilt_loader": {
"group": "io.github.jamalam360",
Expand Down

0 comments on commit 3ff86e6

Please sign in to comment.