From 48653ec89538f1650106a5e77463412cad4684c2 Mon Sep 17 00:00:00 2001
From: Soopyboo32 <49228220+Soopyboo32@users.noreply.github.com>
Date: Sun, 31 Oct 2021 09:49:42 +0800
Subject: first commit
---
features/agentlaiThings/hiddenRequirement.js | 8 +
features/agentlaiThings/index.js | 194 +++++++++++
features/agentlaiThings/metadata.json | 8 +
features/betterGuis/index.js | 197 +++++++++++
features/betterGuis/metadata.json | 8 +
features/changeLogGUI/index.js | 210 +++++++++++
features/changeLogGUI/metadata.json | 8 +
features/dataLoader/index.js | 128 +++++++
features/dataLoader/metadata.json | 8 +
features/dungeonMap/index.js | 299 ++++++++++++++++
features/dungeonMap/metadata.json | 8 +
features/dungeonSolvers/index.js | 153 ++++++++
features/dungeonSolvers/metadata.json | 8 +
features/events/index.js | 463 +++++++++++++++++++++++++
features/events/metadata.json | 8 +
features/featureBase/index.js | 24 ++
features/featureBase/metadata.json | 8 +
features/fragBot/index.js | 84 +++++
features/fragBot/metadata.json | 8 +
features/friendsGUI/index.js | 154 ++++++++
features/friendsGUI/metadata.json | 8 +
features/globalSettings/index.js | 51 +++
features/globalSettings/metadata.json | 8 +
features/hud/HudTextElement.js | 77 ++++
features/hud/index.js | 315 +++++++++++++++++
features/hud/metadata.json | 8 +
features/improvements/index.js | 36 ++
features/improvements/metadata.json | 8 +
features/mining/index.js | 201 +++++++++++
features/mining/metadata.json | 8 +
features/settings/index.js | 249 +++++++++++++
features/settings/metadata.json | 8 +
features/settings/settingThings/button.js | 18 +
features/settings/settingThings/location.js | 332 ++++++++++++++++++
features/settings/settingThings/settingBase.js | 106 ++++++
features/settings/settingThings/textSetting.js | 33 ++
features/settings/settingThings/toggle.js | 58 ++++
features/settings/settingsCommunicator.js | 29 ++
features/slayers/index.js | 359 +++++++++++++++++++
features/slayers/metadata.json | 8 +
features/soopyGui/GuiPage.js | 46 +++
features/soopyGui/index.js | 192 ++++++++++
features/soopyGui/metadata.json | 8 +
features/spamHider/index.js | 175 ++++++++++
features/spamHider/metadata.json | 8 +
features/stat_next_to_name/index.js | 19 +
features/stat_next_to_name/metadata.json | 8 +
47 files changed, 4362 insertions(+)
create mode 100644 features/agentlaiThings/hiddenRequirement.js
create mode 100644 features/agentlaiThings/index.js
create mode 100644 features/agentlaiThings/metadata.json
create mode 100644 features/betterGuis/index.js
create mode 100644 features/betterGuis/metadata.json
create mode 100644 features/changeLogGUI/index.js
create mode 100644 features/changeLogGUI/metadata.json
create mode 100644 features/dataLoader/index.js
create mode 100644 features/dataLoader/metadata.json
create mode 100644 features/dungeonMap/index.js
create mode 100644 features/dungeonMap/metadata.json
create mode 100644 features/dungeonSolvers/index.js
create mode 100644 features/dungeonSolvers/metadata.json
create mode 100644 features/events/index.js
create mode 100644 features/events/metadata.json
create mode 100644 features/featureBase/index.js
create mode 100644 features/featureBase/metadata.json
create mode 100644 features/fragBot/index.js
create mode 100644 features/fragBot/metadata.json
create mode 100644 features/friendsGUI/index.js
create mode 100644 features/friendsGUI/metadata.json
create mode 100644 features/globalSettings/index.js
create mode 100644 features/globalSettings/metadata.json
create mode 100644 features/hud/HudTextElement.js
create mode 100644 features/hud/index.js
create mode 100644 features/hud/metadata.json
create mode 100644 features/improvements/index.js
create mode 100644 features/improvements/metadata.json
create mode 100644 features/mining/index.js
create mode 100644 features/mining/metadata.json
create mode 100644 features/settings/index.js
create mode 100644 features/settings/metadata.json
create mode 100644 features/settings/settingThings/button.js
create mode 100644 features/settings/settingThings/location.js
create mode 100644 features/settings/settingThings/settingBase.js
create mode 100644 features/settings/settingThings/textSetting.js
create mode 100644 features/settings/settingThings/toggle.js
create mode 100644 features/settings/settingsCommunicator.js
create mode 100644 features/slayers/index.js
create mode 100644 features/slayers/metadata.json
create mode 100644 features/soopyGui/GuiPage.js
create mode 100644 features/soopyGui/index.js
create mode 100644 features/soopyGui/metadata.json
create mode 100644 features/spamHider/index.js
create mode 100644 features/spamHider/metadata.json
create mode 100644 features/stat_next_to_name/index.js
create mode 100644 features/stat_next_to_name/metadata.json
(limited to 'features')
diff --git a/features/agentlaiThings/hiddenRequirement.js b/features/agentlaiThings/hiddenRequirement.js
new file mode 100644
index 0000000..3c0408d
--- /dev/null
+++ b/features/agentlaiThings/hiddenRequirement.js
@@ -0,0 +1,8 @@
+let allowedUUIDS = [
+ "f2bcfe6aa54c4eb9b37156b4f1d20beb",
+ "dc8c39647b294e03ae9ed13ebd65dd29"
+]
+
+export default ()=>{
+ return !allowedUUIDS.includes(Player.getUUID().toString().replace(/-/g, ""))
+}
\ No newline at end of file
diff --git a/features/agentlaiThings/index.js b/features/agentlaiThings/index.js
new file mode 100644
index 0000000..aa3fdc3
--- /dev/null
+++ b/features/agentlaiThings/index.js
@@ -0,0 +1,194 @@
+///
+///
+import { SoopyGui, SoopyRenderEvent } from "../../../guimanager";
+import SoopyBoxElement from "../../../guimanager/GuiElement/SoopyBoxElement";
+import SoopyGuiElement from "../../../guimanager/GuiElement/SoopyGuiElement";
+import renderLibs from "../../../guimanager/renderLibs";
+import Feature from "../../featureClass/class";
+import ToggleSetting from "../settings/settingThings/toggle";
+
+class AgentThings extends Feature {
+ constructor() {
+ super()
+ }
+
+ onEnable(){
+ this.initVariables()
+
+ this.nearPlayerData = []
+ while(this.nearPlayerData.length < 100){this.nearPlayerData.push({})}
+
+ this.recordNearestPlayers = new ToggleSetting("Record nearby players", "You can then view this data with /nearplayers", true, "record_near_players", this)
+
+ this.registerStep(false, 1, this.step)
+
+ this.nearPlayersGui = new SoopyGui().setOpenCommand("nearplayers")
+
+ this.nearPlayersGuiBox = new SoopyBoxElement().setLocation(0.25, 0.25, 0.5, 0.5)
+ this.nearPlayersGui.element.addChild(this.nearPlayersGuiBox)
+
+ this.nearPlayersRenderElement = new SoopyGuiElement()
+ this.nearPlayersGuiBox.addChild(this.nearPlayersRenderElement)
+
+
+ let selected = undefined
+ let selectedDist = undefined
+ let lastXY = 0
+ this.nearPlayersRenderElement.addEvent(new SoopyRenderEvent().setHandler((mouseX, mouseY)=>{
+ let moved = lastXY !== mouseX+mouseY
+ lastXY = mouseX+mouseY
+
+ let x = this.nearPlayersRenderElement.location.getXExact()
+ let y = this.nearPlayersRenderElement.location.getYExact()
+ let width = this.nearPlayersRenderElement.location.getWidthExact()
+ let height = this.nearPlayersRenderElement.location.getHeightExact()
+
+ x+=width*0.125
+ y+=height*0.125
+ width*=0.75
+ height*=0.75
+
+ Renderer.drawLine(Renderer.color(0, 0, 0), x, y+height, x+width, y+height, 2)//bottom axis line
+ Renderer.drawLine(Renderer.color(0, 0, 0), x, y, x, y+height, 2)//left axis line
+
+ renderLibs.drawStringCentered("&0100s ago", x, y+height+6, Renderer.screen.getWidth()/1000)
+ renderLibs.drawStringCentered("&050s ago", x+width/2, y+height+6, Renderer.screen.getWidth()/1000)
+ renderLibs.drawStringCentered("&0Now", x+width, y+height+6, Renderer.screen.getWidth()/1000) //bottom axis markers
+
+
+ renderLibs.drawStringCenteredVertically("&025m away", x+3-Renderer.getStringWidth("&025m away")*Renderer.screen.getWidth()/1000, y, Renderer.screen.getWidth()/1000)
+ renderLibs.drawStringCenteredVertically("&020m away", x+3-Renderer.getStringWidth("&020m away")*Renderer.screen.getWidth()/1000, y+height/5*1, Renderer.screen.getWidth()/1000)
+ renderLibs.drawStringCenteredVertically("&010m away", x+3-Renderer.getStringWidth("&010m away")*Renderer.screen.getWidth()/1000, y+height/5*3, Renderer.screen.getWidth()/1000)
+ renderLibs.drawStringCenteredVertically("&00m away", x+3-Renderer.getStringWidth("&00m away")*Renderer.screen.getWidth()/1000, y+height-6, Renderer.screen.getWidth()/1000)
+
+ if(moved){
+ selected = undefined
+ selectedDist = undefined
+ }
+ let lastUuids = []
+ this.nearPlayerData.forEach((data, i)=>{
+ let newLastUuids = []
+ Object.keys(data).forEach(uuid=>{
+ newLastUuids.push(uuid)
+ lastUuids = lastUuids.filter(a=>a!==uuid)
+
+ let dist = data[uuid].distance
+ let oldDist = this.nearPlayerData[i-1]?.[uuid]?.distance || 25
+
+ let thisX = x+(i)/100*width
+ let thisY = y+height-(dist/25)*height
+
+ if(moved && (thisX-mouseX)**2 + (thisY-mouseY)**2 < 3){
+ selected = uuid
+ selectedDist = dist
+ }
+
+ if(i !== 0){
+ Renderer.drawLine(Renderer.color(0, 0, 0), x+(i-1)/100*width, y+height-(oldDist/25)*height, thisX, thisY, 1)
+ }
+
+ Renderer.drawRect(Renderer.color(0, 0, 0), thisX-1, thisY-1, 3, 3)
+ })
+
+ lastUuids.forEach(uuid=>{
+ let dist = 25
+ let oldDist = this.nearPlayerData[i-1]?.[uuid]?.distance || 25
+
+ let thisX = x+(i)/100*width
+ let thisY = y+height-(dist/25)*height
+
+ if(i !== 0){
+ Renderer.drawLine(Renderer.color(0, 0, 0), x+(i-1)/100*width, y+height-(oldDist/25)*height, thisX, thisY, 1)
+ }
+ })
+
+ lastUuids = newLastUuids
+ })
+
+ if(selected){
+ width = this.nearPlayersRenderElement.location.getWidthExact()
+ height = this.nearPlayersRenderElement.location.getHeightExact()
+
+ width*=0.75
+ height*=0.75
+
+ renderLibs.scizzorFast(0,0,Renderer.screen.getWidth(), Renderer.screen.getHeight())
+ let selectedIgn = undefined
+ let lastRenderedSelected = false
+ this.nearPlayerData.forEach((data, i)=>{
+ if(data[selected]){
+ lastRenderedSelected = true
+
+ selectedIgn = data[selected].name
+
+ let dist = data[selected].distance
+ let oldDist = this.nearPlayerData[i-1]?.[selected]?.distance || 25
+
+ let thisX = x+(i)/100*width
+ let thisY = y+height-(dist/25)*height
+
+ if(i !== 0){
+ Renderer.drawLine(Renderer.color(255, 0, 0), x+(i-1)/100*width, y+height-(oldDist/25)*height, thisX, thisY, 3)
+ }
+ }else{
+ if(lastRenderedSelected){
+ lastRenderedSelected = false
+
+ let dist = 25
+ let oldDist = this.nearPlayerData[i-1]?.[selected]?.distance || 25
+
+ let thisX = x+(i)/100*width
+ let thisY = y+height-(dist/25)*height
+
+ if(i !== 0){
+ Renderer.drawLine(Renderer.color(255, 0, 0), x+(i-1)/100*width, y+height-(oldDist/25)*height, thisX, thisY, 3)
+ }
+ }
+ }
+ })
+
+ let width = Math.max(Renderer.getStringWidth(selectedIgn)*2, Renderer.getStringWidth("Distance: " + selectedDist.toFixed(1)))+8
+ let height = 32
+ renderLibs.drawBox([255, 255, 255], mouseX+10, mouseY-height/2, width,height, 3)
+ renderLibs.drawString("&0" + selectedIgn, mouseX+14, mouseY-height/2+3, 2)
+ renderLibs.drawString("&0Distance: &7" + selectedDist.toFixed(1) , mouseX+14, mouseY-height/2+21, 1)
+ }
+
+ }))
+ }
+
+ step(){
+ if(!this.recordNearestPlayers.getValue()) return
+
+ let thisSecondPlayerData = {}
+ World.getAllPlayers().forEach(p=>{
+ let distSq = (p.getX()-Player.getX())**2+(p.getY()-Player.getY())**2+(p.getZ()-Player.getZ())**2
+
+ if(distSq < 25*25 && distSq !== 0){
+ thisSecondPlayerData[p.getUUID().toString()] = {name: p.getName(), distance: Math.sqrt(distSq)}
+ }
+ })
+
+ this.nearPlayerData.push(thisSecondPlayerData)
+
+ if(this.nearPlayerData.length > 100) this.nearPlayerData.shift()
+ }
+
+ initVariables(){
+ this.recordNearestPlayers = undefined
+ this.nearPlayerData = undefined
+ this.nearPlayersGui = undefined
+ this.nearPlayersGuiBox = undefined
+ this.nearPlayersRenderElement = undefined
+ }
+
+ onDisable(){
+ this.nearPlayersGui.delete()
+
+ this.initVariables()
+ }
+}
+
+module.exports = {
+ class: new AgentThings()
+}
\ No newline at end of file
diff --git a/features/agentlaiThings/metadata.json b/features/agentlaiThings/metadata.json
new file mode 100644
index 0000000..e44e8fa
--- /dev/null
+++ b/features/agentlaiThings/metadata.json
@@ -0,0 +1,8 @@
+{
+ "name": "Agentlai Settings",
+ "description": "Settings only avalible to agentlai",
+ "isHidden": "hiddenRequirement.js",
+ "isTogglable": true,
+ "defaultEnabled": false,
+ "sortA": 0
+}
\ No newline at end of file
diff --git a/features/betterGuis/index.js b/features/betterGuis/index.js
new file mode 100644
index 0000000..8600499
--- /dev/null
+++ b/features/betterGuis/index.js
@@ -0,0 +1,197 @@
+///
+///
+import Feature from "../../featureClass/class";
+import { drawBoxAtBlockNotVisThruWalls } from "../../utils/renderUtils";
+import ToggleSetting from "../settings/settingThings/toggle";
+
+class BetterGuis extends Feature {
+ constructor() {
+ super()
+ }
+
+ onEnable(){
+ this.initVariables()
+
+ this.replaceSbMenuClicks = new ToggleSetting("Improve Clicks on SBMENU", "This will change clicks to middle clicks, AND use commands where possible (eg /pets)", true, "sbmenu_clicks", this)
+ this.reliableSbMenuClicks = {getValue: ()=>false}//removed because hypixel fixed may add back later //new ToggleSetting("Make SBMENU clicks reliable", "This will delay clicks on sbmenu to time them so they dont get canceled", true, "sbmenu_time", this)
+
+ this.lastWindowId = 0
+ this.shouldHold = 10
+ this.clickSlot = -1
+ this.clickSlotTime = 0
+
+ this.middleClickGuis = [
+ "Your SkyBlock Profile",
+ "Your Skills",
+ "Farming Skill",
+ "Mining Skill",
+ "Heart of the Mountain",
+ "Combat Skill",
+ "Foraging Skill",
+ "Fishing Skill",
+ "Enchanting Skill",
+ "Alchemy Skill",
+ "Carpentry Skill",
+ "Runecrafting Skill",
+ "Social Skill",
+ "Taming Skill",
+ "Dungeoneering",
+ "Your Essence",
+ "Healer Class Perks",
+ "Mage Class Perks",
+ "Beserk Class Perks",
+ "Archer Class Perks",
+ "Tank Class Perks",
+ "Recipe Book",
+ "Trades",
+ "Quest Log",
+ "Quest Log (Completed)",
+ "Fairt Souls Guide",
+ "Dungeon Journals",
+ "Calendar and Events",
+ "Booster Cookie",
+ "Island Management",
+ "Toggle Potion Effects",
+ "Bank",
+ "Bank Account Upgrades",
+ "Co-op Bank Account",
+ "Bank Deposit",
+ "Bank Withdrawal",
+ "Personal Bank Account",
+ "Bazaar Orders",
+ "Co-op Bazaar Orders"
+ ]
+ this.middleClickStartsWith = [
+ "Bestiary",
+ "Private Island",
+ "Hub",
+ "Spiders Den",
+ "Blazing Fortress",
+ "The End",
+ "Deep Caverns",
+ "The Park",
+ "Spooky Festival",
+ "Catacombs",
+ "The Catacombs",
+ "Settings",
+ "Bazaar",
+ "Farming",
+ "Mining",
+ "Woods & Fishes",
+ "Oddities"
+ ]
+ this.middleClickEndsWith = [
+ "Recipe",
+ "Recipes",
+ "Pets",
+ "Collection",
+ "Active Effects"
+ ]
+
+ this.registerEvent("guiMouseClick", this.guiClicked)
+ this.registerStep(true, 10, this.step)
+ }
+
+ guiClicked(mouseX, mouseY, button, gui, event){
+ if(gui.class.toString()==="class net.minecraft.client.gui.inventory.GuiChest" && button===0 && this.replaceSbMenuClicks.getValue()){
+
+ let hoveredSlot = gui.getSlotUnderMouse()
+ if(!hoveredSlot) return
+
+ let hoveredSlotId = hoveredSlot.field_75222_d
+ // console.log(hoveredSlotId)
+ if(this.guiSlotClicked(ChatLib.removeFormatting(Player.getOpenedInventory().getName()), hoveredSlotId)){
+ cancel(event)
+ }
+ }
+ }
+
+ step(){
+ if(this.replaceSbMenuClicks.getValue()){
+ if(Player.getOpenedInventory().getName()==="SkyBlock Menu"){
+ if(this.lastWindowId === 0){
+ this.lastWindowId = Player.getOpenedInventory().getWindowId()
+ return;
+ }
+ if(Player.getOpenedInventory().getWindowId()!==this.lastWindowId){
+ this.lastWindowId = Player.getOpenedInventory().getWindowId()
+ this.shouldHold+= 10
+ if(Date.now()-this.clickSlotTime >1000){
+ this.clickSlot = -1
+ }
+ if(this.clickSlot && this.clickSlot != -1){
+ Player.getOpenedInventory().click(this.clickSlot, false, "MIDDLE")
+ this.clickSlot = -1
+ }
+ }else{
+ this.shouldHold--
+ }
+ }else{
+ this.lastWindowId =0
+ }
+ }
+ }
+
+ guiSlotClicked(inventoryName, slotId){
+ switch(inventoryName){
+ case "SkyBlock Menu":
+ switch(slotId){
+ case 30:
+ ChatLib.command("pets")
+ break
+ case 25:
+ ChatLib.command("storage")
+ break
+ default:
+ if(this.shouldHold>0 && this.reliableSbMenuClicks.getValue()){
+ this.clickSlot = slotId
+ this.clickSlotTime = Date.now()
+ }else{
+ Player.getOpenedInventory().click(slotId, false, "MIDDLE")
+ }
+ break;
+ }
+ return true
+ break
+ default:
+ if(this.middleClickGuis.includes(inventoryName)){
+ Player.getOpenedInventory().click(slotId, false, "MIDDLE")
+ return true
+ }
+ for(let thing of this.middleClickStartsWith){
+ if(inventoryName.startsWith(thing)){
+ Player.getOpenedInventory().click(slotId, false, "MIDDLE")
+ return true
+ }
+ }
+ for(let thing of this.middleClickEndsWith){
+ if(inventoryName.endsWith(thing)){
+ Player.getOpenedInventory().click(slotId, false, "MIDDLE")
+ return true
+ }
+ }
+ return false
+ break
+ }
+ }
+
+ initVariables(){
+ this.replaceSbMenuClicks = undefined
+ this.lastWindowId = undefined
+ this.shouldHold = undefined
+ this.clickSlot = undefined
+ this.clickSlotTime = undefined
+ this.reliableSbMenuClicks = undefined
+ this.middleClickGuis = undefined
+ this.middleClickStartsWith = undefined
+ this.middleClickEndsWith = undefined
+ }
+
+ onDisable(){
+ this.initVariables()
+ }
+}
+
+module.exports = {
+ class: new BetterGuis()
+}
\ No newline at end of file
diff --git a/features/betterGuis/metadata.json b/features/betterGuis/metadata.json
new file mode 100644
index 0000000..6aeed27
--- /dev/null
+++ b/features/betterGuis/metadata.json
@@ -0,0 +1,8 @@
+{
+ "name": "Better guis",
+ "description": "Edits to a bunch of guis to make them nicer to use",
+ "isHidden": false,
+ "isTogglable": true,
+ "defaultEnabled": true,
+ "sortA": 1
+}
\ No newline at end of file
diff --git a/features/changeLogGUI/index.js b/features/changeLogGUI/index.js
new file mode 100644
index 0000000..f6595b0
--- /dev/null
+++ b/features/changeLogGUI/index.js
@@ -0,0 +1,210 @@
+///
+///
+import SoopyGuiElement from "../../../guimanager/GuiElement/SoopyGuiElement";
+import SoopyTextElement from "../../../guimanager/GuiElement/SoopyTextElement";
+import Feature from "../../featureClass/class";
+import GuiPage from "../soopyGui/GuiPage";
+import SoopyMarkdownElement from '../../../guimanager/GuiElement/SoopyMarkdownElement.js';
+import metadata from "../../metadata";
+import ButtonWithArrow from "../../../guimanager/GuiElement/ButtonWithArrow";
+import SoopyMouseClickEvent from "../../../guimanager/EventListener/SoopyMouseClickEvent";
+import ProgressBar from "../../../guimanager/GuiElement/ProgressBar"
+import SoopyRenderEvent from "../../../guimanager/EventListener/SoopyRenderEvent"
+const File = Java.type("java.io.File")
+const URL = Java.type("java.net.URL");
+const PrintStream = Java.type("java.io.PrintStream");
+const Byte = Java.type("java.lang.Byte");
+
+class ChangeLogGui extends Feature {
+ constructor() {
+ super()
+ }
+
+ onEnable(){
+ this.initVariables()
+
+ this.ChangelogPage = new ChangelogPage()
+ }
+
+ initVariables(){
+ this.ChangelogPage = undefined
+ }
+
+ onDisable(){
+ this.initVariables()
+ }
+}
+
+
+class ChangelogPage extends GuiPage {
+ constructor(){
+ super(9)
+
+ this.name = "Changelog"
+
+ this.pages = [this.newPage()]
+
+ this.changelogData = []
+ this.downloadableVersion = 0
+
+ let changelogTitle = new SoopyTextElement().setText("§0Changelog").setMaxTextScale(3).setLocation(0.1, 0.05, 0.8, 0.1)
+ this.pages[0].addChild(changelogTitle)
+
+ this.changelogArea = new SoopyGuiElement().setLocation(0.1, 0.2, 0.8, 0.8).setScrollable(true)
+ this.pages[0].addChild(this.changelogArea)
+
+ //Update confirmation page
+ this.updatingSidebar =new SoopyGuiElement().setLocation(0,0,1,1)
+ this.updatingSidebarConfirmPage = new SoopyGuiElement().setLocation(0,0,1,1)
+ this.updatingSidebar.addChild(this.updatingSidebarConfirmPage)
+
+ this.updateTitle = new SoopyTextElement().setText("§0Update to SoopyAddons ").setMaxTextScale(3).setLocation(0.1, 0.05, 0.8, 0.1)
+ this.updatingSidebarConfirmPage.addChild(this.updateTitle)
+
+ this.warningMessage = new SoopyMarkdownElement().setLocation(0.1, 0.2, 0.8, 0.8)
+ this.warningMessage.setText(`# NOTE
+Updating SoopyAddons through this method is downloading the code from _§cmy server_
+This means that there is _§cno_ third party that is double checking the code to ensure there is no virus in it.
+This is fine if you trust me to not put a virus in it, but if you dont you should instead wait for the update to be checked and verified by the chattriggers people.`)
+ this.updatingSidebarConfirmPage.addChild(this.warningMessage)
+
+ this.updateButton = new ButtonWithArrow().setText("§0Update").setLocation(0.3, 0.3+this.warningMessage.getHeight(), 0.4, 0.2)
+ this.updatingSidebarConfirmPage.addChild(this.updateButton)
+
+ this.updatingSidebarConfirmPage.setScrollable(true)
+
+ this.updateButton.addEvent(new SoopyRenderEvent().setHandler(()=>{
+ this.updateButton.location.location.y.set(0.3+this.warningMessage.getHeight(),0)
+ }))
+ this.updateButton.addEvent(new SoopyMouseClickEvent().setHandler(()=>{
+ this.downloadUpdate()
+ }))
+
+ this.updatingSidebarLoadingPage = new SoopyGuiElement().setLocation(1,0,1,1)
+ this.updatingSidebar.addChild(this.updatingSidebarLoadingPage)
+
+ let updatingTitle = new SoopyTextElement().setText("§0Updating...").setMaxTextScale(3).setLocation(0.1, 0.05, 0.8, 0.1)
+ this.updatingSidebarLoadingPage.addChild(updatingTitle)
+
+ this.progressBar = new ProgressBar().setLocation(0.1, 0.2, 0.8, 0.1)
+ this.updatingSidebarLoadingPage.addChild(this.progressBar)
+
+ this.currVersionId = metadata.versionId
+
+ this.finaliseLoading()
+ }
+
+ onOpen(){
+ new Thread(()=>{
+ let data = JSON.parse(FileLib.getUrlContent("http://soopymc.my.to/api/soopyv2/changelog.json"))
+
+ this.changelogData = data.changelog.reverse()
+
+ this.downloadableVersion = data.downloadableVersion
+
+ this.updateText()
+ }).start()
+ }
+
+ showConfirmUpdatePage(){
+ let version = ""
+ this.changelogData.forEach(data=>{
+
+ if(this.downloadableVersion === data.versionId && this.downloadableVersion > this.currVersionId){
+ //add button to download this version
+ version = data.version
+ }
+ })
+ this.updateTitle.setText("§0Update to SoopyAddons " + version)
+
+ this.updateButton.location.location.y.set(0.3+this.warningMessage.getHeight(),0)
+
+ this.openSidebarPage(this.updatingSidebar)
+ }
+
+ downloadUpdate(){
+ new Thread(()=>{
+ this.updatingSidebarConfirmPage.location.location.x.set(-1,500)
+ this.updatingSidebarLoadingPage.location.location.x.set(0,500)
+
+ new File("./config/ChatTriggers/modules/SoopyAddonsTempDownload").mkdir()
+
+ this.progressBar.setProgress(0.1)
+
+ this.urlToFile("http://soopymc.my.to/api/soopyv2/downloadLatest.zip", "./config/ChatTriggers/modules/SoopyAddonsTempDownload/SoopyAddons.zip", 10000, 20000)
+
+ this.progressBar.setProgress(0.5)
+
+ FileLib.unzip("./config/ChatTriggers/modules/SoopyAddonsTempDownload/SoopyAddons.zip", "./config/ChatTriggers/modules/SoopyAddonsTempDownload/SoopyAddons/")
+
+ this.progressBar.setProgress(0.75)
+
+ FileLib.deleteDirectory(new File("./config/ChatTriggers/modules/SoopyV2"))
+
+ this.progressBar.setProgress(0.9)
+
+ new File("./config/ChatTriggers/modules/SoopyAddonsTempDownload/SoopyAddons/SoopyV2").renameTo(new File("./config/ChatTriggers/modules/SoopyV2"))
+
+ FileLib.deleteDirectory(new File("./config/ChatTriggers/modules/SoopyAddonsTempDownload"))
+
+ this.progressBar.setProgress(1)
+
+ Client.currentGui.close()
+
+ ChatLib.command("ct load", true)
+ }).start()
+ }
+
+ urlToFile(url, destination, connecttimeout, readtimeout) {
+ const d = new File(destination);
+ d.getParentFile().mkdirs();
+ const connection = new URL(url).openConnection();
+ connection.setDoOutput(true);
+ connection.setConnectTimeout(connecttimeout);
+ connection.setReadTimeout(readtimeout);
+ const IS = connection.getInputStream();
+ const FilePS = new PrintStream(destination);
+ let buf = new Packages.java.lang.reflect.Array.newInstance(Byte.TYPE, 65536);
+ let len;
+ while ((len = IS.read(buf)) > 0) {
+ FilePS.write(buf, 0, len);
+ }
+ IS.close();
+ FilePS.close();
+ }
+
+ updateText(){
+ this.changelogArea.children = []
+
+ let height = 0
+
+ this.changelogData.forEach(data=>{
+
+ if(this.downloadableVersion === data.versionId && this.downloadableVersion > this.currVersionId){
+ //add button to download this version
+ let button = new ButtonWithArrow().setText("§0Download this version").setLocation(0.7, height, 0.3, 0.1)
+ this.changelogArea.addChild(button)
+
+ button.addEvent(new SoopyMouseClickEvent().setHandler(()=>{
+ this.showConfirmUpdatePage()
+ }))
+
+ height += 0.05
+ }
+
+ let changes = new SoopyMarkdownElement().setLocation(0,height, 1, 0)
+
+ this.changelogArea.addChild(changes)
+
+ changes.setText("# __" + data.version + "__" + (data.versionId === this.currVersionId?" §7Current" : "") + "\n" + data.description)
+
+ height += changes.getHeight()
+
+ height += 0.1
+ })
+ }
+}
+
+module.exports = {
+ class: new ChangeLogGui()
+}
\ No newline at end of file
diff --git a/features/changeLogGUI/metadata.json b/features/changeLogGUI/metadata.json
new file mode 100644
index 0000000..8dfbe4b
--- /dev/null
+++ b/features/changeLogGUI/metadata.json
@@ -0,0 +1,8 @@
+{
+ "name": "ChangeLog gui",
+ "description": "Gui for changelog",
+ "isHidden": true,
+ "isTogglable": false,
+ "defaultEnabled": true,
+ "sortA": 0
+}
\ No newline at end of file
diff --git a/features/dataLoader/index.js b/features/dataLoader/index.js
new file mode 100644
index 0000000..41f0c61
--- /dev/null
+++ b/features/dataLoader/index.js
@@ -0,0 +1,128 @@
+///
+///
+import Feature from "../../featureClass/class";
+
+class DataLoader extends Feature {
+ constructor() {
+ super()
+ }
+
+ onEnable(){
+ this.initVariables()
+
+ this.stats = {}
+
+ this.area = undefined
+
+ this.isInSkyblock = false
+
+ this.registerStep(true, 2, this.step)
+
+ this.registerEvent("worldLoad", this.worldLoad)
+
+ this.api_loaded_event = this.createCustomEvent("apiLoad")
+
+ this.lastApiData = {
+ "skyblock": undefined,
+ "player": undefined,
+ "skyblock_raw": undefined, //the _raw is loaded from hypixel api instead of soopy api
+ "player_raw": undefined
+ }
+
+ this.loadApi()
+ }
+
+ worldLoad(){
+ this.area = undefined
+ }
+
+ loadApi(){
+ let data = JSON.parse(FileLib.getUrlContent("http://soopymc.my.to/api/v2/player_skyblock/" + Player.getUUID().replace(/-/g, "")))
+
+ if(!data.success) return
+
+ this.api_loaded_event.trigger(data, "skyblock", true, true)
+ this.lastApiData.skyblock = data
+ }
+
+ loadApiData(type, soopyServer){
+ while(this.FeatureManager.features["globalSettings"] === undefined){
+ Thread.sleep(100)
+ }
+ let key = this.FeatureManager.features["globalSettings"].class.apiKeySetting.getValue()
+ if(!key) return
+
+ if(soopyServer){
+
+ }else{
+ if(type === "skyblock"){
+ let data = JSON.parse(FileLib.getUrlContent("https://api.hypixel.net/skyblock/profiles?key=" + key + "&uuid=" + Player.getUUID().replace(/-/g, "")))
+
+ if(!data.success) return
+
+ this.api_loaded_event.trigger(data, "skyblock", false, true)
+ this.lastApiData.skyblock_raw = data
+ }
+ }
+ }
+
+ step(){ //2fps
+ this.stats["Area"] = undefined
+ this.stats["Dungeon"] = undefined
+ TabList.getNames().forEach(n=>{
+ n = ChatLib.removeFormatting(n)
+ if(n.includes(": ")){
+ this.stats[n.split(": ")[0].trim()] = n.split(": ")[1].trim()
+ }
+ })
+ if(this.stats["Dungeon"]){
+ this.stats["Area"] = this.stats["Dungeon"]
+ this.isInDungeon = true
+ }else{
+ this.isInDungeon = false
+ }
+
+ this.dungeonFloor = undefined
+ Scoreboard.getLines().forEach(line=>{
+ let name = ChatLib.removeFormatting(line.getName()).replace(/[^A-z0-9 \:\(\)\.]/g, "")
+ if(this.isInDungeon){
+ if(name.includes("The Catacombs (")){
+ this.dungeonFloor = name.split("(")[1].split(")")[0].toUpperCase()
+ }
+ }
+ if(ChatLib.removeFormatting(line).startsWith(" ⏣ ")){
+ this.areaFine = ChatLib.removeFormatting(line).split(" ⏣ ")[1].replace(/[^A-z0-9 \:\(\)\.\-]/g, "")
+ }
+ if(name.startsWith("Purse: ")){
+ this.purse = parseInt(name.split("Purse: ")[1].split(" ")[0])
+ }
+ if(name.startsWith("Bits: ")){
+ this.bits = parseInt(name.split("Bits: ")[1].split(" ")[0])
+ }
+ })
+
+ this.isInSkyblock = Scoreboard.getTitle()?.removeFormatting().endsWith("SKYBLOCK")
+ this.area = this.stats["Area"]
+ }
+
+ initVariables(){
+ this.stats = undefined
+ this.isInDungeon = false
+
+ this.dungeonFloor = undefined
+ this.area = undefined
+ this.areaFine = undefined
+ this.bits = undefined
+ this.purse = undefined
+ this.lastApiData = undefined
+ this.isInSkyblock = undefined
+ }
+
+ onDisable(){
+ this.initVariables()
+ }
+}
+
+module.exports = {
+ class: new DataLoader()
+}
\ No newline at end of file
diff --git a/features/dataLoader/metadata.json b/features/dataLoader/metadata.json
new file mode 100644
index 0000000..4953f99
--- /dev/null
+++ b/features/dataLoader/metadata.json
@@ -0,0 +1,8 @@
+{
+ "name": "Data loader",
+ "description": "Loads data",
+ "isHidden": true,
+ "isTogglable": false,
+ "defaultEnabled": true,
+ "sortA": 0
+}
\ No newline at end of file
diff --git a/features/dungeonMap/index.js b/features/dungeonMap/index.js
new file mode 100644
index 0000000..12bd471
--- /dev/null
+++ b/features/dungeonMap/index.js
@@ -0,0 +1,299 @@
+///
+///
+import Feature from "../../featureClass/class";
+const BufferedImage = Java.type("java.awt.image.BufferedImage")
+
+class DungeonMap extends Feature {
+ constructor() {
+ super()
+ }
+
+ isInDungeon(){
+ return this.FeatureManager.features["dataLoader"].class.isInDungeon
+ }
+
+ onEnable(){
+ this.initVariables()
+
+ this.defaultPlayerImage = new Image("skull-steve","https://cravatar.eu/avatar/dc8c39647b294e03ae9ed13ebd65dd29")
+ this.playerImages = {}
+ this.mapDataPlayers = {}
+ this.offset = []
+ this.mapScale = 1
+ this.puzzles = []
+ this.puzzlesTab = []
+ this.newPuzzlesTab = []
+
+ // this.registerEvent("tick", this.tick)
+ this.registerStep(true, 5, this.step)
+ this.registerEvent("renderOverlay", this.renderOverlay)
+ this.registerEvent("worldLoad", this.worldLoad)
+ }
+
+ worldLoad(){
+ this.mortLocation = undefined
+ this.playerImages = {}
+ this.mapDataPlayers = {}
+ this.offset = []
+ this.mapScale = 1
+ this.puzzles = []
+ this.puzzlesTab = []
+ this.newPuzzlesTab = []
+ }
+
+ renderOverlay(){
+ if(this.isInDungeon()){
+ if(this.mapImage){
+ this.mapImage.draw(50,50)
+
+ this.drawPlayersLocations()
+ }
+ }
+ }
+
+ drawPlayersLocations(){
+
+ let uuidToPlayer = {}
+ World.getAllPlayers().forEach(player=>{
+ uuidToPlayer[player.getUUID().toString()] = player
+ })
+
+ Object.keys(this.mapDataPlayers).forEach((uuid)=>{
+ let player = uuidToPlayer[uuid]
+ if(player){
+ this.mapDataPlayers[uuid] = {
+ x: player.getX()/this.mapScale,
+ y: player.getZ()/this.mapScale,
+ rot: player.getYaw()+180
+ }
+ }
+
+ Renderer.translate(this.mapDataPlayers[uuid].x+50+this.offset[0], this.mapDataPlayers[uuid].y+50+this.offset[1])
+ Renderer.rotate(this.mapDataPlayers[uuid].rot)
+ this.getImageForPlayer(uuid).draw(-5,-5, 10, 10)
+ })
+ }
+
+ step(){
+ TabList.getNames().forEach(name=>{
+ name = ChatLib.removeFormatting(name).split()
+ if(name[1].trim() === "[✦]" && !name[0].includes("???") && !this.puzzlesTab.includes(name[0].trim())){
+ this.newPuzzlesTab.push(name[0].trim())
+ this.puzzlesTab.push(name[0].trim())
+ }
+ })
+
+ if(this.isInDungeon()){
+ this.updateMapImage()
+ }else{
+ this.mapImage = undefined
+ }
+ }
+
+ updateMapImage(){
+
+ World.getAllPlayers().forEach(player=>{
+ this.mapDataPlayers[Player.getUUID().toString()] = {
+ x: player.getX()/this.mapScale,
+ y: player.getZ()/this.mapScale,
+ rot: player.getYaw()+180
+ }
+ })
+ if(!this.mortLocation){
+ World.getAllEntities().forEach(entity=>{
+ if(ChatLib.removeFormatting(entity.getName()) === ("Mort")){
+ this.mortLocation = [
+ entity.getX(),
+ entity.getZ()
+ ]
+ }
+ })
+ }
+
+ let IMAGE_SIZE = 128
+ let newImage = new BufferedImage(IMAGE_SIZE,IMAGE_SIZE, BufferedImage.TYPE_INT_RGB)
+ let graphics = newImage.getGraphics()
+
+ graphics.fillRect(0,0,IMAGE_SIZE,IMAGE_SIZE)
+
+ let mapImage = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB)
+ let mapData
+ try {
+ let item = Player.getInventory().getStackInSlot(8)
+ mapData = item.getItem().func_77873_a(item.getItemStack(), World.getWorld()); // ItemStack.getItem().getMapData()
+ } catch (error) {
+ }
+ if(mapData){
+ mapData.field_76203_h.forEach((icon, vec4b) => {
+ let x = vec4b.func_176112_b()
+ let y = vec4b.func_176113_c()
+ let rot = vec4b.func_176111_d()
+
+ //wtf is this
+
+ //vec4b.func_176110_a()
+
+ let closestP = undefined
+ let closestDistance = Infinity
+ Object.keys(this.mapDataPlayers).forEach((uuid)=>{
+ if((x-this.mapDataPlayers[uuid].x)**2+(y-this.mapDataPlayers[uuid].y)**2 < closestDistance){
+ closestDistance = (x-this.mapDataPlayers[uuid].x)**2+(y-this.mapDataPlayers[uuid].y)**2
+ closestP = uuid
+ }
+ })
+
+ this.mapDataPlayers[closestP].x = x
+ this.mapDataPlayers[closestP].y = y
+ this.mapDataPlayers[closestP].rot = rot
+ });
+
+ // console.log("has map data poggies")
+ let bytes = mapData.field_76198_e
+
+ let x = 0
+ let y = 0
+ for(let i = 0; i < bytes.length; i++){
+ // console.log(bytes[i]/4)
+
+ if(bytes[i] !== 0){
+ let j = bytes[i]&255
+ let color = net.minecraft.block.material.MapColor.field_76281_a[j>>2].func_151643_b(j & 3);
+ mapImage.setRGB(x, y, color)
+ newImage.setRGB(x, y, color)
+ }
+ x++
+ if(x >= 128){
+ x=0
+ y++
+
+ if(y>128) break
+ }
+
+ // mapImage.getRGB()
+ }
+
+ // newImage.setRGB(0,0,128,128, ints, 0, 1)
+
+ // graphics. ()
+ //room size is 18
+ //4 inbetween
+
+ //finding room offsets
+ let roomOffsets
+ let mortLocationOnMap = undefined
+ let roomWidth = 0
+ for(let x = 0;x<128;x++){
+ for(let y = 0;y<128;y++){
+ if(bytes[x+y*128] === 30 && bytes[(x-1)+(y-1)*128] === 0){
+ roomWidth++
+ }
+ }
+ if(roomWidth > 0) break;
+ }
+
+ roomWidth = Math.floor(roomWidth*5/4)
+ this.mapScale = 32/roomWidth
+ for(let x = 0;x<128;x++){
+ for(let y = 0;y<128;y++){
+ if(bytes[x+y*128] === 30 && bytes[(x-1)+(y-1)*128] === 0){
+ if(roomOffsets) break;
+ roomOffsets = [x%roomWidth-3, y%roomWidth-3]
+
+ let dir = roomWidth/2-5/this.mapScale
+
+ //top
+ for(let i = 0;i{
+ this.playerImages[uuid] = new Image("skull-" + uuid,"https://cravatar.eu/helmavatar/" + uuid)
+ }).start()
+ return this.defaultPlayerImage
+ }
+
+ initVariables(){
+ this.mapImage = undefined
+ this.defaultPlayerImage = undefined
+ this.mortLocation = undefined
+ this.playerImages = undefined
+ this.offset = undefined
+ this.puzzles = undefined
+ this.puzzlesTab = undefined
+ this.mapScale = undefined
+ this.newPuzzlesTab = undefined
+ }
+
+ onDisable(){
+ this.initVariables()
+ }
+}
+
+module.exports = {
+ class: new DungeonMap()
+}
\ No newline at end of file
diff --git a/features/dungeonMap/metadata.json b/features/dungeonMap/metadata.json
new file mode 100644
index 0000000..2d0df77
--- /dev/null
+++ b/features/dungeonMap/metadata.json
@@ -0,0 +1,8 @@
+{
+ "name": "Dungeon Map",
+ "description": "A really good dungeon map",
+ "isHidden": false,
+ "isTogglable": true,
+ "defaultEnabled": true,
+ "sortA": 1
+}
\ No newline at end of file
diff --git a/features/dungeonSolvers/index.js b/features/dungeonSolvers/index.js
new file mode 100644
index 0000000..5ca1ed5
--- /dev/null
+++ b/features/dungeonSolvers/index.js
@@ -0,0 +1,153 @@
+///
+///
+import Feature from "../../featureClass/class";
+import * as renderUtils from "../../utils/renderUtils";
+import HudTextElement from "../hud/HudTextElement";
+import LocationSetting from "../settings/settingThings/location";
+import ToggleSetting from "../settings/settingThings/toggle";
+
+class DungeonSolvers extends Feature {
+ constructor() {
+ super()
+ }
+
+ onEnable(){
+ this.initVariables()
+
+ this.lividData = {}
+ this.lividData.lividColor = {
+ "Vendetta": "&f",
+ "Crossed": "&d",
+ "Hockey": "&c",
+ "Doctor": "&7",
+ "Frog": "&2",
+ "Smile": "&a",
+ "Scream": "&1",
+ "Purple": "&5",
+ "Arcade": "&e"
+ }
+ this.onWorldLoad()
+
+ this.lividFindEnabled = new ToggleSetting("Correct livid finder", "Finds the real livid to kill in the f5 boss fight", true, "livid_find_enabled", this)
+ this.lividFindHud = new ToggleSetting("Show Livid Hp", "Shows the nametag of the correct livid", true, "livid_hud_enabled", this).requires(this.lividFindEnabled)
+ this.lividHpElement = new HudTextElement()
+ .setToggleSetting(this.lividFindHud)
+ .setLocationSetting(new LocationSetting("Correct Livid Hp Location", "Allows you to edit the location of the correct livid hp text", "livid_hp_location", this, [10, 50, 1, 1])
+ .requires(this.lividFindHud)
+ .editTempText("§r§e﴾ §c§lLivid§r §a7M§c❤ §e﴿§r"))
+
+ this.lividFindChat = new ToggleSetting("Say correct livid in chat", "Sends the correct livid in chat", false, "livid_chat_enabled", this).requires(this.lividFindEnabled)
+ this.lividFindBox = new ToggleSetting("Put a box around the correct livid", "This helps to locate it in the group", true, "livid_box_enabled", this).requires(this.lividFindEnabled)
+ this.lividFindNametags = new ToggleSetting("Hide the nametags of incorrect livids", "This helps to locate it in the group", true, "livid_nametags_enabled", this).requires(this.lividFindEnabled)
+
+ this.hudElements.push(this.lividHpElement)
+
+ this.registerStep(true, 2, this.step)
+ this.registerEvent("worldLoad", this.onWorldLoad)
+
+ this.registerEvent("renderOverlay", this.renderHud)
+ this.registerEvent("renderWorld", this.renderWorld)
+ this.registerEvent("renderEntity", this.renderEntity)
+ }
+
+ renderWorld(ticks){
+ if(this.lividFindBox.getValue()){
+ if(this.lividData.correctLividEntity){
+ renderUtils.drawBoxAtEntity(this.lividData.correctLividEntity, 255, 0, 0, 0.75, -2, ticks)
+ }
+ }
+ }
+
+ renderEntity(entity, position, ticks, event){
+ if(this.lividFindNametags.getValue()){
+ if(this.lividData.correctLividEntity){
+ if(entity.getName().includes("Livid") && entity.getName().includes("❤") && entity.getUUID() !== this.lividData.correctLividEntity.getUUID()){
+ cancel(event)
+ }
+ }
+ }
+ }
+
+ renderHud(){
+ for(let element of this.hudElements){
+ element.render()
+ }
+ }
+
+ onWorldLoad(){
+ this.lividData.correctLividColor = undefined
+ this.lividData.correctLividColorHP = undefined
+ this.lividData.sayLividColors = []
+ this.lividData.sayLividColors2 = []
+ this.lividData.correctLividEntity = undefined
+ this.lividHpElement && this.lividHpElement.setText("")
+ }
+
+ step(){ //2fps
+ if(this.lividFindEnabled.getValue() && (this.FeatureManager.features["dataLoader"].class.dungeonFloor === "F5")){ //TODO: fix on M5
+ World.getAllEntities().forEach(entity => {
+ let entityName = entity.getName()
+ if (/(?:Vendetta|Crossed|Hockey|Doctor|Frog|Smile|Scream|Purple|Arcade) Livid/g.test(entityName)) {
+ let lividName = entityName.replace(" Livid", "")
+
+ if (!this.lividData.sayLividColors2.includes(lividName)) {
+ this.lividData.sayLividColors2.push(lividName)
+ if (this.lividData.sayLividColors2.length === 1) {
+ this.lividData.correctLividColor = lividName
+ }
+ if (this.lividData.sayLividColors2.length === 9) {
+ if(this.lividFindChat.getValue()){
+ ChatLib.chat("Correct livid is: " + this.lividData.lividColor[lividName] + lividName)
+ }
+ this.lividData.correctLividColor = lividName
+ }
+ }
+ return;
+ }
+ if (entityName.includes("Livid") && entityName.includes("❤")) {
+ if (!this.lividData.sayLividColors.includes(entityName.substr(0, 3))) {
+ this.lividData.sayLividColors.push(entityName.substr(0, 3))
+ if (this.lividData.sayLividColors.length === 9) {
+ this.lividData.correctLividColorHP = entityName.substr(0, 3)
+ }
+ if (this.lividData.sayLividColors.length === 1) {
+ this.lividData.correctLividColorHP = entityName.substr(0, 3)
+ }
+ }
+
+ if (this.lividData.sayLividColors.length === 1) {
+ if (entityName.includes("Livid") && entityName.includes("❤")) {
+ this.lividHpElement.setText(entityName)
+ }
+ } else {
+ if (this.lividData.correctLividColorHP !== undefined) {
+ // if (this.lividData.correctLividColor === "Arcade") {
+ // this.lividHpElement.setText("Unknown Health (Yellow Livid)")
+ // } else {
+ if (entityName.includes(this.lividData.correctLividColorHP)) {
+ this.lividHpElement.setText(entityName)
+ this.lividData.correctLividEntity = entity
+ }
+ // }
+ }
+ }
+
+ }
+ })
+ }
+ }
+
+ initVariables(){
+ this.lividFindEnabled = undefined
+ this.lividData = undefined
+ this.hudElements = []
+ }
+
+ onDisable(){
+ this.initVariables()
+ }
+}
+
+module.exports = {
+ class: new DungeonSolvers()
+}
\ No newline at end of file
diff --git a/features/dungeonSolvers/metadata.json b/features/dungeonSolvers/metadata.json
new file mode 100644
index 0000000..6467a3a
--- /dev/null
+++ b/features/dungeonSolvers/metadata.json
@@ -0,0 +1,8 @@
+{
+ "name": "Dungeon Solvers",
+ "description": "Solvers for dungeon things",
+ "isHidden": false,
+ "isTogglable": true,
+ "defaultEnabled": true,
+ "sortA": 1
+}
\ No newline at end of file
diff --git a/features/events/index.js b/features/events/index.js
new file mode 100644
index 0000000..24615e4
--- /dev/null
+++ b/features/events/index.js
@@ -0,0 +1,463 @@
+///
+///
+import Feature from "../../featureClass/class";
+import { drawBoxAtBlock, drawBoxAtBlockNotVisThruWalls, drawLine } from "../../utils/renderUtils";
+import { calculateDistance, calculateDistanceQuick, fastestPathThrough } from "../../utils/utils";
+import HudTextElement from "../hud/HudTextElement";
+import LocationSetting from "../settings/settingThings/location";
+import ToggleSetting from "../settings/settingThings/toggle";
+
+class Events extends Feature {
+ constructor() {
+ super()
+ }
+
+ onEnable(){
+ this.initVariables()
+
+ this.burrialData = {
+ points: [],
+ locations: [],
+ historicalLocations: []
+ }
+ this.lastRequestTime = 0
+ this.nextUpdateApprox = -1
+ this.lastRequest = 0
+ this.potentialParticleLocs = {}
+ this.showingWaypoints = false
+ this.lastPath = []
+ this.updatingPath = false
+ this.hudElements = []
+ this.lastPathCords = undefined
+
+ this.burrialWaypointsEnabled = new ToggleSetting("Burrial waypoints", "Show waypoints for burrials during the diana event", true, "burrial_waypoints", this)
+ this.burrialWaypointsPath = new ToggleSetting("Pathfind waypoints", "Calculate a path thru all the waypoints", true, "burrial_waypoints_path", this).requires(this.burrialWaypointsEnabled)
+ this.burrialWaypointsNearest = new ToggleSetting("Show nearest using pathfinding", "Use pathfinding to highlight the next burrial instead of disance", true, "burrial_nearest_path", this).requires(this.burrialWaypointsEnabled)
+
+ this.updateTimerEnabled = new ToggleSetting("Show API update timer", "Shows a countdown till the burrial waypoints will be next updated", true, "burrial_timer", this).requires(this.burrialWaypointsEnabled)
+ this.updateTimer = new HudTextElement()
+ .setToggleSetting(this.updateTimerEnabled)
+ .setLocationSetting(new LocationSetting("Timer Location", "Allows you to edit the location of the timer", "burrial_timer_location", this, [10, 50, 1, 1])
+ .requires(this.burrialWaypointsEnabled)
+ .editTempText("&6Update&7> &f100s"))
+ this.hudElements.push(this.updateTimer)
+
+ this.registerEvent("worldLoad", this.worldLoad)
+ this.registerEvent("spawnParticle", this.spawnParticle)
+ this.registerEvent("renderWorld", this.renderWorld)
+ this.registerEvent("renderOverlay", this.renderOverlay)
+ this.registerStep(true, 2, this.step)
+ this.registerStep(false, 5, this.step_5s)
+ this.registerSoopy("apiLoad", this.apiLoad)
+ }
+
+ renderOverlay(){
+ for(let element of this.hudElements){
+ element.render()
+ }
+ }
+
+ renderWorld(ticks){
+ if(this.showingWaypoints && this.lastPathCords && this.burrialWaypointsPath.getValue()){
+ let startPoint = [Player.getPlayer().field_70142_S+Player.getPlayer().field_70159_w*ticks,
+ Player.getPlayer().field_70137_T+Player.getPlayer().field_70181_x*ticks,
+ Player.getPlayer().field_70136_U+Player.getPlayer().field_70179_y*ticks]
+
+ let lastPoint = startPoint || [0,0,0]
+
+ this.lastPathCords.forEach((point)=>{
+ drawLine(...lastPoint,...point,255,255,0)
+
+ lastPoint = point
+ })
+ }
+ if(this.showingWaypoints){
+ let sorted = [...this.burrialData.locations]
+ sorted.sort((a,b)=>{
+ let aDist = calculateDistanceQuick([Player.getX(),Player.getY(),Player.getZ()],[a.x+0.5,a.y+2.5,a.z+0.5])
+ let bDist = calculateDistanceQuick([Player.getX(),Player.getY(),Player.getZ()],[b.x+0.5,b.y+2.5,b.z+0.5])
+
+ return bDist-aDist
+ })
+ sorted.forEach((loc,i)=>{
+
+ let typeReplace = [
+ "Start",
+ "Mob",
+ "Treasure",
+ "Finish",
+ "Unknown"
+ ]
+ if(!loc.clicked){
+ blue = false
+ if(loc.lastPing && Date.now()-loc.lastPing < 500){
+ blue = true
+ }
+ drawBoxAtBlock(loc.x, loc.y,loc.z,0,blue?100:255,blue?255:0)
+ }
+ if(loc.fromApi){
+ Tessellator.drawString(
+ "(" + (loc.chain+1) + "/4) " + typeReplace[loc.type] + " BURRIAL (" + Math.round(calculateDistance([Player.getX(),Player.getY(),Player.getZ()],[loc.x+0.5,loc.y+2.5,loc.z+0.5])) + "m)",
+ loc.x+0.5,
+ loc.y+1.5,
+ loc.z+0.5,
+ loc.clicked? 65280:(loc.nearest?16711680:6579300), true, loc.clicked? 0.04:(loc.nearest?1:0.5), !loc.clicked
+ );
+ }else{
+ Tessellator.drawString(
+ typeReplace[loc.type] + " BURRIAL (" + Math.round(calculateDistance([Player.getX(),Player.getY(),Player.getZ()],[loc.x+0.5,loc.y+2.5,loc.z+0.5])) + "m)",
+ loc.x+0.5,
+ loc.y+1.5,
+ loc.z+0.5,
+ loc.clicked? 65280:(loc.nearest?16711680:6579300), true, loc.clicked? 0.04:(loc.nearest?1:0.5), !loc.clicked
+ );
+ }
+ })
+ }
+ }
+
+ step(){
+
+ hasDianaShovle = false
+ let slots = [0, 1, 2, 3, 4, 5, 6, 7, 8]
+
+ slots.forEach(a=>{
+ item = Player.getInventory().getStackInSlot(a)
+ if(ChatLib.removeFormatting(item.getName()) === "Ancestral Spade"){
+ hasDianaShovle = true
+ }
+ })
+
+ let showingWaypointsNew = hasDianaShovle && this.FeatureManager.features["dataLoader"].class.area === "Hub" && this.burrialWaypointsEnabled.getValue()
+
+ if(!this.showingWaypoints && showingWaypointsNew){
+ this.loadApi()
+ }else{
+ if(Date.now()-this.nextUpdateApprox > 0 && this.nextUpdateApprox > 0 && Date.now()-this.lastRequest>5000){
+ this.nextUpdateApprox = -2
+ this.loadApi()
+ }
+ }
+
+ this.showingWaypoints = showingWaypointsNew
+
+ if(this.showingWaypoints){
+
+ this.updateTimer.setText("&6Update&7> &f" + (this.nextUpdateApprox===-1?"Updating...":(this.nextUpdateApprox===-2?"Loading...":Math.ceil((this.nextUpdateApprox-Date.now())/1000) + "s")))
+ }else{
+ this.updateTimer.setText("")
+ }
+
+ }
+ step_5s(){
+ if(this.showingWaypoints){
+ if(this.burrialWaypointsPath.getValue() || this.burrialWaypointsNearest.getValue()){
+ new Thread(()=>{
+ this.updateBurrialPath()
+ }).start()
+ }
+ }
+ }
+
+ worldLoad(){
+ this.burrialData.points = []
+ this.burrialData.locations = []
+ this.burrialData.historicalLocations = []
+
+ this.showingWaypoints = false
+ }
+
+ loadApi(){
+ new Thread(()=>{
+ this.FeatureManager.features["dataLoader"].class.loadApiData("skyblock", false)
+ }).start()
+ }
+
+ apiLoad(data, dataType, isSoopyServer, isLatest){
+ if(!this.showingWaypoints) return;
+ if(isSoopyServer || dataType !== "skyblock" || !isLatest) return
+ this.lastRequest = Date.now()
+
+ let profileData = data.profiles[0].members[Player.getUUID().toString().replace(/-/g,"")]
+
+ data.profiles.forEach((prof)=>{
+ if((prof.members[Player.getUUID().toString().replace(/-/g,"")].last_save || 0) > (profileData.last_save || 0)){
+ profileData = prof.members[Player.getUUID().toString().replace(/-/g,"")]
+ }
+ })
+ this.nextUpdateApprox = profileData.last_save+173000
+ this.nextUpdateApprox += 2000 //incase ur pc time is behind
+ if(profileData.last_save === this.lastRequestTime){
+ return
+ }
+ this.lastRequestTime = profileData.last_save
+
+ let locsAccessed = []
+ let newLocs = []
+ profileData.griffin.burrows.forEach((burrow)=>{
+ let pushed = false
+ this.burrialData.locations.forEach((loc, i)=>{
+ if((loc.fromApi || loc.clicked) && loc.x + "," + loc.y + "," + loc.z === burrow.x + "," + burrow.y + "," + burrow.z){
+ newLocs.push(loc)
+ pushed = true
+ locsAccessed.push(i)
+ }
+ })
+ this.burrialData.historicalLocations.forEach((loc)=>{
+ if(loc.x + "," + loc.y + "," + loc.z === burrow.x + "," + burrow.y + "," + burrow.z){
+ pushed = true
+ }
+ })
+ if(!pushed){
+ burrow.clicked = false
+ burrow.fromApi = true
+ newLocs.push(burrow)
+ }
+ })
+
+ this.burrialData.locations.forEach((loc)=>{
+ if(!loc.fromApi){
+ let found = false
+ newLocs.forEach((burrow)=>{
+ if(loc.x + "," + loc.y + "," + loc.z === burrow.x + "," + burrow.y + "," + burrow.z){
+ found = true
+ }
+ })
+
+ if(!found){
+ newLocs.push(loc)
+ }
+ }
+ })
+
+ this.burrialData.locations = newLocs
+ this.updateBurrialPath()
+ }
+
+
+ spawnParticle(particle, type, event){
+ if(this.showingWaypoints){
+ let foundEnchant = false
+ let foundCrit = false
+ let foundStep = false
+ let isMob = undefined
+
+ if(particle.toString().startsWith('EntityEnchantmentTableParticleFX, ')){
+ foundEnchant = true
+ }
+ else if(particle.toString().startsWith('EntityCrit2FX, ')){
+ foundCrit = true
+
+ isMob = particle.getUnderlyingEntity().func_70534_d() > 0.5 //mob)
+ }
+ else if(particle