diff --git a/README.md b/README.md index 1133bc6..1f01016 100644 --- a/README.md +++ b/README.md @@ -40,17 +40,24 @@ ANY, WEAPON, ARMOR, ACCESSORIES, CONSUMABLES, BLOCKS, MISC - v1.0.2 - Added flipper, profit check, auto post - v1.0.21 - Auto reconnect to server when disconnected - ungrab mouse when sniping/flipping - auto skip confirmation screen, with GUI showing coord fps and time and more error catching - however config still broken, keep using Lilase.cfg first. Will fix config and discord in next update - some movement during sniping so hypixel won't send to afk + Ungrab mouse when sniping/flipping + Auto skip confirmation screen, with GUI showing coord fps and time and more error catching + However config still broken, keep using Lilase.cfg first. Will fix config and discord in next update + Some movement during sniping so hypixel won't send to afk - v1.0.22 - Fatal bug fixed (before it will crash when open controls gui), also added title for process - v1.0.23 - More lines in GUI, flipped, posted, sniped - v1.0.24 - - remove the use of org.json dependency - fixing flipper could not be started when item is sniped - making send auction to be toggleable - added blacklist for sniping + Remove the use of org.json dependency + Fixing flipper could not be started when item is sniped + Making send auction to webhook to be toggleable + Added blacklist for sniping + Changing API URL to a more stable one + Have at most 99 items to snipe at the same time, with 99 items to blacklist too + Mod will now only generate first three items config in the file, but you can add yourself + Fetching price of item earlier so it won't be bugged when posting on auctio house + Fix the weird lag when doing random motion when sniping + Changed names in config so it is more readable and understanable + Added days in GUI # To Do Features: - Console client?? diff --git a/src/main/java/me/night0721/lilase/events/SniperFlipperEvents.java b/src/main/java/me/night0721/lilase/events/SniperFlipperEvents.java index c5af07a..724611d 100644 --- a/src/main/java/me/night0721/lilase/events/SniperFlipperEvents.java +++ b/src/main/java/me/night0721/lilase/events/SniperFlipperEvents.java @@ -23,7 +23,6 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.InputEvent; import org.lwjgl.input.Keyboard; -import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; import java.util.List; @@ -32,6 +31,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import static me.night0721.lilase.features.ah.AHConfig.GUI_COLOR; +import static me.night0721.lilase.features.ah.AHConfig.SEND_MESSAGE; import static me.night0721.lilase.features.ah.AuctionHouse.flipper; import static me.night0721.lilase.features.flip.Flipper.rotation; import static me.night0721.lilase.features.flip.FlipperState.START; @@ -39,14 +39,22 @@ import static me.night0721.lilase.utils.PlayerUtils.sendPacketWithoutEvent; public class SniperFlipperEvents { private int windowId = 1; + private int price; private boolean buying = false; private boolean bought = false; - private final Pattern boughtPattern = Pattern.compile("^(.*?) bought (.*?) for ([\\d,]+) coins CLICK$"); + private final Pattern auctionSoldPattern = Pattern.compile("^(.*?) bought (.*?) for ([\\d,]+) coins CLICK$"); + private final Pattern boughtPattern = Pattern.compile("You purchased (\\w+(?:\\s+\\w+)*) for ([\\d,]+)\\s*(\\w+)!"); + private final Pattern boughtPattern2 = Pattern.compile("You claimed (.+?) from (.+?)'s auction!"); + private final Pattern boughtPattern3 = Pattern.compile("You (purchased|claimed)( (\\\\d+x))? ([^\\\\s]+(\\\\s+[^\\\\d,]+)*)((,| for) (\\\\d+,?)+ coins?(!)?)?"); public static List postedNames = new ArrayList<>(); + @SubscribeEvent - public void onChat(ClientChatReceivedEvent event) throws InterruptedException, IOException { + public void onChat(ClientChatReceivedEvent event) throws InterruptedException { String message = event.message.getUnformattedText(); - Matcher matcher = boughtPattern.matcher(message); + Matcher matcher = auctionSoldPattern.matcher(message); + Matcher boughtMatcher = boughtPattern.matcher(message); + Matcher boughtMatcher2 = boughtPattern2.matcher(message); + Matcher boughtMatcher3 = boughtPattern3.matcher(message); 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"); @@ -59,10 +67,23 @@ public class SniperFlipperEvents { 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...") && bought) { - Utils.debugLog("[Sniper] Bought an item, starting to sell"); - Lilase.auctionHouse.webhook.execute(); - flipper.sellItem(); + } else if ((boughtMatcher.matches() || boughtMatcher2.matches() || boughtMatcher3.matches()) && bought) { + new Thread(() -> { + bought = false; + Utils.debugLog("[Sniper] Bought an item, starting to sell"); + try { + if (SEND_MESSAGE) Lilase.auctionHouse.webhook.execute(); + } catch (Exception e) { + System.out.println("Failed to send webhook"); + } + price = flipper.getItemPrice(); + try { + Thread.sleep(1500); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + flipper.sellItem(); + }).start(); } else if (message.equals("Your starting bid must be at least 10 coins!")) { InventoryUtils.clickOpenContainerSlot(13); Lilase.mc.thePlayer.closeScreen(); @@ -76,10 +97,13 @@ public class SniperFlipperEvents { Flipper.state = FlipperState.NONE; } else if (message.contains("You were spawned in Limbo")) { Utils.sendMessage("Detected in Limbo, stopping everything for 5 minutes"); + Utils.addTitle("You got sent to Limbo!"); Flipper.state = FlipperState.NONE; if (Lilase.auctionHouse.getOpen()) Lilase.auctionHouse.toggleAuction(); Thread.sleep(5000); - Utils.sendServerMessage("/hub"); + Utils.sendServerMessage("/lobby"); + Thread.sleep(5000); + Utils.sendServerMessage("/skyblock"); Thread bzchillingthread = new Thread(bazaarChilling); bzchillingthread.start(); } else if (matcher.matches() && postedNames.contains(matcher.group(2))) { @@ -168,15 +192,9 @@ public class SniperFlipperEvents { int hour = cal.get(Calendar.HOUR_OF_DAY); int minute = cal.get(Calendar.MINUTE); String time = String.format("%02d:%02d", hour, minute); - String lines = "X: " + Math.round(Lilase.mc.thePlayer.posX) + "\n" + - "Y: " + Math.round(Lilase.mc.thePlayer.posY) + "\n" + - "Z: " + Math.round(Lilase.mc.thePlayer.posZ) + "\n" + - time + "\n" + - "FPS: " + Minecraft.getDebugFPS() + "\n" + - "Auctions Sniped: " + Lilase.auctionHouse.getAuctionsSniped() + "\n" + - "Auctions Posted: " + Lilase.auctionHouse.getAuctionsPosted() + "\n" + - "Auctions Flipped: " + Lilase.auctionHouse.getAuctionsFlipped() + "\n"; - TextRenderer.drawString(lines, 0, 0, 1.5, GUI_COLOR.getRGB()); + int days = (int) (Lilase.mc.theWorld.getWorldTime() / 24000); + String lines = "X: " + Math.round(Lilase.mc.thePlayer.posX) + "\n" + "Y: " + Math.round(Lilase.mc.thePlayer.posY) + "\n" + "Z: " + Math.round(Lilase.mc.thePlayer.posZ) + "\n" + time + "\n" + "FPS: " + Minecraft.getDebugFPS() + "\n" + "Day: " + days + "\n" + "Auctions Sniped: " + Lilase.auctionHouse.getAuctionsSniped() + "\n" + "Auctions Posted: " + Lilase.auctionHouse.getAuctionsPosted() + "\n" + "Auctions Flipped: " + Lilase.auctionHouse.getAuctionsFlipped() + "\n"; + TextRenderer.drawString(lines, 0, 0, 0.9, GUI_COLOR.getRGB()); } } } @@ -199,11 +217,12 @@ public class SniperFlipperEvents { if (buying && "Confirm Purchase".equals(windowName)) { Lilase.mc.playerController.windowClick(windowId + 1, 11, 0, 0, Lilase.mc.thePlayer); buying = false; - bought = true; + if (Lilase.auctionHouse.buying) bought = true; } } } + @SubscribeEvent public void onPacketReceive(PacketReceivedEvent event) { if (event.packet instanceof S33PacketUpdateSign && Utils.checkInHub() && Flipper.state.equals(START)) { @@ -211,15 +230,14 @@ public class SniperFlipperEvents { try { S33PacketUpdateSign packetUpdateSign = (S33PacketUpdateSign) event.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); + Utils.debugLog("[Flipper] Item price should be " + price); + Thread.sleep(300); + lines[0] = IChatComponent.Serializer.jsonToComponent("{\"text\":\"" + price + "\"}"); C12PacketUpdateSign packetUpdateSign1 = new C12PacketUpdateSign(packetUpdateSign.getPos(), lines); sendPacketWithoutEvent(packetUpdateSign1); - } catch (IOException | InterruptedException | RuntimeException e) { + } catch (RuntimeException | InterruptedException e) { e.printStackTrace(); } - }).start(); } diff --git a/src/main/java/me/night0721/lilase/features/ah/AHConfig.java b/src/main/java/me/night0721/lilase/features/ah/AHConfig.java index ad49cd1..f9e2d78 100644 --- a/src/main/java/me/night0721/lilase/features/ah/AHConfig.java +++ b/src/main/java/me/night0721/lilase/features/ah/AHConfig.java @@ -13,11 +13,12 @@ public class AHConfig extends Config { public AHConfig() { super(new Mod("Lilase", ModType.UTIL_QOL), "lilase.json"); initialize(); + addListener("SEND_MESSAGE", () -> ConfigUtils.writeBooleanConfig("main", "SendMessageToWebhook", AHConfig.SEND_MESSAGE)); addListener("WEBHOOK", () -> ConfigUtils.writeStringConfig("main", "Webhook", AHConfig.WEBHOOK)); addListener("RECONNECT_DELAY", () -> ConfigUtils.writeIntConfig("main", "ReconnectDelay", Math.round(AHConfig.RECONNECT_DELAY))); addListener("AUCTION_HOUSE_DELAY", () -> ConfigUtils.writeIntConfig("main", "AuctionHouseDelay", Math.round(AHConfig.AUCTION_HOUSE_DELAY))); - addListener("CHECK_MULTIPLIER", () -> ConfigUtils.writeBooleanConfig("main", "checkMultiplierBeforeBuy", AHConfig.CHECK_MULTIPLIER)); - addListener("MULTIPLIER", () -> ConfigUtils.writeIntConfig("main", "MULTIPLIER", Math.round(AHConfig.MULTIPLIER))); + addListener("CHECK_PERCENTAGE", () -> ConfigUtils.writeBooleanConfig("main", "checkProfitPercentageBeforeBuy", AHConfig.CHECK_PERCENTAGE)); + addListener("PROFIT_PERCENTAGE", () -> ConfigUtils.writeIntConfig("main", "ProfitPercentage", Math.round(AHConfig.PROFIT_PERCENTAGE))); addListener("GUI", () -> ConfigUtils.writeBooleanConfig("main", "GUI", AHConfig.GUI)); addListener("GUI_COLOR", () -> ConfigUtils.writeIntConfig("main", "GUI_COLOR", AHConfig.GUI_COLOR.getRGB())); addListener("ITEM_1_NAME", () -> ConfigUtils.writeStringConfig("item1", "Name", AHConfig.ITEM_1_NAME)); @@ -60,7 +61,8 @@ public class AHConfig extends Config { addListener("ITEM_10_TYPE", () -> ConfigUtils.writeStringConfig("item10", "Type", AHConfig.ITEM_10_TYPE)); addListener("ITEM_10_PRICE", () -> ConfigUtils.writeIntConfig("item10", "Price", Math.round(AHConfig.ITEM_10_PRICE))); addListener("ITEM_10_TIER", () -> ConfigUtils.writeStringConfig("item10", "Tier", AHConfig.ITEM_10_TIER)); - addDependency("MULTIPLIER", "CHECK_MULTIPLIER"); + addDependency("WEBHOOK", "SEND_MESSAGE"); + addDependency("PROFIT_PERCENTAGE", "CHECK_PERCENTAGE"); addDependency("GUI_COLOR", "GUI"); addDependency("ITEM_1_NAME", "addItem", () -> ConfigUtils.getString("item1", "Name").equals("")); addDependency("ITEM_1_TYPE", "addItem", () -> ConfigUtils.getString("item1", "Type").equals("")); @@ -110,14 +112,17 @@ public class AHConfig extends Config { @Text(name = "Discord Webhook", placeholder = "URL", category = "Auction House", description = "Discord webhook to send messages to") public static String WEBHOOK = ""; + @Switch(name = "Send message to webhook", category = "Auction House", description = "Send a message to the webhook when an item is bought") + public static boolean SEND_MESSAGE = true; + @Number(name = "Reconnect Delay", min = 5, max = 20, category = "Auction House", description = "Delay between each reconnect attempt to the server") public static int RECONNECT_DELAY = 20; - @Switch(name = "Check Multiplier Before Buying", category = "Flipper", description = "Check the multiplier before buying the item, if the multiplier is too low, it will not buy the item") - public static boolean CHECK_MULTIPLIER = false; + @Switch(name = "Check Profit Percentage Before Buying", category = "Flipper", description = "Check the profit percentage before buying the item, if the profit percentage is too low, it will not buy the item") + public static boolean CHECK_PERCENTAGE = false; - @Number(name = "Multiplier", min = 100, max = 5000, step = 50, category = "Flipper", description = "Multiplier to check before buying the item, if the multiplier is too low, it will not buy the item") - public static int MULTIPLIER = 400; + @Number(name = "ProfitPercentage", min = 100, max = 5000, step = 50, category = "Flipper", description = "Profit percentage to check before buying the item, if the profit percentage is too low, it will not buy the item") + public static int PROFIT_PERCENTAGE = 400; @Switch(name = "Bed Spam & Skip Confirm", category = "Auction House", description = "Spam the bed to buy the item just after the grace period ends and skips the confirmation of buying the item") public static boolean BED_SPAM = true; 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 1c8b8b5..5928008 100644 --- a/src/main/java/me/night0721/lilase/features/ah/AuctionHouse.java +++ b/src/main/java/me/night0721/lilase/features/ah/AuctionHouse.java @@ -1,14 +1,15 @@ package me.night0721.lilase.features.ah; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import me.night0721.lilase.Lilase; import me.night0721.lilase.features.flip.Flipper; +import me.night0721.lilase.features.flip.FlipperState; import me.night0721.lilase.utils.ConfigUtils; import me.night0721.lilase.utils.DiscordWebhook; import me.night0721.lilase.utils.UngrabUtils; import me.night0721.lilase.utils.Utils; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; import javax.net.ssl.HttpsURLConnection; import java.awt.*; @@ -16,6 +17,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; +import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Arrays; @@ -23,34 +25,36 @@ import java.util.List; import java.util.Locale; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static me.night0721.lilase.features.flip.Flipper.rotation; public class AuctionHouse { private Boolean open = false; + public Boolean buying = false; private int auctionsSniped = 0; private int auctionsPosted = 0; private int auctionsFlipped = 0; public DiscordWebhook webhook = new DiscordWebhook(ConfigUtils.getString("main", "Webhook")); private final List items = new ArrayList<>(); + private final List blacklist = new ArrayList<>(); private final List posted = new ArrayList<>(); + private final ThreadLocalRandom randomSlot; public static Flipper flipper; public AuctionHouse() { - 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")))); + for (int i = 1; i <= 99; i++) { + if (!ConfigUtils.getString("item" + i, "Name").equals("") && !ConfigUtils.getString("item" + i, "Type").equals("") && !ConfigUtils.getString("item" + i, "Tier").equals("") && ConfigUtils.getInt("item" + i, "Price") != 0) + items.add(new Item(ConfigUtils.getString("item" + i, "Name"), ItemType.valueOf(ConfigUtils.getString("item" + i, "Type")), ConfigUtils.getInt("item" + i, "Price"), ItemTier.valueOf(ConfigUtils.getString("item" + i, "Tier")))); + } + for (int i = 1; i <= 99; i++) { + if (!ConfigUtils.getString("blacklist" + i, "Name").equals("") && !ConfigUtils.getString("blacklist" + i, "Type").equals("") && !ConfigUtils.getString("blacklist" + i, "Tier").equals("") && ConfigUtils.getInt("blacklist" + i, "Price") != 0) + blacklist.add(new Item(ConfigUtils.getString("blacklist" + i, "Name"), ItemType.valueOf(ConfigUtils.getString("blacklist" + i, "Type")), ConfigUtils.getInt("blacklist" + i, "Price"), ItemTier.valueOf(ConfigUtils.getString("blacklist" + i, "Tier")))); + } webhook.setUsername("Lilase - Auction House"); - //webhook.setAvatarUrl("https://wallpapercave.com/wp/wp2412537.jpg"); webhook.setAvatarUrl("https://th.bing.com/th/id/OIP.Lk2cSujieY70GbsgPZ0TyAHaEK?w=325&h=182&c=7&r=0&o=5&pid=1.7"); + webhook.setTts(false); + randomSlot = ThreadLocalRandom.current(); } - private JSONObject getHypixelData(String player) throws IOException, JSONException { + private JsonObject getHypixelData(String player) throws IOException { URL url = new URL("https://api.hypixel.net/player?key=" + ConfigUtils.getString("main", "APIKey") + "&uuid=" + player); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setRequestProperty("Content-Type", "application/json"); @@ -65,15 +69,11 @@ public class AuctionHouse { } in.close(); connection.disconnect(); - return new JSONObject(content.toString()); + return (JsonObject) new JsonParser().parse(content.toString()); } - private float generateRandomFloat() { - return (float) (ThreadLocalRandom.current().nextFloat() * 180); - } - - public void getItem() throws IOException, JSONException { - if (open == false) return; + public void getItem() throws IOException { + if (!open) return; if (!Utils.checkInHub()) { Utils.sendMessage("Not in hub, stopping"); open = false; @@ -89,8 +89,14 @@ public class AuctionHouse { open = false; return; } + if (Flipper.state != FlipperState.NONE) { + Utils.sendMessage("Flipper is running, stopping"); + open = false; + return; + } + if (Lilase.mc.currentScreen != null) Lilase.mc.thePlayer.closeScreen(); Utils.debugLog("[Sniper] Doing some motion as we don't want to be AFK"); - rotation.easeTo(Lilase.mc.thePlayer.rotationYaw + 1, Lilase.mc.thePlayer.rotationPitch, 500); + Lilase.mc.thePlayer.inventory.currentItem = randomSlot.nextInt(9); URL url = new URL("https://api.hypixel.net/skyblock/auctions"); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setRequestProperty("Content-Type", "application/json"); @@ -108,13 +114,17 @@ 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++) { - JSONObject auction = auctions.getJSONObject(i); + JsonObject data = (JsonObject) new JsonParser().parse(content.toString()); + JsonArray auctions = data.getAsJsonArray("auctions"); + for (int i = 0; i < auctions.size(); i++) { + JsonObject auction = auctions.get(i).getAsJsonObject(); for (Item item : items) { String lore = " "; ItemType type = item.type; + String itemName = auction.get("item_name").getAsString(); + String uuid = auction.get("uuid").getAsString(); + Integer price = auction.get("starting_bid").getAsInt(); + boolean found = false; switch (item.query) { case "Bal": lore = "Made of Lava"; @@ -135,35 +145,43 @@ public class AuctionHouse { lore = "Water Bender"; 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; - if (item.tier != ItemTier.ANY) if (!auction.getString("tier").equals(item.tier.name())) break; - if (type != ItemType.ANY) if (!auction.getString("category").equals(type.lowercase)) break; - 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() == Lilase.mc.thePlayer.getName().toLowerCase()) + if (posted.contains(uuid)) break; + for (Item blacklisted : blacklist) { + if (itemName.contains(blacklisted.getQuery())) { + found = true; 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") + "`"); - 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"); - Utils.sendServerMessage("/viewauction " + auction.getString("uuid")); + } + } + if (found) break; + if (!itemName.toLowerCase().contains(item.query.toLowerCase())) break; + if (!auction.get("item_lore").getAsString().contains(lore)) break; + if (price > item.price) break; + if (item.tier != ItemTier.ANY) if (!auction.get("tier").getAsString().equals(item.tier.name())) break; + if (type != ItemType.ANY) if (!auction.get("category").getAsString().equals(type.getLowercase())) break; + if (!auction.get("bin").getAsBoolean()) break; + if (!posted.contains(uuid)) { + posted.add(uuid); + flipper = new Flipper(itemName, auction.get("item_bytes").getAsString(), price); + NumberFormat format = NumberFormat.getInstance(Locale.US); + JsonObject profile = getHypixelData(auction.get("auctioneer").getAsString()); + String profileName = profile.get("player").getAsJsonObject().get("displayname").getAsString(); + if (profileName.equalsIgnoreCase(Lilase.mc.thePlayer.getName())) break; + String updated = auction.get("item_lore").getAsString().replaceAll("§[0-9a-z]", ""); + DecimalFormat df = new DecimalFormat("#.##"); + webhook.addEmbed(new DiscordWebhook.EmbedObject().setTitle("Bought an item on low price").setUrl("https://sky.coflnet.com/auction/" + uuid).setAuthor("night0721", "https://github.com/night0721", "https://avatars.githubusercontent.com/u/77528305?v=4").setDescription(updated.replace("\n", "\\n")).addField("Item", itemName, true).addField("Price", format.format(price) + " coins", true).addField("Profit", format.format(flipper.getItemPrice() - price) + " coins", true).addField("Profit Percentage", Float.parseFloat(df.format(flipper.getItemPrice() - price)) + "%", true).addField("Seller", profileName, true).addField("Started for", toDuration(System.currentTimeMillis() - auction.get("start").getAsLong()), true).addField("Ends in", getTimeSinceDate(auction.get("end").getAsLong() - System.currentTimeMillis()), true).setColor(Color.decode("#003153"))); + webhook.setContent(itemName + " is sale at " + format.format(price) + "! `" + "/viewauction " + uuid + "`"); + if (ConfigUtils.getBoolean("main", "checkProfitPercentageBeforeBuy")) { + float multi = flipper.checkProfitPercentage(); + Utils.debugLog("[Sniper] Found an item, checking profit percentage"); + if (multi > ConfigUtils.getInt("main", "ProfitPercentage")) { + Utils.debugLog("[Sniper] Higher than required profit percentage, buying now"); + Utils.sendServerMessage("/viewauction " + uuid); + buying = true; } } else { Utils.debugLog("[Sniper] Found an item, trying to buy"); - Utils.sendServerMessage("/viewauction " + auction.getString("uuid")); + Utils.sendServerMessage("/viewauction " + uuid); + buying = true; } return; } @@ -279,4 +297,20 @@ class Item { this.price = price; this.tier = tier; } + + public String getQuery() { + return query; + } + + public ItemType getType() { + return type; + } + + public Integer getPrice() { + return price; + } + + public ItemTier getTier() { + return tier; + } } \ No newline at end of file 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 2144b6e..76f9a49 100644 --- a/src/main/java/me/night0721/lilase/features/flip/Flipper.java +++ b/src/main/java/me/night0721/lilase/features/flip/Flipper.java @@ -1,12 +1,13 @@ package me.night0721.lilase.features.flip; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import me.night0721.lilase.Lilase; import me.night0721.lilase.events.SniperFlipperEvents; 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; @@ -24,6 +25,7 @@ public class Flipper { public static FlipperState state = FlipperState.NONE; public static final Rotation rotation = new Rotation(); private final Clock buyWait = new Clock(); + private JsonObject object; public Flipper(String name, String data, int price) { itemname = name; @@ -31,14 +33,20 @@ public class Flipper { itemprice = price; } - public int getItemPrice() throws IOException { - JSONObject item = getItemData(); - return (int) item.get("price"); + public int getItemPrice() { + if (object == null) { + try { + object = getItemData(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return object.get("price").getAsInt(); } - public int checkMultiplier() throws IOException { - JSONObject item = getItemData(); - return (int) item.get("price") / itemprice * 100; + public int checkProfitPercentage() throws IOException { + if (object == null) object = getItemData(); + return object.get("price").getAsInt() / itemprice * 100; } public void sellItem() { @@ -142,15 +150,17 @@ public class Flipper { } - public JSONObject getItemData() throws IOException { - URL url = new URL("https://api.night0721.me/api/v1/skyblock"); + public JsonObject getItemData() throws IOException { + URL url = new URL("https://api.night0721.me/api//skyblock"); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); 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"); + connection.setRequestMethod("GET"); OutputStream stream = connection.getOutputStream(); - stream.write(("{\"ByteData\": \"" + bytedata + "\"}").getBytes(StandardCharsets.UTF_16)); + JsonObject bd = new JsonObject(); + bd.addProperty("ByteData", bytedata); + stream.write(bd.toString().getBytes(StandardCharsets.UTF_16)); stream.flush(); stream.close(); BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); @@ -161,7 +171,8 @@ public class Flipper { } in.close(); connection.disconnect(); - return new JSONObject(content.toString()); + object = (JsonObject) new JsonParser().parse(content.toString()); + return (JsonObject) new JsonParser().parse(content.toString()); } private float distanceToFirstPoint() { diff --git a/src/main/java/me/night0721/lilase/mixins/MixinNetHandlerPlayClient.java b/src/main/java/me/night0721/lilase/mixins/MixinNetHandlerPlayClient.java new file mode 100644 index 0000000..ea5ef7b --- /dev/null +++ b/src/main/java/me/night0721/lilase/mixins/MixinNetHandlerPlayClient.java @@ -0,0 +1,18 @@ +package me.night0721.lilase.mixins; + +import me.night0721.lilase.utils.Utils; +import net.minecraft.client.network.NetHandlerPlayClient; +import net.minecraft.network.play.server.S47PacketPlayerListHeaderFooter; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(NetHandlerPlayClient.class) +public class MixinNetHandlerPlayClient { + @Inject(method = "handlePlayerListHeaderFooter", at = @At("HEAD")) + public void handlePlayerListHeaderFooter(S47PacketPlayerListHeaderFooter packetIn, CallbackInfo ci) { + Utils.header = packetIn.getHeader().getFormattedText().length() == 0 ? null : packetIn.getHeader(); + Utils.footer = packetIn.getFooter().getFormattedText().length() == 0 ? null : packetIn.getFooter(); + } +} diff --git a/src/main/java/me/night0721/lilase/utils/ConfigUtils.java b/src/main/java/me/night0721/lilase/utils/ConfigUtils.java index 398a603..5ae6a74 100644 --- a/src/main/java/me/night0721/lilase/utils/ConfigUtils.java +++ b/src/main/java/me/night0721/lilase/utils/ConfigUtils.java @@ -30,13 +30,13 @@ public class ConfigUtils { if (!hasKey("main", "ProfitPercentage")) writeIntConfig("main", "ProfitPercentage", 400); //400% if (!hasKey("main", "GUI")) writeBooleanConfig("main", "GUI", true); if (!hasKey("main", "GUI_COLOR")) writeIntConfig("main", "GUI_COLOR", 0x003153); - for (int i = 1; i <= 10; i++) { + for (int i = 1; i <= 3; i++) { if (!hasKey("item" + i, "Name")) writeStringConfig("item" + i, "Name", ""); if (!hasKey("item" + i, "Type")) writeStringConfig("item" + i, "Type", ""); if (!hasKey("item" + i, "Price")) writeIntConfig("item" + i, "Price", 0); if (!hasKey("item" + i, "Tier")) writeStringConfig("item" + i, "Tier", ""); } - for (int i = 1; i <= 10; i++) { + for (int i = 1; i <= 3; i++) { if (!hasKey("blacklist" + i, "Name")) writeStringConfig("blacklist" + i, "Name", ""); if (!hasKey("blacklist" + i, "Type")) writeStringConfig("blacklist" + i, "Type", ""); if (!hasKey("blacklist" + i, "Price")) writeIntConfig("blacklist" + i, "Price", 0); diff --git a/src/main/java/me/night0721/lilase/utils/Utils.java b/src/main/java/me/night0721/lilase/utils/Utils.java index 30e18fe..2908001 100644 --- a/src/main/java/me/night0721/lilase/utils/Utils.java +++ b/src/main/java/me/night0721/lilase/utils/Utils.java @@ -4,11 +4,20 @@ import me.night0721.lilase.Lilase; import net.minecraft.network.play.server.S45PacketTitle; import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class Utils { public static boolean inHub = false; + public static IChatComponent header = null; + public static IChatComponent footer = null; + private static final Pattern PATTERN_ACTIVE_EFFECTS = Pattern.compile( + "§r§r§7You have a §r§cGod Potion §r§7active! §r§d([0-9]*?:?[0-9]*?:?[0-9]*)§r"); + public static EffectState cookie; + public static EffectState godPot; public static String translateAlternateColorCodes(String text) { char[] b = text.toCharArray(); @@ -38,6 +47,39 @@ public class Utils { return inHub; } + public static void checkFooter() { + // + boolean foundGodPot = false; + boolean foundCookieText = false; + boolean loaded = false; + + if (footer != null) { + String formatted = footer.getFormattedText(); + for (String line : formatted.split("\n")) { + Matcher activeEffectsMatcher = PATTERN_ACTIVE_EFFECTS.matcher(line); + if (activeEffectsMatcher.matches()) { + foundGodPot = true; + } else if (line.contains("§d§lCookie Buff")) { + foundCookieText = true; + } else if (foundCookieText && line.contains("Not active! Obtain")) { + foundCookieText = false; + cookie = EffectState.OFF; + } else if (foundCookieText) { + foundCookieText = false; + cookie = EffectState.ON; + } + if (line.contains("Active")) { + loaded = true; + } + } + godPot = foundGodPot ? EffectState.ON : EffectState.OFF; + if (!loaded) { + godPot = EffectState.INDETERMINABLE; + cookie = EffectState.INDETERMINABLE; + } + } + } + public static void sendMessage(String message) { Lilase.mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.LIGHT_PURPLE + "" + EnumChatFormatting.BOLD + "Liliase" + EnumChatFormatting.RESET + EnumChatFormatting.DARK_GRAY + " » " + EnumChatFormatting.RESET + EnumChatFormatting.GREEN + EnumChatFormatting.BOLD + message)); } @@ -50,3 +92,7 @@ public class Utils { Lilase.mc.thePlayer.sendChatMessage(message); } } + +enum EffectState { + ON, OFF, INDETERMINABLE +} diff --git a/src/main/resources/mixins.lilase.json b/src/main/resources/mixins.lilase.json index 91251ea..6a04f4c 100644 --- a/src/main/resources/mixins.lilase.json +++ b/src/main/resources/mixins.lilase.json @@ -8,6 +8,7 @@ "MixinNetworkManager" ], "client": [ - "MixinMinecraft" + "MixinMinecraft", + "MixinNetHandlerPlayClient" ] }