diff --git a/README.md b/README.md index a0a3c3d..f47f199 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,16 @@ Forge mod will automatiaclly buy item according to your configuration, and send you a webhook when it has been bought. # Features: -- Autobuy any item you want, customised by yourself +- Auto buy any item you want, with query customised by yourself +- Auto walk to the auction house +- Auto sell after buying with profit check, so profit is ensured - Can customise fetch time (the faster, the higher chance to get the item you want) - Webhook system to send you that an item has been bought +- Failsafe in Limbo # Changelog: -- v1.0.1-beta - Initial Release +- v1.0.1-beta - Initial Release, with auto buy +- v1.0.2 - Added flipper, profit check, auto post # Example Config: ```cfg @@ -18,6 +22,7 @@ item1 { S:Type=ANY } + item2 { S:Name=Livid Dagger I:Price=5000000 @@ -25,6 +30,7 @@ item2 { S:Type=WEAPON } + item3 { S:Name= I:Price=0 @@ -32,9 +38,12 @@ item3 { S:Type= } + main { - S:APIKey=PASTE KEY HERE - I:AuctionHouseDelay=10 - S:Webhook=PASTE WEBHOOK HERE + S:APIKey=Paste your API key here + I:AuctionHouseDelay=15 + I:Multiplier=400 + S:Webhook=Paste your webhook here + B:checkMultiplierBeforeBuy=false } ``` \ No newline at end of file diff --git a/build.gradle b/build.gradle index a90188c..411d947 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ apply plugin: "net.minecraftforge.gradle.forge" apply plugin: "com.github.johnrengelman.shadow" apply plugin: "org.spongepowered.mixin" -version = "1.0.1-beta" +version = "1.0.2" group = "me.night0721.lilase" archivesBaseName = "Lilase" sourceCompatibility = 1.8 diff --git a/src/main/java/me/night0721/lilase/Lilase.java b/src/main/java/me/night0721/lilase/Lilase.java index 0b57cdd..9c23c04 100644 --- a/src/main/java/me/night0721/lilase/Lilase.java +++ b/src/main/java/me/night0721/lilase/Lilase.java @@ -7,7 +7,9 @@ import com.mojang.realmsclient.gui.ChatFormatting; import me.night0721.lilase.config.AHConfig; import me.night0721.lilase.events.PacketReceivedEvent; import me.night0721.lilase.features.ah.AuctionHouse; +import me.night0721.lilase.features.flip.Flipper; import me.night0721.lilase.managers.KeyBindingManager; +import me.night0721.lilase.managers.SniperFlipperEvents; import me.night0721.lilase.utils.ConfigUtils; import me.night0721.lilase.utils.Utils; import net.minecraft.client.Minecraft; @@ -18,12 +20,17 @@ import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.lwjgl.opengl.Display; + +import java.io.IOException; + +import static me.night0721.lilase.config.AHConfig.AUCTION_HOUSE_DELAY; @Mod(modid = Lilase.MODID, name = Lilase.MOD_NAME, version = Lilase.VERSION, acceptedMinecraftVersions = "[1.8.9]") public class Lilase { public static final String MOD_NAME = "Lilase"; public static final String MODID = "Lilase"; - public static final String VERSION = "1.0.1-beta"; + public static final String VERSION = "1.0.2"; static int tickAmount; public static AuctionHouse auctionHouse; public static AHConfig config; @@ -34,12 +41,12 @@ public class Lilase { public void init(FMLInitializationEvent event) { MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(new KeyBindingManager()); - MinecraftForge.EVENT_BUS.register(new me.night0721.lilase.managers.EventManager()); + MinecraftForge.EVENT_BUS.register(new SniperFlipperEvents()); EventManager.INSTANCE.register(this); ConfigUtils.register(); auctionHouse = new AuctionHouse(); KeyBindingManager.registerKeyBindings(); - ConfigUtils.checkWebhookAndAPI(); + Display.setTitle("Lilase v" + VERSION); } @Subscribe @@ -48,13 +55,20 @@ public class Lilase { } @SubscribeEvent - public void onTick(TickEvent.ClientTickEvent event) { + public void onTick(TickEvent.ClientTickEvent event) throws IOException { if (mc.thePlayer == null || event.phase != TickEvent.Phase.START) return; tickAmount++; if (tickAmount % 20 == 0) { Utils.checkForDungeon(); } + if (tickAmount % (20 * AUCTION_HOUSE_DELAY) == 0) { + auctionHouse.getItem(); + } + if (tickAmount % 2400 == 0) { + ConfigUtils.checkWebhookAndAPI(); + } AuctionHouse.switchStates(); + Flipper.switchStates(); } @SubscribeEvent diff --git a/src/main/java/me/night0721/lilase/config/AHConfig.java b/src/main/java/me/night0721/lilase/config/AHConfig.java index ede4883..20dee56 100644 --- a/src/main/java/me/night0721/lilase/config/AHConfig.java +++ b/src/main/java/me/night0721/lilase/config/AHConfig.java @@ -1,12 +1,12 @@ package me.night0721.lilase.config; import cc.polyfrost.oneconfig.config.Config; -import cc.polyfrost.oneconfig.config.annotations.HUD; +import cc.polyfrost.oneconfig.config.annotations.Checkbox; +import cc.polyfrost.oneconfig.config.annotations.Number; import cc.polyfrost.oneconfig.config.annotations.Slider; import cc.polyfrost.oneconfig.config.annotations.Text; import cc.polyfrost.oneconfig.config.data.Mod; import cc.polyfrost.oneconfig.config.data.ModType; -import me.night0721.lilase.gui.CoordinateGUI; import me.night0721.lilase.utils.ConfigUtils; public class AHConfig extends Config { @@ -15,15 +15,25 @@ public class AHConfig extends Config { initialize(); addListener("AUCTION_HOUSE_DELAY", () -> ConfigUtils.writeIntConfig("main", "AuctionHouseDelay", Math.round(AHConfig.AUCTION_HOUSE_DELAY))); addListener("WEBHOOK", () -> ConfigUtils.writeStringConfig("main", "Webhook", AHConfig.WEBHOOK)); + addListener("CHECK_MULTIPLIER", () -> ConfigUtils.writeBooleanConfig("main", "checkMultiplierBeforeBuy", AHConfig.CHECK_MULTIPLIER)); + addListener("MULTIPLIER", () -> ConfigUtils.writeIntConfig("main", "MULTIPLIER", Math.round(AHConfig.MULTIPLIER))); } - @HUD(name = "Lilase") - public CoordinateGUI hud = new CoordinateGUI(); +// @HUD(name = "Lilase") +// public CoordinateGUI hud = new CoordinateGUI(); - @Slider(name = "Time per fetch (seconds)", min = 5, max = 15, step = 1) - public static int AUCTION_HOUSE_DELAY = 5; + @Slider(name = "Time per fetch (seconds)", min = 5, max = 15, step = 1, category = "Auction House") + public static int AUCTION_HOUSE_DELAY = 8; - @Text(name = "Discord Webhook", placeholder = "URL") + @Text(name = "Discord Webhook", placeholder = "URL", category = "Auction House") public static String WEBHOOK = ""; + + @Checkbox(name = "Check Multiplier Before Buying", category = "Flipper") + public static boolean CHECK_MULTIPLIER = false; + + @Number(name = "Multiplier", min = 100, max = 5000, step = 50, category = "Flipper") + public static int MULTIPLIER = 400; + + } diff --git a/src/main/java/me/night0721/lilase/events/PacketReceivedEvent.java b/src/main/java/me/night0721/lilase/events/PacketReceivedEvent.java index 9c33e96..964f378 100644 --- a/src/main/java/me/night0721/lilase/events/PacketReceivedEvent.java +++ b/src/main/java/me/night0721/lilase/events/PacketReceivedEvent.java @@ -1,10 +1,21 @@ package me.night0721.lilase.events; import io.netty.channel.ChannelHandlerContext; +import me.night0721.lilase.features.flip.Flipper; +import me.night0721.lilase.utils.Utils; import net.minecraft.network.Packet; +import net.minecraft.network.play.client.C12PacketUpdateSign; +import net.minecraft.network.play.server.S33PacketUpdateSign; +import net.minecraft.util.IChatComponent; import net.minecraftforge.fml.common.eventhandler.Cancelable; import net.minecraftforge.fml.common.eventhandler.Event; +import java.io.IOException; + +import static me.night0721.lilase.features.ah.AuctionHouse.flipper; +import static me.night0721.lilase.features.flip.FlipperState.START; +import static me.night0721.lilase.utils.PlayerUtils.sendPacketWithoutEvent; + @Cancelable public class PacketReceivedEvent extends Event { public final Packet packet; @@ -13,5 +24,21 @@ public class PacketReceivedEvent extends Event { public PacketReceivedEvent(final Packet packet, final ChannelHandlerContext context) { this.packet = packet; this.context = context; + if (packet instanceof S33PacketUpdateSign && Utils.checkInHub() && Flipper.state.equals(START)) { + new Thread(() -> { + try { + S33PacketUpdateSign packetUpdateSign = (S33PacketUpdateSign) packet; + IChatComponent[] lines = packetUpdateSign.getLines(); + Utils.debugLog("[Flipper] Item price should be " + flipper.getItemPrice()); + lines[0] = IChatComponent.Serializer.jsonToComponent("{\"text\":\"" + flipper.getItemPrice() + "\"}"); + Thread.sleep(1500); + C12PacketUpdateSign packetUpdateSign1 = new C12PacketUpdateSign(packetUpdateSign.getPos(), lines); + sendPacketWithoutEvent(packetUpdateSign1); + } catch (IOException | InterruptedException | RuntimeException e) { + e.printStackTrace(); + } + + }).start(); + } } } diff --git a/src/main/java/me/night0721/lilase/events/PacketSentEvent.java b/src/main/java/me/night0721/lilase/events/PacketSentEvent.java index 54e2590..17d8679 100644 --- a/src/main/java/me/night0721/lilase/events/PacketSentEvent.java +++ b/src/main/java/me/night0721/lilase/events/PacketSentEvent.java @@ -1,7 +1,8 @@ package me.night0721.lilase.events; -import net.minecraftforge.fml.common.eventhandler.*; -import net.minecraft.network.*; +import net.minecraft.network.Packet; +import net.minecraftforge.fml.common.eventhandler.Cancelable; +import net.minecraftforge.fml.common.eventhandler.Event; @Cancelable public class PacketSentEvent extends Event { @@ -10,5 +11,4 @@ public class PacketSentEvent extends Event { public PacketSentEvent(Packet packet) { this.packet = packet; } - } diff --git a/src/main/java/me/night0721/lilase/features/ah/AuctionHouse.java b/src/main/java/me/night0721/lilase/features/ah/AuctionHouse.java index 9e8c152..335351e 100644 --- a/src/main/java/me/night0721/lilase/features/ah/AuctionHouse.java +++ b/src/main/java/me/night0721/lilase/features/ah/AuctionHouse.java @@ -1,7 +1,10 @@ package me.night0721.lilase.features.ah; +import me.night0721.lilase.features.flip.Flipper; +import me.night0721.lilase.features.flip.FlipperState; +import me.night0721.lilase.misc.DiscordWebhook; import me.night0721.lilase.utils.ConfigUtils; -import me.night0721.lilase.utils.DiscordWebhook; +import me.night0721.lilase.utils.InventoryUtils; import me.night0721.lilase.utils.PlayerUtils; import me.night0721.lilase.utils.Utils; import org.json.JSONArray; @@ -27,27 +30,23 @@ public class AuctionHouse { private static String uuid; private static String message_toSend; private static long lastAction; - private static Thread thread; - private Boolean open = false; - private static final DiscordWebhook webhook = new DiscordWebhook(ConfigUtils.getString("main", "Webhook")); - private final List items = new ArrayList<>(); - private final List temp_items = new ArrayList<>(); - private final List posted = new ArrayList<>(); + private static String name; + private static String bytedata; public static States clickState = States.NONE; + public static Flipper flipper; + private static final DiscordWebhook webhook = new DiscordWebhook(ConfigUtils.getString("main", "Webhook")); + + public Boolean open = false; + private final List items = new ArrayList<>(); + private final List posted = new ArrayList<>(); public AuctionHouse() { -// items.add(new Item("Livid Dagger", ItemType.WEAPON, 8000000, ItemTier.LEGENDARY)); -// items.add(new Item("Aspect of the Void", ItemType.WEAPON, 8000000, ItemTier.EPIC)); -// items.add(new Item("Bal", ItemType.MISC, 10000000, ItemTier.EPIC)); -// items.add(new Item(" ", ItemType.ANY, 1000, ItemTier.ANY)); - if (!ConfigUtils.getString("item1", "Name").equals("") && !ConfigUtils.getString("item1", "Type").equals("") && !ConfigUtils.getString("item1", "Tier").equals("") && ConfigUtils.getInt("item1", "Price") != 0) items.add(new Item(ConfigUtils.getString("item1", "Name"), ItemType.valueOf(ConfigUtils.getString("item1", "Type")), ConfigUtils.getInt("item1", "Price"), ItemTier.valueOf(ConfigUtils.getString("item1", "Tier")))); if (!ConfigUtils.getString("item2", "Name").equals("") && !ConfigUtils.getString("item2", "Type").equals("") && !ConfigUtils.getString("item2", "Tier").equals("") && ConfigUtils.getInt("item2", "Price") != 0) items.add(new Item(ConfigUtils.getString("item2", "Name"), ItemType.valueOf(ConfigUtils.getString("item2", "Type")), ConfigUtils.getInt("item2", "Price"), ItemTier.valueOf(ConfigUtils.getString("item2", "Tier")))); if (!ConfigUtils.getString("item3", "Name").equals("") && !ConfigUtils.getString("item3", "Type").equals("") && !ConfigUtils.getString("item3", "Tier").equals("") && ConfigUtils.getInt("item3", "Price") != 0) items.add(new Item(ConfigUtils.getString("item3", "Name"), ItemType.valueOf(ConfigUtils.getString("item3", "Type")), ConfigUtils.getInt("item3", "Price"), ItemTier.valueOf(ConfigUtils.getString("item3", "Tier")))); - webhook.setUsername("Lilase - Auction House"); webhook.setAvatarUrl("https://wallpapercave.com/wp/wp2412537.jpg"); } @@ -70,16 +69,26 @@ public class AuctionHouse { return new JSONObject(content.toString()); } - private void getItem() throws IOException, JSONException { - if (ConfigUtils.getString("main", "APIKey").equals("") || ConfigUtils.getString("main", "Webhook").equals("")) { - Utils.sendMessage("Missing APIKey or Webhook, stopping"); - toggleAuction(); + public void getItem() throws IOException, JSONException { + if (open == false) return; + if (!Utils.checkInHub()) { + Utils.sendMessage("Not in hub, stopping"); + open = false; return; } - if (items.size() == 0 && open == false) return; if (items.size() == 0) { Utils.sendMessage("No Item queued, stopping"); - toggleAuction(); + open = false; + return; + } + if (ConfigUtils.getString("main", "APIKey").equals("") || ConfigUtils.getString("main", "Webhook").equals("")) { + Utils.sendMessage("Missing APIKey or Webhook, stopping"); + open = false; + return; + } + if (Flipper.state != FlipperState.NONE) { + Utils.sendMessage("Flipper is running, stopping, will resume when flipper is done"); + open = false; return; } URL url = new URL("https://api.hypixel.net/skyblock/auctions"); @@ -98,7 +107,7 @@ public class AuctionHouse { } in.close(); connection.disconnect(); - + Utils.sendMessage("Getting item from auction house"); JSONObject data = new JSONObject(content.toString()); JSONArray auctions = data.getJSONArray("auctions"); for (int i = 0; i < auctions.length(); i++) { @@ -127,6 +136,7 @@ public class AuctionHouse { break; } + if (posted.contains(auction.getString("uuid"))) break; if (!auction.getString("item_name").toLowerCase().contains(item.query.toLowerCase())) break; if (!auction.getString("item_lore").contains(lore)) break; if (auction.getInt("starting_bid") > item.price) break; @@ -135,17 +145,28 @@ public class AuctionHouse { if (!auction.getBoolean("bin")) break; if (!posted.contains(auction.getString("uuid"))) { posted.add(auction.getString("uuid")); + flipper = new Flipper(auction.getString("item_name"), auction.getString("item_bytes"), auction.getInt("starting_bid")); NumberFormat format = NumberFormat.getInstance(Locale.US); JSONObject profile = getHypixelData(auction.getString("auctioneer")); + if (profile.getJSONObject("player").getString("displayname").toLowerCase() == PlayerUtils.mc.thePlayer.getName().toLowerCase()) break; Pattern pattern = Pattern.compile("§[0-9a-z]", Pattern.MULTILINE); Matcher matcher = pattern.matcher(auction.getString("item_lore")); String updated = matcher.replaceAll(""); webhook.addEmbed(new DiscordWebhook.EmbedObject().setTitle("Bought an item on low price").setUrl("https://sky.coflnet.com/auction/" + auction.getString("uuid")).setAuthor("night0721", "https://github.com/night0721", "https://avatars.githubusercontent.com/u/77528305?v=4").setDescription(updated.replace("\n", "\\n")).addField("Item", auction.getString("item_name"), true).addField("Price", format.format(auction.getInt("starting_bid")) + " coins", true).addField("Seller", profile.getJSONObject("player").getString("displayname"), true).addField("Started for", toDuration(System.currentTimeMillis() - auction.getLong("start")), true).addField("Ends in", getTimeSinceDate(auction.getLong("end") - System.currentTimeMillis()), true).setColor(Color.decode("#003153"))); webhook.setContent(auction.getString("item_name") + " is sale at " + format.format(auction.getInt("starting_bid")) + "! `" + "/viewauction " + auction.getString("uuid") + "`"); - uuid = auction.getString("uuid"); message_toSend = "Auction House: " + auction.getString("item_name") + " is sale for " + format.format(auction.getInt("starting_bid")) + "!"; - clickState = States.OPEN; + if (ConfigUtils.getBoolean("main", "checkMultiplierBeforeBuy")) { + float multi = flipper.checkMultiplier(); + Utils.debugLog("[Sniper] Found an item, checking profit multiplier"); + if (multi > ConfigUtils.getInt("main", "Multiplier")) { + Utils.debugLog("[Sniper] Higher than required multiplier, buying now"); + clickState = States.OPEN; + } + } else { + Utils.debugLog("[Sniper] Found an item, trying to buy"); + clickState = States.OPEN; + } return; } } @@ -157,8 +178,8 @@ public class AuctionHouse { Utils.sendMessage(message_toSend); } - public final List times = Arrays.asList(TimeUnit.DAYS.toMillis(365), TimeUnit.DAYS.toMillis(30), TimeUnit.DAYS.toMillis(1), TimeUnit.HOURS.toMillis(1), TimeUnit.MINUTES.toMillis(1), TimeUnit.SECONDS.toMillis(1)); - public final List timesString = Arrays.asList("year", "month", "day", "hour", "minute", "second"); + private final List times = Arrays.asList(TimeUnit.DAYS.toMillis(365), TimeUnit.DAYS.toMillis(30), TimeUnit.DAYS.toMillis(1), TimeUnit.HOURS.toMillis(1), TimeUnit.MINUTES.toMillis(1), TimeUnit.SECONDS.toMillis(1)); + private final List timesString = Arrays.asList("year", "month", "day", "hour", "minute", "second"); public String toDuration(long duration) { @@ -191,39 +212,26 @@ public class AuctionHouse { public void toggleAuction() { if (open) { Utils.sendMessage("Stopped Auction House"); - temp_items.addAll(items); - items.clear(); open = false; } else { if (Utils.checkInHub()) { Utils.sendMessage("Started Auction House"); - items.addAll(temp_items); - thread = new Thread(() -> { - while (true) { - try { - getItem(); - thread.sleep(TimeUnit.SECONDS.toMillis(ConfigUtils.getInt("main", "AuctionHouseDelay"))); - } catch (IOException | JSONException | InterruptedException ignore) { - } - } - }); - thread.start(); open = true; } else Utils.sendMessage("Detected not in hub, please go to hub to start"); } } - public static void switchStates() { + public static void switchStates() throws IOException { switch (clickState) { case CLICK: if (System.currentTimeMillis() - lastAction < 500) return; - PlayerUtils.mc.playerController.windowClick(PlayerUtils.mc.thePlayer.openContainer.windowId, 31, 0, 0, PlayerUtils.mc.thePlayer); + InventoryUtils.clickOpenContainerSlot(31); lastAction = System.currentTimeMillis(); clickState = States.CONFIRM; break; case CONFIRM: if (System.currentTimeMillis() - lastAction < 500) return; - PlayerUtils.mc.playerController.windowClick(PlayerUtils.mc.thePlayer.openContainer.windowId, 11, 0, 0, PlayerUtils.mc.thePlayer); + InventoryUtils.clickOpenContainerSlot(11); lastAction = System.currentTimeMillis(); clickState = States.NONE; break; @@ -233,13 +241,9 @@ public class AuctionHouse { clickState = States.CLICK; break; case EXECUTE: - new Thread(() -> { - try { - webhook.execute(); - } catch (IOException e) { - e.printStackTrace(); - } - }).start(); + Utils.debugLog("[Sniper] Bought an item, starting to sell"); + webhook.execute(); + flipper.sellItem(); clickState = States.NONE; break; case NONE: diff --git a/src/main/java/me/night0721/lilase/features/flip/Flipper.java b/src/main/java/me/night0721/lilase/features/flip/Flipper.java index a1edad6..8b8c657 100644 --- a/src/main/java/me/night0721/lilase/features/flip/Flipper.java +++ b/src/main/java/me/night0721/lilase/features/flip/Flipper.java @@ -1,42 +1,145 @@ package me.night0721.lilase.features.flip; -import org.json.JSONArray; +import me.night0721.lilase.Lilase; +import me.night0721.lilase.managers.KeyBindingManager; +import me.night0721.lilase.player.Rotation; +import me.night0721.lilase.utils.*; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityArmorStand; +import net.minecraft.util.StringUtils; import org.json.JSONObject; import javax.net.ssl.HttpsURLConnection; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.io.OutputStream; import java.net.URL; -import java.util.ArrayList; -import java.util.List; +import java.nio.charset.StandardCharsets; + public class Flipper { - public static List same_items = new ArrayList<>(); - private static String[] SWORD_REFORGE_NAMES = new String[]{"Epic", "Fair", "Fast", "Gentle", "Heroic", "Legendary", "Odd", "Sharp", "Spicy", "Strong", "Coldfused", "Dirty", "Fabled", "Glided", "Suspicious", "Warped", "Withered", "Bulky", "Jerry's"}; - private static String[] ARMOR_REFORGE_NAMES = new String[]{"Clean", "Fierce", "Heavy", "Light", "Mythic", "Pure", "Titanic", "Smart", "Wise", "Candied", "Submerged", "Perfect", "Reinforced", "Renowned", "Spiked", "Hyper", "Giant", "Jaded", "Cubic", "Necrotic", "Empowered", "Ancient", "Undead", "Loving", "Ridiculous"}; - private static String reforge; - public static void walkToAuctionHouse() { + private static String itemname = null; + private final String bytedata; + private final int itemprice; + public static FlipperState state = FlipperState.NONE; + public static final Rotation rotation = new Rotation(); + private static final Clock buyWait = new Clock(); + + public Flipper(String name, String data, int price) { + itemname = name; + bytedata = data; + itemprice = price; + } + + public int getItemPrice() throws IOException { + JSONObject item = getItemData(); + return (int) item.get("price"); + } + + public int checkMultiplier() throws IOException { + JSONObject item = getItemData(); + return (int) item.get("price") / itemprice * 100; + } + + public void sellItem() { + Utils.sendServerMessage("/hub"); + state = FlipperState.WALKING_TO_FIRST_POINT; + } + + public static void switchStates() { + switch (state) { + case WALKING_TO_FIRST_POINT: + if (PlayerUtils.mc.currentScreen != null) { + PlayerUtils.mc.thePlayer.closeScreen(); + } else if (distanceToFirstPoint() < 0.7f) { + Utils.debugLog("[Flipper] Moving to auction house"); + KeyBindingManager.updateKeys(false, false, false, false, false); + state = FlipperState.WALKING_INTO_AUCTION_HOUSE; + } else if (distanceToFirstPoint() < 5f) { + Utils.debugLog("[Flipper] Crouching to point 1"); + KeyBindingManager.updateKeys(true, false, false, false, false, true, false); + } else { + KeyBindingManager.updateKeys(true, false, false, false, false); + } + break; + case WALKING_INTO_AUCTION_HOUSE: + if (PlayerUtils.mc.currentScreen != null) { + PlayerUtils.mc.thePlayer.closeScreen(); + } else if (AngleUtils.smallestAngleDifference(AngleUtils.get360RotationYaw(), 88f) > 1.2) { + Utils.debugLog("[Flipper] Rotating to Auction Master"); + rotation.easeTo(88f, PlayerUtils.mc.thePlayer.rotationPitch, 500); + } else if (distanceToAuctionMaster() < 0.7f) { + Utils.debugLog("[Flipper] At Auction Master, opening shop"); + KeyBindingManager.updateKeys(false, false, false, false, false); + state = FlipperState.BUYING; + } else if (distanceToAuctionMaster() < 5f) { + Utils.debugLog("[Flipper] Crouching to Auction Master"); + KeyBindingManager.updateKeys(true, false, false, false, false, true, false); + } else { + KeyBindingManager.updateKeys(true, false, false, false, false); + } + break; + case BUYING: + if (PlayerUtils.mc.currentScreen == null && buyWait.passed()) { + final Entity auctionMaster = getAuctionMaster(); + if (auctionMaster == null) { + Utils.debugLog("[Flipper] Cannot find shop NPC, retrying"); + buyWait.schedule(500); + } else { + PlayerUtils.mc.playerController.interactWithEntitySendPacket(PlayerUtils.mc.thePlayer, auctionMaster); + buyWait.schedule(1500); + } + } else if (InventoryUtils.inventoryNameContains("Auction House") && buyWait.passed()) { + InventoryUtils.clickOpenContainerSlot(15); + buyWait.schedule(1500); + } else if (InventoryUtils.inventoryNameContains("Create BIN Auction")) { + if (InventoryUtils.isStoneButton() && buyWait.passed()) { + InventoryUtils.clickOpenContainerSlot(InventoryUtils.getSlotForItem(itemname)); + buyWait.schedule(1000); + } else if (!InventoryUtils.isStoneButton() && InventoryUtils.isToAuctionItem(itemname) && buyWait.passed()) { + InventoryUtils.clickOpenContainerSlot(31); + buyWait.schedule(1000); + state = FlipperState.START; + } else if (!InventoryUtils.isStoneButton() && !InventoryUtils.isToAuctionItem(itemname) && buyWait.passed()) { + InventoryUtils.clickOpenContainerSlot(13); + buyWait.schedule(1000); + } + } else if (InventoryUtils.inventoryNameContains("Manage Auction") && buyWait.passed()) { + InventoryUtils.clickOpenContainerSlot(24); + buyWait.schedule(1500); + } + case START: + if (!InventoryUtils.isStoneButton() && InventoryUtils.isToAuctionItem(itemname) && InventoryUtils.inventoryNameStartsWith("Create BIN Auction") && buyWait.passed()) { + InventoryUtils.clickOpenContainerSlot(29); + buyWait.schedule(1000); + } else if (InventoryUtils.inventoryNameContains("Confirm BIN Auction") && buyWait.passed()) { + InventoryUtils.clickOpenContainerSlot(11); + buyWait.schedule(1000); + } else if (InventoryUtils.inventoryNameContains("BIN Auction View") && buyWait.passed()) { + InventoryUtils.clickOpenContainerSlot(49); + PlayerUtils.mc.thePlayer.closeScreen(); + Utils.sendMessage("Posted item on Auction House, continue sniping now"); + state = FlipperState.NONE; + Lilase.auctionHouse.toggleAuction(); + } + case NONE: + break; + } } - public static void walkToBank() { - - } - - public static void sellItem() { - - } - - public static void calculateProfit(JSONObject item) throws IOException { - URL url = new URL("https://api.hypixel.net/skyblock/auctions"); + public JSONObject getItemData() throws IOException { + URL url = new URL("https://api.night0721.me/api/v1/skyblock"); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); - connection.setRequestProperty("Content-Type", "application/json"); - connection.setRequestMethod("GET"); - connection.setConnectTimeout(5000); - connection.setReadTimeout(5000); - int status = connection.getResponseCode(); - if (status != 200) return; + connection.addRequestProperty("Content-Type", "application/json"); + connection.addRequestProperty("User-Agent", "Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"); + connection.setDoOutput(true); + connection.setRequestMethod("POST"); + OutputStream stream = connection.getOutputStream(); + stream.write(("{\"ByteData\": \"" + bytedata + "\"}").getBytes(StandardCharsets.UTF_8)); + stream.flush(); + stream.close(); BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String inputLine; StringBuilder content = new StringBuilder(); @@ -45,44 +148,27 @@ public class Flipper { } in.close(); connection.disconnect(); - JSONObject data = new JSONObject(content.toString()); - JSONArray auctions = data.getJSONArray("auctions"); - for (int i = 0; i < auctions.length(); i++) { - JSONObject auction = auctions.getJSONObject(i); - if (auction.getString("item_name").contains(item.getString("name"))) { - same_items.add(auction); -// if (auction.getInt("starting_bid") < item.getInt("price")) { -// System.out.println("Profitable"); -// } + return new JSONObject(content.toString()); + } + + private static float distanceToFirstPoint() { + return (float) Math.sqrt(Math.pow(PlayerUtils.mc.thePlayer.posX - (-2.5), 2) + Math.pow(PlayerUtils.mc.thePlayer.posZ - (-91.5), 2)); + } + + private static float distanceToAuctionMaster() { + return (float) Math.sqrt(Math.pow(PlayerUtils.mc.thePlayer.posX - (-45), 2) + Math.pow(PlayerUtils.mc.thePlayer.posZ - (-90), 2)); + } + + private static Entity getAuctionMaster() { + for (final Entity e : PlayerUtils.mc.theWorld.loadedEntityList) { + if (e instanceof EntityArmorStand) { + final String name = StringUtils.stripControlCodes(e.getDisplayName().getUnformattedText()); + if (name.startsWith("Auction Master")) { + return e; + } } } - - // check reforge - switch (item.getString("type")) { - case "weapon": - for (String reforge_name : SWORD_REFORGE_NAMES) { - if (item.getString("name").contains(reforge_name)) { - for (JSONObject auction : same_items) { - if (auction.getString("item_name").split(" ")[0].equals(reforge_name)) { - reforge = reforge_name; - } - } - } - } - break; - case "armor": - for (String reforge_name : ARMOR_REFORGE_NAMES) { - if (item.getString("name").contains(reforge_name)) { - for (JSONObject auction : same_items) { - if (auction.getString("item_name").split(" ")[0].equals(reforge_name)) { - reforge = reforge_name; - } - } - } - } - break; - } - // check the median price on skyblock every 5 minutes, if it rise then put the item in median price - + return null; } } + diff --git a/src/main/java/me/night0721/lilase/features/flip/FlipperState.java b/src/main/java/me/night0721/lilase/features/flip/FlipperState.java new file mode 100644 index 0000000..6c69133 --- /dev/null +++ b/src/main/java/me/night0721/lilase/features/flip/FlipperState.java @@ -0,0 +1,5 @@ +package me.night0721.lilase.features.flip; + +public enum FlipperState { + WALKING_TO_FIRST_POINT, WALKING_INTO_AUCTION_HOUSE, BUYING, START, NONE +} diff --git a/src/main/java/me/night0721/lilase/managers/EventManager.java b/src/main/java/me/night0721/lilase/managers/EventManager.java deleted file mode 100644 index a9e403f..0000000 --- a/src/main/java/me/night0721/lilase/managers/EventManager.java +++ /dev/null @@ -1,35 +0,0 @@ -package me.night0721.lilase.managers; - -import me.night0721.lilase.features.ah.AuctionHouse; -import me.night0721.lilase.features.ah.States; -import me.night0721.lilase.utils.ConfigUtils; -import me.night0721.lilase.utils.PlayerUtils; -import me.night0721.lilase.utils.Utils; -import net.minecraftforge.client.event.ClientChatReceivedEvent; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; - -public class EventManager { - @SubscribeEvent - public void onChat(ClientChatReceivedEvent event) { - String message = event.message.getUnformattedText(); - if (!message.contains(":")) { - if (message.equals("You didn't participate in this auction!")) { - System.out.println("Failed to buy item, not fast enough. Closing the menu"); - PlayerUtils.mc.playerController.windowClick(PlayerUtils.mc.thePlayer.openContainer.windowId, 49, 0, 0, PlayerUtils.mc.thePlayer); // Close the window as could not buy - } else if (message.equals("You don't have enough coins to afford this bid!")) { - System.out.println("Failed to buy item, not enough money. Closing the menu"); - AuctionHouse.clickState = States.NONE; - PlayerUtils.mc.playerController.windowClick(PlayerUtils.mc.thePlayer.openContainer.windowId, 49, 0, 0, PlayerUtils.mc.thePlayer); // Close the window as could not buy - } else if (message.contains("Your new API key is")) { - System.out.println("Detected new API key, saving it to config"); - Utils.sendMessage("Saved new API key to config"); - String apiKey = message.replace("Your new API key is ", ""); - ConfigUtils.writeStringConfig("main", "APIKey", apiKey); - } else if (message.equals("Claiming BIN auction...")) { - AuctionHouse.clickState = States.EXECUTE; - } else if (message.equals("This BIN sale is still in its grace period!")) { - AuctionHouse.clickState = States.CLICK; - } - } - } -} diff --git a/src/main/java/me/night0721/lilase/managers/KeyBindingManager.java b/src/main/java/me/night0721/lilase/managers/KeyBindingManager.java index 12a250e..1afc55e 100644 --- a/src/main/java/me/night0721/lilase/managers/KeyBindingManager.java +++ b/src/main/java/me/night0721/lilase/managers/KeyBindingManager.java @@ -1,6 +1,8 @@ package me.night0721.lilase.managers; import me.night0721.lilase.Lilase; +import me.night0721.lilase.utils.PlayerUtils; +import me.night0721.lilase.utils.ReflectionUtils; import net.minecraft.client.settings.KeyBinding; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -46,4 +48,50 @@ public class KeyBindingManager { } } + public static void rightClick() { + if (!ReflectionUtils.invoke(PlayerUtils.mc, "func_147121_ag")) { + ReflectionUtils.invoke(PlayerUtils.mc, "rightClickMouse"); + } + } + + public static void leftClick() { + if (!ReflectionUtils.invoke(PlayerUtils.mc, "func_147116_af")) { + ReflectionUtils.invoke(PlayerUtils.mc, "clickMouse"); + } + } + + public static void middleClick() { + if (!ReflectionUtils.invoke(PlayerUtils.mc, "func_147112_ai")) { + ReflectionUtils.invoke(PlayerUtils.mc, "middleClickMouse"); + } + } + + public static void updateKeys(boolean forward, boolean back, boolean right, boolean left, boolean attack) { + updateKeys(forward, back, right, left, attack, false, false); + } + + public static void updateKeys(boolean forward, boolean back, boolean right, boolean left, boolean attack, boolean crouch, boolean space) { + if (PlayerUtils.mc.currentScreen != null) { + stopMovement(); + return; + } + KeyBinding.setKeyBindState(PlayerUtils.mc.gameSettings.keyBindForward.getKeyCode(), forward); + KeyBinding.setKeyBindState(PlayerUtils.mc.gameSettings.keyBindBack.getKeyCode(), back); + KeyBinding.setKeyBindState(PlayerUtils.mc.gameSettings.keyBindRight.getKeyCode(), right); + KeyBinding.setKeyBindState(PlayerUtils.mc.gameSettings.keyBindLeft.getKeyCode(), left); + KeyBinding.setKeyBindState(PlayerUtils.mc.gameSettings.keyBindAttack.getKeyCode(), attack); + KeyBinding.setKeyBindState(PlayerUtils.mc.gameSettings.keyBindSneak.getKeyCode(), crouch); + KeyBinding.setKeyBindState(PlayerUtils.mc.gameSettings.keyBindJump.getKeyCode(), space); + } + + public static void stopMovement() { + KeyBinding.setKeyBindState(PlayerUtils.mc.gameSettings.keyBindForward.getKeyCode(), false); + KeyBinding.setKeyBindState(PlayerUtils.mc.gameSettings.keyBindBack.getKeyCode(), false); + KeyBinding.setKeyBindState(PlayerUtils.mc.gameSettings.keyBindRight.getKeyCode(), false); + KeyBinding.setKeyBindState(PlayerUtils.mc.gameSettings.keyBindLeft.getKeyCode(), false); + KeyBinding.setKeyBindState(PlayerUtils.mc.gameSettings.keyBindAttack.getKeyCode(), false); + KeyBinding.setKeyBindState(PlayerUtils.mc.gameSettings.keyBindSneak.getKeyCode(), false); + KeyBinding.setKeyBindState(PlayerUtils.mc.gameSettings.keyBindJump.getKeyCode(), false); + } + } diff --git a/src/main/java/me/night0721/lilase/managers/SniperFlipperEvents.java b/src/main/java/me/night0721/lilase/managers/SniperFlipperEvents.java new file mode 100644 index 0000000..d682092 --- /dev/null +++ b/src/main/java/me/night0721/lilase/managers/SniperFlipperEvents.java @@ -0,0 +1,136 @@ +package me.night0721.lilase.managers; + +import me.night0721.lilase.Lilase; +import me.night0721.lilase.features.ah.AuctionHouse; +import me.night0721.lilase.features.ah.States; +import me.night0721.lilase.features.flip.Flipper; +import me.night0721.lilase.features.flip.FlipperState; +import me.night0721.lilase.utils.*; +import net.minecraft.init.Blocks; +import net.minecraftforge.client.event.ClientChatReceivedEvent; +import net.minecraftforge.client.event.RenderWorldLastEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.InputEvent; +import org.lwjgl.input.Keyboard; + +import static me.night0721.lilase.features.flip.Flipper.rotation; + +public class SniperFlipperEvents { + Thread bzchillingthread; + + @SubscribeEvent + public void onChat(ClientChatReceivedEvent event) throws InterruptedException { + String message = event.message.getUnformattedText(); + if (!message.contains(":")) { + if (message.equals("You didn't participate in this auction!")) { + Utils.debugLog("[Sniper] Failed to buy item, not fast enough. Closing the menu"); + PlayerUtils.mc.playerController.windowClick(PlayerUtils.mc.thePlayer.openContainer.windowId, 49, 0, 0, PlayerUtils.mc.thePlayer); // Close the window as could not buy + } else if (message.equals("You don't have enough coins to afford this bid!")) { + Utils.debugLog("[Sniper] Failed to buy item, not enough money. Closing the menu"); + AuctionHouse.clickState = States.NONE; + PlayerUtils.mc.playerController.windowClick(PlayerUtils.mc.thePlayer.openContainer.windowId, 49, 0, 0, PlayerUtils.mc.thePlayer); // Close the window as could not buy + } else if (message.contains("Your new API key is")) { + Utils.debugLog("[Sniper] Detected new API key, saving it to config"); + Utils.debugLog("[Sniper] Saved new API key to config"); + String apiKey = message.replace("Your new API key is ", ""); + ConfigUtils.writeStringConfig("main", "APIKey", apiKey); + } else if (message.equals("Claiming BIN auction...")) { + AuctionHouse.clickState = States.EXECUTE; + } else if (message.equals("This BIN sale is still in its grace period!")) { + AuctionHouse.clickState = States.CLICK; + } else if (message.equals("Your starting bid must be at least 10 coins!")) { + InventoryUtils.clickOpenContainerSlot(13); + PlayerUtils.mc.thePlayer.closeScreen(); + Utils.debugLog("[Flipper] Cannot post item as the cost is too low, stopping fliiper and starting sniper"); + Lilase.auctionHouse.toggleAuction(); + Flipper.state = FlipperState.NONE; + } else if (message.contains("Can't create a BIN auction for this item for a PRICE this LOW!")) { + PlayerUtils.mc.thePlayer.closeScreen(); + Utils.debugLog("[Flipper] Cannot post item as the cost is too low, stopping fliiper and starting sniper"); + Lilase.auctionHouse.toggleAuction(); + Flipper.state = FlipperState.NONE; + } else if (message.contains("You were spawned in Limbo")) { + Utils.sendMessage("Detected in Limbo, stopping everything for 5 minutes"); + Flipper.state = FlipperState.NONE; + AuctionHouse.clickState = States.NONE; + if (Lilase.auctionHouse.open) + Lilase.auctionHouse.toggleAuction(); + Thread.sleep(5000); + Utils.sendServerMessage("/hub"); + bzchillingthread = new Thread(bazaarChilling); + bzchillingthread.start(); + } + } + } + + Runnable bazaarChilling = () -> { + try { + rotation.reset(); + rotation.easeTo(103f, -11f, 1000); + Thread.sleep(1500); + KeyBindingManager.updateKeys(true, false, false, false, false, true, false); + long timeout = System.currentTimeMillis(); + boolean timedOut = false; + while (BlockUtils.getRelativeBlock(0, 0, 1) != Blocks.spruce_stairs) { + if ((System.currentTimeMillis() - timeout) > 10000) { + Utils.debugLog("[Sniper] Couldn't find bz, gonna chill here"); + timedOut = true; + break; + } + } + KeyBindingManager.stopMovement(); + + if (!timedOut) { + // about 5 minutes + for (int i = 0; i < 15; i++) { + Thread.sleep(6000); + KeyBindingManager.rightClick(); + Thread.sleep(3000); + InventoryUtils.clickOpenContainerSlot(11); + Thread.sleep(3000); + InventoryUtils.clickOpenContainerSlot(11); + Thread.sleep(3000); + InventoryUtils.clickOpenContainerSlot(10); + Thread.sleep(3000); + InventoryUtils.clickOpenContainerSlot(10); + Thread.sleep(3000); + PlayerUtils.mc.thePlayer.closeScreen(); + } + } else { + Thread.sleep(1000 * 60 * 5); + } + PlayerUtils.mc.thePlayer.sendChatMessage("/hub"); + Thread.sleep(6000); + Lilase.auctionHouse.toggleAuction(); + } catch (Exception ignore) { + } + + }; + + @SubscribeEvent + public void onLastRender(RenderWorldLastEvent event) { + if (rotation.rotating) { + rotation.update(); + } + } + + @SubscribeEvent + public void OnKeyPress(InputEvent.KeyInputEvent event) { + if (Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) { + if (Flipper.state != FlipperState.NONE) { + new Thread(() -> { + try { + Utils.debugLog("[Flipper] Interrupting Flipper selling"); + Thread.sleep(500); + PlayerUtils.mc.thePlayer.closeScreen(); + Flipper.state = FlipperState.NONE; + Lilase.auctionHouse.toggleAuction(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }).start(); + + } + } + } +} diff --git a/src/main/java/me/night0721/lilase/utils/DiscordWebhook.java b/src/main/java/me/night0721/lilase/misc/DiscordWebhook.java similarity index 99% rename from src/main/java/me/night0721/lilase/utils/DiscordWebhook.java rename to src/main/java/me/night0721/lilase/misc/DiscordWebhook.java index a05016b..381d8f6 100644 --- a/src/main/java/me/night0721/lilase/utils/DiscordWebhook.java +++ b/src/main/java/me/night0721/lilase/misc/DiscordWebhook.java @@ -1,4 +1,4 @@ -package me.night0721.lilase.utils; +package me.night0721.lilase.misc; import javax.net.ssl.HttpsURLConnection; import java.awt.*; diff --git a/src/main/java/me/night0721/lilase/player/Rotation.java b/src/main/java/me/night0721/lilase/player/Rotation.java new file mode 100644 index 0000000..fa7b5e1 --- /dev/null +++ b/src/main/java/me/night0721/lilase/player/Rotation.java @@ -0,0 +1,86 @@ +package me.night0721.lilase.player; + +import me.night0721.lilase.utils.AngleUtils; +import net.minecraft.client.Minecraft; +import org.apache.commons.lang3.tuple.MutablePair; + +public class Rotation { + private final static Minecraft mc = Minecraft.getMinecraft(); + public boolean rotating; + public boolean completed; + + private long startTime; + private long endTime; + + MutablePair start = new MutablePair<>(0f, 0f); + MutablePair target = new MutablePair<>(0f, 0f); + MutablePair difference = new MutablePair<>(0f, 0f); + + public void easeTo(float yaw, float pitch, long time) { + completed = false; + rotating = true; + startTime = System.currentTimeMillis(); + endTime = System.currentTimeMillis() + time; + start.setLeft(mc.thePlayer.rotationYaw); + start.setRight(mc.thePlayer.rotationPitch); + target.setLeft(AngleUtils.get360RotationYaw(yaw)); + target.setRight(pitch); + getDifference(); + } + + public void lockAngle(float yaw, float pitch) { + if (mc.thePlayer.rotationYaw != yaw || mc.thePlayer.rotationPitch != pitch && !rotating) + easeTo(yaw, pitch, 1000); + } + + public void update() { + if (System.currentTimeMillis() <= endTime) { + if (shouldRotateClockwise()) { + mc.thePlayer.rotationYaw = start.left + interpolate(difference.left); + } else { + mc.thePlayer.rotationYaw = start.left - interpolate(difference.left); + } + mc.thePlayer.rotationPitch = start.right + interpolate(difference.right); + } else if (!completed) { + if (shouldRotateClockwise()) { + System.out.println("Rotation final st - " + start.left + ", " + mc.thePlayer.rotationYaw); + mc.thePlayer.rotationYaw = target.left; + System.out.println("Rotation final - " + start.left + difference.left); + } else { + mc.thePlayer.rotationYaw = target.left; + System.out.println("Rotation final - " + (start.left - difference.left)); + } + mc.thePlayer.rotationPitch = start.right + difference.right; + completed = true; + rotating = false; + } + } + + private boolean shouldRotateClockwise() { + return AngleUtils.clockwiseDifference(AngleUtils.get360RotationYaw(start.left), target.left) < 180; + } + + public void reset() { + completed = false; + rotating = false; + } + + private void getDifference() { + difference.setLeft(AngleUtils.smallestAngleDifference(AngleUtils.get360RotationYaw(), target.left)); + difference.setRight(target.right - start.right); + } + + private float interpolate(float difference) { + final float spentMillis = System.currentTimeMillis() - startTime; + final float relativeProgress = spentMillis / (endTime - startTime); + return (difference) * easeOutSine(relativeProgress); + } + + private float easeOutCubic(double number) { + return (float) (1.0 - Math.pow(1.0 - number, 3.0)); + } + + private float easeOutSine(double number) { + return (float) Math.sin((number * Math.PI) / 2); + } +} \ No newline at end of file diff --git a/src/main/java/me/night0721/lilase/utils/AngleUtils.java b/src/main/java/me/night0721/lilase/utils/AngleUtils.java new file mode 100644 index 0000000..687a42e --- /dev/null +++ b/src/main/java/me/night0721/lilase/utils/AngleUtils.java @@ -0,0 +1,51 @@ +package me.night0721.lilase.utils; + +import net.minecraft.client.Minecraft; + +public class AngleUtils { + private static final Minecraft mc = Minecraft.getMinecraft(); + + public static float get360RotationYaw(float yaw) { + return (yaw % 360 + 360) % 360; + } + + public static float get360RotationYaw() { + return get360RotationYaw(mc.thePlayer.rotationYaw); + } + + public static float clockwiseDifference(float initialYaw360, float targetYaw360) { + return get360RotationYaw(targetYaw360 - initialYaw360); + } + + public static float antiClockwiseDifference(float initialYaw360, float targetYaw360) { + return get360RotationYaw(initialYaw360 - targetYaw360); + } + + public static float smallestAngleDifference(float initialYaw360, float targetYaw360) { + return Math.min(clockwiseDifference(initialYaw360, targetYaw360), antiClockwiseDifference(initialYaw360, targetYaw360)); + } + + public static float getClosest() { + if (get360RotationYaw() < 45 || get360RotationYaw() > 315) { + return 0f; + } else if (get360RotationYaw() < 135) { + return 90f; + } else if (get360RotationYaw() < 225) { + return 180f; + } else { + return 270f; + } + } + + public static float getClosest(float yaw) { + if (yaw < 45 || yaw > 315) { + return 0f; + } else if (yaw < 135) { + return 90f; + } else if (yaw < 225) { + return 180f; + } else { + return 270f; + } + } +} \ No newline at end of file diff --git a/src/main/java/me/night0721/lilase/utils/BlockUtils.java b/src/main/java/me/night0721/lilase/utils/BlockUtils.java new file mode 100644 index 0000000..310cf17 --- /dev/null +++ b/src/main/java/me/night0721/lilase/utils/BlockUtils.java @@ -0,0 +1,108 @@ +package me.night0721.lilase.utils; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockCarpet; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.init.Blocks; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.BlockPos; +import net.minecraft.util.Vec3i; + +import java.util.Arrays; + +public class BlockUtils { + private static final Minecraft mc = Minecraft.getMinecraft(); + private static final Block[] walkables = { Blocks.air, Blocks.water, Blocks.flowing_water, Blocks.dark_oak_fence_gate, Blocks.acacia_fence_gate, Blocks.birch_fence_gate, Blocks.oak_fence_gate, Blocks.jungle_fence_gate, Blocks.spruce_fence_gate, Blocks.wall_sign, Blocks.reeds }; + + public static int getUnitX() { + double modYaw = (mc.thePlayer.rotationYaw % 360 + 360) % 360; + if (modYaw < 45 || modYaw > 315) { + return 0; + } else if (modYaw < 135) { + return -1; + } else if (modYaw < 225) { + return 0; + } else { + return 1; + } + } + + public static int getUnitZ() { + double modYaw = (mc.thePlayer.rotationYaw % 360 + 360) % 360; + if (modYaw < 45 || modYaw > 315) { + return 1; + } else if (modYaw < 135) { + return 0; + } else if (modYaw < 225) { + return -1; + } else { + return 0; + } + } + + public static Block getRelativeBlock(float x, float y, float z) { + return (mc.theWorld.getBlockState( + new BlockPos( + mc.thePlayer.posX + (getUnitX() * z) + (getUnitZ() * -1 * x), + mc.thePlayer.posY + y, + mc.thePlayer.posZ + (getUnitZ() * z) + (getUnitX() * x) + )).getBlock()); + } + public static BlockPos getRelativeBlockPos(float x, float y, float z) { + return new BlockPos( + mc.thePlayer.posX + (getUnitX() * z) + (getUnitZ() * -1 * x), + mc.thePlayer.posY + y, + mc.thePlayer.posZ + (getUnitZ() * z) + (getUnitX() * x) + ); + } + + public static int countCarpet() { + int r = 2; + int count = 0; + BlockPos playerPos = mc.thePlayer.getPosition(); + playerPos.add(0, 1, 0); + Vec3i vec3i = new Vec3i(r, r, r); + Vec3i vec3i2 = new Vec3i(r, r, r); + for (BlockPos blockPos : BlockPos.getAllInBox(playerPos.add(vec3i), playerPos.subtract(vec3i2))) { + IBlockState blockState = mc.theWorld.getBlockState(blockPos); + if (blockState.getBlock() == Blocks.carpet && blockState.getValue(BlockCarpet.COLOR) == EnumDyeColor.BROWN) { + System.out.println("Carpet color: " + blockState.getValue(BlockCarpet.COLOR)); + count++; + } + } + return count; + } + + public static int bedrockCount() { + int r = 4; + int count = 0; + BlockPos playerPos = Minecraft.getMinecraft().thePlayer.getPosition(); + playerPos.add(0, 1, 0); + Vec3i vec3i = new Vec3i(r, r, r); + Vec3i vec3i2 = new Vec3i(r, r, r); + for (BlockPos blockPos : BlockPos.getAllInBox(playerPos.add(vec3i), playerPos.subtract(vec3i2))) { + IBlockState blockState = Minecraft.getMinecraft().theWorld.getBlockState(blockPos); + if (blockState.getBlock() == Blocks.bedrock) { + count++; + } + } + return count; + } + public static Block getLeftBlock(){ + return getRelativeBlock(-1, 0, 0); + } + public static Block getRightBlock(){ + return getRelativeBlock(1, 0, 0); + } + public static Block getBackBlock(){ + return getRelativeBlock(0, 0, -1); + } + public static Block getFrontBlock(){ + return getRelativeBlock(0, 0, 1); + } + + public static boolean isWalkable(Block block) { + return Arrays.asList(walkables).contains(block); + } +} \ No newline at end of file diff --git a/src/main/java/me/night0721/lilase/utils/Clock.java b/src/main/java/me/night0721/lilase/utils/Clock.java new file mode 100644 index 0000000..704ec03 --- /dev/null +++ b/src/main/java/me/night0721/lilase/utils/Clock.java @@ -0,0 +1,31 @@ +package me.night0721.lilase.utils; + +public class Clock { + private long endTime; + private boolean scheduled; + + public void schedule(long milliseconds) { + this.endTime = System.currentTimeMillis() + milliseconds; + scheduled = true; + } + + public long getRemainingTime() { + return endTime - System.currentTimeMillis(); + } + + public long getEndTime() { + return endTime; + } + + public boolean passed() { + return System.currentTimeMillis() >= endTime; + } + + public boolean isScheduled() { + return scheduled; + } + + public void reset() { + scheduled = false; + } +} \ No newline at end of file diff --git a/src/main/java/me/night0721/lilase/utils/ConfigUtils.java b/src/main/java/me/night0721/lilase/utils/ConfigUtils.java index 47c220d..69a169c 100644 --- a/src/main/java/me/night0721/lilase/utils/ConfigUtils.java +++ b/src/main/java/me/night0721/lilase/utils/ConfigUtils.java @@ -15,24 +15,17 @@ public class ConfigUtils { } public static void checkWebhookAndAPI() { - new Thread(() -> { - while (true) { - try { - Thread.sleep(120000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - if (getString("main", "APIKey").equals("") || getString("main", "Webhook").equals("")) { - Utils.sendMessage("API Key or Webhook is not set, please set it in the menu (Press *)"); - } - } - }).start(); + if (getString("main", "APIKey").equals("") || getString("main", "Webhook").equals("")) { + Utils.sendMessage("API Key or Webhook is not set, please set it in the menu (Press *)"); + } } public static void reloadConfig() { if (!hasKey("main", "APIKey")) writeStringConfig("main", "APIKey", ""); if (!hasKey("main", "Webhook")) writeStringConfig("main", "Webhook", ""); if (!hasKey("main", "AuctionHouseDelay")) writeIntConfig("main", "AuctionHouseDelay", 8); + if (!hasKey("main", "checkMultiplierBeforeBuy")) writeBooleanConfig("main", "checkMultiplierBeforeBuy", false); + if (!hasKey("main", "Multiplier")) writeIntConfig("main", "Multiplier", 400); //400% if (!hasKey("item1", "Name")) writeStringConfig("item1", "Name", ""); if (!hasKey("item1", "Type")) writeStringConfig("item1", "Type", ""); if (!hasKey("item1", "Price")) writeIntConfig("item1", "Price", 0); diff --git a/src/main/java/me/night0721/lilase/utils/InventoryUtils.java b/src/main/java/me/night0721/lilase/utils/InventoryUtils.java new file mode 100644 index 0000000..3d10559 --- /dev/null +++ b/src/main/java/me/night0721/lilase/utils/InventoryUtils.java @@ -0,0 +1,206 @@ +package me.night0721.lilase.utils; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.inventory.GuiChest; +import net.minecraft.client.gui.inventory.GuiInventory; +import net.minecraft.inventory.ContainerChest; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class InventoryUtils { + static int opened = 0; + /* + * @Author Mostly Apfelsaft + */ + private static final Minecraft mc = Minecraft.getMinecraft(); + + + public static boolean isToAuctionItem(String name) { + final ItemStack stack = mc.thePlayer.openContainer.getSlot(13).getStack(); + if (stack != null && stack.hasTagCompound()) { + final NBTTagCompound tag = stack.getTagCompound(); + final Pattern pattern = Pattern.compile(name, Pattern.MULTILINE); + final Matcher matcher = pattern.matcher(tag.toString()); + while (matcher.find()) { + if (matcher.group(0) != null) { + return true; + } + } + } + return false; + } + + public static boolean isStoneButton() { + final ItemStack stack = mc.thePlayer.openContainer.getSlot(13).getStack(); + if (stack != null && stack.hasTagCompound()) { + final NBTTagCompound tag = stack.getTagCompound(); + final Pattern pattern = Pattern.compile("Click an item in your inventory!", Pattern.MULTILINE); + final Matcher matcher = pattern.matcher(tag.toString()); + while (matcher.find()) { + if (matcher.group(0) != null) { + return true; + } + } + } + return false; + } + + public static String getInventoryName() { + if (InventoryUtils.mc.currentScreen instanceof GuiChest) { + final ContainerChest chest = (ContainerChest) InventoryUtils.mc.thePlayer.openContainer; + final IInventory inv = chest.getLowerChestInventory(); + return inv.hasCustomName() ? inv.getName() : null; + } + return null; + } + + public static boolean inventoryNameStartsWith(String startsWithString) { + return InventoryUtils.getInventoryName() != null && InventoryUtils.getInventoryName().startsWith(startsWithString); + } + + public static boolean inventoryNameContains(String startsWithString) { + return InventoryUtils.getInventoryName() != null && InventoryUtils.getInventoryName().contains(startsWithString); + } + + public static void openInventory() { + mc.displayGuiScreen(new GuiInventory(mc.thePlayer)); + } + + public static ItemStack getStackInSlot(final int slot) { + return InventoryUtils.mc.thePlayer.inventory.getStackInSlot(slot); + } + + public static ItemStack getStackInOpenContainerSlot(final int slot) { + if (InventoryUtils.mc.thePlayer.openContainer.inventorySlots.get(slot).getHasStack()) { + return InventoryUtils.mc.thePlayer.openContainer.inventorySlots.get(slot).getStack(); + } + return null; + } + + public static int getSlotForItem(final String itemName) { + for (final Slot slot : mc.thePlayer.openContainer.inventorySlots) { + if (slot.getHasStack()) { + final ItemStack is = slot.getStack(); + if (is.getDisplayName().contains(itemName)) { + return slot.slotNumber; + } + } + } + return -1; + } + + public static void clickOpenContainerSlot(final int slot, final int button, final int clickType) { + mc.playerController.windowClick(mc.thePlayer.openContainer.windowId, slot, button, clickType, mc.thePlayer); + } + + public static void clickOpenContainerSlot(final int slot, final int button) { + clickOpenContainerSlot(slot, button, 0); + } + + public static void clickOpenContainerSlot(final int slot) { + clickOpenContainerSlot(slot, 0, 0); + } + + + public static int getAvailableHotbarSlot(final String name) { + for (int i = 0; i < 8; ++i) { + final ItemStack is = mc.thePlayer.inventory.getStackInSlot(i); + if (is == null || is.getDisplayName().contains(name)) { + return i; + } + } + return -1; + } + + public static List getAllSlots(final String name) { + final List ret = new ArrayList<>(); + for (int i = 9; i < 44; ++i) { + final ItemStack is = mc.thePlayer.inventoryContainer.inventorySlots.get(i).getStack(); + if (is != null && is.getDisplayName().contains(name)) { + ret.add(i); + } + } + return ret; + } + + public static int getAmountInHotbar(final String item) { + for (int i = 0; i < 8; ++i) { + final ItemStack is = InventoryUtils.mc.thePlayer.inventory.getStackInSlot(i); + if (is != null && StringUtils.stripControlCodes(is.getDisplayName()).equals(item)) { + return is.stackSize; + } + } + return 0; + } + + public static int getItemInHotbar(final String itemName) { + for (int i = 0; i < 8; ++i) { + final ItemStack is = InventoryUtils.mc.thePlayer.inventory.getStackInSlot(i); + if (is != null && StringUtils.stripControlCodes(is.getDisplayName()).contains(itemName)) { + return i; + } + } + return -1; + } + + public static List getInventoryStacks() { + final List ret = new ArrayList(); + for (int i = 9; i < 44; ++i) { + final Slot slot = InventoryUtils.mc.thePlayer.inventoryContainer.getSlot(i); + if (slot != null) { + final ItemStack stack = slot.getStack(); + if (stack != null) { + ret.add(stack); + } + } + } + return ret; + } + + public static List getInventorySlots() { + final List ret = new ArrayList<>(); + for (int i = 9; i < 44; ++i) { + final Slot slot = InventoryUtils.mc.thePlayer.inventoryContainer.getSlot(i); + if (slot != null) { + final ItemStack stack = slot.getStack(); + if (stack != null) { + ret.add(slot); + } + } + } + return ret; + } + + + public static NBTTagCompound getExtraAttributes(ItemStack item) { + if (item == null) { + throw new NullPointerException("The item cannot be null!"); + } + if (!item.hasTagCompound()) { + return null; + } + + return item.getSubCompound("ExtraAttributes", false); + } + + public static NBTTagList getLore(ItemStack item) { + if (item == null) { + throw new NullPointerException("The item cannot be null!"); + } + if (!item.hasTagCompound()) { + return null; + } + + return item.getSubCompound("display", false).getTagList("Lore", 8); + } +} \ No newline at end of file diff --git a/src/main/java/me/night0721/lilase/utils/ReflectionUtils.java b/src/main/java/me/night0721/lilase/utils/ReflectionUtils.java new file mode 100644 index 0000000..a81a20a --- /dev/null +++ b/src/main/java/me/night0721/lilase/utils/ReflectionUtils.java @@ -0,0 +1,29 @@ +package me.night0721.lilase.utils; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +public class ReflectionUtils { + + public static boolean invoke(Object object, String methodName) { + try { + final Method method = object.getClass().getDeclaredMethod(methodName); + method.setAccessible(true); + method.invoke(object); + return true; + } catch (Exception ignored) { + } + return false; + } + + public static Object field(Object object, String name) { + try { + Field field = object.getClass().getDeclaredField(name); + field.setAccessible(true); + return field.get(object); + } catch (Exception ignored) { + } + return null; + } + +} \ No newline at end of file diff --git a/src/main/java/me/night0721/lilase/utils/Utils.java b/src/main/java/me/night0721/lilase/utils/Utils.java index dcb29cb..00101d7 100644 --- a/src/main/java/me/night0721/lilase/utils/Utils.java +++ b/src/main/java/me/night0721/lilase/utils/Utils.java @@ -9,7 +9,7 @@ import java.util.List; public class Utils { public static boolean inDungeon; - public static boolean inHub; + public static boolean inHub = false; public static String translateAlternateColorCodes(String text) { char[] b = text.toCharArray(); @@ -55,6 +55,10 @@ public class Utils { PlayerUtils.mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.LIGHT_PURPLE + "" + EnumChatFormatting.BOLD + "Liliase" + EnumChatFormatting.RESET + EnumChatFormatting.DARK_GRAY + " » " + EnumChatFormatting.RESET + EnumChatFormatting.GREEN + EnumChatFormatting.BOLD + message)); } + public static void debugLog(String message) { + PlayerUtils.mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.LIGHT_PURPLE + "" + "Liliase" + EnumChatFormatting.RESET + EnumChatFormatting.DARK_GRAY + " » " + EnumChatFormatting.RESET + EnumChatFormatting.WHITE + message)); + } + public static void sendServerMessage(String message) { PlayerUtils.mc.thePlayer.sendChatMessage(message); }