diff --git a/src/main/java/net/shadow/client/ShadowMain.java b/src/main/java/net/shadow/client/ShadowMain.java index 06acf9f..dc63dd1 100644 --- a/src/main/java/net/shadow/client/ShadowMain.java +++ b/src/main/java/net/shadow/client/ShadowMain.java @@ -8,6 +8,7 @@ import coffeeprotect.SkipObfuscation; import net.fabricmc.api.ModInitializer; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.Element; +import net.shadow.client.feature.addon.AddonManager; import net.shadow.client.feature.command.CommandRegistry; import net.shadow.client.feature.gui.FastTickable; import net.shadow.client.feature.gui.notifications.NotificationRenderer; @@ -61,6 +62,10 @@ public class ShadowMain implements ModInitializer { if (!BASE.exists()) { BASE.mkdir(); } + + log(Level.INFO, "Loading addons"); + AddonManager.init(); + ConfigManager.loadState(); log(Level.INFO, "Done initializing"); diff --git a/src/main/java/net/shadow/client/feature/addon/Addon.java b/src/main/java/net/shadow/client/feature/addon/Addon.java new file mode 100644 index 0000000..addf636 --- /dev/null +++ b/src/main/java/net/shadow/client/feature/addon/Addon.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved. + */ + +package net.shadow.client.feature.addon; + +import net.shadow.client.feature.command.Command; +import net.shadow.client.feature.module.AddonModule; + +import java.awt.image.BufferedImage; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +@SuppressWarnings("unused") +public abstract class Addon { + private final AtomicBoolean isEnabled = new AtomicBoolean(false); + + public abstract String getName(); + + public abstract String getDescription(); + + public abstract BufferedImage getIcon(); + + public abstract String[] getAuthors(); + + public abstract List getAdditionalModules(); + + public abstract List getAdditionalCommands(); + + public final void onEnable() { + isEnabled.set(true); + enabled(); + } + + public final void onDisable() { + isEnabled.set(false); + disabled(); + } + + public final boolean isEnabled() { + return isEnabled.get(); + } + + public abstract void enabled(); + + public abstract void disabled(); + + public abstract void reloaded(); +} diff --git a/src/main/java/net/shadow/client/feature/addon/AddonManager.java b/src/main/java/net/shadow/client/feature/addon/AddonManager.java new file mode 100644 index 0000000..abd6e7d --- /dev/null +++ b/src/main/java/net/shadow/client/feature/addon/AddonManager.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved. + */ + +package net.shadow.client.feature.addon; + +import net.shadow.client.ShadowMain; +import net.shadow.client.feature.command.Command; +import net.shadow.client.feature.command.CommandRegistry; +import net.shadow.client.feature.module.AddonModule; +import net.shadow.client.feature.module.ModuleRegistry; +import net.shadow.client.helper.ClassLoaderAddendum; +import org.apache.logging.log4j.Level; + +import java.io.File; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.stream.Collectors; + +public class AddonManager { + public static final File ADDON_DIRECTORY = new File(ShadowMain.BASE, "addons"); + private static final int[] EXPECTED_CLASS_SIGNATURE = new int[]{ + 0xCA, 0xFE, 0xBA, 0xBE + }; + public static AddonManager INSTANCE; + private final ClassLoaderAddendum classLoader = new ClassLoaderAddendum(AddonManager.class.getClassLoader()); + private final List loadedAddons = new ArrayList<>(); + + @SuppressWarnings("ResultOfMethodCallIgnored") + private AddonManager() { + INSTANCE = this; + if (!ADDON_DIRECTORY.isDirectory()) ADDON_DIRECTORY.delete(); + if (!ADDON_DIRECTORY.exists()) ADDON_DIRECTORY.mkdir(); + initializeAddons(); + } + + public static void init() { + new AddonManager(); + } + + void initializeAddons() { + for (File file : Objects.requireNonNull(ADDON_DIRECTORY.listFiles())) { + if (file.getName().endsWith(".jar")) { + ShadowMain.log(Level.INFO, "Attempting to load addon " + file.getName()); + try { + loadAddon(file); + } catch (Throwable e) { + ShadowMain.log(Level.ERROR, "Failed to load " + file.getName()); + e.printStackTrace(); + if (e instanceof NoClassDefFoundError noClassDefFoundError) { + ShadowMain.log(Level.INFO, "This error is in releation to the class file being remapped for the wrong dev environment. If you're running this in a dev environment, this is on you. In this case, please ask the developer(s) for a \"dev\" jar, and use that instead. If not, please report this error to the addon developer(s)."); + ShadowMain.log(Level.INFO, "(Some additional information about the error: ERR:CLASS_MISSING, class " + noClassDefFoundError.getMessage() + " not found)"); + } + if (e instanceof IncompatibleClassChangeError) { + ShadowMain.log(Level.INFO, "This error either occurs because the addon is heavily obfuscated and the obfuscator is bad, or because the addon is built on an outdated shadow SDK. Please report this error to the addon developer(s)."); + } + if (e instanceof ClassCastException) { + ShadowMain.log(Level.INFO, "This error probably occurs because of an outdated shadow SDK. Please report this error to the addon developer(s)."); + } + } + } + } + dispatchEnable(); + } + + public void reload() { + dispatchReload(); + dispatchDisable(); + loadedAddons.clear(); + initializeAddons(); + } + + void dispatchReload() { + for (Addon loadedAddon : loadedAddons) { + loadedAddon.reloaded(); + } + } + + public void disableAddon(Addon addon) { + if (!addon.isEnabled()) throw new IllegalStateException("Addon already disabled"); + addon.onDisable(); + ModuleRegistry.clearCustomModules(addon); + CommandRegistry.clearCustomCommands(addon); + } + + public void enableAddon(Addon addon) { + if (addon.isEnabled()) throw new IllegalStateException("Addon already enabled"); + addon.onEnable(); + List customModules = addon.getAdditionalModules(); + List customCommands = addon.getAdditionalCommands(); + if (customModules != null) for (AddonModule additionalModule : customModules) { + ShadowMain.log(Level.INFO, "Loading module " + additionalModule.getName() + " from addon " + addon.getName()); + ModuleRegistry.registerAddonModule(addon, additionalModule); + } + if (customCommands != null) for (Command customCommand : customCommands) { + ShadowMain.log(Level.INFO, "Loading command " + customCommand.getName() + " from addon " + addon.getName()); + CommandRegistry.registerCustomCommand(addon, customCommand); + } + } + + void dispatchDisable() { + for (Addon loadedAddon : loadedAddons) { + disableAddon(loadedAddon); + } + } + + void dispatchEnable() { + for (Addon loadedAddon : loadedAddons) { + enableAddon(loadedAddon); + } + } + + void loadAddon(File location) throws Exception { + JarFile jf = new JarFile(location); + Addon mainClass = null; + for (JarEntry jarEntry : jf.stream().toList()) { + if (jarEntry.getName().endsWith(".class")) { + System.out.println(jarEntry.getName()); + InputStream stream = jf.getInputStream(jarEntry); + byte[] classBytes = stream.readAllBytes(); + stream.close(); + byte[] cSig = Arrays.copyOfRange(classBytes, 0, 4); + int[] cSigP = new int[4]; + for (int i = 0; i < cSig.length; i++) { + cSigP[i] = Byte.toUnsignedInt(cSig[i]); + } + if (!Arrays.equals(cSigP, EXPECTED_CLASS_SIGNATURE)) { + throw new IllegalStateException( + "Invalid class file signature for " + jarEntry.getName() + ": expected 0x" + Arrays.stream(EXPECTED_CLASS_SIGNATURE) + .mapToObj(value -> Integer.toHexString(value).toUpperCase()) + .collect(Collectors.joining()) + + ", got 0x" + Arrays.stream(cSigP) + .mapToObj(value -> Integer.toHexString(value).toUpperCase()) + .collect(Collectors.joining())); + } + Class loadedClass = classLoader.defineAndGetClass(classBytes); + if (Addon.class.isAssignableFrom(loadedClass)) { + if (mainClass != null) + throw new IllegalStateException("Jarfile " + location.getName() + " has multiple main classes"); + mainClass = (Addon) loadedClass.getDeclaredConstructor().newInstance(); + System.out.println("Found main class " + loadedClass.getName()); + } + + } + } + if (mainClass == null) + throw new IllegalStateException("Jarfile " + location.getName() + " does not have a main class"); + System.out.println("Discovered addon " + mainClass.getName() + " by " + String.join(", ", mainClass.getAuthors())); + loadedAddons.add(mainClass); + } +} + diff --git a/src/main/java/net/shadow/client/feature/command/CommandRegistry.java b/src/main/java/net/shadow/client/feature/command/CommandRegistry.java index 60d9f18..32d82f3 100644 --- a/src/main/java/net/shadow/client/feature/command/CommandRegistry.java +++ b/src/main/java/net/shadow/client/feature/command/CommandRegistry.java @@ -4,6 +4,7 @@ package net.shadow.client.feature.command; +import net.shadow.client.feature.addon.Addon; import net.shadow.client.feature.command.exception.CommandException; import net.shadow.client.feature.command.impl.*; import net.shadow.client.helper.util.Utils; @@ -13,71 +14,98 @@ import java.util.Arrays; import java.util.List; public class CommandRegistry { + private static final List vanillaCommands = new ArrayList<>(); + private static final List customCommands = new ArrayList<>(); + private static final List sharedCommands = new ArrayList<>(); - private static final List commands = new ArrayList<>(); + public static void registerCustomCommand(Addon addon, Command command) { + for (CustomCommandEntry e : customCommands) { + if (e.command.getClass() == command.getClass()) { + throw new IllegalStateException("Command " + command.getClass().getSimpleName() + " already registered"); + } + } + customCommands.add(new CustomCommandEntry(addon, command)); + rebuildSharedCommands(); + } + + public static void clearCustomCommands(Addon addon) { + customCommands.removeIf(customCommandEntry -> customCommandEntry.addon == addon); + rebuildSharedCommands(); + } + + private static void rebuildSharedCommands() { + sharedCommands.clear(); + sharedCommands.addAll(vanillaCommands); + for (CustomCommandEntry customCommand : customCommands) { + sharedCommands.add(customCommand.command); + } + } + + public static void init() { + vanillaCommands.clear(); + vanillaCommands.add(new Toggle()); + vanillaCommands.add(new Config()); + vanillaCommands.add(new Gamemode()); + vanillaCommands.add(new Effect()); + vanillaCommands.add(new Hologram()); + vanillaCommands.add(new Help()); + vanillaCommands.add(new ForEach()); + vanillaCommands.add(new Drop()); + vanillaCommands.add(new Panic()); + vanillaCommands.add(new Rename()); + vanillaCommands.add(new ViewNbt()); + vanillaCommands.add(new Say()); + vanillaCommands.add(new ConfigUtils()); + vanillaCommands.add(new Kill()); + vanillaCommands.add(new Invsee()); + vanillaCommands.add(new RageQuit()); + vanillaCommands.add(new Find()); + vanillaCommands.add(new FakeItem()); + vanillaCommands.add(new Taco()); + vanillaCommands.add(new Bind()); + vanillaCommands.add(new Test()); + vanillaCommands.add(new Kickall()); + vanillaCommands.add(new ItemExploit()); + vanillaCommands.add(new Inject()); + vanillaCommands.add(new ApplyVel()); + vanillaCommands.add(new AsConsole()); + vanillaCommands.add(new Author()); + vanillaCommands.add(new Ban()); + vanillaCommands.add(new Boot()); + vanillaCommands.add(new CheckCmd()); + vanillaCommands.add(new LogFlood()); + vanillaCommands.add(new PermissionLevel()); + vanillaCommands.add(new Crash()); + vanillaCommands.add(new Damage()); + vanillaCommands.add(new Equip()); + vanillaCommands.add(new EVclip()); + vanillaCommands.add(new FloodLuckperms()); + vanillaCommands.add(new ForceOP()); + vanillaCommands.add(new ItemSpoof()); + vanillaCommands.add(new HClip()); + vanillaCommands.add(new Image()); + vanillaCommands.add(new ItemData()); + vanillaCommands.add(new KickSelf()); + vanillaCommands.add(new TitleLag()); + vanillaCommands.add(new LinkWolf()); + vanillaCommands.add(new Poof()); + vanillaCommands.add(new SpawnData()); + vanillaCommands.add(new StopServer()); + vanillaCommands.add(new VClip()); + vanillaCommands.add(new MessageSpam()); + vanillaCommands.add(new ClearInventory()); + } static { // TODO: 18.12.21 add commands init(); } - public static void init() { - commands.clear(); - commands.add(new Toggle()); - commands.add(new Config()); - commands.add(new Gamemode()); - commands.add(new Effect()); - commands.add(new Hologram()); - commands.add(new Help()); - commands.add(new ForEach()); - commands.add(new Drop()); - commands.add(new Panic()); - commands.add(new Rename()); - commands.add(new ViewNbt()); - commands.add(new Say()); - commands.add(new ConfigUtils()); - commands.add(new Kill()); - commands.add(new Invsee()); - commands.add(new RageQuit()); - commands.add(new Find()); - commands.add(new FakeItem()); - commands.add(new Taco()); - commands.add(new Bind()); - commands.add(new Test()); - commands.add(new Kickall()); - commands.add(new ItemExploit()); - commands.add(new Inject()); - commands.add(new ApplyVel()); - commands.add(new AsConsole()); - commands.add(new Author()); - commands.add(new Ban()); - commands.add(new Boot()); - commands.add(new CheckCmd()); - commands.add(new LogFlood()); - commands.add(new PermissionLevel()); - commands.add(new Crash()); - commands.add(new Damage()); - commands.add(new Equip()); - commands.add(new EVclip()); - commands.add(new FloodLuckperms()); - commands.add(new ForceOP()); - commands.add(new ItemSpoof()); - commands.add(new HClip()); - commands.add(new Image()); - commands.add(new ItemData()); - commands.add(new KickSelf()); - commands.add(new TitleLag()); - commands.add(new LinkWolf()); - commands.add(new Poof()); - commands.add(new SpawnData()); - commands.add(new StopServer()); - commands.add(new VClip()); - commands.add(new MessageSpam()); - commands.add(new ClearInventory()); + public static List getCommands() { + return sharedCommands; } - public static List getCommands() { - return commands; + record CustomCommandEntry(Addon addon, Command command) { } public static void execute(String command) { diff --git a/src/main/java/net/shadow/client/feature/gui/clickgui/ClickGUI.java b/src/main/java/net/shadow/client/feature/gui/clickgui/ClickGUI.java index 0885ea4..0ee046a 100644 --- a/src/main/java/net/shadow/client/feature/gui/clickgui/ClickGUI.java +++ b/src/main/java/net/shadow/client/feature/gui/clickgui/ClickGUI.java @@ -162,9 +162,9 @@ public class ClickGUI extends Screen implements FastTickable { for (String s : text) { width = Math.max(width, FontRenderers.getRenderer().getStringWidth(s)); } - if (descX + width > ShadowMain.client.getWindow().getScaledWidth()) { - descX -= (descX + width - ShadowMain.client.getWindow().getScaledWidth()) + 4; - } +// if (descX + width > ShadowMain.client.getWindow().getScaledWidth()) { +// descX -= (descX + width - ShadowMain.client.getWindow().getScaledWidth()) + 4; +// } Vec2f root = Renderer.R2D.renderTooltip(matrices, descX, descY, width + 4, FontRenderers.getRenderer().getMarginHeight() + 4, tooltipColor); float yOffset = 2; for (String s : text) { diff --git a/src/main/java/net/shadow/client/feature/module/AddonModule.java b/src/main/java/net/shadow/client/feature/module/AddonModule.java new file mode 100644 index 0000000..1f6d9f2 --- /dev/null +++ b/src/main/java/net/shadow/client/feature/module/AddonModule.java @@ -0,0 +1,11 @@ +/* + * Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved. + */ + +package net.shadow.client.feature.module; + +public abstract class AddonModule extends Module { + public AddonModule(String n, String d) { + super(n, d, ModuleType.ADDON_PROVIDED); + } +} diff --git a/src/main/java/net/shadow/client/feature/module/Module.java b/src/main/java/net/shadow/client/feature/module/Module.java index cfd7998..e0ddacc 100644 --- a/src/main/java/net/shadow/client/feature/module/Module.java +++ b/src/main/java/net/shadow/client/feature/module/Module.java @@ -45,7 +45,7 @@ public abstract class Module { return this.debuggerEnabled.getValue(); } - public ModuleType getModuleType() { + public final ModuleType getModuleType() { return moduleType; } diff --git a/src/main/java/net/shadow/client/feature/module/ModuleRegistry.java b/src/main/java/net/shadow/client/feature/module/ModuleRegistry.java index dc0f732..582d540 100644 --- a/src/main/java/net/shadow/client/feature/module/ModuleRegistry.java +++ b/src/main/java/net/shadow/client/feature/module/ModuleRegistry.java @@ -5,6 +5,7 @@ package net.shadow.client.feature.module; +import net.shadow.client.feature.addon.Addon; import net.shadow.client.feature.module.impl.combat.*; import net.shadow.client.feature.module.impl.crash.AnimationCrash; import net.shadow.client.feature.module.impl.crash.BookInflator; @@ -20,130 +21,160 @@ import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; public class ModuleRegistry { - static final List modules = new ArrayList<>(); + static final List vanillaModules = new ArrayList<>(); + static final List customModules = new ArrayList<>(); + static final List sharedModuleList = new ArrayList<>(); + + public static void registerAddonModule(Addon source, Module module) { + for (AddonModuleEntry customModule : customModules) { + if (customModule.module.getClass() == module.getClass()) { + throw new IllegalStateException("Module " + module.getClass().getSimpleName() + " already registered"); + } + } + customModules.add(new AddonModuleEntry(source, module)); + rebuildSharedModuleList(); + } static final AtomicBoolean initialized = new AtomicBoolean(false); + public static void clearCustomModules(Addon addon) { + customModules.removeIf(addonModuleEntry -> addonModuleEntry.addon == addon); + rebuildSharedModuleList(); + } + + private static void rebuildSharedModuleList() { + sharedModuleList.clear(); + sharedModuleList.addAll(vanillaModules); + for (AddonModuleEntry customModule : customModules) { + sharedModuleList.add(customModule.module); + } + } + public static void init() { if (initialized.get()) return; initialized.set(true); - modules.clear(); + vanillaModules.clear(); - modules.add(new Flight()); - modules.add(new Sprint()); - modules.add(new Fullbright()); - modules.add(new Hud()); - modules.add(new TargetHud()); + vanillaModules.add(new Flight()); + vanillaModules.add(new Sprint()); + vanillaModules.add(new Fullbright()); + vanillaModules.add(new Hud()); + vanillaModules.add(new TargetHud()); //modules.add(new AntiOffhandCrash()); this should be under anticrash - modules.add(new AntiPacketKick()); - modules.add(new AntiReducedDebugInfo()); - modules.add(new BoatPhase()); - modules.add(new Boaty()); - modules.add(new Boom()); - modules.add(new CaveMapper()); // its fun - modules.add(new InstaBow()); - modules.add(new NoComCrash()); - modules.add(new OffhandCrash()); - modules.add(new OOBCrash()); - modules.add(new Phase()); - modules.add(new VanillaSpoof()); - modules.add(new XRAY()); - modules.add(new Decimator()); - modules.add(new ClickGUI()); - modules.add(new TpRange()); - modules.add(new AnyPlacer()); - modules.add(new FireballDeflector()); // its a fucking utility client saturn - modules.add(new ShulkerDeflector()); - modules.add(new CarpetBomb()); + vanillaModules.add(new AntiPacketKick()); + vanillaModules.add(new AntiReducedDebugInfo()); + vanillaModules.add(new BoatPhase()); + vanillaModules.add(new Boaty()); + vanillaModules.add(new Boom()); + vanillaModules.add(new CaveMapper()); // its fun + vanillaModules.add(new InstaBow()); + vanillaModules.add(new NoComCrash()); + vanillaModules.add(new OffhandCrash()); + vanillaModules.add(new OOBCrash()); + vanillaModules.add(new Phase()); + vanillaModules.add(new VanillaSpoof()); + vanillaModules.add(new XRAY()); + vanillaModules.add(new Decimator()); + vanillaModules.add(new ClickGUI()); + vanillaModules.add(new TpRange()); + vanillaModules.add(new AnyPlacer()); + vanillaModules.add(new FireballDeflector()); // its a fucking utility client saturn + vanillaModules.add(new ShulkerDeflector()); + vanillaModules.add(new CarpetBomb()); //modules.add(new SkinChangeExploit()); litteral fucking joke module, to be re-written as personhider or whatever i named it (skinfuscator is a good name lol) - modules.add(new AutoTrap()); - modules.add(new AutoTnt()); + vanillaModules.add(new AutoTrap()); + vanillaModules.add(new AutoTnt()); //modules.add(new LetThereBeLight()); awful why? - modules.add(new FakeHacker()); - modules.add(new NoFall()); - modules.add(new ESP()); - modules.add(new Tracers()); - modules.add(new Hyperspeed()); - modules.add(new AntiAnvil()); - modules.add(new Swing()); - modules.add(new AimAssist()); - modules.add(new Criticals()); - modules.add(new Killaura()); //TODO: add settings and shit - modules.add(new Velocity()); - modules.add(new AntiAntiXray()); - modules.add(new PingSpoof()); - modules.add(new AutoAttack()); - modules.add(new MouseEars()); //i really wanna remove this one | dont - modules.add(new Spinner()); - modules.add(new AllowFormatCodes()); - modules.add(new InfChatLength()); - modules.add(new NoTitles()); - modules.add(new PortalGUI()); - modules.add(new Timer()); - modules.add(new XCarry()); - modules.add(new AirJump()); //TODO: unshit - modules.add(new AutoElytra()); - modules.add(new Blink()); - modules.add(new Boost()); - modules.add(new EdgeJump()); // UTILITY CLIENT - modules.add(new EdgeSneak()); - modules.add(new EntityFly()); - modules.add(new IgnoreWorldBorder()); //i'll allow it | as you should - modules.add(new InventoryWalk()); - modules.add(new Jesus()); - modules.add(new LongJump()); - modules.add(new MoonGravity()); - modules.add(new NoJumpCooldown()); - modules.add(new NoLevitation()); - modules.add(new NoPush()); - modules.add(new Step()); - modules.add(new Freecam()); - modules.add(new FreeLook()); - modules.add(new ItemByteSize()); // TO BE RE-WRITTEN AS TOOLTIPS | keep it in for now tho - modules.add(new Zoom()); - modules.add(new AutoTool()); // WHY????? this is so useless | how? - modules.add(new BlockTagViewer()); - modules.add(new Annhilator()); - modules.add(new FastUse()); - modules.add(new Flattener()); - modules.add(new GodBridge()); //TODO: add this as a mode to scaffold - modules.add(new InstantBreak()); //TODO: unshit - modules.add(new MassUse()); - modules.add(new NoBreakDelay()); - modules.add(new SurvivalNuker()); - modules.add(new Nuker()); - modules.add(new Scaffold()); - modules.add(new Test()); - modules.add(new BlocksmcFlight()); - modules.add(new NameTags()); - modules.add(new Trail()); - modules.add(new MinehutAdBlocker()); - modules.add(new AutoLavacast()); - modules.add(new Backtrack()); - modules.add(new TabGui()); - modules.add(new Theme()); - modules.add(new AntiCrash()); - modules.add(new ClientSettings()); - modules.add(new NoLiquidFog()); - modules.add(new Spotlight()); - modules.add(new ShowTntPrime()); - modules.add(new ShadowScreen()); - modules.add(new BookInflator()); - modules.add(new BlockHighlighting()); - modules.add(new AutoIgnite()); - modules.add(new DiscordRPC()); - modules.add(new AirPlace()); - modules.add(new AdSpammer()); - modules.add(new AnimationCrash()); - modules.add(new AutoFireball()); - modules.add(new AutoFish()); - modules.add(new AutoRun()); + vanillaModules.add(new FakeHacker()); + vanillaModules.add(new NoFall()); + vanillaModules.add(new ESP()); + vanillaModules.add(new Tracers()); + vanillaModules.add(new Hyperspeed()); + vanillaModules.add(new AntiAnvil()); + vanillaModules.add(new Swing()); + vanillaModules.add(new AimAssist()); + vanillaModules.add(new Criticals()); + vanillaModules.add(new Killaura()); //TODO: add settings and shit + vanillaModules.add(new Velocity()); + vanillaModules.add(new AntiAntiXray()); + vanillaModules.add(new PingSpoof()); + vanillaModules.add(new AutoAttack()); + vanillaModules.add(new MouseEars()); //i really wanna remove this one | dont + vanillaModules.add(new Spinner()); + vanillaModules.add(new AllowFormatCodes()); + vanillaModules.add(new InfChatLength()); + vanillaModules.add(new NoTitles()); + vanillaModules.add(new PortalGUI()); + vanillaModules.add(new Timer()); + vanillaModules.add(new XCarry()); + vanillaModules.add(new AirJump()); //TODO: unshit + vanillaModules.add(new AutoElytra()); + vanillaModules.add(new Blink()); + vanillaModules.add(new Boost()); + vanillaModules.add(new EdgeJump()); // UTILITY CLIENT + vanillaModules.add(new EdgeSneak()); + vanillaModules.add(new EntityFly()); + vanillaModules.add(new IgnoreWorldBorder()); //i'll allow it | as you should + vanillaModules.add(new InventoryWalk()); + vanillaModules.add(new Jesus()); + vanillaModules.add(new LongJump()); + vanillaModules.add(new MoonGravity()); + vanillaModules.add(new NoJumpCooldown()); + vanillaModules.add(new NoLevitation()); + vanillaModules.add(new NoPush()); + vanillaModules.add(new Step()); + vanillaModules.add(new Freecam()); + vanillaModules.add(new FreeLook()); + vanillaModules.add(new ItemByteSize()); // TO BE RE-WRITTEN AS TOOLTIPS | keep it in for now tho + vanillaModules.add(new Zoom()); + vanillaModules.add(new AutoTool()); // WHY????? this is so useless | how? + vanillaModules.add(new BlockTagViewer()); + vanillaModules.add(new Annhilator()); + vanillaModules.add(new FastUse()); + vanillaModules.add(new Flattener()); + vanillaModules.add(new GodBridge()); //TODO: add this as a mode to scaffold + vanillaModules.add(new InstantBreak()); //TODO: unshit + vanillaModules.add(new MassUse()); + vanillaModules.add(new NoBreakDelay()); + vanillaModules.add(new SurvivalNuker()); + vanillaModules.add(new Nuker()); + vanillaModules.add(new Scaffold()); + vanillaModules.add(new Test()); + vanillaModules.add(new BlocksmcFlight()); + vanillaModules.add(new NameTags()); + vanillaModules.add(new Trail()); + vanillaModules.add(new MinehutAdBlocker()); + vanillaModules.add(new AutoLavacast()); + vanillaModules.add(new Backtrack()); + vanillaModules.add(new TabGui()); + vanillaModules.add(new Theme()); + vanillaModules.add(new AntiCrash()); + vanillaModules.add(new ClientSettings()); + vanillaModules.add(new NoLiquidFog()); + vanillaModules.add(new Spotlight()); + vanillaModules.add(new ShowTntPrime()); + vanillaModules.add(new ShadowScreen()); + vanillaModules.add(new BookInflator()); + vanillaModules.add(new BlockHighlighting()); + vanillaModules.add(new AutoIgnite()); + vanillaModules.add(new DiscordRPC()); + vanillaModules.add(new AirPlace()); + vanillaModules.add(new AdSpammer()); + vanillaModules.add(new AnimationCrash()); + vanillaModules.add(new AutoFireball()); + vanillaModules.add(new AutoFish()); + vanillaModules.add(new AutoRun()); + + rebuildSharedModuleList(); } public static List getModules() { if (!initialized.get()) { init(); } - return modules; + return sharedModuleList; + } + + record AddonModuleEntry(Addon addon, Module module) { } @SuppressWarnings("unchecked") diff --git a/src/main/java/net/shadow/client/feature/module/ModuleType.java b/src/main/java/net/shadow/client/feature/module/ModuleType.java index 2d28a53..efedf8e 100644 --- a/src/main/java/net/shadow/client/feature/module/ModuleType.java +++ b/src/main/java/net/shadow/client/feature/module/ModuleType.java @@ -14,7 +14,7 @@ public enum ModuleType { WORLD("World", GameTexture.ICONS_WORLD.getWhere()), EXPLOIT("Exploit", GameTexture.ICONS_EXPLOIT.getWhere()), CRASH("Crash", GameTexture.ICONS_CRASH.getWhere()), - ITEM("Items", GameTexture.ICONS_ITEMS.getWhere()), + ADDON_PROVIDED("Addons", GameTexture.ICONS_ITEMS.getWhere()), GRIEF("Grief", GameTexture.ICONS_GRIEF.getWhere()), COMBAT("Combat", GameTexture.ICONS_COMBAT.getWhere()); diff --git a/src/main/java/net/shadow/client/helper/ClassLoaderAddendum.java b/src/main/java/net/shadow/client/helper/ClassLoaderAddendum.java new file mode 100644 index 0000000..182698a --- /dev/null +++ b/src/main/java/net/shadow/client/helper/ClassLoaderAddendum.java @@ -0,0 +1,18 @@ +/* + * Copyright (c) Shadow client, 0x150, Saturn5VFive 2022. All rights reserved. + */ + +package net.shadow.client.helper; + +import java.net.URL; +import java.net.URLClassLoader; + +public class ClassLoaderAddendum extends URLClassLoader { + public ClassLoaderAddendum(ClassLoader parent) { + super(new URL[0], parent); + } + + public Class defineAndGetClass(byte[] classBytes) { + return super.defineClass(null, classBytes, 0, classBytes.length); + } +}