commit 64c060edb554a90043897eb07732b75efada1a6c Author: Flummi Date: Sun Jun 4 13:24:56 2023 +0200 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..896dca7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# gradle + +.gradle/ +build/ +out/ +classes/ +logs/ + +# eclipse + +*.launch + +# idea + +.idea/ +*.iml +*.ipr +*.iws + +# vscode + +.settings/ +.vscode/ +bin/ +.classpath +.project + +# macos + +*.DS_Store + +# fabric + +run/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..eaef946 --- /dev/null +++ b/build.gradle @@ -0,0 +1,80 @@ +plugins { + id 'fabric-loom' version '1.2-SNAPSHOT' + id 'maven-publish' +} + +version = "${project.mod_version}+${project.minecraft_version}" +group = project.maven_group + +repositories { + // Add repositories to retrieve artifacts from in here. + // You should only use this when depending on other mods because + // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html + // for more information about repositories. +} + +dependencies { + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + + // Fabric API. This is technically optional, but you probably want it anyway. + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" +} + +base { + archivesName = project.archives_base_name +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +tasks.withType(JavaCompile).configureEach { + // ensure that the encoding is set to UTF-8, no matter what the system default is + // this fixes some edge cases with special characters not displaying correctly + // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html + // If Javadoc is generated, this must be specified in that task too. + + + // Minecraft 1.18 upwards uses Java 17. + it.options.release = 17 +} + +java { + // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task + // if it is present. + // If you remove this line, sources will not be generated. + withSourcesJar() + + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + +jar { + from("LICENSE") { + rename { "${it}_${base.archivesName.get()}"} + } +} + +// configure the maven publication +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + // Notice: This block does NOT have the same function as the block in the top level. + // The repositories here will be used for publishing your artifact, not for + // retrieving dependencies. + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..7825b5e --- /dev/null +++ b/gradle.properties @@ -0,0 +1,17 @@ +# Done to increase the memory available to gradle. +org.gradle.jvmargs=-Xmx1G +org.gradle.parallel=true + +# Fabric Properties +# check these on https://fabricmc.net/develop +minecraft_version=1.19.4 +yarn_mappings=1.19.4+build.2 +loader_version=0.14.20 + +# Mod Properties +mod_version = 1.0.0 +maven_group = lel.flummi +archives_base_name = skilloverlay + +# Dependencies +fabric_version=0.79.0+1.19.4 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..c1962a7 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..37aef8d --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +networkTimeout=10000 +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..aeb74cb --- /dev/null +++ b/gradlew @@ -0,0 +1,245 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..b02216b --- /dev/null +++ b/settings.gradle @@ -0,0 +1,10 @@ +pluginManagement { + repositories { + maven { + name = 'Fabric' + url = 'https://maven.fabricmc.net/' + } + mavenCentral() + gradlePluginPortal() + } +} diff --git a/src/main/java/lel/flummi/skilloverlay/api/PlayerProfile.java b/src/main/java/lel/flummi/skilloverlay/api/PlayerProfile.java new file mode 100644 index 0000000..1dabb91 --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/api/PlayerProfile.java @@ -0,0 +1,52 @@ +package lel.flummi.skilloverlay.api; + +import net.minecraft.client.MinecraftClient; + +import lel.flummi.skilloverlay.api.records.PlayerProfiles; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.io.InputStreamReader; +import java.net.URL; +import java.util.Timer; +import java.util.TimerTask; + +public class PlayerProfile { + public static PlayerProfiles.PlayerProfile PROFILE; + + public static void init() { + Timer timer = new Timer(); + timer.schedule(new TimerTask() { + @Override + public void run() { + PlayerProfiles profiles = PlayerProfile.updateProfile(); + + PlayerProfiles.PlayerProfile currentProfile = profiles.profiles().get(""); + + for (PlayerProfiles.PlayerProfile profile: profiles.profiles().values()) { + if(profile.current() == true) { + currentProfile = profile; + } + } + + PROFILE = currentProfile; + } + }, 0, 60 * 1000); + } + + public static PlayerProfiles updateProfile() { + try { + URL url = new URL("https://sky.shiiyu.moe/api/v2/profile/" + MinecraftClient.getInstance().getSession().getUsername()); + InputStreamReader reader = new InputStreamReader(url.openStream()); + Gson gson = new GsonBuilder() + .serializeNulls() + .create(); + return gson.fromJson(reader, PlayerProfiles.class); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/src/main/java/lel/flummi/skilloverlay/api/records/Enchanting.java b/src/main/java/lel/flummi/skilloverlay/api/records/Enchanting.java new file mode 100644 index 0000000..fe1a41d --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/api/records/Enchanting.java @@ -0,0 +1,26 @@ +package lel.flummi.skilloverlay.api.records; + +import com.google.gson.annotations.SerializedName; + +import java.util.HashMap; + +public record Enchanting(boolean experimented, HashMap experiments){ + public record Experiment( + String name, + Stats stats, + Tier[] tiers + + ){ + public record Stats( + @SerializedName("last_attempt") PlayerProfiles.PlayerProfile.Data.LastUpdated lastAttempt, + @SerializedName("bonus_clicks") int bonusClicks, + @SerializedName("last_claimed") PlayerProfiles.PlayerProfile.Data.LastUpdated lastClaimed + ){} + public record Tier( + String name, + int attempts, + int claims, + @SerializedName("best_score") int bestScore + ){} + } +} diff --git a/src/main/java/lel/flummi/skilloverlay/api/records/Farming.java b/src/main/java/lel/flummi/skilloverlay/api/records/Farming.java new file mode 100644 index 0000000..0496d17 --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/api/records/Farming.java @@ -0,0 +1,30 @@ +package lel.flummi.skilloverlay.api.records; + +import com.google.gson.annotations.SerializedName; + +import java.util.HashMap; + +public record Farming( + boolean talked, + @SerializedName("current_badges") Badges currentBadges, + @SerializedName("total_badges") Badges totalBadges, + Perks perks, + @SerializedName("unique_golds") int unique_golds, + HashMap crops, + Contests contests +){ + public record Badges(int bronze, int silver, int gold){} + public record Perks(@SerializedName("double_drops") int doubleDrops, @SerializedName("farming_level_cap") int farmingLevelCap){} + public record Crop( + String name, + boolean attended, + @SerializedName("unique_gold") boolean uniqueGold, + int contests, + @SerializedName("personal_best") int personalBest, + Badges badges + ){} + public record Contests(@SerializedName("attended_contests") int attendedContests, @SerializedName("all_contests") Contest[] allContests){} + public record Contest(String date, String crop, int collected, boolean claimed, String medal, Placing placing){ + public record Placing(int position, double percentage){} + } +} diff --git a/src/main/java/lel/flummi/skilloverlay/api/records/Items.java b/src/main/java/lel/flummi/skilloverlay/api/records/Items.java new file mode 100644 index 0000000..f8ea01d --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/api/records/Items.java @@ -0,0 +1,52 @@ +package lel.flummi.skilloverlay.api.records; + +import com.google.gson.annotations.SerializedName; + +import java.util.HashMap; + +public record Items( + Item[] armor, + Item[][] wardrobe, + Item[] inventory, + Item[] enderchest, + @SerializedName("talisman_bag") Item[] talismanBag, + @SerializedName("fishing_bag") Item[] fishingBag, + Item[] quiver, + @SerializedName("potion_bag") Item[] potionBag, + @SerializedName("personal_vault") Item[] personalVault, + Item[] storage, + Item[] weapons, + Item[] hoes, + Item[] pickaxes, + Item[] rods, + @SerializedName("highest_rarity_sword") Item highestRaritySword, + @SerializedName("highest_rarity_bow") Item highestRarityBow, + @SerializedName("highest_rarity_rod") Item highestRarityRod, + @SerializedName("armor_set_rarity") String armorSetRarity +){ + public record Item( + @SerializedName("Count") byte count, + int damage, + Tag tag, + boolean isInactive, + boolean inBackpack, + Item[] containsItems + ){ + public record Tag( + @SerializedName("ExtraAttributes") ExtraAttributes extraAttributes, + Display display, + @SerializedName("SkullOwner") SkullOwner skullOwner, + Enchant[] ench + ){ + public record ExtraAttributes(String id, HashMap enchantments){} + public record Display(@SerializedName("Name") String name, @SerializedName("Lore") String[] lore, Integer color){} + public record SkullOwner( + @SerializedName("Id") String id, + @SerializedName("Properties") Properties properties + ){ + public record Properties(HashMap[] textures){} + } + public record Enchant(int lvl, int id){} + } + } +} \ No newline at end of file diff --git a/src/main/java/lel/flummi/skilloverlay/api/records/PlayerProfiles.java b/src/main/java/lel/flummi/skilloverlay/api/records/PlayerProfiles.java new file mode 100644 index 0000000..8f26659 --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/api/records/PlayerProfiles.java @@ -0,0 +1,164 @@ +package lel.flummi.skilloverlay.api.records; + +import lel.flummi.skilloverlay.api.records.dungeons.Dungeons; +import lel.flummi.skilloverlay.api.records.mining.Mining; +import lel.flummi.skilloverlay.api.records.misc.Misc; + +import com.google.gson.annotations.SerializedName; +import java.util.HashMap; + +public record PlayerProfiles(HashMap profiles) { + public record PlayerProfile( + @SerializedName("profile_id") String profileId, + @SerializedName("cute_name") String cuteName, + boolean current, + @SerializedName("last_save") long lastSave, + Items items, + Data data) { + public record Data( + Stats stats, + @SerializedName("fairy_bonus") Stats fairyBonus, + @SerializedName("fairy_souls") FairySouls fairySouls, + @SerializedName("levels") HashMap skills, + @SerializedName("average_level") double averageLevel, + @SerializedName("average_level_no_progress") double trueAverageLevel, + @SerializedName("total_skill_xp") double totalSkillXp, + @SerializedName("skill_bonus") HashMap skillBonus, + @SerializedName("average_level_rank") double averageLevelRank, + @SerializedName("slayer_coins_spent") HashMap slayerCoinsSpent, + @SerializedName("slayer_bonus") HashMap slayerBonus, + HashMap slayers, + @SerializedName("slayer_xp") int slayerXp, + @SerializedName("display_name") String username, + String uuid, + double bank, + double purse, + @SerializedName("current_area") String currentArea, + Entity[] kills, + Entity[] deaths, + @SerializedName("wardrobe_equipped_slot") int wardrobeEquippedSlot, + @SerializedName("skin_data") SkinData skinData, + Profile profile, + Member[] members, + Minion[] minions, + @SerializedName("minion_slots") MinionSlots minionSlots, + HashMap collections, + Social social, + Dungeons dungeons, + Fishing fishing, + Farming farming, + Enchanting Enchanting, + Mining mining, + Misc misc, + @SerializedName("auctions_bought") Auctions auctionsBought, + @SerializedName("auctions_sold") Auctions auctionsSold, + @SerializedName("last_updated") LastUpdated lastUpdated, + @SerializedName("first_join") LastUpdated firstJoin + ) { + public record Stats( + int health, + int defense, + @SerializedName("effective_health") int effectiveHealth, + int strength, + int speed, + @SerializedName("crit_chance") double critChance, + @SerializedName("crit_damage") int critDamage, + @SerializedName("bonus_attack_speed") int bonusAttackSpeed, + int intelligence, + @SerializedName("sea_creature_chance") int seaCreatureChance, + @SerializedName("magic_find") int magicFind, + @SerializedName("pet_luck") int petLuck, + int ferocity, + @SerializedName("ability_damage") double abilityDamage, + @SerializedName("mining_speed") int miningSpeed, + @SerializedName("mining_fortune") int miningFortune, + @SerializedName("farming_fortune") int farmingFortune, + @SerializedName("foraging_fortune") int foragingFortune, + int pristine, + int damage, + @SerializedName("damage_increase") double damageIncrease) { + } + + public record FairySouls(int collected, int total, double progress) { + } + + public record Level( + Double xp, + Integer level, + Integer maxLevel, + Long xpCurrent, + Integer xpForNext, + Double progress, + Integer levelCap, + Integer uncappedLevel, + Integer rank, + Double levelWithProgress, + Double unlockableLevelWithProgress) { + } + + public record Entity(String type, String entityId, int amount, String entityName) { + } + + public record SkinData(@SerializedName("skinurl") String skinUrl, String model) { + } + + public record Profile(String gamemode) { + } + + public record Member( + String uuid, + @SerializedName("display_name") String displayName, + @SerializedName("last_updated") LastUpdated lastUpdated, + @SerializedName("skin_data") SkinData skinData) { + } + + public record LastUpdated(long unix, String text) { + } + + public record Minion( + String id, + String type, + int tiers, + String name, + Integer[] levels + + ) { + } + + public record MinionSlots(int currentSlots, int toNext, int toNextSlot) { + } + + public record Collection(int tier, long amount, long totalAmount, UserAmount[] amounts) { + public record UserAmount(String username, long amount) { + } + } + + public record Social( + @SerializedName("DISCORD") String discord, + @SerializedName("HYPIXEL") String hypixel, + @SerializedName("TWITTER") String twitter, + @SerializedName("YOUTUBE") String youtube, + @SerializedName("INSTAGRAM") String instagram, + @SerializedName("TWITCH") String twitch) { + } + + public record Fishing( + int total, + int treasure, + @SerializedName("treasure_large") int treasureLarge, + @SerializedName("shredder_fished") int shredderFished, + @SerializedName("shredder_bait") int shredderBait) { + } + + public record Auctions( + int uncommon, + int rare, + int epic, + int common, + int legendary, + int special) { + } + } + + } +} \ No newline at end of file diff --git a/src/main/java/lel/flummi/skilloverlay/api/records/Slayer.java b/src/main/java/lel/flummi/skilloverlay/api/records/Slayer.java new file mode 100644 index 0000000..3b2b9bb --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/api/records/Slayer.java @@ -0,0 +1,29 @@ +package lel.flummi.skilloverlay.api.records; + +import com.google.gson.annotations.SerializedName; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; + +public record Slayer( + PlayerProfiles.PlayerProfile.Data.Level level, + Kills kills, + @SerializedName("claimed_levels") ClaimedLevels claimedLevels, + int xp, + @SerializedName("boss_kills_tier_0") int bossKillsTier0, + @SerializedName("boss_kills_tier_1") int bossKillsTier1, + @SerializedName("boss_kills_tier_2") int bossKillsTier2, + @SerializedName("boss_kills_tier_3") int bossKillsTier3 +){ + public record Kills(@Nullable HashMap kills){} + public record ClaimedLevels( + @SerializedName("level_1") boolean level1, + @SerializedName("level_2") boolean level2, + @SerializedName("level_3") boolean level3, + @SerializedName("level_4") boolean level4, + @SerializedName("level_5") boolean level5, + @SerializedName("level_6") boolean level6, + @SerializedName("level_7_special") boolean level7 + ){} + +} diff --git a/src/main/java/lel/flummi/skilloverlay/api/records/dungeons/Dungeons.java b/src/main/java/lel/flummi/skilloverlay/api/records/dungeons/Dungeons.java new file mode 100644 index 0000000..c189e90 --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/api/records/dungeons/Dungeons.java @@ -0,0 +1,40 @@ +package lel.flummi.skilloverlay.api.records.dungeons; + +import com.google.gson.annotations.SerializedName; +import lel.flummi.skilloverlay.api.records.PlayerProfiles; + +import java.util.HashMap; + +public record Dungeons( + Dungeon catacombs, + @SerializedName("master_catacombs") Dungeon masterCatacombs, + HashMap classes, + @SerializedName("used_classes") boolean usedClasses, + @SerializedName("selected_class") String selectedClass, + @SerializedName("secrets_found") int secretsFound, + HashMap essence, + @SerializedName("unlocked_collections") boolean unlockedCollections, + @SerializedName("boss_collections") HashMap bossCollections + //Journals journals + +){ + public record Dungeon( + String id, + boolean visited, + PlayerProfiles.PlayerProfile.Data.Level level, + @SerializedName("highest_floor") String highestFloor, + HashMap floors + + ){} + public record Collection( + String name, + String texture, + int tier, + boolean maxed, + int killed, + HashMap floors, + int unclaimed, + String[] claimed + ){} + public record Class(PlayerProfiles.PlayerProfile.Data.Level experience, boolean current){} +} diff --git a/src/main/java/lel/flummi/skilloverlay/api/records/dungeons/Floor.java b/src/main/java/lel/flummi/skilloverlay/api/records/dungeons/Floor.java new file mode 100644 index 0000000..a28304c --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/api/records/dungeons/Floor.java @@ -0,0 +1,44 @@ +package lel.flummi.skilloverlay.api.records.dungeons; + +import com.google.gson.annotations.SerializedName; + +public record Floor( + String name, + Stats stats, + @SerializedName("most_damage") MostDamage mostDamage, + Bonuses bonuses + +){ + public record Stats( + @SerializedName("times_played") int timesPlayed, + @SerializedName("best_score") int bestScore, + @SerializedName("mobs_killed") int mobsKilled, + @SerializedName("most_mobs_killed") int mostMobsKilled, + @SerializedName("most_healing") double mostHealing, + @SerializedName("tier_completions") int tierCompletions, + @SerializedName("fastest_time") long fastestTime, + @SerializedName("watcher_kills") int watcherKills, + @SerializedName("best_runs") Run[] bestRuns + ){} + public record MostDamage( + @SerializedName("class") String classUsed, + @SerializedName("value") double damage + ){} + public record Run( + long timestamp, + @SerializedName("score_exploration") int scoreExploration, + @SerializedName("score_speed") int scoreSpeed, + @SerializedName("score_skill") int scoreSkill, + @SerializedName("score_bonus") int scoreBonus, + @SerializedName("dungeon_class") int dungeonClass, + String[] teammates, + @SerializedName("elapsed_time") long elapsedTime, + @SerializedName("damaged_dealt") int damageDealt, + int deaths, + @SerializedName("mobs_killed") int mobsKilled, + @SerializedName("secrets_found") int secretsFound, + @SerializedName("damage_mitigated") double damageMitigated, + @SerializedName("ally_healing") int allyHealing + ){} + public record Bonuses(@SerializedName("item_boost") int itemBoost){} +} diff --git a/src/main/java/lel/flummi/skilloverlay/api/records/dungeons/Journals.java b/src/main/java/lel/flummi/skilloverlay/api/records/dungeons/Journals.java new file mode 100644 index 0000000..22ed2ad --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/api/records/dungeons/Journals.java @@ -0,0 +1,18 @@ +package lel.flummi.skilloverlay.api.records.dungeons; + +import com.google.gson.annotations.SerializedName; + +public record Journals( + @SerializedName("pages_completed") int pagesCompleted, + @SerializedName("journals_completed") int journalsCompleted, + @SerializedName("total_pages") Integer totalPages, + boolean maxed, + @SerializedName("journal_entries") Entry[] journalEntries + +){ + public record Entry( + String name, + @SerializedName("pages_collected") int pagesCollected, + @SerializedName("total_pages") Integer totalPages + ){} +} diff --git a/src/main/java/lel/flummi/skilloverlay/api/records/mining/Core.java b/src/main/java/lel/flummi/skilloverlay/api/records/mining/Core.java new file mode 100644 index 0000000..924e6c1 --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/api/records/mining/Core.java @@ -0,0 +1,41 @@ +package lel.flummi.skilloverlay.api.records.mining; + +import com.google.gson.annotations.SerializedName; +import lel.flummi.skilloverlay.api.records.PlayerProfiles; + +import java.util.HashMap; + +public record Core( + PlayerProfiles.PlayerProfile.Data.Level tier, + Spent tokens, + @SerializedName("selected_pickaxe_ability") String selectedMiningAbility, + HashMap powder, + @SerializedName("crystal_nucleus") Nucleus crystalNucleus, + @SerializedName("daily_ores") DailyOres dailyOres, + @SerializedName("hotm_last_reset") long hotmLastReset, + @SerializedName("crystal_hollows_last_access") long crystalHollowsLastAccess +){ + public record Spent(int total, int spent, int available){} + public record Nucleus( + @SerializedName("times_completed") int timesCompleted, + HashMap crystals, + Goblin goblin + ){ + public record Crystal( + String state, + @SerializedName("total_placed") int totalPlaced, + @SerializedName("total_found") int totalFound + ){} + public record Goblin( + @SerializedName("king_quest_active") boolean kingQuestActive, + @SerializedName("king_quest_completed") boolean kingQuestCompleted + ){} + } + public record DailyOres( + int mined, + int day, + @SerializedName("daily_ores") HashMap dailyOres + ){ + public record Ore(int day, int count){} + } +} diff --git a/src/main/java/lel/flummi/skilloverlay/api/records/mining/Mining.java b/src/main/java/lel/flummi/skilloverlay/api/records/mining/Mining.java new file mode 100644 index 0000000..c82b2e9 --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/api/records/mining/Mining.java @@ -0,0 +1,18 @@ +package lel.flummi.skilloverlay.api.records.mining; + +public record Mining( + Commissions commissions, + Forge forge, + Core core +){ + public record Forge(Process[] processes){ + public record Process( + String id, + int slot, + long timeFinished, + String timeFinishedText, + String name + ){} + } + public record Commissions(int milestone){} +} diff --git a/src/main/java/lel/flummi/skilloverlay/api/records/misc/Burrows.java b/src/main/java/lel/flummi/skilloverlay/api/records/misc/Burrows.java new file mode 100644 index 0000000..60ae510 --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/api/records/misc/Burrows.java @@ -0,0 +1,19 @@ +package lel.flummi.skilloverlay.api.records.misc; + +import com.google.gson.annotations.SerializedName; + +public record Burrows( + @SerializedName("dug_next") Rarities dugNext, + @SerializedName("dug_combat") Rarities dugCombat, + @SerializedName("dug_treasure") Rarities dugTreasure, + @SerializedName("chains_complete") Rarities chainsComplete +){ + public record Rarities( + int total, + @SerializedName("null") int common, + int uncommon, + int rare, + int epic, + int legendary + ){} +} diff --git a/src/main/java/lel/flummi/skilloverlay/api/records/misc/Misc.java b/src/main/java/lel/flummi/skilloverlay/api/records/misc/Misc.java new file mode 100644 index 0000000..26861ae --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/api/records/misc/Misc.java @@ -0,0 +1,42 @@ +package lel.flummi.skilloverlay.api.records.misc; + +import com.google.gson.annotations.SerializedName; + +public record Misc( + Milestones milestones, + Gifts gifts, + Winter winter, + Dragons dragons, + Protector protector, + Damage damage, + Burrows burrows, + ProfileUpgrades profileUpgrades +){ + public record Milestones( + @SerializedName("ores_mined") int oresMined, + @SerializedName("sea_creatures_killed") int seaCreaturesKilled + ){} + public record Gifts(@SerializedName("gifts_given") int giftsGiven){} + public record Winter( + @SerializedName("most_winter_snowballs_hit") int mostWinterSnowballsHit, + @SerializedName("most_winter_damage_dealt") int mostWinterDamageDealt, + @SerializedName("most_winter_magma_damage_dealt") int mostWinterMagmaDamageDealt + ){} + public record Dragons( + @SerializedName("ender_crystals_destroyed") int enderCrystalsDestroyed, + @SerializedName("last_hits") int lastHits, + @SerializedName("deaths") int deaths + ){} + public record Protector( + @SerializedName("last_hits") int lastHits, + int deaths + ){} + public record Damage(@SerializedName("highest_critical_damage") double highestCriticalDamage){} + public record ProfileUpgrades( + @SerializedName("island_size") int islandSize, + @SerializedName("minion_slots") int minionSlots, + @SerializedName("guest_count") int guestCount, + @SerializedName("coop_slots") int coopSlots, + @SerializedName("coins_allowance") int coinsAllowance + ){} +} diff --git a/src/main/java/lel/flummi/skilloverlay/mixin/GameRenderMixin.java b/src/main/java/lel/flummi/skilloverlay/mixin/GameRenderMixin.java new file mode 100644 index 0000000..1c1a957 --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/mixin/GameRenderMixin.java @@ -0,0 +1,25 @@ +package lel.flummi.skilloverlay.mixin; + +import lel.flummi.skilloverlay.skilloverlay; +import net.minecraft.client.MinecraftClient; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.gui.hud.InGameHud; +import net.minecraft.client.util.math.MatrixStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Environment(EnvType.CLIENT) +@Mixin(InGameHud.class) +public abstract class GameRenderMixin { + @Shadow @Final private MinecraftClient client; + + @Inject(at = @At("RETURN"), method = "render") + private void render(MatrixStack matrices, float tickDelta, CallbackInfo ci) { + skilloverlay.OVERLAY.render(matrices, client); + } +} diff --git a/src/main/java/lel/flummi/skilloverlay/overlays/FarmingOverlay.java b/src/main/java/lel/flummi/skilloverlay/overlays/FarmingOverlay.java new file mode 100644 index 0000000..d117407 --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/overlays/FarmingOverlay.java @@ -0,0 +1,306 @@ +package lel.flummi.skilloverlay.overlays; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.util.Formatting; +import net.minecraft.client.gui.DrawableHelper; +import com.mojang.blaze3d.systems.RenderSystem; + +import lel.flummi.skilloverlay.skilloverlay; +import lel.flummi.skilloverlay.utils.LerpUtils; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; + +@Environment(EnvType.CLIENT) +public class FarmingOverlay extends DrawableHelper { + private MinecraftClient client; + private MatrixStack matrixStack; + + private long lastUpdate = -1; + private final LinkedList counterQueue = new LinkedList<>(); + private int cultivatingTier = -1; + private String cultivatingTierAmount = "1"; + private long counter = -1; + private int cultivating = -1; + private int cultivatingLast = -1; + private float cropsPerSecondLast = 0; + private float cropsPerSecond = 0; + private ArrayList cropsOverLastXSeconds = new ArrayList<>(); + private String cropName; + + public FarmingOverlay() { + /*HudRenderCallback.EVENT.register((matrixStack, tickDelta) -> { + if(client.player == null) + return; + this.render(matrixStack, client); + });*/ + } + + public void render(MatrixStack matrixStack, MinecraftClient client) { + if (client.player == null) + return; + + this.matrixStack = matrixStack; + this.client = MinecraftClient.getInstance(); + + RenderSystem.enableBlend(); + this.renderOverlay(); + + this.client.getProfiler().pop(); + } + + public void renderOverlay() { + this.lastUpdate = System.currentTimeMillis(); + ItemStack heldItem = client.player.getMainHandStack(); + String internalName = ""; + this.counter = 0; + boolean holdingFarmItem = false; + this.cultivatingLast = cultivating; + this.cultivating = 0; + + //System.out.println(skilloverlay.PROFILE.data().skills().get("farming").level()); + + if (heldItem != null) { + NbtCompound tag = heldItem.getNbt(); + + if (tag != null && tag.contains("ExtraAttributes", 10)) { + NbtCompound ea = tag.getCompound("ExtraAttributes"); + internalName = ea.getString("id"); + + for (CropType crop : CropType.values()) { + if (internalName.startsWith(crop.toolName)) { + this.cropName = crop.item; + holdingFarmItem = true; + } + } + if(holdingFarmItem) { + if (ea.contains("mined_crops", 99)) { + this.counter = ea.getLong("mined_crops"); + cultivating = ea.getInt("farmed_cultivating"); + this.counterQueue.add(0, this.counter); + } else if (ea.contains("farmed_cultivating", 99)) { + this.counter = ea.getInt("farmed_cultivating"); + cultivating = ea.getInt("farmed_cultivating"); + this.counterQueue.add(0, this.counter); + } + } + else + holdingFarmItem = false; + } + + if (this.cultivating < 1000) { + this.cultivatingTier = 1; + this.cultivatingTierAmount = "1,000"; + } else if (this.cultivating < 5000) { + this.cultivatingTier = 2; + this.cultivatingTierAmount = "5,000"; + } else if (this.cultivating < 25000) { + this.cultivatingTier = 3; + this.cultivatingTierAmount = "25,000"; + } else if (this.cultivating < 100000) { + this.cultivatingTier = 4; + this.cultivatingTierAmount = "100,000"; + } else if (this.cultivating < 300000) { + this.cultivatingTier = 5; + this.cultivatingTierAmount = "300,000"; + } else if (this.cultivating < 1500000) { + this.cultivatingTier = 6; + this.cultivatingTierAmount = "1,500,000"; + } else if (this.cultivating < 5000000) { + this.cultivatingTier = 7; + this.cultivatingTierAmount = "5,000,000"; + } else if (this.cultivating < 20000000) { + this.cultivatingTier = 8; + this.cultivatingTierAmount = "20,000,000"; + } else if (this.cultivating < 100000000) { + this.cultivatingTier = 9; + this.cultivatingTierAmount = "100,000,000"; + } else if (this.cultivating > 100000000) { + this.cultivatingTier = 10; + this.cultivatingTierAmount = "Maxed"; + } + } + + while (this.counterQueue.size() >= 4) { + this.counterQueue.removeLast(); + } + + if (this.counterQueue.isEmpty()) { + this.cropsPerSecond = -1; + this.cropsPerSecondLast = 0; + } else { + this.cropsPerSecondLast = this.cropsPerSecond; + long last = this.counterQueue.getLast(); + long first = this.counterQueue.getFirst(); + while (this.cropsOverLastXSeconds.size() > 60) { + this.cropsOverLastXSeconds.remove(0); + } + if ((first - last) / 2f != 0) { + this.cropsOverLastXSeconds.add((first - last) / 2f); + } else { + if (this.cropsPerSecondLast == 0) { + int i = 12; + while (i > 0) { + i--; + if (this.cropsOverLastXSeconds.size() > 0) { + this.cropsOverLastXSeconds.remove(0); + } else { + break; + } + } + } + } + + if (!holdingFarmItem) { + this.cropsOverLastXSeconds.clear(); + this.cropsPerSecond = -1; + this.cropsPerSecondLast = 0; + } + + ArrayList temp = new ArrayList<>(cropsOverLastXSeconds); + if (this.cropsOverLastXSeconds.size() >= 3) { + temp.remove(Collections.min(temp)); + } + if (this.cropsOverLastXSeconds.size() >= 6) { + temp.remove(Collections.min(temp)); + temp.remove(Collections.max(temp)); + } + if (this.cropsOverLastXSeconds.size() >= 10) { + temp.remove(Collections.max(temp)); + } + + float cropsOverLastXSecondsTotal = 0; + for (Float crops : temp) { + cropsOverLastXSecondsTotal += crops; + } + this.cropsPerSecond = temp.size() != 0 && cropsOverLastXSecondsTotal != 0 + ? cropsOverLastXSecondsTotal / temp.size() + : 0; + } + + ArrayList overlayStringList = new ArrayList<>(); + NumberFormat format = NumberFormat.getIntegerInstance(); + + // Add all the lines to the array + if (this.counter >= 0 && this.cultivating != this.counter) { + overlayStringList.add(new OverlayString("Counter", format.format(this.counter))); + } + + if (this.counter >= 0) { + if (this.cropsPerSecondLast == this.cropsPerSecond && this.cropsPerSecond <= 0) { + overlayStringList.add(new OverlayString(this.cropName + "/m", "N/A")); + } else { + float cpsInterp = interp(this.cropsPerSecond, this.cropsPerSecondLast); + overlayStringList.add(new OverlayString(this.cropName + "/m", String.format("%,.2f", cpsInterp * 60 * 30))); + } + } + + if (this.cultivatingTier <= 9 && this.cultivating > 0) { + int counterInterp = (int) interp(this.cultivating, this.cultivatingLast); + overlayStringList.add(new OverlayString("Cultivating", format.format(counterInterp) + "/" + this.cultivatingTierAmount)); + } + if (this.cultivatingTier == 10) { + int counterInterp = (int) interp(this.cultivating, this.cultivatingLast); + overlayStringList.add(new OverlayString("Cultivating", format.format(counterInterp))); + } + + float yaw = client.player.getYaw(); + float pitch = client.player.getPitch(); + yaw %= 360; + if (yaw < 0) + yaw += 360; + if (yaw > 180) + yaw -= 360; + pitch %= 360; + if (pitch < 0) + pitch += 360; + if (pitch > 180) + pitch -= 360; + + overlayStringList.add(new OverlayString("Yaw", String.format("%.2f", yaw) + Formatting.BOLD + "\u1D52")); + overlayStringList.add(new OverlayString("Pitch", String.format("%.2f", pitch) + Formatting.BOLD + "\u1D52")); + + if (!holdingFarmItem) { + overlayStringList.clear(); + } + + // Draw HUD + int xAxis = 10; + int yAxis = 200; + + // Get the longest string in the array + int longestString = 0; + int BoxWidth = 0; + for (OverlayString s : overlayStringList) { + String combined = s.toString(); + if (combined.length() > longestString) { + longestString = combined.length(); + BoxWidth = this.client.textRenderer.getWidth(combined); + } + } + + int lineHeight = this.client.textRenderer.fontHeight + 2; + + DrawableHelper.fill(matrixStack, xAxis, yAxis, xAxis + BoxWidth + 10, + yAxis + ((lineHeight + 1) * overlayStringList.size()), 0x64000000); + + for (OverlayString line : overlayStringList) { + int offset = 5; + + this.client.textRenderer.drawWithShadow(this.matrixStack, line.toString(), xAxis + offset, yAxis + offset, 0xFFFFFF); + yAxis += lineHeight; + } + } + + private float interp(float now, float last) { + float interp = now; + if (last >= 0 && last != now) { + float factor = (System.currentTimeMillis() - this.lastUpdate) / 1000f; + factor = LerpUtils.clampZeroOne(factor); + interp = last + (now - last) * factor; + } + return interp; + } + + private enum CropType { + WHEAT("THEORETICAL_HOE_WHEAT", "Wheat"), + NETHER_WART("THEORETICAL_HOE_WARTS", "Warts"), + SUGAR_CANE("THEORETICAL_HOE_CANE", "Sugar"), + CARROT("THEORETICAL_HOE_CARROT", "Carrots"), + POTATO("THEORETICAL_HOE_POTATO", "Potatoes"), + COCOA_BEANS("COCO_CHOPPER", "Cocoas"), + PUMPKIN("PUMPKIN_DICER", "Pumpkins"), + MELON("MELON_DICER", "Melons"), + CACTUS("CACTUS_KNIFE", "Cactus"), + ; + + private final String toolName; + private final String item; + + CropType(String toolName, String item) { + this.toolName = toolName; + this.item = item; + } + } + + private class OverlayString { + final String type; + final String text; + + private OverlayString(String type, String text) { + this.type = type; + this.text = text; + } + + public String toString() { + return Formatting.AQUA + this.type + ": " + Formatting.YELLOW + this.text; + } + } +} diff --git a/src/main/java/lel/flummi/skilloverlay/overlays/FarmingOverlay.java.unused b/src/main/java/lel/flummi/skilloverlay/overlays/FarmingOverlay.java.unused new file mode 100644 index 0000000..4b8c87b --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/overlays/FarmingOverlay.java.unused @@ -0,0 +1,73 @@ +package lel.flummi.skilloverlay.overlays; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.client.gui.DrawableHelper; +import com.mojang.blaze3d.systems.RenderSystem; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import java.util.ArrayList; + +@Environment(EnvType.CLIENT) +public class FarmingOverlay extends DrawableHelper { + private MinecraftClient client; + private MatrixStack matrixStack; + + public FarmingOverlay() {} + + public void render(MatrixStack matrixStack, MinecraftClient client) { + this.matrixStack = matrixStack; + this.client = MinecraftClient.getInstance(); + + RenderSystem.enableBlend(); + this.renderOverlay(); + + this.client.getProfiler().pop(); + } + + public void renderOverlay() { + ArrayList overlayStringList = new ArrayList<>(); + + // Add all the lines to the array + overlayStringList.add("Test"); + + //Remove empty lines from the array + overlayStringList.removeIf(String::isEmpty); + + // Draw HUD + int Xcords = 10; + int Ycords = 200; + + // Get the longest string in the array + int longestString = 0; + int BoxWidth = 0; + for (String s : overlayStringList) { + if (s.length() > longestString) { + longestString = s.length(); + BoxWidth = this.client.textRenderer.getWidth(s); + } + } + + int lineHeight = this.client.textRenderer.fontHeight + 2; + int yAxis = (((this.client.getWindow().getScaledHeight()) - ((lineHeight + 4) * overlayStringList.size())) + (lineHeight + 4)) * (Ycords) / 100; + int xAxis = ((this.client.getWindow().getScaledWidth() - 4) - (BoxWidth)) * Xcords / 100; + + // Add Padding to left of the screen + if (xAxis <= 4) { + xAxis = 4; + } + + for (String line : overlayStringList) { + int offset = 0; + if (Xcords >= 50) { + int lineLength = this.client.textRenderer.getWidth(line); + offset = (BoxWidth - lineLength); + } + + this.client.textRenderer.drawWithShadow(this.matrixStack, line, xAxis + offset, yAxis + 4, 0xFFFFFF); + yAxis += lineHeight; + } + } +} diff --git a/src/main/java/lel/flummi/skilloverlay/skilloverlay.java b/src/main/java/lel/flummi/skilloverlay/skilloverlay.java new file mode 100644 index 0000000..a73af8e --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/skilloverlay.java @@ -0,0 +1,23 @@ +package lel.flummi.skilloverlay; + +import net.fabricmc.api.ModInitializer; + +import lel.flummi.skilloverlay.overlays.FarmingOverlay; + +import lel.flummi.skilloverlay.api.PlayerProfile; + +public class skilloverlay implements ModInitializer { + public static FarmingOverlay OVERLAY; + public static PlayerProfile API; + + @Override + public void onInitialize() { + System.out.println("Skilloverlay started."); + + OVERLAY = new FarmingOverlay(); + + PlayerProfile.init(); + + //System.out.println(profiles.profiles().get("b2255349-d395-4169-9980-3ec0a32b2cfb").data().skills().get("farming").xp()); + } +} diff --git a/src/main/java/lel/flummi/skilloverlay/utils/LerpUtils.java b/src/main/java/lel/flummi/skilloverlay/utils/LerpUtils.java new file mode 100644 index 0000000..4b04b5b --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/utils/LerpUtils.java @@ -0,0 +1,24 @@ +package lel.flummi.skilloverlay.utils; + +public class LerpUtils { + public static float clampZeroOne(float f) { + return Math.max(0, Math.min(1, f)); + } + + public static float sigmoid(float val) { + return (float) (1 / (1 + Math.exp(-val))); + } + + private static final float sigmoidStr = 8; + private static final float sigmoidA = -1 / (sigmoid(-0.5f * sigmoidStr) - sigmoid(0.5f * sigmoidStr)); + private static final float sigmoidB = sigmoidA * sigmoid(-0.5f * sigmoidStr); + + public static float sigmoidZeroOne(float f) { + f = clampZeroOne(f); + return sigmoidA * sigmoid(sigmoidStr * (f - 0.5f)) - sigmoidB; + } + + public static float lerp(float a, float b, float amount) { + return b + (a - b) * clampZeroOne(amount); + } +} diff --git a/src/main/resources/assets/skilloverlay/icon.png b/src/main/resources/assets/skilloverlay/icon.png new file mode 100644 index 0000000..047b91f Binary files /dev/null and b/src/main/resources/assets/skilloverlay/icon.png differ diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..02e8dba --- /dev/null +++ b/src/main/resources/fabric.mod.json @@ -0,0 +1,34 @@ +{ + "schemaVersion": 1, + "id": "skilloverlay", + "version": "${version}", + "name": "skilloverlay", + "description": "skilloverlay for Hypixel Skyblock", + "authors": [ + "Flummi" + ], + "contact": { + "homepage": "https://fabricmc.net/", + "sources": "https://github.com/FabricMC/fabric-example-mod" + }, + + "license": "GNU LGPLv3", + "icon": "assets/skilloverlay/icon.png", + + "environment": "client", + "entrypoints": { + "main": [ + "lel.flummi.skilloverlay.skilloverlay" + ] + }, + "mixins": [ + "skilloverlay.mixins.json" + ], + + "depends": { + "fabricloader": ">=0.14.19", + "fabric-api": ">=0.81.0+1.19.4", + "minecraft": "~1.19.4", + "java": ">=17" + } +} diff --git a/src/main/resources/skilloverlay.mixins.json b/src/main/resources/skilloverlay.mixins.json new file mode 100644 index 0000000..f9bff9b --- /dev/null +++ b/src/main/resources/skilloverlay.mixins.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "lel.flummi.skilloverlay.mixin", + "compatibilityLevel": "JAVA_17", + "client": [ + "GameRenderMixin" + ], + "injectors": { + "defaultRequire": 1 + } +}