/* * This file is a part of the SteamWar software. * * Copyright (C) 2026 SteamWar.de-Serverteam * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ package de.steamwar; import java.io.File; import java.io.IOException; import java.lang.instrument.Instrumentation; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; /** * Java agent entry point. * * Can be used two ways: * 1. At JVM startup: java -javaagent:paper-access-widener-agent.jar -jar server.jar * 2. Late attach: from inside a Paper plugin via the Attach API * * On attach the agent: * 1. Scans all existing plugin ClassLoaders for "plugin.accesswidener" resources * 2. Registers a ClassFileTransformer that: * a. Applies widening to every class as it loads * b. Detects new plugin ClassLoaders and scans them automatically * 3. Retransforms any Minecraft/server classes that are already loaded */ public class Agent { private Agent() { throw new IllegalStateException("Utility class"); } private static final Logger LOG = Logger.getLogger("AccessWidenerAgent"); // -javaagent: startup public static void premain(String args, Instrumentation inst) { init(inst); } private static void init(Instrumentation inst) { LOG.info("[AccessWidener] Agent initialising."); List entries = new ArrayList<>(); File file = new File(new File(".").getAbsoluteFile(), "plugins/"); File[] files = file.listFiles(); if (files == null) files = new File[0]; for (File jarFile : files) { if (!jarFile.isFile()) continue; if (!jarFile.getName().endsWith(".jar")) continue; try { entries.addAll(Utils.findAndParseAccessWideners(jarFile.toPath())); } catch (IOException e) { LOG.warning("Failed to parse access wideners from " + jarFile.getAbsolutePath()); } } LOG.info("[AccessWidener] Loaded " + entries.size() + " access wideners."); inst.addTransformer(new WideningTransformer(entries), false); LOG.info("[AccessWidener] Agent ready."); } }