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:
@@ -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();
|
||||||
|
|
||||||
|
}
|
||||||
+10
-5
@@ -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",
|
||||||
|
|||||||
Reference in New Issue
Block a user