mirror of
https://github.com/Miasmusa/Shadow.git
synced 2024-11-15 03:14:54 -05:00
the addon
This commit is contained in:
parent
0d1e20b433
commit
9370619e71
10 changed files with 469 additions and 170 deletions
|
@ -8,6 +8,7 @@ import coffeeprotect.SkipObfuscation;
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.gui.Element;
|
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.command.CommandRegistry;
|
||||||
import net.shadow.client.feature.gui.FastTickable;
|
import net.shadow.client.feature.gui.FastTickable;
|
||||||
import net.shadow.client.feature.gui.notifications.NotificationRenderer;
|
import net.shadow.client.feature.gui.notifications.NotificationRenderer;
|
||||||
|
@ -61,6 +62,10 @@ public class ShadowMain implements ModInitializer {
|
||||||
if (!BASE.exists()) {
|
if (!BASE.exists()) {
|
||||||
BASE.mkdir();
|
BASE.mkdir();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log(Level.INFO, "Loading addons");
|
||||||
|
AddonManager.init();
|
||||||
|
|
||||||
ConfigManager.loadState();
|
ConfigManager.loadState();
|
||||||
|
|
||||||
log(Level.INFO, "Done initializing");
|
log(Level.INFO, "Done initializing");
|
||||||
|
|
49
src/main/java/net/shadow/client/feature/addon/Addon.java
Normal file
49
src/main/java/net/shadow/client/feature/addon/Addon.java
Normal file
|
@ -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<AddonModule> getAdditionalModules();
|
||||||
|
|
||||||
|
public abstract List<Command> 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();
|
||||||
|
}
|
157
src/main/java/net/shadow/client/feature/addon/AddonManager.java
Normal file
157
src/main/java/net/shadow/client/feature/addon/AddonManager.java
Normal file
|
@ -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<Addon> 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<AddonModule> customModules = addon.getAdditionalModules();
|
||||||
|
List<Command> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
package net.shadow.client.feature.command;
|
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.exception.CommandException;
|
||||||
import net.shadow.client.feature.command.impl.*;
|
import net.shadow.client.feature.command.impl.*;
|
||||||
import net.shadow.client.helper.util.Utils;
|
import net.shadow.client.helper.util.Utils;
|
||||||
|
@ -13,71 +14,98 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CommandRegistry {
|
public class CommandRegistry {
|
||||||
|
private static final List<Command> vanillaCommands = new ArrayList<>();
|
||||||
|
private static final List<CustomCommandEntry> customCommands = new ArrayList<>();
|
||||||
|
private static final List<Command> sharedCommands = new ArrayList<>();
|
||||||
|
|
||||||
private static final List<Command> 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 {
|
static {
|
||||||
// TODO: 18.12.21 add commands
|
// TODO: 18.12.21 add commands
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init() {
|
public static List<Command> getCommands() {
|
||||||
commands.clear();
|
return sharedCommands;
|
||||||
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<Command> getCommands() {
|
record CustomCommandEntry(Addon addon, Command command) {
|
||||||
return commands;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void execute(String command) {
|
public static void execute(String command) {
|
||||||
|
|
|
@ -162,9 +162,9 @@ public class ClickGUI extends Screen implements FastTickable {
|
||||||
for (String s : text) {
|
for (String s : text) {
|
||||||
width = Math.max(width, FontRenderers.getRenderer().getStringWidth(s));
|
width = Math.max(width, FontRenderers.getRenderer().getStringWidth(s));
|
||||||
}
|
}
|
||||||
if (descX + width > ShadowMain.client.getWindow().getScaledWidth()) {
|
// if (descX + width > ShadowMain.client.getWindow().getScaledWidth()) {
|
||||||
descX -= (descX + width - ShadowMain.client.getWindow().getScaledWidth()) + 4;
|
// descX -= (descX + width - ShadowMain.client.getWindow().getScaledWidth()) + 4;
|
||||||
}
|
// }
|
||||||
Vec2f root = Renderer.R2D.renderTooltip(matrices, descX, descY, width + 4, FontRenderers.getRenderer().getMarginHeight() + 4, tooltipColor);
|
Vec2f root = Renderer.R2D.renderTooltip(matrices, descX, descY, width + 4, FontRenderers.getRenderer().getMarginHeight() + 4, tooltipColor);
|
||||||
float yOffset = 2;
|
float yOffset = 2;
|
||||||
for (String s : text) {
|
for (String s : text) {
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,7 +45,7 @@ public abstract class Module {
|
||||||
return this.debuggerEnabled.getValue();
|
return this.debuggerEnabled.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModuleType getModuleType() {
|
public final ModuleType getModuleType() {
|
||||||
return moduleType;
|
return moduleType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package net.shadow.client.feature.module;
|
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.combat.*;
|
||||||
import net.shadow.client.feature.module.impl.crash.AnimationCrash;
|
import net.shadow.client.feature.module.impl.crash.AnimationCrash;
|
||||||
import net.shadow.client.feature.module.impl.crash.BookInflator;
|
import net.shadow.client.feature.module.impl.crash.BookInflator;
|
||||||
|
@ -20,130 +21,160 @@ import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class ModuleRegistry {
|
public class ModuleRegistry {
|
||||||
static final List<Module> modules = new ArrayList<>();
|
static final List<Module> vanillaModules = new ArrayList<>();
|
||||||
|
static final List<AddonModuleEntry> customModules = new ArrayList<>();
|
||||||
|
static final List<Module> 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);
|
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() {
|
public static void init() {
|
||||||
if (initialized.get()) return;
|
if (initialized.get()) return;
|
||||||
initialized.set(true);
|
initialized.set(true);
|
||||||
modules.clear();
|
vanillaModules.clear();
|
||||||
|
|
||||||
modules.add(new Flight());
|
vanillaModules.add(new Flight());
|
||||||
modules.add(new Sprint());
|
vanillaModules.add(new Sprint());
|
||||||
modules.add(new Fullbright());
|
vanillaModules.add(new Fullbright());
|
||||||
modules.add(new Hud());
|
vanillaModules.add(new Hud());
|
||||||
modules.add(new TargetHud());
|
vanillaModules.add(new TargetHud());
|
||||||
//modules.add(new AntiOffhandCrash()); this should be under anticrash
|
//modules.add(new AntiOffhandCrash()); this should be under anticrash
|
||||||
modules.add(new AntiPacketKick());
|
vanillaModules.add(new AntiPacketKick());
|
||||||
modules.add(new AntiReducedDebugInfo());
|
vanillaModules.add(new AntiReducedDebugInfo());
|
||||||
modules.add(new BoatPhase());
|
vanillaModules.add(new BoatPhase());
|
||||||
modules.add(new Boaty());
|
vanillaModules.add(new Boaty());
|
||||||
modules.add(new Boom());
|
vanillaModules.add(new Boom());
|
||||||
modules.add(new CaveMapper()); // its fun
|
vanillaModules.add(new CaveMapper()); // its fun
|
||||||
modules.add(new InstaBow());
|
vanillaModules.add(new InstaBow());
|
||||||
modules.add(new NoComCrash());
|
vanillaModules.add(new NoComCrash());
|
||||||
modules.add(new OffhandCrash());
|
vanillaModules.add(new OffhandCrash());
|
||||||
modules.add(new OOBCrash());
|
vanillaModules.add(new OOBCrash());
|
||||||
modules.add(new Phase());
|
vanillaModules.add(new Phase());
|
||||||
modules.add(new VanillaSpoof());
|
vanillaModules.add(new VanillaSpoof());
|
||||||
modules.add(new XRAY());
|
vanillaModules.add(new XRAY());
|
||||||
modules.add(new Decimator());
|
vanillaModules.add(new Decimator());
|
||||||
modules.add(new ClickGUI());
|
vanillaModules.add(new ClickGUI());
|
||||||
modules.add(new TpRange());
|
vanillaModules.add(new TpRange());
|
||||||
modules.add(new AnyPlacer());
|
vanillaModules.add(new AnyPlacer());
|
||||||
modules.add(new FireballDeflector()); // its a fucking utility client saturn
|
vanillaModules.add(new FireballDeflector()); // its a fucking utility client saturn
|
||||||
modules.add(new ShulkerDeflector());
|
vanillaModules.add(new ShulkerDeflector());
|
||||||
modules.add(new CarpetBomb());
|
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 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());
|
vanillaModules.add(new AutoTrap());
|
||||||
modules.add(new AutoTnt());
|
vanillaModules.add(new AutoTnt());
|
||||||
//modules.add(new LetThereBeLight()); awful why?
|
//modules.add(new LetThereBeLight()); awful why?
|
||||||
modules.add(new FakeHacker());
|
vanillaModules.add(new FakeHacker());
|
||||||
modules.add(new NoFall());
|
vanillaModules.add(new NoFall());
|
||||||
modules.add(new ESP());
|
vanillaModules.add(new ESP());
|
||||||
modules.add(new Tracers());
|
vanillaModules.add(new Tracers());
|
||||||
modules.add(new Hyperspeed());
|
vanillaModules.add(new Hyperspeed());
|
||||||
modules.add(new AntiAnvil());
|
vanillaModules.add(new AntiAnvil());
|
||||||
modules.add(new Swing());
|
vanillaModules.add(new Swing());
|
||||||
modules.add(new AimAssist());
|
vanillaModules.add(new AimAssist());
|
||||||
modules.add(new Criticals());
|
vanillaModules.add(new Criticals());
|
||||||
modules.add(new Killaura()); //TODO: add settings and shit
|
vanillaModules.add(new Killaura()); //TODO: add settings and shit
|
||||||
modules.add(new Velocity());
|
vanillaModules.add(new Velocity());
|
||||||
modules.add(new AntiAntiXray());
|
vanillaModules.add(new AntiAntiXray());
|
||||||
modules.add(new PingSpoof());
|
vanillaModules.add(new PingSpoof());
|
||||||
modules.add(new AutoAttack());
|
vanillaModules.add(new AutoAttack());
|
||||||
modules.add(new MouseEars()); //i really wanna remove this one | dont
|
vanillaModules.add(new MouseEars()); //i really wanna remove this one | dont
|
||||||
modules.add(new Spinner());
|
vanillaModules.add(new Spinner());
|
||||||
modules.add(new AllowFormatCodes());
|
vanillaModules.add(new AllowFormatCodes());
|
||||||
modules.add(new InfChatLength());
|
vanillaModules.add(new InfChatLength());
|
||||||
modules.add(new NoTitles());
|
vanillaModules.add(new NoTitles());
|
||||||
modules.add(new PortalGUI());
|
vanillaModules.add(new PortalGUI());
|
||||||
modules.add(new Timer());
|
vanillaModules.add(new Timer());
|
||||||
modules.add(new XCarry());
|
vanillaModules.add(new XCarry());
|
||||||
modules.add(new AirJump()); //TODO: unshit
|
vanillaModules.add(new AirJump()); //TODO: unshit
|
||||||
modules.add(new AutoElytra());
|
vanillaModules.add(new AutoElytra());
|
||||||
modules.add(new Blink());
|
vanillaModules.add(new Blink());
|
||||||
modules.add(new Boost());
|
vanillaModules.add(new Boost());
|
||||||
modules.add(new EdgeJump()); // UTILITY CLIENT
|
vanillaModules.add(new EdgeJump()); // UTILITY CLIENT
|
||||||
modules.add(new EdgeSneak());
|
vanillaModules.add(new EdgeSneak());
|
||||||
modules.add(new EntityFly());
|
vanillaModules.add(new EntityFly());
|
||||||
modules.add(new IgnoreWorldBorder()); //i'll allow it | as you should
|
vanillaModules.add(new IgnoreWorldBorder()); //i'll allow it | as you should
|
||||||
modules.add(new InventoryWalk());
|
vanillaModules.add(new InventoryWalk());
|
||||||
modules.add(new Jesus());
|
vanillaModules.add(new Jesus());
|
||||||
modules.add(new LongJump());
|
vanillaModules.add(new LongJump());
|
||||||
modules.add(new MoonGravity());
|
vanillaModules.add(new MoonGravity());
|
||||||
modules.add(new NoJumpCooldown());
|
vanillaModules.add(new NoJumpCooldown());
|
||||||
modules.add(new NoLevitation());
|
vanillaModules.add(new NoLevitation());
|
||||||
modules.add(new NoPush());
|
vanillaModules.add(new NoPush());
|
||||||
modules.add(new Step());
|
vanillaModules.add(new Step());
|
||||||
modules.add(new Freecam());
|
vanillaModules.add(new Freecam());
|
||||||
modules.add(new FreeLook());
|
vanillaModules.add(new FreeLook());
|
||||||
modules.add(new ItemByteSize()); // TO BE RE-WRITTEN AS TOOLTIPS | keep it in for now tho
|
vanillaModules.add(new ItemByteSize()); // TO BE RE-WRITTEN AS TOOLTIPS | keep it in for now tho
|
||||||
modules.add(new Zoom());
|
vanillaModules.add(new Zoom());
|
||||||
modules.add(new AutoTool()); // WHY????? this is so useless | how?
|
vanillaModules.add(new AutoTool()); // WHY????? this is so useless | how?
|
||||||
modules.add(new BlockTagViewer());
|
vanillaModules.add(new BlockTagViewer());
|
||||||
modules.add(new Annhilator());
|
vanillaModules.add(new Annhilator());
|
||||||
modules.add(new FastUse());
|
vanillaModules.add(new FastUse());
|
||||||
modules.add(new Flattener());
|
vanillaModules.add(new Flattener());
|
||||||
modules.add(new GodBridge()); //TODO: add this as a mode to scaffold
|
vanillaModules.add(new GodBridge()); //TODO: add this as a mode to scaffold
|
||||||
modules.add(new InstantBreak()); //TODO: unshit
|
vanillaModules.add(new InstantBreak()); //TODO: unshit
|
||||||
modules.add(new MassUse());
|
vanillaModules.add(new MassUse());
|
||||||
modules.add(new NoBreakDelay());
|
vanillaModules.add(new NoBreakDelay());
|
||||||
modules.add(new SurvivalNuker());
|
vanillaModules.add(new SurvivalNuker());
|
||||||
modules.add(new Nuker());
|
vanillaModules.add(new Nuker());
|
||||||
modules.add(new Scaffold());
|
vanillaModules.add(new Scaffold());
|
||||||
modules.add(new Test());
|
vanillaModules.add(new Test());
|
||||||
modules.add(new BlocksmcFlight());
|
vanillaModules.add(new BlocksmcFlight());
|
||||||
modules.add(new NameTags());
|
vanillaModules.add(new NameTags());
|
||||||
modules.add(new Trail());
|
vanillaModules.add(new Trail());
|
||||||
modules.add(new MinehutAdBlocker());
|
vanillaModules.add(new MinehutAdBlocker());
|
||||||
modules.add(new AutoLavacast());
|
vanillaModules.add(new AutoLavacast());
|
||||||
modules.add(new Backtrack());
|
vanillaModules.add(new Backtrack());
|
||||||
modules.add(new TabGui());
|
vanillaModules.add(new TabGui());
|
||||||
modules.add(new Theme());
|
vanillaModules.add(new Theme());
|
||||||
modules.add(new AntiCrash());
|
vanillaModules.add(new AntiCrash());
|
||||||
modules.add(new ClientSettings());
|
vanillaModules.add(new ClientSettings());
|
||||||
modules.add(new NoLiquidFog());
|
vanillaModules.add(new NoLiquidFog());
|
||||||
modules.add(new Spotlight());
|
vanillaModules.add(new Spotlight());
|
||||||
modules.add(new ShowTntPrime());
|
vanillaModules.add(new ShowTntPrime());
|
||||||
modules.add(new ShadowScreen());
|
vanillaModules.add(new ShadowScreen());
|
||||||
modules.add(new BookInflator());
|
vanillaModules.add(new BookInflator());
|
||||||
modules.add(new BlockHighlighting());
|
vanillaModules.add(new BlockHighlighting());
|
||||||
modules.add(new AutoIgnite());
|
vanillaModules.add(new AutoIgnite());
|
||||||
modules.add(new DiscordRPC());
|
vanillaModules.add(new DiscordRPC());
|
||||||
modules.add(new AirPlace());
|
vanillaModules.add(new AirPlace());
|
||||||
modules.add(new AdSpammer());
|
vanillaModules.add(new AdSpammer());
|
||||||
modules.add(new AnimationCrash());
|
vanillaModules.add(new AnimationCrash());
|
||||||
modules.add(new AutoFireball());
|
vanillaModules.add(new AutoFireball());
|
||||||
modules.add(new AutoFish());
|
vanillaModules.add(new AutoFish());
|
||||||
modules.add(new AutoRun());
|
vanillaModules.add(new AutoRun());
|
||||||
|
|
||||||
|
rebuildSharedModuleList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Module> getModules() {
|
public static List<Module> getModules() {
|
||||||
if (!initialized.get()) {
|
if (!initialized.get()) {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
return modules;
|
return sharedModuleList;
|
||||||
|
}
|
||||||
|
|
||||||
|
record AddonModuleEntry(Addon addon, Module module) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
|
@ -14,7 +14,7 @@ public enum ModuleType {
|
||||||
WORLD("World", GameTexture.ICONS_WORLD.getWhere()),
|
WORLD("World", GameTexture.ICONS_WORLD.getWhere()),
|
||||||
EXPLOIT("Exploit", GameTexture.ICONS_EXPLOIT.getWhere()),
|
EXPLOIT("Exploit", GameTexture.ICONS_EXPLOIT.getWhere()),
|
||||||
CRASH("Crash", GameTexture.ICONS_CRASH.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()),
|
GRIEF("Grief", GameTexture.ICONS_GRIEF.getWhere()),
|
||||||
COMBAT("Combat", GameTexture.ICONS_COMBAT.getWhere());
|
COMBAT("Combat", GameTexture.ICONS_COMBAT.getWhere());
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue