diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4b97d27a..26c55671 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -188,8 +188,10 @@ target_compile_definitions(${PROJECT_NAME} INTERFACE GEODE_GD_VERSION=${GEODE_GD
 
 if (WIN32)
 	# This allows you to compile in debug mode
-	add_compile_definitions(_HAS_ITERATOR_DEBUGGING=0)
+	# add_compile_definitions(_HAS_ITERATOR_DEBUGGING=0)
 	add_definitions(-D_HAS_ITERATOR_DEBUGGING=0)
+	target_compile_definitions(${PROJECT_NAME} INTERFACE _HAS_ITERATOR_DEBUGGING=0)
+	
 	target_link_libraries(${PROJECT_NAME} INTERFACE delayimp)
 	if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
 		CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
diff --git a/installer/windows/Language Files/SimpChineseExtra.nsh b/installer/windows/Language Files/SimpChineseExtra.nsh
index 99993c45..9e7298dc 100644
--- a/installer/windows/Language Files/SimpChineseExtra.nsh	
+++ b/installer/windows/Language Files/SimpChineseExtra.nsh	
@@ -7,10 +7,10 @@ ${LangFileString} MUI_UNTEXT_WELCOME_INFO_TEXT "Setup会帮您卸载$(^NameDA)
 
 ; installer
 
-${LangFileString} GEODE_TEXT_GD_MISSING "$\r$\n$\r$\nGeometry Dash不在这文件目录,请再试一遍!"
-${LangFileString} GEODE_TEXT_MH_ALREADY_INSTALLED "这文件目录已经安装了Mega Hack v6/v7!$\r$\nGeode不能跟MHv6/v7一起用(可是MHv8可以跟Geode一起用)。$\r$\n请先卸载MHv6/v7。"
-${LangFileString} GEODE_TEXT_MOD_LOADER_ALREADY_INSTALLED "这文件目录已经安装了不同的游戏修改器加载器!$\r$\nGeode不能和不同的游戏修改器加载器一起用。$\r$\n请先卸载那个游戏修改器加载器。 (the dll trademark)"
+${LangFileString} GEODE_TEXT_GD_MISSING "$\r$\n$\r$\nGeometry Dash不在这文件夹,请再试一遍!"
+${LangFileString} GEODE_TEXT_MH_ALREADY_INSTALLED "这文件夹已经安装了Mega Hack v6/v7!$\r$\nGeode不能跟MHv6/v7一起用(可是MHv8可以)。$\r$\n请先卸载MHv6/v7。"
+${LangFileString} GEODE_TEXT_MOD_LOADER_ALREADY_INSTALLED "这文件夹已经安装了不同的游戏修改器加载器!$\r$\nGeode不能和不同的游戏修改器加载器一起用。$\r$\n请先卸载那个游戏修改器加载器。 (the dll trademark)"
 
 ; uninstaller
 
-${LangFileString} GEODE_UNTEXT_GEODE_MISSING "Geode不在这文件目录,请再试一遍!"
\ No newline at end of file
+${LangFileString} GEODE_UNTEXT_GEODE_MISSING "Geode不在这文件夹,请再试一遍!"
diff --git a/installer/windows/Language Files/TradChineseExtra.nsh b/installer/windows/Language Files/TradChineseExtra.nsh
index c324ba48..efe800e3 100644
--- a/installer/windows/Language Files/TradChineseExtra.nsh	
+++ b/installer/windows/Language Files/TradChineseExtra.nsh	
@@ -7,10 +7,10 @@ ${LangFileString} MUI_UNTEXT_WELCOME_INFO_TEXT "Setup會幫您卸載$(^NameDA)
 
 ; installer
 
-${LangFileString} GEODE_TEXT_GD_MISSING "$\r$\n$\r$\nGeometry Dash不在這文件目錄,請再試一遍!"
-${LangFileString} GEODE_TEXT_MH_ALREADY_INSTALLED "這文件目錄已經安裝了Mega Hack v6/v7!$\r$\nGeode不能跟MHv6/v7一起用(可是MHv8可以跟Geode一起用)。$\r$\n請先卸載MHv6/v7。"
-${LangFileString} GEODE_TEXT_MOD_LOADER_ALREADY_INSTALLED "這文件目錄已經安裝了不同的遊戲修改器加載器!$\r$\nGeode不能跟不同的遊戲修改器加載器一起用。$\r$\n請先卸載那個遊戲修改器加載器。 (the dll trademark)"
+${LangFileString} GEODE_TEXT_GD_MISSING "$\r$\n$\r$\nGeometry Dash不在這文件夾,請再試一遍!"
+${LangFileString} GEODE_TEXT_MH_ALREADY_INSTALLED "這文件夾已經安裝了Mega Hack v6/v7!$\r$\nGeode不能跟MHv6/v7一起用(可是MHv8可以跟Geode一起用)。$\r$\n請先卸載MHv6/v7。"
+${LangFileString} GEODE_TEXT_MOD_LOADER_ALREADY_INSTALLED "這文件夾已經安裝了不同的遊戲修改器加載器!$\r$\nGeode不能跟不同的遊戲修改器加載器一起用。$\r$\n請先卸載那個遊戲修改器加載器。 (the dll trademark)"
 
 ; uninstaller
 
-${LangFileString} GEODE_UNTEXT_GEODE_MISSING "Geode不在這文件目錄,請再試一遍!"
\ No newline at end of file
+${LangFileString} GEODE_UNTEXT_GEODE_MISSING "Geode不在這文件夾,請再試一遍!"
\ No newline at end of file
diff --git a/loader/include/Geode/Enums.hpp b/loader/include/Geode/Enums.hpp
index 804690df..8a7ca0a5 100644
--- a/loader/include/Geode/Enums.hpp
+++ b/loader/include/Geode/Enums.hpp
@@ -257,8 +257,17 @@ enum class StatKey {};
 enum class TextStyleType {};
 enum class InputValueType {};
 enum class GJInputStyle {};
-enum class GJDifficultyName {};
-enum class GJFeatureState {};
+enum class GJDifficultyName {
+    Short = 0,
+    Long = 1
+};
+enum class GJFeatureState {
+    None = 0,
+    Featured = 1,
+    Epic = 2,
+    Legendary = 3,
+    Mythic = 4
+};
 enum class GJKeyGroup {};
 enum class GJKeyCommand {};
 enum class SelectSettingType {};
diff --git a/loader/include/Geode/ui/TextInput.hpp b/loader/include/Geode/ui/TextInput.hpp
index 2090432b..3b8640e3 100644
--- a/loader/include/Geode/ui/TextInput.hpp
+++ b/loader/include/Geode/ui/TextInput.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include <Geode/DefaultInclude.hpp>
+#include <Geode/binding/TextInputDelegate.hpp>
 #include <Geode/binding/CCTextInputNode.hpp>
 #include <cocos2d.h>
 
diff --git a/loader/include/Geode/utils/cocos.hpp b/loader/include/Geode/utils/cocos.hpp
index bc394ec6..2c3e92a3 100644
--- a/loader/include/Geode/utils/cocos.hpp
+++ b/loader/include/Geode/utils/cocos.hpp
@@ -780,6 +780,28 @@ namespace geode::cocos {
      */
     GEODE_DLL cocos2d::CCNode* getChildBySpriteFrameName(cocos2d::CCNode* parent, const char* name);
 
+    /**
+     * Checks if a node has the given sprite name either
+     * in the sprite or in the sprite inside the button.
+     * 
+     * @param node Node to check
+     * @param name Name of the sprite to search for
+     * @returns True if the node has the given sprite name
+     */
+    GEODE_DLL bool isSpriteName(cocos2d::CCNode* node, const char* name);
+
+    /**
+     * Get the first child that has the given sprite name
+     * either in the sprite or in the sprite inside the
+     * button.
+     *
+     * @param parent Parent node to search in
+     * @param name Name of the sprite to search for
+     * @returns Child with the given sprite name, or
+     * nullptr if there is none
+     */
+    GEODE_DLL cocos2d::CCNode* getChildBySpriteName(cocos2d::CCNode* parent, const char* name);
+
     /**
      * Checks if a given file exists in CCFileUtils
      * search paths.
diff --git a/loader/include/link/libfmod.dylib b/loader/include/link/libfmod.dylib
old mode 100644
new mode 100755
index 11374487..5ffd3712
Binary files a/loader/include/link/libfmod.dylib and b/loader/include/link/libfmod.dylib differ
diff --git a/loader/src/hooks/FMODFix.cpp b/loader/src/hooks/FMODFix.cpp
index ced7da58..1cef5888 100644
--- a/loader/src/hooks/FMODFix.cpp
+++ b/loader/src/hooks/FMODFix.cpp
@@ -1,8 +1,5 @@
 #include <Geode/Geode.hpp>
 
-// uncomment whenever macos stops complaining about fmod link errors
-#ifndef GEODE_IS_MACOS
-
 using namespace geode::prelude;
 
 auto g_systemInitialized = false;
@@ -66,5 +63,3 @@ struct AndroidFMODFix : Modify<AndroidFMODFix, FMODAudioEngine> {
     }
 };
 */
-
-#endif
diff --git a/loader/src/platform/windows/info.rc.in b/loader/src/platform/windows/info.rc.in
index f5bd03c8..f1e05f99 100644
--- a/loader/src/platform/windows/info.rc.in
+++ b/loader/src/platform/windows/info.rc.in
@@ -20,7 +20,7 @@ BEGIN
             VALUE "FileDescription", "Geode mod loader."
             VALUE "FileVersion", "@PROJECT_VERSION_MAJOR@,@PROJECT_VERSION_MINOR@,@PROJECT_VERSION_PATCH@,0"
             VALUE "InternalName", "@PROJECT_NAME@"
-            VALUE "LegalCopyright", "2022 The Geode Team"
+            VALUE "LegalCopyright", "2024 The Geode Team"
             VALUE "OriginalFilename", "@PROJECT_NAME@.dll"
             VALUE "ProductName", "Geode Loader"
             VALUE "ProductVersion", "@PROJECT_VERSION_MAJOR@,@PROJECT_VERSION_MINOR@,@PROJECT_VERSION_PATCH@,0"
diff --git a/loader/src/utils/cocos.cpp b/loader/src/utils/cocos.cpp
index 0266608d..b1018f42 100644
--- a/loader/src/utils/cocos.cpp
+++ b/loader/src/utils/cocos.cpp
@@ -372,6 +372,37 @@ CCNode* geode::cocos::getChildBySpriteFrameName(CCNode* parent, const char* name
     return nullptr;
 }
 
+bool geode::cocos::isSpriteName(CCNode* node, const char* name) {
+    if (!node) return false;
+
+    auto texture = CCTextureCache::sharedTextureCache()->textureForKey(name);
+    if (!texture) return false;
+
+    if (auto* spr = typeinfo_cast<CCSprite*>(node)) {
+        if (spr->getTexture() == texture) {
+            return true;
+        }
+    }
+    else if (auto* btn = typeinfo_cast<CCMenuItemSprite*>(node)) {
+        auto* img = btn->getNormalImage();
+        if (auto* spr = typeinfo_cast<CCSprite*>(img)) {
+            if (spr->getTexture() == texture) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+CCNode* geode::cocos::getChildBySpriteName(CCNode* parent, const char* name) {
+    for (auto child : CCArrayExt<CCNode*>(parent->getChildren())) {
+        if (::isSpriteName(static_cast<CCNode*>(child), name)) {
+            return child;
+        }
+    }
+    return nullptr;
+}
+
 CCRect geode::cocos::calculateNodeCoverage(std::vector<CCNode*> const& nodes) {
     CCRect coverage;
     for (auto child : nodes) {