Compare commits

..

34 commits

Author SHA1 Message Date
115c4f0470
fix: use gitversion properly 2024-05-08 23:26:10 +02:00
7640b4f6b8
Merge branch 'dev' of fantabos.co:ftbsc/bscv into dev 2024-02-14 20:31:52 +01:00
5adc5da6cd
feat: block and item id search 2024-02-14 20:30:53 +01:00
f1b2842357
fix: multiblock updates show correctly
the callback blockpos is always the same, clone it to store it and it
now works as intended
2024-01-17 01:46:47 +01:00
57dd48049d
fix: only hide effects when no gui is shown 2024-01-17 00:36:57 +01:00
2893438f64
feat: add distance option to autofish 2024-01-17 00:18:13 +01:00
85f8adb577 Merge branch 'dev' of https://git.fantabos.co/bscv into dev 2024-01-10 23:35:23 +01:00
a2df8fd999 spot player(s) when they enter render distance 2024-01-10 23:35:13 +01:00
63cfbaa56c
feat[containercleaner]: throw whole stacks 2023-11-26 00:07:22 +01:00
aebd63ac13
feat: /mods command lists all mods
badly tho: it doesn't fit on screen and must be read from minecraft logs
2023-11-13 05:02:17 +01:00
b2caa0f762
chore: gitignore factorypath, who creates it? 2023-11-13 04:42:11 +01:00
34b96b67d3
feat: added crude fastcraft 2023-11-13 04:41:06 +01:00
939a0f7a40
fix: typo 2023-11-13 04:40:59 +01:00
cf69868863
feat: use list of integers (ids) for containerclean 2023-11-13 04:27:23 +01:00
0045af0117
chore: better default reach for aura 2023-11-13 04:26:49 +01:00
c2874312d3
feat: added item search command
also renamed because it clashed with import
2023-11-13 04:26:27 +01:00
72333dfd33
chore: NoOverlay is not really a hud mod 2023-11-13 04:26:06 +01:00
399af0c12d
chore: better defaults for VanillaFlight 2023-11-13 04:25:49 +01:00
3638f7f9c1
chore: move regex filters from Highlighter to utils 2023-11-13 04:25:29 +01:00
bfc6d4fef6
feat: added Many setting for collections
still very raw and not super helpful but kind of usable?
2023-11-13 04:24:49 +01:00
add2ea7945
feat: add crude regex containercleaner
also works on self inventory btw
2023-11-12 06:03:18 +01:00
12f1ec92a0
feat: allow to select prefer-looting in autoweapon
yes i know that *technically* a sharp 5 axe has 3 DPS and a god sword
has only 2.9411763880904593 but if a mob dies in 3 attacks, faster
attacks means it will die faster, also looting is usually more
important, to say nothing about fire aspect which deals DoT and sweeping
edge which deals AoE damage. USE THE SWORD!!!!!
2023-11-11 15:29:52 +01:00
b71dcba7a2
feat: updated cursor commands, added block search 2023-11-02 16:52:31 +01:00
6201f66c85
feat: added ruler 2023-11-02 16:52:21 +01:00
78b9ffa352
feat: added initial bad impl of HandChanger 2023-11-02 16:51:55 +01:00
bf5405d64d
feat: allow disabling drift in vanillaflight 2023-06-21 00:15:07 +02:00
134d6fedaa
chore: removed unneeded imports and implements 2023-06-21 00:10:23 +02:00
434b0cc0cc
fix: aura attacks closest target 2023-06-21 00:03:03 +02:00
954a8c806f
Merge branch 'processor5' into dev 2023-06-20 23:54:17 +02:00
f4ec2cddb1
chore: processor version bump 2023-04-12 01:37:22 +02:00
3d2966d986
fix: updated build.gradle 2023-04-06 15:00:42 +02:00
a5271a1d32
fix: reference inner class name in patch finder 2023-04-06 14:46:08 +02:00
9c8a192866
chore: updated to 0.5.1, direct hook targeting 2023-04-02 23:52:02 +02:00
d90f2ca4d9
chore: upgraded patches to lillero-processor 0.5 2023-03-28 14:26:36 +02:00
45 changed files with 994 additions and 360 deletions

3
.gitignore vendored
View file

@ -18,6 +18,9 @@ build
.gradle .gradle
gradle.properties gradle.properties
# ??? gradle again ???
.factorypath
# other # other
eclipse eclipse
run run

View file

@ -6,12 +6,10 @@ plugins {
alias libs.plugins.checkerFramework alias libs.plugins.checkerFramework
} }
version = gitVersion() version = versionDetails().lastTag
group = 'ftbsc' group = 'ftbsc'
archivesBaseName = 'bscv' archivesBaseName = 'bscv'
def shortVersion = version.split('-')[0].replaceAll(".dirty", "") // necessary when there are no extra commits on tags, and thus no dash
project.ext { project.ext {
deployJarDo = getProjectProperty("deployJar.do", "false") deployJarDo = getProjectProperty("deployJar.do", "false")
deployJarTargetDir = getProjectProperty("deployJar.targetDir", ".") deployJarTargetDir = getProjectProperty("deployJar.targetDir", ".")
@ -70,7 +68,7 @@ compileJava { //mappings for lillero-processor
} }
jar { jar {
archiveFileName = "${jar.archiveBaseName.get()}-${shortVersion}.${jar.archiveExtension.get()}" archiveFileName = "${jar.archiveBaseName.get()}-${archiveVersion.get()}.${jar.archiveExtension.get()}"
manifest { manifest {
attributes([ attributes([
"Specification-Title": "bscv", "Specification-Title": "bscv",

View file

@ -4,8 +4,8 @@ gitVersion = "0.13.0"
minecraft = "1.16.5" minecraft = "1.16.5"
forge = "1.16.5-36.2.34" forge = "1.16.5-36.2.34"
autoService = "1.0.1" autoService = "1.0.1"
lillero = "0.3.4" lillero = "0.4.1"
lilleroProcessor = "0.4.2" lilleroProcessor = "0.5.2"
checkerFramework = "0.6.24" checkerFramework = "0.6.24"
[plugins] [plugins]

View file

@ -8,7 +8,7 @@ import ftbsc.bscv.api.IModule;
import ftbsc.bscv.patches.CommandsPatch.CommandsBuiltEvent; import ftbsc.bscv.patches.CommandsPatch.CommandsBuiltEvent;
import ftbsc.bscv.system.Friends; import ftbsc.bscv.system.Friends;
import ftbsc.bscv.system.ModManager; import ftbsc.bscv.system.ModManager;
import ftbsc.bscv.system.PacketHandler; import ftbsc.bscv.system.Ruler;
import net.minecraft.client.gui.screen.IngameMenuScreen; import net.minecraft.client.gui.screen.IngameMenuScreen;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.command.CommandSource; import net.minecraft.command.CommandSource;
@ -28,9 +28,9 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@Mod(Boscovicino.MOD_ID) @Mod("bscv")
public class Boscovicino implements ICommons { public class Boscovicino implements ICommons {
public static final String MOD_ID = "bscv"; public static String MOD_ID = "bscv";
public static final Logger LOGGER = LogManager.getLogger(); public static final Logger LOGGER = LogManager.getLogger();
@ -41,12 +41,10 @@ public class Boscovicino implements ICommons {
public static ForgeConfigSpec spec; public static ForgeConfigSpec spec;
private static Friends friends; private static Friends friends;
public static Friends friends() { return Boscovicino.friends; }
private static PacketHandler packetHandler; @SuppressWarnings("unused") // it just needs to exist to be used by player
private static Ruler ruler;
public static Friends friends() {
return Boscovicino.friends;
}
public Boscovicino() { public Boscovicino() {
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onSetupComplete); FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onSetupComplete);
@ -54,16 +52,15 @@ public class Boscovicino implements ICommons {
ForgeConfigSpec.Builder cfg = new ForgeConfigSpec.Builder(); ForgeConfigSpec.Builder cfg = new ForgeConfigSpec.Builder();
CommandDispatcher<CommandSource> dp = this.dispatcher; CommandDispatcher<CommandSource> dp = this.dispatcher;
// load mods
Boscovicino.modManager = new ModManager(cfg, dp); Boscovicino.modManager = new ModManager(cfg, dp);
Boscovicino.modManager.load(); Boscovicino.modManager.load();
Boscovicino.modManager.finish(); Boscovicino.modManager.finish();
Boscovicino.ruler = new Ruler();
Boscovicino.spec = cfg.build(); Boscovicino.spec = cfg.build();
// initialise packet handler
Boscovicino.packetHandler = new PacketHandler();
// initialise friend manager
ForgeConfigSpec.Builder friendSpec = new ForgeConfigSpec.Builder(); ForgeConfigSpec.Builder friendSpec = new ForgeConfigSpec.Builder();
Boscovicino.friends = new Friends(friendSpec, dp); Boscovicino.friends = new Friends(friendSpec, dp);
@ -71,7 +68,7 @@ public class Boscovicino implements ICommons {
ModLoadingContext.get().registerConfig(Type.CLIENT, spec, "bscv.toml"); ModLoadingContext.get().registerConfig(Type.CLIENT, spec, "bscv.toml");
ModLoadingContext.get().registerConfig(Type.CLIENT, friendSpec.build(), "friends.toml"); ModLoadingContext.get().registerConfig(Type.CLIENT, friendSpec.build(), "friends.toml");
// register ourselves on the event bus // Register ourselves for server and other game events we are interested in
MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(this);
} }
@ -80,14 +77,19 @@ public class Boscovicino implements ICommons {
} }
public static void log(String message) { public static void log(String message) {
log(message, true);
}
public static void log(String message, boolean overlay) {
LOGGER.info(message); LOGGER.info(message);
if (MC.player != null) { if (MC.player != null) {
MC.player.displayClientMessage(new StringTextComponent(message), true); MC.player.displayClientMessage(new StringTextComponent(message), overlay);
} }
} }
private void onSetupComplete(final FMLLoadCompleteEvent event) { private void onSetupComplete(final FMLLoadCompleteEvent event) {
LOGGER.info("Initializing modules"); LOGGER.info("Initializing modules");
for (IModule m : modManager.mods) { for (IModule m : modManager.mods) {
if (m.isEnabled()) { if (m.isEnabled()) {
m.enable(); // re-run enable() to register on the event bus and run enabled callbacks m.enable(); // re-run enable() to register on the event bus and run enabled callbacks

View file

@ -0,0 +1,72 @@
package ftbsc.bscv.commands;
import com.google.auto.service.AutoService;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import ftbsc.bscv.api.ILoadable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands;
import net.minecraft.command.arguments.BlockStateArgument;
import net.minecraft.command.arguments.BlockStateInput;
import static ftbsc.bscv.Boscovicino.log;
@AutoService(ILoadable.class)
public class BlockSearch extends AbstractCommand {
@Override
public String getName() { return "block"; }
public LiteralArgumentBuilder<CommandSource> register(LiteralArgumentBuilder<CommandSource> builder) {
return builder
.then(
Commands.literal("search")
.then(
Commands.argument("id", IntegerArgumentType.integer(0))
.executes( ctx -> {
int block_id = ctx.getArgument("id", Integer.class);
int block_number = block_id >> 4;
int block_meta = block_id & 0b1111;
BlockState state = Block.stateById(block_id);
log("block #[%d:%d]::%d >> %s", block_number, block_meta, block_id, state.toString());
return 1;
})
)
.then(
Commands.argument("number", IntegerArgumentType.integer(0))
.then(
Commands.argument("meta", IntegerArgumentType.integer(0))
.executes( ctx -> {
int block_number = ctx.getArgument("number", Integer.class);
int block_meta = ctx.getArgument("meta", Integer.class);
int block_id = (block_number << 4) | block_meta;
BlockState state = Block.stateById(block_id);
log("block #[%d:%d]::%d >> %s", block_number, block_meta, block_id, state.toString());
return 1;
})
)
)
)
.then(
Commands.literal("id")
.then(
Commands.argument("name", BlockStateArgument.block())
.executes( ctx -> {
BlockStateInput arg = ctx.getArgument("name", BlockStateInput.class);
BlockState state = arg.getState();
int block_id = Block.getId(state);
log("block #[%d:%d] >> %s", block_id >> 4, block_id & 0xF, state.toString());
return 1;
})
)
)
.executes(ctx -> {
log("no block specified");
return 0;
});
}
}

View file

@ -4,6 +4,7 @@ import com.google.auto.service.AutoService;
import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import ftbsc.bscv.api.ILoadable; import ftbsc.bscv.api.ILoadable;
import net.minecraft.block.BlockState;
import net.minecraft.command.CommandSource; import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands; import net.minecraft.command.Commands;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
@ -18,17 +19,18 @@ public class Cursor extends AbstractCommand {
public LiteralArgumentBuilder<CommandSource> register(LiteralArgumentBuilder<CommandSource> builder) { public LiteralArgumentBuilder<CommandSource> register(LiteralArgumentBuilder<CommandSource> builder) {
return builder return builder
.then( .then(
Commands.literal("pos") Commands.literal("info")
.executes(ctx -> { .executes(ctx -> {
switch (MC.hitResult.getType()) { switch (MC.hitResult.getType()) {
case BLOCK: case BLOCK:
BlockRayTraceResult result = (BlockRayTraceResult) MC.hitResult; BlockRayTraceResult result = (BlockRayTraceResult) MC.hitResult;
Direction dir = result.getDirection(); Direction dir = result.getDirection();
BlockPos pos =result.getBlockPos(); BlockPos pos = result.getBlockPos();
log("Block @ %s (%s)", pos.toString(), dir.toString()); BlockState state = MC.level.getBlockState(pos);
log("Block @ %s (%s): %s", pos.toString(), dir.toString(), state.toString());
return 1; return 1;
case ENTITY: case ENTITY:
log("Entity @ %s", MC.hitResult.getLocation().toString()); log("Entity @ %s (TODO!)", MC.hitResult.getLocation().toString());
return 1; return 1;
default: default:
case MISS: case MISS:

View file

@ -1,18 +1,25 @@
package ftbsc.bscv.commands; package ftbsc.bscv.commands;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import ftbsc.bscv.api.ILoadable; import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.tools.Inventory; import ftbsc.bscv.tools.Inventory;
import net.minecraft.command.CommandSource; import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands; import net.minecraft.command.Commands;
import net.minecraft.command.arguments.ItemArgument;
import net.minecraft.command.arguments.ItemInput;
import net.minecraft.inventory.container.Slot; import net.minecraft.inventory.container.Slot;
import net.minecraft.item.Item;
import static ftbsc.bscv.Boscovicino.log; import static ftbsc.bscv.Boscovicino.log;
@AutoService(ILoadable.class) @AutoService(ILoadable.class)
public class Item extends AbstractCommand { public class ItemCommand extends AbstractCommand {
@Override
public String getName() { return "item"; }
public LiteralArgumentBuilder<CommandSource> register(LiteralArgumentBuilder<CommandSource> builder) { public LiteralArgumentBuilder<CommandSource> register(LiteralArgumentBuilder<CommandSource> builder) {
return builder return builder
@ -32,6 +39,29 @@ public class Item extends AbstractCommand {
return 1; return 1;
}) })
) )
.then(
Commands.literal("search")
.then(
Commands.argument("id", IntegerArgumentType.integer(0))
.executes(ctx -> {
int item_id = ctx.getArgument("id", Integer.class);
log("item #[%d] >> %s", item_id, Item.byId(item_id).toString());
return 1;
})
)
)
.then(
Commands.literal("id")
.then(
Commands.argument("name", ItemArgument.item())
.executes( ctx -> {
ItemInput arg = ctx.getArgument("name", ItemInput.class);
Item item = arg.getItem();
log("item #[%d] >> %s", Item.getId(item), item.toString());
return 1;
})
)
)
.executes(ctx -> { .executes(ctx -> {
Slot slot = Inventory.hotbar(MC.player).get(MC.player.inventory.selected); Slot slot = Inventory.hotbar(MC.player).get(MC.player.inventory.selected);
if (!slot.hasItem()) return 0; if (!slot.hasItem()) return 0;

View file

@ -9,7 +9,7 @@ import ftbsc.bscv.api.IModule;
import net.minecraft.command.CommandSource; import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands; import net.minecraft.command.Commands;
import static ftbsc.bscv.Boscovicino.log; import java.util.stream.Collectors;
@AutoService(ILoadable.class) @AutoService(ILoadable.class)
public class ModCommands extends AbstractCommand { public class ModCommands extends AbstractCommand {
@ -43,8 +43,11 @@ public class ModCommands extends AbstractCommand {
}) })
) )
.executes(ctx -> { .executes(ctx -> {
log("no args specified"); String mods = Boscovicino.modManager.mods.stream()
return 0; .map(x -> x.getName())
.collect(Collectors.joining(","));
Boscovicino.log("[ %s ]", mods);
return 1;
}); });
} }

View file

@ -1,6 +1,7 @@
package ftbsc.bscv.modules; package ftbsc.bscv.modules;
import ftbsc.bscv.Boscovicino; import ftbsc.bscv.Boscovicino;
import ftbsc.bscv.tools.Keybind;
import net.minecraft.client.settings.KeyBinding; import net.minecraft.client.settings.KeyBinding;
import net.minecraft.client.util.InputMappings; import net.minecraft.client.util.InputMappings;
import net.minecraftforge.client.event.InputEvent; import net.minecraftforge.client.event.InputEvent;
@ -51,7 +52,7 @@ public abstract class QuickModule extends AbstractModule {
public QuickModule() { public QuickModule() {
super(); super();
this.keybind = new KeyBinding(key_name(this.getName()), this.getDefaultKey(), key_category()); this.keybind = new KeyBinding(Keybind.name(this.getName()), this.getDefaultKey(), Keybind.category());
ClientRegistry.registerKeyBinding(this.keybind); ClientRegistry.registerKeyBinding(this.keybind);
// register a separate subclass on the hook, so that it's always listening // register a separate subclass on the hook, so that it's always listening
@ -76,12 +77,4 @@ public abstract class QuickModule extends AbstractModule {
// ); // );
} }
private static String key_name(String name) {
return String.format("key.%s.%s", Boscovicino.MOD_ID, name);
}
private static String key_category() {
return String.format("key.category.%s", Boscovicino.MOD_ID);
}
} }

View file

@ -3,7 +3,6 @@ package ftbsc.bscv.modules.defense;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import ftbsc.bscv.Boscovicino; import ftbsc.bscv.Boscovicino;
import ftbsc.bscv.ICommons;
import ftbsc.bscv.api.ILoadable; import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.QuickModule; import ftbsc.bscv.modules.QuickModule;
import ftbsc.bscv.modules.self.AutoTool; import ftbsc.bscv.modules.self.AutoTool;
@ -23,7 +22,7 @@ import net.minecraftforge.event.TickEvent.Phase;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
@AutoService(ILoadable.class) @AutoService(ILoadable.class)
public class Aura extends QuickModule implements ICommons { public class Aura extends QuickModule {
private enum LookType { private enum LookType {
NONE, NONE,
@ -53,7 +52,7 @@ public class Aura extends QuickModule implements ICommons {
this.reach = Setting.Decimal.builder() this.reach = Setting.Decimal.builder()
.min(0.) .min(0.)
.fallback(5.) .fallback(4.)
.name("reach") .name("reach")
.comment("aura attack reach") .comment("aura attack reach")
.build(this); .build(this);
@ -129,6 +128,9 @@ public class Aura extends QuickModule implements ICommons {
if (MC.player.getAttackStrengthScale(0.f) < this.strenght.get()) return; if (MC.player.getAttackStrengthScale(0.f) < this.strenght.get()) return;
float distance = Float.MAX_VALUE;
Entity target = null;
for (Entity e : MC.level.entitiesForRendering()) { for (Entity e : MC.level.entitiesForRendering()) {
if (e.equals(MC.player)) continue; if (e.equals(MC.player)) continue;
if (!(e instanceof LivingEntity)) continue; if (!(e instanceof LivingEntity)) continue;
@ -143,13 +145,21 @@ public class Aura extends QuickModule implements ICommons {
} }
if (this.trace.get() && !MC.player.canSee(e)) continue; if (this.trace.get() && !MC.player.canSee(e)) continue;
float dist = MC.player.distanceTo(e);
if (dist < distance) {
distance = dist;
target = e;
}
}
if (target != null) {
switch (this.look.get()) { switch (this.look.get()) {
case ONCE: case ONCE:
MC.player.lookAt(Type.EYES, e.getEyePosition(1.0F)); MC.player.lookAt(Type.EYES, target.getEyePosition(1.0F));
MC.player.connection.send(new CPlayerPacket.RotationPacket(MC.player.yRot, MC.player.xRot, MC.player.isOnGround())); MC.player.connection.send(new CPlayerPacket.RotationPacket(MC.player.yRot, MC.player.xRot, MC.player.isOnGround()));
break; break;
case PACKET: case PACKET:
this.lookAtHidden(Type.EYES, e.getEyePosition(1.0F)); this.lookAtHidden(Type.EYES, target.getEyePosition(1.0F));
break; break;
case NONE: break; case NONE: break;
} }
@ -157,12 +167,10 @@ public class Aura extends QuickModule implements ICommons {
if (this.tool.get()) { if (this.tool.get()) {
this.autotool.selectBestWeapon(); this.autotool.selectBestWeapon();
} }
MC.gameMode.attack(MC.player, e); MC.gameMode.attack(MC.player, target);
if (this.swing.get()) { if (this.swing.get()) {
MC.player.swing(Hand.MAIN_HAND); MC.player.swing(Hand.MAIN_HAND);
} }
break; // TODO should find all valid targets and choose one rather than stopping here
} }
} }
} }

View file

@ -4,6 +4,7 @@ import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import ftbsc.bscv.modules.AbstractModule; import ftbsc.bscv.modules.AbstractModule;
import ftbsc.bscv.tools.Inventory;
import ftbsc.bscv.tools.Setting; import ftbsc.bscv.tools.Setting;
import net.minecraft.client.gui.screen.inventory.ContainerScreen; import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.inventory.container.Slot; import net.minecraft.inventory.container.Slot;
@ -48,38 +49,6 @@ public class Highlighter extends AbstractModule {
this.pattern = Pattern.compile(this.query.get()); this.pattern = Pattern.compile(this.query.get());
} }
private List<String> enchantments(ItemStack stack) {
final ListNBT tags;
if (Items.ENCHANTED_BOOK.equals(stack.getItem())) {
tags = EnchantedBookItem.getEnchantments(stack); // special case to also search book enchants
} else {
tags = stack.getEnchantmentTags();
}
List<String> out = new ArrayList<>();
for (int i = 0; i < tags.size(); i++) {
CompoundNBT tag = tags.getCompound(i);
out.add(String.format("%s %s", tag.getString("id"), tag.getInt("lvl")));
}
return out;
}
private boolean matches(ItemStack stack) {
if (stack.isEmpty()) return false;
String displayName = stack.getDisplayName().getString();
if (this.pattern.matcher(displayName).find()) return true;
if (Items.ENCHANTED_BOOK.equals(stack.getItem()) || stack.isEnchanted()) {
for (String ench : this.enchantments(stack)) {
if (this.pattern.matcher(ench).find()) return true;
}
}
return false;
}
@SubscribeEvent @SubscribeEvent
public void onGuiContainerDraw(GuiContainerEvent.DrawBackground event) { public void onGuiContainerDraw(GuiContainerEvent.DrawBackground event) {
MatrixStack matrix = event.getMatrixStack(); MatrixStack matrix = event.getMatrixStack();
@ -91,7 +60,7 @@ public class Highlighter extends AbstractModule {
for (Slot slot : screen.getMenu().slots) { for (Slot slot : screen.getMenu().slots) {
ItemStack stack = slot.getItem(); ItemStack stack = slot.getItem();
if (this.matches(stack)) { if (Inventory.matchItem(this.pattern, stack)) {
GuiUtils.drawGradientRect( GuiUtils.drawGradientRect(
matrix.last().pose(), 0, matrix.last().pose(), 0,
slot.x, slot.y, slot.x + 16, slot.y + 16, slot.x, slot.y, slot.x + 16, slot.y + 16,

View file

@ -3,7 +3,7 @@ package ftbsc.bscv.modules.hud;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import ftbsc.bscv.api.ILoadable; import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.HudModule; import ftbsc.bscv.modules.HudModule;
import ftbsc.bscv.system.PacketHandler.PacketEvent; import ftbsc.bscv.patches.PacketPatch.PacketEvent;
import ftbsc.bscv.tools.Setting; import ftbsc.bscv.tools.Setting;
import net.minecraft.client.network.play.NetworkPlayerInfo; import net.minecraft.client.network.play.NetworkPlayerInfo;
import net.minecraft.network.play.server.SUpdateTimePacket; import net.minecraft.network.play.server.SUpdateTimePacket;
@ -175,11 +175,14 @@ public class InfoDisplay extends HudModule {
@SubscribeEvent @SubscribeEvent
public void onRenderOverlay(RenderGameOverlayEvent event) { public void onRenderOverlay(RenderGameOverlayEvent event) {
if (event.getType() == ElementType.POTION_ICONS) { if (
if (this.hide_effects.get() && event.isCancelable()) { event.getType() == ElementType.POTION_ICONS
&& MC.screen == null
&& this.hide_effects.get()
&& event.isCancelable()
) {
event.setCanceled(true); event.setCanceled(true);
} }
}
if (event.getType() != ElementType.TEXT) return; if (event.getType() != ElementType.TEXT) return;
if (this.shouldHide()) return; if (this.shouldHide()) return;

View file

@ -1,19 +1,38 @@
package ftbsc.bscv.modules.hud; package ftbsc.bscv.modules.hud;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import ftbsc.bscv.ICommons;
import ftbsc.bscv.api.ILoadable; import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.HudModule; import ftbsc.bscv.modules.HudModule;
import ftbsc.bscv.tools.Setting;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import static ftbsc.bscv.tools.Text.TextBuilder; import static ftbsc.bscv.tools.Text.TextBuilder;
import static ftbsc.bscv.Boscovicino.log;
@AutoService(ILoadable.class) @AutoService(ILoadable.class)
public class PlayerList extends HudModule implements ICommons { public class PlayerList extends HudModule {
public final ForgeConfigSpec.ConfigValue<Boolean> notify;
public PlayerList() {
super();
this.notify = Setting.Bool.builder()
.fallback(false)
.name("notify")
.comment("notify when players enter render distance")
.build(this);
}
@SubscribeEvent @SubscribeEvent
public void onRenderOverlay(RenderGameOverlayEvent event) { public void onRenderOverlay(RenderGameOverlayEvent event) {
@ -35,4 +54,14 @@ public class PlayerList extends HudModule implements ICommons {
offset += MC.font.lineHeight; offset += MC.font.lineHeight;
} }
} }
@SubscribeEvent
public void onEntityEntersRenderdistance(EntityJoinWorldEvent event) {
if (!notify.get()) return;
if (event.getEntity() instanceof PlayerEntity){
PlayerEntity player = (PlayerEntity) event.getEntity();
if (MC.player != null && player.getId() == MC.player.getId()) return;
log(String.format("%s spotted", player.getDisplayName().getString()), false);
}
}
} }

View file

@ -3,7 +3,8 @@ package ftbsc.bscv.modules.motion;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import ftbsc.bscv.api.ILoadable; import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.QuickModule; import ftbsc.bscv.modules.QuickModule;
import ftbsc.bscv.system.PacketHandler.PacketEvent; import ftbsc.bscv.patches.PacketPatch.PacketEvent;
import ftbsc.bscv.tools.Keyboard;
import ftbsc.bscv.tools.Setting; import ftbsc.bscv.tools.Setting;
import net.minecraft.network.play.client.CPlayerPacket; import net.minecraft.network.play.client.CPlayerPacket;
import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.math.vector.Vector3d;
@ -24,6 +25,7 @@ public class VanillaFlight extends QuickModule {
private static final int MS_PER_TICK = 50; private static final int MS_PER_TICK = 50;
public final ForgeConfigSpec.ConfigValue<Boolean> force; public final ForgeConfigSpec.ConfigValue<Boolean> force;
public final ForgeConfigSpec.ConfigValue<Boolean> drift;
public final ForgeConfigSpec.ConfigValue<Double> speed; public final ForgeConfigSpec.ConfigValue<Double> speed;
public final ForgeConfigSpec.ConfigValue<AntikickMode> antikick; public final ForgeConfigSpec.ConfigValue<AntikickMode> antikick;
public final ForgeConfigSpec.ConfigValue<Double> antikick_magnitude; public final ForgeConfigSpec.ConfigValue<Double> antikick_magnitude;
@ -38,18 +40,24 @@ public class VanillaFlight extends QuickModule {
this.force = Setting.Bool.builder() this.force = Setting.Bool.builder()
.name("force") .name("force")
.comment("force enable flight on user") .comment("force enable flight on user")
.fallback(true)
.build(this);
this.drift = Setting.Bool.builder()
.name("drift")
.comment("gradually reduce momentum")
.fallback(false) .fallback(false)
.build(this); .build(this);
this.speed = Setting.Decimal.builder() this.speed = Setting.Decimal.builder()
.min(0.) .min(0.)
.fallback(0.05) .fallback(0.1)
.name("speed") .name("speed")
.comment("flight speed to set") .comment("flight speed to set")
.build(this); .build(this);
this.antikick = Setting.Switch.builder(AntikickMode.class) this.antikick = Setting.Switch.builder(AntikickMode.class)
.fallback(AntikickMode.NONE) .fallback(AntikickMode.PACKET)
.name("antikick") .name("antikick")
.comment("prevent vanilla flight kick by descending") .comment("prevent vanilla flight kick by descending")
.build(this); .build(this);
@ -101,6 +109,10 @@ public class VanillaFlight extends QuickModule {
MC.player.abilities.flying = true; MC.player.abilities.flying = true;
} }
if (!this.drift.get() && !Keyboard.isMoving()) {
MC.player.setDeltaMovement(Vector3d.ZERO);
}
this.tick = ( this.tick + 1 ) % this.antikick_cycle.get(); this.tick = ( this.tick + 1 ) % this.antikick_cycle.get();
Vector3d pos = MC.player.position(); Vector3d pos = MC.player.position();

View file

@ -24,7 +24,7 @@ import com.google.gson.JsonPrimitive;
import ftbsc.bscv.Boscovicino; import ftbsc.bscv.Boscovicino;
import ftbsc.bscv.api.ILoadable; import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.QuickModule; import ftbsc.bscv.modules.QuickModule;
import ftbsc.bscv.system.PacketHandler.PacketEvent; import ftbsc.bscv.patches.PacketPatch.PacketEvent;
import net.minecraft.network.IPacket; import net.minecraft.network.IPacket;
import net.minecraft.util.math.vector.Vector2f; import net.minecraft.util.math.vector.Vector2f;
import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.math.vector.Vector3d;

View file

@ -1,10 +1,9 @@
package ftbsc.bscv.modules.self; package ftbsc.bscv.modules.self;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import ftbsc.bscv.ICommons;
import ftbsc.bscv.api.ILoadable; import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.AbstractModule; import ftbsc.bscv.modules.AbstractModule;
import ftbsc.bscv.system.PacketHandler.PacketEvent; import ftbsc.bscv.patches.PacketPatch.PacketEvent;
import ftbsc.bscv.tools.Setting; import ftbsc.bscv.tools.Setting;
import net.minecraft.network.play.client.CEntityActionPacket; import net.minecraft.network.play.client.CEntityActionPacket;
import net.minecraft.network.play.client.CEntityActionPacket.Action; import net.minecraft.network.play.client.CEntityActionPacket.Action;
@ -13,7 +12,7 @@ import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
@AutoService(ILoadable.class) @AutoService(ILoadable.class)
public class AntiHunger extends AbstractModule implements ICommons { public class AntiHunger extends AbstractModule {
public final ForgeConfigSpec.ConfigValue<Boolean> sprint; public final ForgeConfigSpec.ConfigValue<Boolean> sprint;
public final ForgeConfigSpec.ConfigValue<Boolean> hover; public final ForgeConfigSpec.ConfigValue<Boolean> hover;

View file

@ -1,10 +1,9 @@
package ftbsc.bscv.modules.self; package ftbsc.bscv.modules.self;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import ftbsc.bscv.ICommons;
import ftbsc.bscv.api.ILoadable; import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.AbstractModule; import ftbsc.bscv.modules.AbstractModule;
import ftbsc.bscv.system.PacketHandler.PacketEvent; import ftbsc.bscv.patches.PacketPatch.PacketEvent;
import ftbsc.bscv.tools.Setting; import ftbsc.bscv.tools.Setting;
import net.minecraft.network.play.server.SDisconnectPacket; import net.minecraft.network.play.server.SDisconnectPacket;
import net.minecraft.network.play.server.SUpdateHealthPacket; import net.minecraft.network.play.server.SUpdateHealthPacket;
@ -13,7 +12,7 @@ import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
@AutoService(ILoadable.class) @AutoService(ILoadable.class)
public class AutoDisconnect extends AbstractModule implements ICommons { public class AutoDisconnect extends AbstractModule {
public final ForgeConfigSpec.ConfigValue<Double> threshold; public final ForgeConfigSpec.ConfigValue<Double> threshold;

View file

@ -1,23 +1,24 @@
package ftbsc.bscv.modules.self; package ftbsc.bscv.modules.self;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import ftbsc.bscv.ICommons;
import ftbsc.bscv.api.ILoadable; import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.AbstractModule; import ftbsc.bscv.modules.AbstractModule;
import ftbsc.bscv.system.PacketHandler.PacketEvent; import ftbsc.bscv.patches.PacketPatch.PacketEvent;
import ftbsc.bscv.tools.Setting; import ftbsc.bscv.tools.Setting;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.network.play.server.SPlaySoundEffectPacket; import net.minecraft.network.play.server.SPlaySoundEffectPacket;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.SoundEvents; import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
@AutoService(ILoadable.class) @AutoService(ILoadable.class)
public class AutoFish extends AbstractModule implements ICommons { public class AutoFish extends AbstractModule {
public final ForgeConfigSpec.ConfigValue<Boolean> recast; public final ForgeConfigSpec.ConfigValue<Boolean> recast;
public final ForgeConfigSpec.ConfigValue<Integer> delay; public final ForgeConfigSpec.ConfigValue<Integer> delay;
public final ForgeConfigSpec.ConfigValue<Double> distance;
// public final ForgeConfigSpec.ConfigValue<Long> reaction; // public final ForgeConfigSpec.ConfigValue<Long> reaction;
public AutoFish() { public AutoFish() {
@ -34,13 +35,23 @@ public class AutoFish extends AbstractModule implements ICommons {
.name("delay") .name("delay")
.comment("how long in ms to wait before recasting hook") .comment("how long in ms to wait before recasting hook")
.build(this); .build(this);
this.distance = Setting.Decimal.builder()
.fallback(0.)
.name("distance")
.comment("ignore splashes further than X blocks, set to 0 to disable")
.build(this);
} }
@SubscribeEvent @SubscribeEvent
public void onPacket(PacketEvent.Incoming event) { public void onPacket(PacketEvent.Incoming event) {
if (event.packet instanceof SPlaySoundEffectPacket) { if (event.packet instanceof SPlaySoundEffectPacket) {
SPlaySoundEffectPacket packet = (SPlaySoundEffectPacket) event.packet; SPlaySoundEffectPacket packet = (SPlaySoundEffectPacket) event.packet;
if (packet.getSound().equals(SoundEvents.FISHING_BOBBER_SPLASH)) { Vector3d location = new Vector3d(packet.getX(), packet.getY(), packet.getZ());
if (
packet.getSound().equals(SoundEvents.FISHING_BOBBER_SPLASH)
&& (this.distance.get() == 0 || MC.player.position().distanceTo(location) < this.distance.get())
) {
MC.gameMode.useItem(MC.player, MC.level, Hand.MAIN_HAND); MC.gameMode.useItem(MC.player, MC.level, Hand.MAIN_HAND);
if (this.recast.get()) { if (this.recast.get()) {
new RecastThread(MC, this.delay.get()).start(); new RecastThread(MC, this.delay.get()).start();
@ -49,6 +60,7 @@ public class AutoFish extends AbstractModule implements ICommons {
} }
} }
// TODO don't spawn a thread, minecraft has a way to schedule actions for later
private class RecastThread extends Thread { private class RecastThread extends Thread {
private long delay; private long delay;
private Minecraft mc; private Minecraft mc;

View file

@ -1,12 +1,14 @@
package ftbsc.bscv.modules.self; package ftbsc.bscv.modules.self;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import ftbsc.bscv.ICommons;
import ftbsc.bscv.Boscovicino;
import ftbsc.bscv.api.ILoadable; import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.AbstractModule; import ftbsc.bscv.modules.AbstractModule;
import ftbsc.bscv.tools.Inventory; import ftbsc.bscv.tools.Inventory;
import ftbsc.bscv.tools.Setting; import ftbsc.bscv.tools.Setting;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.inventory.container.Slot; import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.BlockRayTraceResult;
@ -17,9 +19,10 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
import java.util.List; import java.util.List;
@AutoService(ILoadable.class) @AutoService(ILoadable.class)
public class AutoTool extends AbstractModule implements ICommons { public class AutoTool extends AbstractModule {
public final ForgeConfigSpec.ConfigValue<Integer> limit; public final ForgeConfigSpec.ConfigValue<Integer> limit;
public final ForgeConfigSpec.ConfigValue<Boolean> prefer_looting;
public AutoTool() { public AutoTool() {
super(); super();
@ -29,6 +32,12 @@ public class AutoTool extends AbstractModule implements ICommons {
.comment("durability limit for tools, set to 0 to destroy them") .comment("durability limit for tools, set to 0 to destroy them")
.fallback(1) .fallback(1)
.build(this); .build(this);
this.prefer_looting = Setting.Bool.builder()
.name("prefer-looting")
.comment("when picking best weapon, prefer looting over slight more DPS")
.fallback(true)
.build(this);
} }
private boolean itemIsTooDamaged(ItemStack item) { private boolean itemIsTooDamaged(ItemStack item) {
@ -48,6 +57,12 @@ public class AutoTool extends AbstractModule implements ICommons {
} }
double damage = Inventory.itemDPS(item); double damage = Inventory.itemDPS(item);
int looting = Inventory.getEnchLevel(item, Enchantments.MOB_LOOTING);
if (this.prefer_looting.get() && looting > 0) {
damage += 0.1 * looting;
}
if (damage > current_damage) { if (damage > current_damage) {
current_slot = i; current_slot = i;
current_damage = damage; current_damage = damage;

View file

@ -0,0 +1,79 @@
package ftbsc.bscv.modules.self;
import java.util.ArrayList;
import java.util.List;
import com.google.auto.service.AutoService;
import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.AbstractModule;
import ftbsc.bscv.tools.Inventory;
import ftbsc.bscv.tools.Setting;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.command.arguments.ItemArgument;
import net.minecraft.command.arguments.ItemInput;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.Item;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.event.TickEvent.ClientTickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
@AutoService(ILoadable.class)
public class ContainerCleaner extends AbstractModule {
public final ForgeConfigSpec.ConfigValue<Integer> cooldown;
public final ForgeConfigSpec.ConfigValue<Boolean> limit;
public final ForgeConfigSpec.ConfigValue<Boolean> all;
public final ForgeConfigSpec.ConfigValue<List<? extends Integer>> blacklist;
private int counter;
public ContainerCleaner() {
super();
this.counter = 0;
this.cooldown = Setting.Number.builder()
.fallback(0)
.name("cooldown")
.comment("ticks before throwing next item")
.build(this);
this.limit = Setting.Bool.builder()
.fallback(true)
.name("limit")
.comment("limit to one action per tick")
.build(this);
this.all = Setting.Bool.builder()
.fallback(true)
.name("all")
.comment("throw whole stacks instead of single items")
.build(this);
this.blacklist = new Setting.Many<ItemInput, Integer>(ItemArgument.item(), ItemInput.class)
.writer(x -> Item.getId(x.getItem()))
.fallback(new ArrayList<Integer>())
.name("blacklist")
.comment("items to throw away")
.build(this);
}
@SubscribeEvent
public void onTick(ClientTickEvent event) {
if (MC.screen == null) return;
if (!(MC.screen instanceof ContainerScreen)) return;
if (this.counter > 0) {
this.counter -= 1;
return;
}
ContainerScreen<?> screen = (ContainerScreen<?>) MC.screen;
for (Slot slot : screen.getMenu().slots) {
if (this.blacklist.get().contains(Item.getId(slot.getItem().getItem()))) {
int button = this.all.get() ? 1 : 0;
Inventory.clickSlot(screen.getMenu().containerId, slot.index, button, ClickType.THROW);
this.counter = this.cooldown.get();
if (this.limit.get()) return; // only throw one item per tick
}
}
}
}

View file

@ -0,0 +1,39 @@
package ftbsc.bscv.modules.self;
import com.google.auto.service.AutoService;
import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.AbstractModule;
import ftbsc.bscv.tools.Inventory;
import ftbsc.bscv.tools.Setting;
import net.minecraft.client.gui.screen.inventory.InventoryScreen;
import net.minecraft.inventory.container.ClickType;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.event.TickEvent.ClientTickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
@AutoService(ILoadable.class)
public class FastCraft extends AbstractModule {
public final ForgeConfigSpec.ConfigValue<Boolean> drop;
public FastCraft() {
super();
this.drop = Setting.Bool.builder()
.fallback(false)
.name("drop")
.comment("throw cradted items away instead of moving them back in inventory")
.build(this);
}
@SubscribeEvent
public void onTick(ClientTickEvent event) {
if (MC.screen == null) return;
if (!(MC.screen instanceof InventoryScreen)) return;
InventoryScreen inventory = (InventoryScreen) MC.screen;
if (inventory.getMenu().slots.get(0).hasItem()) {
// TODO can we throw them all? like this it throws one by one
Inventory.clickSlot(0, this.drop.get() ? ClickType.THROW : ClickType.QUICK_MOVE);
}
}
}

View file

@ -1,18 +1,13 @@
package ftbsc.bscv.modules.self; package ftbsc.bscv.modules.self;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import ftbsc.bscv.ICommons;
import ftbsc.bscv.api.ILoadable; import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.QuickModule; import ftbsc.bscv.modules.QuickModule;
import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import java.lang.reflect.Field;
import static ftbsc.bscv.Boscovicino.log;
@AutoService(ILoadable.class) @AutoService(ILoadable.class)
public class FastInteract extends QuickModule implements ICommons { public class FastInteract extends QuickModule {
protected int getDefaultKey() { return UNBOUND; } protected int getDefaultKey() { return UNBOUND; }

View file

@ -2,10 +2,9 @@ package ftbsc.bscv.modules.self;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import ftbsc.bscv.Boscovicino; import ftbsc.bscv.Boscovicino;
import ftbsc.bscv.ICommons;
import ftbsc.bscv.api.ILoadable; import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.QuickModule; import ftbsc.bscv.modules.QuickModule;
import ftbsc.bscv.system.PacketHandler.PacketEvent; import ftbsc.bscv.patches.PacketPatch.PacketEvent;
import ftbsc.bscv.tools.Keyboard; import ftbsc.bscv.tools.Keyboard;
import ftbsc.bscv.tools.Setting; import ftbsc.bscv.tools.Setting;
import net.minecraft.client.entity.player.RemoteClientPlayerEntity; import net.minecraft.client.entity.player.RemoteClientPlayerEntity;
@ -18,7 +17,7 @@ import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
@AutoService(ILoadable.class) @AutoService(ILoadable.class)
public class Freecam extends QuickModule implements ICommons { public class Freecam extends QuickModule {
public final ForgeConfigSpec.ConfigValue<Boolean> log; public final ForgeConfigSpec.ConfigValue<Boolean> log;
public final ForgeConfigSpec.ConfigValue<Double> speed; public final ForgeConfigSpec.ConfigValue<Double> speed;

View file

@ -0,0 +1,72 @@
package ftbsc.bscv.modules.self;
import com.google.auto.service.AutoService;
import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.AbstractModule;
import ftbsc.bscv.tools.Setting;
import net.minecraftforge.client.event.RenderHandEvent;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.eventbus.api.SubscribeEvent;
@AutoService(ILoadable.class)
public class HandChanger extends AbstractModule {
public final ForgeConfigSpec.ConfigValue<Double> main;
public final ForgeConfigSpec.ConfigValue<Double> off;
public final ForgeConfigSpec.ConfigValue<Boolean> cancel_main;
public final ForgeConfigSpec.ConfigValue<Boolean> cancel_off;
public HandChanger() {
super();
this.main = Setting.Decimal.builder()
.min(0.)
.max(1.)
.name("main")
.comment("height of main hand")
.fallback(1.)
.build(this);
this.off = Setting.Decimal.builder()
.min(0.)
.max(1.)
.name("off")
.comment("height of off hand")
.fallback(1.)
.build(this);
this.cancel_main = Setting.Bool.builder()
.name("cancel-main")
.comment("completely prevent main hand rendering")
.fallback(false)
.build(this);
this.cancel_off = Setting.Bool.builder()
.name("cancel-off")
.comment("completely prevent off hand rendering")
.fallback(false)
.build(this);
}
@SubscribeEvent
public void onRenderHands(RenderHandEvent event) {
switch (event.getHand()) {
case MAIN_HAND:
if (this.cancel_main.get()) {
event.setCanceled(true);
} else if (this.main.get() != 1.0) {
MC.gameRenderer.itemInHandRenderer.mainHandHeight = this.main.get().floatValue(); // ACCESSTRANSFORMER public net.minecraft.client.renderer.FirstPersonRenderer field_187469_f
MC.gameRenderer.itemInHandRenderer.oMainHandHeight = this.main.get().floatValue(); // ACCESSTRANSFORMER public net.minecraft.client.renderer.FirstPersonRenderer field_187469_f
}
break;
case OFF_HAND:
if (this.cancel_off.get()) {
event.setCanceled(true);
} else if (this.off.get() != 1.0) {
MC.gameRenderer.itemInHandRenderer.offHandHeight = this.off.get().floatValue(); // ACCESSTRANSFORMER public net.minecraft.client.renderer.FirstPersonRenderer field_187470_g
MC.gameRenderer.itemInHandRenderer.oOffHandHeight = this.off.get().floatValue(); // ACCESSTRANSFORMER public net.minecraft.client.renderer.FirstPersonRenderer field_187470_g
}
break;
}
}
}

View file

@ -7,7 +7,7 @@ import ftbsc.bscv.modules.AbstractModule;
import ftbsc.bscv.patches.BlockPushPatch.PlayerBlockPushEvent; import ftbsc.bscv.patches.BlockPushPatch.PlayerBlockPushEvent;
import ftbsc.bscv.patches.EntityPushPatch.PlayerEntityPushEvent; import ftbsc.bscv.patches.EntityPushPatch.PlayerEntityPushEvent;
import ftbsc.bscv.patches.LiquidPushPatch.PlayerLiquidPushEvent; import ftbsc.bscv.patches.LiquidPushPatch.PlayerLiquidPushEvent;
import ftbsc.bscv.system.PacketHandler.PacketEvent; import ftbsc.bscv.patches.PacketPatch.PacketEvent;
import ftbsc.bscv.tools.Setting; import ftbsc.bscv.tools.Setting;
import net.minecraft.network.play.server.SEntityVelocityPacket; import net.minecraft.network.play.server.SEntityVelocityPacket;
import net.minecraft.network.play.server.SExplosionPacket; import net.minecraft.network.play.server.SExplosionPacket;

View file

@ -1,4 +1,4 @@
package ftbsc.bscv.modules.hud; package ftbsc.bscv.modules.self;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;

View file

@ -5,14 +5,13 @@ import org.lwjgl.opengl.GL11;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
import ftbsc.bscv.ICommons;
import ftbsc.bscv.api.ILoadable; import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.QuickModule; import ftbsc.bscv.modules.QuickModule;
import net.minecraftforge.client.event.RenderLivingEvent; import net.minecraftforge.client.event.RenderLivingEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
@AutoService(ILoadable.class) @AutoService(ILoadable.class)
public class Chams extends QuickModule implements ICommons { public class Chams extends QuickModule {
protected int getDefaultKey() { return UNBOUND; } protected int getDefaultKey() { return UNBOUND; }

View file

@ -1,7 +1,6 @@
package ftbsc.bscv.modules.vision; package ftbsc.bscv.modules.vision;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import ftbsc.bscv.ICommons;
import ftbsc.bscv.api.ILoadable; import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.QuickModule; import ftbsc.bscv.modules.QuickModule;
import net.minecraft.potion.Effect; import net.minecraft.potion.Effect;
@ -12,7 +11,7 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
@AutoService(ILoadable.class) @AutoService(ILoadable.class)
public class Fullbright extends QuickModule implements ICommons { public class Fullbright extends QuickModule {
private final static int NIGHT_VISION_ID = 16; private final static int NIGHT_VISION_ID = 16;
private final static int FOUR_MINUTES_TWENTY_SECONDS = 5204; private final static int FOUR_MINUTES_TWENTY_SECONDS = 5204;

View file

@ -1,7 +1,5 @@
package ftbsc.bscv.modules.vision; package ftbsc.bscv.modules.vision;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
@ -11,8 +9,8 @@ import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import ftbsc.bscv.api.ILoadable; import ftbsc.bscv.api.ILoadable;
import ftbsc.bscv.modules.QuickModule; import ftbsc.bscv.modules.AbstractModule;
import ftbsc.bscv.system.PacketHandler.PacketEvent; import ftbsc.bscv.patches.PacketPatch.PacketEvent;
import ftbsc.bscv.tools.Setting; import ftbsc.bscv.tools.Setting;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
@ -20,8 +18,10 @@ import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.WorldVertexBufferUploader; import net.minecraft.client.renderer.WorldVertexBufferUploader;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.network.play.server.SChangeBlockPacket; import net.minecraft.network.play.server.SChangeBlockPacket;
import net.minecraft.network.play.server.SChunkDataPacket;
import net.minecraft.network.play.server.SMultiBlockChangePacket; import net.minecraft.network.play.server.SMultiBlockChangePacket;
import net.minecraft.util.Tuple; import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.math.vector.Vector3i; import net.minecraft.util.math.vector.Vector3i;
import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.client.event.RenderWorldLastEvent;
@ -31,7 +31,7 @@ import net.minecraftforge.event.TickEvent.Phase;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
@AutoService(ILoadable.class) @AutoService(ILoadable.class)
public class UpdateESP extends QuickModule { public class UpdateESP extends AbstractModule {
public final ForgeConfigSpec.ConfigValue<Integer> duration; public final ForgeConfigSpec.ConfigValue<Integer> duration;
public final ForgeConfigSpec.ConfigValue<Double> alpha; public final ForgeConfigSpec.ConfigValue<Double> alpha;
@ -144,7 +144,7 @@ public class UpdateESP extends QuickModule {
if (event.packet instanceof SMultiBlockChangePacket) { if (event.packet instanceof SMultiBlockChangePacket) {
SMultiBlockChangePacket packet = (SMultiBlockChangePacket) event.packet; SMultiBlockChangePacket packet = (SMultiBlockChangePacket) event.packet;
packet.runUpdates( (pos, state) -> this.updates.add(new Tuple<>(pos, System.currentTimeMillis())) ); packet.runUpdates( (pos, state) -> this.updates.add(new Tuple<>(new BlockPos(pos), System.currentTimeMillis())) );
} }
} }
} }

View file

@ -5,7 +5,7 @@ import ftbsc.lll.processor.annotations.Find;
import ftbsc.lll.processor.annotations.Injector; import ftbsc.lll.processor.annotations.Injector;
import ftbsc.lll.processor.annotations.Patch; import ftbsc.lll.processor.annotations.Patch;
import ftbsc.lll.processor.annotations.Target; import ftbsc.lll.processor.annotations.Target;
import ftbsc.lll.proxies.MethodProxy; import ftbsc.lll.proxies.impl.MethodProxy;
import ftbsc.lll.tools.InsnSequence; import ftbsc.lll.tools.InsnSequence;
import ftbsc.lll.tools.PatternMatcher; import ftbsc.lll.tools.PatternMatcher;
import ftbsc.lll.tools.nodes.MethodProxyInsnNode; import ftbsc.lll.tools.nodes.MethodProxyInsnNode;
@ -20,11 +20,6 @@ import org.objectweb.asm.tree.*;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
public class BackgroundPatch implements ICommons { public class BackgroundPatch implements ICommons {
public static boolean shouldDrawBackground(Screen screen) {
return MinecraftForge.EVENT_BUS.post(new RenderBackgroundEvent(screen));
}
@Cancelable @Cancelable
public static class RenderBackgroundEvent extends Event { public static class RenderBackgroundEvent extends Event {
public final Screen screen; public final Screen screen;
@ -34,15 +29,21 @@ public class BackgroundPatch implements ICommons {
} }
} }
@Patch(value = Screen.class, reason = "add hook to cancel background on some screens") @Patch(Screen.class)
public abstract static class BackgroundOverride implements Opcodes { public abstract static class BackgroundOverride implements Opcodes {
@Find(parent = BackgroundPatch.class) @Find(BackgroundOverride.class)
abstract MethodProxy shouldDrawBackground(); MethodProxy shouldDrawBackground;
@Target
@Target(of = "shouldDrawBackground")
public static boolean shouldDrawBackground(Screen screen) {
return MinecraftForge.EVENT_BUS.post(new RenderBackgroundEvent(screen));
}
@Target(of = "injectCancelBackgroundHook")
abstract void renderBackground(MatrixStack stack, int x); abstract void renderBackground(MatrixStack stack, int x);
@Injector @Injector(reason = "add hook to cancel background on some screens")
public void inject(ClassNode clazz, MethodNode main) { public void injectCancelBackgroundHook(ClassNode clazz, MethodNode main) {
AbstractInsnNode found = PatternMatcher.builder() AbstractInsnNode found = PatternMatcher.builder()
.opcodes(ALOAD, ALOAD, ICONST_0, ICONST_0) .opcodes(ALOAD, ALOAD, ICONST_0, ICONST_0)
.ignoreFrames() .ignoreFrames()
@ -55,7 +56,7 @@ public class BackgroundPatch implements ICommons {
LabelNode skip = new LabelNode(); LabelNode skip = new LabelNode();
InsnSequence is = new InsnSequence(); InsnSequence is = new InsnSequence();
is.add(new VarInsnNode(ALOAD, 0)); is.add(new VarInsnNode(ALOAD, 0));
is.add(new MethodProxyInsnNode(INVOKESTATIC, shouldDrawBackground())); is.add(new MethodProxyInsnNode(INVOKESTATIC, shouldDrawBackground));
is.add(new JumpInsnNode(IFEQ, skip)); is.add(new JumpInsnNode(IFEQ, skip));
is.add(new InsnNode(RETURN)); is.add(new InsnNode(RETURN));
is.add(skip); is.add(skip);

View file

@ -4,7 +4,7 @@ import ftbsc.lll.processor.annotations.Find;
import ftbsc.lll.processor.annotations.Injector; import ftbsc.lll.processor.annotations.Injector;
import ftbsc.lll.processor.annotations.Patch; import ftbsc.lll.processor.annotations.Patch;
import ftbsc.lll.processor.annotations.Target; import ftbsc.lll.processor.annotations.Target;
import ftbsc.lll.proxies.MethodProxy; import ftbsc.lll.proxies.impl.MethodProxy;
import ftbsc.lll.tools.InsnSequence; import ftbsc.lll.tools.InsnSequence;
import ftbsc.lll.tools.nodes.MethodProxyInsnNode; import ftbsc.lll.tools.nodes.MethodProxyInsnNode;
import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.entity.player.ClientPlayerEntity;
@ -20,23 +20,24 @@ public class BlockPushPatch {
@Cancelable @Cancelable
public static class PlayerBlockPushEvent extends Event {} public static class PlayerBlockPushEvent extends Event {}
@Patch(ClientPlayerEntity.class)
public abstract static class BlockCollisionsOverride implements Opcodes {
@Find(BlockCollisionsOverride.class)
MethodProxy shouldCancelBlockCollisions;
@Target(of = "shouldCancelBlockCollisions")
public static boolean shouldCancelBlockCollisions() { public static boolean shouldCancelBlockCollisions() {
return MinecraftForge.EVENT_BUS.post(new PlayerBlockPushEvent()); return MinecraftForge.EVENT_BUS.post(new PlayerBlockPushEvent());
} }
@Patch(value = ClientPlayerEntity.class, reason = "add hook to cancel block collisions") @Target(of = "injectCancelCollisionsHook")
public abstract static class BlockCollisionsOverride implements Opcodes {
@Find(parent = BlockPushPatch.class)
abstract MethodProxy shouldCancelBlockCollisions();
@Target
abstract void moveTowardsClosestSpace(double x, double z); abstract void moveTowardsClosestSpace(double x, double z);
@Injector @Injector(reason = "add hook to cancel block collisions")
public void inject(ClassNode clazz, MethodNode main) { public void injectCancelCollisionsHook(ClassNode clazz, MethodNode main) {
LabelNode skip = new LabelNode(); LabelNode skip = new LabelNode();
InsnSequence is = new InsnSequence(); InsnSequence is = new InsnSequence();
is.add(new MethodProxyInsnNode(INVOKESTATIC, shouldCancelBlockCollisions())); is.add(new MethodProxyInsnNode(INVOKESTATIC, shouldCancelBlockCollisions));
is.add(new JumpInsnNode(IFEQ, skip)); is.add(new JumpInsnNode(IFEQ, skip));
is.add(new InsnNode(RETURN)); is.add(new InsnNode(RETURN));
is.add(skip); is.add(skip);

View file

@ -5,7 +5,7 @@ import ftbsc.lll.processor.annotations.Find;
import ftbsc.lll.processor.annotations.Injector; import ftbsc.lll.processor.annotations.Injector;
import ftbsc.lll.processor.annotations.Patch; import ftbsc.lll.processor.annotations.Patch;
import ftbsc.lll.processor.annotations.Target; import ftbsc.lll.processor.annotations.Target;
import ftbsc.lll.proxies.MethodProxy; import ftbsc.lll.proxies.impl.MethodProxy;
import ftbsc.lll.tools.InsnSequence; import ftbsc.lll.tools.InsnSequence;
import ftbsc.lll.tools.nodes.MethodProxyInsnNode; import ftbsc.lll.tools.nodes.MethodProxyInsnNode;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
@ -30,14 +30,66 @@ public class BoatPatch implements ICommons {
public static class Gravity extends Event { } public static class Gravity extends Event { }
} }
@Patch(BoatEntity.class)
public abstract static class BoatControlOverride implements Opcodes {
@Find(BoatControlOverride.class)
MethodProxy boatControl;
@Target(of = "boatControl")
public static boolean boatControl() { public static boolean boatControl() {
return MinecraftForge.EVENT_BUS.post(new BoatEvent.Control()); return MinecraftForge.EVENT_BUS.post(new BoatEvent.Control());
} }
@Target(of = "injectBoatControlHook")
public abstract void controlBoat();
@Injector(reason = "add hook to cancel vanilla boat controls")
public void injectBoatControlHook(ClassNode clazz, MethodNode main) {
// Hook at method start
LabelNode skip = new LabelNode();
InsnSequence is = new InsnSequence();
is.add(new MethodProxyInsnNode(INVOKESTATIC, boatControl));
is.add(new JumpInsnNode(IFEQ, skip));
is.add(new InsnNode(RETURN));
is.add(skip);
main.instructions.insert(is);
}
}
@Patch(BoatEntity.class)
public abstract static class BoatClampOverride implements Opcodes {
@Find(BoatClampOverride.class)
MethodProxy boatClampRotation;
@Target(of = "boatClampRotation")
public static boolean boatClampRotation() { public static boolean boatClampRotation() {
return MinecraftForge.EVENT_BUS.post(new BoatEvent.ClampRotation()); return MinecraftForge.EVENT_BUS.post(new BoatEvent.ClampRotation());
} }
@Target(of = "injectRotationClampingHook")
public abstract void clampRotation(Entity e);
@Injector(reason = "add hook to cancel vanilla boat rotation clamping")
public void injectRotationClampingHook(ClassNode clazz, MethodNode main) {
// Hook at method start
LabelNode skip = new LabelNode();
InsnSequence is = new InsnSequence();
is.add(new MethodProxyInsnNode(INVOKESTATIC, boatClampRotation));
is.add(new JumpInsnNode(IFEQ, skip));
is.add(new InsnNode(RETURN));
is.add(skip);
main.instructions.insert(is);
}
}
@Patch(Entity.class)
public abstract static class BoatGravityOverride implements Opcodes {
@Find(BoatGravityOverride.class)
MethodProxy boatGravityCheck;
@Target(of = "boatGravityCheck")
public static boolean boatGravityCheck(Entity entity) { public static boolean boatGravityCheck(Entity entity) {
if (MC.player == null) return false; if (MC.player == null) return false;
if (MC.player.getVehicle() == null) return false; if (MC.player.getVehicle() == null) return false;
@ -45,65 +97,16 @@ public class BoatPatch implements ICommons {
return MinecraftForge.EVENT_BUS.post(new BoatEvent.Gravity()); return MinecraftForge.EVENT_BUS.post(new BoatEvent.Gravity());
} }
@Patch(value = BoatEntity.class, reason = "add hook to cancel vanilla boat controls") @Target(of = "injectGravityHook")
public abstract static class BoatControlOverride implements Opcodes {
@Find(parent = BoatPatch.class)
abstract MethodProxy boatControl();
@Target
public abstract void controlBoat();
@Injector
public void inject(ClassNode clazz, MethodNode main) {
// Hook at method start
LabelNode skip = new LabelNode();
InsnSequence is = new InsnSequence();
is.add(new MethodProxyInsnNode(INVOKESTATIC, boatControl()));
is.add(new JumpInsnNode(IFEQ, skip));
is.add(new InsnNode(RETURN));
is.add(skip);
main.instructions.insert(is);
}
}
@Patch(value = BoatEntity.class, reason = "add hook to cancel vanilla boat rotation clamping")
public abstract static class BoatClampOverride implements Opcodes {
@Find(parent = BoatPatch.class)
abstract MethodProxy boatClampRotation();
@Target
public abstract void clampRotation(Entity e);
@Injector
public void inject(ClassNode clazz, MethodNode main) {
// Hook at method start
LabelNode skip = new LabelNode();
InsnSequence is = new InsnSequence();
is.add(new MethodProxyInsnNode(INVOKESTATIC, boatClampRotation()));
is.add(new JumpInsnNode(IFEQ, skip));
is.add(new InsnNode(RETURN));
is.add(skip);
main.instructions.insert(is);
}
}
@Patch(value = Entity.class, reason = "add hook to alter vanilla boat gravity")
public abstract static class BoatGravityOverride implements Opcodes {
@Find(parent = BoatPatch.class)
abstract MethodProxy boatGravityCheck();
@Target
public abstract boolean isNoGravity(); public abstract boolean isNoGravity();
@Injector @Injector(reason = "add hook to alter vanilla boat gravity")
public void inject(ClassNode clazz, MethodNode main) { public void injectGravityHook(ClassNode clazz, MethodNode main) {
// Hook at method start // Hook at method start
LabelNode skip = new LabelNode(); LabelNode skip = new LabelNode();
InsnSequence is = new InsnSequence(); InsnSequence is = new InsnSequence();
is.add(new VarInsnNode(ALOAD, 0)); is.add(new VarInsnNode(ALOAD, 0));
is.add(new MethodProxyInsnNode(INVOKESTATIC, boatGravityCheck())); is.add(new MethodProxyInsnNode(INVOKESTATIC, boatGravityCheck));
is.add(new JumpInsnNode(IFEQ, skip)); is.add(new JumpInsnNode(IFEQ, skip));
is.add(new InsnNode(ICONST_1)); is.add(new InsnNode(ICONST_1));
is.add(new InsnNode(IRETURN)); is.add(new InsnNode(IRETURN));

View file

@ -14,16 +14,16 @@ import org.objectweb.asm.tree.*;
public class ChatPatch { public class ChatPatch {
@Patch(value = Minecraft.class, reason = "add hook to prevent chat from being cleared") @Patch(Minecraft.class)
public abstract static class ChatClearInterceptor implements Opcodes { public abstract static class ChatClearInterceptor implements Opcodes {
// TODO this should be optional // TODO this should be optional
@Target @Target(of = "injectClearChatHook")
abstract void setScreen(Screen screen); abstract void setScreen(Screen screen);
@Injector @Injector(reason = "skips chat clearing")
public void inject(ClassNode clazz, MethodNode main) { public void injectClearChatHook(ClassNode clazz, MethodNode main) {
InsnSequence match = PatternMatcher.builder() InsnSequence match = PatternMatcher.builder()
.opcodes(ALOAD, GETFIELD, INVOKEVIRTUAL, ICONST_1, INVOKEVIRTUAL) .opcodes(ALOAD, GETFIELD, INVOKEVIRTUAL, ICONST_1, INVOKEVIRTUAL)
.ignoreLineNumbers() .ignoreLineNumbers()

View file

@ -4,10 +4,9 @@ import ftbsc.lll.processor.annotations.Find;
import ftbsc.lll.processor.annotations.Injector; import ftbsc.lll.processor.annotations.Injector;
import ftbsc.lll.processor.annotations.Patch; import ftbsc.lll.processor.annotations.Patch;
import ftbsc.lll.processor.annotations.Target; import ftbsc.lll.processor.annotations.Target;
import ftbsc.lll.proxies.MethodProxy; import ftbsc.lll.proxies.impl.MethodProxy;
import ftbsc.lll.tools.InsnSequence; import ftbsc.lll.tools.InsnSequence;
import ftbsc.lll.tools.PatternMatcher; import ftbsc.lll.tools.PatternMatcher;
import ftbsc.lll.tools.debug.BytecodePrinter;
import ftbsc.lll.tools.nodes.MethodProxyInsnNode; import ftbsc.lll.tools.nodes.MethodProxyInsnNode;
import net.minecraft.client.network.play.ClientPlayNetHandler; import net.minecraft.client.network.play.ClientPlayNetHandler;
import net.minecraft.command.CommandSource; import net.minecraft.command.CommandSource;
@ -30,21 +29,21 @@ public class CommandsPatch {
} }
} }
@Patch(ClientPlayNetHandler.class)
public abstract static class CommandsDispatcherCatcher implements Opcodes {
@Find(CommandsDispatcherCatcher.class)
MethodProxy cmdBuilt;
@Target(of = "cmdBuilt")
public static void cmdBuilt(CommandDispatcher<CommandSource> dispatcher) { public static void cmdBuilt(CommandDispatcher<CommandSource> dispatcher) {
MinecraftForge.EVENT_BUS.post(new CommandsBuiltEvent(dispatcher)); MinecraftForge.EVENT_BUS.post(new CommandsBuiltEvent(dispatcher));
} }
@Patch(value = ClientPlayNetHandler.class, reason = "add hook to insert our command suggestions") @Target(of = "injectCommandHandler")
public abstract static class CommandsDispatcherCatcher implements Opcodes {
@Find(parent = CommandsPatch.class)
abstract MethodProxy cmdBuilt();
@Target
abstract void handleCommands(SCommandListPacket pkt); abstract void handleCommands(SCommandListPacket pkt);
@Injector @Injector(reason = "add hook to insert our command suggestions")
public void inject(ClassNode clazz, MethodNode main) { public void injectCommandHandler(ClassNode clazz, MethodNode main) {
BytecodePrinter.logAsmMethod(main, "pre.log");
AbstractInsnNode found = PatternMatcher.builder() AbstractInsnNode found = PatternMatcher.builder()
.opcodes(ALOAD, INVOKEVIRTUAL, INVOKESPECIAL) .opcodes(ALOAD, INVOKEVIRTUAL, INVOKESPECIAL)
.ignoreFrames() .ignoreFrames()
@ -56,10 +55,9 @@ public class CommandsPatch {
InsnSequence is = new InsnSequence(); InsnSequence is = new InsnSequence();
is.add(new InsnNode(DUP)); is.add(new InsnNode(DUP));
is.add(new MethodProxyInsnNode(INVOKESTATIC, cmdBuilt())); is.add(new MethodProxyInsnNode(INVOKESTATIC, cmdBuilt));
main.instructions.insert(found, is); main.instructions.insert(found, is);
BytecodePrinter.logAsmMethod(main, "post.log");
} }
} }
} }

View file

@ -5,7 +5,7 @@ import ftbsc.lll.processor.annotations.Find;
import ftbsc.lll.processor.annotations.Injector; import ftbsc.lll.processor.annotations.Injector;
import ftbsc.lll.processor.annotations.Patch; import ftbsc.lll.processor.annotations.Patch;
import ftbsc.lll.processor.annotations.Target; import ftbsc.lll.processor.annotations.Target;
import ftbsc.lll.proxies.MethodProxy; import ftbsc.lll.proxies.impl.MethodProxy;
import ftbsc.lll.tools.InsnSequence; import ftbsc.lll.tools.InsnSequence;
import ftbsc.lll.tools.nodes.MethodProxyInsnNode; import ftbsc.lll.tools.nodes.MethodProxyInsnNode;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
@ -21,6 +21,12 @@ public class EntityPushPatch implements ICommons {
@Cancelable @Cancelable
public static class PlayerEntityPushEvent extends Event {} public static class PlayerEntityPushEvent extends Event {}
@Patch(Entity.class)
public abstract static class EntityCollisionsOverride implements Opcodes {
@Find(EntityCollisionsOverride.class)
MethodProxy shouldCancelEntityCollisions;
@Target(of = "shouldCancelEntityCollisions")
public static boolean shouldCancelEntityCollisions(Entity e) { public static boolean shouldCancelEntityCollisions(Entity e) {
if (e.equals(MC.player)) { if (e.equals(MC.player)) {
return MinecraftForge.EVENT_BUS.post(new PlayerEntityPushEvent()); return MinecraftForge.EVENT_BUS.post(new PlayerEntityPushEvent());
@ -28,20 +34,15 @@ public class EntityPushPatch implements ICommons {
return false; return false;
} }
@Patch(value = Entity.class, reason = "add hook to cancel entity collisions") @Target(of = "injectEntityCollisionHook")
public abstract static class EntityCollisionsOverride implements Opcodes {
@Find(parent = EntityPushPatch.class)
abstract MethodProxy shouldCancelEntityCollisions();
@Target
abstract void push(double x, double y, double z); abstract void push(double x, double y, double z);
@Injector @Injector(reason = "add hook to cancel entity collisions")
public void inject(ClassNode clazz, MethodNode main) { public void injectEntityCollisionHook(ClassNode clazz, MethodNode main) {
LabelNode skip = new LabelNode(); LabelNode skip = new LabelNode();
InsnSequence is = new InsnSequence(); InsnSequence is = new InsnSequence();
is.add(new VarInsnNode(ALOAD, 0)); is.add(new VarInsnNode(ALOAD, 0));
is.add(new MethodProxyInsnNode(INVOKESTATIC, shouldCancelEntityCollisions())); is.add(new MethodProxyInsnNode(INVOKESTATIC, shouldCancelEntityCollisions));
is.add(new JumpInsnNode(IFEQ, skip)); is.add(new JumpInsnNode(IFEQ, skip));
is.add(new InsnNode(RETURN)); is.add(new InsnNode(RETURN));
is.add(skip); is.add(skip);

View file

@ -5,7 +5,7 @@ import ftbsc.lll.processor.annotations.Find;
import ftbsc.lll.processor.annotations.Injector; import ftbsc.lll.processor.annotations.Injector;
import ftbsc.lll.processor.annotations.Patch; import ftbsc.lll.processor.annotations.Patch;
import ftbsc.lll.processor.annotations.Target; import ftbsc.lll.processor.annotations.Target;
import ftbsc.lll.proxies.MethodProxy; import ftbsc.lll.proxies.impl.MethodProxy;
import ftbsc.lll.tools.InsnSequence; import ftbsc.lll.tools.InsnSequence;
import ftbsc.lll.tools.nodes.MethodProxyInsnNode; import ftbsc.lll.tools.nodes.MethodProxyInsnNode;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
@ -21,6 +21,12 @@ public class LiquidPushPatch implements ICommons {
@Cancelable @Cancelable
public static class PlayerLiquidPushEvent extends Event {} public static class PlayerLiquidPushEvent extends Event {}
@Patch(PlayerEntity.class)
public abstract static class LiquidCollisionsOverride implements Opcodes {
@Find(LiquidCollisionsOverride.class)
MethodProxy shouldCancelLiquidCollisions;
@Target(of = "shouldCancelLiquidCollisions")
public static boolean shouldCancelLiquidCollisions(PlayerEntity player) { public static boolean shouldCancelLiquidCollisions(PlayerEntity player) {
if (player.equals(MC.player)) { if (player.equals(MC.player)) {
return MinecraftForge.EVENT_BUS.post(new PlayerLiquidPushEvent()); return MinecraftForge.EVENT_BUS.post(new PlayerLiquidPushEvent());
@ -28,20 +34,15 @@ public class LiquidPushPatch implements ICommons {
return false; return false;
} }
@Patch(value = PlayerEntity.class, reason = "add hook to cancel liquid collisions") @Target(of = "injectLiquidCollisionHook")
public abstract static class LiquidCollisionsOverride implements Opcodes {
@Find(parent = LiquidPushPatch.class)
abstract MethodProxy shouldCancelLiquidCollisions();
@Target
abstract boolean isPushedByFluid(); abstract boolean isPushedByFluid();
@Injector @Injector(reason = "add hook to cancel liquid collisions")
public void inject(ClassNode clazz, MethodNode main) { public void injectLiquidCollisionHook(ClassNode clazz, MethodNode main) {
LabelNode skip = new LabelNode(); LabelNode skip = new LabelNode();
InsnSequence is = new InsnSequence(); InsnSequence is = new InsnSequence();
is.add(new VarInsnNode(ALOAD, 0)); is.add(new VarInsnNode(ALOAD, 0));
is.add(new MethodProxyInsnNode(INVOKESTATIC, shouldCancelLiquidCollisions())); is.add(new MethodProxyInsnNode(INVOKESTATIC, shouldCancelLiquidCollisions));
is.add(new JumpInsnNode(IFEQ, skip)); is.add(new JumpInsnNode(IFEQ, skip));
is.add(new InsnNode(ICONST_0)); is.add(new InsnNode(ICONST_0));
is.add(new InsnNode(IRETURN)); is.add(new InsnNode(IRETURN));

View file

@ -4,7 +4,7 @@ import ftbsc.lll.processor.annotations.Find;
import ftbsc.lll.processor.annotations.Injector; import ftbsc.lll.processor.annotations.Injector;
import ftbsc.lll.processor.annotations.Patch; import ftbsc.lll.processor.annotations.Patch;
import ftbsc.lll.processor.annotations.Target; import ftbsc.lll.processor.annotations.Target;
import ftbsc.lll.proxies.MethodProxy; import ftbsc.lll.proxies.impl.MethodProxy;
import ftbsc.lll.tools.InsnSequence; import ftbsc.lll.tools.InsnSequence;
import ftbsc.lll.tools.PatternMatcher; import ftbsc.lll.tools.PatternMatcher;
import ftbsc.lll.tools.nodes.MethodProxyInsnNode; import ftbsc.lll.tools.nodes.MethodProxyInsnNode;
@ -21,21 +21,22 @@ public class NoSlowPatch {
@Cancelable @Cancelable
public static class PlayerSlowDownEvent extends Event { } public static class PlayerSlowDownEvent extends Event { }
@Patch(ClientPlayerEntity.class)
public abstract static class SlowDownOverride implements Opcodes {
@Find(SlowDownOverride.class)
MethodProxy shouldSlowPlayer;
@Target(of = "shouldSlowPlayer")
public static boolean shouldSlowPlayer() { public static boolean shouldSlowPlayer() {
return MinecraftForge.EVENT_BUS.post(new PlayerSlowDownEvent()); return MinecraftForge.EVENT_BUS.post(new PlayerSlowDownEvent());
} }
@Patch(value = ClientPlayerEntity.class, reason = "add hook to cancel slowing down effect of using items") @Target(of = "injectNoSlowHook")
public abstract static class SlowDownOverride implements Opcodes {
@Find(parent = NoSlowPatch.class)
abstract MethodProxy shouldSlowPlayer();
@Target
abstract void aiStep(); abstract void aiStep();
@Injector @Injector(reason = "add hook to cancel slowing down effect of using items")
public void inject(ClassNode clazz, MethodNode main) { public void injectNoSlowHook(ClassNode clazz, MethodNode main) {
AbstractInsnNode found = PatternMatcher.builder() AbstractInsnNode found = PatternMatcher.builder()
.opcodes(ALOAD, INVOKEVIRTUAL, IFEQ, ALOAD, INVOKEVIRTUAL, IFNE) .opcodes(ALOAD, INVOKEVIRTUAL, IFEQ, ALOAD, INVOKEVIRTUAL, IFNE)
.ignoreFrames() .ignoreFrames()
@ -56,7 +57,7 @@ public class NoSlowPatch {
LabelNode skip = new LabelNode(); // TODO can we get the label that the original IF is jumping to without adding one ourselves? LabelNode skip = new LabelNode(); // TODO can we get the label that the original IF is jumping to without adding one ourselves?
InsnSequence is = new InsnSequence(); InsnSequence is = new InsnSequence();
is.add(new MethodProxyInsnNode(INVOKESTATIC, shouldSlowPlayer())); is.add(new MethodProxyInsnNode(INVOKESTATIC, shouldSlowPlayer));
is.add(new JumpInsnNode(IFNE, skip)); is.add(new JumpInsnNode(IFNE, skip));
main.instructions.insert(found, is); main.instructions.insert(found, is);

View file

@ -0,0 +1,108 @@
package ftbsc.bscv.patches;
import ftbsc.lll.processor.annotations.Find;
import ftbsc.lll.processor.annotations.Injector;
import ftbsc.lll.processor.annotations.Patch;
import ftbsc.lll.processor.annotations.Target;
import ftbsc.lll.proxies.impl.MethodProxy;
import ftbsc.lll.tools.InsnSequence;
import ftbsc.lll.tools.PatternMatcher;
import ftbsc.lll.tools.nodes.MethodProxyInsnNode;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import net.minecraft.network.IPacket;
import net.minecraft.network.NetworkManager;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.Cancelable;
import net.minecraftforge.eventbus.api.Event;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.*;
public class PacketPatch {
public static class PacketEvent {
@Cancelable
public static class Outgoing extends Event {
public final IPacket<?> packet;
public Outgoing(IPacket<?> packet) {
this.packet = packet;
}
}
@Cancelable
public static class Incoming extends Event {
public final IPacket<?> packet;
public Incoming(IPacket<?> packet) {
this.packet = packet;
}
}
}
@Patch(NetworkManager.class)
public abstract static class IncomingPacketInterceptor implements Opcodes {
@Find(IncomingPacketInterceptor.class)
MethodProxy pktIn;
@Target(of = "pktIn")
public static boolean pktIn(IPacket<?> pkt) {
return MinecraftForge.EVENT_BUS.post(new PacketEvent.Incoming(pkt));
}
@Target(of = "injectIncomingInterceptor")
abstract void channelRead0(ChannelHandlerContext ctx, IPacket<?> pak);
@Injector(reason = "add hook to intercept and alter/cancel incoming packets")
public void injectIncomingInterceptor(ClassNode clazz, MethodNode main) {
AbstractInsnNode found = PatternMatcher.builder()
.opcodes(ALOAD, GETFIELD, INVOKEINTERFACE, IFEQ)
.ignoreFrames()
.ignoreLabels()
.ignoreLineNumbers()
.build()
.find(main)
.getLast();
LabelNode skip = new LabelNode();
InsnSequence is = new InsnSequence();
is.add(new VarInsnNode(ALOAD, 2));
is.add(new MethodProxyInsnNode(INVOKESTATIC, pktIn));
is.add(new JumpInsnNode(IFEQ, skip));
is.add(new InsnNode(RETURN));
is.add(skip);
main.instructions.insert(found, is);
}
}
@Patch(NetworkManager.class)
public abstract static class OutgoingPacketInterceptor implements Opcodes {
@Find(OutgoingPacketInterceptor.class)
MethodProxy pktOut;
@Target(of = "pktOut")
public static boolean pktOut(IPacket<?> pkt) {
return MinecraftForge.EVENT_BUS.post(new PacketEvent.Outgoing(pkt));
}
@Target(of = "injectOutgoingInterceptor")
public abstract void sendPacket(IPacket<?> pak, GenericFutureListener<? extends Future<? super Void>> gfl);
@Injector(reason = "add hook to intercept and alter/cancel outgoing packets")
public void injectOutgoingInterceptor(ClassNode clazz, MethodNode main) {
// hook at the top
LabelNode skip = new LabelNode();
InsnSequence is = new InsnSequence();
is.add(new VarInsnNode(ALOAD, 1));
is.add(new MethodProxyInsnNode(INVOKESTATIC, pktOut));
is.add(new JumpInsnNode(IFEQ, skip));
is.add(new InsnNode(RETURN));
is.add(skip);
main.instructions.insert(is);
}
}
}

View file

@ -13,12 +13,12 @@ import ftbsc.lll.processor.annotations.Target;
import ftbsc.lll.tools.PatternMatcher; import ftbsc.lll.tools.PatternMatcher;
import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.entity.player.ClientPlayerEntity;
@Patch(value = ClientPlayerEntity.class, reason = "prevent minecraft from force closing guis when entering portals") @Patch(ClientPlayerEntity.class)
public abstract class PortalGuiPatch implements Opcodes { public abstract class PortalGuiPatch implements Opcodes {
@Target @Target(of = "inject")
abstract void handleNetherPortalClient(); abstract void handleNetherPortalClient();
@Injector @Injector(reason = "prevent minecraft from force closing guis when entering portals")
public void inject(ClassNode clazz, MethodNode main) { public void inject(ClassNode clazz, MethodNode main) {
LabelNode skip = new LabelNode(); LabelNode skip = new LabelNode();

View file

@ -1,69 +0,0 @@
package ftbsc.bscv.system;
import ftbsc.bscv.Boscovicino;
import io.netty.channel.*;
import net.minecraft.network.IPacket;
import net.minecraft.network.NetworkManager;
import net.minecraftforge.client.event.ClientPlayerNetworkEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.Cancelable;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.eventbus.api.SubscribeEvent;
@ChannelHandler.Sharable
public class PacketHandler extends ChannelDuplexHandler {
public PacketHandler() {
MinecraftForge.EVENT_BUS.register(this);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if(processPacket(msg, false))
super.channelRead(ctx, msg);
}
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
if(processPacket(msg, true))
super.write(ctx, msg, promise);
}
private static boolean processPacket(Object msg, boolean outgoing) {
if(msg instanceof IPacket) {
IPacket<?> pkt = (IPacket<?>) msg;
PacketEvent event = outgoing ? new PacketEvent.Outgoing(pkt) : new PacketEvent.Incoming(pkt);
MinecraftForge.EVENT_BUS.post(event);
return !event.isCanceled();
} else return true;
}
@SubscribeEvent
public void registerOnLogin(ClientPlayerNetworkEvent.LoggedInEvent event) {
NetworkManager nm = event.getNetworkManager();
if(nm != null) {
nm.channel().pipeline().addBefore("packet_handler", "bscv_handler", this);
Boscovicino.LOGGER.info("Successfully registered PacketHandler!");
} else Boscovicino.LOGGER.error("Failed to register PacketHandler: NetworkManager was null!");
}
@Cancelable
public static class PacketEvent extends Event {
public static class Outgoing extends PacketEvent {
public final IPacket<?> packet;
public Outgoing(IPacket<?> packet) {
this.packet = packet;
}
}
public static class Incoming extends PacketEvent {
public final IPacket<?> packet;
public Incoming(IPacket<?> packet) {
this.packet = packet;
}
}
}
}

View file

@ -0,0 +1,85 @@
package ftbsc.bscv.system;
import ftbsc.bscv.ICommons;
import ftbsc.bscv.tools.Keybind;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.client.util.InputMappings;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.RayTraceResult.Type;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import static ftbsc.bscv.Boscovicino.log;
public class Ruler implements ICommons {
public final KeyBinding keybind;
public Ruler() {
super();
this.keybind = new KeyBinding(Keybind.name("Ruler"), InputMappings.UNKNOWN.getValue(), Keybind.category());
ClientRegistry.registerKeyBinding(this.keybind);
// register a separate subclass on the hook, so that it's always listening
MinecraftForge.EVENT_BUS.register(new ToggleHook(this.keybind));
// dispatcher.register(
// Commands.literal(this.name.toLowerCase())
// .then(
// Commands.literal("bind")
// .then(
// Commands.argument("key", StringArgumentType.word())
// .executes( ctx -> {
// this.keybind.setKey(
// InputMappings.getKey( // TODO it's not this easy!
// StringArgumentType.getString(ctx, "key")
// )
// );
// return 1;
// })
// )
// )
// );
}
public static void measure() {
RayTraceResult aim = MC.player.pick(1024, 0, false); // will 1024 be enough?
double distance = Math.sqrt(aim.distanceTo(MC.player));
if (aim.getType() == Type.BLOCK) {
log("distance: %.1fm", distance);
}
}
// TODO can this be made an util or a global event listener?
private class ToggleHook {
private final KeyBinding key;
private boolean debounce;
// TODO all examples show isPressed() to get a debounced value
// but it seems to be missing? making my own debounce for now
protected ToggleHook(KeyBinding key) {
this.key = key;
this.debounce = false;
}
private void onInput() {
if (this.debounce) {
if (!this.key.isDown()) {
this.debounce = false;
}
} else {
if (this.key.isDown()) {
Ruler.measure();
this.debounce = true;
}
}
}
@SubscribeEvent
public void onKeyPress(InputEvent.KeyInputEvent event) { this.onInput(); }
@SubscribeEvent
public void onKeyPress(InputEvent.MouseInputEvent event) { this.onInput(); }
}
}

View file

@ -7,13 +7,19 @@ import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.ai.attributes.Attributes; import net.minecraft.entity.ai.attributes.Attributes;
import net.minecraft.inventory.EquipmentSlotType; import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.inventory.container.Slot; import net.minecraft.inventory.container.Slot;
import net.minecraft.item.EnchantedBookItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.INBT; import net.minecraft.nbt.INBT;
import net.minecraft.nbt.ListNBT;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.regex.Pattern;
public class Inventory implements ICommons { public class Inventory implements ICommons {
@ -68,4 +74,44 @@ public class Inventory implements ICommons {
return damage / (1. + speed); return damage / (1. + speed);
} }
public static List<String> itemEnchantments(ItemStack stack) {
final ListNBT tags;
if (Items.ENCHANTED_BOOK.equals(stack.getItem())) {
tags = EnchantedBookItem.getEnchantments(stack); // special case to also search book enchants
} else {
tags = stack.getEnchantmentTags();
}
List<String> out = new ArrayList<>();
for (int i = 0; i < tags.size(); i++) {
CompoundNBT tag = tags.getCompound(i);
out.add(String.format("%s %s", tag.getString("id"), tag.getInt("lvl")));
}
return out;
}
public static void clickSlot(int slot_index, ClickType click) { clickSlot(0, slot_index, 0, click); }
public static void clickSlot(Slot slot, int button, ClickType click) { clickSlot(0, slot.index, button, click); }
public static void clickSlot(int container, int slot_index, ClickType click) { clickSlot(container, slot_index, 0, click); }
public static void clickSlot(int container, int slot_index, int button, ClickType click) {
MC.gameMode.handleInventoryMouseClick(container, slot_index, button, click, MC.player);
}
public static boolean matchItem(Pattern pattern, ItemStack stack) {
if (stack.isEmpty()) return false;
String displayName = stack.getDisplayName().getString();
if (pattern.matcher(displayName).find()) return true;
if (Items.ENCHANTED_BOOK.equals(stack.getItem()) || stack.isEnchanted()) {
for (String ench : itemEnchantments(stack)) {
if (pattern.matcher(ench).find()) return true;
}
}
return false;
}
} }

View file

@ -0,0 +1,13 @@
package ftbsc.bscv.tools;
import ftbsc.bscv.Boscovicino;
public class Keybind {
public static String name(String name) {
return String.format("key.%s.%s", Boscovicino.MOD_ID, name);
}
public static String category() {
return String.format("key.category.%s", Boscovicino.MOD_ID);
}
}

View file

@ -1,23 +1,28 @@
package ftbsc.bscv.tools; package ftbsc.bscv.tools;
import com.google.common.collect.Lists;
import com.mojang.brigadier.arguments.*; import com.mojang.brigadier.arguments.*;
import ftbsc.bscv.api.IModule; import ftbsc.bscv.api.IModule;
import net.minecraft.command.Commands; import net.minecraft.command.Commands;
import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.server.command.EnumArgument; import net.minecraftforge.server.command.EnumArgument;
import java.io.Serializable;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import static ftbsc.bscv.Boscovicino.log; import static ftbsc.bscv.Boscovicino.log;
public abstract class Setting<T> { public abstract class Setting<T, I> {
protected Optional<String> name; protected Optional<String> name;
protected Optional<String> comment; protected Optional<String> comment;
protected Optional<T> fallback; protected Optional<T> fallback;
protected Optional<Consumer<T>> callback; protected Optional<Consumer<I>> callback;
Setting() { Setting() {
this.name = Optional.empty(); this.name = Optional.empty();
@ -26,29 +31,35 @@ public abstract class Setting<T> {
this.callback = Optional.empty(); this.callback = Optional.empty();
} }
public Setting<T> name(String name) { public Setting<T, I> name(String name) {
this.name = Optional.of(name); this.name = Optional.of(name);
return this; return this;
} }
public Setting<T> comment(String comment) { public Setting<T, I> comment(String comment) {
this.comment = Optional.of(comment); this.comment = Optional.of(comment);
return this; return this;
} }
public Setting<T> fallback(T fallback) { public Setting<T, I> fallback(T fallback) {
this.fallback = Optional.of(fallback); this.fallback = Optional.of(fallback);
return this; return this;
} }
public Setting<T> callback(Consumer<T> callback) { public Setting<T, I> callback(Consumer<I> callback) {
this.callback = Optional.of(callback); this.callback = Optional.of(callback);
return this; return this;
} }
abstract ForgeConfigSpec.ConfigValue<T> value(ForgeConfigSpec.Builder builder); abstract ForgeConfigSpec.ConfigValue<T> value(ForgeConfigSpec.Builder builder);
abstract ArgumentType<T> argument(); abstract ArgumentType<I> argument();
public abstract ForgeConfigSpec.ConfigValue<T> build(IModule module);
private static abstract class ValueSetting<T> extends Setting<T, T> {
abstract Class<T> clazz(); abstract Class<T> clazz();
@ -84,10 +95,11 @@ public abstract class Setting<T> {
); );
return conf; return conf;
}
} }
public static class Bool extends Setting<Boolean> { public static class Bool extends ValueSetting<Boolean> {
public static Bool builder() { return new Bool(); } public static Bool builder() { return new Bool(); }
public Class<Boolean> clazz() { return Boolean.class; } public Class<Boolean> clazz() { return Boolean.class; }
@ -101,7 +113,7 @@ public abstract class Setting<T> {
} }
public static class Decimal extends Setting<Double> { public static class Decimal extends ValueSetting<Double> {
protected Optional<Double> min; protected Optional<Double> min;
protected Optional<Double> max; protected Optional<Double> max;
@ -133,7 +145,7 @@ public abstract class Setting<T> {
} }
public static class Number extends Setting<Integer> { public static class Number extends ValueSetting<Integer> {
protected Optional<Integer> min; protected Optional<Integer> min;
protected Optional<Integer> max; protected Optional<Integer> max;
@ -165,7 +177,7 @@ public abstract class Setting<T> {
} }
public static class Str extends Setting<String> { public static class Str extends ValueSetting<String> {
public static Str builder() { return new Str(); } public static Str builder() { return new Str(); }
protected boolean greedy = false; protected boolean greedy = false;
@ -190,7 +202,7 @@ public abstract class Setting<T> {
} }
public static class Switch<T extends Enum<T>> extends Setting<T> { public static class Switch<T extends Enum<T>> extends ValueSetting<T> {
private final Class<T> enumClazz; private final Class<T> enumClazz;
public static<T extends Enum<T>> Switch<T> builder(Class<T> type) { return new Switch<T>(type); } public static<T extends Enum<T>> Switch<T> builder(Class<T> type) { return new Switch<T>(type); }
@ -214,4 +226,102 @@ public abstract class Setting<T> {
} }
} }
public static class Many<T, S extends Serializable> extends Setting<List<? extends S>, T> {
private Predicate<Object> validator;
private Function<T, S> writer;
private final ArgumentType<T> argument_type;
private final Class<T> clazz;
// TODO can we infer clazz from the argument type without needing the second argument???
public Many(ArgumentType<T> argument, Class<T> clazz) {
super();
this.validator = x -> true;
this.writer = x -> (S) x; // TODO this works ootb if it's just the same type but crashes at runtime for everything else
this.argument_type = argument;
this.clazz = clazz;
}
public static<T, S extends Serializable> Many<T, S> builder(ArgumentType<T> argument, Class<T> clazz) { return new Many<T, S>(argument, clazz); }
public Many<T, S> validator(Predicate<Object> validator) {
this.validator = validator;
return this;
}
public Many<T, S> writer(Function<T, S> writer) {
this.writer = writer;
return this;
}
public ArgumentType<T> argument() {
return this.argument_type;
}
public ForgeConfigSpec.ConfigValue<List<? extends S>> value(ForgeConfigSpec.Builder builder) {
return builder
.comment(this.comment.get())
.defineList(
this.name.get(),
this.fallback.get(),
this.validator
);
}
public ForgeConfigSpec.ConfigValue<List<? extends S>> build(IModule module) {
ForgeConfigSpec.ConfigValue<List<? extends S>> conf = this.value(module.getConfigBuilder());
String optName = this.name.get();
ArgumentType<T> arg = this.argument();
Consumer<T> cb = this.callback.isPresent() ? this.callback.get() : null;
module.getDispatcher().register(
Commands.literal(module.getName().toLowerCase())
.then(
Commands.literal(optName)
.then(
Commands.literal("add")
.then(
Commands.argument(optName, arg)
.executes( ctx -> {
T value = ctx.getArgument(optName, this.clazz);
if (cb != null) {
cb.accept(value);
}
List<S> botch = Lists.newArrayList(conf.get());
botch.add(this.writer.apply(value));
conf.set(botch);
conf.save();
log(String.format("> %s -++> %s <", String.join(".", conf.getPath()), conf.get().toString()));
return 1;
})
)
)
.then(
Commands.literal("remove")
.then(
Commands.argument(optName, arg)
.executes( ctx -> {
T value = ctx.getArgument(optName, clazz);
if (cb != null) {
cb.accept(value);
}
List<S> botch = Lists.newArrayList(conf.get());
boolean removed = botch.remove(this.writer.apply(value));
conf.set(botch);
conf.save();
log(String.format("> %s -%s> %s <", String.join(".", conf.getPath()), removed ? "//" : "--", conf.get().toString()));
return 1;
})
)
)
.executes(ctx -> {
log(String.format("> %s: %s <", optName, conf.get().toString()));
return 1;
})
)
);
return conf;
}
}
} }

View file

@ -5,3 +5,7 @@ public net.minecraft.network.play.client.CPlayerPacket field_149474_g # onGround
public net.minecraft.network.play.client.CPlayerPacket field_149477_b # y public net.minecraft.network.play.client.CPlayerPacket field_149477_b # y
public net.minecraft.client.multiplayer.PlayerController func_78750_j()V # ensureHasSentCarriedItem() public net.minecraft.client.multiplayer.PlayerController func_78750_j()V # ensureHasSentCarriedItem()
public net.minecraft.client.Minecraft field_71467_ac # rightClickDelay public net.minecraft.client.Minecraft field_71467_ac # rightClickDelay
public net.minecraft.client.renderer.FirstPersonRenderer field_187469_f # mainHandHeight
public net.minecraft.client.renderer.FirstPersonRenderer field_187470_g # oMainHandHeight
public net.minecraft.client.renderer.FirstPersonRenderer field_187471_h # offHandHeight
public net.minecraft.client.renderer.FirstPersonRenderer field_187472_i # oOffHandHeight