Add SQLite-based data storage system & account manager
You can access the account manager by pressing right-shift from the title screenmain
parent
a1cff649dd
commit
f96a4fc83d
|
@ -19,7 +19,9 @@ version = modVersion
|
|||
val mavenGroup: String by project
|
||||
group = mavenGroup
|
||||
|
||||
repositories {}
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
val minecraftVersion: String by project
|
||||
|
@ -52,7 +54,12 @@ dependencies {
|
|||
implementation(files("vendor/libs/lwjgl-util.jar"))
|
||||
implementation(files("vendor/libs/minecraft_authenticator-2.0.1.jar"))
|
||||
|
||||
runtimeOnly("org.joml:joml:1.10.2")
|
||||
implementation("org.jetbrains.exposed:exposed-core:0.37.3")
|
||||
implementation("org.jetbrains.exposed:exposed-dao:0.37.3")
|
||||
implementation("org.jetbrains.exposed:exposed-jdbc:0.37.3")
|
||||
runtimeOnly("org.xerial:sqlite-jdbc:3.36.0.3")
|
||||
|
||||
runtimeOnly("org.joml:joml:1.10.4")
|
||||
runtimeOnly("org.anarres:jcpp:1.4.14")
|
||||
|
||||
modImplementation(files("vendor/mods/baritone-unoptimized-fabric-1.8.2.jar"))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package codes.som.hibiscus.mixins;
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod;
|
||||
import codes.som.hibiscus.Hibiscus;
|
||||
import codes.som.hibiscus.events.ReceivePacketEvent;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import net.minecraft.network.Packet;
|
||||
|
@ -15,7 +15,7 @@ public abstract class MixinClientConnection {
|
|||
@Inject(method = "handlePacket", at = @At("HEAD"), cancellable = true)
|
||||
private static <T extends PacketListener> void onHandlePacket(Packet<T> packet, PacketListener listener, CallbackInfo ci) {
|
||||
var event = new ReceivePacketEvent(packet);
|
||||
HibiscusMod.bus().fire(event);
|
||||
Hibiscus.bus().fire(event);
|
||||
if (event.isCancelled())
|
||||
ci.cancel();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package codes.som.hibiscus.mixins;
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod;
|
||||
import codes.som.hibiscus.Hibiscus;
|
||||
import codes.som.hibiscus.events.SendPacketEvent;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
|
@ -14,7 +14,7 @@ public abstract class MixinClientPlayNetworkHandler {
|
|||
@Redirect(method = "sendPacket", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;send(Lnet/minecraft/network/Packet;)V"))
|
||||
public void onSendPacket(ClientConnection clientConnection, Packet<?> packet) {
|
||||
var event = new SendPacketEvent(packet);
|
||||
HibiscusMod.bus().fire(event);
|
||||
Hibiscus.bus().fire(event);
|
||||
if (!event.isCancelled()) {
|
||||
clientConnection.send(event.getPacket());
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package codes.som.hibiscus.mixins;
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod;
|
||||
import codes.som.hibiscus.Hibiscus;
|
||||
import codes.som.hibiscus.events.MovePlayerEvent;
|
||||
import codes.som.hibiscus.events.PlayerPreTickEvent;
|
||||
import codes.som.hibiscus.events.PlayerTickEvent;
|
||||
|
@ -19,18 +19,18 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||
public abstract class MixinClientPlayerEntity {
|
||||
@Inject(method = "tick", at = @At("HEAD"))
|
||||
private void onPreTick(CallbackInfo ci) {
|
||||
HibiscusMod.bus().fire(PlayerPreTickEvent.INSTANCE);
|
||||
Hibiscus.bus().fire(PlayerPreTickEvent.INSTANCE);
|
||||
}
|
||||
|
||||
@Inject(method = "tick", at = @At("RETURN"))
|
||||
private void onPostTick(CallbackInfo ci) {
|
||||
HibiscusMod.bus().fire(PlayerTickEvent.INSTANCE);
|
||||
Hibiscus.bus().fire(PlayerTickEvent.INSTANCE);
|
||||
}
|
||||
|
||||
@Inject(method = "sendChatMessage", at = @At("HEAD"), cancellable = true)
|
||||
private void onChatMessage(String message, CallbackInfo ci) {
|
||||
var event = new SendChatEvent(message);
|
||||
HibiscusMod.bus().fire(event);
|
||||
Hibiscus.bus().fire(event);
|
||||
if (event.isCancelled())
|
||||
ci.cancel();
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public abstract class MixinClientPlayerEntity {
|
|||
@ModifyVariable(method = "move", at = @At(value = "HEAD", shift = At.Shift.AFTER), argsOnly = true)
|
||||
private Vec3d onMovePlayer(Vec3d movement) {
|
||||
var event = new MovePlayerEvent(movement.x, movement.y, movement.z, this.movementType);
|
||||
HibiscusMod.bus().fire(event);
|
||||
Hibiscus.bus().fire(event);
|
||||
return new Vec3d(event.getX(), event.getY(), event.getZ());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package codes.som.hibiscus.mixins;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.util.Session;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(MinecraftClient.class)
|
||||
public interface MixinExtMinecraftClient {
|
||||
@Accessor
|
||||
@Mutable
|
||||
void setSession(Session session);
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package codes.som.hibiscus.mixins;
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod;
|
||||
import codes.som.hibiscus.Hibiscus;
|
||||
import codes.som.hibiscus.events.Render3DEvent;
|
||||
import codes.som.hibiscus.events.RenderHandEvent;
|
||||
import codes.som.hibiscus.util.graphics.MinecraftRenderPipelineProgress;
|
||||
|
@ -44,7 +44,7 @@ public abstract class MixinGameRenderer {
|
|||
|
||||
matrices.push();
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
HibiscusMod.bus().fire(new Render3DEvent(tickDelta, this.camera, matrices));
|
||||
Hibiscus.bus().fire(new Render3DEvent(tickDelta, this.camera, matrices));
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ public abstract class MixinGameRenderer {
|
|||
@Inject(method = "renderHand", at = @At("HEAD"), cancellable = true)
|
||||
private void onRenderHand(MatrixStack matrices, Camera camera, float tickDelta, CallbackInfo ci) {
|
||||
var event = new RenderHandEvent(tickDelta);
|
||||
HibiscusMod.bus().fire(event);
|
||||
Hibiscus.bus().fire(event);
|
||||
if (event.isCancelled())
|
||||
ci.cancel();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package codes.som.hibiscus.mixins;
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod;
|
||||
import codes.som.hibiscus.Hibiscus;
|
||||
import codes.som.hibiscus.events.CharEvent;
|
||||
import codes.som.hibiscus.events.KeyEvent;
|
||||
import net.minecraft.client.Keyboard;
|
||||
|
@ -23,7 +23,7 @@ public abstract class MixinKeyboard {
|
|||
if (window != this.client.getWindow().getHandle())
|
||||
return; // Just in case
|
||||
|
||||
HibiscusMod.bus().fire(new KeyEvent(key, action));
|
||||
Hibiscus.bus().fire(new KeyEvent(key, action));
|
||||
}
|
||||
|
||||
@Inject(method = "onChar", at = @At("HEAD"))
|
||||
|
@ -31,6 +31,6 @@ public abstract class MixinKeyboard {
|
|||
if (window != this.client.getWindow().getHandle())
|
||||
return;
|
||||
|
||||
HibiscusMod.bus().fire(new CharEvent((char) character));
|
||||
Hibiscus.bus().fire(new CharEvent((char) character));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package codes.som.hibiscus.mixins;
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod;
|
||||
import codes.som.hibiscus.Hibiscus;
|
||||
import codes.som.hibiscus.events.GetRenderViewEntityEvent;
|
||||
import codes.som.hibiscus.events.PostRenderAllEvent;
|
||||
import codes.som.hibiscus.gui.ImGuiRenderer;
|
||||
|
@ -43,7 +43,7 @@ public abstract class MixinMinecraftClient {
|
|||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gl/Framebuffer;endWrite()V", shift = At.Shift.BEFORE))
|
||||
private void onPostRenderEverything(boolean tick, CallbackInfo ci) {
|
||||
float delta = this.paused ? this.pausedTickDelta : this.renderTickCounter.tickDelta;
|
||||
HibiscusMod.bus().fire(new PostRenderAllEvent(delta));
|
||||
Hibiscus.bus().fire(new PostRenderAllEvent(delta));
|
||||
ImGuiRenderer.INSTANCE.finishFrame(delta);
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ public abstract class MixinMinecraftClient {
|
|||
|
||||
if (view != null) {
|
||||
var event = new GetRenderViewEntityEvent(view);
|
||||
HibiscusMod.bus().fire(event);
|
||||
Hibiscus.bus().fire(event);
|
||||
cir.setReturnValue(event.getViewEntity());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package codes.som.hibiscus.mixins;
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod;
|
||||
import codes.som.hibiscus.Hibiscus;
|
||||
import codes.som.hibiscus.events.WorldCullingEvent;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.RenderSectionManager;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
@ -13,7 +13,7 @@ public abstract class MixinRenderSectionManager {
|
|||
@Redirect(method = "initSearch", at = @At(value = "FIELD", target = "Lnet/minecraft/client/MinecraftClient;chunkCullingEnabled:Z"))
|
||||
public boolean cancelCulling(MinecraftClient client) {
|
||||
var event = new WorldCullingEvent();
|
||||
HibiscusMod.bus().fire(event);
|
||||
Hibiscus.bus().fire(event);
|
||||
return client.chunkCullingEnabled && !event.isCancelled();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package codes.som.hibiscus.mixins;
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod;
|
||||
import codes.som.hibiscus.Hibiscus;
|
||||
import codes.som.hibiscus.events.PostRenderEntitiesEvent;
|
||||
import codes.som.hibiscus.events.PostRenderWorldEvent;
|
||||
import codes.som.hibiscus.events.PreRenderEntitiesEvent;
|
||||
|
@ -21,12 +21,12 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||
public abstract class MixinWorldRenderer {
|
||||
@Inject(method = "render", at = @At("HEAD"))
|
||||
private void onPreRenderWorld(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) {
|
||||
HibiscusMod.bus().fire(new PreRenderWorldEvent(tickDelta, camera, matrices));
|
||||
Hibiscus.bus().fire(new PreRenderWorldEvent(tickDelta, camera, matrices));
|
||||
}
|
||||
|
||||
@Inject(method = "render", at = @At("HEAD"))
|
||||
private void onPostRenderWorld(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) {
|
||||
HibiscusMod.bus().fire(new PostRenderWorldEvent(tickDelta, camera, matrices));
|
||||
Hibiscus.bus().fire(new PostRenderWorldEvent(tickDelta, camera, matrices));
|
||||
}
|
||||
|
||||
/* Obsoleted by Sodium-compatible MixinRenderSectionManager
|
||||
|
@ -40,12 +40,12 @@ public abstract class MixinWorldRenderer {
|
|||
@Inject(method = "render", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiler/Profiler;swap(Ljava/lang/String;)V", args = "ldc=entities"))
|
||||
private void startRenderEntities(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) {
|
||||
MinecraftRenderPipelineProgress.INSTANCE.setRenderingEntities(true);
|
||||
HibiscusMod.bus().fire(new PreRenderEntitiesEvent(tickDelta));
|
||||
Hibiscus.bus().fire(new PreRenderEntitiesEvent(tickDelta));
|
||||
}
|
||||
|
||||
@Inject(method = "render", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiler/Profiler;swap(Ljava/lang/String;)V", args = "ldc=blockentities"))
|
||||
private void startRenderBlockEntities(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) {
|
||||
MinecraftRenderPipelineProgress.INSTANCE.setRenderingEntities(false);
|
||||
HibiscusMod.bus().fire(new PostRenderEntitiesEvent(tickDelta));
|
||||
Hibiscus.bus().fire(new PostRenderEntitiesEvent(tickDelta));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,22 +4,25 @@ import codes.som.hibiscus.api.event.EventBus
|
|||
import codes.som.hibiscus.api.event.EventPhase
|
||||
import codes.som.hibiscus.api.keybinds.KeybindRegistry
|
||||
import codes.som.hibiscus.commands.CommandRegistry
|
||||
import codes.som.hibiscus.data.DataManager
|
||||
import codes.som.hibiscus.events.KeyEvent
|
||||
import codes.som.hibiscus.features.FeaturesRegistry
|
||||
import codes.som.hibiscus.features.combat.Criticals
|
||||
import codes.som.hibiscus.features.exploits.AntiGhost
|
||||
import codes.som.hibiscus.features.player.NoFallDamage
|
||||
import codes.som.hibiscus.features.player.NoSprintingPacket
|
||||
import codes.som.hibiscus.gui.ImGuiScreen
|
||||
import codes.som.hibiscus.gui.screens.AccountManagerUIScreen
|
||||
import codes.som.hibiscus.gui.screens.InGameClientUIScreen
|
||||
import codes.som.hibiscus.util.command.ChatCommandListener
|
||||
import codes.som.hibiscus.util.input.KeybindDispatcher
|
||||
import codes.som.hibiscus.util.netmoving.NetworkMovingDispatcher
|
||||
import net.fabricmc.api.ModInitializer
|
||||
import net.minecraft.client.gui.screen.TitleScreen
|
||||
import org.lwjgl.glfw.GLFW
|
||||
import org.lwjgl.glfw.GLFW.*
|
||||
|
||||
@Suppress("UNUSED")
|
||||
object HibiscusMod : ModInitializer {
|
||||
object Hibiscus : ModInitializer {
|
||||
private const val MOD_ID = "hibiscus_client"
|
||||
|
||||
@JvmStatic
|
||||
|
@ -29,8 +32,11 @@ object HibiscusMod : ModInitializer {
|
|||
val features = FeaturesRegistry()
|
||||
val commands = CommandRegistry()
|
||||
val keybinds = KeybindRegistry()
|
||||
val data = DataManager()
|
||||
|
||||
override fun onInitialize() {
|
||||
data.runMigrations()
|
||||
|
||||
for (feature in features.getAllFeatures()) {
|
||||
commands.register(feature.createFeatureCommand())
|
||||
}
|
||||
|
@ -39,10 +45,10 @@ object HibiscusMod : ModInitializer {
|
|||
if (event.key != GLFW_KEY_RIGHT_SHIFT || event.action != GLFW.GLFW_PRESS)
|
||||
return@register
|
||||
|
||||
if (mc.currentScreen != null)
|
||||
return@register
|
||||
|
||||
mc.setScreen(ImGuiScreen)
|
||||
when (mc.currentScreen) {
|
||||
null -> mc.setScreen(InGameClientUIScreen)
|
||||
is TitleScreen -> mc.setScreen(AccountManagerUIScreen)
|
||||
}
|
||||
}
|
||||
|
||||
bus.register(NetworkMovingDispatcher(), EventPhase.AFTER)
|
||||
|
@ -50,12 +56,9 @@ object HibiscusMod : ModInitializer {
|
|||
bus.register(KeybindDispatcher())
|
||||
|
||||
defaultConfig()
|
||||
// TODO: Load files
|
||||
}
|
||||
|
||||
fun shutdown() {
|
||||
// TODO: Save files
|
||||
|
||||
for (system in sequenceOf(bus, features, commands, keybinds)) {
|
||||
system.reset()
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package codes.som.hibiscus.api.feature
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod
|
||||
import codes.som.hibiscus.Hibiscus
|
||||
import codes.som.hibiscus.api.command.Command
|
||||
import codes.som.hibiscus.api.event.*
|
||||
import codes.som.hibiscus.api.feature.values.ValueRegistry
|
||||
|
@ -23,9 +23,9 @@ abstract class Feature(val name: String, val category: FeatureCategory) {
|
|||
field = value
|
||||
if (value) {
|
||||
onEnable()
|
||||
listeners.forEach { HibiscusMod.bus.registerTyped(it) }
|
||||
listeners.forEach { Hibiscus.bus.registerTyped(it) }
|
||||
} else {
|
||||
listeners.forEach { HibiscusMod.bus.unregisterTyped(it) }
|
||||
listeners.forEach { Hibiscus.bus.unregisterTyped(it) }
|
||||
onDisable()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package codes.som.hibiscus.api.feature
|
||||
|
||||
import codes.som.hibiscus.HibiscusLog
|
||||
import codes.som.hibiscus.HibiscusMod
|
||||
import codes.som.hibiscus.Hibiscus
|
||||
import codes.som.hibiscus.api.command.Command
|
||||
import codes.som.hibiscus.api.command.CommandContext
|
||||
import java.util.*
|
||||
|
@ -11,7 +11,7 @@ class FeatureCommand(feature: Feature) : Command(feature.name.replace(" ", "").l
|
|||
branch {
|
||||
feature.enabled = !feature.enabled
|
||||
|
||||
if (HibiscusMod.commands.context == CommandContext.MANUAL) {
|
||||
if (Hibiscus.commands.context == CommandContext.MANUAL) {
|
||||
val state = if (feature.enabled) "enabled" else "disabled"
|
||||
HibiscusLog.info("${feature.name} is now $state.")
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package codes.som.hibiscus.commands
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod
|
||||
import codes.som.hibiscus.Hibiscus
|
||||
import codes.som.hibiscus.api.command.Command
|
||||
|
||||
class Reload : Command("reload") {
|
||||
init {
|
||||
branch {
|
||||
HibiscusMod.shutdown()
|
||||
HibiscusMod.onInitialize()
|
||||
Hibiscus.shutdown()
|
||||
Hibiscus.onInitialize()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package codes.som.hibiscus.data
|
||||
|
||||
import org.jetbrains.exposed.dao.IntEntity
|
||||
import org.jetbrains.exposed.dao.IntEntityClass
|
||||
import org.jetbrains.exposed.dao.id.EntityID
|
||||
import org.jetbrains.exposed.dao.id.IntIdTable
|
||||
|
||||
object MinecraftAccounts : IntIdTable("mc_accounts") {
|
||||
val name = varchar("name", 64)
|
||||
val lastKnownDisplayName = varchar("last_display_name", 32).nullable()
|
||||
val loginData = text("login_data", eagerLoading = true)
|
||||
}
|
||||
|
||||
class MinecraftAccount(id: EntityID<Int>) : IntEntity(id) {
|
||||
companion object : IntEntityClass<MinecraftAccount>(MinecraftAccounts)
|
||||
|
||||
var name by MinecraftAccounts.name
|
||||
var lastKnownDisplayName by MinecraftAccounts.lastKnownDisplayName
|
||||
var loginData by MinecraftAccounts.loginData
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package codes.som.hibiscus.data
|
||||
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
import java.sql.Connection
|
||||
import java.sql.SQLException
|
||||
|
||||
class DataManager {
|
||||
private val db: Database = Database.connect("jdbc:sqlite:${getDatabaseLocation()}").also {
|
||||
TransactionManager.manager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE
|
||||
}
|
||||
|
||||
fun runMigrations() {
|
||||
val latestId = try {
|
||||
txn {
|
||||
HibiscusDataMigrations.selectAll().orderBy(
|
||||
HibiscusDataMigrations.id,
|
||||
SortOrder.DESC
|
||||
).limit(1).lastOrNull()?.get(HibiscusDataMigrations.id)?.value
|
||||
}
|
||||
} catch (e: SQLException) {
|
||||
null
|
||||
} ?: -1
|
||||
|
||||
txn {
|
||||
for ((idx, migration) in HIBISCUS_MIGRATIONS().withIndex()) {
|
||||
if (idx <= latestId)
|
||||
continue
|
||||
migration(this)
|
||||
HibiscusDataMigrations.insert { it[id] = idx }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getDatabaseLocation(): String {
|
||||
val osName = System.getProperty("os.name")
|
||||
|
||||
val databasePath = when {
|
||||
osName.contains("Windows") -> {
|
||||
Paths.get(System.getenv("APPDATA"), "hibiscus-client", "hibiscus-client.db")
|
||||
}
|
||||
else -> {
|
||||
Paths.get(System.getProperty("user.home"), ".config", "hibiscus-client", "hibiscus-client.db")
|
||||
}
|
||||
}
|
||||
|
||||
Files.createDirectories(databasePath.parent)
|
||||
return databasePath.toString()
|
||||
}
|
||||
|
||||
fun <T> txn(stmnt: Transaction.() -> T) = transaction(db, stmnt)
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package codes.som.hibiscus.data
|
||||
|
||||
import org.jetbrains.exposed.dao.id.IntIdTable
|
||||
import org.jetbrains.exposed.sql.SchemaUtils
|
||||
import org.jetbrains.exposed.sql.Transaction
|
||||
|
||||
object HibiscusDataMigrations : IntIdTable("_hibiscus_migrations")
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun HIBISCUS_MIGRATIONS(): Sequence<Transaction.() -> Unit> = sequenceOf(
|
||||
{ SchemaUtils.create(HibiscusDataMigrations) },
|
||||
{ SchemaUtils.create(MinecraftAccounts) }
|
||||
)
|
|
@ -15,7 +15,8 @@ import codes.som.hibiscus.features.visual.Fullbright
|
|||
import codes.som.hibiscus.features.visual.Xray
|
||||
import codes.som.hibiscus.util.Resettable
|
||||
|
||||
fun allFeatureClasses(): Array<() -> Feature> = arrayOf(
|
||||
@Suppress("FunctionName")
|
||||
fun FEATURE_CONSTRUCTORS(): Array<() -> Feature> = arrayOf(
|
||||
::NoFallDamage,
|
||||
::Flight,
|
||||
::Overlay,
|
||||
|
@ -46,7 +47,7 @@ class FeaturesRegistry : Resettable {
|
|||
getAllFeatures().first { it.javaClass == type } as T
|
||||
|
||||
private fun registerFeatures() {
|
||||
features.addAll(allFeatureClasses().map { it() })
|
||||
features.addAll(FEATURE_CONSTRUCTORS().map { it() })
|
||||
}
|
||||
|
||||
override fun reset() {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package codes.som.hibiscus.features.overlay
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod
|
||||
import codes.som.hibiscus.Hibiscus
|
||||
import codes.som.hibiscus.api.feature.Feature
|
||||
import codes.som.hibiscus.api.feature.FeatureCategory
|
||||
import codes.som.hibiscus.events.PostRenderAllEvent
|
||||
|
@ -40,7 +40,7 @@ class Overlay : Feature("Overlay", FeatureCategory.OVERLAY) {
|
|||
|
||||
private fun drawEnabledFeatures() {
|
||||
val displayedFeatures =
|
||||
HibiscusMod.features.getAllFeatures()
|
||||
Hibiscus.features.getAllFeatures()
|
||||
.filter { !it.hiddenInOverlay }
|
||||
.filter { it.enabled }.toList()
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package codes.som.hibiscus.features.visual
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod
|
||||
import codes.som.hibiscus.Hibiscus
|
||||
import codes.som.hibiscus.api.feature.Feature
|
||||
import codes.som.hibiscus.api.feature.FeatureCategory
|
||||
import codes.som.hibiscus.events.*
|
||||
|
@ -131,7 +131,7 @@ class Freecam : Feature("Freecam", FeatureCategory.VISUAL) {
|
|||
var lastMouseY = 0.0
|
||||
var mouseDeltaX = 0.0
|
||||
var mouseDeltaY = 0.0
|
||||
HibiscusMod.bus.register { _: PostRenderWorldEvent ->
|
||||
Hibiscus.bus.register { _: PostRenderWorldEvent ->
|
||||
mouseDeltaX = mc.mouse.x - lastMouseX
|
||||
mouseDeltaY = mc.mouse.y - lastMouseY
|
||||
lastMouseX = mc.mouse.x
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package codes.som.hibiscus.gui
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod
|
||||
import codes.som.hibiscus.Hibiscus
|
||||
import codes.som.hibiscus.api.feature.Feature
|
||||
import codes.som.hibiscus.api.feature.FeatureCategory
|
||||
import codes.som.hibiscus.features.overlay.Overlay
|
||||
|
@ -11,13 +11,13 @@ import imgui.flag.ImGuiWindowFlags
|
|||
import imgui.flag.ImGuiWindowFlags.AlwaysVerticalScrollbar
|
||||
import imgui.type.ImBoolean
|
||||
|
||||
object ModuleControlsUI {
|
||||
object FeatureControlsUI {
|
||||
private val moduleValueWindows = mutableMapOf<Feature, ImBoolean>()
|
||||
|
||||
private fun drawCategoryPanel(category: FeatureCategory, ) {
|
||||
|
||||
private fun drawCategoryPanel(category: FeatureCategory) {
|
||||
ImGui.begin(category.humanName, AlwaysVerticalScrollbar)
|
||||
|
||||
for (feature in HibiscusMod.features.getAllFeatures().filter { it.category == category }) {
|
||||
for (feature in Hibiscus.features.getAllFeatures().filter { it.category == category }) {
|
||||
drawFeatureControls(feature)
|
||||
}
|
||||
|
||||
|
@ -63,34 +63,34 @@ object ModuleControlsUI {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun drawOverlaySettings() {
|
||||
val overlayFeature = HibiscusMod.features.getFeature<Overlay>()
|
||||
val overlayFeature = Hibiscus.features.getFeature<Overlay>()
|
||||
if (ImGui.begin("${overlayFeature.name}##Feature Controls"))
|
||||
for (value in overlayFeature.values)
|
||||
value.drawUIControl()
|
||||
ImGui.end()
|
||||
}
|
||||
|
||||
|
||||
fun render(delta: Float) {
|
||||
var yOffset = 0f
|
||||
|
||||
|
||||
fun pushInitialPanelConfig() {
|
||||
val initialX = ImGui.getMainViewport().posX + 10f
|
||||
val initialY = ImGui.getMainViewport().posY + 10f + yOffset
|
||||
|
||||
|
||||
ImGui.setNextWindowPos(initialX, initialY, Once)
|
||||
ImGui.setNextWindowCollapsed(true, Once)
|
||||
ImGui.setNextWindowSize(300f, 0f, Once)
|
||||
}
|
||||
|
||||
|
||||
for (category in FeatureCategory.values()) {
|
||||
if (category == FeatureCategory.OVERLAY)
|
||||
continue
|
||||
|
||||
|
||||
pushInitialPanelConfig()
|
||||
drawCategoryPanel(category)
|
||||
|
||||
|
||||
yOffset += 30f
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package codes.som.hibiscus.gui
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod
|
||||
import codes.som.hibiscus.Hibiscus
|
||||
import imgui.ImFontConfig
|
||||
import imgui.ImGui
|
||||
import imgui.ImGuiStyle
|
||||
|
@ -83,7 +83,7 @@ fun applyHibiscusImGuiTheme() {
|
|||
style.setColor(ImGuiCol.TabUnfocusedActive, colMed(1.0f))
|
||||
|
||||
with(ImGui.getIO().fonts) {
|
||||
val interTTF = HibiscusMod.javaClass.getResourceAsStream("/assets/inter/Inter-V.ttf")
|
||||
val interTTF = Hibiscus.javaClass.getResourceAsStream("/assets/inter/Inter-V.ttf")
|
||||
?: error("Couldn't find Inter TTF in assets!")
|
||||
addFontFromMemoryTTF(interTTF.readAllBytes(), 20f, ImFontConfig().apply {
|
||||
setName("Inter")
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
package codes.som.hibiscus.gui.screens
|
||||
|
||||
import codes.som.hibiscus.Hibiscus
|
||||
import codes.som.hibiscus.data.MinecraftAccount
|
||||
import codes.som.hibiscus.mixins.MixinExtMinecraftClient
|
||||
import imgui.ImGui
|
||||
import imgui.flag.ImGuiInputTextFlags
|
||||
import imgui.type.ImBoolean
|
||||
import imgui.type.ImInt
|
||||
import imgui.type.ImString
|
||||
import net.hycrafthd.minecraft_authenticator.login.Authenticator
|
||||
import net.hycrafthd.minecraft_authenticator.login.User
|
||||
import net.hycrafthd.minecraft_authenticator.login.file.AuthenticationFile
|
||||
import net.minecraft.client.gui.screen.Screen
|
||||
import net.minecraft.client.util.Session
|
||||
import net.minecraft.client.util.math.MatrixStack
|
||||
import net.minecraft.text.Text
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.util.*
|
||||
|
||||
object AccountManagerUIScreen : Screen(Text.of("account management hacker menu")) {
|
||||
private var accounts = emptyList<MinecraftAccount>()
|
||||
private val createAccountPanelOpen = ImBoolean(false)
|
||||
private var selectedAccountId = -1
|
||||
|
||||
init {
|
||||
refreshAccounts()
|
||||
}
|
||||
|
||||
private fun refreshAccounts() {
|
||||
this.accounts = Hibiscus.data.txn {
|
||||
MinecraftAccount.all().toList()
|
||||
}
|
||||
}
|
||||
|
||||
override fun render(matrices: MatrixStack?, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
renderBackground(matrices)
|
||||
|
||||
if (ImGui.begin("Accounts")) {
|
||||
ImGui.text("Available accounts: ${accounts.size}")
|
||||
ImGui.text("Logged in as: ${client!!.session.username}")
|
||||
|
||||
if (ImGui.button("Add Account")) {
|
||||
createAccountPanelOpen.set(true)
|
||||
}
|
||||
|
||||
val calculatedHeight = (accounts.size.coerceIn(4, 20) * 28f)
|
||||
if (ImGui.beginListBox("Accounts", 0f, calculatedHeight)) {
|
||||
for (account in accounts) {
|
||||
if (ImGui.selectable(account.name, account.id.value == selectedAccountId)) {
|
||||
selectedAccountId = account.id.value
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.endListBox()
|
||||
}
|
||||
|
||||
accounts.firstOrNull { it.id.value == selectedAccountId }?.let { account ->
|
||||
ImGui.text("Selected account: ${account.name}")
|
||||
ImGui.text("Last known username: ${account.lastKnownDisplayName}")
|
||||
|
||||
if (ImGui.button("Log In")) {
|
||||
try {
|
||||
val loginFile = AuthenticationFile.read(account.loginData.byteInputStream(Charsets.UTF_8))
|
||||
val loginResult = Authenticator.of(loginFile).shouldAuthenticate().run()
|
||||
if (loginResult.user.isPresent) {
|
||||
val user = loginResult.user.get()
|
||||
(client!! as MixinExtMinecraftClient).setSession(user.createSession())
|
||||
|
||||
val loginData = ByteArrayOutputStream()
|
||||
.apply { loginResult.resultFile.write(this) }
|
||||
.toString(Charsets.UTF_8)
|
||||
|
||||
Hibiscus.data.txn {
|
||||
account.lastKnownDisplayName = user.name
|
||||
account.loginData = loginData
|
||||
refreshAccounts()
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
ImGui.sameLine()
|
||||
if (ImGui.button("Remove")) {
|
||||
// TODO: Some confirmation modal
|
||||
Hibiscus.data.txn {
|
||||
account.delete()
|
||||
refreshAccounts()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui.end()
|
||||
|
||||
drawCreateAccountPanel()
|
||||
}
|
||||
|
||||
private val loginType = ImInt(1)
|
||||
private val yggdrasilUsername = ImString(320)
|
||||
private val yggdrasilPassword = ImString(256)
|
||||
private val microsoftToken = ImString(256)
|
||||
|
||||
private fun drawCreateAccountPanel() {
|
||||
if (createAccountPanelOpen.get()) {
|
||||
if (ImGui.begin("Add Account", createAccountPanelOpen)) {
|
||||
ImGui.pushItemWidth(ImGui.getContentRegionMaxX() - ImGui.getWindowContentRegionMinX())
|
||||
|
||||
ImGui.text("Login Type:")
|
||||
ImGui.combo(
|
||||
"Login Type",
|
||||
loginType,
|
||||
arrayOf("Yggdrasil", "Microsoft")
|
||||
)
|
||||
|
||||
ImGui.separator()
|
||||
|
||||
when (loginType.get()) {
|
||||
0 -> {
|
||||
ImGui.text("Login Name (Username or Email):")
|
||||
ImGui.inputText("##new-account-login-name", yggdrasilUsername)
|
||||
ImGui.text("Password:")
|
||||
ImGui.inputText("##new-account-login-password", yggdrasilPassword, ImGuiInputTextFlags.Password)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
ImGui.text("You may want to visit the Microsoft login site.")
|
||||
if (ImGui.button("Copy URL")) {
|
||||
ImGui.setClipboardText(Authenticator.microsoftLogin().toString())
|
||||
}
|
||||
|
||||
ImGui.text("Login Token:")
|
||||
ImGui.inputText("##new-account-login-token", microsoftToken)
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.popItemWidth()
|
||||
|
||||
ImGui.separator()
|
||||
if (ImGui.button("Log In")) {
|
||||
val authenticator = when (loginType.get()) {
|
||||
0 -> Authenticator.ofYggdrasil("-", yggdrasilUsername.get(), yggdrasilPassword.get())
|
||||
1 -> Authenticator.ofMicrosoft(microsoftToken.get())
|
||||
else -> throw IllegalStateException()
|
||||
}.shouldAuthenticate()
|
||||
|
||||
try {
|
||||
val loginResult = authenticator.run()
|
||||
if (loginResult.user.isPresent) {
|
||||
val user = loginResult.user.get()
|
||||
|
||||
val loginData = ByteArrayOutputStream()
|
||||
.apply { loginResult.resultFile.write(this) }
|
||||
.toString(Charsets.UTF_8)
|
||||
|
||||
yggdrasilUsername.set("")
|
||||
yggdrasilPassword.set("")
|
||||
microsoftToken.set("")
|
||||
|
||||
Hibiscus.data.txn {
|
||||
MinecraftAccount.new {
|
||||
this.name = user.name
|
||||
this.lastKnownDisplayName = user.name
|
||||
this.loginData = loginData
|
||||
}
|
||||
|
||||
refreshAccounts()
|
||||
|
||||
(client!! as MixinExtMinecraftClient).setSession(user.createSession())
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
// TODO: Display some error
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui.end()
|
||||
}
|
||||
}
|
||||
|
||||
private fun User.createSession() = Session(
|
||||
name,
|
||||
uuid,
|
||||
accessToken,
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Session.AccountType.byName(type)
|
||||
)
|
||||
}
|
|
@ -1,14 +1,15 @@
|
|||
package codes.som.hibiscus.gui
|
||||
package codes.som.hibiscus.gui.screens
|
||||
|
||||
import codes.som.hibiscus.gui.FeatureControlsUI
|
||||
import net.minecraft.client.gui.screen.Screen
|
||||
import net.minecraft.client.util.math.MatrixStack
|
||||
import net.minecraft.text.Text
|
||||
|
||||
object ImGuiScreen : Screen(Text.of("hacker menu")) {
|
||||
object InGameClientUIScreen : Screen(Text.of("in game hacker menu")) {
|
||||
override fun render(matrices: MatrixStack?, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
super.render(matrices, mouseX, mouseY, delta)
|
||||
|
||||
ModuleControlsUI.render(delta)
|
||||
FeatureControlsUI.render(delta)
|
||||
}
|
||||
|
||||
override fun isPauseScreen() = false
|
|
@ -1,13 +1,13 @@
|
|||
package codes.som.hibiscus.subsystems.fullbright
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod
|
||||
import codes.som.hibiscus.Hibiscus
|
||||
import codes.som.hibiscus.features.visual.Fullbright
|
||||
|
||||
object FullbrightSystem {
|
||||
@JvmStatic
|
||||
fun shouldRenderFullbright(): Boolean {
|
||||
try {
|
||||
return HibiscusMod.features.getFeature<Fullbright>().enabled
|
||||
return Hibiscus.features.getFeature<Fullbright>().enabled
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package codes.som.hibiscus.subsystems.xray
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod
|
||||
import codes.som.hibiscus.Hibiscus
|
||||
import codes.som.hibiscus.features.visual.Xray
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.FluidBlock
|
||||
|
@ -11,7 +11,7 @@ object XraySystem {
|
|||
@JvmStatic
|
||||
fun shouldRenderXray(): Boolean {
|
||||
try {
|
||||
return HibiscusMod.features.getFeature<Xray>().enabled
|
||||
return Hibiscus.features.getFeature<Xray>().enabled
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package codes.som.hibiscus.util.command
|
||||
|
||||
import codes.som.hibiscus.HibiscusLog
|
||||
import codes.som.hibiscus.HibiscusMod
|
||||
import codes.som.hibiscus.Hibiscus
|
||||
import codes.som.hibiscus.api.command.CommandContext
|
||||
import codes.som.hibiscus.api.command.exceptions.CommandExecutionException
|
||||
import codes.som.hibiscus.api.event.TypedListener
|
||||
|
@ -11,8 +11,8 @@ class ChatCommandListener : TypedListener<SendChatEvent>(SendChatEvent::class.ja
|
|||
override fun on(event: SendChatEvent) {
|
||||
if (event.message.startsWith(".")) {
|
||||
try {
|
||||
HibiscusMod.commands.context = CommandContext.MANUAL
|
||||
HibiscusMod.commands.executeCommand(event.message.substring(1))
|
||||
Hibiscus.commands.context = CommandContext.MANUAL
|
||||
Hibiscus.commands.executeCommand(event.message.substring(1))
|
||||
} catch (e: CommandExecutionException) {
|
||||
// e.printStackTrace()
|
||||
e.cause?.message?.let { HibiscusLog.error(it) }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package codes.som.hibiscus.util.input
|
||||
|
||||
import codes.som.hibiscus.HibiscusLog
|
||||
import codes.som.hibiscus.HibiscusMod
|
||||
import codes.som.hibiscus.Hibiscus
|
||||
import codes.som.hibiscus.api.command.CommandContext
|
||||
import codes.som.hibiscus.api.command.exceptions.CommandExecutionException
|
||||
import codes.som.hibiscus.api.event.TypedListener
|
||||
|
@ -12,10 +12,10 @@ import org.lwjgl.glfw.GLFW
|
|||
class KeybindDispatcher : TypedListener<KeyEvent>(KeyEvent::class.java) {
|
||||
override fun on(event: KeyEvent) {
|
||||
if (mc.isWindowFocused && mc.currentScreen == null && event.action == GLFW.GLFW_PRESS) {
|
||||
HibiscusMod.keybinds.getBinds(event.key).forEach { bind ->
|
||||
Hibiscus.keybinds.getBinds(event.key).forEach { bind ->
|
||||
try {
|
||||
HibiscusMod.commands.context = CommandContext.KEYBIND
|
||||
HibiscusMod.commands.executeCommand(bind)
|
||||
Hibiscus.commands.context = CommandContext.KEYBIND
|
||||
Hibiscus.commands.executeCommand(bind)
|
||||
} catch (e: CommandExecutionException) {
|
||||
e.cause?.message?.let { HibiscusLog.error(it) }
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package codes.som.hibiscus.util.netmoving
|
||||
|
||||
import codes.som.hibiscus.HibiscusMod
|
||||
import codes.som.hibiscus.Hibiscus
|
||||
import codes.som.hibiscus.api.event.TypedListener
|
||||
import codes.som.hibiscus.events.NetworkMovingEvent
|
||||
import codes.som.hibiscus.events.SendPacketEvent
|
||||
|
@ -21,7 +21,7 @@ class NetworkMovingDispatcher : TypedListener<SendPacketEvent>(SendPacketEvent::
|
|||
packet.getYaw(player.yaw), packet.getPitch(player.pitch), packet.isOnGround
|
||||
)
|
||||
|
||||
HibiscusMod.bus.fire(movingEvent)
|
||||
Hibiscus.bus.fire(movingEvent)
|
||||
|
||||
if (movingEvent.cancelled)
|
||||
event.cancel()
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
"main": [
|
||||
{
|
||||
"adapter": "kotlin",
|
||||
"value": "codes.som.hibiscus.HibiscusMod"
|
||||
"value": "codes.som.hibiscus.Hibiscus"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
"MixinClientPlayNetworkHandler",
|
||||
"MixinExtClientPlayerEntity",
|
||||
"MixinExtEntity",
|
||||
"MixinExtMinecraftClient",
|
||||
"MixinExtPlayerInteractEntityC2SPacket",
|
||||
"MixinExtPlayerMoveC2SPacket",
|
||||
"MixinExtUpdatePlayerAbilitiesC2SPacket",
|
||||
|
|
Loading…
Reference in New Issue