add client base

This commit is contained in:
froslanz
2026-10-21 16:41:54 -04:00
parent 7139a130f3
commit 131df5fb0a
138 changed files with 7958 additions and 2 deletions
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2023 3arthqu4ke, alpha432, cattyn
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+14 -2
View File
@@ -1,2 +1,14 @@
# fros.cc
A utility client for Minecraft 1.21.11.
<div align="center">
# oyvey-ported
Kosher client base ported to modern Minecraft by [@cattyngmd](https://github.com/cattyngmd)
<img src="images/ui.png" width="90%" />
# Why
![](https://i.imgur.com/VYjIphG.png)
# What
Add stuff to it like you would add stuff to your 1.12.2 OyVey paste
</div>
+111
View File
@@ -0,0 +1,111 @@
import java.nio.file.Paths
import java.text.SimpleDateFormat
import java.util.Date
plugins {
id("fabric-loom")
id("com.github.gmazzo.buildconfig")
java
}
val mod_version: String by project
val maven_group: String by project
val mod_name: String by project
val archives_base_name: String by project
val minecraft_version: String by project
val loader_version: String by project
val fabric_version: String by project
val catformat_version: String by project
val USING_GIT = Paths.get(rootDir.absolutePath).resolve(".git").toFile().exists()
val GIT_HASH = execute("git rev-parse --short HEAD")
version = mod_version
group = maven_group
buildConfig {
packageName("$group.util")
useJavaOutput()
generateAtSync.set(true)
val typeString = String::class.java
val typeBool = Boolean::class.java
val buildTime = SimpleDateFormat("MM/dd/yyyy HH:mm").format(Date())
buildConfigField(typeString, "NAME", mod_name)
buildConfigField(typeString, "GROUP", maven_group)
buildConfigField(typeString, "VERSION", mod_version)
buildConfigField(typeString, "BUILD_TIME", buildTime)
buildConfigField(typeBool, "USING_GIT", USING_GIT)
buildConfigField(typeString, "HASH", GIT_HASH)
buildConfigField(typeString, "BRANCH", execute("git branch --show-current"))
}
sourceSets.main {
java.srcDirs("build/gen/buildconfig/src/main")
}
base {
archivesName.set("$archives_base_name-$GIT_HASH")
}
repositories {
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
loom {
accessWidenerPath.set(file("src/main/resources/oyvey.accesswidener"))
}
dependencies {
minecraft("com.mojang:minecraft:$minecraft_version")
mappings(loom.officialMojangMappings())
modImplementation("net.fabricmc:fabric-loader:$loader_version")
modImplementation("net.fabricmc.fabric-api:fabric-api:$fabric_version")
include(implementation("com.github.cattyngmd.catformat:catformat-core:$catformat_version")!!)
include(modImplementation("com.github.cattyngmd.catformat:catformat-fabric:$catformat_version")!!)
}
tasks.processResources {
inputs.property("version", version)
inputs.property("minecraft_version", minecraft_version)
inputs.property("loader_version", loader_version)
filteringCharset = "UTF-8"
filesMatching("fabric.mod.json") {
expand(
"version" to version,
"minecraft_version" to minecraft_version,
"loader_version" to loader_version
)
}
}
tasks.withType<JavaCompile>().configureEach {
options.release = 21
dependsOn("generateBuildConfig")
}
java {
withSourcesJar()
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
tasks.named<Jar>("sourcesJar") {
dependsOn("generateBuildConfig")
}
tasks.jar {
from("LICENSE") {
rename { "${it}_$archives_base_name" }
}
}
fun execute(cmd: String): String = providers.exec {
commandLine(cmd.split(" "))
isIgnoreExitValue = true
}.standardOutput.asText.getOrElse("nogit").trim().replace("\n", "")
+17
View File
@@ -0,0 +1,17 @@
# Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx1G
# Fabric Properties
# check these on https://modmuss50.me/fabric.html
minecraft_version=1.21.11
loader_version=0.18.4
loom_version=1.14-SNAPSHOT
# Mod Properties
maven_group=me.alpha432.oyvey
mod_version=1.0.0
mod_name=OyVey
archives_base_name=oyvey
# Dependencies
# check this on https://modmuss50.me/fabric.html
fabric_version=0.141.1+1.21.11
catformat_version=2.1.0
buildconfig_version=5.3.5
Binary file not shown.
+7
View File
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+245
View File
@@ -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" "$@"
Vendored
+92
View File
@@ -0,0 +1,92 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 817 KiB

+17
View File
@@ -0,0 +1,17 @@
pluginManagement {
repositories {
maven {
name = "Fabric"
url = uri("https://maven.fabricmc.net/")
}
gradlePluginPortal()
}
plugins {
id("fabric-loom") version providers.gradleProperty("loom_version")
id("com.github.gmazzo.buildconfig") version providers.gradleProperty("buildconfig_version")
java
}
}
rootProject.name = "oyvey-ported"
@@ -0,0 +1,66 @@
package me.alpha432.oyvey;
import me.alpha432.oyvey.manager.*;
import me.alpha432.oyvey.util.BuildConfig;
import me.alpha432.oyvey.util.TextUtil;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.ModInitializer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class OyVey implements ModInitializer, ClientModInitializer {
public static float TIMER = 1f;
public static final Logger LOGGER = LogManager.getLogger("OyVey");
public static ServerManager serverManager;
public static ColorManager colorManager;
public static RotationManager rotationManager;
public static PositionManager positionManager;
public static HoleManager holeManager;
public static EventManager eventManager;
public static SpeedManager speedManager;
public static CommandManager commandManager;
public static FriendManager friendManager;
public static ModuleManager moduleManager;
public static ConfigManager configManager;
@Override
public void onInitialize() {
LOGGER.info("Pre-initializing {} v{}",
BuildConfig.NAME, BuildConfig.VERSION);
configManager = new ConfigManager();
eventManager = new EventManager();
serverManager = new ServerManager();
rotationManager = new RotationManager();
positionManager = new PositionManager();
friendManager = new FriendManager();
colorManager = new ColorManager();
commandManager = new CommandManager();
moduleManager = new ModuleManager();
speedManager = new SpeedManager();
holeManager = new HoleManager();
TextUtil.init();
}
@Override
public void onInitializeClient() {
LOGGER.info("Initializing {}", BuildConfig.NAME);
long startTime = System.nanoTime();
eventManager.init();
commandManager.init();
moduleManager.init();
friendManager.init();
configManager.load();
colorManager.init();
Runtime.getRuntime().addShutdownHook(new Thread(() -> configManager.save()));
long endTime = System.nanoTime();
LOGGER.info("Initialized {} in {}ms",
BuildConfig.NAME, (endTime - startTime) / 1000000.0);
}
}
@@ -0,0 +1,9 @@
package me.alpha432.oyvey.ducks.render;
import net.minecraft.client.GuiMessage;
import net.minecraft.network.chat.MessageSignature;
public interface IChatComponent {
void oyvey$addMessage(GuiMessage message);
void oyvey$removeMessage(MessageSignature signature);
}
@@ -0,0 +1,13 @@
package me.alpha432.oyvey.event;
public class Event {
private boolean cancelled;
public boolean isCancelled() {
return cancelled;
}
public void cancel() {
cancelled = true;
}
}
@@ -0,0 +1,6 @@
package me.alpha432.oyvey.event;
public enum Stage {
PRE,
POST
}
@@ -0,0 +1,38 @@
package me.alpha432.oyvey.event.impl;
import me.alpha432.oyvey.event.Event;
import me.alpha432.oyvey.features.Feature;
import me.alpha432.oyvey.features.settings.Setting;
public class ClientEvent extends Event {
private final Type type;
private final Feature feature;
private Setting<?> setting;
public ClientEvent(Type type, Feature feature) {
this.type = type;
this.feature = feature;
}
public ClientEvent(Setting<?> setting) {
this(Type.SETTING_UPDATE, setting.getFeature());
this.setting = setting;
}
public Type getType() {
return type;
}
public Feature getFeature() {
return this.feature;
}
public Setting<?> getSetting() {
return this.setting;
}
public enum Type {
TOGGLE_MODULE,
SETTING_UPDATE
}
}
@@ -0,0 +1,16 @@
package me.alpha432.oyvey.event.impl.entity;
import me.alpha432.oyvey.event.Event;
import net.minecraft.world.entity.LivingEntity;
public class DeathEvent extends Event {
private final LivingEntity entity;
public DeathEvent(LivingEntity entity) {
this.entity = entity;
}
public LivingEntity getEntity() {
return entity;
}
}
@@ -0,0 +1,31 @@
package me.alpha432.oyvey.event.impl.entity.player;
import me.alpha432.oyvey.event.Event;
import net.minecraft.world.entity.MoverType;
import net.minecraft.world.phys.Vec3;
public class MoveEvent extends Event {
private final MoverType type;
private Vec3 movement;
public MoveEvent(MoverType type, Vec3 movement) {
this.type = type;
this.movement = movement;
}
public MoverType getType() {
return type;
}
public Vec3 getMovement() {
return movement;
}
public void setMovement(Vec3 movement) {
this.movement = movement;
}
public void setMovement(double x, double y, double z) {
this.movement = new Vec3(x, y, z);
}
}
@@ -0,0 +1,9 @@
package me.alpha432.oyvey.event.impl.entity.player;
import me.alpha432.oyvey.event.Event;
public class TickEvent extends Event {
public static class Post extends TickEvent { }
public static class Pre extends TickEvent { }
}
@@ -0,0 +1,9 @@
package me.alpha432.oyvey.event.impl.entity.player;
import me.alpha432.oyvey.event.Event;
public class TravelEvent extends Event {
public static class Post extends TravelEvent { }
public static class Pre extends TravelEvent { }
}
@@ -0,0 +1,16 @@
package me.alpha432.oyvey.event.impl.entity.player;
import me.alpha432.oyvey.event.Event;
import me.alpha432.oyvey.event.Stage;
public class UpdateWalkingPlayerEvent extends Event {
private final Stage stage;
public UpdateWalkingPlayerEvent(Stage stage) {
this.stage = stage;
}
public Stage getStage() {
return stage;
}
}
@@ -0,0 +1,15 @@
package me.alpha432.oyvey.event.impl.input;
import me.alpha432.oyvey.event.Event;
public class KeyInputEvent extends Event {
private final int key;
public KeyInputEvent(int key) {
this.key = key;
}
public int getKey() {
return key;
}
}
@@ -0,0 +1,22 @@
package me.alpha432.oyvey.event.impl.input;
import me.alpha432.oyvey.event.Event;
public class MouseInputEvent extends Event {
private final int button;
private final int action;
public MouseInputEvent(int button, int action) {
this.button = button;
this.action = action;
}
public int getButton() {
return button;
}
public int getAction() {
return action;
}
}
@@ -0,0 +1,15 @@
package me.alpha432.oyvey.event.impl.network;
import me.alpha432.oyvey.event.Event;
public class ChatEvent extends Event {
private final String content;
public ChatEvent(String content) {
this.content = content;
}
public String getMessage() {
return content;
}
}
@@ -0,0 +1,30 @@
package me.alpha432.oyvey.event.impl.network;
import me.alpha432.oyvey.event.Event;
import net.minecraft.network.protocol.Packet;
public abstract class PacketEvent extends Event {
private final Packet<?> packet;
public PacketEvent(Packet<?> packet) {
this.packet = packet;
}
public Packet<?> getPacket() {
return packet;
}
public static class Receive extends PacketEvent {
public Receive(Packet<?> packet) {
super(packet);
}
}
public static class Send extends PacketEvent {
public Send(Packet<?> packet) {
super(packet);
}
}
}
@@ -0,0 +1,22 @@
package me.alpha432.oyvey.event.impl.render;
import me.alpha432.oyvey.event.Event;
import net.minecraft.client.gui.GuiGraphics;
public class Render2DEvent extends Event {
private final GuiGraphics context;
private final float delta;
public Render2DEvent(GuiGraphics context, float delta) {
this.context = context;
this.delta = delta;
}
public GuiGraphics getContext() {
return context;
}
public float getDelta() {
return delta;
}
}
@@ -0,0 +1,22 @@
package me.alpha432.oyvey.event.impl.render;
import com.mojang.blaze3d.vertex.PoseStack;
import me.alpha432.oyvey.event.Event;
public class Render3DEvent extends Event {
private final PoseStack matrix;
private final float delta;
public Render3DEvent(PoseStack matrix, float delta) {
this.matrix = matrix;
this.delta = delta;
}
public PoseStack getMatrix() {
return matrix;
}
public float getDelta() {
return delta;
}
}
@@ -0,0 +1,6 @@
package me.alpha432.oyvey.event.impl.render;
import me.alpha432.oyvey.event.Event;
public class RenderBlockOutlineEvent extends Event {
}
@@ -0,0 +1,74 @@
package me.alpha432.oyvey.event.system;
import me.alpha432.oyvey.event.Event;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
public class EventBus {
private final Map<Class<?>, CopyOnWriteArrayList<Listener>> listeners = new ConcurrentHashMap<>();
public void register(Object host) {
register(host, host.getClass());
}
public void unregister(Object host) {
for (CopyOnWriteArrayList<Listener> list : listeners.values()) {
list.removeIf(listener -> listener.getHost().equals(host));
}
}
public boolean post(Event event) {
List<Listener> list = listeners.get(event.getClass());
if (list == null) return false;
for (Listener listener : list) {
listener.invoke(event);
if (event.isCancelled())
return true;
}
return false;
}
private void register(Object host, Class<?> klass) {
for (Method method : klass.getDeclaredMethods()) {
Subscribe subscribe = method.getAnnotation(Subscribe.class);
if (subscribe == null) continue;
Class<?>[] params = method.getParameterTypes();
if (params.length == 1) {
Class<?> eventType = params[0];
Listener listener = Listener.of(host, subscribe.priority(), method);
List<Listener> registry = listeners.computeIfAbsent(
eventType,
k -> new CopyOnWriteArrayList<>()
);
register(registry, listener);
}
}
if (klass.getSuperclass() != null)
register(host, klass.getSuperclass());
}
private void register(List<Listener> registry, Listener target) {
int i = 0;
for (Listener listener : registry) {
if (target.priority() > listener.priority()) {
break;
}
i++;
}
registry.add(i, target);
}
}
@@ -0,0 +1,38 @@
package me.alpha432.oyvey.event.system;
import java.lang.invoke.*;
import java.lang.reflect.Method;
import java.util.function.Consumer;
public record Listener(Object host, int priority, Consumer<Object> consumer) {
public static Listener of(Object host, int priority, Method method) {
return new Listener(host, priority, buildLambdaMetafactory(host, method));
}
public void invoke(Object event) {
consumer.accept(event);
}
public Object getHost() {
return host;
}
@SuppressWarnings("unchecked")
private static Consumer<Object> buildLambdaMetafactory(Object host, Method method) {
try {
MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(method.getDeclaringClass(), MethodHandles.lookup());
CallSite site = LambdaMetafactory.metafactory(
lookup,
"accept",
MethodType.methodType(Consumer.class, method.getDeclaringClass()),
MethodType.methodType(void.class, Object.class),
lookup.unreflect(method),
MethodType.methodType(void.class, method.getParameterTypes()[0])
);
MethodHandle target = site.getTarget();
return (Consumer<Object>) (target.invoke(host));
} catch (Throwable e) {
throw new RuntimeException("Failed to build lambda from %s method".formatted(method.getName()), e);
}
}
}
@@ -0,0 +1,13 @@
package me.alpha432.oyvey.event.system;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Subscribe {
int priority() default 0;
}
@@ -0,0 +1,65 @@
package me.alpha432.oyvey.features;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.features.settings.SettingFactory;
import me.alpha432.oyvey.util.traits.Util;
import java.util.ArrayList;
import java.util.List;
public class Feature
implements Util, SettingFactory {
public List<Setting<?>> settings = new ArrayList<>();
private String name;
public Feature() {
}
public Feature(String name) {
this.name = name;
}
public static boolean nullCheck() {
return Feature.mc.player == null || Feature.mc.level == null;
}
public String getName() {
return this.name;
}
public List<Setting<?>> getSettings() {
return this.settings;
}
public boolean hasSettings() {
return !this.settings.isEmpty();
}
public boolean isEnabled() {
return false;
}
public boolean isDisabled() {
return !this.isEnabled();
}
public <T extends Setting<?>> T register(T setting) {
setting.setFeature(this);
this.settings.add(setting);
return setting;
}
public Setting<?> getSettingByName(String name) {
for (Setting<?> setting : this.settings) {
if (!setting.getName().equalsIgnoreCase(name)) continue;
return setting;
}
return null;
}
public void reset() {
for (Setting<?> setting : this.settings) {
setting.reset();
}
}
}
@@ -0,0 +1,37 @@
package me.alpha432.oyvey.features.commands;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import java.util.Locale;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Stream;
public final class ArgumentSuggestions {
public static CompletableFuture<Suggestions> suggest(Stream<String> stream, SuggestionsBuilder builder) {
return suggest(stream.toList(), x -> x, builder);
}
public static CompletableFuture<Suggestions> suggest(Iterable<String> iterable, SuggestionsBuilder builder) {
return suggest(iterable, x -> x, builder);
}
public static <T> CompletableFuture<Suggestions> suggest(Iterable<T> iterable, Function<T, String> map, SuggestionsBuilder builder) {
String remaining = builder.getRemainingLowerCase();
for (T t : iterable) {
String target = map.apply(t).toLowerCase(Locale.ROOT);
if (target.equals(remaining)) {
builder.suggest(target);
return builder.buildFuture();
}
}
for (T t : iterable) {
String target = map.apply(t).toLowerCase(Locale.ROOT);
if (target.contains(remaining)) builder.suggest(target);
}
return builder.buildFuture();
}
}
@@ -0,0 +1,81 @@
package me.alpha432.oyvey.features.commands;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import me.alpha432.oyvey.features.Feature;
import me.alpha432.oyvey.manager.CommandManager;
import me.alpha432.oyvey.util.TextUtil;
import me.alpha432.oyvey.util.chat.ChatUtil;
import me.alpha432.oyvey.util.chat.Signature;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
import static me.alpha432.oyvey.features.commands.MessageSignatures.FAIL;
import static me.alpha432.oyvey.features.commands.MessageSignatures.SUCCESS;
public abstract class Command extends Feature {
public static final int NO_OP = -1;
public static final int SINGLE_FAILURE = 0;
private final String[] aliases;
private String description = "No description was provided for this command.";
public Command(String... aliases) {
super(aliases[0]);
this.aliases = aliases;
}
public abstract void createArgumentBuilder(LiteralArgumentBuilder<CommandManager> builder);
protected int success(String message, Object... format) {
sendMessage(message, SUCCESS, format);
return NO_OP;
}
protected int success() {
return SINGLE_SUCCESS;
}
protected int fail(String message, Object... format) {
sendMessage("{red} " + message, FAIL, format);
return NO_OP;
}
protected int fail() {
return SINGLE_FAILURE;
}
public String[] getAliases() {
return aliases;
}
protected void setDescription(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public boolean isShown() {
return true;
}
public static void sendMessage(String message, Signature identifier) {
if (message == null) return;
ChatUtil.sendMessage(TextUtil.text(message), identifier);
}
public static void sendMessage(String message, Signature identifier, Object... format) {
if (message == null) return;
ChatUtil.sendMessage(TextUtil.text(message, format), identifier);
}
public static LiteralArgumentBuilder<CommandManager> literal(String literal) {
return LiteralArgumentBuilder.literal(literal);
}
public static <T> RequiredArgumentBuilder<CommandManager, T> argument(String name, ArgumentType<T> type) {
return RequiredArgumentBuilder.argument(name, type);
}
}
@@ -0,0 +1,10 @@
package me.alpha432.oyvey.features.commands;
import com.mojang.brigadier.LiteralMessage;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
public class CommandExceptions {
public static SimpleCommandExceptionType invalidArgument(String message, Object... format) {
return new SimpleCommandExceptionType(new LiteralMessage(String.format(message, format)));
}
}
@@ -0,0 +1,10 @@
package me.alpha432.oyvey.features.commands;
import me.alpha432.oyvey.util.chat.Signature;
import me.alpha432.oyvey.util.chat.SimpleSignature;
public class MessageSignatures {
public static final Signature GENERAL = SimpleSignature.fromLong(-1L);
public static final Signature SUCCESS = SimpleSignature.fromLong(0L);
public static final Signature FAIL = SimpleSignature.fromLong(1L);
}
@@ -0,0 +1,160 @@
package me.alpha432.oyvey.features.commands;
import com.mojang.brigadier.arguments.BoolArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.commands.argument.ColorArgumentType;
import me.alpha432.oyvey.features.modules.Module;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.manager.CommandManager;
import me.alpha432.oyvey.util.chat.ChatUtil;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style;
import java.awt.*;
import static com.mojang.brigadier.arguments.BoolArgumentType.getBool;
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
import static me.alpha432.oyvey.features.commands.argument.ColorArgumentType.getColor;
import static me.alpha432.oyvey.features.commands.argument.EnumArgumentType._enum;
import static me.alpha432.oyvey.features.commands.argument.EnumArgumentType.getEnum;
import static me.alpha432.oyvey.features.commands.argument.NumberArgumentType.*;
public class ModuleCommand extends Command {
private final Module module;
public ModuleCommand(Module module) {
super(module.getName().toLowerCase());
setDescription("Command line configuration implementation for \"" + module.getName() + "\"");
this.module = module;
}
@SuppressWarnings("unchecked")
@Override
public void createArgumentBuilder(LiteralArgumentBuilder<CommandManager> builder) {
registerDefault(builder);
for (Setting<?> setting : module.getSettings()) {
Class<?> type = setting.getDefaultValue().getClass();
if (Boolean.class.isAssignableFrom(type)) {
registerBooleanArgument(builder, (Setting<Boolean>) setting);
} else if (Number.class.isAssignableFrom(type)) {
registerNumberArgument(builder, (Setting<? extends Number>) setting);
} else if (Enum.class.isAssignableFrom(type)) {
registerEnumArgument(builder, (Setting<Enum<?>>) setting);
} else if (String.class.isAssignableFrom(type)) {
registerStringArgument(builder, (Setting<String>) setting);
} else if (Color.class.isAssignableFrom(type)) {
registerColorArgument(builder, (Setting<Color>) setting);
}
}
}
private void registerDefault(LiteralArgumentBuilder<CommandManager> builder) {
builder.executes(ctx -> {
var message = Component.empty();
message.append("[ ");
message.append(Component.literal(module.getName())
.withStyle(s -> s.withColor(module.isToggled() ? ChatFormatting.GREEN : ChatFormatting.RED))
.withStyle(s -> s.withClickEvent(suggestCommand("toggle " + module.getName())))
);
message.append(" ]");
for (Setting<?> setting : module.getSettings()) {
message.append("\n");
message.append(Component.literal(setting.getName() + ": ").withStyle(ChatFormatting.GRAY));
message.append(Component.literal(setting.getValueAsString()).withStyle(s -> styledValue(setting, s)));
}
ChatUtil.sendMessage(message, MessageSignatures.SUCCESS);
return success();
});
}
private void registerColorArgument(LiteralArgumentBuilder<CommandManager> builder,
Setting<Color> setting) {
builder.then(literal(setting.getName().toLowerCase())
.then(argument("value", ColorArgumentType.color())
.executes((ctx) -> {
setting.setValue(getColor(ctx, "value"));
Color value = setting.getValue();
return success("Set %s.%s to RGB(%s, %s, %s)",
module.getName(),
setting.getName(),
value.getRed(),
value.getGreen(),
value.getBlue());
})));
}
private void registerStringArgument(LiteralArgumentBuilder<CommandManager> builder,
Setting<String> setting) {
builder.then(literal(setting.getName().toLowerCase())
.then(argument("value", greedyString())
.executes((ctx) -> {
setting.setValue(getString(ctx, "value"));
return settingChangeReturn(setting);
})));
}
@SuppressWarnings("unchecked")
private void registerEnumArgument(LiteralArgumentBuilder<CommandManager> builder,
Setting<Enum<?>> setting) {
Class<Enum<?>> type = (Class<Enum<?>>) setting.getDefaultValue().getClass();
builder.then(literal(setting.getName().toLowerCase())
.then(argument("value", _enum(type))
.executes((ctx) -> {
setting.setValue(getEnum(ctx, "value"));
return settingChangeReturn(setting);
})));
}
@SuppressWarnings("unchecked")
private <T extends Number> void registerNumberArgument(LiteralArgumentBuilder<CommandManager> builder,
Setting<T> setting) {
Class<T> type = (Class<T>) setting.getDefaultValue().getClass();
builder.then(literal(setting.getName().toLowerCase())
.then(argument("value", number(type, minMax(setting.getMin(), setting.getMax())))
.executes((ctx) -> {
setting.setValue(get(type, ctx, "value"));
return settingChangeReturn(setting);
})));
}
private void registerBooleanArgument(LiteralArgumentBuilder<CommandManager> builder,
Setting<Boolean> setting) {
builder.then(literal(setting.getName().toLowerCase())
.then(argument("value", BoolArgumentType.bool())
.executes((ctx) -> {
setting.setValue(getBool(ctx, "value"));
return settingChangeReturn(setting);
})));
}
private int settingChangeReturn(final Setting<?> setting) {
return success("Set %s.%s to %s", module.getName(), setting.getName(), setting.getValue());
}
private static ClickEvent suggestCommand(String command) {
return new ClickEvent.SuggestCommand(OyVey.commandManager.getCommandPrefix() + command);
}
private static Style styledValue(Setting<?> setting, Style style) {
return switch (setting.getValue()) {
case Boolean value -> style.withColor(value ? ChatFormatting.GREEN : ChatFormatting.RED);
case Color value -> style.withColor(value.getRGB());
case Enum<?> ignored -> style.withColor(ChatFormatting.YELLOW);
default -> style.withColor(ChatFormatting.WHITE);
};
}
@Override
public boolean isShown() {
return false;
}
}
@@ -0,0 +1,148 @@
package me.alpha432.oyvey.features.commands.argument;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import me.alpha432.oyvey.features.commands.CommandExceptions;
import net.minecraft.ChatFormatting;
import java.awt.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static me.alpha432.oyvey.features.commands.ArgumentSuggestions.suggest;
public final class ColorArgumentType implements ArgumentType<Color> {
private static final List<String> EXAMPLES = List.of("hsb:55,100,100", "255,0,255", "0,255,255,80");
private static final String[] RGBA_VALUES = {"Red", "Green", "Blue", "Alpha"};
@Override
public Color parse(StringReader reader) throws CommandSyntaxException {
String value = reader.getRemaining();
reader.setCursor(reader.getTotalLength());
// if input begins with "#" its a hex color
if (value.startsWith("#")) {
int color;
if (value.length() == 4) {
char[] c = value.toCharArray();
String hex = "" + c[1] + c[1] + c[2] + c[2] + c[3] + c[3];
color = Integer.parseInt(hex, 16);
} else {
color = Integer.parseInt(value.substring(1), 16);
}
return new Color(color);
}
if (value.startsWith("hsb:")) {
int[] elements = parseColorElements(reader, value.substring(4));
int hue = elements[0];
if (hue < 0 || hue > 360) {
throw CommandExceptions.invalidArgument("Hue value must be between 0-360")
.createWithContext(reader);
}
int saturation = elements[1];
if (saturation < 0 || saturation > 100) {
throw CommandExceptions.invalidArgument("Saturation value must be between 0-100")
.createWithContext(reader);
}
int brightness = elements[2];
if (brightness < 0 || brightness > 100) {
throw CommandExceptions.invalidArgument("Brightness value must be between 0-100")
.createWithContext(reader);
}
return Color.getHSBColor((float) hue / 360.0f,
(float) saturation / 100.0f,
(float) brightness / 100.0f);
}
ChatFormatting format = parseFormatting(value);
if (format != null) {
return new Color(format.getColor(), false);
}
int[] elements = parseColorElements(reader, value);
for (int i = 0; i < elements.length; ++i) {
int element = elements[i];
if (element < 0 || element > 255) {
throw CommandExceptions.invalidArgument("%s value must be between 0-255", RGBA_VALUES[i])
.createWithContext(reader);
}
}
return new Color(elements[0],
elements[1],
elements[2],
elements.length == 4 ? elements[3] : 255);
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
String input = builder.getRemainingLowerCase();
if (input.isEmpty()) {
builder.suggest("#");
builder.suggest("hsb:");
return builder.buildFuture();
}
if (input.startsWith("#")) {
builder.suggest(input);
} else if (input.startsWith("h")) {
if (input.startsWith("hsb:")) builder.suggest(input);
else builder.suggest("hsb:");
} else if (!Character.isDigit(input.charAt(0))){
return suggest(Arrays.stream(ChatFormatting.values())
.filter(ChatFormatting::isColor)
.map(ChatFormatting::getName), builder);
}
return builder.buildFuture();
}
private int[] parseColorElements(StringReader reader, String value) throws CommandSyntaxException {
String[] parts = value.split(",");
if (parts.length < 3) {
throw CommandExceptions.invalidArgument("Color element must have three values (with optional alpha value), either RGB(A) or hsb:HSB")
.createWithContext(reader);
}
int[] elements = new int[parts.length];
for (int i = 0; i < parts.length; ++i) {
elements[i] = Integer.parseInt(parts[i]);
}
return elements;
}
private ChatFormatting parseFormatting(String value) {
for (ChatFormatting format : ChatFormatting.values()) {
if (!format.isColor()) continue;
if (value.equalsIgnoreCase(format.getName())) {
return format;
}
}
return null;
}
@Override
public Collection<String> getExamples() {
return EXAMPLES;
}
public static Color getColor(CommandContext<?> ctx, String name) {
return ctx.getArgument(name, Color.class);
}
public static ColorArgumentType color() {
return new ColorArgumentType();
}
}
@@ -0,0 +1,44 @@
package me.alpha432.oyvey.features.commands.argument;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandExceptionType;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.commands.Command;
import me.alpha432.oyvey.features.commands.CommandExceptions;
import java.util.concurrent.CompletableFuture;
import static me.alpha432.oyvey.features.commands.ArgumentSuggestions.suggest;
public final class CommandArgumentType implements ArgumentType<Command>, CommandExceptionType {
@Override
public Command parse(StringReader reader) throws CommandSyntaxException {
String value = reader.readString().toLowerCase();
for (String alias : OyVey.commandManager.getCommandAliases()) {
if (value.equalsIgnoreCase(alias)) {
return OyVey.commandManager.getCommand(alias);
}
}
throw CommandExceptions.invalidArgument("Invalid command").createWithContext(reader);
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
return suggest(OyVey.commandManager.getCommandAliases(), builder);
}
public static Command getCommand(CommandContext<?> ctx, String name) {
return ctx.getArgument(name, Command.class);
}
public static CommandArgumentType command() {
return new CommandArgumentType();
}
}
@@ -0,0 +1,62 @@
package me.alpha432.oyvey.features.commands.argument;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import me.alpha432.oyvey.features.commands.CommandExceptions;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import static me.alpha432.oyvey.features.commands.ArgumentSuggestions.suggest;
public final class EnumArgumentType<T extends Enum<?>> implements ArgumentType<T> {
private final Map<String, T> enumNameMap = new HashMap<>();
private final T defaultValue;
public EnumArgumentType(Class<T> clazz, T defaultValue) {
this.defaultValue = defaultValue;
for (T constant : clazz.getEnumConstants()) {
enumNameMap.put(constant.toString(), constant);
}
}
@Override
public T parse(StringReader reader) throws CommandSyntaxException {
String value = reader.readString();
for (String name : enumNameMap.keySet()) {
if (value.equalsIgnoreCase(name)) {
return enumNameMap.get(name);
}
}
if (defaultValue != null) {
return defaultValue;
}
throw CommandExceptions.invalidArgument("Invalid enum type").createWithContext(reader);
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
return suggest(enumNameMap.keySet(), builder);
}
@SuppressWarnings("unchecked")
public static <T extends Enum<?>> T getEnum(CommandContext<?> ctx, String name) {
return (T) ctx.getArgument(name, Object.class);
}
public static <T extends Enum<?>> EnumArgumentType<T> _enum(Class<T> clazz) {
return _enum(clazz, null);
}
public static <T extends Enum<?>> EnumArgumentType<T> _enum(Class<T> clazz, T defaultValue) {
return new EnumArgumentType<>(clazz, defaultValue);
}
}
@@ -0,0 +1,40 @@
package me.alpha432.oyvey.features.commands.argument;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import java.lang.reflect.Array;
import java.util.concurrent.CompletableFuture;
public record GreedyArgumentType<T>(ArgumentType<T> parent, Class<T> type) implements ArgumentType<T[]> {
@Override
@SuppressWarnings("unchecked")
public T[] parse(StringReader reader) throws CommandSyntaxException {
String input = reader.getRemaining();
reader.setCursor(reader.getTotalLength());
String[] split = input.split(" ");
T[] values = (T[]) Array.newInstance(type, split.length);
for (int i = 0; i < split.length; i++) {
values[i] = parent.parse(new StringReader(split[i]));
}
return values;
}
@Override public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
String[] s = builder.getRemaining().split(" ", -1);
if (s.length == 0) {
return parent.listSuggestions(context, builder);
}
int st = builder.getStart() + builder.getRemaining().length() - s[s.length - 1].length();
return parent.listSuggestions(context, new SuggestionsBuilder(builder.getInput(), st));
}
public static <T> GreedyArgumentType<T> greedy(ArgumentType<T> parent, Class<T> type) {
return new GreedyArgumentType<>(parent, type);
}
}
@@ -0,0 +1,45 @@
package me.alpha432.oyvey.features.commands.argument;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import me.alpha432.oyvey.features.commands.CommandExceptions;
import me.alpha432.oyvey.features.settings.Bind;
import me.alpha432.oyvey.util.KeyboardUtil;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static me.alpha432.oyvey.features.commands.ArgumentSuggestions.suggest;
public final class KeybindArgumentType implements ArgumentType<Bind> {
private static final List<String> EXAMPLES = List.of("A", "RIGHT_SHIFT", "MOUSE0");
@Override
public Bind parse(StringReader reader) throws CommandSyntaxException {
String input = reader.readString();
Bind bind = KeyboardUtil.getBind(input);
if (bind == null) {
throw CommandExceptions.invalidArgument("Invalid key name").createWithContext(reader);
}
return bind;
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
return suggest(KeyboardUtil.iterateKeys(), builder);
}
@Override
public Collection<String> getExamples() {
return EXAMPLES;
}
public static KeybindArgumentType keybind() {
return new KeybindArgumentType();
}
}
@@ -0,0 +1,57 @@
package me.alpha432.oyvey.features.commands.argument;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.Feature;
import me.alpha432.oyvey.features.commands.CommandExceptions;
import me.alpha432.oyvey.features.modules.Module;
import java.util.Locale;
import java.util.concurrent.CompletableFuture;
import static me.alpha432.oyvey.features.commands.ArgumentSuggestions.suggest;
public record ModuleArgumentType(boolean fullName) implements ArgumentType<Module> {
@Override
public Module parse(StringReader reader) throws CommandSyntaxException {
String value = reader.readString().toLowerCase(Locale.ROOT);
for (Module module : OyVey.moduleManager.getModules()) {
if (value.equalsIgnoreCase(module.getName())) {
return module;
}
}
if (!fullName) {
for (Module module : OyVey.moduleManager.getModules()) {
if (module.getName().toLowerCase(Locale.ROOT).startsWith(value)) {
return module;
}
}
}
throw CommandExceptions.invalidArgument("Invalid module").createWithContext(reader);
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
return suggest(OyVey.moduleManager.getModules(), Feature::getName, builder);
}
public static ModuleArgumentType module() {
return module(false);
}
public static ModuleArgumentType module(boolean fullName) {
return new ModuleArgumentType(fullName);
}
public static Module getModule(CommandContext<?> ctx, String name) {
return ctx.getArgument(name, Module.class);
}
}
@@ -0,0 +1,70 @@
package me.alpha432.oyvey.features.commands.argument;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import me.alpha432.oyvey.features.commands.CommandExceptions;
public record NumberArgumentType<T extends Number>(Class<T> type, Constraint<T> constraint) implements ArgumentType<T> {
@SuppressWarnings("unchecked")
@Override
public T parse(StringReader reader) throws CommandSyntaxException {
String input = reader.readString();
T value = null;
try {
if (type.isAssignableFrom(Integer.class)) {
value = (T) Integer.valueOf(input);
} else if (type.isAssignableFrom(Double.class)) {
value = (T) Double.valueOf(input);
} else if (type.isAssignableFrom(Float.class)) {
value = (T) Float.valueOf(input);
} else if (type.isAssignableFrom(Long.class)) {
value = (T) Long.valueOf(input);
}
} catch (NumberFormatException ignored) {
}
if (value == null) {
throw CommandExceptions.invalidArgument("Could not parse \"%s\"", input)
.createWithContext(reader);
}
if (constraint != null) {
constraint.validate(reader, value);
}
return value;
}
public static <T extends Number> Constraint<T> minMax(T min, T max) {
return (reader, input) -> {
double value = input.doubleValue();
if (min.doubleValue() > value) {
throw CommandExceptions.invalidArgument("Value is less than minimum(%s)", min.toString())
.createWithContext(reader);
}
if (max.doubleValue() < value) {
throw CommandExceptions.invalidArgument("Value is more than maximum(%s)", max.toString())
.createWithContext(reader);
}
};
}
public static <T extends Number> T get(Class<T> type, CommandContext<?> ctx, String name) {
return ctx.getArgument(name, type);
}
public static <T extends Number> NumberArgumentType<T> number(Class<T> type) {
return number(type, null);
}
public static <T extends Number> NumberArgumentType<T> number(Class<T> type, Constraint<T> constraint) {
return new NumberArgumentType<>(type, constraint);
}
public interface Constraint<T extends Number> {
void validate(StringReader reader, T input) throws CommandSyntaxException;
}
}
@@ -0,0 +1,64 @@
package me.alpha432.oyvey.features.commands.impl;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.alpha432.oyvey.event.impl.input.KeyInputEvent;
import me.alpha432.oyvey.event.system.Subscribe;
import me.alpha432.oyvey.features.commands.Command;
import me.alpha432.oyvey.features.modules.Module;
import me.alpha432.oyvey.features.settings.Bind;
import me.alpha432.oyvey.manager.CommandManager;
import me.alpha432.oyvey.util.KeyboardUtil;
import static me.alpha432.oyvey.features.commands.argument.KeybindArgumentType.keybind;
import static me.alpha432.oyvey.features.commands.argument.ModuleArgumentType.module;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_ESCAPE;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_UNKNOWN;
public class BindCommand extends Command {
private Module module;
public BindCommand() {
super("bind", "setbind");
setDescription("Sets a key bind for a module");
EVENT_BUS.register(this);
}
@Override
public void createArgumentBuilder(LiteralArgumentBuilder<CommandManager> builder) {
builder.then(argument("module", module(true)).then(
argument("keybind", keybind()).executes(ctx -> {
Module module = ctx.getArgument("module", Module.class);
Bind bind = ctx.getArgument("keybind", Bind.class);
module.bind.setValue(bind);
return success("Bind for {green} %s {} set to {green} %s",
module.getName(),
KeyboardUtil.getKeyName(bind)
);
})
).executes((ctx) -> {
module = ctx.getArgument("module", Module.class);
return success("Press any key...");
}));
}
@Subscribe
public void onKey(final KeyInputEvent event) {
if (nullCheck() || module == null || event.getKey() == GLFW_KEY_UNKNOWN) {
return;
}
if (event.getKey() == GLFW_KEY_ESCAPE) {
module = null;
fail("Operation canceled.");
return;
}
module.bind.setValue(Bind.keyboard(event.getKey()));
success("Bind for {green} %s {} set to {green} %s",
module.getName(),
KeyboardUtil.getKeyName(module.getBind())
);
module = null;
}
}
@@ -0,0 +1,30 @@
package me.alpha432.oyvey.features.commands.impl;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.alpha432.oyvey.features.commands.Command;
import me.alpha432.oyvey.features.modules.Module;
import me.alpha432.oyvey.manager.CommandManager;
import static me.alpha432.oyvey.features.commands.argument.ModuleArgumentType.getModule;
import static me.alpha432.oyvey.features.commands.argument.ModuleArgumentType.module;
public class DrawnCommand extends Command {
public DrawnCommand() {
super("drawn");
setDescription("Sets a module to be drawn to the arraylist or not");
}
@Override
public void createArgumentBuilder(LiteralArgumentBuilder<CommandManager> builder) {
builder.then(argument("module", module())
.executes((ctx) -> {
Module module = getModule(ctx, "module");
module.setDrawn(!module.isDrawn());
boolean drawn = module.isDrawn();
return success("{gray} %s {reset} is now %s %s",
module.getDisplayName(),
drawn ? "{green}" : "{red}",
drawn ? "drawn" : "hidden");
}));
}
}
@@ -0,0 +1,58 @@
package me.alpha432.oyvey.features.commands.impl;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.commands.Command;
import me.alpha432.oyvey.manager.CommandManager;
import java.util.List;
import java.util.StringJoiner;
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import static com.mojang.brigadier.arguments.StringArgumentType.word;
public class FriendCommand extends Command {
public FriendCommand() {
super("friend", "friends", "f");
setDescription("Manages your friends list");
}
@Override
public void createArgumentBuilder(LiteralArgumentBuilder<CommandManager> builder) {
builder.then(literal("list")
.executes((ctx) -> {
List<String> friends = OyVey.friendManager.getFriends();
if (friends.isEmpty()) {
return success("You have no friends :(");
}
StringJoiner joiner = new StringJoiner(",");
friends.forEach(joiner::add);
return success("Friends (%s): %s", friends.size(), joiner);
}))
.then(literal("clear")
.executes((ctx) -> {
OyVey.friendManager.getFriends().clear();
return success("Cleared friends list");
}))
.then(literal("add")
.then(argument("username", word())
.executes((ctx) -> {
String username = getString(ctx, "username");
if (OyVey.friendManager.isFriend(username)) {
return success("{green} %s {reset} is already on your friends list.", username);
}
OyVey.friendManager.addFriend(username);
return success("Added {green} %s {reset} to your friends list", username);
})))
.then(literal("remove")
.then(argument("username", word())
.executes((ctx) -> {
String username = getString(ctx, "username");
if (!OyVey.friendManager.isFriend(username)) {
return success("{green} %s {reset} is not on your friends list.", username);
}
OyVey.friendManager.removeFriend(username);
return success("Removed {green} %s {reset} from your friends list", username);
})));
}
}
@@ -0,0 +1,118 @@
package me.alpha432.oyvey.features.commands.impl;
import com.google.common.collect.Iterables;
import com.mojang.brigadier.ParseResults;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.tree.CommandNode;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.commands.Command;
import me.alpha432.oyvey.manager.CommandManager;
import me.alpha432.oyvey.util.chat.ChatUtil;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ComponentUtils;
import net.minecraft.network.chat.MutableComponent;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static me.alpha432.oyvey.features.commands.MessageSignatures.GENERAL;
import static me.alpha432.oyvey.features.commands.argument.CommandArgumentType.command;
import static me.alpha432.oyvey.features.commands.argument.CommandArgumentType.getCommand;
import static me.alpha432.oyvey.features.commands.argument.NumberArgumentType.get;
import static me.alpha432.oyvey.features.commands.argument.NumberArgumentType.number;
import static me.alpha432.oyvey.util.TextUtil.text;
import static me.alpha432.oyvey.util.chat.ChatUtil.prefix;
import static me.alpha432.oyvey.util.chat.ChatUtil.withPrefix;
public class HelpCommand extends Command {
private static final int ITEMS_PER_PAGE = 5;
public HelpCommand() {
super("help", "commands", "h", "cmds");
setDescription("Displays all executable commands and additional information");
}
@Override
public void createArgumentBuilder(LiteralArgumentBuilder<CommandManager> builder) {
builder.then(argument("page", number(Integer.class))
.executes((ctx) -> helpCommands(ctx, get(Integer.class, ctx, "page"))))
.then(argument("command_name", command())
.executes(this::helpSpecific))
.executes((ctx) -> helpCommands(ctx, 1));
}
private int helpSpecific(CommandContext<CommandManager> ctx) {
Command command = getCommand(ctx, "command_name");
MutableComponent text = Component.empty();
text.append(withPrefix("Usages for %s:\n", command.getName()));
ParseResults<CommandManager> results = ctx.getSource().getDispatcher()
.parse(command.getName(), ctx.getSource());
if (results.getContext().getNodes().isEmpty()) {
text.append(withPrefix("No usages available"));
} else {
Map<CommandNode<CommandManager>, String> smartUsages = ctx.getSource().getDispatcher().getSmartUsage(
Iterables.getLast(results.getContext().getNodes()).getNode(), ctx.getSource());
List<Component> usages = new ArrayList<>();
for (String usage : smartUsages.values()) {
usages.add(text(" {gray}%s%s %s", ctx.getSource().getCommandPrefix(), command.getName(), usage));
}
text.append(ComponentUtils.formatList(usages, Component.literal("\n")));
}
ChatUtil.sendClientSideMessage(text, GENERAL);
return success();
}
private int helpCommands(CommandContext<CommandManager> ctx, int page) {
List<Command> commands = ctx.getSource().getCommands()
.stream().filter(Command::isShown).toList();
int pages = Math.max(1, (int) Math.ceil((double) commands.size() / ITEMS_PER_PAGE));
int pageIndex = page < 1 || page > pages ? 1 : page;
List<Command> paginated = commands.subList((pageIndex - 1) * ITEMS_PER_PAGE,
Math.min(commands.size(), pageIndex * ITEMS_PER_PAGE));
MutableComponent text = Component.empty();
text.append(withPrefix("Commands (%s): \n", commands.size()));
for (Command command : paginated) {
String aliases = String.join(", ", command.getAliases());
String description = command.getDescription();
text.append(withPrefix("{dark_gray} %s: {reset}\n %s\n", aliases, description));
}
text.append(buildPages(pageIndex, pages));
ChatUtil.sendClientSideMessage(text, GENERAL);
return success();
}
private static Component buildPages(int index, int pages) {
String command = OyVey.commandManager.getCommandPrefix() + "help ";
MutableComponent text = prefix();
boolean hasPages = pages > 1;
if (hasPages && index != 1)
text.append(suggest(Component.literal(" <"), command + (index - 1)));
text.append(text(" Page %d/%d", index, pages));
if (hasPages && index != pages)
text.append(suggest(Component.literal(" > "), command + (index + 1)));
return text;
}
private static Component suggest(MutableComponent component, String command) {
return component.withStyle(s -> s.withClickEvent(new ClickEvent.SuggestCommand(command.formatted())));
}
}
@@ -0,0 +1,28 @@
package me.alpha432.oyvey.features.commands.impl;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.alpha432.oyvey.features.commands.Command;
import me.alpha432.oyvey.manager.CommandManager;
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
public class PrefixCommand extends Command {
public PrefixCommand() {
super("prefix", "setprefix");
setDescription("Sets the command prefix");
}
@Override
public void createArgumentBuilder(LiteralArgumentBuilder<CommandManager> builder) {
builder.then(argument("prefix", greedyString())
.executes((ctx) -> {
String prefix = getString(ctx, "prefix").trim();
if (prefix.isBlank()) {
return fail("Prefix must contain at least one character");
}
ctx.getSource().setCommandPrefix(prefix);
return success("Prefix changed to {green} %s", prefix);
}));
}
}
@@ -0,0 +1,30 @@
package me.alpha432.oyvey.features.commands.impl;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.alpha432.oyvey.features.commands.Command;
import me.alpha432.oyvey.features.modules.Module;
import me.alpha432.oyvey.manager.CommandManager;
import static me.alpha432.oyvey.features.commands.argument.ModuleArgumentType.getModule;
import static me.alpha432.oyvey.features.commands.argument.ModuleArgumentType.module;
public class ToggleCommand extends Command {
public ToggleCommand() {
super("toggle", "t");
setDescription("Toggles a module");
}
@Override
public void createArgumentBuilder(LiteralArgumentBuilder<CommandManager> builder) {
builder.then(argument("module", module(true))
.executes((ctx) -> {
Module module = getModule(ctx, "module");
module.toggle();
boolean toggled = module.isEnabled();
return success("{gray} %s {reset} is now %s %s",
module.getDisplayName(),
toggled ? "{green}" : "{red}",
toggled ? "enabled" : "disabled");
}));
}
}
@@ -0,0 +1,100 @@
package me.alpha432.oyvey.features.gui;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.Feature;
import me.alpha432.oyvey.features.gui.items.buttons.ModuleButton;
import me.alpha432.oyvey.features.modules.Module;
import me.alpha432.oyvey.features.modules.client.HudModule;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.input.CharacterEvent;
import net.minecraft.client.input.KeyEvent;
import net.minecraft.client.input.MouseButtonEvent;
import net.minecraft.network.chat.Component;
import java.util.ArrayList;
import java.util.Comparator;
public class HudEditorScreen extends Screen {
private static HudEditorScreen INSTANCE;
private final ArrayList<Widget> components = new ArrayList<>();
public HudModule currentDragging;
public boolean anyHover;
private HudEditorScreen() {
super(Component.literal("oyvey-hudeditor"));
load();
}
private void load() {
Widget hud = new Widget("Hud", 50, 50, true);
OyVey.moduleManager.stream()
.filter(m -> m.getCategory() == Module.Category.HUD && !m.hidden)
.map(ModuleButton::new)
.forEach(hud::addButton);
this.components.add(hud);
this.components.forEach(component -> component.getItems().sort(Comparator.comparing(Feature::getName)));
}
@Override
public void render(GuiGraphics context, int mouseX, int mouseY, float delta) {
anyHover = false;
this.components.forEach(component -> component.drawScreen(context, mouseX, mouseY, delta));
}
@Override
public boolean mouseClicked(MouseButtonEvent click, boolean doubled) {
this.components.forEach(component -> component.mouseClicked((int) click.x(), (int) click.y(), click.button()));
return super.mouseClicked(click, doubled);
}
@Override
public boolean mouseReleased(MouseButtonEvent click) {
this.components.forEach(component -> component.mouseReleased((int) click.x(), (int) click.y(), click.button()));
return super.mouseReleased(click);
}
@Override
public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) {
if (verticalAmount < 0) {
this.components.forEach(component -> component.setY(component.getY() - 10));
} else if (verticalAmount > 0) {
this.components.forEach(component -> component.setY(component.getY() + 10));
}
return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount);
}
@Override
public boolean keyPressed(KeyEvent input) {
this.components.forEach(component -> component.onKeyPressed(input.input()));
return super.keyPressed(input);
}
@Override
public boolean charTyped(CharacterEvent input) {
this.components.forEach(component -> component.onKeyTyped(input.codepointAsString(), input.modifiers()));
return super.charTyped(input);
}
@Override
public boolean isPauseScreen() {
return false;
}
@Override // ignore 1.21.8 menu blur thing
public void renderBackground(GuiGraphics context, int mouseX, int mouseY, float delta) {
}
public ArrayList<Widget> getComponents() {
return components;
}
public static HudEditorScreen getInstance() {
if (INSTANCE == null) {
INSTANCE = new HudEditorScreen();
}
return INSTANCE;
}
}
@@ -0,0 +1,147 @@
package me.alpha432.oyvey.features.gui;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.Feature;
import me.alpha432.oyvey.features.gui.items.buttons.ModuleButton;
import me.alpha432.oyvey.features.modules.Module;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.input.CharacterEvent;
import net.minecraft.client.input.KeyEvent;
import net.minecraft.client.input.MouseButtonEvent;
import net.minecraft.network.chat.Component;
import java.awt.*;
import java.util.ArrayList;
import java.util.Comparator;
public class OyVeyGui extends Screen {
private static OyVeyGui INSTANCE;
private static Color colorClipboard = null;
static {
INSTANCE = new OyVeyGui();
}
private Screen lastScreen;
private final ArrayList<Widget> widgets = new ArrayList<>();
public OyVeyGui() {
super(Component.literal("OyVey"));
setInstance();
load();
}
public static OyVeyGui getInstance() {
if (INSTANCE == null) {
INSTANCE = new OyVeyGui();
}
return INSTANCE;
}
public static OyVeyGui getClickGui() {
return OyVeyGui.getInstance();
}
public static void open(Screen previous) {
OyVeyGui gui = getInstance();
gui.lastScreen = previous;
Minecraft.getInstance().setScreen(gui);
}
@Override
public void onClose() {
Screen previous = this.lastScreen;
this.lastScreen = null;
this.minecraft.setScreen(previous);
}
private void setInstance() {
INSTANCE = this;
}
private void load() {
int x = -84;
for (Module.Category category : OyVey.moduleManager.getCategories()) {
if (category == Module.Category.HUD) continue;
Widget panel = new Widget(category.getName(), x += 90, 4, true);
OyVey.moduleManager.stream()
.filter(m -> m.getCategory() == category && !m.hidden)
.map(ModuleButton::new)
.forEach(panel::addButton);
this.widgets.add(panel);
}
this.widgets.forEach(components -> components.getItems().sort(Comparator.comparing(Feature::getName)));
}
@Override
public void render(GuiGraphics context, int mouseX, int mouseY, float delta) {
if (lastScreen != null) {
lastScreen.renderBackground(context, Integer.MIN_VALUE, Integer.MIN_VALUE, delta);
lastScreen.render(context, Integer.MIN_VALUE, Integer.MIN_VALUE, delta);
context.nextStratum();
}
context.fill(0, 0, context.guiWidth(), context.guiHeight(), new Color(0, 0, 0, 120).hashCode());
this.widgets.forEach(components -> components.drawScreen(context, mouseX, mouseY, delta));
}
@Override
public boolean mouseClicked(MouseButtonEvent click, boolean doubled) {
this.widgets.forEach(components -> components.mouseClicked((int) click.x(), (int) click.y(), click.button()));
return super.mouseClicked(click, doubled);
}
@Override
public boolean mouseReleased(MouseButtonEvent click) {
this.widgets.forEach(components -> components.mouseReleased((int) click.x(), (int) click.y(), click.button()));
return super.mouseReleased(click);
}
@Override
public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) {
if (verticalAmount < 0) {
this.widgets.forEach(component -> component.setY(component.getY() - 10));
} else if (verticalAmount > 0) {
this.widgets.forEach(component -> component.setY(component.getY() + 10));
}
return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount);
}
@Override
public boolean keyPressed(KeyEvent input) {
this.widgets.forEach(component -> component.onKeyPressed(input.input()));
return super.keyPressed(input);
}
@Override
public boolean charTyped(CharacterEvent input) {
this.widgets.forEach(component -> component.onKeyTyped(input.codepointAsString(), input.modifiers()));
return super.charTyped(input);
}
@Override
public boolean isPauseScreen() {
return false;
}
@Override
public void renderBackground(GuiGraphics context, int mouseX, int mouseY, float delta) {
}//ignore 1.21.8 blur thing
public final ArrayList<Widget> getComponents() {
return this.widgets;
}
public int getTextOffset() {
return -6;
}
public static Color getColorClipboard() {
return colorClipboard;
}
public static void setColorClipboard(Color color) {
colorClipboard = color;
}
}
@@ -0,0 +1,198 @@
package me.alpha432.oyvey.features.gui;
import me.alpha432.oyvey.features.Feature;
import me.alpha432.oyvey.features.gui.items.Item;
import me.alpha432.oyvey.features.gui.items.buttons.Button;
import me.alpha432.oyvey.features.modules.client.ClickGuiModule;
import me.alpha432.oyvey.util.ColorUtil;
import me.alpha432.oyvey.util.render.RenderUtil;
import me.alpha432.oyvey.util.render.ScissorUtil;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
import net.minecraft.sounds.SoundEvents;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class Widget
extends Feature {
protected GuiGraphics context;
private final List<Item> items = new ArrayList<>();
public boolean drag;
private int x;
private int y;
private int x2;
private int y2;
private int width;
private int height;
private boolean open;
private boolean hidden = false;
public Widget(String name, int x, int y, boolean open) {
super(name);
this.x = x;
this.y = y;
this.width = 88;
this.height = 18;
this.open = open;
}
private void drag(int mouseX, int mouseY) {
if (!this.drag) {
return;
}
this.x = this.x2 + mouseX;
this.y = this.y2 + mouseY;
}
public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) {
this.context = context;
this.drag(mouseX, mouseY);
float totalItemHeight = this.open ? this.getTotalItemHeight() - 2.0f : 0.0f;
int color = ClickGuiModule.getInstance().topColor.getValue().getRGB();
context.fill(this.x, this.y - 1, this.x + this.width, this.y + this.height - 6, ClickGuiModule.getInstance().rainbow.getValue() ? ColorUtil.rainbow(ClickGuiModule.getInstance().rainbowHue.getValue()).getRGB() : color);
if (this.open) {
RenderUtil.rect(context, this.x, (float) this.y + 12.5f, this.x + this.width, (float) (this.y + this.height) + totalItemHeight, 0x77000000);
}
drawString(this.getName(), (float) this.x + 3.0f, (float) this.y - 4.0f - (float) OyVeyGui.getClickGui().getTextOffset(), -1);
ScissorUtil.enable(context, x, 0, x + width, mc.getWindow().getGuiScaledHeight());
if (this.open) {
float y = (float) (this.getY() + this.getHeight()) - 3.0f;
for (Item item : this.getItems()) {
if (item.isHidden()) continue;
item.setLocation((float) this.x + 2.0f, y);
item.setWidth(this.getWidth() - 4);
if (item.isHovering(mouseX, mouseY)) {
ScissorUtil.disable(context);
}
item.drawScreen(context, mouseX, mouseY, partialTicks);
if (item.isHovering(mouseX, mouseY)) {
ScissorUtil.enable(context);
}
y += (float) item.getHeight() + 2f;
}
}
ScissorUtil.disable(context);
}
public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
if (mouseButton == 0 && this.isHovering(mouseX, mouseY)) {
this.x2 = this.x - mouseX;
this.y2 = this.y - mouseY;
OyVeyGui.getClickGui().getComponents().forEach(component -> {
if (component.drag) {
component.drag = false;
}
});
this.drag = true;
return;
}
if (mouseButton == 1 && this.isHovering(mouseX, mouseY)) {
this.open = !this.open;
mc.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1f));
return;
}
if (!this.open) {
return;
}
this.getItems().forEach(item -> item.mouseClicked(mouseX, mouseY, mouseButton));
}
public void mouseReleased(int mouseX, int mouseY, int releaseButton) {
if (releaseButton == 0) {
this.drag = false;
}
if (!this.open) {
return;
}
this.getItems().forEach(item -> item.mouseReleased(mouseX, mouseY, releaseButton));
}
public void onKeyTyped(String typedChar, int keyCode) {
if (!this.open) {
return;
}
this.getItems().forEach(item -> item.onKeyTyped(typedChar, keyCode));
}
public void onKeyPressed(int key) {
if (!open) return;
this.getItems().forEach(item -> item.onKeyPressed(key));
}
public void addButton(Button button) {
this.items.add(button);
}
public int getX() {
return this.x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return this.y;
}
public void setY(int y) {
this.y = y;
}
public int getWidth() {
return this.width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return this.height;
}
public void setHeight(int height) {
this.height = height;
}
public boolean isHidden() {
return this.hidden;
}
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
public boolean isOpen() {
return this.open;
}
public final List<Item> getItems() {
return this.items;
}
public boolean isHovering(int mouseX, int mouseY) {
return mouseX >= this.getX() && mouseX <= this.getX() + this.getWidth() && mouseY >= this.getY() && mouseY <= this.getY() + this.getHeight() - (this.open ? 2 : 0);
}
private float getTotalItemHeight() {
float height = 0.0f;
for (Item item : this.getItems()) {
height += (float) item.getHeight() + 2;
}
return height;
}
protected void drawString(String text, double x, double y, Color color) {
drawString(text, x, y, color.hashCode());
}
protected void drawString(String text, double x, double y, int color) {
context.drawString(mc.font, text, (int) x, (int) y, color);
}
}
@@ -0,0 +1,87 @@
package me.alpha432.oyvey.features.gui.items;
import me.alpha432.oyvey.features.Feature;
import net.minecraft.client.gui.GuiGraphics;
import java.awt.*;
public class Item
extends Feature {
protected float x;
protected float y;
protected int width;
protected int height;
private boolean hidden;
public Item(String name) {
super(name);
}
public void setLocation(float x, float y) {
this.x = x;
this.y = y;
}
public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) {
}
public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
}
public void mouseReleased(int mouseX, int mouseY, int releaseButton) {
}
public void update() {
}
public void onKeyTyped(String typedChar, int keyCode) {
}
public void onKeyPressed(int key) {
}
public float getX() {
return this.x;
}
public float getY() {
return this.y;
}
public int getWidth() {
return this.width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return this.height;
}
public void setHeight(int height) {
this.height = height;
}
public boolean isHidden() {
return this.hidden;
}
public boolean setHidden(boolean hidden) {
this.hidden = hidden;
return this.hidden;
}
protected void drawString(GuiGraphics context, String text, double x, double y, Color color) {
drawString(context, text, x, y, color.getRGB());
}
protected void drawString(GuiGraphics context, String text, double x, double y, int color) {
context.drawString(mc.font, text, (int) x, (int) y, color);
}
public boolean isHovering(int mouseX, int mouseY) {
return false;
}
}
@@ -0,0 +1,80 @@
package me.alpha432.oyvey.features.gui.items.buttons;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.gui.OyVeyGui;
import me.alpha432.oyvey.features.modules.client.ClickGuiModule;
import me.alpha432.oyvey.features.settings.Bind;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.util.KeyboardUtil;
import me.alpha432.oyvey.util.render.RenderUtil;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
import net.minecraft.sounds.SoundEvents;
import org.lwjgl.glfw.GLFW;
public class BindButton
extends Button {
private final Setting<Bind> setting;
public boolean isListening;
public BindButton(Setting<Bind> setting) {
super(setting.getName());
this.setting = setting;
this.width = 15;
}
@Override
public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) {
int color = ClickGuiModule.getInstance().color.getValue().getRGB();
RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width + 7.4f, this.y + (float) this.height - 0.5f, this.getState() ? (!this.isHovering(mouseX, mouseY) ? 0x11555555 : -2007673515) : (!this.isHovering(mouseX, mouseY) ? OyVey.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : OyVey.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha())));
if (this.isListening) {
drawString(context, "Press a Key...", this.x + 2.3f, this.y - 1.7f - (float) OyVeyGui.getClickGui().getTextOffset(), -1);
} else {
String str = KeyboardUtil.getKeyName(setting.getValue());
drawString(context, this.setting.getName() + " " + ChatFormatting.GRAY + str, this.x + 2.3f, this.y - 1.7f - (float) OyVeyGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406);
}
}
@Override
public void update() {
this.setHidden(!this.setting.isVisible());
}
@Override
public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
super.mouseClicked(mouseX, mouseY, mouseButton);
if (this.isListening) {
if (mouseButton != 0 && mouseButton != 1) {
this.setting.setValue(new Bind(-mouseButton - 2));
this.onMouseClick();
}
} else if (this.isHovering(mouseX, mouseY)) {
mc.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1f));
}
}
@Override
public void onKeyPressed(int key) {
if (this.isListening) {
Bind bind = new Bind(key);
if (key == GLFW.GLFW_KEY_DELETE
|| key == GLFW.GLFW_KEY_BACKSPACE
|| key == GLFW.GLFW_KEY_ESCAPE) {
bind = new Bind(-1);
}
this.setting.setValue(bind);
this.onMouseClick();
}
}
@Override
public void toggle() {
this.isListening = !this.isListening;
}
@Override
public boolean getState() {
return !this.isListening;
}
}
@@ -0,0 +1,51 @@
package me.alpha432.oyvey.features.gui.items.buttons;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.gui.OyVeyGui;
import me.alpha432.oyvey.features.modules.client.ClickGuiModule;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.util.render.RenderUtil;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
import net.minecraft.sounds.SoundEvents;
public class BooleanButton
extends Button {
private final Setting<Boolean> setting;
public BooleanButton(Setting<Boolean> setting) {
super(setting.getName());
this.setting = setting;
this.width = 15;
}
@Override
public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) {
RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width + 7.4f, this.y + (float) this.height - 0.5f, this.getState() ? (!this.isHovering(mouseX, mouseY) ? OyVey.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : OyVey.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha())) : (!this.isHovering(mouseX, mouseY) ? 0x11555555 : -2007673515));
drawString(context, this.getName(), this.x + 2.3f, this.y - 1.7f - (float) OyVeyGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406);
}
@Override
public void update() {
this.setHidden(!this.setting.isVisible());
}
@Override
public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
super.mouseClicked(mouseX, mouseY, mouseButton);
if (this.isHovering(mouseX, mouseY)) {
mc.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1f));
}
}
@Override
public void toggle() {
this.setting.setValue(!this.setting.getValue());
}
@Override
public boolean getState() {
return this.setting.getValue();
}
}
@@ -0,0 +1,60 @@
package me.alpha432.oyvey.features.gui.items.buttons;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.gui.OyVeyGui;
import me.alpha432.oyvey.features.gui.Widget;
import me.alpha432.oyvey.features.gui.items.Item;
import me.alpha432.oyvey.features.modules.client.ClickGuiModule;
import me.alpha432.oyvey.util.render.RenderUtil;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
import net.minecraft.sounds.SoundEvents;
public class Button
extends Item {
private boolean state;
public Button(String name) {
super(name);
this.height = 15;
}
@Override
public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) {
RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width, this.y + (float) this.height - 0.5f, this.getState() ? (!this.isHovering(mouseX, mouseY) ? OyVey.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : OyVey.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha())) : (!this.isHovering(mouseX, mouseY) ? 0x11555555 : -2007673515));
drawString(context, this.getName(), this.x + 2.3f, this.y - 2.0f - (float) OyVeyGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406);
}
@Override
public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
if (mouseButton == 0 && this.isHovering(mouseX, mouseY)) {
this.onMouseClick();
}
}
public void onMouseClick() {
this.state = !this.state;
this.toggle();
mc.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1f));
}
public void toggle() {
}
public boolean getState() {
return this.state;
}
@Override
public int getHeight() {
return 14;
}
public boolean isHovering(int mouseX, int mouseY) {
for (Widget widget : OyVeyGui.getClickGui().getComponents()) {
if (!widget.drag) continue;
return false;
}
return (float) mouseX >= this.getX() && (float) mouseX <= this.getX() + (float) this.getWidth() && (float) mouseY >= this.getY() && (float) mouseY < this.getY() + (float) this.height;
}
}
@@ -0,0 +1,201 @@
package me.alpha432.oyvey.features.gui.items.buttons;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.gui.OyVeyGui;
import me.alpha432.oyvey.features.gui.Widget;
import me.alpha432.oyvey.features.modules.client.ClickGuiModule;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.util.render.RenderUtil;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.util.Mth;
import java.awt.*;
public class ColorButton extends Button {
private static final int PICKER_SIZE = 84;
private final Setting<Color> setting;
private boolean open = false;
private boolean hoveringHue = false, hoveringColor = false, hoveringAlpha = false, hoveringCopy = false, hoveringPaste = false;
private boolean draggingHue = false, draggingColor = false, draggingAlpha = false;
private float[] hsb;
public ColorButton(Setting<Color> setting) {
super(setting.getName());
this.setting = setting;
this.width = 15;
hsb = Color.RGBtoHSB(setting.getValue().getRed(), setting.getValue().getGreen(), setting.getValue().getBlue(), null);
}
@Override
public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) {
Color currentColor = setting.getValue();
Color outlineColor = Color.BLACK;
Color realColor = Color.getHSBColor(hsb[0], 1, 1);
RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width + 7.4f, this.y + (float) this.height - 0.5f,
!this.isHovering(mouseX, mouseY) ? 0x11555555 : -2007673515);
RenderUtil.rect(context, this.x + (float) this.width - 4f, this.y + 3f,
this.x + (float) this.width + 5.0f, this.y + (float) this.height - 2.5f,
new Color(currentColor.getRGB(), false).getRGB());
drawString(context, this.getName(), this.x + 2.3f, this.y - 1.7f - (float) OyVeyGui.getClickGui().getTextOffset(), -1);
if (open) {
float yOffset = this.height + 1;
int availableWidth = this.width + 3;
int pickerWidth = Math.min(PICKER_SIZE, availableWidth);
float pickerX = this.x + 2.0f;
int dragX = Mth.clamp(mouseX - (int) pickerX, 0, pickerWidth);
int dragY = Mth.clamp(mouseY - (int) (getY() + yOffset), 0, pickerWidth);
float dragHue = Math.max(pickerWidth * hsb[0] - .5f, 1);
float dragSaturation = Math.max(pickerWidth * hsb[1] - 1, 2);
float dragBrightness = Math.max(pickerWidth * (1.0f - hsb[2]) - 1, 2);
float dragAlpha = Math.max(pickerWidth * (currentColor.getAlpha() / 255.0f) - .5f, 1);
RenderUtil.horizontalGradient(context, pickerX, this.y + yOffset, pickerX + pickerWidth, this.y + yOffset + pickerWidth, Color.WHITE, realColor);
RenderUtil.verticalGradient(context, pickerX, this.y + yOffset, pickerX + pickerWidth, this.y + yOffset + pickerWidth, new Color(0, 0, 0, 0), Color.BLACK);
RenderUtil.rect(context, pickerX, this.y + yOffset, pickerX + pickerWidth, this.y + yOffset + pickerWidth, outlineColor.getRGB(), 1.0f);
hoveringColor = isHoveringArea(mouseX, mouseY, pickerX, this.y + yOffset, pickerX + pickerWidth, this.y + yOffset + pickerWidth);
if (dragSaturation < pickerWidth && dragBrightness < pickerWidth) {
RenderUtil.rect(context, pickerX + dragSaturation - 2.5f, this.y + yOffset + dragBrightness - 2.5f,
pickerX + dragSaturation + 0.5f, this.y + yOffset + dragBrightness + 0.5f, outlineColor.getRGB());
RenderUtil.rect(context, pickerX + dragSaturation - 1.5f, this.y + yOffset + dragBrightness - 1.5f,
pickerX + dragSaturation - 0.5f, this.y + yOffset + dragBrightness - 0.5f, Color.WHITE.getRGB());
}
if (draggingColor) {
hsb[1] = (float) dragX / pickerWidth;
hsb[2] = 1.0f - (float) dragY / pickerWidth;
setColor(hsb);
}
yOffset += pickerWidth + 2;
RenderUtil.horizontalGradient(context, pickerX, this.y + yOffset, pickerX + pickerWidth, this.y + yOffset + 8,
new Color(currentColor.getRed(), currentColor.getGreen(), currentColor.getBlue(), 0),
new Color(currentColor.getRed(), currentColor.getGreen(), currentColor.getBlue(), 255));
RenderUtil.rect(context, pickerX, this.y + yOffset, pickerX + pickerWidth, this.y + yOffset + 8, outlineColor.getRGB(), 1.0f);
hoveringAlpha = isHoveringArea(mouseX, mouseY, pickerX, this.y + yOffset, pickerX + pickerWidth, this.y + yOffset + 8);
RenderUtil.rect(context, pickerX + dragAlpha - 1.5f, this.y + yOffset - 1,
pickerX + dragAlpha + 1.5f, this.y + yOffset + 9, outlineColor.getRGB());
RenderUtil.rect(context, pickerX + dragAlpha - 0.5f, this.y + yOffset,
pickerX + dragAlpha + 0.5f, this.y + yOffset + 8, Color.WHITE.getRGB());
if (draggingAlpha) {
setColor(hsb, (int) (255 * (float) dragX / pickerWidth));
}
yOffset += 10;
for (float i = 0; i < pickerWidth; i += 0.5f) {
RenderUtil.rect(context, pickerX + i, this.y + yOffset, pickerX + i + 0.5f, this.y + yOffset + 8,
Color.getHSBColor(i / pickerWidth, 1.0f, 1.0f).getRGB());
}
RenderUtil.rect(context, pickerX, this.y + yOffset, pickerX + pickerWidth, this.y + yOffset + 8, outlineColor.getRGB(), 1.0f);
hoveringHue = isHoveringArea(mouseX, mouseY, pickerX, this.y + yOffset, pickerX + pickerWidth, this.y + yOffset + 8);
if (dragHue < pickerWidth) {
RenderUtil.rect(context, pickerX + dragHue - 1.5f, this.y + yOffset - 1,
pickerX + dragHue + 1.5f, this.y + yOffset + 9, outlineColor.getRGB());
RenderUtil.rect(context, pickerX + dragHue - 0.5f, this.y + yOffset,
pickerX + dragHue + 0.5f, this.y + yOffset + 8, Color.WHITE.getRGB());
}
if (draggingHue) {
hsb[0] = (float) dragX / pickerWidth;
setColor(hsb);
}
yOffset += 10;
int buttonWidth = availableWidth / 2;
RenderUtil.rect(context, pickerX, this.y + yOffset, pickerX + buttonWidth, this.y + yOffset + 14,
hoveringCopy ? OyVey.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha()) : 0x11555555);
drawString(context, "Copy", pickerX + buttonWidth / 2.0 - mc.font.width("Copy") / 2.0, this.y + yOffset + 3, -1);
hoveringCopy = isHoveringArea(mouseX, mouseY, pickerX, this.y + yOffset, pickerX + buttonWidth, this.y + yOffset + 14);
RenderUtil.rect(context, pickerX + buttonWidth + 1, this.y + yOffset, pickerX + buttonWidth * 2 + 1, this.y + yOffset + 14,
hoveringPaste ? OyVey.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha()) : 0x11555555);
drawString(context, "Paste", pickerX + buttonWidth + buttonWidth / 2.0 - mc.font.width("Paste") / 2.0 + 1, this.y + yOffset + 3, -1);
hoveringPaste = isHoveringArea(mouseX, mouseY, pickerX + buttonWidth + 1, this.y + yOffset, pickerX + buttonWidth * 2 + 1, this.y + yOffset + 14);
}
}
@Override
public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
if (this.isHovering(mouseX, mouseY) && mouseButton == 1) {
open = !open;
mc.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1f));
}
if (mouseButton == 0) {
if (hoveringHue) draggingHue = true;
if (hoveringColor) draggingColor = true;
if (hoveringAlpha) draggingAlpha = true;
if (hoveringCopy) {
OyVeyGui.setColorClipboard(setting.getValue());
mc.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1f));
}
if (hoveringPaste && OyVeyGui.getColorClipboard() != null) {
setting.setValue(OyVeyGui.getColorClipboard());
hsb = Color.RGBtoHSB(setting.getValue().getRed(), setting.getValue().getGreen(), setting.getValue().getBlue(), null);
mc.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1f));
}
}
}
@Override
public void mouseReleased(int mouseX, int mouseY, int releaseButton) {
if (releaseButton == 0) {
draggingHue = false;
draggingColor = false;
draggingAlpha = false;
}
}
@Override
public void update() {
this.setHidden(!this.setting.isVisible());
}
@Override
public int getHeight() {
if (!open) return 14;
int pickerWidth = Math.min(PICKER_SIZE, this.width + 3);
return 14 + pickerWidth + 8 + 8 + 14 + 8;
}
@Override
public boolean isHovering(int mouseX, int mouseY) {
for (Widget widget : OyVeyGui.getClickGui().getComponents()) {
if (widget.drag) return false;
}
return (float) mouseX >= this.getX() && (float) mouseX <= this.getX() + (float) this.getWidth() + 8.0f
&& (float) mouseY >= this.getY() && (float) mouseY < this.getY() + (float) this.height;
}
private boolean isHoveringArea(int mouseX, int mouseY, float left, float top, float right, float bottom) {
for (Widget widget : OyVeyGui.getClickGui().getComponents()) {
if (widget.drag) return false;
}
return left <= mouseX && top <= mouseY && right > mouseX && bottom > mouseY;
}
private void setColor(float[] hsb) {
setColor(hsb, setting.getValue().getAlpha());
}
private void setColor(float[] hsb, int alpha) {
Color color = new Color(Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]));
setting.setValue(new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha));
}
}
@@ -0,0 +1,52 @@
package me.alpha432.oyvey.features.gui.items.buttons;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.gui.OyVeyGui;
import me.alpha432.oyvey.features.modules.client.ClickGuiModule;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.util.render.RenderUtil;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
import net.minecraft.sounds.SoundEvents;
public class EnumButton
extends Button {
public Setting<Enum<?>> setting;
public EnumButton(Setting<Enum<?>> setting) {
super(setting.getName());
this.setting = setting;
this.width = 15;
}
@Override
public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) {
RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width + 7.4f, this.y + (float) this.height - 0.5f, this.getState() ? (!this.isHovering(mouseX, mouseY) ? OyVey.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : OyVey.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha())) : (!this.isHovering(mouseX, mouseY) ? 0x11555555 : -2007673515));
drawString(context, this.setting.getName() + " " + ChatFormatting.GRAY + (this.setting.currentEnumName().equalsIgnoreCase("ABC") ? "ABC" : this.setting.currentEnumName()), this.x + 2.3f, this.y - 1.7f - (float) OyVeyGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406);
}
@Override
public void update() {
this.setHidden(!this.setting.isVisible());
}
@Override
public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
super.mouseClicked(mouseX, mouseY, mouseButton);
if (this.isHovering(mouseX, mouseY)) {
mc.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1f));
}
}
@Override
public void toggle() {
this.setting.increaseEnum();
}
@Override
public boolean getState() {
return true;
}
}
@@ -0,0 +1,151 @@
package me.alpha432.oyvey.features.gui.items.buttons;
import me.alpha432.oyvey.features.gui.items.Item;
import me.alpha432.oyvey.features.modules.Module;
import me.alpha432.oyvey.features.settings.Bind;
import me.alpha432.oyvey.features.settings.Setting;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
import net.minecraft.sounds.SoundEvents;
import java.util.ArrayList;
import java.util.List;
public class ModuleButton
extends Button {
private final Module module;
private List<Item> items = new ArrayList<>();
private boolean subOpen;
public ModuleButton(Module module) {
super(module.getName());
this.module = module;
this.initSettings();
}
@SuppressWarnings("unchecked")
public void initSettings() {
ArrayList<Item> newItems = new ArrayList<>();
if (!this.module.getSettings().isEmpty()) {
for (Setting<?> setting : this.module.getSettings()) {
if (setting.getValue() instanceof Boolean && !setting.getName().equals("Enabled")) {
newItems.add(new BooleanButton((Setting<Boolean>) setting));
}
if (setting.getValue() instanceof Bind && !setting.getName().equalsIgnoreCase("Keybind") && !this.module.getName().equalsIgnoreCase("Hud")) {
newItems.add(new BindButton((Setting<Bind>) setting));
}
if ((setting.getValue() instanceof String || setting.getValue() instanceof Character) && !setting.getName().equalsIgnoreCase("displayName")) {
newItems.add(new StringButton((Setting<String>) setting));
}
if (setting.isColorSetting()) {
newItems.add(new ColorButton((Setting<java.awt.Color>) setting));
continue;
}
if (setting.isNumberSetting() && setting.hasRestriction()) {
newItems.add(new Slider((Setting<Number>) setting));
continue;
}
if (!setting.isEnumSetting()) continue;
newItems.add(new EnumButton((Setting<Enum<?>>) setting));
}
}
newItems.add(new BindButton((Setting<Bind>) this.module.getSettingByName("Keybind")));
this.items = newItems;
}
@Override
public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) {
super.drawScreen(context, mouseX, mouseY, partialTicks);
if (!this.items.isEmpty()) {
if (this.subOpen) {
float height = 16.0f;
for (Item item : this.items) {
if (!item.isHidden()) {
item.setLocation(this.x + 1.0f, this.y + height);
item.setWidth(this.width - 9);
item.drawScreen(context, mouseX, mouseY, partialTicks);
height += item.getHeight() + 1f;
}
item.update();
}
}
}
}
@Override
public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
super.mouseClicked(mouseX, mouseY, mouseButton);
if (!this.items.isEmpty()) {
if (mouseButton == 1 && this.isHovering(mouseX, mouseY)) {
this.subOpen = !this.subOpen;
mc.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1f));
}
if (this.subOpen) {
for (Item item : this.items) {
if (item.isHidden()) continue;
item.mouseClicked(mouseX, mouseY, mouseButton);
}
}
}
}
@Override
public void mouseReleased(int mouseX, int mouseY, int releaseButton) {
super.mouseReleased(mouseX, mouseY, releaseButton);
if (!this.items.isEmpty() && this.subOpen) {
for (Item item : this.items) {
if (item.isHidden()) continue;
item.mouseReleased(mouseX, mouseY, releaseButton);
}
}
}
@Override
public void onKeyTyped(String typedChar, int keyCode) {
super.onKeyTyped(typedChar, keyCode);
if (!this.items.isEmpty() && this.subOpen) {
for (Item item : this.items) {
if (item.isHidden()) continue;
item.onKeyTyped(typedChar, keyCode);
}
}
}
@Override
public void onKeyPressed(int key) {
super.onKeyPressed(key);
if (!this.items.isEmpty() && this.subOpen) {
for (Item item : this.items) {
if (item.isHidden()) continue;
item.onKeyPressed(key);
}
}
}
@Override
public int getHeight() {
if (this.subOpen) {
int height = 16;
for (Item item : this.items) {
if (item.isHidden()) continue;
height += item.getHeight() + 1;
}
return height;
}
return 14;
}
public Module getModule() {
return this.module;
}
@Override
public void toggle() {
this.module.toggle();
}
@Override
public boolean getState() {
return this.module.isEnabled();
}
}
@@ -0,0 +1,95 @@
package me.alpha432.oyvey.features.gui.items.buttons;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.gui.OyVeyGui;
import me.alpha432.oyvey.features.gui.Widget;
import me.alpha432.oyvey.features.modules.client.ClickGuiModule;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.util.render.RenderUtil;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphics;
import org.lwjgl.glfw.GLFW;
public class Slider
extends Button {
private final Number min;
private final Number max;
private final double difference;
public Setting<Number> setting;
private boolean dragging;
public Slider(Setting<Number> setting) {
super(setting.getName());
this.setting = setting;
this.min = setting.getMin();
this.max = setting.getMax();
this.difference = this.max.doubleValue() - this.min.doubleValue();
this.width = 15;
}
@Override
public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) {
this.dragSetting(mouseX, mouseY);
RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width + 7.4f, this.y + (float) this.height - 0.5f, !(this.dragging || this.isHovering(mouseX, mouseY)) ? 0x11555555 : -2007673515);
RenderUtil.rect(context, this.x, this.y, (this.setting.getValue()).floatValue() <= this.min.floatValue() ? this.x : this.x + ((float) this.width + 7.4f) * this.partialMultiplier(), this.y + (float) this.height - 0.5f, !(this.dragging || this.isHovering(mouseX, mouseY)) ? OyVey.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : OyVey.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha()));
drawString(context, this.getName() + " " + ChatFormatting.GRAY + (this.setting.getValue() instanceof Float ? this.setting.getValue() : Double.valueOf((this.setting.getValue()).doubleValue())), this.x + 2.3f, this.y - 1.7f - (float) OyVeyGui.getClickGui().getTextOffset(), -1);
}
@Override
public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
super.mouseClicked(mouseX, mouseY, mouseButton);
if (mouseButton == 0 && this.isHovering(mouseX, mouseY)) {
this.dragging = true;
this.setSettingFromX(mouseX);
}
}
@Override
public boolean isHovering(int mouseX, int mouseY) {
for (Widget widget : OyVeyGui.getClickGui().getComponents()) {
if (!widget.drag) continue;
return false;
}
return (float) mouseX >= this.getX() && (float) mouseX <= this.getX() + (float) this.getWidth() + 8.0f && (float) mouseY >= this.getY() && (float) mouseY < this.getY() + (float) this.height;
}
@Override
public void update() {
this.setHidden(!this.setting.isVisible());
}
private void dragSetting(int mouseX, int mouseY) {
if (GLFW.glfwGetMouseButton(mc.getWindow().handle(), 0) != 1) {
this.dragging = false;
return;
}
if (this.dragging) {
this.setSettingFromX(mouseX);
}
}
private void setSettingFromX(int mouseX) {
float percent = Math.clamp(((float) mouseX - this.x) / ((float) this.width + 7.4f), 0.0f, 1.0f);
if (this.setting.getValue() instanceof Double) {
double result = this.setting.getMin().doubleValue() + this.difference * percent;
this.setting.setValue((double) Math.round(10.0 * result) / 10.0);
} else if (this.setting.getValue() instanceof Float) {
float result = this.setting.getMin().floatValue() + (float) (this.difference * percent);
this.setting.setValue((float) Math.round(10.0f * result) / 10.0f);
} else if (this.setting.getValue() instanceof Integer) {
this.setting.setValue(this.setting.getMin().intValue() + (int) Math.round(this.difference * percent));
}
}
private float middle() {
return this.max.floatValue() - this.min.floatValue();
}
private float part() {
return (this.setting.getValue()).floatValue() - this.min.floatValue();
}
private float partialMultiplier() {
return this.part() / this.middle();
}
}
@@ -0,0 +1,117 @@
package me.alpha432.oyvey.features.gui.items.buttons;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.gui.OyVeyGui;
import me.alpha432.oyvey.features.modules.client.ClickGuiModule;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.util.models.Timer;
import me.alpha432.oyvey.util.render.RenderUtil;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
import net.minecraft.sounds.SoundEvents;
import org.lwjgl.glfw.GLFW;
public class StringButton
extends Button {
private static final Timer idleTimer = new Timer();
private static boolean idle;
private final Setting<String> setting;
public boolean isListening;
private CurrentString currentString = new CurrentString("");
public StringButton(Setting<String> setting) {
super(setting.getName());
this.setting = setting;
this.width = 15;
}
public static String removeLastChar(String str) {
String output = "";
if (str != null && !str.isEmpty()) {
output = str.substring(0, str.length() - 1);
}
return output;
}
@Override
public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) {
RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width + 7.4f, this.y + (float) this.height - 0.5f, this.getState() ? (!this.isHovering(mouseX, mouseY) ? OyVey.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : OyVey.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha())) : (!this.isHovering(mouseX, mouseY) ? 0x11555555 : -2007673515));
if (this.isListening) {
drawString(context, this.currentString.string() + getIdleSign(), this.x + 2.3f, this.y - 1.7f - (float) OyVeyGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406);
} else {
drawString(context, (this.setting.getName().equals("Buttons") ? "Buttons " : (this.setting.getName().equals("Prefix") ? "Prefix " + ChatFormatting.GRAY : "")) + this.setting.getValue(), this.x + 2.3f, this.y - 1.7f - (float) OyVeyGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406);
}
}
@Override
public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
super.mouseClicked(mouseX, mouseY, mouseButton);
if (this.isHovering(mouseX, mouseY)) {
mc.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1f));
}
}
@Override
public void onKeyTyped(String typedChar, int keyCode) {
if (this.isListening) {
this.setString(this.currentString.string() + typedChar);
}
}
@Override
public void onKeyPressed(int key) {
if (isListening) {
switch (key) {
case GLFW.GLFW_KEY_ENTER: {
this.enterString();
break;
}
case GLFW.GLFW_KEY_BACKSPACE: {
this.setString(StringButton.removeLastChar(this.currentString.string()));
}
}
}
}
@Override
public void update() {
this.setHidden(!this.setting.isVisible());
}
private void enterString() {
if (this.currentString.string().isEmpty()) {
this.setting.setValue(this.setting.getDefaultValue());
} else {
this.setting.setValue(this.currentString.string());
}
this.setString("");
this.onMouseClick();
}
@Override
public void toggle() {
this.isListening = !this.isListening;
}
@Override
public boolean getState() {
return !this.isListening;
}
public void setString(String newString) {
this.currentString = new CurrentString(newString);
}
public static String getIdleSign() {
if (idleTimer.passedMs(500)) {
idle = !idle;
idleTimer.reset();
}
if (idle) return "_";
return "";
}
public record CurrentString(String string) {
}
}
@@ -0,0 +1,204 @@
package me.alpha432.oyvey.features.modules;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.event.impl.ClientEvent;
import me.alpha432.oyvey.event.impl.render.Render2DEvent;
import me.alpha432.oyvey.event.impl.render.Render3DEvent;
import me.alpha432.oyvey.features.Feature;
import me.alpha432.oyvey.features.commands.Command;
import me.alpha432.oyvey.features.commands.MessageSignatures;
import me.alpha432.oyvey.features.settings.Bind;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.manager.ConfigManager;
import me.alpha432.oyvey.util.traits.Jsonable;
import me.alpha432.oyvey.util.traits.Toggleable;
import net.minecraft.ChatFormatting;
import org.joml.Vector2f;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_UNKNOWN;
public class Module extends Feature implements Jsonable, Toggleable {
private final String description;
private final Category category;
public final Setting<Boolean> enabled = bool("Enabled", false);
public final Setting<Boolean> drawn = bool("Drawn", true);
public final Setting<Bind> bind = key("Keybind", new Bind(GLFW_KEY_UNKNOWN));
public final Setting<String> displayName;
public boolean hidden;
public Module(String name, String description, Category category) {
super(name);
this.displayName = str("DisplayName", name);
this.description = description;
this.category = category;
}
public void onEnable() {
}
public void onDisable() {
}
public void onToggle() {
}
public void onLoad() {
}
public void onTick() {
}
public void onRender2D(Render2DEvent event) {
}
public void onRender3D(Render3DEvent event) {
}
public void onUnload() {
}
public String getDisplayInfo() {
return null;
}
public void enable() {
this.enabled.setValue(true);
EVENT_BUS.register(this);
EVENT_BUS.post(new ClientEvent(ClientEvent.Type.TOGGLE_MODULE, this));
this.onToggle();
this.onEnable();
}
public void disable() {
this.enabled.setValue(false);
EVENT_BUS.unregister(this);
EVENT_BUS.post(new ClientEvent(ClientEvent.Type.TOGGLE_MODULE, this));
this.onToggle();
this.onDisable();
}
public String getDisplayName() {
return this.displayName.getValue();
}
public void setDisplayName(String name) {
Module module = OyVey.moduleManager.getModuleByDisplayName(name);
Module originalModule = OyVey.moduleManager.getModuleByName(name);
if (module == null && originalModule == null) {
Command.sendMessage("%s, name: %s, has been renamed to: %s", MessageSignatures.GENERAL,
getDisplayName(), getName(), name);
this.displayName.setValue(name);
return;
}
Command.sendMessage("{red} A module of this name already exists.", MessageSignatures.GENERAL);
}
@Override
public boolean isEnabled() {
return enabled.getValue();
}
@Override
public boolean isToggled() {
return isEnabled();
}
public String getDescription() {
return this.description;
}
public boolean isDrawn() {
return this.drawn.getValue();
}
public void setDrawn(boolean drawn) {
this.drawn.setValue(drawn);
}
public Category getCategory() {
return this.category;
}
public String getInfo() {
return null;
}
public Bind getBind() {
return this.bind.getValue();
}
public void setBind(int key) {
this.bind.setValue(new Bind(key));
}
public String getFullArrayString() {
return this.getDisplayName() + ChatFormatting.GRAY + (this.getDisplayInfo() != null ? " [" + ChatFormatting.WHITE + this.getDisplayInfo() + ChatFormatting.GRAY + "]" : "");
}
@Override
public JsonElement toJson() {
JsonObject object = new JsonObject();
for (Setting<?> setting : getSettings()) {
try {
if (setting.getValue() instanceof Bind keyBind) {
object.addProperty(setting.getName(), keyBind.getKey());
} else if (setting.getValue() instanceof java.awt.Color color) {
object.addProperty(setting.getName(), color.getRed() + "," + color.getGreen() + "," + color.getBlue() + "," + color.getAlpha());
} else if (setting.getValue() instanceof Vector2f pos) {
object.addProperty(setting.getName(), pos.x() + "," + pos.y());
} else {
object.addProperty(setting.getName(), setting.getValueAsString());
}
} catch (Throwable e) {
OyVey.LOGGER.error("Failed to create JSON field", e);
}
}
return object;
}
@Override
public void fromJson(JsonElement element) {
if (element == null || element.isJsonNull()) return;
JsonObject object = element.getAsJsonObject();
if (object.has("Enabled")) {
boolean enabled = Boolean.parseBoolean(object.get("Enabled").getAsString());
if (enabled != isEnabled()) toggle();
}
for (Setting<?> setting : getSettings()) {
if (setting == this.enabled) continue;
try {
JsonElement settingElement = object.get(setting.getName());
if (settingElement != null && !settingElement.isJsonNull()) {
ConfigManager.setValueFromJson(this, setting, settingElement);
}
} catch (Throwable throwable) {
OyVey.LOGGER.error("Failed to load from JSON", throwable);
}
}
}
public enum Category {
COMBAT("Combat"),
MISC("Misc"),
RENDER("Render"),
MOVEMENT("Movement"),
PLAYER("Player"),
CLIENT("Client"),
HUD("Hud");
private final String name;
Category(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
}
@@ -0,0 +1,73 @@
package me.alpha432.oyvey.features.modules.client;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.event.impl.ClientEvent;
import me.alpha432.oyvey.event.system.Subscribe;
import me.alpha432.oyvey.features.commands.Command;
import me.alpha432.oyvey.features.gui.OyVeyGui;
import me.alpha432.oyvey.features.modules.Module;
import me.alpha432.oyvey.features.settings.Setting;
import org.lwjgl.glfw.GLFW;
import java.awt.*;
import static me.alpha432.oyvey.features.commands.MessageSignatures.GENERAL;
public class ClickGuiModule extends Module {
private static ClickGuiModule INSTANCE;
public final Setting<String> prefix = str("Prefix", ".");
public final Setting<Color> color = color("Color", 0, 0, 255, 180);
public final Setting<Color> topColor = color("TopColor", 0, 0, 150, 240);
public final Setting<Boolean> rainbow = bool("Rainbow", false);
public final Setting<Integer> rainbowHue = num("Delay", 240, 0, 600);
public final Setting<Float> rainbowBrightness = num("Brightness", 150.0f, 1.0f, 255.0f);
public final Setting<Float> rainbowSaturation = num("Saturation", 150.0f, 1.0f, 255.0f);
public ClickGuiModule() {
super("ClickGui", "Opens the ClickGui", Module.Category.CLIENT);
setBind(GLFW.GLFW_KEY_RIGHT_SHIFT);
rainbowHue.setVisibility(v -> rainbow.getValue());
rainbowBrightness.setVisibility(v -> rainbow.getValue());
rainbowSaturation.setVisibility(v -> rainbow.getValue());
INSTANCE = this;
}
@Subscribe
public void onSettingChange(ClientEvent event) {
if (event.getType() == ClientEvent.Type.SETTING_UPDATE && event.getSetting().getFeature().equals(this)) {
if (event.getSetting().equals(this.prefix)) {
OyVey.commandManager.setCommandPrefix(this.prefix.getPlannedValue());
Command.sendMessage("Prefix set to {global} %s", GENERAL, OyVey.commandManager.getCommandPrefix());
}
if (event.getSetting().equals(this.color)) {
OyVey.colorManager.setColor(this.color.getPlannedValue());
}
}
}
@Override
public void onEnable() {
if (nullCheck()) {
return;
}
mc.setScreen(OyVeyGui.getClickGui());
}
@Override
public void onLoad() {
OyVey.colorManager.setColor(this.color.getValue());
OyVey.commandManager.setCommandPrefix(this.prefix.getValue());
}
@Override
public void onTick() {
if (!(ClickGuiModule.mc.screen instanceof OyVeyGui)) {
this.disable();
}
}
public static ClickGuiModule getInstance() {
return INSTANCE;
}
}
@@ -0,0 +1,21 @@
package me.alpha432.oyvey.features.modules.client;
import me.alpha432.oyvey.features.gui.HudEditorScreen;
import me.alpha432.oyvey.features.modules.Module;
public class HudEditorModule extends Module {
public HudEditorModule() {
super("HudEditor", "Edit HUD element positions", Category.CLIENT);
}
@Override
public void onEnable() {
if (nullCheck()) {
disable();
return;
}
mc.setScreen(HudEditorScreen.getInstance());
disable();
}
}
@@ -0,0 +1,150 @@
package me.alpha432.oyvey.features.modules.client;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.event.impl.input.MouseInputEvent;
import me.alpha432.oyvey.event.impl.render.Render2DEvent;
import me.alpha432.oyvey.event.system.Subscribe;
import me.alpha432.oyvey.features.gui.HudEditorScreen;
import me.alpha432.oyvey.features.modules.Module;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.util.render.RenderUtil;
import net.minecraft.client.gui.screens.ChatScreen;
import org.joml.Vector2f;
public abstract class HudModule extends Module {
public final Setting<Vector2f> pos = vec2f("Position", 0.5f, 0.5f);
private float dragX, dragY, width, height;
private boolean dragging, button;
public HudModule(String name, String description, float width, float height) {
super(name, description, Category.HUD);
this.width = width;
this.height = height;
}
public float getX() {
return mc.getWindow().getGuiScaledWidth() * pos.getValue().x();
}
public float getY() {
float heightWithChat = mc.getWindow().getGuiScaledHeight() - 14;
float baseY = mc.getWindow().getGuiScaledHeight() * pos.getValue().y();
float combined = baseY + getHeight();
if (mc.screen instanceof ChatScreen) {
baseY = Math.min(combined, heightWithChat) - getHeight();
}
return baseY;
}
@Subscribe
public void onRender2DHud(Render2DEvent e) {
render(e);
}
@Subscribe
public void onMouse(MouseInputEvent e) {
if (!(mc.screen instanceof HudEditorScreen) || nullCheck()) return;
if (e.getAction() == 0) {
button = false;
dragging = false;
HudEditorScreen.getInstance().currentDragging = null;
}
if (e.getAction() == 1 && isHovering()) {
button = true;
}
}
protected void render(Render2DEvent e) {
if (!(mc.screen instanceof HudEditorScreen) || nullCheck()) return;
float x = getX();
float y = getY();
if (button) {
if (!dragging && isHovering() && HudEditorScreen.getInstance().currentDragging == null) {
dragX = getMouseX() - x;
dragY = getMouseY() - y;
dragging = true;
HudEditorScreen.getInstance().currentDragging = this;
}
if (dragging) {
float finalX = Math.min(Math.max(getMouseX() - dragX, 0),
mc.getWindow().getGuiScaledWidth() - width);
float finalY = Math.min(Math.max(getMouseY() - dragY, 0),
mc.getWindow().getGuiScaledHeight() - height);
pos.setValue(new Vector2f(finalX, finalY)
.div(mc.getWindow().getGuiScaledWidth(), mc.getWindow().getGuiScaledHeight()));
}
} else {
dragging = false;
}
boolean shouldDrawDescription = isHovering() && !HudEditorScreen.getInstance().anyHover;
if (HudEditorScreen.getInstance().currentDragging != null) {
shouldDrawDescription = HudEditorScreen.getInstance().currentDragging == this;
}
if (shouldDrawDescription) {
int textWidth = mc.font.width(getName());
int textHeight = mc.font.lineHeight;
float textX = x + width + 5;
if (textX + textWidth > mc.getWindow().getGuiScaledWidth()) {
textX = x - 5 - textWidth;
}
e.getContext().drawString(mc.font, getName(),
(int) textX, (int) (y + height / 2f - textHeight / 2f), -1);
HudEditorScreen.getInstance().anyHover = true;
}
RenderUtil.rect(e.getContext(),
x - 1, y - 1, x + width + 1, y + height + 1,
OyVey.colorManager.getColor().getRGB(), 1.0f);
}
public int getMouseX() {
return (int) (mc.mouseHandler.xpos() / mc.getWindow().getGuiScale());
}
public int getMouseY() {
return (int) (mc.mouseHandler.ypos() / mc.getWindow().getGuiScale());
}
public void setBounds(float x, float y, float width, float height) {
this.width = width;
this.height = height;
pos.setValue(new Vector2f(x, y)
.div(mc.getWindow().getGuiScaledWidth(), mc.getWindow().getGuiScaledHeight()));
}
public boolean isHovering() {
float x = getX();
float y = getY();
int mouseX = getMouseX();
int mouseY = getMouseY();
return mouseX >= x - 1 && mouseX <= x + width + 1 &&
mouseY >= y - 1 && mouseY <= y + height + 1;
}
public float getWidth() {
return width;
}
public float getHeight() {
return height;
}
public void setWidth(float width) {
this.width = width;
}
public void setHeight(float height) {
this.height = height;
}
}
@@ -0,0 +1,39 @@
package me.alpha432.oyvey.features.modules.client;
import me.alpha432.oyvey.event.impl.ClientEvent;
import me.alpha432.oyvey.event.system.Subscribe;
import me.alpha432.oyvey.features.modules.Module;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.util.TextUtil;
import me.alpha432.oyvey.util.chat.ChatUtil;
import static me.alpha432.oyvey.util.chat.SimpleSignature.from;
public class NotificationsModule extends Module {
private static final String MODULE_FORMAT = "{gray} %s %s%s";
public final Setting<Boolean> moduleToggle = bool("ModuleToggle", true);
public NotificationsModule() {
super("Notifications", "Displays notifications for various client events", Category.CLIENT);
}
@Subscribe
public void onClient(ClientEvent event) {
if (!moduleToggle.getValue()
|| event.getType() != ClientEvent.Type.TOGGLE_MODULE
|| event.getFeature() instanceof ClickGuiModule) {
return;
}
boolean moduleState = event.getFeature().isEnabled();
String name = event.getFeature() instanceof Module module
? module.getDisplayName()
: event.getFeature().getName();
ChatUtil.sendMessage(TextUtil.text(MODULE_FORMAT,
name,
moduleState ? "{green}" : "{red}",
moduleState ? "on" : "off"), from(event.getFeature().getName()));
}
}
@@ -0,0 +1,37 @@
package me.alpha432.oyvey.features.modules.combat;
import me.alpha432.oyvey.event.impl.network.PacketEvent;
import me.alpha432.oyvey.event.system.Subscribe;
import me.alpha432.oyvey.features.modules.Module;
import net.minecraft.network.protocol.game.ServerboundInteractPacket;
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.boss.enderdragon.EndCrystal;
public class CriticalsModule extends Module {
public CriticalsModule() {
super("Criticals", "Makes you do critical hits", Category.COMBAT);
}
@Subscribe
private void onPacketSend(PacketEvent.Send event) {
if (event.getPacket() instanceof ServerboundInteractPacket packet && packet.action.getType() == ServerboundInteractPacket.ActionType.ATTACK) {
Entity entity = mc.level.getEntity(packet.entityId);
if (entity == null
|| entity instanceof EndCrystal
|| !mc.player.onGround()
|| !(entity instanceof LivingEntity)) return;
boolean bl = mc.player.horizontalCollision;
mc.player.connection.send(new ServerboundMovePlayerPacket.Pos(mc.player.getX(), mc.player.getY() + 0.1f, mc.player.getZ(), false, bl));
mc.player.connection.send(new ServerboundMovePlayerPacket.Pos(mc.player.getX(), mc.player.getY(), mc.player.getZ(), false, bl));
mc.player.crit(entity);
}
}
@Override
public String getDisplayInfo() {
return "Packet";
}
}
@@ -0,0 +1,28 @@
package me.alpha432.oyvey.features.modules.combat;
import me.alpha432.oyvey.features.modules.Module;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.util.inventory.InventoryUtil;
import me.alpha432.oyvey.util.inventory.Result;
import net.minecraft.world.item.Items;
import static me.alpha432.oyvey.util.inventory.InventoryUtil.FULL_SCOPE;
import static me.alpha432.oyvey.util.inventory.InventoryUtil.HOTBAR_SCOPE;
public class KeyPearlModule extends Module {
private final Setting<Boolean> inventory = bool("Inventory", false);
public KeyPearlModule() {
super("KeyPearl", "Throws a pearl when enabled.", Category.COMBAT);
}
@Override
public void onEnable() {
disable();
if (nullCheck()) return;
Result result = InventoryUtil.find(Items.ENDER_PEARL, inventory.getValue() ? FULL_SCOPE : HOTBAR_SCOPE);
InventoryUtil.withSwap(result, () -> mc.gameMode.useItem(mc.player, result.hand()));
}
}
@@ -0,0 +1,77 @@
package me.alpha432.oyvey.features.modules.combat;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.event.impl.entity.player.TickEvent;
import me.alpha432.oyvey.event.system.Subscribe;
import me.alpha432.oyvey.features.modules.Module;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.util.models.Angles;
import net.minecraft.tags.ItemTags;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
public class KillAuraModule extends Module {
private final Setting<Float> delay = num("Delay", 1f, 0f, 1f);
private final Setting<Float> range = num("Range", 3f, 1f, 6f);
private final Setting<Boolean> onlyWeapon = bool("OnlyWeapon", false);
private final Setting<Boolean> sync = bool("MovementSync", false);
public KillAuraModule() {
super("KillAura", "Attacks nearby players.", Category.COMBAT);
}
@Subscribe public void onPreTick(TickEvent.Pre event) {
if (isOnCooldown())
return;
if (onlyWeapon.getValue() && !isHoldingWeapon())
return;
Player target = findPlayerTarget();
if (target == null)
return;
Angles angles = Angles.entity(target);
int priority = 0;
if (sync.getValue()) {
OyVey.rotationManager.sync(angles, priority, () -> attack(target));
} else {
OyVey.rotationManager.motion(angles, priority, () -> attack(target));
}
}
private void attack(Entity entity) {
if (nullCheck() || !entity.isAlive() || entity.isRemoved() || entity.distanceTo(mc.player) > range.getValue())
return;
mc.gameMode.attack(mc.player, entity);
mc.player.swing(InteractionHand.MAIN_HAND);
}
private boolean isOnCooldown() {
float attackDelay = sync.getValue() ? 1 : 0;
return mc.player.getAttackStrengthScale(attackDelay) < delay.getValue();
}
private boolean isHoldingWeapon() {
ItemStack stack = mc.player.getMainHandItem();
return stack.is(ItemTags.SWORDS) || stack.is(ItemTags.AXES) || stack.is(ItemTags.SPEARS)
|| stack.is(Items.MACE) || stack.is(Items.TRIDENT);
}
private Player findPlayerTarget() {
Player target = null;
float min = range.getValue();
for (Player entity : mc.level.players()) {
float dist = entity.distanceTo(mc.player);
if (entity == mc.player || dist > min) continue;
if (OyVey.friendManager.isFriend(entity)) continue;
target = entity;
min = dist;
}
return target;
}
}
@@ -0,0 +1,43 @@
package me.alpha432.oyvey.features.modules.hud;
import me.alpha432.oyvey.event.impl.render.Render2DEvent;
import me.alpha432.oyvey.features.modules.client.HudModule;
import me.alpha432.oyvey.features.settings.Setting;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.Level;
public class CoordinatesHudModule extends HudModule {
public final Setting<Boolean> nether = bool("Nether", false);
public CoordinatesHudModule() {
super("Coordinates", "Display coordinates", 150, 20);
}
@Override
protected void render(Render2DEvent e) {
super.render(e);
if (nullCheck()) return;
String coordsStr = String.format("X: %d Y: %d Z: %d",
mc.player.getBlockX(),
mc.player.getBlockY(),
mc.player.getBlockZ());
if (nether.getValue()) {
ResourceKey<Level> dimension = mc.player.level().dimension();
if (dimension == Level.NETHER) {
coordsStr += String.format(" [%d, %d]", mc.player.getBlockX() * 8, mc.player.getBlockZ() * 8);
} else if (dimension == Level.OVERWORLD) {
coordsStr += String.format(" [%d, %d]", Math.floorDiv(mc.player.getBlockX(), 8), Math.floorDiv(mc.player.getBlockZ(), 8));
}
}
e.getContext().drawString(mc.font, coordsStr,
(int) getX(), (int) getY(), -1);
setWidth(mc.font.width(coordsStr));
setHeight(mc.font.lineHeight);
}
}
@@ -0,0 +1,36 @@
package me.alpha432.oyvey.features.modules.hud;
import me.alpha432.oyvey.event.impl.render.Render2DEvent;
import me.alpha432.oyvey.features.modules.client.HudModule;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.util.BuildConfig;
import me.alpha432.oyvey.util.TextUtil;
import net.minecraft.network.chat.Component;
public class WatermarkHudModule extends HudModule {
public final Setting<String> text = str("Text", BuildConfig.NAME);
public final Setting<Boolean> fullVersion = new Setting<>("FullVersion", false);
public WatermarkHudModule() {
super("Watermark", "Display watermark", 100, 10);
if (BuildConfig.USING_GIT) {
register(fullVersion);
}
}
@Override
protected void render(Render2DEvent e) {
super.render(e);
String watermarkString = "{global} %s {} %s";
if (fullVersion.getValue() && BuildConfig.USING_GIT) {
watermarkString += "/" + BuildConfig.BRANCH + "-" + BuildConfig.HASH;
}
Component component = TextUtil.text(watermarkString, text.getValue(), BuildConfig.VERSION);
e.getContext().drawString(mc.font, component, (int) getX(), (int) getY(), -1);
setWidth(mc.font.width(component));
setHeight(mc.font.lineHeight);
}
}
@@ -0,0 +1,48 @@
package me.alpha432.oyvey.features.modules.misc;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.commands.Command;
import me.alpha432.oyvey.features.modules.Module;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import org.lwjgl.glfw.GLFW;
import static me.alpha432.oyvey.util.chat.SimpleSignature.from;
public class MCFModule extends Module {
private boolean pressed;
public MCFModule() {
super("MCF", "Middle click friend", Category.MISC);
}
@Override
public void onTick() {
if (mc.screen != null) {
pressed = false;
return;
}
if (GLFW.glfwGetMouseButton(mc.getWindow().handle(), 2) == 1) {
if (!pressed) click();
pressed = true;
} else {
pressed = false;
}
}
private void click() {
Entity targetedEntity = mc.crosshairPickEntity;
if (!(targetedEntity instanceof Player)) return;
String name = ((Player) targetedEntity).getGameProfile().name();
if (OyVey.friendManager.isFriend(name)) {
OyVey.friendManager.removeFriend(name);
Command.sendMessage("{red} %s has been unfriended.", from(getName()), name);
} else {
OyVey.friendManager.addFriend(name);
Command.sendMessage("{aqua} %s has been friended.", from(getName()), name);
}
}
}
@@ -0,0 +1,34 @@
package me.alpha432.oyvey.features.modules.movement;
import me.alpha432.oyvey.event.impl.entity.player.MoveEvent;
import me.alpha432.oyvey.event.system.Subscribe;
import me.alpha432.oyvey.features.modules.Module;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.util.MovementUtil;
import net.minecraft.world.entity.MoverType;
import org.joml.Vector2f;
public class FastAccelModule extends Module {
private final Setting<Float> speed = num("Speed", 1f, 0.5f, 2f);
private final Setting<Boolean> slowness = bool("Slowness", true);
public FastAccelModule() {
super("FastAccel", "Makes the player accelerate faster while walking", Category.MOVEMENT);
}
@Subscribe
private void onMove(MoveEvent event) {
if (nullCheck() || event.getType() != MoverType.SELF) return;
if (mc.player.isInLiquid() || mc.player.isFallFlying()
|| mc.player.getAbilities().flying || mc.player.isSpectator()) return;
double speed = MovementUtil.SPRINT_SPEED * this.speed.getValue() * MovementUtil.getSpeedFactor(true, slowness.getValue());
if (event.getMovement().horizontalDistance() > speed) {
speed = event.getMovement().horizontalDistance();
}
Vector2f motion = MovementUtil.calcMoveVector(mc.player.getYRot(), speed);
event.setMovement(motion.x, event.getMovement().y, motion.y);
}
}
@@ -0,0 +1,16 @@
package me.alpha432.oyvey.features.modules.movement;
import me.alpha432.oyvey.features.modules.Module;
public class ReverseStepModule extends Module {
public ReverseStepModule() {
super("ReverseStep", "step but reversed..", Category.MOVEMENT);
}
@Override
public void onTick() {
if (nullCheck()) return;
if (mc.player.isInLava() || mc.player.isInWater() || !mc.player.onGround()) return;
mc.player.push(0, -1, 0);
}
}
@@ -0,0 +1,36 @@
package me.alpha432.oyvey.features.modules.movement;
import me.alpha432.oyvey.features.modules.Module;
import me.alpha432.oyvey.features.settings.Setting;
import net.minecraft.world.entity.ai.attributes.Attributes;
public class StepModule extends Module {
private final Setting<Float> height = num("Height", 2f, 1f, 3f);
public StepModule() {
super("Step", "step..", Category.MOVEMENT);
}
private float prev;
@Override
public void onEnable() {
if (nullCheck()) {
prev = 0.6f;
return;
}
prev = mc.player.maxUpStep();
}
@Override
public void onDisable() {
if (nullCheck()) return;
mc.player.getAttribute(Attributes.STEP_HEIGHT).setBaseValue(prev);
}
@Override
public void onTick() {
if (nullCheck()) return;
mc.player.getAttribute(Attributes.STEP_HEIGHT).setBaseValue(height.getValue());
}
}
@@ -0,0 +1,19 @@
package me.alpha432.oyvey.features.modules.player;
import me.alpha432.oyvey.features.modules.Module;
import net.minecraft.world.item.Items;
public class FastPlaceModule extends Module {
public FastPlaceModule() {
super("FastPlace", "Makes you throw exp faster", Category.PLAYER);
}
@Override
public void onTick() {
if (nullCheck()) return;
if (mc.player.isHolding(Items.EXPERIENCE_BOTTLE)) {
mc.rightClickDelay = 0;
}
}
}
@@ -0,0 +1,21 @@
package me.alpha432.oyvey.features.modules.player;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.modules.Module;
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
public class NoFallModule extends Module {
public NoFallModule() {
super("NoFall", "Removes fall damage", Category.PLAYER);
}
@Override
public void onTick() {
if (!mc.player.onGround() && OyVey.positionManager.getFallDistance() > 3) {
boolean bl = mc.player.horizontalCollision;
ServerboundMovePlayerPacket.PosRot packet = new ServerboundMovePlayerPacket.PosRot(mc.player.getX(), mc.player.getY() + 0.000000001, mc.player.getZ(),
mc.player.getYRot(), mc.player.getXRot(), false, bl);
mc.player.connection.send(packet);
}
}
}
@@ -0,0 +1,24 @@
package me.alpha432.oyvey.features.modules.player;
import me.alpha432.oyvey.event.impl.network.PacketEvent;
import me.alpha432.oyvey.event.system.Subscribe;
import me.alpha432.oyvey.features.modules.Module;
import net.minecraft.network.protocol.game.ClientboundExplodePacket;
import net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket;
public class VelocityModule extends Module {
public VelocityModule() {
super("Velocity", "Removes velocity from explosions and entities", Category.PLAYER);
}
@Subscribe
private void onPacketReceive(PacketEvent.Receive event) {
if (nullCheck())
return;
if (event.getPacket() instanceof ClientboundSetEntityMotionPacket packet && packet.getId() == mc.player.getId()
|| event.getPacket() instanceof ClientboundExplodePacket) {
event.cancel();
}
}
}
@@ -0,0 +1,39 @@
package me.alpha432.oyvey.features.modules.render;
import me.alpha432.oyvey.event.impl.render.Render3DEvent;
import me.alpha432.oyvey.event.impl.render.RenderBlockOutlineEvent;
import me.alpha432.oyvey.event.system.Subscribe;
import me.alpha432.oyvey.features.modules.Module;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.util.render.RenderUtil;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.shapes.VoxelShape;
import java.awt.*;
public class BlockHighlightModule extends Module {
public final Setting<Color> color = color("Color", 255, 0, 0, 255);
public final Setting<Float> lineWidth = num("LineWidth", 1.0f, 0.1f, 5.0f);
public BlockHighlightModule() {
super("BlockHighlight", "Draws box at the block that you are looking at", Category.RENDER);
}
@Override
public void onRender3D(Render3DEvent event) {
if (mc.hitResult instanceof BlockHitResult result) {
VoxelShape shape = mc.level.getBlockState(result.getBlockPos()).getShape(mc.level, result.getBlockPos());
if (shape.isEmpty() || result.getType() == HitResult.Type.MISS) return;
AABB aabb = shape.bounds();
aabb = aabb.move(result.getBlockPos());
RenderUtil.drawBox(event.getMatrix(), aabb, color.getValue(), lineWidth.getValue());
}
}
@Subscribe
public void onRenderBlockOutline(RenderBlockOutlineEvent event) {
event.cancel();
}
}
@@ -0,0 +1,61 @@
package me.alpha432.oyvey.features.settings;
import com.mojang.blaze3d.platform.InputConstants;
import me.alpha432.oyvey.util.traits.Util;
import net.minecraft.client.input.KeyEvent;
import org.lwjgl.glfw.GLFW;
public class Bind implements Util {
private int key;
public Bind(int key) {
this.key = key;
}
public static Bind keyboard(int key) {
return new Bind(key);
}
public static Bind mouse(int key) {
return new Bind(-key - 2);
}
public static Bind none() {
return new Bind(-1);
}
public int getKey() {
return this.key;
}
public void setKey(int key) {
this.key = key;
}
public boolean isEmpty() {
return this.key == -1;
}
public boolean isMouse() {
return key < -1;
}
public String toString() {
if (this.isEmpty()) return "None";
if (this.key < -1) return "Mouse " + (-this.key - 1);
return this.capitalise(InputConstants.getKey(new KeyEvent(this.key, 0, 0)).getName().replace("key.keyboard.", ""));
}
public boolean isDown() {
if (this.isEmpty()) return false;
if (this.key < -1) return GLFW.glfwGetMouseButton(mc.getWindow().handle(), -this.key - 2) == 1;
return GLFW.glfwGetKey(mc.getWindow().handle(), this.getKey()) == 1;
}
private String capitalise(String str) {
if (str.isEmpty()) {
return "";
}
return Character.toUpperCase(str.charAt(0)) + (str.length() != 1 ? str.substring(1).toLowerCase() : "");
}
}
@@ -0,0 +1,51 @@
package me.alpha432.oyvey.features.settings;
import com.google.common.base.Converter;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
@SuppressWarnings("unchecked")
public class EnumConverter<T extends Enum<T>> extends Converter<T, JsonElement> {
private final Class<T> clazz;
public EnumConverter(Class<T> clazz) {
this.clazz = clazz;
}
public static <T extends Enum<?>> int currentEnum(T clazz) {
for (int i = 0; i < clazz.getDeclaringClass().getEnumConstants().length; ++i) {
T e = (T) clazz.getDeclaringClass().getEnumConstants()[i];
if (!e.name().equalsIgnoreCase(clazz.name())) continue;
return i;
}
return -1;
}
public static <T extends Enum<?>> T increaseEnum(T clazz) {
int index = EnumConverter.currentEnum(clazz);
for (int i = 0; i < clazz.getDeclaringClass().getEnumConstants().length; ++i) {
T e = (T) clazz.getDeclaringClass().getEnumConstants()[i];
if (i != index + 1) continue;
return e;
}
return (T) clazz.getDeclaringClass().getEnumConstants()[0];
}
public static <T extends Enum<?>> String getProperName(T clazz) {
return Character.toUpperCase(clazz.name().charAt(0)) + clazz.name().toLowerCase().substring(1);
}
public JsonElement doForward(Enum anEnum) {
return new JsonPrimitive(anEnum.name());
}
public T doBackward(JsonElement jsonElement) {
String name = jsonElement.getAsString();
for (T constant : this.clazz.getEnumConstants()) {
if (constant.name().equalsIgnoreCase(name) || constant.toString().equalsIgnoreCase(name)) {
return constant;
}
}
return null;
}
}
@@ -0,0 +1,287 @@
package me.alpha432.oyvey.features.settings;
import me.alpha432.oyvey.event.impl.ClientEvent;
import me.alpha432.oyvey.features.Feature;
import org.joml.Vector2f;
import java.awt.*;
import java.util.Objects;
import java.util.function.Predicate;
import static me.alpha432.oyvey.util.traits.Util.EVENT_BUS;
public class Setting<T> {
private final String name;
private final T defaultValue;
private T value;
private T plannedValue;
private T min;
private T max;
private boolean hasRestriction;
private Predicate<T> visibility;
private String description;
private Feature feature;
public Setting(String name, T defaultValue) {
this.name = name;
this.defaultValue = defaultValue;
this.value = copy(defaultValue);
this.plannedValue = this.value;
this.description = "";
}
public Setting(String name, T defaultValue, String description) {
this.name = name;
this.defaultValue = defaultValue;
this.value = copy(defaultValue);
this.plannedValue = this.value;
this.description = description;
}
public Setting(String name, T defaultValue, T min, T max, String description) {
this.name = name;
this.defaultValue = defaultValue;
this.value = copy(defaultValue);
this.min = min;
this.max = max;
this.plannedValue = this.value;
this.description = description;
this.hasRestriction = true;
}
public Setting(String name, T defaultValue, T min, T max) {
this.name = name;
this.defaultValue = defaultValue;
this.value = copy(defaultValue);
this.min = min;
this.max = max;
this.plannedValue = this.value;
this.description = "";
this.hasRestriction = true;
}
public Setting(String name, T defaultValue, T min, T max, Predicate<T> visibility, String description) {
this.name = name;
this.defaultValue = defaultValue;
this.value = copy(defaultValue);
this.min = min;
this.max = max;
this.plannedValue = this.value;
this.visibility = visibility;
this.description = description;
this.hasRestriction = true;
}
public Setting(String name, T defaultValue, T min, T max, Predicate<T> visibility) {
this.name = name;
this.defaultValue = defaultValue;
this.value = copy(defaultValue);
this.min = min;
this.max = max;
this.plannedValue = this.value;
this.visibility = visibility;
this.description = "";
this.hasRestriction = true;
}
public Setting(String name, T defaultValue, Predicate<T> visibility) {
this.name = name;
this.defaultValue = defaultValue;
this.value = copy(defaultValue);
this.visibility = visibility;
this.plannedValue = this.value;
}
public String getName() {
return this.name;
}
public T getValue() {
return this.value;
}
public void setValue(T value) {
this.setPlannedValue(value);
if (this.hasRestriction) {
if (((Number) this.min).floatValue() > ((Number) value).floatValue()) {
this.setPlannedValue(this.min);
}
if (((Number) this.max).floatValue() < ((Number) value).floatValue()) {
this.setPlannedValue(this.max);
}
}
ClientEvent event = new ClientEvent(this);
EVENT_BUS.post(event);
if (!event.isCancelled()) {
this.value = this.plannedValue;
} else {
this.plannedValue = this.value;
}
}
public void reset() {
setValue(copy(getDefaultValue()));
}
@SuppressWarnings("unchecked")
private static <T> T copy(T value) {
if (value instanceof Vector2f vector) {
return (T) new Vector2f(vector);
}
return value;
}
public T getPlannedValue() {
return this.plannedValue;
}
public void setPlannedValue(T value) {
this.plannedValue = value;
}
public T getMin() {
return this.min;
}
public void setMin(T min) {
this.min = min;
}
public T getMax() {
return this.max;
}
public void setMax(T max) {
this.max = max;
}
public void setValueNoEvent(T value) {
this.setPlannedValue(value);
if (this.hasRestriction) {
if (((Number) this.min).floatValue() > ((Number) value).floatValue()) {
this.setPlannedValue(this.min);
}
if (((Number) this.max).floatValue() < ((Number) value).floatValue()) {
this.setPlannedValue(this.max);
}
}
this.value = this.plannedValue;
}
public Feature getFeature() {
return this.feature;
}
public void setFeature(Feature feature) {
this.feature = feature;
}
public int getEnum(String input) {
for (int i = 0; i < this.value.getClass().getEnumConstants().length; ++i) {
Enum<?> e = (Enum<?>) this.value.getClass().getEnumConstants()[i];
if (!e.name().equalsIgnoreCase(input)) continue;
return i;
}
return -1;
}
@SuppressWarnings("unchecked")
public void setEnumValue(String value) {
for (Enum<?> e : ((Enum<?>) this.value).getClass().getEnumConstants()) {
if (!e.name().equalsIgnoreCase(value)) continue;
this.value = (T) e;
}
}
public String currentEnumName() {
return EnumConverter.getProperName((Enum<?>) this.value);
}
public int currentEnum() {
return EnumConverter.currentEnum((Enum<?>) this.value);
}
@SuppressWarnings("unchecked")
public void increaseEnum() {
this.plannedValue = (T) EnumConverter.increaseEnum((Enum<?>) this.value);
ClientEvent event = new ClientEvent(this);
EVENT_BUS.post(event);
if (!event.isCancelled()) {
this.value = this.plannedValue;
} else {
this.plannedValue = this.value;
}
}
@SuppressWarnings("unchecked")
public void increaseEnumNoEvent() {
this.value = (T) EnumConverter.increaseEnum((Enum<?>) this.value);
}
public String getType() {
if (this.isEnumSetting()) {
return "Enum";
}
if (this.isColorSetting()) {
return "Color";
}
if (this.isVec2fSetting()) {
return "Pos";
}
return this.getClassName(this.defaultValue);
}
public <K> String getClassName(K value) {
return value.getClass().getSimpleName();
}
public String getDescription() {
return Objects.requireNonNullElse(this.description, "");
}
public boolean isNumberSetting() {
return this.value instanceof Number;
}
public boolean isEnumSetting() {
return this.value instanceof Enum<?>;
}
public boolean isStringSetting() {
return this.value instanceof String;
}
public boolean isColorSetting() {
return this.value instanceof java.awt.Color;
}
public boolean isVec2fSetting() {
return this.value instanceof Vector2f;
}
public T getDefaultValue() {
return this.defaultValue;
}
public String getValueAsString() {
if (value instanceof Color color) {
return "%d, %d, %d, %d".formatted(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
}
if (value instanceof Enum<?> e) {
return e.name();
}
return this.value.toString();
}
public boolean hasRestriction() {
return this.hasRestriction;
}
public void setVisibility(Predicate<T> visibility) {
this.visibility = visibility;
}
public boolean isVisible() {
return this.visibility == null || this.visibility.test(this.getValue());
}
}
@@ -0,0 +1,46 @@
package me.alpha432.oyvey.features.settings;
import org.joml.Vector2f;
import java.awt.*;
public interface SettingFactory {
<T extends Setting<?>> T register(T setting);
default Setting<Boolean> bool(String name, boolean value) {
return register(new Setting<>(name, value));
}
default <T extends Number> Setting<T> num(String name, T value, T min, T max) {
return register(new Setting<>(name, value, min, max));
}
default Setting<String> str(String name, String value) {
return register(new Setting<>(name, value));
}
default <T extends Enum<?>> Setting<T> mode(String name, T value) {
return register(new Setting<>(name, value));
}
default Setting<Bind> key(String name, Bind bind) {
return register(new Setting<>(name, bind));
}
default Setting<Color> color(String name, Color value) {
return register(new Setting<>(name, value));
}
default Setting<Color> color(String name, int r, int g, int b, int a) {
return register(new Setting<>(name, new Color(r, g, b, a)));
}
default Setting<Vector2f> vec2f(String name, Vector2f value) {
return register(new Setting<>(name, value));
}
default Setting<Vector2f> vec2f(String name, float x, float y) {
return register(new Setting<>(name, new Vector2f(x, y)));
}
}
@@ -0,0 +1,39 @@
package me.alpha432.oyvey.manager;
import me.alpha432.oyvey.features.modules.client.ClickGuiModule;
import me.alpha432.oyvey.util.ColorUtil;
import java.awt.*;
public class ColorManager {
private Color color = new Color(0, 0, 255, 180);
public void init() {
ClickGuiModule ui = ClickGuiModule.getInstance();
setColor(ui.color.getValue());
}
public Color getColor() {
return this.color;
}
public void setColor(Color color) {
this.color = color;
}
public int getColorAsInt() {
return this.color.getRGB();
}
public int getColorAsIntFullAlpha() {
return new Color(this.color.getRed(), this.color.getGreen(), this.color.getBlue(), 255).getRGB();
}
public int getColorWithAlpha(float offset, int alpha) {
if (ClickGuiModule.getInstance().rainbow.getValue()) {
int rgb = ColorUtil.rainbow((int) (offset / 10f * ClickGuiModule.getInstance().rainbowHue.getValue())).getRGB();
return (rgb & 0xFFFFFF) | ((alpha & 0xFF) << 24);
}
return new Color(this.color.getRed(), this.color.getGreen(), this.color.getBlue(), alpha).getRGB();
}
}
@@ -0,0 +1,114 @@
package me.alpha432.oyvey.manager;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.features.Feature;
import me.alpha432.oyvey.features.commands.Command;
import me.alpha432.oyvey.features.commands.impl.*;
import me.alpha432.oyvey.util.traits.Jsonable;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.*;
import static me.alpha432.oyvey.features.commands.Command.SINGLE_FAILURE;
import static me.alpha432.oyvey.features.commands.MessageSignatures.GENERAL;
import static me.alpha432.oyvey.features.commands.MessageSignatures.SUCCESS;
public class CommandManager extends Feature implements Jsonable {
private static final Logger LOGGER = LogManager.getLogger("Commands");
private final CommandDispatcher<CommandManager> dispatcher = new CommandDispatcher<>();
private final Map<String, Command> commandAliasMap = new LinkedHashMap<>();
private final List<Command> commandList = new LinkedList<>();
private String commandPrefix = ".";
public CommandManager() {
super("Commands");
}
public void init() {
register(new BindCommand());
register(new DrawnCommand());
register(new FriendCommand());
register(new HelpCommand());
register(new PrefixCommand());
register(new ToggleCommand());
LOGGER.info("Registered {} commands", commandList.size());
OyVey.configManager.addConfig(this);
}
public void onChatSent(String message) {
try {
int result = dispatcher.execute(message.substring(getCommandPrefix().length()).trim(), this);
if (result == SINGLE_FAILURE) {
Command.sendMessage("{red} Failed to execute command", SUCCESS);
}
} catch (CommandSyntaxException e) {
LOGGER.error("Failed to execute command", e);
Command.sendMessage("{red} %s", GENERAL, e.getMessage());
} catch (RuntimeException e) {
LOGGER.error("Unexpected error while executing command", e);
Command.sendMessage("{red} Failed to execute command", GENERAL);
}
}
public void register(Command command) {
commandList.add(command);
for (String alias : command.getAliases()) {
commandAliasMap.put(alias, command);
LiteralArgumentBuilder<CommandManager> builder = Command.literal(alias);
command.createArgumentBuilder(builder);
dispatcher.register(builder);
}
}
public void setCommandPrefix(String commandPrefix) {
this.commandPrefix = commandPrefix;
}
public String getCommandPrefix() {
return commandPrefix;
}
public Command getCommand(String alias) {
return commandAliasMap.get(alias);
}
public Set<String> getCommandAliases() {
return commandAliasMap.keySet();
}
public List<Command> getCommands() {
return commandList;
}
public CommandDispatcher<CommandManager> getDispatcher() {
return dispatcher;
}
@Override
public JsonElement toJson() {
JsonObject object = new JsonObject();
object.addProperty("prefix", commandPrefix);
return object;
}
@Override
public void fromJson(JsonElement element) {
if (element == null || !element.isJsonObject()) return;
JsonObject object = element.getAsJsonObject();
if (object.has("prefix")) {
setCommandPrefix(object.get("prefix").getAsString());
}
}
}
@@ -0,0 +1,120 @@
package me.alpha432.oyvey.manager;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import me.alpha432.oyvey.features.Feature;
import me.alpha432.oyvey.features.settings.Bind;
import me.alpha432.oyvey.features.settings.EnumConverter;
import me.alpha432.oyvey.features.settings.Setting;
import me.alpha432.oyvey.util.traits.Jsonable;
import net.fabricmc.loader.api.FabricLoader;
import org.joml.Vector2f;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedList;
import java.util.List;
public class ConfigManager {
private static final Logger LOGGER = LoggerFactory.getLogger("ConfigManager");
private static final Path OYVEY_PATH = FabricLoader.getInstance().getGameDir().resolve("oyvey");
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private final List<Jsonable> jsonables = new LinkedList<>();
public void addConfig(Jsonable jsonable) {
jsonables.add(jsonable);
}
public void load() {
mkdirs();
for (Jsonable jsonable : jsonables) {
Path path = OYVEY_PATH.resolve(jsonable.getFileName());
if (!Files.exists(path)) continue;
try {
String read = Files.readString(path);
jsonable.fromJson(JsonParser.parseString(read));
} catch (Throwable e) {
LOGGER.error("Failed to load", e);
}
}
}
public synchronized void save() {
mkdirs();
for (Jsonable jsonable : jsonables) {
try {
JsonElement json = jsonable.toJson();
Path path = OYVEY_PATH.resolve(jsonable.getFileName());
Files.writeString(path, GSON.toJson(json));
} catch (Throwable e) {
LOGGER.error("Failed to write to file", e);
}
}
}
private void mkdirs() {
if (!OYVEY_PATH.toFile().exists()) {
boolean success = OYVEY_PATH.toFile().mkdirs();
if (!success) {
throw new RuntimeException("Failed to create needed directories!");
}
}
}
@SuppressWarnings({"rawtypes", "unchecked"})
public static void setValueFromJson(Feature feature, Setting setting, JsonElement element) {
if (element == null || element.isJsonNull()) return;
switch (setting.getType()) {
case "Boolean" -> setting.setValue(element.getAsBoolean());
case "Double" -> setting.setValue(element.getAsDouble());
case "Float" -> setting.setValue(element.getAsFloat());
case "Integer" -> setting.setValue(element.getAsInt());
case "String" -> setting.setValue(element.getAsString());
case "Bind" -> setting.setValue(new Bind(element.getAsInt()));
case "Color" -> {
try {
String colorStr = element.getAsString();
String[] parts = colorStr.split(",");
if (parts.length == 4) {
int r = Integer.parseInt(parts[0]);
int g = Integer.parseInt(parts[1]);
int b = Integer.parseInt(parts[2]);
int a = Integer.parseInt(parts[3]);
setting.setValue(new Color(r, g, b, a));
}
} catch (Exception exception) {
LOGGER.error("Error parsing color for: {} : {}", feature.getName(), setting.getName());
}
}
case "Pos" -> {
try {
String posStr = element.getAsString();
String[] parts = posStr.split(",");
if (parts.length == 2) {
float x = Float.parseFloat(parts[0]);
float y = Float.parseFloat(parts[1]);
setting.setValue(new Vector2f(x, y));
}
} catch (Exception exception) {
LOGGER.error("Error parsing position for: {} : {}", feature.getName(), setting.getName());
}
}
case "Enum" -> {
try {
EnumConverter converter = new EnumConverter(((Enum) setting.getValue()).getDeclaringClass());
Enum value = converter.doBackward(element);
setting.setValue(value);
} catch (Exception exception) {
LOGGER.error("Error parsing enum for {}.{}: {}", feature.getName(), setting.getName(), exception);
}
}
default -> LOGGER.error("Unknown Setting type for: {} : {}", feature.getName(), setting.getName());
}
}
}
@@ -0,0 +1,96 @@
package me.alpha432.oyvey.manager;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.event.Stage;
import me.alpha432.oyvey.event.impl.entity.DeathEvent;
import me.alpha432.oyvey.event.impl.entity.player.TickEvent;
import me.alpha432.oyvey.event.impl.entity.player.UpdateWalkingPlayerEvent;
import me.alpha432.oyvey.event.impl.input.KeyInputEvent;
import me.alpha432.oyvey.event.impl.input.MouseInputEvent;
import me.alpha432.oyvey.event.impl.network.ChatEvent;
import me.alpha432.oyvey.event.impl.network.PacketEvent;
import me.alpha432.oyvey.event.impl.render.Render2DEvent;
import me.alpha432.oyvey.event.impl.render.Render3DEvent;
import me.alpha432.oyvey.event.system.Subscribe;
import me.alpha432.oyvey.features.Feature;
import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket;
import net.minecraft.network.protocol.common.custom.BrandPayload;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.network.protocol.game.ClientboundSetTimePacket;
import net.minecraft.world.entity.player.Player;
import java.util.HashSet;
import java.util.Set;
public class EventManager extends Feature {
private final Set<Integer> deadPlayers = new HashSet<>();
public void init() {
EVENT_BUS.register(this);
}
public void onUnload() {
EVENT_BUS.unregister(this);
}
@Subscribe
public void onTick(TickEvent.Post event) {
if (nullCheck())
return;
OyVey.speedManager.update();
OyVey.moduleManager.onTick();
Set<Integer> dead = new HashSet<>();
for (Player player : mc.level.players()) {
if (player == null || player.getHealth() > 0.0F)
continue;
dead.add(player.getId());
if (!deadPlayers.contains(player.getId()))
EVENT_BUS.post(new DeathEvent(player));
}
deadPlayers.clear();
deadPlayers.addAll(dead);
}
@Subscribe
public void onPacketReceive(PacketEvent.Receive event) {
OyVey.serverManager.onPacketReceived();
if (event.getPacket() instanceof ClientboundSetTimePacket)
OyVey.serverManager.update();
if (event.getPacket() instanceof ClientboundCustomPayloadPacket(CustomPacketPayload payload)
&& payload instanceof BrandPayload(String brand)) {
OyVey.serverManager.setServerBrand(brand);
}
}
@Subscribe
public void onWorldRender(Render3DEvent event) {
OyVey.moduleManager.onRender3D(event);
}
@Subscribe
public void onRenderGameOverlayEvent(Render2DEvent event) {
OyVey.moduleManager.onRender2D(event);
}
@Subscribe
public void onKeyInput(KeyInputEvent event) {
OyVey.moduleManager.onKeyPressed(event.getKey());
}
@Subscribe
public void onMouseInput(MouseInputEvent event) {
if (event.getAction() == 1) {
OyVey.moduleManager.onMouseClicked(event.getButton());
}
}
@Subscribe
public void onChatSent(ChatEvent event) {
String message = event.getMessage();
if (!message.startsWith(OyVey.commandManager.getCommandPrefix())) {
return;
}
event.cancel();
OyVey.commandManager.onChatSent(message);
}
}
@@ -0,0 +1,67 @@
package me.alpha432.oyvey.manager;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.util.traits.Jsonable;
import net.minecraft.world.entity.player.Player;
import java.util.ArrayList;
import java.util.List;
public class FriendManager implements Jsonable {
private final List<String> friends = new ArrayList<>();
public void init() {
OyVey.configManager.addConfig(this);
}
public boolean isFriend(String name) {
return this.friends.stream().anyMatch(friend -> friend.equalsIgnoreCase(name));
}
public boolean isFriend(Player player) {
return this.isFriend(player.getGameProfile().name());
}
public void addFriend(String name) {
this.friends.add(name);
}
public void removeFriend(String name) {
friends.removeIf(s -> s.equalsIgnoreCase(name));
}
public List<String> getFriends() {
return this.friends;
}
@Override
public JsonElement toJson() {
JsonObject object = new JsonObject();
JsonArray array = new JsonArray();
for (String friend : friends) {
array.add(friend);
}
object.add("friends", array);
return object;
}
@Override
public void fromJson(JsonElement element) {
friends.clear();
if (element == null || !element.isJsonObject()) return;
JsonElement array = element.getAsJsonObject().get("friends");
if (array == null || !array.isJsonArray()) return;
for (JsonElement e : array.getAsJsonArray()) {
String name = e.getAsString();
if (!friends.contains(name)) friends.add(name);
}
}
@Override
public String getFileName() {
return "friends.json";
}
}
@@ -0,0 +1,68 @@
package me.alpha432.oyvey.manager;
import me.alpha432.oyvey.event.impl.entity.player.TickEvent;
import me.alpha432.oyvey.event.system.Subscribe;
import me.alpha432.oyvey.features.Feature;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class HoleManager extends Feature {
private static final int RANGE = 8;
private final List<Hole> holes = new ArrayList<>();
private final BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
public HoleManager() {
EVENT_BUS.register(this);
}
@Subscribe
private void onTick(TickEvent.Pre event) {
holes.clear();
for (int x = -RANGE; x < RANGE; x++) {
for (int y = -RANGE; y < RANGE; y++) {
for (int z = -RANGE; z < RANGE; z++) {
pos.set(mc.player.getX() + x, mc.player.getY() + y, mc.player.getZ() + z);
Hole hole = getHole(pos);
if (hole == null) continue;
holes.add(hole);
}
}
}
}
@Nullable
public Hole getHole(BlockPos pos) {
if (mc.level.getBlockState(pos).getBlock() != Blocks.AIR)
return null;
HoleType type = HoleType.BEDROCK;
for (Direction direction : Direction.Plane.HORIZONTAL) {
Block block = mc.level.getBlockState(pos.relative(direction)).getBlock();
if (block == Blocks.OBSIDIAN) type = HoleType.UNSAFE;
else if (block != Blocks.BEDROCK) return null;
}
return new Hole(pos.immutable(), type);
}
public List<Hole> getHoles() {
return holes;
}
public boolean isHole(BlockPos pos) {
return holes.stream().anyMatch(hole -> hole.pos().equals(pos));
}
public record Hole(BlockPos pos, HoleType holeType) {
}
private enum HoleType {
BEDROCK,
UNSAFE
}
}
@@ -0,0 +1,165 @@
package me.alpha432.oyvey.manager;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import me.alpha432.oyvey.OyVey;
import me.alpha432.oyvey.event.impl.render.Render2DEvent;
import me.alpha432.oyvey.features.gui.OyVeyGui;
import net.minecraft.client.gui.screens.TitleScreen;
import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen;
import me.alpha432.oyvey.event.impl.render.Render3DEvent;
import me.alpha432.oyvey.features.Feature;
import me.alpha432.oyvey.features.commands.ModuleCommand;
import me.alpha432.oyvey.features.modules.Module;
import me.alpha432.oyvey.features.modules.client.ClickGuiModule;
import me.alpha432.oyvey.features.modules.client.HudEditorModule;
import me.alpha432.oyvey.features.modules.client.NotificationsModule;
import me.alpha432.oyvey.features.modules.combat.KillAuraModule;
import me.alpha432.oyvey.features.modules.combat.CriticalsModule;
import me.alpha432.oyvey.features.modules.combat.KeyPearlModule;
import me.alpha432.oyvey.features.modules.hud.CoordinatesHudModule;
import me.alpha432.oyvey.features.modules.hud.WatermarkHudModule;
import me.alpha432.oyvey.features.modules.misc.MCFModule;
import me.alpha432.oyvey.features.modules.movement.FastAccelModule;
import me.alpha432.oyvey.features.modules.movement.ReverseStepModule;
import me.alpha432.oyvey.features.modules.movement.StepModule;
import me.alpha432.oyvey.features.modules.player.FastPlaceModule;
import me.alpha432.oyvey.features.modules.player.NoFallModule;
import me.alpha432.oyvey.features.modules.player.VelocityModule;
import me.alpha432.oyvey.features.modules.render.BlockHighlightModule;
import me.alpha432.oyvey.util.traits.Jsonable;
import me.alpha432.oyvey.util.traits.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.stream.Stream;
public class ModuleManager implements Jsonable, Util {
private static final Logger LOGGER = LoggerFactory.getLogger("ModuleManager");
private final Map<Class<? extends Module>, Module> fastRegistry = new HashMap<>();
private final List<Module> modules = new ArrayList<>();
public void init() {
register(new WatermarkHudModule());
register(new CoordinatesHudModule());
register(new HudEditorModule());
register(new ClickGuiModule());
register(new NotificationsModule());
register(new CriticalsModule());
register(new MCFModule());
register(new StepModule());
register(new ReverseStepModule());
register(new FastPlaceModule());
register(new VelocityModule());
register(new BlockHighlightModule());
register(new NoFallModule());
register(new KeyPearlModule());
register(new KillAuraModule());
register(new FastAccelModule());
LOGGER.info("Registered {} modules", modules.size());
// Create a command for each module for modules to be configurable via command line
for (Module module : modules) {
OyVey.commandManager.register(new ModuleCommand(module));
}
OyVey.configManager.addConfig(this);
}
public void register(Module module) {
getModules().add(module);
fastRegistry.put(module.getClass(), module);
}
public List<Module> getModules() {
return modules;
}
public Stream<Module> stream() {
return getModules().stream();
}
@SuppressWarnings("unchecked")
public <T extends Module> T getModuleByClass(Class<T> clazz) {
return (T) fastRegistry.get(clazz);
}
public Module getModuleByName(String name) {
return stream().filter(m -> m.getName().equalsIgnoreCase(name)).findFirst().orElse(null);
}
public Module getModuleByDisplayName(String display) {
return stream().filter(m -> m.getDisplayName().equalsIgnoreCase(display)).findFirst().orElse(null);
}
public List<Module> getModulesByCategory(Module.Category category) {
return stream().filter(m -> m.getCategory() == category).toList();
}
public List<Module.Category> getCategories() {
return Arrays.asList(Module.Category.values());
}
public void onLoad() {
getModules().forEach(Module::onLoad);
}
public void onTick() {
stream().filter(Feature::isEnabled).forEach(Module::onTick);
}
public void onRender2D(Render2DEvent event) {
stream().filter(Feature::isEnabled).forEach(module -> module.onRender2D(event));
}
public void onRender3D(Render3DEvent event) {
stream().filter(Feature::isEnabled).forEach(module -> module.onRender3D(event));
}
public void onUnload() {
getModules().forEach(EVENT_BUS::unregister);
getModules().forEach(Module::onUnload);
}
public void onKeyPressed(int key) {
if (key <= 0) return;
if (mc.screen instanceof TitleScreen || mc.screen instanceof JoinMultiplayerScreen) {
if (ClickGuiModule.getInstance().getBind().getKey() == key) {
OyVeyGui.open(mc.screen);
}
return;
}
if (mc.screen != null) return;
stream().filter(module -> module.getBind().getKey() == key).forEach(Module::toggle);
}
public void onMouseClicked(int button) {
if (mc.screen != null) return;
int key = -button - 2;
stream().filter(module -> module.getBind().getKey() == key).forEach(Module::toggle);
}
@Override
public JsonElement toJson() {
JsonObject object = new JsonObject();
for (Module module : getModules()) {
object.add(module.getName(), module.toJson());
}
return object;
}
@Override
public void fromJson(JsonElement element) {
for (Module module : getModules()) {
module.fromJson(element.getAsJsonObject().get(module.getName()));
}
}
@Override
public String getFileName() {
return "modules.json";
}
}
@@ -0,0 +1,92 @@
package me.alpha432.oyvey.manager;
import me.alpha432.oyvey.event.Stage;
import me.alpha432.oyvey.event.impl.entity.player.UpdateWalkingPlayerEvent;
import me.alpha432.oyvey.event.system.Subscribe;
import me.alpha432.oyvey.features.Feature;
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
public class PositionManager
extends Feature {
private double x;
private double y;
private double z;
private boolean onground;
private double fallDistance;
public PositionManager() {
EVENT_BUS.register(this);
}
@Subscribe
public void onUpdateWalkingPlayer(UpdateWalkingPlayerEvent event) {
if (event.getStage() == Stage.POST) return;
double diff = mc.player.yo - mc.player.getY();
if (mc.player.onGround() || diff <= 0) {
fallDistance = 0;
} else {
fallDistance += diff;
}
}
public void updatePosition() {
this.x = mc.player.getX();
this.y = mc.player.getY();
this.z = mc.player.getZ();
this.onground = mc.player.onGround();
}
public void restorePosition() {
mc.player.setPos(x, y, z);
mc.player.setOnGround(onground);
}
public void setPlayerPosition(double x, double y, double z) {
mc.player.setPos(x, y, z);
}
public void setPlayerPosition(double x, double y, double z, boolean onground) {
mc.player.setPos(x, y, z);
mc.player.setOnGround(onground);
}
public void setPositionPacket(double x, double y, double z, boolean onGround, boolean setPos, boolean noLagBack) {
boolean bl = mc.player.horizontalCollision;
mc.player.connection.send(new ServerboundMovePlayerPacket.Pos(x, y, z, onGround, bl));
if (setPos) {
mc.player.setPos(x, y, z);
if (noLagBack) {
this.updatePosition();
}
}
}
public double getX() {
return this.x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return this.y;
}
public void setY(double y) {
this.y = y;
}
public double getZ() {
return this.z;
}
public void setZ(double z) {
this.z = z;
}
public double getFallDistance() {
return fallDistance;
}
}
@@ -0,0 +1,162 @@
package me.alpha432.oyvey.manager;
import me.alpha432.oyvey.event.Stage;
import me.alpha432.oyvey.event.impl.entity.player.TickEvent;
import me.alpha432.oyvey.event.impl.entity.player.TravelEvent;
import me.alpha432.oyvey.event.impl.entity.player.UpdateWalkingPlayerEvent;
import me.alpha432.oyvey.event.system.Subscribe;
import me.alpha432.oyvey.util.models.Angles;
import me.alpha432.oyvey.util.traits.Util;
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
import net.minecraft.util.Mth;
import java.util.*;
import java.util.function.Predicate;
public class RotationManager implements Util {
private final List<Callback> callbacks = new ArrayList<>();
private boolean updateRender;
private Angles renderSnapshot, renderSnapshot0;
private Angles snapshot;
private Angles travelSnapshot;
public RotationManager() {
EVENT_BUS.register(this);
}
@Subscribe(priority = 1000)
public void onTickPre(TickEvent.Pre event) {
executeCallbacks(callback -> callback.type() == Type.SYNC);
}
@Subscribe
public void onTravelPre(TravelEvent.Pre event) {
if (callbacks.isEmpty())
return;
Callback highest = callbacks.stream().max(Comparator.comparing(Callback::priority)).orElseThrow();
if (highest.type() == Type.SYNC) {
travelSnapshot = new Angles(mc.player.getYRot(), mc.player.getXRot());
mc.player.setYRot(highest.angles().yRot());
mc.player.setXRot(highest.angles().xRot());
}
}
@Subscribe
public void onTravelPost(TravelEvent.Post event) {
if (travelSnapshot != null) {
mc.player.setYRot(travelSnapshot.yRot());
mc.player.setXRot(travelSnapshot.xRot());
travelSnapshot = null;
}
}
@Subscribe
public void onUpdateWalking(UpdateWalkingPlayerEvent event) {
if (event.getStage() == Stage.PRE) {
if (callbacks.isEmpty()) {
updateRenderSnapshot(new Angles(mc.player.getYRot(), mc.player.getXRot()), false);
return;
}
Callback highest = callbacks.stream().max(Comparator.comparing(Callback::priority)).orElseThrow();
updateRenderSnapshot(highest.angles(), true);
snapshot = new Angles(mc.player.getYRot(), mc.player.getXRot());
mc.player.setYRot(highest.angles().yRot());
mc.player.setXRot(highest.angles().xRot());
} else if (snapshot != null) {
executeCallbacks(callback -> callback.type() == Type.MOTION);
mc.player.setYRot(snapshot.yRot());
mc.player.setXRot(snapshot.xRot());
snapshot = null;
}
}
public void sync(Angles angles, Runnable runnable) {
sync(angles, 0, runnable);
}
public void sync(Angles angles, int priority, Runnable runnable) {
request(Type.SYNC, angles, priority, runnable);
}
public void motion(Angles angles, Runnable runnable) {
motion(angles, 0, runnable);
}
public void motion(Angles angles, int priority, Runnable runnable) {
request(Type.MOTION, angles, priority, runnable);
}
public void silent(Angles angles, Runnable runnable) {
request(Type.SILENT, angles, 0, runnable);
}
public Angles getLerpRenderSnapshot(float lerp) {
if (!updateRender) return null;
return new Angles(
Mth.lerp(lerp, renderSnapshot0.yRot(), renderSnapshot.yRot()),
Mth.lerp(lerp, renderSnapshot0.xRot(), renderSnapshot.xRot())
);
}
public void sendDuplicate(float yaw, float pitch) {
mc.player.positionReminder = 20;
mc.player.yRotLast = yaw;
mc.player.xRotLast = pitch;
mc.player.connection.send(new ServerboundMovePlayerPacket.PosRot(
mc.player.getX(), mc.player.getY(), mc.player.getZ(),
yaw, pitch,
mc.player.onGround(), mc.player.horizontalCollision
));
}
private void request(Type type, Angles angles, int priority, Runnable runnable) {
Callback callback = new Callback(type, angles, priority, runnable);
if (type == Type.SILENT) {
sendDuplicate(angles.yRot(), angles.xRot());
callback.execute();
} else {
callbacks.add(callback);
}
}
private void executeCallbacks(Predicate<Callback> filter) {
callbacks.removeIf(callback -> {
if (filter.test(callback)) {
callback.execute();
return true;
}
return false;
});
}
private void updateRenderSnapshot(Angles angles, boolean update) {
this.renderSnapshot0 = this.renderSnapshot;
this.renderSnapshot = angles;
this.updateRender = update;
if (renderSnapshot0 == null || renderSnapshot == null)
return;
if (Mth.abs(renderSnapshot.yRot() - renderSnapshot0.yRot()) > 320) {
this.renderSnapshot0 = this.renderSnapshot;
}
}
record Callback(Type type, Angles angles, int priority, Runnable action) {
public void execute() {
if (action != null) action.run();
}
}
public enum Type {
MOTION,
SYNC,
SILENT
}
}
@@ -0,0 +1,88 @@
package me.alpha432.oyvey.manager;
import me.alpha432.oyvey.features.Feature;
import me.alpha432.oyvey.util.models.Timer;
import java.util.Arrays;
public class ServerManager
extends Feature {
private final float[] tpsCounts = new float[10];
private final Timer timer = new Timer();
private float tps = 20.0f;
private long lastUpdate = -1L;
private String serverBrand = "";
public void onPacketReceived() {
this.timer.reset();
}
public void update() {
float tps;
long currentTime = System.currentTimeMillis();
if (this.lastUpdate == -1L) {
this.lastUpdate = currentTime;
return;
}
long timeDiff = currentTime - this.lastUpdate;
float tickTime = (float) timeDiff / 20.0f;
if (tickTime == 0.0f) {
tickTime = 50.0f;
}
if ((tps = 1000.0f / tickTime) > 20.0f) {
tps = 20.0f;
}
System.arraycopy(this.tpsCounts, 0, this.tpsCounts, 1, this.tpsCounts.length - 1);
this.tpsCounts[0] = tps;
double total = 0.0;
for (float f : this.tpsCounts) {
total += f;
}
if ((total /= this.tpsCounts.length) > 20.0) {
total = 20.0;
}
this.tps = (float) total;
this.lastUpdate = currentTime;
}
@Override
public void reset() {
Arrays.fill(this.tpsCounts, 20.0f);
this.tps = 20.0f;
}
public boolean isServerNotResponding() {
return this.timer.passedMs(2000);
}
public long serverRespondingTime() {
return this.timer.getPassedTimeMs();
}
public float getTpsFactor() {
return 20.0f / this.tps;
}
public float getTps() {
return this.tps;
}
public String getServerBrand() {
return this.serverBrand;
}
public void setServerBrand(String brand) {
this.serverBrand = brand;
}
public int getPing() {
if (ServerManager.nullCheck()) {
return 0;
}
try {
return mc.getConnection().getPlayerInfo(mc.player.getGameProfile().name()).getLatency();
} catch (Throwable e) {
return 0;
}
}
}
@@ -0,0 +1,47 @@
package me.alpha432.oyvey.manager;
import me.alpha432.oyvey.features.Feature;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import java.util.ArrayList;
import java.util.List;
public class SpeedManager extends Feature {
private static final int SPEED_NORMALIZATION = 20;
private final List<Float> localSpeed = new ArrayList<>();
private float localSpeedNormal = 0f;
public void update() {
localSpeed.add(getCurrentSpeed(mc.player));
while (localSpeed.size() > SPEED_NORMALIZATION) localSpeed.removeFirst();
localSpeedNormal = localSpeed.stream().reduce(0f, Float::sum) / localSpeed.size();
}
public double getSpeed(Player player) {
if (mc.player == player) return localSpeedNormal;
return getCurrentSpeed(player);
}
public double getSpeedBpS(Player player) {
return getSpeed(player) * 20;
}
public double getSpeedKmH(Player player) {
return getSpeedBpS(player) * 3.6;
}
public float getCurrentSpeed(Entity entity) {
Entity vehicle = entity.getVehicle();
double distTraveledX = entity.getX() - entity.xo;
double distTraveledZ = entity.getZ() - entity.zo;
if (vehicle != null) {
distTraveledX = vehicle.getX() - vehicle.xo;
distTraveledZ = vehicle.getZ() - vehicle.zo;
}
return (float) Math.hypot(distTraveledX, distTraveledZ);
}
}
@@ -0,0 +1,28 @@
package me.alpha432.oyvey.mixin.entity;
import me.alpha432.oyvey.event.impl.entity.player.TravelEvent;
import net.minecraft.client.player.AbstractClientPlayer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static me.alpha432.oyvey.util.traits.Util.EVENT_BUS;
import static me.alpha432.oyvey.util.traits.Util.isLocalPlayer;
@Mixin(AbstractClientPlayer.class)
public class MixinAbstractClientPlayer {
@Inject(method = "tick", at = @At("HEAD"))
private void travelPreHook(CallbackInfo ci) {
if (isLocalPlayer(this)) {
EVENT_BUS.post(new TravelEvent.Pre());
}
}
@Inject(method = "tick", at = @At("TAIL"))
private void travelPostHook(CallbackInfo ci) {
if (isLocalPlayer(this)) {
EVENT_BUS.post(new TravelEvent.Post());
}
}
}
@@ -0,0 +1,48 @@
package me.alpha432.oyvey.mixin.entity;
import me.alpha432.oyvey.event.Stage;
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import me.alpha432.oyvey.event.impl.entity.player.MoveEvent;
import me.alpha432.oyvey.event.impl.entity.player.TickEvent;
import me.alpha432.oyvey.event.impl.entity.player.UpdateWalkingPlayerEvent;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.world.entity.MoverType;
import net.minecraft.world.phys.Vec3;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static me.alpha432.oyvey.util.traits.Util.EVENT_BUS;
@Mixin(LocalPlayer.class)
public class MixinClientPlayerEntity {
@Inject(method = "tick", at = @At("HEAD"))
private void tickPreHook(CallbackInfo ci) {
EVENT_BUS.post(new TickEvent.Pre());
}
@Inject(method = "tick", at = @At("TAIL"))
private void tickHook(CallbackInfo ci) {
EVENT_BUS.post(new TickEvent.Post());
}
@Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/AbstractClientPlayer;tick()V", shift = At.Shift.AFTER))
private void tickHook2(CallbackInfo ci) {
EVENT_BUS.post(new UpdateWalkingPlayerEvent(Stage.PRE));
}
@Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;sendPosition()V", shift = At.Shift.AFTER))
private void tickHook3(CallbackInfo ci) {
EVENT_BUS.post(new UpdateWalkingPlayerEvent(Stage.POST));
}
@WrapMethod(method = "move")
private void moveHook(MoverType type, Vec3 movement, Operation<Void> original) {
MoveEvent event = new MoveEvent(type, movement);
EVENT_BUS.post(event);
if (event.isCancelled()) return;
original.call(type, event.getMovement());
}
}
@@ -0,0 +1,21 @@
package me.alpha432.oyvey.mixin.input;
import me.alpha432.oyvey.event.impl.input.KeyInputEvent;
import net.minecraft.client.KeyboardHandler;
import net.minecraft.client.input.KeyEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static me.alpha432.oyvey.util.traits.Util.EVENT_BUS;
@Mixin(KeyboardHandler.class)
public class MixinKeyboardHandler {
@Inject(method = "keyPress", at = @At("TAIL"))
private void keyPress(long l, int i, KeyEvent keyEvent, CallbackInfo ci) {
if (i != 1) return;
EVENT_BUS.post(new KeyInputEvent(keyEvent.key()));
}
}
@@ -0,0 +1,22 @@
package me.alpha432.oyvey.mixin.input;
import me.alpha432.oyvey.event.impl.input.MouseInputEvent;
import net.minecraft.client.MouseHandler;
import net.minecraft.client.input.MouseButtonInfo;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static me.alpha432.oyvey.util.traits.Util.EVENT_BUS;
@Mixin(MouseHandler.class)
public class MixinMouseHandler {
@Inject(method = "onButton", at = @At("HEAD"), cancellable = true)
private void onButton(long window, MouseButtonInfo input, int action, CallbackInfo ci) {
if (EVENT_BUS.post(new MouseInputEvent(input.button(), action))) {
ci.cancel();
}
}
}
@@ -0,0 +1,20 @@
package me.alpha432.oyvey.mixin.network;
import me.alpha432.oyvey.event.impl.network.ChatEvent;
import net.minecraft.client.multiplayer.ClientPacketListener;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static me.alpha432.oyvey.util.traits.Util.EVENT_BUS;
@Mixin(ClientPacketListener.class)
public class MixinClientPacketListener {
@Inject(method = "sendChat", at = @At("HEAD"), cancellable = true)
private void sendChat(String content, CallbackInfo ci) {
if (EVENT_BUS.post(new ChatEvent(content))) {
ci.cancel();
}
}
}
@@ -0,0 +1,59 @@
package me.alpha432.oyvey.mixin.network;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import me.alpha432.oyvey.event.impl.network.PacketEvent;
import net.minecraft.network.Connection;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.PacketFlow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static me.alpha432.oyvey.util.traits.Util.EVENT_BUS;
@Mixin(Connection.class)
public class MixinConnection {
@Unique
private static final Logger LOGGER = LoggerFactory.getLogger("PacketEvent");
@Shadow
private Channel channel;
@Shadow
@Final
private PacketFlow receiving;
@Inject(method = "channelRead0*", at = @At("HEAD"), cancellable = true)
public void channelRead0(ChannelHandlerContext chc, Packet<?> packet, CallbackInfo ci) {
if (this.channel.isOpen() && packet != null) {
try {
if (EVENT_BUS.post(new PacketEvent.Receive(packet))) {
ci.cancel();
}
} catch (Exception e) {
LOGGER.error("Failed to post packet event for {}", packet.getClass().getSimpleName(), e);
}
}
}
@Inject(method = "sendPacket", at = @At("HEAD"), cancellable = true)
private void sendPacket(Packet<?> packet, ChannelFutureListener callbacks, boolean flush, CallbackInfo ci) {
if (this.receiving != PacketFlow.CLIENTBOUND) return;
try {
if (EVENT_BUS.post(new PacketEvent.Send(packet))) {
ci.cancel();
}
} catch (Exception e) {
LOGGER.error("Failed to post packet event for {}", packet.getClass().getSimpleName(), e);
}
}
}

Some files were not shown because too many files have changed in this diff Show More