From 159fb9af27e65efcb8aec92d3e2d1d48a61563e4 Mon Sep 17 00:00:00 2001 From: chri-k Date: Sun, 23 Nov 2025 23:48:26 +0200 Subject: [PATCH] [init] it compiles --- .../meteorclient/commands/Commands.java | 1 + .../commands/arguments/EnemyArgumentType.java | 54 ++ .../arguments/FriendArgumentType.java | 10 +- .../commands/commands/EnemiesCommand.java | 70 +++ .../commands/commands/FriendsCommand.java | 16 +- .../commands/commands/ReloadCommand.java | 7 +- .../meteorclient/gui/tabs/Tabs.java | 2 +- .../{FriendsTab.java => TargetingTab.java} | 74 ++- .../meteorclient/systems/Systems.java | 4 +- .../meteorclient/systems/config/Config.java | 7 + .../meteorclient/systems/friends/Friend.java | 113 +---- .../meteorclient/systems/friends/Friends.java | 123 ++--- .../systems/hud/elements/CombatHud.java | 35 +- .../systems/hud/elements/PlayerRadarHud.java | 6 +- .../systems/modules/combat/AnchorAura.java | 8 +- .../systems/modules/combat/AutoAnvil.java | 8 +- .../systems/modules/combat/AutoCity.java | 8 +- .../systems/modules/combat/AutoLog.java | 20 +- .../systems/modules/combat/AutoTrap.java | 8 +- .../systems/modules/combat/AutoWeb.java | 8 +- .../systems/modules/combat/BedAura.java | 4 +- .../systems/modules/combat/BowAimbot.java | 14 +- .../systems/modules/combat/CrystalAura.java | 41 +- .../systems/modules/combat/Hitboxes.java | 4 +- .../systems/modules/combat/HoleFiller.java | 21 +- .../systems/modules/combat/KillAura.java | 10 +- .../systems/modules/combat/SelfWeb.java | 4 +- .../systems/modules/misc/MessageAura.java | 19 +- .../systems/modules/misc/Notifier.java | 53 +- .../systems/modules/movement/AutoWasp.java | 13 +- .../modules/player/MiddleClickExtra.java | 10 +- .../systems/modules/player/NoInteract.java | 12 +- .../systems/modules/render/BetterTab.java | 18 +- .../systems/modules/render/CityESP.java | 7 +- .../systems/modules/render/ESP.java | 17 +- .../systems/modules/render/Nametags.java | 12 +- .../systems/modules/render/Tracers.java | 22 +- .../systems/modules/world/AutoNametag.java | 6 +- .../systems/modules/world/HighwayBuilder.java | 7 +- .../systems/targeting/SavedPlayer.java | 124 +++++ .../systems/targeting/Targeting.java | 462 ++++++++++++++++++ .../utils/entity/TargetUtils.java | 52 +- .../utils/player/PlayerUtils.java | 6 +- 43 files changed, 1045 insertions(+), 475 deletions(-) create mode 100644 src/main/java/meteordevelopment/meteorclient/commands/arguments/EnemyArgumentType.java create mode 100644 src/main/java/meteordevelopment/meteorclient/commands/commands/EnemiesCommand.java rename src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/{FriendsTab.java => TargetingTab.java} (53%) create mode 100644 src/main/java/meteordevelopment/meteorclient/systems/targeting/SavedPlayer.java create mode 100644 src/main/java/meteordevelopment/meteorclient/systems/targeting/Targeting.java diff --git a/src/main/java/meteordevelopment/meteorclient/commands/Commands.java b/src/main/java/meteordevelopment/meteorclient/commands/Commands.java index 8764f20636..cf4e4520f8 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/Commands.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/Commands.java @@ -38,6 +38,7 @@ public static void init() { add(new EnchantCommand()); add(new FakePlayerCommand()); add(new FriendsCommand()); + add(new EnemiesCommand()); add(new CommandsCommand()); add(new InventoryCommand()); add(new NbtCommand()); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/arguments/EnemyArgumentType.java b/src/main/java/meteordevelopment/meteorclient/commands/arguments/EnemyArgumentType.java new file mode 100644 index 0000000000..8e3f3c6ea3 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/commands/arguments/EnemyArgumentType.java @@ -0,0 +1,54 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.commands.arguments; + +import com.google.common.collect.Streams; +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import meteordevelopment.meteorclient.systems.targeting.SavedPlayer; +import meteordevelopment.meteorclient.systems.targeting.Targeting; + +import java.util.Collection; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import static net.minecraft.command.CommandSource.suggestMatching; + +// TODO: functionality duplication + +public class EnemyArgumentType implements ArgumentType { + private static final EnemyArgumentType INSTANCE = new EnemyArgumentType(); + private static final Collection EXAMPLES = List.of("seasnail8169", "MineGame159"); + + public static EnemyArgumentType create() { + return INSTANCE; + } + + public static SavedPlayer get(CommandContext context) { + return Targeting.getFriend(context.getArgument("enemy", String.class)); + } + + private EnemyArgumentType() {} + + @Override + public String parse(StringReader reader) throws CommandSyntaxException { + return reader.readString(); + } + + @Override + public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { + return suggestMatching(Streams.stream(Targeting.get().getEnemies()).map(SavedPlayer::getName), builder); + } + + @Override + public Collection getExamples() { + return EXAMPLES; + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/commands/arguments/FriendArgumentType.java b/src/main/java/meteordevelopment/meteorclient/commands/arguments/FriendArgumentType.java index e236bdf789..b53b74c161 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/arguments/FriendArgumentType.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/arguments/FriendArgumentType.java @@ -12,8 +12,8 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import meteordevelopment.meteorclient.systems.friends.Friend; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.SavedPlayer; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import java.util.Collection; import java.util.List; @@ -29,8 +29,8 @@ public static FriendArgumentType create() { return INSTANCE; } - public static Friend get(CommandContext context) { - return Friends.get().get(context.getArgument("friend", String.class)); + public static SavedPlayer get(CommandContext context) { + return Targeting.getFriend(context.getArgument("friend", String.class)); } private FriendArgumentType() {} @@ -42,7 +42,7 @@ public String parse(StringReader reader) throws CommandSyntaxException { @Override public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { - return suggestMatching(Streams.stream(Friends.get()).map(Friend::getName), builder); + return suggestMatching(Streams.stream(Targeting.get().getFriends()).map(SavedPlayer::getName), builder); } @Override diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/EnemiesCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/EnemiesCommand.java new file mode 100644 index 0000000000..9352264ebf --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/EnemiesCommand.java @@ -0,0 +1,70 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.commands.commands; + +import com.mojang.authlib.GameProfile; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import meteordevelopment.meteorclient.commands.Command; +import meteordevelopment.meteorclient.commands.arguments.EnemyArgumentType; +import meteordevelopment.meteorclient.commands.arguments.PlayerListEntryArgumentType; +import meteordevelopment.meteorclient.systems.targeting.SavedPlayer; +import meteordevelopment.meteorclient.systems.targeting.Targeting; +import meteordevelopment.meteorclient.utils.player.ChatUtils; +import net.minecraft.command.CommandSource; +import net.minecraft.util.Formatting; + +// TODO: functionality duplication + +public class EnemiesCommand extends Command { + public EnemiesCommand() { + super("enemies", "Manages enemies."); + } + + @Override + public void build(LiteralArgumentBuilder builder) { + builder.then(literal("add") + .then(argument("player", PlayerListEntryArgumentType.create()) + .executes(context -> { + GameProfile profile = PlayerListEntryArgumentType.get(context).getProfile(); + SavedPlayer enemy = new SavedPlayer(profile.name(), profile.id()); + + if (Targeting.get().addEnemy(enemy)) { + ChatUtils.sendMsg(enemy.hashCode(), Formatting.GRAY, "Added (highlight)%s (default)to enemies.".formatted(enemy.getName())); + } + else error("Already enemies with that player."); + + return SINGLE_SUCCESS; + }) + ) + ); + + builder.then(literal("remove") + .then(argument("enemy", EnemyArgumentType.create()) + .executes(context -> { + SavedPlayer enemy = EnemyArgumentType.get(context); + if (enemy == null) { + error("Not enemies with that player."); + return SINGLE_SUCCESS; + } + + if (Targeting.get().removeEnemy(enemy)) { + ChatUtils.sendMsg(enemy.hashCode(), Formatting.GRAY, "Removed (highlight)%s (default)from enemies.".formatted(enemy.getName())); + } + else error("Failed to remove that enemy."); + + return SINGLE_SUCCESS; + }) + ) + ); + + builder.then(literal("list").executes(context -> { + info("--- Targeting ((highlight)%s(default)) ---", Targeting.get().countEnemies()); + Targeting.get().getEnemies().forEach(enemy -> ChatUtils.info("(highlight)%s".formatted(enemy.getName()))); + return SINGLE_SUCCESS; + }) + ); + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java index 23ae209cad..2da5377d4b 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/FriendsCommand.java @@ -10,8 +10,8 @@ import meteordevelopment.meteorclient.commands.Command; import meteordevelopment.meteorclient.commands.arguments.FriendArgumentType; import meteordevelopment.meteorclient.commands.arguments.PlayerListEntryArgumentType; -import meteordevelopment.meteorclient.systems.friends.Friend; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.SavedPlayer; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.utils.player.ChatUtils; import net.minecraft.command.CommandSource; import net.minecraft.util.Formatting; @@ -27,9 +27,9 @@ public void build(LiteralArgumentBuilder builder) { .then(argument("player", PlayerListEntryArgumentType.create()) .executes(context -> { GameProfile profile = PlayerListEntryArgumentType.get(context).getProfile(); - Friend friend = new Friend(profile.name(), profile.id()); + SavedPlayer friend = new SavedPlayer(profile.name(), profile.id()); - if (Friends.get().add(friend)) { + if (Targeting.get().addFriend(friend)) { ChatUtils.sendMsg(friend.hashCode(), Formatting.GRAY, "Added (highlight)%s (default)to friends.".formatted(friend.getName())); } else error("Already friends with that player."); @@ -42,13 +42,13 @@ public void build(LiteralArgumentBuilder builder) { builder.then(literal("remove") .then(argument("friend", FriendArgumentType.create()) .executes(context -> { - Friend friend = FriendArgumentType.get(context); + SavedPlayer friend = FriendArgumentType.get(context); if (friend == null) { error("Not friends with that player."); return SINGLE_SUCCESS; } - if (Friends.get().remove(friend)) { + if (Targeting.get().removeFriend(friend)) { ChatUtils.sendMsg(friend.hashCode(), Formatting.GRAY, "Removed (highlight)%s (default)from friends.".formatted(friend.getName())); } else error("Failed to remove that friend."); @@ -59,8 +59,8 @@ public void build(LiteralArgumentBuilder builder) { ); builder.then(literal("list").executes(context -> { - info("--- Friends ((highlight)%s(default)) ---", Friends.get().count()); - Friends.get().forEach(friend -> ChatUtils.info("(highlight)%s".formatted(friend.getName()))); + info("--- Targeting ((highlight)%s(default)) ---", Targeting.get().countFriends()); + Targeting.get().getFriends().forEach(friend -> ChatUtils.info("(highlight)%s".formatted(friend.getName()))); return SINGLE_SUCCESS; }) ); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/ReloadCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/ReloadCommand.java index f299819854..5eabc67cf2 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/ReloadCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/ReloadCommand.java @@ -9,8 +9,8 @@ import meteordevelopment.meteorclient.commands.Command; import meteordevelopment.meteorclient.renderer.Fonts; import meteordevelopment.meteorclient.systems.Systems; -import meteordevelopment.meteorclient.systems.friends.Friend; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.SavedPlayer; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.utils.network.Capes; import meteordevelopment.meteorclient.utils.network.MeteorExecutor; import net.minecraft.command.CommandSource; @@ -28,7 +28,8 @@ public void build(LiteralArgumentBuilder builder) { Systems.load(); Capes.init(); Fonts.refresh(); - MeteorExecutor.execute(() -> Friends.get().forEach(Friend::updateInfo)); + MeteorExecutor.execute(() -> Targeting.get().getFriends().forEach(SavedPlayer::updateInfo)); + MeteorExecutor.execute(() -> Targeting.get().getEnemies().forEach(SavedPlayer::updateInfo)); return SINGLE_SUCCESS; }); diff --git a/src/main/java/meteordevelopment/meteorclient/gui/tabs/Tabs.java b/src/main/java/meteordevelopment/meteorclient/gui/tabs/Tabs.java index 2bdec4a316..943eef904c 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/tabs/Tabs.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/tabs/Tabs.java @@ -26,7 +26,7 @@ public static void init() { add(new ConfigTab()); add(new GuiTab()); add(new HudTab()); - add(new FriendsTab()); + add(new TargetingTab()); add(new MacrosTab()); add(new ProfilesTab()); diff --git a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/FriendsTab.java b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/TargetingTab.java similarity index 53% rename from src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/FriendsTab.java rename to src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/TargetingTab.java index aeaec4e1ed..58244db848 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/FriendsTab.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/tabs/builtin/TargetingTab.java @@ -12,40 +12,50 @@ import meteordevelopment.meteorclient.gui.widgets.containers.WHorizontalList; import meteordevelopment.meteorclient.gui.widgets.containers.WTable; import meteordevelopment.meteorclient.gui.widgets.input.WTextBox; +import meteordevelopment.meteorclient.gui.widgets.pressable.WButton; import meteordevelopment.meteorclient.gui.widgets.pressable.WMinus; import meteordevelopment.meteorclient.gui.widgets.pressable.WPlus; -import meteordevelopment.meteorclient.systems.friends.Friend; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.SavedPlayer; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.utils.misc.NbtUtils; import meteordevelopment.meteorclient.utils.network.MeteorExecutor; import net.minecraft.client.gui.screen.Screen; +import java.util.function.Consumer; + import static meteordevelopment.meteorclient.MeteorClient.mc; -public class FriendsTab extends Tab { - public FriendsTab() { - super("Friends"); +public class TargetingTab extends Tab { + public TargetingTab() { + super("Players"); } @Override public TabScreen createScreen(GuiTheme theme) { - return new FriendsScreen(theme, this); + return new TargetingScreen(theme, this); } @Override public boolean isScreen(Screen screen) { - return screen instanceof FriendsScreen; + return screen instanceof TargetingScreen; } - private static class FriendsScreen extends WindowTabScreen { - public FriendsScreen(GuiTheme theme, Tab tab) { + private static class TargetingScreen extends WindowTabScreen { + public TargetingScreen(GuiTheme theme, Tab tab) { super(theme, tab); } @Override public void initWidgets() { - WTable table = add(theme.table()).expandX().minWidth(400).widget(); - initTable(table); + WTable outerTable = add(theme.table()).expandX().minWidth(800).widget(); + WTable friends = outerTable.add(theme.table()).expandX().minWidth(400).top().widget(); + outerTable.add(theme.verticalSeparator()); + WTable enemies = outerTable.add(theme.table()).expandX().minWidth(400).top().widget(); + + Targeting targeting = Targeting.get(); + + initTable(friends, "Friends", targeting.getFriends(), targeting::removeFriend); + initTable(enemies, "Enemies", targeting.getEnemies(), targeting::removeEnemy); add(theme.horizontalSeparator()).expandX(); @@ -55,12 +65,14 @@ public void initWidgets() { WTextBox nameW = list.add(theme.textBox("", (text, c) -> c != ' ')).expandX().widget(); nameW.setFocused(true); - WPlus add = list.add(theme.plus()).widget(); - add.action = () -> { + WButton addF = list.add(theme.button("Friend")).widget(); + WButton addE = list.add(theme.button("Enemy")).widget(); + + addF.action = () -> { String name = nameW.get().trim(); - Friend friend = new Friend(name); + SavedPlayer friend = new SavedPlayer(name); - if (Friends.get().add(friend)) { + if (targeting.addFriend(friend)) { nameW.set(""); reload(); @@ -71,14 +83,30 @@ public void initWidgets() { } }; - enterAction = add.action; + addE.action = () -> { + String name = nameW.get().trim(); + SavedPlayer enemy = new SavedPlayer(name); + + if (targeting.addEnemy(enemy)) { + nameW.set(""); + reload(); + + MeteorExecutor.execute(() -> { + enemy.updateInfo(); + mc.execute(this::reload); + }); + } + }; } - private void initTable(WTable table) { + private void initTable(WTable table, String title,Iterable source, Consumer removeAction) { table.clear(); - if (Friends.get().isEmpty()) return; - Friends.get().forEach(friend -> + table.add(theme.label(title, true)).expandCellX().centerX(); + + table.row(); + + source.forEach(friend -> MeteorExecutor.execute(() -> { if (friend.headTextureNeedsUpdate()) { friend.updateInfo(); @@ -86,13 +114,13 @@ private void initTable(WTable table) { }) ); - for (Friend friend : Friends.get()) { + for (SavedPlayer friend : source) { table.add(theme.texture(32, 32, friend.getHead().needsRotate() ? 90 : 0, friend.getHead())); table.add(theme.label(friend.getName())); WMinus remove = table.add(theme.minus()).expandCellX().right().widget(); remove.action = () -> { - Friends.get().remove(friend); + removeAction.accept(friend); reload(); }; @@ -102,12 +130,12 @@ private void initTable(WTable table) { @Override public boolean toClipboard() { - return NbtUtils.toClipboard(Friends.get()); + return NbtUtils.toClipboard(Targeting.get()); } @Override public boolean fromClipboard() { - return NbtUtils.fromClipboard(Friends.get()); + return NbtUtils.fromClipboard(Targeting.get()); } } } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/Systems.java b/src/main/java/meteordevelopment/meteorclient/systems/Systems.java index 803d5706b8..73ea84abb4 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/Systems.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/Systems.java @@ -10,7 +10,7 @@ import meteordevelopment.meteorclient.events.game.GameLeftEvent; import meteordevelopment.meteorclient.systems.accounts.Accounts; import meteordevelopment.meteorclient.systems.config.Config; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.hud.Hud; import meteordevelopment.meteorclient.systems.macros.Macros; import meteordevelopment.meteorclient.systems.modules.Modules; @@ -46,7 +46,7 @@ public static void init() { config.settings.registerColorSettings(null); add(new Macros()); - add(new Friends()); + add(new Targeting()); add(new Accounts()); add(new Waypoints()); add(new Profiles()); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/config/Config.java b/src/main/java/meteordevelopment/meteorclient/systems/config/Config.java index fbb9898355..435eb9e3a3 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/config/Config.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/config/Config.java @@ -96,6 +96,13 @@ public class Config extends System { .build() ); + public final Setting enemyColor = sgVisual.add(new ColorSetting.Builder() + .name("friend-color") + .description("The color used to show enemies.") + .defaultValue(new SettingColor(255, 180, 0)) + .build() + ); + // Modules public final Setting> hiddenModules = sgModules.add(new ModuleListSetting.Builder() diff --git a/src/main/java/meteordevelopment/meteorclient/systems/friends/Friend.java b/src/main/java/meteordevelopment/meteorclient/systems/friends/Friend.java index 125479962d..50b949d4f2 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/friends/Friend.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/friends/Friend.java @@ -5,120 +5,23 @@ package meteordevelopment.meteorclient.systems.friends; -import com.mojang.util.UndashedUuid; -import meteordevelopment.meteorclient.MeteorClient; -import meteordevelopment.meteorclient.utils.misc.ISerializable; -import meteordevelopment.meteorclient.utils.network.FailedHttpResponse; -import meteordevelopment.meteorclient.utils.network.Http; -import meteordevelopment.meteorclient.utils.render.PlayerHeadTexture; -import meteordevelopment.meteorclient.utils.render.PlayerHeadUtils; +import meteordevelopment.meteorclient.systems.targeting.SavedPlayer; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.nbt.NbtCompound; -import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import javax.annotation.Nullable; -import java.net.http.HttpResponse; -import java.util.Objects; import java.util.UUID; -import static meteordevelopment.meteorclient.MeteorClient.mc; - -public class Friend implements ISerializable, Comparable { - public volatile String name; - private volatile @Nullable UUID id; - private volatile @Nullable PlayerHeadTexture headTexture; - private volatile boolean updating; - +@Deprecated // systems.targeting.SavedPlayer +public class Friend extends SavedPlayer { public Friend(String name, @Nullable UUID id) { - this.name = name; - this.id = id; - this.headTexture = null; + super(name, id); } public Friend(PlayerEntity player) { - this(player.getName().getString(), player.getUuid()); - } - public Friend(String name) { - this(name, null); - } - - public String getName() { - return name; - } - - public PlayerHeadTexture getHead() { - return headTexture != null ? headTexture : PlayerHeadUtils.STEVE_HEAD; - } - - public void updateInfo() { - updating = true; - HttpResponse res = null; - - if (id != null) { - res = Http.get("https://sessionserver.mojang.com/session/minecraft/profile/" + UndashedUuid.toString(id)) - .exceptionHandler(e -> MeteorClient.LOG.error("Error while trying to connect session server for friend '{}'", name)) - .sendJsonResponse(APIResponse.class); - } - - // Fallback to name-based lookup - if (res == null || res.statusCode() != 200) { - res = Http.get("https://api.mojang.com/users/profiles/minecraft/" + name) - .exceptionHandler(e -> MeteorClient.LOG.error("Error while trying to update info for friend '{}'", name)) - .sendJsonResponse(APIResponse.class); - } - - if (res != null && res.statusCode() == 200) { - name = res.body().name; - id = UndashedUuid.fromStringLenient(res.body().id); - mc.execute(() -> headTexture = PlayerHeadUtils.fetchHead(id)); - } - - // cracked accounts shouldn't be assigned ids - else if (!(res instanceof FailedHttpResponse)) { - id = null; - } - - updating = false; + super(player); } - public boolean headTextureNeedsUpdate() { - return !this.updating && headTexture == null; - } - - @Override - public NbtCompound toTag() { - NbtCompound tag = new NbtCompound(); - - tag.putString("name", name); - if (id != null) tag.putString("id", UndashedUuid.toString(id)); - - return tag; - } - - @Override - public Friend fromTag(NbtCompound tag) { - return this; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Friend friend = (Friend) o; - return Objects.equals(name, friend.name); - } - - @Override - public int hashCode() { - return Objects.hash(name); - } - - @Override - public int compareTo(@NotNull Friend friend) { - return name.compareToIgnoreCase(friend.name); - } - - private static class APIResponse { - String name, id; + public Friend(String name) { + super(name); } } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/friends/Friends.java b/src/main/java/meteordevelopment/meteorclient/systems/friends/Friends.java index 271d6ae92e..1b1c2281e9 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/friends/Friends.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/friends/Friends.java @@ -5,130 +5,97 @@ package meteordevelopment.meteorclient.systems.friends; -import com.mojang.util.UndashedUuid; -import meteordevelopment.meteorclient.systems.System; -import meteordevelopment.meteorclient.systems.Systems; -import meteordevelopment.meteorclient.utils.misc.NbtUtils; -import meteordevelopment.meteorclient.utils.network.MeteorExecutor; +import meteordevelopment.meteorclient.systems.targeting.SavedPlayer; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import net.minecraft.client.network.PlayerListEntry; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.Collections; import java.util.Iterator; -import java.util.List; -public class Friends extends System implements Iterable { - private final List friends = new ArrayList<>(); +// XXX: @Deprecated is spammed in order to make more squiggly lines and increase the probability of them being inspected - public Friends() { - super("friends"); - } +// Behaviour is NOT identical to old the Friends, some things might still break minorly. + +@Deprecated // systems.targeting.Targeting +public class Friends implements Iterable { + private static Friends INSTANCE; + + private Friends() { } public static Friends get() { - return Systems.get(Friends.class); + if (INSTANCE == null) INSTANCE = new Friends(); + return INSTANCE; } + @Deprecated public boolean add(Friend friend) { - if (friend.name.isEmpty() || friend.name.contains(" ")) return false; - - if (!friends.contains(friend)) { - friends.add(friend); - save(); - - return true; - } - - return false; + return Targeting.get().addFriend(friend); } + @Deprecated public boolean remove(Friend friend) { - if (friends.remove(friend)) { - save(); - return true; - } - - return false; + return Targeting.get().removeFriend(friend); } + @Deprecated public Friend get(String name) { - for (Friend friend : friends) { - if (friend.name.equalsIgnoreCase(name)) { - return friend; - } - } - - return null; + return (Friend) Targeting.getFriend(name); } + @Deprecated public Friend get(PlayerEntity player) { return get(player.getName().getString()); } + @Deprecated public Friend get(PlayerListEntry player) { return get(player.getProfile().name()); } + @Deprecated public boolean isFriend(PlayerEntity player) { - return player != null && get(player) != null; + return Targeting.isFriend(player); } + @Deprecated public boolean isFriend(PlayerListEntry player) { - return get(player) != null; + return Targeting.isFriend(player); } + @Deprecated public boolean shouldAttack(PlayerEntity player) { - return !isFriend(player); + return Targeting.shouldAttack(player); } + @Deprecated public int count() { - return friends.size(); + return Targeting.get().countFriends(); } + @Deprecated public boolean isEmpty() { - return friends.isEmpty(); + return Targeting.get().friendsIsEmpty(); } @Override public @NotNull Iterator iterator() { - return friends.iterator(); - } - - @Override - public NbtCompound toTag() { - NbtCompound tag = new NbtCompound(); - - tag.put("friends", NbtUtils.listToTag(friends)); - - return tag; - } - - @Override - public Friends fromTag(NbtCompound tag) { - friends.clear(); - - for (NbtElement itemTag : tag.getListOrEmpty("friends")) { - NbtCompound friendTag = (NbtCompound) itemTag; - if (!friendTag.contains("name")) continue; - - String name = friendTag.getString("name", ""); - if (get(name) != null) continue; - - String uuid = friendTag.getString("id", ""); - Friend friend = !uuid.isBlank() - ? new Friend(name, UndashedUuid.fromStringLenient(uuid)) - : new Friend(name); - - friends.add(friend); - } - - Collections.sort(friends); + Iterator it = Targeting.get().getFriends().iterator(); + return new Iterator<>() { + @Override + public boolean hasNext() { + return it.hasNext(); + } - MeteorExecutor.execute(() -> friends.forEach(Friend::updateInfo)); + @Override + public Friend next() { + return (Friend) it.next(); + } - return this; + @Override + public void remove() { + it.remove(); + } + }; } } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/hud/elements/CombatHud.java b/src/main/java/meteordevelopment/meteorclient/systems/hud/elements/CombatHud.java index 2e2ffd1a42..95752fc759 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/hud/elements/CombatHud.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/hud/elements/CombatHud.java @@ -13,7 +13,7 @@ import meteordevelopment.meteorclient.renderer.text.TextRenderer; import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.config.Config; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.hud.Hud; import meteordevelopment.meteorclient.systems.hud.HudElement; import meteordevelopment.meteorclient.systems.hud.HudElementInfo; @@ -21,7 +21,6 @@ import meteordevelopment.meteorclient.utils.Utils; import meteordevelopment.meteorclient.utils.entity.EntityUtils; import meteordevelopment.meteorclient.utils.entity.SortPriority; -import meteordevelopment.meteorclient.utils.entity.TargetUtils; import meteordevelopment.meteorclient.utils.player.PlayerUtils; import meteordevelopment.meteorclient.utils.render.color.Color; import meteordevelopment.meteorclient.utils.render.color.SettingColor; @@ -237,7 +236,7 @@ public void render(HudRenderer renderer) { Color secondaryColor = TextHud.getSectionColor(1); if (isInEditor()) playerEntity = mc.player; - else playerEntity = TargetUtils.getPlayerTarget(range.get(), SortPriority.LowestDistance); + else playerEntity = Targeting.findPlayerTarget(range.get(), SortPriority.LowestDistance); if (playerEntity == null && !isInEditor()) return; @@ -298,14 +297,22 @@ public void render(HudRenderer renderer) { else distColor = distColor3.get(); // Status Text - String friendText = "Unknown"; + String classText = "Unknown"; - Color friendColor = primaryColor; + Color classColour = primaryColor; - if (Friends.get().isFriend(playerEntity)) { - friendText = "Friend"; - friendColor = Config.get().friendColor.get(); + Targeting.Relation relation = Targeting.getRelation(playerEntity); + + if (relation == Targeting.Relation.FRIEND) { + classText = "Friend"; + classColour = Config.get().friendColor.get(); } else { + + if (relation == Targeting.Relation.ENEMY) { + classText = "Enemy"; + classColour = Config.get().enemyColor.get(); + } + boolean naked = true; for (int position = 3; position >= 0; position--) { @@ -315,8 +322,8 @@ public void render(HudRenderer renderer) { } if (naked) { - friendText = "Naked"; - friendColor = GREEN; + classText = relation == Targeting.Relation.ENEMY ? "Naked (Enemy)" : "Naked"; + classColour = relation == Targeting.Relation.ENEMY ? Color.YELLOW : GREEN; } else { boolean threat = false; @@ -330,8 +337,8 @@ public void render(HudRenderer renderer) { } if (threat) { - friendText = "Threat"; - friendColor = RED; + classText = relation == Targeting.Relation.ENEMY ? "Threat (Enemy)" : "Threat"; + classColour = relation == Targeting.Relation.ENEMY ? Config.get().enemyColor.get() : RED; } } } @@ -340,13 +347,13 @@ public void render(HudRenderer renderer) { double breakWidth = TextRenderer.get().getWidth(breakText); double pingWidth = TextRenderer.get().getWidth(pingText); - double friendWidth = TextRenderer.get().getWidth(friendText); + double friendWidth = TextRenderer.get().getWidth(classText); TextRenderer.get().render(nameText, x, y, nameColor != null ? nameColor : primaryColor); y += TextRenderer.get().getHeight(); - TextRenderer.get().render(friendText, x, y, friendColor); + TextRenderer.get().render(classText, x, y, classColour); if (displayPing.get()) { TextRenderer.get().render(breakText, x + friendWidth, y, secondaryColor); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/hud/elements/PlayerRadarHud.java b/src/main/java/meteordevelopment/meteorclient/systems/hud/elements/PlayerRadarHud.java index c2908620f3..cff54fdb11 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/hud/elements/PlayerRadarHud.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/hud/elements/PlayerRadarHud.java @@ -6,7 +6,7 @@ package meteordevelopment.meteorclient.systems.hud.elements; import meteordevelopment.meteorclient.settings.*; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.hud.*; import meteordevelopment.meteorclient.utils.player.PlayerUtils; import meteordevelopment.meteorclient.utils.render.color.Color; @@ -151,7 +151,7 @@ public void tick(HudRenderer renderer) { for (PlayerEntity entity : getPlayers()) { if (entity.equals(mc.player)) continue; - if (!friends.get() && Friends.get().isFriend(entity)) continue; + if (!friends.get() && Targeting.isFriend(entity)) continue; String text = entity.getName().getString(); if (distance.get()) text += String.format("(%sm)", Math.round(mc.getCameraEntity().distanceTo(entity))); @@ -178,7 +178,7 @@ public void render(HudRenderer renderer) { for (PlayerEntity entity : getPlayers()) { if (entity.equals(mc.player)) continue; - if (!friends.get() && Friends.get().isFriend(entity)) continue; + if (!friends.get() && Targeting.isFriend(entity)) continue; String text = entity.getName().getString(); Color color = PlayerUtils.getPlayerColor(entity, primaryColor.get()); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AnchorAura.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AnchorAura.java index 0623add9e0..8f830a10c1 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AnchorAura.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AnchorAura.java @@ -12,10 +12,10 @@ import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.utils.entity.DamageUtils; import meteordevelopment.meteorclient.utils.entity.EntityUtils; import meteordevelopment.meteorclient.utils.entity.SortPriority; -import meteordevelopment.meteorclient.utils.entity.TargetUtils; import meteordevelopment.meteorclient.utils.player.FindItemResult; import meteordevelopment.meteorclient.utils.player.InvUtils; import meteordevelopment.meteorclient.utils.player.PlayerUtils; @@ -286,10 +286,10 @@ private void onTick(TickEvent.Pre event) { } // Find a target - if (TargetUtils.isBadTarget(target, targetRange.get())) { + if (!Targeting.isValidPlayerTarget(target, targetRange.get())) { renderBlockPos = null; - target = TargetUtils.getPlayerTarget(targetRange.get(), targetPriority.get()); - if (TargetUtils.isBadTarget(target, targetRange.get())) return; + target = Targeting.findPlayerTarget(targetRange.get(), targetPriority.get()); + if (target == null) return; } doAnchorAura(); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoAnvil.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoAnvil.java index 674afe4078..e716cbb371 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoAnvil.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoAnvil.java @@ -10,9 +10,9 @@ import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.utils.entity.EntityUtils; import meteordevelopment.meteorclient.utils.entity.SortPriority; -import meteordevelopment.meteorclient.utils.entity.TargetUtils; import meteordevelopment.meteorclient.utils.player.FindItemResult; import meteordevelopment.meteorclient.utils.player.InvUtils; import meteordevelopment.meteorclient.utils.world.BlockUtils; @@ -121,9 +121,9 @@ private void onTick(TickEvent.Pre event) { } // Check distance + alive - if (TargetUtils.isBadTarget(target, range.get())) { - target = TargetUtils.getPlayerTarget(range.get(), priority.get()); - if (TargetUtils.isBadTarget(target, range.get())) return; + if (!Targeting.isValidPlayerTarget(target, range.get())) { + target = Targeting.findPlayerTarget(range.get(), priority.get()); + if (target == null) return; } if (placeButton.get()) { diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoCity.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoCity.java index a7e3629c6f..064c0e8ecc 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoCity.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoCity.java @@ -11,9 +11,9 @@ import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.utils.entity.EntityUtils; import meteordevelopment.meteorclient.utils.entity.SortPriority; -import meteordevelopment.meteorclient.utils.entity.TargetUtils; import meteordevelopment.meteorclient.utils.player.FindItemResult; import meteordevelopment.meteorclient.utils.player.InvUtils; import meteordevelopment.meteorclient.utils.player.PlayerUtils; @@ -141,8 +141,8 @@ public AutoCity() { @Override public void onActivate() { - target = TargetUtils.getPlayerTarget(targetRange.get(), SortPriority.ClosestAngle); - if (TargetUtils.isBadTarget(target, targetRange.get())) { + target = Targeting.findPlayerTarget(targetRange.get(), SortPriority.ClosestAngle); + if (!Targeting.isValidPlayerTarget(target, targetRange.get())) { if (chatInfo.get()) error("Couldn't find a target, disabling."); toggle(); return; @@ -181,7 +181,7 @@ public void onDeactivate() { @EventHandler private void onTick(TickEvent.Pre event) { - if (TargetUtils.isBadTarget(target, targetRange.get())) { + if (!Targeting.isValidPlayerTarget(target, targetRange.get())) { toggle(); return; } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoLog.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoLog.java index a7245f206e..373f4a0c34 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoLog.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoLog.java @@ -11,7 +11,7 @@ import meteordevelopment.meteorclient.events.packets.PacketEvent; import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.settings.*; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; @@ -61,10 +61,10 @@ public class AutoLog extends Module { .build() ); - private final Setting onlyTrusted = sgGeneral.add(new BoolSetting.Builder() - .name("only-trusted") - .description("Disconnects when a player not on your friends list appears in render distance.") - .defaultValue(false) + private final Setting playerSelector = sgGeneral.add(new EnumSetting.Builder() + .name("players") + .description("Disconnects when a player appears in render distance.") + .defaultValue(Targeting.Selector.Enemies) .build() ); @@ -193,13 +193,17 @@ private void onTick(TickEvent.Post event) { return; } - if (!onlyTrusted.get() && !instantDeath.get() && entities.get().isEmpty()) + if (playerSelector.get() == Targeting.Selector.None && !instantDeath.get() && entities.get().isEmpty()) return; // only check all entities if needed for (Entity entity : mc.world.getEntities()) { if (entity instanceof PlayerEntity player && player.getUuid() != mc.player.getUuid()) { - if (onlyTrusted.get() && player != mc.player && !Friends.get().isFriend(player)) { - disconnect(Text.literal("Non-trusted player '" + Formatting.RED + player.getName().getString() + Formatting.WHITE + "' appeared in your render distance.")); + if (player == mc.player) continue; + + Targeting.Relation relation = Targeting.getRelation(player); + + if (Targeting.matchesSelector(playerSelector.get(), relation)) { + disconnect(Text.literal("Player '" + Formatting.RED + player.getName().getString() + Formatting.WHITE + "' (" + relation + ") appeared in your render distance.")); if (toggleOff.get()) this.toggle(); return; } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoTrap.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoTrap.java index d22367c277..624e3205c4 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoTrap.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoTrap.java @@ -11,10 +11,10 @@ import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.utils.Utils; import meteordevelopment.meteorclient.utils.entity.EntityUtils; import meteordevelopment.meteorclient.utils.entity.SortPriority; -import meteordevelopment.meteorclient.utils.entity.TargetUtils; import meteordevelopment.meteorclient.utils.player.FindItemResult; import meteordevelopment.meteorclient.utils.player.InvUtils; import meteordevelopment.meteorclient.utils.player.PlayerUtils; @@ -211,9 +211,9 @@ private void onTick(TickEvent.Pre event) { if (!block.found()) return; // Find target to trap - if (TargetUtils.isBadTarget(target, targetRange.get())) { - target = TargetUtils.getPlayerTarget(targetRange.get(), priority.get()); - if (TargetUtils.isBadTarget(target, targetRange.get())) return; + if (!Targeting.isValidPlayerTarget(target, targetRange.get())) { + target = Targeting.findPlayerTarget(targetRange.get(), priority.get()); + if (target == null) return; } fillPlaceArray(target); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoWeb.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoWeb.java index 0199240000..66bcbb0ec2 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoWeb.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoWeb.java @@ -11,8 +11,8 @@ import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.utils.entity.SortPriority; -import meteordevelopment.meteorclient.utils.entity.TargetUtils; import meteordevelopment.meteorclient.utils.player.FindItemResult; import meteordevelopment.meteorclient.utils.player.InvUtils; import meteordevelopment.meteorclient.utils.player.PlayerUtils; @@ -152,9 +152,9 @@ public void onDeactivate() { private void onTick(TickEvent.Pre event) { placePositions.clear(); - if (TargetUtils.isBadTarget(target, targetRange.get())) { - target = TargetUtils.getPlayerTarget(targetRange.get(), priority.get()); - if (TargetUtils.isBadTarget(target, targetRange.get())) return; + if (!Targeting.isValidPlayerTarget(target, targetRange.get())) { + target = Targeting.findPlayerTarget(targetRange.get(), priority.get()); + if (target == null) return; } // Grab webs from hotbar diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/BedAura.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/BedAura.java index 366a95cf4c..3946a3a4b8 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/BedAura.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/BedAura.java @@ -11,11 +11,11 @@ import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.utils.Utils; import meteordevelopment.meteorclient.utils.entity.DamageUtils; import meteordevelopment.meteorclient.utils.entity.EntityUtils; import meteordevelopment.meteorclient.utils.entity.SortPriority; -import meteordevelopment.meteorclient.utils.entity.TargetUtils; import meteordevelopment.meteorclient.utils.player.*; import meteordevelopment.meteorclient.utils.render.color.SettingColor; import meteordevelopment.meteorclient.utils.world.BlockUtils; @@ -214,7 +214,7 @@ private void onTick(TickEvent.Post event) { if (PlayerUtils.shouldPause(pauseOnMine.get(), pauseOnEat.get(), pauseOnDrink.get())) return; // Find a target - target = TargetUtils.getPlayerTarget(targetRange.get(), priority.get()); + target = Targeting.findPlayerTarget(targetRange.get(), priority.get()); if (target == null) { placePos = null; breakPos = null; diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/BowAimbot.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/BowAimbot.java index f978b420cd..5072e38b73 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/BowAimbot.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/BowAimbot.java @@ -8,12 +8,11 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.pathing.PathManagers; import meteordevelopment.meteorclient.settings.*; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.entity.EntityUtils; import meteordevelopment.meteorclient.utils.entity.SortPriority; -import meteordevelopment.meteorclient.utils.entity.TargetUtils; import meteordevelopment.meteorclient.utils.player.InvUtils; import meteordevelopment.meteorclient.utils.player.PlayerUtils; import meteordevelopment.meteorclient.utils.player.Rotations; @@ -96,19 +95,14 @@ private void onTick(TickEvent.Pre event) { if (!PlayerUtils.isAlive() || !itemInHand()) return; if (!mc.player.getAbilities().creativeMode && !InvUtils.find(itemStack -> itemStack.getItem() instanceof ArrowItem).found()) return; - target = TargetUtils.get(entity -> { - if (entity == mc.player || entity == mc.getCameraEntity()) return false; - if ((entity instanceof LivingEntity && ((LivingEntity) entity).isDead()) || !entity.isAlive()) return false; + target = Targeting.findTarget(priority.get(), entity -> { + if (!Targeting.isValidTarget(entity)) return false; if (!PlayerUtils.isWithin(entity, range.get())) return false; if (!entities.get().contains(entity.getType())) return false; if (!nametagged.get() && entity.hasCustomName()) return false; if (!PlayerUtils.canSeeEntity(entity)) return false; - if (entity instanceof PlayerEntity) { - if (((PlayerEntity) entity).isCreative()) return false; - if (!Friends.get().shouldAttack((PlayerEntity) entity)) return false; - } return !(entity instanceof AnimalEntity) || babies.get() || !((AnimalEntity) entity).isBaby(); - }, priority.get()); + }); if (target == null) { if (wasPathing) { diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/CrystalAura.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/CrystalAura.java index b3e4461342..ee1605a4be 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/CrystalAura.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/CrystalAura.java @@ -19,7 +19,7 @@ import meteordevelopment.meteorclient.renderer.ShapeMode; import meteordevelopment.meteorclient.renderer.text.TextRenderer; import meteordevelopment.meteorclient.settings.*; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.entity.DamageUtils; @@ -559,7 +559,7 @@ public class CrystalAura extends Module { private Item mainItem, offItem; private int breakTimer, placeTimer, switchTimer, ticksPassed; - private final List targets = new ArrayList<>(); + private final List targets = new ArrayList<>(); private final Vec3d vec3d = new Vec3d(0, 0, 0); private final Vec3d playerEyePos = new Vec3d(0, 0, 0); @@ -1120,7 +1120,8 @@ private boolean shouldFacePlace() { if (forceFacePlace.get().isPressed()) return true; // Checks if the provided crystal position should face place to any target - for (LivingEntity target : targets) { + for (Entity _target : targets) { + LivingEntity target = (LivingEntity) _target; if (EntityUtils.getTotalHealth(target) <= facePlaceHealth.get()) return true; for (EquipmentSlot slot : AttributeModifierSlot.ARMOR) { @@ -1165,11 +1166,11 @@ private LivingEntity getNearestTarget() { LivingEntity nearestTarget = null; double nearestDistance = Double.MAX_VALUE; - for (LivingEntity target : targets) { + for (Entity target : targets) { double distance = PlayerUtils.squaredDistanceTo(target); if (distance < nearestDistance) { - nearestTarget = target; + nearestTarget = (LivingEntity) target; nearestDistance = distance; } } @@ -1185,7 +1186,8 @@ private float getDamageToTargets(Vec3d vec3d, BlockPos obsidianPos, boolean brea if (!(smartDelay.get() && breaking && target.hurtTime > 0)) damage = DamageUtils.crystalDamage(target, vec3d, predictMovement.get(), obsidianPos); } else { - for (LivingEntity target : targets) { + for (Entity _target : targets) { + LivingEntity target = (LivingEntity) _target; if (smartDelay.get() && breaking && target.hurtTime > 0) continue; float dmg = DamageUtils.crystalDamage(target, vec3d, predictMovement.get(), obsidianPos); @@ -1210,18 +1212,11 @@ public String getInfoString() { } private void findTargets() { - targets.clear(); - - // Living Entities - for (Entity entity : mc.world.getEntities()) { - // Ignore non-living - if (!(entity instanceof LivingEntity livingEntity)) continue; + Targeting.findTargets(targets, entity -> { + if (!(entity instanceof LivingEntity livingEntity)) return false; + if (!Targeting.isValidTarget(entity)) return false; - // Player if (livingEntity instanceof PlayerEntity player) { - if (player.getAbilities().creativeMode || livingEntity == mc.player) continue; - if (!player.isAlive() || !Friends.get().shouldAttack(player)) continue; - if (ignoreNakeds.get()) { if (player.getOffHandStack().isEmpty() && player.getMainHandStack().isEmpty() @@ -1229,18 +1224,14 @@ private void findTargets() { && player.getEquippedStack(EquipmentSlot.LEGS).isEmpty() && player.getEquippedStack(EquipmentSlot.CHEST).isEmpty() && player.getEquippedStack(EquipmentSlot.HEAD).isEmpty() - ) continue; + ) return false; } + } else if (!(entities.get().contains(livingEntity.getType()))) { + return false; } - // Animals, water animals, monsters, bats, misc - if (!(entities.get().contains(livingEntity.getType()))) continue; - - // Close enough to damage - if (livingEntity.squaredDistanceTo(mc.player) > targetRange.get() * targetRange.get()) continue; - - targets.add(livingEntity); - } + return livingEntity.squaredDistanceTo(mc.player) > targetRange.get() * targetRange.get(); + }, true); } private boolean intersectsWithEntities(Box box) { diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Hitboxes.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Hitboxes.java index e93622a24c..ca8280d791 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Hitboxes.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Hitboxes.java @@ -6,7 +6,7 @@ package meteordevelopment.meteorclient.systems.modules.combat; import meteordevelopment.meteorclient.settings.*; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.player.InvUtils; @@ -103,7 +103,7 @@ public Hitboxes() { } public double getEntityValue(Entity entity) { - if (!(isActive() && testWeapon()) || (ignoreFriends.get() && entity instanceof PlayerEntity playerEntity && Friends.get().isFriend(playerEntity))) return 0; + if (!(isActive() && testWeapon()) || (ignoreFriends.get() && entity instanceof PlayerEntity playerEntity && Targeting.isFriend(playerEntity))) return 0; if (entities.get().contains(entity.getType())) return value.get(); return 0; } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/HoleFiller.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/HoleFiller.java index 25ea0b41cf..ba2d5c97de 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/HoleFiller.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/HoleFiller.java @@ -10,7 +10,7 @@ import meteordevelopment.meteorclient.mixin.DirectionAccessor; import meteordevelopment.meteorclient.renderer.ShapeMode; import meteordevelopment.meteorclient.settings.*; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.misc.Keybind; @@ -346,20 +346,11 @@ private boolean validHole(BlockPos blockPos) { } private void setTargets() { - targets.clear(); - - for (PlayerEntity player : mc.world.getPlayers()) { - if (player.squaredDistanceTo(mc.player) > Math.pow(targetRange.get(), 2) || - player.isCreative() || - player == mc.player || - player.isDead() || - !Friends.get().shouldAttack(player) || - (ignoreSafe.get() && isSurrounded(player)) || - (onlyMoving.get() && (player.getX() - player.lastX != 0 || player.getY() - player.lastY != 0 || player.getZ() - player.lastZ != 0)) - ) continue; - - targets.add(player); - } + Targeting.findPlayerTargets(targets, targetRange.get(), (player) -> { + if (!Targeting.isValidPlayerTarget(player)) return false; + if (ignoreSafe.get() && isSurrounded(player)) return false; + return !onlyMoving.get() || (player.getX() - player.lastX == 0 && player.getY() - player.lastY == 0 && player.getZ() - player.lastZ == 0); + }); } private boolean isSurrounded(PlayerEntity target) { diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/KillAura.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/KillAura.java index 8726ebb3fc..23201f1aa9 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/KillAura.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/KillAura.java @@ -9,14 +9,13 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.pathing.PathManagers; import meteordevelopment.meteorclient.settings.*; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; import meteordevelopment.meteorclient.utils.entity.EntityUtils; import meteordevelopment.meteorclient.utils.entity.SortPriority; import meteordevelopment.meteorclient.utils.entity.Target; -import meteordevelopment.meteorclient.utils.entity.TargetUtils; import meteordevelopment.meteorclient.utils.player.FindItemResult; import meteordevelopment.meteorclient.utils.player.InvUtils; import meteordevelopment.meteorclient.utils.player.PlayerUtils; @@ -299,7 +298,7 @@ private void onTick(TickEvent.Pre event) { targets.add(mc.targetedEntity); } else { targets.clear(); - TargetUtils.getList(targets, this::entityCheck, priority.get(), maxTargets.get()); + Targeting.findTargets(targets, this::entityCheck, priority.get(), maxTargets.get()); } if (targets.isEmpty()) { @@ -381,8 +380,7 @@ private boolean shouldShieldBreak() { } private boolean entityCheck(Entity entity) { - if (entity.equals(mc.player) || entity.equals(mc.getCameraEntity())) return false; - if ((entity instanceof LivingEntity livingEntity && livingEntity.isDead()) || !entity.isAlive()) return false; + if (!Targeting.isValidTarget(entity)) return false; Box hitbox = entity.getBoundingBox(); if (!PlayerUtils.isWithin( @@ -408,8 +406,6 @@ private boolean entityCheck(Entity entity) { if (entity instanceof WolfEntity wolf && !wolf.isAttacking()) return false; } if (entity instanceof PlayerEntity player) { - if (player.isCreative()) return false; - if (!Friends.get().shouldAttack(player)) return false; if (shieldMode.get() == ShieldMode.Ignore && player.isBlocking()) return false; } if (entity instanceof AnimalEntity animal) { diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/SelfWeb.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/SelfWeb.java index ab3ff3f6bc..e65c87d713 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/SelfWeb.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/SelfWeb.java @@ -9,8 +9,8 @@ import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.utils.entity.SortPriority; -import meteordevelopment.meteorclient.utils.entity.TargetUtils; import meteordevelopment.meteorclient.utils.player.FindItemResult; import meteordevelopment.meteorclient.utils.player.InvUtils; import meteordevelopment.meteorclient.utils.world.BlockUtils; @@ -67,7 +67,7 @@ private void onTick(TickEvent.Pre event) { switch (mode.get()) { case Normal -> placeWeb(); case Smart -> { - if (TargetUtils.getPlayerTarget(range.get(), SortPriority.LowestDistance) != null) placeWeb(); + if (Targeting.findPlayerTarget(range.get(), SortPriority.LowestDistance) != null) placeWeb(); } } } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/MessageAura.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/MessageAura.java index 23c795b191..99ae7f688b 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/MessageAura.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/MessageAura.java @@ -6,11 +6,8 @@ package meteordevelopment.meteorclient.systems.modules.misc; import meteordevelopment.meteorclient.events.entity.EntityAddedEvent; -import meteordevelopment.meteorclient.settings.BoolSetting; -import meteordevelopment.meteorclient.settings.Setting; -import meteordevelopment.meteorclient.settings.SettingGroup; -import meteordevelopment.meteorclient.settings.StringSetting; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.player.ChatUtils; @@ -27,10 +24,10 @@ public class MessageAura extends Module { .build() ); - private final Setting ignoreFriends = sgGeneral.add(new BoolSetting.Builder() - .name("ignore-friends") - .description("Will not send any messages to people friended.") - .defaultValue(false) + private final Setting selector = sgGeneral.add(new EnumSetting.Builder() + .name("target") + .description("What players to target with messages") + .defaultValue(Targeting.Selector.All) .build() ); @@ -40,9 +37,9 @@ public MessageAura() { @EventHandler private void onEntityAdded(EntityAddedEvent event) { - if (!(event.entity instanceof PlayerEntity) || event.entity.getUuid().equals(mc.player.getUuid())) return; + if (!(event.entity instanceof PlayerEntity player) || event.entity.getUuid().equals(mc.player.getUuid())) return; - if (!ignoreFriends.get() || (ignoreFriends.get() && !Friends.get().isFriend((PlayerEntity)event.entity))) { + if (Targeting.matchesSelector(selector.get(), player)) { ChatUtils.sendPlayerMsg("/msg " + event.entity.getName().getString() + " " + message.get()); } } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java index aee4004eef..e0bcc8cdcc 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java @@ -14,7 +14,7 @@ import meteordevelopment.meteorclient.events.packets.PacketEvent; import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.settings.*; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.entity.fakeplayer.FakePlayerEntity; @@ -82,17 +82,10 @@ public class Notifier extends Module { .build() ); - private final Setting totemsIgnoreFriends = sgTotemPops.add(new BoolSetting.Builder() - .name("ignore-friends") - .description("Ignores friends totem pops.") - .defaultValue(false) - .build() - ); - - private final Setting totemsIgnoreOthers = sgTotemPops.add(new BoolSetting.Builder() - .name("ignore-others") - .description("Ignores other players totem pops.") - .defaultValue(false) + private final Setting totemsSelector = sgTotemPops.add(new EnumSetting.Builder() + .name("show-others") + .description("What others players to show totem pops of") + .defaultValue(Targeting.Selector.All) .build() ); @@ -119,10 +112,10 @@ public class Notifier extends Module { .build() ); - private final Setting visualRangeIgnoreFriends = sgVisualRange.add(new BoolSetting.Builder() - .name("ignore-friends") - .description("Ignores friends.") - .defaultValue(true) + private final Setting visualRangeSelector = sgVisualRange.add(new EnumSetting.Builder() + .name("which-players") + .description("Which players to notify of.") + .defaultValue(Targeting.Selector.Nonfriends) .build() ); @@ -156,10 +149,10 @@ public class Notifier extends Module { .build() ); - private final Setting pearlIgnoreFriends = sgPearl.add(new BoolSetting.Builder() - .name("ignore-friends") - .description("Ignores friends pearls.") - .defaultValue(false) + private final Setting pearlSelector = sgPearl.add(new EnumSetting.Builder() + .name("which-pearls") + .description("Which players' pearls to notify of.") + .defaultValue(Targeting.Selector.All) .build() ); @@ -206,9 +199,10 @@ public Notifier() { @EventHandler private void onEntityAdded(EntityAddedEvent event) { if (!event.entity.getUuid().equals(mc.player.getUuid()) && entities.get().contains(event.entity.getType()) && visualRange.get() && this.event.get() != Event.Despawn) { - if (event.entity instanceof PlayerEntity) { - if ((!visualRangeIgnoreFriends.get() || !Friends.get().isFriend(((PlayerEntity) event.entity))) && (!visualRangeIgnoreFakes.get() || !(event.entity instanceof FakePlayerEntity))) { - ChatUtils.sendMsg(event.entity.getId() + 100, Formatting.GRAY, "(highlight)%s(default) has entered your visual range!", event.entity.getName().getString()); + if (event.entity instanceof PlayerEntity player) { + Targeting.Relation relation = Targeting.getRelation(player); + if (Targeting.matchesSelector(visualRangeSelector.get(), relation) && (!visualRangeIgnoreFakes.get() || !(player instanceof FakePlayerEntity))) { + ChatUtils.sendMsg(player.getId() + 100, Formatting.GRAY, "(highlight)%s(default) (%s) has entered your visual range!", player.getName().getString(), relation.toString()); if (visualMakeSound.get()) mc.world.playSoundFromEntity(mc.player, mc.player, SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.AMBIENT, 3.0F, 1.0F); @@ -230,9 +224,10 @@ private void onEntityAdded(EntityAddedEvent event) { @EventHandler private void onEntityRemoved(EntityRemovedEvent event) { if (!event.entity.getUuid().equals(mc.player.getUuid()) && entities.get().contains(event.entity.getType()) && visualRange.get() && this.event.get() != Event.Spawn) { - if (event.entity instanceof PlayerEntity) { - if ((!visualRangeIgnoreFriends.get() || !Friends.get().isFriend(((PlayerEntity) event.entity))) && (!visualRangeIgnoreFakes.get() || !(event.entity instanceof FakePlayerEntity))) { - ChatUtils.sendMsg(event.entity.getId() + 100, Formatting.GRAY, "(highlight)%s(default) has left your visual range!", event.entity.getName().getString()); + if (event.entity instanceof PlayerEntity player) { + Targeting.Relation relation = Targeting.getRelation(player); + if (Targeting.matchesSelector(visualRangeSelector.get(), relation) && (!visualRangeIgnoreFakes.get() || !(player instanceof FakePlayerEntity))) { + ChatUtils.sendMsg(player.getId() + 100, Formatting.GRAY, "(highlight)%s(default) (%s) has left your visual range!", player.getName().getString(), relation.toString()); if (visualMakeSound.get()) mc.world.playSoundFromEntity(mc.player, mc.player, SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.AMBIENT, 3.0F, 1.0F); @@ -253,7 +248,7 @@ private void onEntityRemoved(EntityRemovedEvent event) { EnderPearlEntity pearl = (EnderPearlEntity) e; if (pearl.getOwner() != null && pearl.getOwner() instanceof PlayerEntity p) { double d = pearlStartPosMap.get(i).distanceTo(e.getEntityPos()); - if ((!Friends.get().isFriend(p) || !pearlIgnoreFriends.get()) && (!p.equals(mc.player) || !pearlIgnoreOwn.get())) { + if (Targeting.matchesSelector(pearlSelector.get(), p) && (!p.equals(mc.player) || !pearlIgnoreOwn.get())) { info("(highlight)%s's(default) pearl landed at %d, %d, %d (highlight)(%.1fm away, travelled %.1fm)(default).", pearl.getOwner().getName().getString(), pearl.getBlockPos().getX(), pearl.getBlockPos().getY(), pearl.getBlockPos().getZ(), pearl.distanceTo(mc.player), d); } } @@ -308,9 +303,7 @@ private void onReceivePacket(PacketEvent.Receive event) { createLeaveNotification(packet); case EntityStatusS2CPacket packet when totemPops.get() && packet.getStatus() == EntityStatuses.USE_TOTEM_OF_UNDYING && packet.getEntity(mc.world) instanceof PlayerEntity entity -> { - if ((entity.equals(mc.player) && totemsIgnoreOwn.get()) - || (Friends.get().isFriend(entity) && totemsIgnoreOthers.get()) - || (!Friends.get().isFriend(entity) && totemsIgnoreFriends.get()) + if ((entity.equals(mc.player) && totemsIgnoreOwn.get()) || !Targeting.matchesSelector(totemsSelector.get(), entity) ) return; synchronized (totemPopMap) { diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/movement/AutoWasp.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/movement/AutoWasp.java index 34921e0a4b..37f23971d1 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/movement/AutoWasp.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/movement/AutoWasp.java @@ -11,11 +11,10 @@ import meteordevelopment.meteorclient.mixin.DirectionAccessor; import meteordevelopment.meteorclient.mixininterface.IVec3d; import meteordevelopment.meteorclient.settings.*; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.entity.SortPriority; -import meteordevelopment.meteorclient.utils.entity.TargetUtils; import meteordevelopment.orbit.EventHandler; import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.EquipmentSlot; @@ -92,11 +91,11 @@ public AutoWasp() { @Override public void onActivate() { if (target == null || target.isRemoved()) { - target = (PlayerEntity) TargetUtils.get(entity -> { - if (!(entity instanceof PlayerEntity) || entity == mc.player) return false; - if (((PlayerEntity) entity).isDead() || ((PlayerEntity) entity).getHealth() <= 0) return false; - return !onlyFriends.get() || Friends.get().get((PlayerEntity) entity) != null; - }, SortPriority.LowestDistance); + target = (PlayerEntity) Targeting.findTarget(SortPriority.LowestDistance,entity -> { + if (!(entity instanceof PlayerEntity player) || entity == mc.player) return false; + if (player.isDead() || player.getHealth() <= 0) return false; + return !onlyFriends.get() || Targeting.isFriend(player); + }); if (target == null) { error("No valid targets."); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/MiddleClickExtra.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/MiddleClickExtra.java index 0e08757c94..210238e855 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/MiddleClickExtra.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/MiddleClickExtra.java @@ -14,8 +14,8 @@ import meteordevelopment.meteorclient.settings.EnumSetting; import meteordevelopment.meteorclient.settings.Setting; import meteordevelopment.meteorclient.settings.SettingGroup; -import meteordevelopment.meteorclient.systems.friends.Friend; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.SavedPlayer; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.misc.input.KeyAction; @@ -106,12 +106,12 @@ private void onMouseClick(MouseClickEvent event) { if (mc.targetedEntity == null) return; if (!(mc.targetedEntity instanceof PlayerEntity player)) return; - if (!Friends.get().isFriend(player)) { - Friends.get().add(new Friend(player)); + if (!Targeting.isFriend(player)) { + Targeting.get().addFriend(new SavedPlayer(player)); info("Added %s to friends", player.getName().getString()); if (message.get()) ChatUtils.sendPlayerMsg("/msg " + player.getName() + " I just friended you on Meteor."); } else { - Friends.get().remove(Friends.get().get(player)); + Targeting.get().removeFriend(Targeting.getFriend(player)); info("Removed %s from friends", player.getName().getString()); } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoInteract.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoInteract.java index 4bea37d511..fe7bd7f659 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoInteract.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoInteract.java @@ -10,7 +10,7 @@ import meteordevelopment.meteorclient.events.entity.player.InteractEntityEvent; import meteordevelopment.meteorclient.events.entity.player.StartBreakingBlockEvent; import meteordevelopment.meteorclient.settings.*; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.orbit.EventHandler; @@ -105,7 +105,7 @@ public class NoInteract extends Module { private final Setting friends = sgEntities.add(new EnumSetting.Builder() .name("friends") - .description("Friends cancel mode.") + .description("Targeting cancel mode.") .defaultValue(InteractMode.None) .build() ); @@ -177,9 +177,9 @@ private boolean shouldInteractBlock(BlockHitResult hitResult, Hand hand) { } private boolean shouldAttackEntity(Entity entity) { - // Friends + // Targeting if ((friends.get() == InteractMode.Both || friends.get() == InteractMode.Hit) && - entity instanceof PlayerEntity && !Friends.get().shouldAttack((PlayerEntity) entity)) { + entity instanceof PlayerEntity && !Targeting.shouldAttack((PlayerEntity) entity)) { return false; } @@ -210,9 +210,9 @@ private boolean shouldInteractEntity(Entity entity, Hand hand) { return false; } - // Friends + // Targeting if ((friends.get() == InteractMode.Both || friends.get() == InteractMode.Interact) && - entity instanceof PlayerEntity && !Friends.get().shouldAttack((PlayerEntity) entity)) { + entity instanceof PlayerEntity && !Targeting.shouldAttack((PlayerEntity) entity)) { return false; } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/BetterTab.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/BetterTab.java index ac4ed36104..d7dc2e7bc8 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/BetterTab.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/BetterTab.java @@ -7,10 +7,11 @@ import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.config.Config; -import meteordevelopment.meteorclient.systems.friends.Friend; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.SavedPlayer; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.utils.entity.Target; import meteordevelopment.meteorclient.utils.render.color.Color; import meteordevelopment.meteorclient.utils.render.color.SettingColor; import net.minecraft.client.network.PlayerListEntry; @@ -57,9 +58,9 @@ public class BetterTab extends Module { .build() ); - private final Setting friends = sgGeneral.add(new BoolSetting.Builder() - .name("highlight-friends") - .description("Highlights friends in the tablist.") + private final Setting relations = sgGeneral.add(new BoolSetting.Builder() + .name("highlight-players") + .description("Highlights friends and enemies in the tablist.") .defaultValue(true) .build() ); @@ -93,9 +94,10 @@ public Text getPlayerName(PlayerListEntry playerListEntry) { if (playerListEntry.getProfile().id().toString().equals(mc.player.getGameProfile().id().toString()) && self.get()) { color = selfColor.get(); } - else if (friends.get() && Friends.get().isFriend(playerListEntry)) { - Friend friend = Friends.get().get(playerListEntry); - if (friend != null) color = Config.get().friendColor.get(); + else if (relations.get()) { + Targeting.Relation relation = Targeting.getRelation(playerListEntry); + if (relation == Targeting.Relation.FRIEND) color = Config.get().friendColor.get(); + if (relation == Targeting.Relation.ENEMY) color = Config.get().enemyColor.get(); } if (color != null) { diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/CityESP.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/CityESP.java index 6d9816db96..caab6b7099 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/CityESP.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/CityESP.java @@ -14,9 +14,10 @@ import meteordevelopment.meteorclient.settings.SettingGroup; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.utils.entity.EntityUtils; import meteordevelopment.meteorclient.utils.entity.SortPriority; -import meteordevelopment.meteorclient.utils.entity.TargetUtils; +import meteordevelopment.meteorclient.utils.player.PlayerUtils; import meteordevelopment.meteorclient.utils.render.color.SettingColor; import meteordevelopment.orbit.EventHandler; import net.minecraft.entity.player.PlayerEntity; @@ -56,9 +57,9 @@ public CityESP() { @EventHandler private void onTick(TickEvent.Post event) { - PlayerEntity targetEntity = TargetUtils.getPlayerTarget(mc.player.getBlockInteractionRange() + 2, SortPriority.LowestDistance); + PlayerEntity targetEntity = Targeting.findPlayerTarget(mc.player.getBlockInteractionRange() + 2, SortPriority.LowestDistance); - if (TargetUtils.isBadTarget(targetEntity, mc.player.getBlockInteractionRange() + 2)) { + if (targetEntity == null) { target = null; } else { target = EntityUtils.getCityBlock(targetEntity); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/ESP.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/ESP.java index 284eef7afe..981ca214a2 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/ESP.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/ESP.java @@ -11,7 +11,7 @@ import meteordevelopment.meteorclient.renderer.ShapeMode; import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.config.Config; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.entity.EntityUtils; @@ -130,9 +130,9 @@ public class ESP extends Module { .build() ); - public final Setting friendOverride = sgColors.add(new BoolSetting.Builder() - .name("show-friend-colors") - .description("Whether or not to override the distance color of friends with the friend color.") + public final Setting relationOverride = sgColors.add(new BoolSetting.Builder() + .name("show-relation-colors") + .description("Whether or not to override the distance color of friends/enemies with the friend color.") .defaultValue(true) .visible(distance::get) .build() @@ -380,9 +380,12 @@ private double getFadeAlpha(Entity entity) { public Color getEntityTypeColor(Entity entity) { if (distance.get()) { - if (friendOverride.get() && entity instanceof PlayerEntity && Friends.get().isFriend((PlayerEntity) entity)) { - return Config.get().friendColor.get(); - } else return EntityUtils.getColorFromDistance(entity); + if (relationOverride.get() && entity instanceof PlayerEntity player) { + Targeting.Relation relation = Targeting.getRelation(player); + if (relation == Targeting.Relation.FRIEND) return Config.get().friendColor.get(); + if (relation == Targeting.Relation.ENEMY) return Config.get().enemyColor.get(); + } + return EntityUtils.getColorFromDistance(entity); } else if (entity instanceof PlayerEntity) { return PlayerUtils.getPlayerColor(((PlayerEntity) entity), playersColor.get()); } else { diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Nametags.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Nametags.java index ccf56bef3a..d1bb36da01 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Nametags.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Nametags.java @@ -14,7 +14,7 @@ import meteordevelopment.meteorclient.renderer.text.TextRenderer; import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.config.Config; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; @@ -77,10 +77,10 @@ public class Nametags extends Module { .build() ); - private final Setting ignoreFriends = sgGeneral.add(new BoolSetting.Builder() - .name("ignore-friends") - .description("Ignore rendering nametags for friends.") - .defaultValue(false) + private final Setting selector = sgGeneral.add(new EnumSetting.Builder() + .name("other-players") + .description("Which other players to show nametags for") + .defaultValue(Targeting.Selector.All) .build() ); @@ -330,7 +330,7 @@ private void onTick(TickEvent.Post event) { if (type == EntityType.PLAYER) { if ((ignoreSelf.get() || (freecamNotActive && notThirdPerson)) && entity == mc.player) continue; if (EntityUtils.getGameMode((PlayerEntity) entity) == null && ignoreBots.get()) continue; - if (Friends.get().isFriend((PlayerEntity) entity) && ignoreFriends.get()) continue; + if (!Targeting.matchesSelector(selector.get(), (PlayerEntity) entity)) continue; } if (!culling.get() || PlayerUtils.isWithinCamera(entity, maxCullRange.get())) { diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Tracers.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Tracers.java index edac39cb37..ff791c4926 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Tracers.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Tracers.java @@ -10,7 +10,7 @@ import meteordevelopment.meteorclient.renderer.Renderer2D; import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.config.Config; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; @@ -154,7 +154,7 @@ public enum TracerStyle { .build() ); - public final Setting friendOverride = sgColors.add(new BoolSetting.Builder() + public final Setting relationOverride = sgColors.add(new BoolSetting.Builder() .name("show-friend-colors") .description("Whether or not to override the distance color of friends with the friend color.") .defaultValue(true) @@ -218,17 +218,25 @@ public Tracers() { } private boolean shouldBeIgnored(Entity entity) { - return !PlayerUtils.isWithin(entity, maxDist.get()) || (!Modules.get().isActive(Freecam.class) && entity == mc.player) || !entities.get().contains(entity.getType()) || (ignoreSelf.get() && entity == mc.player) || (ignoreFriends.get() && entity instanceof PlayerEntity && Friends.get().isFriend((PlayerEntity) entity)) || (!showInvis.get() && entity.isInvisible()) | !EntityUtils.isInRenderDistance(entity); + if (!PlayerUtils.isWithin(entity, maxDist.get())) return true; + if (!Modules.get().isActive(Freecam.class) && entity == mc.player) return true; + if (!entities.get().contains(entity.getType())) return true; + if (ignoreSelf.get() && entity == mc.player) return true; + if (ignoreFriends.get() && entity instanceof PlayerEntity && Targeting.isFriend((PlayerEntity) entity)) return true; + if (!showInvis.get() && entity.isInvisible()) return true; + return !EntityUtils.isInRenderDistance(entity); } private Color getEntityColor(Entity entity) { - Color color; + Color color = null; if (distance.get()) { - if (friendOverride.get() && entity instanceof PlayerEntity && Friends.get().isFriend((PlayerEntity) entity)) { - color = Config.get().friendColor.get(); + if (entity instanceof PlayerEntity player && relationOverride.get()) { + Targeting.Relation relation = Targeting.getRelation(player); + if (relation == Targeting.Relation.FRIEND) color = Config.get().friendColor.get(); + if (relation == Targeting.Relation.ENEMY) color = Config.get().enemyColor.get(); } - else color = EntityUtils.getColorFromDistance(entity); + if (color == null) color = EntityUtils.getColorFromDistance(entity); } else if (entity instanceof PlayerEntity) { color = PlayerUtils.getPlayerColor(((PlayerEntity) entity), playersColor.get()); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoNametag.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoNametag.java index 5c93427b05..3c8d43e25e 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoNametag.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoNametag.java @@ -11,8 +11,8 @@ import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.utils.entity.SortPriority; -import meteordevelopment.meteorclient.utils.entity.TargetUtils; import meteordevelopment.meteorclient.utils.player.FindItemResult; import meteordevelopment.meteorclient.utils.player.InvUtils; import meteordevelopment.meteorclient.utils.player.PlayerUtils; @@ -92,7 +92,7 @@ private void onTickPre(TickEvent.Pre event) { } // Target - target = TargetUtils.get(entity -> { + target = Targeting.findTarget(priority.get(),entity -> { if (!PlayerUtils.isWithin(entity, range.get())) return false; if (!entities.get().contains(entity.getType())) return false; @@ -100,7 +100,7 @@ private void onTickPre(TickEvent.Pre event) { return false; return entityCooldowns.getInt(entity) <= 0; - }, priority.get()); + }); if (target == null) return; diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/HighwayBuilder.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/HighwayBuilder.java index 9a82372443..fc3fda4b67 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/HighwayBuilder.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/HighwayBuilder.java @@ -20,9 +20,9 @@ import meteordevelopment.meteorclient.systems.modules.Modules; import meteordevelopment.meteorclient.systems.modules.combat.KillAura; import meteordevelopment.meteorclient.systems.modules.player.*; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.utils.Utils; import meteordevelopment.meteorclient.utils.entity.SortPriority; -import meteordevelopment.meteorclient.utils.entity.TargetUtils; import meteordevelopment.meteorclient.utils.misc.HorizontalDirection; import meteordevelopment.meteorclient.utils.misc.MBlockPos; import meteordevelopment.meteorclient.utils.player.*; @@ -1777,7 +1777,8 @@ protected void tick(HighwayBuilder b) { InvUtils.swap(slot, false); } - EndCrystalEntity potentialTarget = (EndCrystalEntity) TargetUtils.get(entity -> { + EndCrystalEntity potentialTarget = (EndCrystalEntity) Targeting.findTarget(SortPriority.LowestDistance, + entity -> { if (!(entity instanceof EndCrystalEntity endCrystal)) return false; if (PlayerUtils.isWithin(endCrystal, 12) || !PlayerUtils.isWithin(endCrystal, 24)) return false; if (b.ignoreCrystals.contains(endCrystal)) return false; @@ -1788,7 +1789,7 @@ protected void tick(HighwayBuilder b) { ((IVec3d) vec1).meteor$set(b.mc.player.getX(), b.mc.player.getY() + b.mc.player.getStandingEyeHeight(), b.mc.player.getZ()); ((IVec3d) vec2).meteor$set(entity.getX(), entity.getY() + 0.5, entity.getZ()); return b.mc.world.raycast(new RaycastContext(vec1, vec2, RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.NONE, b.mc.player)).getType() == HitResult.Type.MISS; - }, SortPriority.LowestDistance); + }); if (target == null || target.isRemoved()) { if (potentialTarget == null) { diff --git a/src/main/java/meteordevelopment/meteorclient/systems/targeting/SavedPlayer.java b/src/main/java/meteordevelopment/meteorclient/systems/targeting/SavedPlayer.java new file mode 100644 index 0000000000..63bf10bcba --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/systems/targeting/SavedPlayer.java @@ -0,0 +1,124 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.systems.targeting; + +import com.mojang.util.UndashedUuid; +import meteordevelopment.meteorclient.MeteorClient; +import meteordevelopment.meteorclient.utils.misc.ISerializable; +import meteordevelopment.meteorclient.utils.network.FailedHttpResponse; +import meteordevelopment.meteorclient.utils.network.Http; +import meteordevelopment.meteorclient.utils.render.PlayerHeadTexture; +import meteordevelopment.meteorclient.utils.render.PlayerHeadUtils; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.NbtCompound; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nullable; +import java.net.http.HttpResponse; +import java.util.Objects; +import java.util.UUID; + +import static meteordevelopment.meteorclient.MeteorClient.mc; + +public class SavedPlayer implements ISerializable, Comparable { + public volatile String name; + private volatile @Nullable UUID id; + private volatile @Nullable PlayerHeadTexture headTexture; + private volatile boolean updating; + + public SavedPlayer(String name, @Nullable UUID id) { + this.name = name; + this.id = id; + this.headTexture = null; + } + + public SavedPlayer(PlayerEntity player) { + this(player.getName().getString(), player.getUuid()); + } + public SavedPlayer(String name) { + this(name, null); + } + + public String getName() { + return name; + } + + public PlayerHeadTexture getHead() { + return headTexture != null ? headTexture : PlayerHeadUtils.STEVE_HEAD; + } + + public void updateInfo() { + updating = true; + HttpResponse res = null; + + if (id != null) { + res = Http.get("https://sessionserver.mojang.com/session/minecraft/profile/" + UndashedUuid.toString(id)) + .exceptionHandler(e -> MeteorClient.LOG.error("Error while trying to connect session server for friend '{}'", name)) + .sendJsonResponse(APIResponse.class); + } + + // Fallback to name-based lookup + if (res == null || res.statusCode() != 200) { + res = Http.get("https://api.mojang.com/users/profiles/minecraft/" + name) + .exceptionHandler(e -> MeteorClient.LOG.error("Error while trying to update info for friend '{}'", name)) + .sendJsonResponse(APIResponse.class); + } + + if (res != null && res.statusCode() == 200) { + name = res.body().name; + id = UndashedUuid.fromStringLenient(res.body().id); + mc.execute(() -> headTexture = PlayerHeadUtils.fetchHead(id)); + } + + // cracked accounts shouldn't be assigned ids + else if (!(res instanceof FailedHttpResponse)) { + id = null; + } + + updating = false; + } + + public boolean headTextureNeedsUpdate() { + return !this.updating && headTexture == null; + } + + @Override + public NbtCompound toTag() { + NbtCompound tag = new NbtCompound(); + + tag.putString("name", name); + if (id != null) tag.putString("id", UndashedUuid.toString(id)); + + return tag; + } + + @Override + public SavedPlayer fromTag(NbtCompound tag) { + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SavedPlayer player = (SavedPlayer) o; + return Objects.equals(name, player.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } + + @Override + public int compareTo(@NotNull SavedPlayer player) { + return name.compareToIgnoreCase(player.name); + } + + private static class APIResponse { + String name, id; + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/systems/targeting/Targeting.java b/src/main/java/meteordevelopment/meteorclient/systems/targeting/Targeting.java new file mode 100644 index 0000000000..86ca371ed7 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/systems/targeting/Targeting.java @@ -0,0 +1,462 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.systems.targeting; + +import com.mojang.util.UndashedUuid; +import meteordevelopment.meteorclient.systems.System; +import meteordevelopment.meteorclient.systems.Systems; +import meteordevelopment.meteorclient.utils.Utils; +import meteordevelopment.meteorclient.utils.entity.EntityUtils; +import meteordevelopment.meteorclient.utils.entity.fakeplayer.FakePlayerEntity; +import meteordevelopment.meteorclient.utils.entity.fakeplayer.FakePlayerManager; +import meteordevelopment.meteorclient.utils.misc.NbtUtils; +import meteordevelopment.meteorclient.utils.network.MeteorExecutor; +import meteordevelopment.meteorclient.utils.player.PlayerUtils; +import net.minecraft.client.network.PlayerListEntry; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; +import net.minecraft.nbt.NbtList; +import net.minecraft.world.GameMode; +import org.jetbrains.annotations.Unmodifiable; + +import javax.annotation.Nullable; +import java.util.*; +import java.util.function.Predicate; + +import static meteordevelopment.meteorclient.MeteorClient.mc; + + +@SuppressWarnings("BooleanMethodIsAlwaysInverted") +public final class Targeting extends System { + private final List friends = new ArrayList<>(); + private final List enemies = new ArrayList<>(); + + public boolean prioritizePlayers; + + private static Targeting INSTANCE; + + public static Targeting get() { + if (INSTANCE == null) INSTANCE = Systems.get(Targeting.class); + return INSTANCE; + } + + public Targeting() { + // legacy name + super("friends"); + } + + public boolean addFriend(SavedPlayer friend) { + if (friend.name.isEmpty() || friend.name.contains(" ")) return false; + + enemies.remove(friend); + + if (!friends.contains(friend)) { + friends.add(friend); + save(); + + return true; + } + + return false; + } + + public boolean removeFriend(SavedPlayer friend) { + if (friends.remove(friend)) { + save(); + return true; + } + + return false; + } + + public boolean addEnemy(SavedPlayer enemy) { + if (enemy.name.isEmpty() || enemy.name.contains(" ")) return false; + + friends.remove(enemy); + + if (!enemies.contains(enemy)) { + enemies.add(enemy); + save(); + + return true; + } + + return false; + } + + public boolean removeEnemy(SavedPlayer enemy) { + if (enemies.remove(enemy)) { + save(); + return true; + } + + return false; + } + + + + public int countFriends() { + return friends.size(); + } + + public int countEnemies() { + return enemies.size(); + } + + public boolean friendsIsEmpty() { + return friends.isEmpty(); + } + + public boolean enemiesIsEmpty() { + return enemies.isEmpty(); + } + + public static Relation getRelation(String playerName) { + Targeting self = get(); + for (SavedPlayer friend : self.friends) { + if (friend.name.equalsIgnoreCase(playerName)) { + return Relation.FRIEND; + } + } + for (SavedPlayer enemy : self.enemies) { + if (enemy.name.equalsIgnoreCase(playerName)) { + return Relation.ENEMY; + } + } + return Relation.NEUTRAL; + } + + public static boolean matchesSelector(Selector selector, Relation relation) { + if (relation == Relation.IGNORE) return false; + if (selector == Selector.All) return true; + if (selector == Selector.None) return false; + + if (relation == Relation.FRIEND) return selector == Selector.Friends || selector == Selector.Nonenemies; + if (relation == Relation.ENEMY) return selector == Selector.Enemies || selector == Selector.Nonfriends; + + return selector == Selector.Neutrals || selector == Selector.Nonfriends || selector == Selector.Nonenemies; + } + + public static boolean matchesSelector(Selector selector, String playerName) { + return matchesSelector(selector, getRelation(playerName)); + } + + public static boolean matchesSelector(Selector selector, PlayerListEntry player) { + return matchesSelector(selector, getRelation(player)); + } + + public static boolean matchesSelector(Selector selector, PlayerEntity player) { + return matchesSelector(selector, getRelation(player)); + } + + public static Relation getRelation(PlayerListEntry player) { + return getRelation(player.getProfile().name()); + } + + public static Relation getRelation(PlayerEntity player) { + if (player == null) return Relation.IGNORE; + if (player == mc.player) return Relation.IGNORE; + return getRelation(player.getName().getString()); + } + + public static SavedPlayer getFriend(String name) { + for (SavedPlayer friend : get().friends) { + if (friend.name.equalsIgnoreCase(name)) { + return friend; + } + } + + return null; + } + + public static SavedPlayer getFriend(PlayerEntity player) { + return getFriend(player.getName().getString()); + } + + public static SavedPlayer getFriend(PlayerListEntry player) { + return getFriend(player.getProfile().name()); + } + + public static SavedPlayer getEnemy(String name) { + for (SavedPlayer enemy : get().enemies) { + if (enemy.name.equalsIgnoreCase(name)) { + return enemy; + } + } + + return null; + } + + public static SavedPlayer getEnemy(PlayerEntity player) { + return getEnemy(player.getName().getString()); + } + + public static SavedPlayer getEnemy(PlayerListEntry player) { + return getEnemy(player.getProfile().name()); + } + + public static boolean isFriend(PlayerEntity player) { + return player != null && getFriend(player) != null; + } + + public static boolean isFriend(PlayerListEntry player) { + return getFriend(player) != null; + } + + public static boolean isEnemy(PlayerEntity player) { + return player != null && getEnemy(player) != null; + } + + public static boolean isEnemy(PlayerListEntry player) { + return getEnemy(player) != null; + } + + public static boolean isNeutral(PlayerEntity player) { + return !isEnemy(player) && !isFriend(player); + } + + public static boolean isNeutral(PlayerListEntry player) { + return !isEnemy(player) && !isFriend(player); + } + + public static boolean shouldAttack(PlayerEntity player) { + return !isFriend(player); + } + + + public static void sortTargets(List targets, @Nullable Boolean prioritizePlayers, Comparator secondarySort) { + boolean pp = (prioritizePlayers != null) ? prioritizePlayers : get().prioritizePlayers; + + targets.sort((a, b) -> { + if (pp) { + if (a instanceof PlayerEntity && !(b instanceof PlayerEntity)) return +1; + if (!(a instanceof PlayerEntity) && b instanceof PlayerEntity) return -1; + } + + if (a instanceof PlayerEntity pa && b instanceof PlayerEntity pb) { + if (isEnemy(pa) && !isEnemy(pb)) return 1; + if (!isEnemy(pa) && isEnemy(pb)) return -1; + } + return secondarySort.compare(a, b); + }); + } + + public static void sortTargets(List targets, Comparator secondarySort) { + sortTargets(targets, null, secondarySort); + } + + public static void findTargets(List output, @Nullable Predicate matching, @Nullable Boolean prioritizePlayers, Comparator secondarySort, int maxCount) { + output.clear(); + + if (!Utils.canUpdate()) return; + + for (Entity entity : mc.world.getEntities()) { + if (entity != null && (matching == null || matching.test(entity))) output.add(entity); + } + + FakePlayerManager.forEach(fp -> { + if (fp != null && (matching == null || matching.test(fp))) output.add(fp); + }); + + sortTargets(output, prioritizePlayers, secondarySort); + + // fast list trimming + if (maxCount > 0 && output.size() > maxCount) { + output.subList(maxCount, output.size()).clear(); + } + } + + public static void findTargets(List output, @Nullable Predicate matching, Comparator secondarySort, int maxCount) { + findTargets(output, matching, null, secondarySort, maxCount); + } + + public static void findTargets(List output, @Nullable Predicate matching, Comparator secondarySort) { + findTargets(output, matching, secondarySort, 0); + } + + public static void findTargets(List output, @Nullable Predicate matching, @Nullable Boolean prioritizePlayers, Comparator secondarySort) { + findTargets(output, matching, prioritizePlayers, secondarySort, 0); + } + + public static void findTargets(List output, @Nullable Predicate matching, @Nullable Boolean prioritizePlayers) { + findTargets(output, matching, prioritizePlayers, (a, b) -> 0, 0); + } + + public static void findTargets(List output, @Nullable Predicate matching) { + findTargets(output, matching, null, (a, b) -> 0, 0); + } + + public static void findPlayerTargets(List output, double range, @Nullable Predicate matching, Comparator secondarySort, int maxCount) { + output.clear(); + + if (!Utils.canUpdate()) return; + + for (PlayerEntity entity : mc.world.getPlayers()) { + if (entity != null && (matching == null || matching.test(entity))) output.add(entity); + } + + FakePlayerManager.forEach(fp -> { + if (fp != null && (matching == null || matching.test(fp))) output.add(fp); + }); + + output.sort((a, b) -> { + if (isEnemy(a) && !isEnemy(b)) return 1; + if (!isEnemy(a) && isEnemy(b)) return -1; + return secondarySort.compare(a, b); + }); + + // fast list trimming + if (maxCount > 0 && output.size() > maxCount) { + output.subList(maxCount, output.size()).clear(); + } + } + + public static void findPlayerTargets(List output, double range, @Nullable Predicate matching, Comparator secondarySort) { + findPlayerTargets(output, range, matching, secondarySort, 0); + } + + public static void findPlayerTargets(List output, double range, @Nullable Predicate matching) { + findPlayerTargets(output, range, matching, (a, b) -> 0, 0); + } + + public static void findPlayerTargets(List output, double range, @Nullable Predicate matching, int maxCount) { + findPlayerTargets(output, range, matching, (a, b) -> 0, maxCount); + } + + private static final List ENTITIES = new ArrayList<>(); + + @Nullable + public static Entity findTarget(Comparator secondarySort, @Nullable Predicate matching) { + ENTITIES.clear(); + findTargets(ENTITIES, matching, secondarySort, 1); + if (!ENTITIES.isEmpty()) { + return ENTITIES.getFirst(); + } + + return null; + } + + @Nullable + public static Entity findTarget(Comparator secondarySort) { + return findTarget(secondarySort, null); + } + + @Nullable + public static PlayerEntity findPlayerTarget(double range, Comparator secondarySort) { + return (PlayerEntity) findTarget(secondarySort, entity -> { + if (!(entity instanceof PlayerEntity player)) return false; + return isValidTarget(player, range); + }); + } + + public static boolean isValidPlayerTarget(@Nullable PlayerEntity player) { + if (player == null) return false; + if (player == mc.player || player == mc.getCameraEntity()) return false; + if (player.isDead() || player.getHealth() <= 0) return false; + if (!shouldAttack(player)) return false; + return EntityUtils.getGameMode(player) == GameMode.SURVIVAL || player instanceof FakePlayerEntity; + } + + public static boolean isValidPlayerTarget(@Nullable PlayerEntity player, double range) { + if (player == null) return false; + return PlayerUtils.isWithin(player, range) && isValidPlayerTarget(player); + } + + public static boolean isValidTarget(@Nullable Entity entity) { + if (entity == null) return false; + if (entity == mc.player || entity == mc.getCameraEntity()) return false; + if ((entity instanceof LivingEntity le && le.isDead()) || !entity.isAlive()) return false; + return (!(entity instanceof PlayerEntity pe)) || isValidPlayerTarget(pe); + } + + public static boolean isValidTarget(@Nullable Entity entity, double range) { + if (entity == null) return false; + return PlayerUtils.isWithin(entity, range) && isValidTarget(entity); + } + + + @Override + public NbtCompound toTag() { + NbtCompound tag = new NbtCompound(); + + tag.put("friends", NbtUtils.listToTag(friends)); + tag.put("enemies", NbtUtils.listToTag(enemies)); + + return tag; + } + + private void _fromTag(List to, NbtList from) { + to.clear(); + + for (NbtElement itemTag : from) { + NbtCompound playerTag = (NbtCompound) itemTag; + if (!playerTag.contains("name")) continue; + + String name = playerTag.getString("name", ""); + if (getFriend(name) != null) continue; + + String uuid = playerTag.getString("id", ""); + SavedPlayer player = !uuid.isBlank() + ? new SavedPlayer(name, UndashedUuid.fromStringLenient(uuid)) + : new SavedPlayer(name); + + to.add(player); + } + + Collections.sort(to); + + MeteorExecutor.execute(() -> to.forEach(SavedPlayer::updateInfo)); + } + + @Unmodifiable + public Iterable getFriends() { + return Collections.unmodifiableList(friends); + } + + @Unmodifiable + public Iterable getEnemies() { + return Collections.unmodifiableList(enemies); + } + + @Override + public Targeting fromTag(NbtCompound tag) { + + _fromTag(this.friends, tag.getListOrEmpty("friends")); + _fromTag(this.enemies, tag.getListOrEmpty("enemies")); + + return this; + } + + public enum Relation { + FRIEND, + NEUTRAL, + IGNORE, + ENEMY; + + @Override + public String toString() { + return switch (this) { + case FRIEND -> "Friend"; + case NEUTRAL -> "Neutral"; + case ENEMY -> "Enemy"; + case IGNORE -> "Self"; + }; + } + } + + public enum Selector { + None, + Enemies, + Nonfriends, + Neutrals, + Nonenemies, + Friends, + All + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/utils/entity/TargetUtils.java b/src/main/java/meteordevelopment/meteorclient/utils/entity/TargetUtils.java index bf852e0823..0e89d2ca4f 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/entity/TargetUtils.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/entity/TargetUtils.java @@ -5,71 +5,37 @@ package meteordevelopment.meteorclient.utils.entity; -import meteordevelopment.meteorclient.systems.friends.Friends; -import meteordevelopment.meteorclient.utils.Utils; -import meteordevelopment.meteorclient.utils.entity.fakeplayer.FakePlayerEntity; -import meteordevelopment.meteorclient.utils.entity.fakeplayer.FakePlayerManager; -import meteordevelopment.meteorclient.utils.player.PlayerUtils; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.world.GameMode; import javax.annotation.Nullable; -import java.util.ArrayList; import java.util.List; import java.util.function.Predicate; -import static meteordevelopment.meteorclient.MeteorClient.mc; - +@Deprecated // systems.targeting.Targeting public class TargetUtils { - private static final List ENTITIES = new ArrayList<>(); - private TargetUtils() { + } @Nullable public static Entity get(Predicate isGood, SortPriority sortPriority) { - ENTITIES.clear(); - getList(ENTITIES, isGood, sortPriority, 1); - if (!ENTITIES.isEmpty()) { - return ENTITIES.getFirst(); - } - - return null; + return Targeting.findTarget(sortPriority, isGood); } - public static void getList(List targetList, Predicate isGood, SortPriority sortPriority, int maxCount) { - targetList.clear(); - for (Entity entity : mc.world.getEntities()) { - if (entity != null && isGood.test(entity)) targetList.add(entity); - } - - FakePlayerManager.forEach(fp -> { - if (fp != null && isGood.test(fp)) targetList.add(fp); - }); - - targetList.sort(sortPriority); - // fast list trimming - if (targetList.size() > maxCount) { - targetList.subList(maxCount, targetList.size()).clear(); - } + public static void getList(List targetList, Predicate isGood, SortPriority sortPriority, int maxCount) { + Targeting.findTargets(targetList, isGood, sortPriority, maxCount); } @Nullable public static PlayerEntity getPlayerTarget(double range, SortPriority priority) { - if (!Utils.canUpdate()) return null; - return (PlayerEntity) get(entity -> { - if (!(entity instanceof PlayerEntity) || entity == mc.player) return false; - if (((PlayerEntity) entity).isDead() || ((PlayerEntity) entity).getHealth() <= 0) return false; - if (!PlayerUtils.isWithin(entity, range)) return false; - if (!Friends.get().shouldAttack((PlayerEntity) entity)) return false; - return EntityUtils.getGameMode((PlayerEntity) entity) == GameMode.SURVIVAL || entity instanceof FakePlayerEntity; - }, priority); + return Targeting.findPlayerTarget(range, priority); } + public static boolean isBadTarget(PlayerEntity target, double range) { - if (target == null) return true; - return !PlayerUtils.isWithin(target, range) || !target.isAlive() || target.isDead() || target.getHealth() <= 0; + return !Targeting.isValidPlayerTarget(target, range); } } diff --git a/src/main/java/meteordevelopment/meteorclient/utils/player/PlayerUtils.java b/src/main/java/meteordevelopment/meteorclient/utils/player/PlayerUtils.java index c38fc97d50..14e7bc443e 100644 --- a/src/main/java/meteordevelopment/meteorclient/utils/player/PlayerUtils.java +++ b/src/main/java/meteordevelopment/meteorclient/utils/player/PlayerUtils.java @@ -8,7 +8,7 @@ import meteordevelopment.meteorclient.mixininterface.IVec3d; import meteordevelopment.meteorclient.pathing.PathManagers; import meteordevelopment.meteorclient.systems.config.Config; -import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.targeting.Targeting; import meteordevelopment.meteorclient.systems.modules.Modules; import meteordevelopment.meteorclient.systems.modules.movement.NoFall; import meteordevelopment.meteorclient.utils.Utils; @@ -48,7 +48,7 @@ private PlayerUtils() { } public static Color getPlayerColor(PlayerEntity entity, Color defaultColor) { - if (Friends.get().isFriend(entity)) { + if (Targeting.isFriend(entity)) { return color.set(Config.get().friendColor.get()).a(defaultColor.a); } @@ -198,7 +198,7 @@ public static float possibleHealthReductions(boolean entities, boolean fall) { if (crystalDamage > damageTaken) damageTaken = crystalDamage; } // Check for players holding swords - else if (entity instanceof PlayerEntity player && !Friends.get().isFriend(player) && isWithin(entity, 5)) { + else if (entity instanceof PlayerEntity player && !Targeting.isFriend(player) && isWithin(entity, 5)) { float attackDamage = DamageUtils.getAttackDamage(player, mc.player); if (attackDamage > damageTaken) damageTaken = attackDamage; }