1
mirror of https://github.com/Shiewk/ViewServerResources.git synced 2026-04-28 03:44:17 +02:00

Make whitelist work

This commit is contained in:
Shy
2024-08-24 15:19:57 +02:00
parent 45afdde854
commit 45d1c075f8
6 changed files with 162 additions and 16 deletions
@@ -4,11 +4,20 @@ import net.fabricmc.api.ModInitializer;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.IOException;
public class ResourcePackPrivacy implements ModInitializer { public class ResourcePackPrivacy implements ModInitializer {
public static final String MOD_ID = "resourcepackprivacy"; public static final String MOD_ID = "resourcepackprivacy";
public static final Logger LOGGER = LoggerFactory.getLogger(ResourcePackPrivacy.class); public static final Logger LOGGER = LoggerFactory.getLogger(ResourcePackPrivacy.class);
public static void logThrowable(IOException e) {
LOGGER.error(e.toString());
for (StackTraceElement element : e.getStackTrace()) {
LOGGER.error(element.toString());
}
}
@Override @Override
public void onInitialize() { public void onInitialize() {
} }
@@ -1,16 +1,112 @@
package de.shiewk.resourcepackprivacy.client; package de.shiewk.resourcepackprivacy.client;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.internal.Streams;
import com.google.gson.stream.JsonWriter;
import de.shiewk.resourcepackprivacy.ResourcePackPrivacy;
import de.shiewk.resourcepackprivacy.event.ChatAnnouncer; import de.shiewk.resourcepackprivacy.event.ChatAnnouncer;
import de.shiewk.resourcepackprivacy.event.ScreenListener; import de.shiewk.resourcepackprivacy.event.ScreenListener;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
import net.minecraft.client.MinecraftClient;
import java.io.*;
import java.net.URL;
public class ResourcePackPrivacyClient implements ClientModInitializer { public class ResourcePackPrivacyClient implements ClientModInitializer {
private static final ObjectArrayList<String> whitelistedURLs = new ObjectArrayList<>();
private static final ObjectArrayList<String> whitelistedHosts = new ObjectArrayList<>();
private static File whitelistFile;
private static final Gson gson = new Gson();
public static boolean allowedURL(URL uRL) {
if (whitelistedURLs.contains(uRL.toString())){
ResourcePackPrivacy.LOGGER.info("URL {} is whitelisted", uRL);
return true;
} else if (whitelistedHosts.contains(uRL.getHost())){
ResourcePackPrivacy.LOGGER.info("Host {} is whitelisted", uRL.getHost());
return true;
}
return false;
}
public static void addWhitelistURL(URL url){
final String urls = url.toString();
ResourcePackPrivacy.LOGGER.info("Whitelist url {}", urls);
if (!whitelistedURLs.contains(urls)){
whitelistedURLs.add(urls);
}
}
public static void addWhitelistHost(URL url){
final String h = url.getHost();
ResourcePackPrivacy.LOGGER.info("Whitelist host {}", h);
if (!whitelistedHosts.contains(h)){
whitelistedHosts.add(h);
}
}
public static void loadConfig(){
ResourcePackPrivacy.LOGGER.info("Loading config");
try (FileReader fr = new FileReader(whitelistFile)){
final JsonObject cfg = gson.fromJson(fr, JsonObject.class);
final JsonObject whitelist = cfg.get("whitelist").getAsJsonObject();
final JsonArray whitelistHosts = whitelist.getAsJsonArray("hosts");
whitelistedHosts.clear();
for (JsonElement whitelistHost : whitelistHosts) {
whitelistedHosts.add(whitelistHost.getAsString());
}
final JsonArray whitelistURLs = whitelist.getAsJsonArray("urls");
whitelistedURLs.clear();
for (JsonElement whitelistURL : whitelistURLs) {
whitelistedURLs.add(whitelistURL.getAsString());
}
} catch (FileNotFoundException e) {
ResourcePackPrivacy.LOGGER.warn("Config file not found");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void saveConfig() {
ResourcePackPrivacy.LOGGER.info("Saving config");
try (FileWriter fw = new FileWriter(whitelistFile)) {
JsonObject cfg = new JsonObject();
JsonObject whitelist = new JsonObject();
JsonArray hosts = new JsonArray();
for (String whitelistedHost : whitelistedHosts) {
hosts.add(whitelistedHost);
}
whitelist.add("hosts", hosts);
JsonArray urls = new JsonArray();
for (String whitelistedURL : whitelistedURLs) {
urls.add(whitelistedURL);
}
whitelist.add("urls", urls);
cfg.add("whitelist", whitelist);
try (JsonWriter jsonWriter = new JsonWriter(fw)) {
Streams.write(cfg, jsonWriter);
}
} catch (IOException e) {
ResourcePackPrivacy.logThrowable(e);
}
}
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
whitelistFile = new File(MinecraftClient.getInstance().runDirectory.getPath() + "/resourcepackprivacy.json");
ScreenEvents.AFTER_INIT.register(new ScreenListener()); ScreenEvents.AFTER_INIT.register(new ScreenListener());
ClientTickEvents.END_CLIENT_TICK.register(new ChatAnnouncer()); ClientTickEvents.END_CLIENT_TICK.register(new ChatAnnouncer());
loadConfig();
} }
} }
@@ -1,24 +1,24 @@
package de.shiewk.resourcepackprivacy.event; package de.shiewk.resourcepackprivacy.event;
import de.shiewk.resourcepackprivacy.ResourcePackPrivacy; import de.shiewk.resourcepackprivacy.client.ResourcePackPrivacyClient;
import de.shiewk.resourcepackprivacy.mixin.AccessorConfirmScreen;
import de.shiewk.resourcepackprivacy.mixin.AccessorConfirmServerResourcePackScreen; import de.shiewk.resourcepackprivacy.mixin.AccessorConfirmServerResourcePackScreen;
import de.shiewk.resourcepackprivacy.mixin.AccessorConfirmServerResourcePackScreenPack; import de.shiewk.resourcepackprivacy.mixin.AccessorConfirmServerResourcePackScreenPack;
import de.shiewk.resourcepackprivacy.mixin.MixinClientCommonNetworkHandler;
import de.shiewk.resourcepackprivacy.screen.ViewResourceURLsScreen; import de.shiewk.resourcepackprivacy.screen.ViewResourceURLsScreen;
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
import net.fabricmc.fabric.api.client.screen.v1.Screens; import net.fabricmc.fabric.api.client.screen.v1.Screens;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ConfirmScreen; import net.minecraft.client.gui.screen.ConfirmScreen;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.*; import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.client.gui.widget.GridWidget;
import net.minecraft.client.gui.widget.SimplePositioningWidget;
import net.minecraft.client.network.ClientCommonNetworkHandler; import net.minecraft.client.network.ClientCommonNetworkHandler;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.awt.*; import java.awt.*;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -46,15 +46,37 @@ public class ScreenListener implements ScreenEvents.AfterInit {
} }
adder.add(createButton(Text.translatable(infos.size() == 1 ? "gui.resourcepackprivacy.viewURL" : "gui.resourcepackprivacy.viewURLs"), btn -> viewURLs(client, screen, infos))); adder.add(createButton(Text.translatable(infos.size() == 1 ? "gui.resourcepackprivacy.viewURL" : "gui.resourcepackprivacy.viewURLs"), btn -> viewURLs(client, screen, infos)));
adder.add(createButton(Text.translatable(infos.size() == 1 ? "gui.resourcepackprivacy.alwaysURL" : "gui.resourcepackprivacy.alwaysURLs"), btn -> btn.active = false)); adder.add(createButton(Text.translatable(infos.size() == 1 ? "gui.resourcepackprivacy.alwaysURL" : "gui.resourcepackprivacy.alwaysURLs"), btn -> whitelistURLsAndAccept(btn, screen, infos)));
adder.add(createLargeButton(Text.translatable("gui.resourcepackprivacy.alwaysHost", Text.literal(infos.getFirst().url().getHost()).withColor(Color.GREEN.getRGB())), btn -> btn.active = false), 2); adder.add(createLargeButton(Text.translatable("gui.resourcepackprivacy.alwaysHost", Text.literal(infos.getFirst().url().getHost()).withColor(Color.GREEN.getRGB())), btn -> whitelistHostsAndAccept(btn, screen, infos)), 2);
gw.refreshPositions(); gw.refreshPositions();
SimplePositioningWidget.setPos(gw, 0, 0, scaledWidth, scaledHeight, 0.5F, 0.875F); SimplePositioningWidget.setPos(gw, 0, 0, scaledWidth, scaledHeight, 0.5F, 0.85F);
gw.forEachChild(buttons::add); gw.forEachChild(buttons::add);
} }
} }
private void whitelistURLsAndAccept(ButtonWidget btn, Screen screen, List<PackInfo> infos){
btn.active = false;
for (PackInfo info : infos) {
ResourcePackPrivacyClient.addWhitelistURL(info.url());
}
ResourcePackPrivacyClient.saveConfig();
accept(screen);
}
private void accept(Screen screen){
((AccessorConfirmScreen) screen).getCallback().accept(true);
}
private void whitelistHostsAndAccept(ButtonWidget btn, Screen screen, List<PackInfo> infos){
btn.active = false;
for (PackInfo info : infos) {
ResourcePackPrivacyClient.addWhitelistHost(info.url());
}
ResourcePackPrivacyClient.saveConfig();
accept(screen);
}
private void viewURLs(MinecraftClient client, Screen screen, List<PackInfo> infos) { private void viewURLs(MinecraftClient client, Screen screen, List<PackInfo> infos) {
client.setScreen(new ViewResourceURLsScreen(screen, infos)); client.setScreen(new ViewResourceURLsScreen(screen, infos));
} }
@@ -0,0 +1,14 @@
package de.shiewk.resourcepackprivacy.mixin;
import it.unimi.dsi.fastutil.booleans.BooleanConsumer;
import net.minecraft.client.gui.screen.ConfirmScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ConfirmScreen.class)
public interface AccessorConfirmScreen {
@Accessor("callback")
BooleanConsumer getCallback();
}
@@ -2,7 +2,7 @@ package de.shiewk.resourcepackprivacy.mixin;
import com.llamalad7.mixinextras.sugar.Local; import com.llamalad7.mixinextras.sugar.Local;
import de.shiewk.resourcepackprivacy.ResourcePackPrivacy; import de.shiewk.resourcepackprivacy.ResourcePackPrivacy;
import net.fabricmc.fabric.mixin.networking.client.accessor.ClientCommonNetworkHandlerAccessor; import de.shiewk.resourcepackprivacy.client.ResourcePackPrivacyClient;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.network.ClientCommonNetworkHandler; import net.minecraft.client.network.ClientCommonNetworkHandler;
@@ -17,7 +17,6 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.awt.*;
import java.net.URL; import java.net.URL;
import java.util.UUID; import java.util.UUID;
@@ -29,12 +28,18 @@ public abstract class MixinClientCommonNetworkHandler {
@Shadow @Final protected MinecraftClient client; @Shadow @Final protected MinecraftClient client;
@Shadow @Final protected ClientConnection connection;
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/s2c/common/ResourcePackSendS2CPacket;hash()Ljava/lang/String;"), method = "onResourcePackSend", cancellable = true) @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/s2c/common/ResourcePackSendS2CPacket;hash()Ljava/lang/String;"), method = "onResourcePackSend", cancellable = true)
public void onResourcePackSend(ResourcePackSendS2CPacket packet, CallbackInfo ci, @Local UUID uUID, @Local URL uRL){ public void onResourcePackSend(ResourcePackSendS2CPacket packet, CallbackInfo ci, @Local UUID uUID, @Local URL uRL){
ResourcePackPrivacy.LOGGER.info(packet.url()); ResourcePackPrivacy.LOGGER.info(packet.url());
String hash = packet.hash(); String hash = packet.hash();
boolean required = packet.required(); if (ResourcePackPrivacyClient.allowedURL(uRL)){
this.client.setScreen(this.createConfirmServerResourcePackScreen(uUID, uRL, hash, required, packet.prompt().orElse(null))); this.client.getServerResourcePackProvider().addResourcePack(uUID, uRL, hash);
ci.cancel(); } else {
boolean required = packet.required();
this.client.setScreen(this.createConfirmServerResourcePackScreen(uUID, uRL, hash, required, packet.prompt().orElse(null)));
ci.cancel();
}
} }
} }
@@ -3,9 +3,9 @@
"minVersion": "0.8", "minVersion": "0.8",
"package": "de.shiewk.resourcepackprivacy.mixin", "package": "de.shiewk.resourcepackprivacy.mixin",
"compatibilityLevel": "JAVA_21", "compatibilityLevel": "JAVA_21",
"mixins": [ "mixins": [],
],
"client": [ "client": [
"AccessorConfirmScreen",
"AccessorConfirmServerResourcePackScreen", "AccessorConfirmServerResourcePackScreen",
"AccessorConfirmServerResourcePackScreenPack", "AccessorConfirmServerResourcePackScreenPack",
"MixinClientCommonNetworkHandler", "MixinClientCommonNetworkHandler",