feat: added "basic" functionality

This commit is contained in:
moonleay 2023-08-06 21:49:31 +02:00
parent 09cdba403a
commit 7664589f56
36 changed files with 1391 additions and 0 deletions

View file

@ -0,0 +1,55 @@
package net.moonleay.etaorion.client
import net.fabricmc.api.ClientModInitializer
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents
import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl
import net.minecraft.client.MinecraftClient
import net.minecraft.client.option.KeyBinding
import net.minecraft.client.util.InputUtil
import net.moonleay.etaorion.build.BuildConstants
import net.moonleay.etaorion.client.autotext.AutoTextManager
import net.moonleay.etaorion.client.autotext.EOKeyBinding
import net.moonleay.etaorion.client.autotext.KeyBindingManager
import net.moonleay.etaorion.client.modules.component.ModuleManager
import net.moonleay.etaorion.client.modules.component.listener.EndTickListener
import net.moonleay.etaorion.config.AutoTextConfig
import org.apache.logging.log4j.LogManager
import org.lwjgl.glfw.GLFW
internal object ClientMain : ClientModInitializer {
private val lgr = LogManager.getLogger(BuildConstants.modName)
override fun onInitializeClient() {
lgr.info("Starting Eta Orion")
lgr.info("Registering Modules")
ModuleManager.registerModules()
ClientTickEvents.END_CLIENT_TICK.register(EndTickListener())
lgr.info("Registered EndTickListener #1/2")
ClientTickEvents.END_CLIENT_TICK.register(ClientTickEvents.EndTick { client: MinecraftClient? ->
AutoTextManager.onClientTick(client!!)
})
lgr.info("Registered EndTickListener #2/2")
for(i in 0 .. 9){
val keyBinding: KeyBinding = KeyBinding(
"etaorion.key_binding_$i",
InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_UNKNOWN,
"category.etaorion.autotext"
)
KeyBindingManager.add(EOKeyBinding(keyBinding, i, false))
KeyBindingRegistryImpl.registerKeyBinding(keyBinding)
val autoText = AutoTextConfig.load(i)
if(autoText == null){
lgr.info("AutoText with index $i is null.")
continue
}
AutoTextManager.registerNewAutoTxtObject(autoText)
}
lgr.info("Registerd all keys")
lgr.info("EtaOrionFabric has been initialized")
lgr.info("Eta Orion Ver.${BuildConstants.modVersion}.")
}
}

View file

@ -0,0 +1,26 @@
package net.moonleay.etaorion.client.autotext
import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl
import net.minecraft.client.MinecraftClient
import net.minecraft.client.option.KeyBinding
import net.minecraft.client.util.InputUtil
import net.minecraft.text.Text
import net.moonleay.etaorion.mixin.KeyBindingRegistryImplAccessor
import net.moonleay.etaorion.util.KeyBindingManagement
import org.lwjgl.glfw.GLFW
class AutoText(val textToSend: String, val eoKeyBinding: EOKeyBinding) {
//Text.translatable("etaorion.key_binding_1", textToSend)
fun sendMessage(client: MinecraftClient, addToHistory: Boolean){
if (addToHistory) {
client.inGameHud.chatHud.addToMessageHistory(textToSend)
}
if (textToSend.startsWith("/")) {
client.player?.networkHandler?.sendChatCommand(textToSend.substring(1))
} else {
client.player?.networkHandler?.sendChatMessage(textToSend)
}
}
}

View file

@ -0,0 +1,35 @@
package net.moonleay.etaorion.client.autotext
import net.minecraft.client.MinecraftClient
import net.moonleay.etaorion.config.AutoTextConfig
object AutoTextManager {
val autoTextObjects: MutableList<AutoText> = mutableListOf()
fun registerNewAutoTxtObject(autoText: AutoText): Boolean {
if(autoTextObjects.size >= 10){
return false
}
autoTextObjects.add(autoText)
return true
}
fun unregisterAutoTextObject(index: Int){
AutoTextConfig.delete(index)
KeyBindingManager.cancelKeyBinding(autoTextObjects[index].eoKeyBinding)
autoTextObjects.removeAt(index)
}
fun unregisterAutoTextObject(autoText: AutoText){
KeyBindingManager.cancelKeyBinding(autoText.eoKeyBinding)
autoTextObjects.remove(autoText)
}
fun onClientTick(client: MinecraftClient){
for(o in autoTextObjects){
while(o.eoKeyBinding.keyBinding.wasPressed()){
o.sendMessage(client, true)
}
}
}
}

View file

@ -0,0 +1,8 @@
package net.moonleay.etaorion.client.autotext
import net.minecraft.client.option.KeyBinding
data class EOKeyBinding (var keyBinding: KeyBinding,
var index: Int,
var isInUse: Boolean = false,
)

View file

@ -0,0 +1,53 @@
package net.moonleay.etaorion.client.autotext
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
object KeyBindingManager {
private val lgr: Logger = LogManager.getLogger(KeyBindingManager::class.java)
private var keyBindings: MutableList<EOKeyBinding> = mutableListOf()
fun add(keyBinding: EOKeyBinding) {
if(keyBindings.size >= 10){
lgr.info("Too many key bindings!")
return
}
keyBindings += keyBinding
}
fun bookWithIndex(index: Int): EOKeyBinding?{
for(keyBinding in keyBindings){
if(keyBinding.index == index){
if(keyBinding.isInUse)
return null
keyBinding.isInUse = true
return keyBinding
}
}
return null
}
private fun getFree(): EOKeyBinding? {
for(keyBinding in keyBindings){
if(!keyBinding.isInUse){
lgr.info("Found free keybinding with index ${keyBinding.index}")
return keyBinding
}
}
return null
}
fun bookKeyBinding(): EOKeyBinding?{
val eoKeyBinding = getFree()?: return null
eoKeyBinding.isInUse = true
lgr.info("Booked KeyBinding with index ${eoKeyBinding.index}")
return eoKeyBinding
}
fun cancelKeyBinding(binding: EOKeyBinding){
lgr.info("Cancelled KeyBinding with index ${binding.index}")
binding.isInUse = false
binding.keyBinding.setBoundKey(binding.keyBinding.defaultKey)
}
}

View file

@ -0,0 +1,8 @@
package net.moonleay.etaorion.client.modules.component
enum class Category(val Name: String) {
MOVEMENT("Movement"),
HUD("HUD"),
FEEL("Feel"),
SYSTEM("System");
}

View file

@ -0,0 +1,29 @@
package net.moonleay.etaorion.client.modules.component
import net.minecraft.client.MinecraftClient
open class Module(val name: String, val category: Category) {
protected val mc = MinecraftClient.getInstance()
open var enabled = false
open var listIndex = 0
open fun onTick() {}
open fun onClientShutdown() {}
open fun onLoad(enabled: Boolean) {
this.enabled = enabled
ModuleManager.toggleModule(this, enabled)
onToggleEnabled(enabled)
}
open fun updateEnabled(enabled: Boolean) {
this.enabled = enabled
onToggleEnabled(enabled)
}
open fun onToggleEnabled(enabled: Boolean) {}
open fun onEventPre() {}
}

View file

@ -0,0 +1,85 @@
package net.moonleay.etaorion.client.modules.component
import net.moonleay.etaorion.client.modules.component.system.AntiFatFinger
import net.moonleay.etaorion.client.modules.feel.NoBob
import net.moonleay.etaorion.client.modules.hud.*
import net.moonleay.etaorion.config.ModuleConfig
import org.apache.logging.log4j.LogManager
object ModuleManager {
val lgr = LogManager.getLogger(ModuleManager::class.java)
lateinit var modules: ArrayList<Module>
var enabledModules = arrayListOf<Module>()
var enabledGfxModules = mutableMapOf<Position, ArrayList<MovableModule>>()
fun registerModules() {
modules = arrayListOf<Module>(
NoBob(),
FPS(),
XYZ(),
Direction(),
AntiFatFinger(),
DurabilityMainHand(),
DurabilityOffHand(),
)
lgr.info("Registered ${modules.size} Modules!")
for (p in Position.values())
enabledGfxModules[p] = arrayListOf()
ModuleConfig.load(modules)
lgr.info("Loaded config files")
}
fun toggleModule(module: Module, enabled: Boolean) {
if (module is MovableModule) {
if (enabled) {
val mapOfPosition = enabledGfxModules[module.position] ?: arrayListOf()
mapOfPosition.add(module)
enabledGfxModules[module.position] = mapOfPosition
} else {
val mapOfPosition = enabledGfxModules[module.position] ?: return
mapOfPosition.remove(module)
enabledGfxModules[module.position] = mapOfPosition
}
} else {
if (enabled) {
enabledModules.add(module)
} else {
enabledModules.remove(module)
}
}
}
fun updatePositionOfModule(module: MovableModule, oldPosition: Position, targetPosition: Position) {
var mapOfPosition = enabledGfxModules[oldPosition] ?: return
mapOfPosition.remove(module)
enabledGfxModules[oldPosition] = mapOfPosition
mapOfPosition = enabledGfxModules[targetPosition] ?: arrayListOf()
mapOfPosition.add(module)
enabledGfxModules[targetPosition] = mapOfPosition
}
fun saveAllModules() {
ModuleConfig.save(modules)
}
fun getPositionFromname(name: String): Position {
for (p in Position.values()) {
if (p.Name == name)
return p
}
return Position.OFF
}
fun getPositionNumberInt(position: Position): Int {
var i = 0
for (p in Position.values()) {
if (p == position)
return i
++i
}
return -1
}
}

View file

@ -0,0 +1,6 @@
package net.moonleay.etaorion.client.modules.component
object ModuleStorage {
var noBobEnabled = false
var antiFatFingerEnabled = false
}

View file

@ -0,0 +1,36 @@
package net.moonleay.etaorion.client.modules.component
import net.minecraft.client.font.TextRenderer
import net.minecraft.client.util.math.MatrixStack
open class MovableModule(
name: String,
category: Category
) : Module(
name,
category
) {
var position = Position.OFF
open fun onRender(matrices: MatrixStack, tr: TextRenderer) {
}
open fun onLoadGfx(enabled: Boolean, position: Position) {
this.position = position
super.onLoad(enabled)
}
open fun updatePosition(newPosition: Position) {
if (this.position == Position.OFF && newPosition != Position.OFF)
super.updateEnabled(true)
this.position = newPosition
if (newPosition == Position.OFF)
super.updateEnabled(false)
}
open fun getText4Render(): String {
return "Not set"
}
}

View file

@ -0,0 +1,14 @@
package net.moonleay.etaorion.client.modules.component
enum class Position(val Name: String) {
OFF("off"),
TOPLEFT("top left"),
TOPCENTER("top centered"),
TOPRIGHT("top right"),
RIGHTCENTER("right centered"),
BOTTOMRIGHT("bottom right"),
BOTTOMCENTER("bottom center"),
BOTTOMLEFT("bottom left"),
LEFTCENTER("left centered");
}

View file

@ -0,0 +1,14 @@
package net.moonleay.etaorion.client.modules.component.listener
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents
import net.minecraft.client.MinecraftClient
import net.moonleay.etaorion.client.modules.component.ModuleStorage
import java.util.*
class EndTickListener : ClientTickEvents.EndTick {
override fun onEndTick(client: MinecraftClient?) {
if (Objects.nonNull(MinecraftClient.getInstance().player) && ModuleStorage.noBobEnabled) {
MinecraftClient.getInstance().player!!.horizontalSpeed = 0.0F
}
}
}

View file

@ -0,0 +1,16 @@
package net.moonleay.etaorion.client.modules.component.system
import net.moonleay.etaorion.client.modules.component.Category
import net.moonleay.etaorion.client.modules.component.Module
import net.moonleay.etaorion.client.modules.component.ModuleStorage
class AntiFatFinger : Module("Anti-Fat-Finger", Category.SYSTEM) {
override fun onLoad(enabled: Boolean) {
super.onLoad(enabled)
ModuleStorage.antiFatFingerEnabled = enabled
}
override fun onToggleEnabled(enabled: Boolean) {
ModuleStorage.antiFatFingerEnabled = enabled
}
}

View file

@ -0,0 +1,17 @@
package net.moonleay.etaorion.client.modules.feel
import net.moonleay.etaorion.client.modules.component.Category
import net.moonleay.etaorion.client.modules.component.Module
import net.moonleay.etaorion.client.modules.component.ModuleStorage
class NoBob : Module("No Bob", Category.FEEL) {
override fun onLoad(enabled: Boolean) {
super.onLoad(enabled)
ModuleStorage.noBobEnabled = enabled
}
override fun onToggleEnabled(enabled: Boolean) {
ModuleStorage.noBobEnabled = enabled
}
}

View file

@ -0,0 +1,25 @@
package net.moonleay.etaorion.client.modules.hud
import net.minecraft.client.MinecraftClient
import net.minecraft.entity.Entity
import net.minecraft.util.math.Direction
import net.moonleay.etaorion.client.modules.component.Category
import net.moonleay.etaorion.client.modules.component.MovableModule
class Direction: MovableModule("Direction", Category.HUD){
override fun getText4Render(): String {
val entity: Entity = MinecraftClient.getInstance().getCameraEntity()!!
val direction = entity.horizontalFacing
val string2 = when (direction) {
Direction.NORTH -> "north (-z)"
Direction.SOUTH -> "south (+z)"
Direction.WEST -> "west (-x)"
Direction.EAST -> "east (+x)"
else -> "Invalid"
}
return string2
}
private fun Float.format(digits: Int) = "%.${digits}f".format(this)
}

View file

@ -0,0 +1,17 @@
package net.moonleay.etaorion.client.modules.hud
import net.minecraft.client.MinecraftClient
import net.minecraft.text.Text
import net.minecraft.util.Hand
import net.moonleay.etaorion.client.modules.component.Category
import net.moonleay.etaorion.client.modules.component.MovableModule
class DurabilityMainHand: MovableModule("Durability (Main Hand)", Category.HUD) {
override fun getText4Render(): String {
val playerEntity = MinecraftClient.getInstance().player!!
val stack = playerEntity.getStackInHand(Hand.MAIN_HAND)
val itemName = if (stack.item.name.string == "Air") "Empty" else stack.item.name.string
if(stack.maxDamage == 0) return itemName
return "${itemName} ${stack.maxDamage - stack.damage}/${stack.maxDamage}"
}
}

View file

@ -0,0 +1,16 @@
package net.moonleay.etaorion.client.modules.hud
import net.minecraft.client.MinecraftClient
import net.minecraft.util.Hand
import net.moonleay.etaorion.client.modules.component.Category
import net.moonleay.etaorion.client.modules.component.MovableModule
class DurabilityOffHand: MovableModule("Durability (Off Hand)", Category.HUD) {
override fun getText4Render(): String {
val playerEntity = MinecraftClient.getInstance().player!!
val stack = playerEntity.getStackInHand(Hand.OFF_HAND)
val itemName = if (stack.item.name.string == "Air") "Empty" else stack.item.name.string
if(stack.maxDamage == 0) return itemName
return "${itemName} ${stack.maxDamage - stack.damage}/${stack.maxDamage}"
}
}

View file

@ -0,0 +1,19 @@
package net.moonleay.etaorion.client.modules.hud
import net.moonleay.etaorion.client.modules.component.Category
import net.moonleay.etaorion.client.modules.component.MovableModule
class FPS : MovableModule("FPS Display", Category.HUD) {
val fps = mutableListOf<Long>()
fun getFPS(): Int {
val time = System.currentTimeMillis()
fps.removeIf { aLong -> aLong + 1000L < time }
return fps.size
}
override fun getText4Render(): String {
fps.add(System.currentTimeMillis())
return "${getFPS()}FPS"
}
}

View file

@ -0,0 +1,15 @@
package net.moonleay.etaorion.client.modules.hud
import net.minecraft.client.MinecraftClient
import net.moonleay.etaorion.client.modules.component.Category
import net.moonleay.etaorion.client.modules.component.MovableModule
class XYZ : MovableModule("XYZ Display", Category.HUD) {
override fun getText4Render(): String {
val playerEntity = MinecraftClient.getInstance().player!!
return "${playerEntity.x.format(2)}x ${playerEntity.y.format(2)}y ${playerEntity.z.format(2)}z"
}
private fun Double.format(digits: Int) = "%.${digits}f".format(this)
}

View file

@ -0,0 +1,102 @@
package net.moonleay.etaorion.client.screen
import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.screen.Screen
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.client.gui.widget.TextFieldWidget
import net.minecraft.screen.ScreenTexts
import net.minecraft.text.Text
import net.moonleay.etaorion.client.autotext.AutoText
import net.moonleay.etaorion.client.autotext.AutoTextManager
import net.moonleay.etaorion.client.autotext.KeyBindingManager
import net.moonleay.etaorion.client.modules.component.ModuleManager
import net.moonleay.etaorion.config.AutoTextConfig
import org.lwjgl.glfw.GLFW
class AutoTextScreen(val parent: Screen) : Screen(Text.of("AutoText Manager")) {
private var optionList: AutoTextWidget? = null
private var addressField:TextFieldWidget? = null
override fun init() {
optionList = AutoTextWidget(this, client!!)
addSelectableChild(optionList)
addressField =
TextFieldWidget(textRenderer, 4, height - 25, 200, 20, Text.of("Add new AutoText"))
addressField!!.setMaxLength(300)
addSelectableChild(addressField)
addDrawableChild(
ButtonWidget.builder(
Text.of("Add")
) { addText() }
.dimensions(210, height - 25, 40, 20).build())
addDrawableChild(
ButtonWidget.builder(
ScreenTexts.DONE
) { onClose() }
.dimensions(250, height - 25, 40, 20).build())
}
private fun addText(){
val keyBinding = KeyBindingManager.bookKeyBinding()?: return
val response = AutoTextManager.registerNewAutoTxtObject(AutoText(addressField!!.text, keyBinding))
if(response){
addressField!!.setText("")
this.client?.setScreen(this)
}
}
override fun close() {
onClose()
super.close()
}
override fun shouldCloseOnEsc(): Boolean {
return false
}
fun onClose() {
for(at in AutoTextManager.autoTextObjects){
AutoTextConfig.save(at)
}
client!!.setScreen(parent)
MinecraftClient.getInstance().setScreen(parent)
}
override fun tick() {
addressField!!.tick()
}
override fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean {
if (this.addressField!!.active && focused === addressField && (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER)) {
return true
}
return super.keyPressed(keyCode, scanCode, modifiers)
}
override fun resize(client: MinecraftClient?, width: Int, height: Int) {
val string = addressField!!.text
this.init(client, width, height)
addressField!!.setText(string)
}
override fun render(context: DrawContext?, mouseX: Int, mouseY: Int, delta: Float) {
// this.renderBackground(context)
optionList!!.render(context, mouseX, mouseY, delta)
context?.drawCenteredTextWithShadow(
textRenderer,
title,
width / 2,
8,
0xFFFFFF
)
addressField!!.render(context, mouseX, mouseY, delta)
super.render(context, mouseX, mouseY, delta)
}
}

View file

@ -0,0 +1,96 @@
package net.moonleay.etaorion.client.screen
import com.google.common.collect.ImmutableList
import net.moonleay.etaorion.client.modules.component.*
import net.fabricmc.api.EnvType
import net.fabricmc.api.Environment
import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.Element
import net.minecraft.client.gui.Selectable
import net.minecraft.client.gui.screen.Screen
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder
import net.minecraft.client.gui.screen.narration.NarrationPart
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.client.gui.widget.ElementListWidget
import net.minecraft.client.gui.widget.EntryListWidget
import net.minecraft.text.Text
import net.moonleay.etaorion.client.autotext.AutoText
import net.moonleay.etaorion.client.autotext.AutoTextManager
class AutoTextWidget(parent: Screen, client: MinecraftClient) :
EntryListWidget<AutoTextWidget.Entry>(client, parent.width + 45, parent.height, 20, parent.height - 32, 20) {
init {
for (o in AutoTextManager.autoTextObjects) {
if(o != null)
addEntry(ToggleButtonEntry(o, client))
}
}
override fun getScrollbarPositionX(): Int {
return super.getScrollbarPositionX() + 15
}
override fun getRowWidth(): Int {
return super.getRowWidth() + 32
}
override fun appendNarrations(builder: NarrationMessageBuilder?) {}
@Environment(EnvType.CLIENT)
class ToggleButtonEntry internal constructor(autoText: AutoText, client: MinecraftClient) : Entry() {
private val optionName: Text = Text.of(autoText.textToSend + " (Text ${autoText.eoKeyBinding.index})")
private val toggleButton: ButtonWidget
init {
toggleButton = ButtonWidget.builder(
Text.of("Remove")
) { onButtonClick(autoText, client) }
.dimensions(0, 0, 75, 20).build()
}
private fun onButtonClick(autoText: AutoText, client: MinecraftClient) {
AutoTextManager.unregisterAutoTextObject(autoText.eoKeyBinding.index)
client.setScreen(client.currentScreen)
}
override fun render(
context: DrawContext?,
index: Int,
y: Int,
x: Int,
entryWidth: Int,
entryHeight: Int,
mouseX: Int,
mouseY: Int,
hovered: Boolean,
tickDelta: Float
) {
context?.drawTextWithShadow(MinecraftClient.getInstance().textRenderer,
optionName,
(x - 60F).toInt(),
(y + entryHeight / 2 - MinecraftClient.getInstance().textRenderer.fontHeight / 2F).toInt(),
0xFFFFFF)
toggleButton.x = x + 150
toggleButton.y = y
toggleButton.message = Text.of("Remove")
toggleButton.render(context, mouseX, mouseY, tickDelta)
}
override fun children(): List<Element?> {
return ImmutableList.of(toggleButton)
}
override fun selectableChildren(): List<Selectable?> {
return ImmutableList.of(toggleButton)
}
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
return toggleButton.mouseClicked(mouseX, mouseY, button)
}
}
@Environment(EnvType.CLIENT)
abstract class Entry : ElementListWidget.Entry<Entry?>()
}

View file

@ -0,0 +1,167 @@
package net.moonleay.etaorion.client.screen
import com.google.common.collect.ImmutableList
import net.moonleay.etaorion.client.modules.component.*
import net.fabricmc.api.EnvType
import net.fabricmc.api.Environment
import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.Element
import net.minecraft.client.gui.Selectable
import net.minecraft.client.gui.screen.Screen
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder
import net.minecraft.client.gui.screen.narration.NarrationPart
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.client.gui.widget.ElementListWidget
import net.minecraft.client.gui.widget.EntryListWidget
import net.minecraft.text.Text
class ModuleOptionWidget(parent: Screen, client: MinecraftClient) :
EntryListWidget<ModuleOptionWidget.Entry>(client, parent.width + 45, parent.height, 20, parent.height - 32, 20) {
init {
for (type in Category.values()) {
this.addEntry(CategoryEntry(Text.of(type.Name)))
for (o in ModuleManager.modules) {
if (o.category != type)
continue
addEntry(ToggleButtonEntry(o))
}
}
}
override fun getScrollbarPositionX(): Int {
return super.getScrollbarPositionX() + 15
}
override fun getRowWidth(): Int {
return super.getRowWidth() + 32
}
override fun appendNarrations(builder: NarrationMessageBuilder?) {}
@Environment(EnvType.CLIENT)
class ToggleButtonEntry internal constructor(val module: Module) : Entry() {
private val optionName: Text = Text.of(module.name)
private val toggleButton: ButtonWidget
init {
if (module is MovableModule) {
val mm: MovableModule = module
toggleButton = ButtonWidget.builder(
Text.of(" " + mm.position.Name)
) { onButtonClick(module) }
.dimensions(0, 0, 100, 20).build()
} else {
toggleButton = ButtonWidget.builder(
Text.of(if (module.enabled) " on" else " off")
) { onButtonClick(module) }
.dimensions(0, 0, 100, 20).build()
}
}
fun onButtonClick(module: Module) {
if (module is MovableModule) {
val mm: MovableModule = module
var intOfCurrentPos = ModuleManager.getPositionNumberInt(mm.position)
val oldPos = mm.position
if (intOfCurrentPos + 1 == Position.values().size)
intOfCurrentPos = -1
mm.updatePosition(Position.values()[intOfCurrentPos + 1])
ModuleManager.updatePositionOfModule(mm, oldPos, Position.values()[intOfCurrentPos + 1])
return
}
module.updateEnabled(!module.enabled)
}
override fun render(
context: DrawContext?,
index: Int,
y: Int,
x: Int,
entryWidth: Int,
entryHeight: Int,
mouseX: Int,
mouseY: Int,
hovered: Boolean,
tickDelta: Float
) {
context?.drawTextWithShadow(MinecraftClient.getInstance().textRenderer,
optionName,
(x - 60F).toInt(),
(y + entryHeight / 2 - MinecraftClient.getInstance().textRenderer.fontHeight / 2F).toInt(),
0xFFFFFF)
toggleButton.x = x + 150
toggleButton.y = y
if (module is MovableModule) {
val mm: MovableModule = module
toggleButton.message = Text.of(mm.position.Name)
} else {
toggleButton.message = Text.of(if (module.enabled) "on" else "off")
}
toggleButton.render(context, mouseX, mouseY, tickDelta)
}
override fun children(): List<Element?> {
return ImmutableList.of(toggleButton)
}
override fun selectableChildren(): List<Selectable?> {
return ImmutableList.of(toggleButton)
}
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
return toggleButton.mouseClicked(mouseX, mouseY, button)
}
}
@Environment(EnvType.CLIENT)
abstract class Entry : ElementListWidget.Entry<Entry?>()
@Environment(EnvType.CLIENT)
class CategoryEntry(text: Text) : Entry() {
private val text: Text
private val textWidth: Int
init {
this.text = text
textWidth = MinecraftClient.getInstance().textRenderer.getWidth(this.text)
}
override fun render(
context: DrawContext?,
index: Int,
y: Int,
x: Int,
entryWidth: Int,
entryHeight: Int,
mouseX: Int,
mouseY: Int,
hovered: Boolean,
tickDelta: Float
) {
context?.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, text,
(MinecraftClient.getInstance().currentScreen!!.width / 2 - textWidth / 2F).toInt(),
(y + entryHeight - MinecraftClient.getInstance().textRenderer.fontHeight - 1F).toInt(),
0xFFFFFF)
}
override fun children(): List<Element?> {
return emptyList()
}
override fun selectableChildren(): List<Selectable?> {
return ImmutableList.of(object : Selectable {
override fun getType(): Selectable.SelectionType {
return Selectable.SelectionType.HOVERED
}
override fun appendNarrations(builder: NarrationMessageBuilder) {
builder.put(NarrationPart.TITLE, text)
}
})
}
}
}

View file

@ -0,0 +1,55 @@
package net.moonleay.etaorion.client.screen
import net.moonleay.etaorion.client.modules.component.ModuleManager
import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.screen.Screen
import net.minecraft.client.gui.widget.ButtonWidget
import net.minecraft.screen.ScreenTexts
import net.minecraft.text.Text
class OptionScreen(val parent: Screen) : Screen(Text.of("EtaOrion Fabric Options")) {
private var optionList: ModuleOptionWidget? = null
override fun init() {
optionList = ModuleOptionWidget(this, client!!)
addSelectableChild(optionList)
addDrawableChild(
ButtonWidget.builder(
ScreenTexts.DONE
) { onClose() }
.dimensions(width / 2 - 100, height - 25, 200, 20).build())
}
override fun close() {
onClose()
super.close()
}
override fun shouldCloseOnEsc(): Boolean {
return false
}
private fun onClose() {
client!!.setScreen(parent)
ModuleManager.saveAllModules()
MinecraftClient.getInstance().setScreen(parent)
}
override fun render(context: DrawContext?, mouseX: Int, mouseY: Int, delta: Float) {
this.renderBackground(context)
//drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 15, 0xFFFFFF);
optionList!!.render(context, mouseX, mouseY, delta)
context?.drawCenteredTextWithShadow(
textRenderer,
title,
width / 2,
8,
0xFFFFFF
)
super.render(context, mouseX, mouseY, delta)
}
}

View file

@ -0,0 +1,97 @@
package net.moonleay.etaorion.config
import net.moonleay.etaorion.client.autotext.AutoText
import net.moonleay.etaorion.client.autotext.KeyBindingManager
import net.moonleay.etaorion.client.modules.component.MovableModule
import org.apache.logging.log4j.LogManager
import java.io.*
import java.util.*
object AutoTextConfig {
private val lgr = LogManager.getLogger(AutoTextConfig::class.java)
private const val basePath = "./config/EtaOrionFabric/AutoTexts/"
fun delete(index: Int){
val baseDir = File(basePath)
if (!baseDir.exists()) {
lgr.info("No AT folder found.")
return
}
var textFile: File
textFile = File(baseDir, "${index}.EOF")
if(!textFile.exists()){
lgr.info("No AT # ${index} found. No need to delete.")
return
}
textFile.delete()
}
fun load(index: Int): AutoText? {
val baseDir = File(basePath)
if (!baseDir.exists()) {
lgr.info("No AT folder found.")
return null
}
var textFile: File
var input: InputStream?
var prop: Properties
textFile = File(baseDir, "${index}.EOF")
if (!textFile.exists()) {
lgr.info("No AT # ${index} found. No need to load.")
return null
}
lgr.info("Loading AT # ${index}, file: ${textFile.path}")
try {
input = FileInputStream(textFile)
prop = Properties()
prop.load(input)
val keyBinding = KeyBindingManager.bookWithIndex(index)?: KeyBindingManager.bookKeyBinding()
if(keyBinding == null){
lgr.info("Shit. No free keybinding found for AT # ${index}")
return null
}
// Resort to a new keybinding if the old one is in use, return null if there is no free keybinding
lgr.info("Loaded AutoText #${index}")
return AutoText(prop.getProperty("text"), keyBinding)
} catch (e: IOException) {
throw RuntimeException(e)
}
}
fun save(at: AutoText) {
val baseDir = File(basePath)
if (!baseDir.exists()) this.createFolder()
var textFile: File
var output: OutputStream?
var prop: Properties
textFile = File(baseDir, at.eoKeyBinding.index.toString() + ".EOF")
if (!textFile.exists()) {
try {
textFile.createNewFile()
} catch (e: IOException) {
throw RuntimeException(e)
}
}
lgr.info("Saving AT # ${at.eoKeyBinding.index}, File: " + textFile)
try {
output = FileOutputStream(textFile)
prop = Properties()
prop.setProperty("text", at.textToSend)
prop.store(output, null)
lgr.info("Saved Module Settings")
} catch (e: IOException) {
throw RuntimeException(e)
}
}
private fun createFolder(){
val baseDir = File(basePath)
if (!baseDir.exists()) baseDir.mkdirs()
}
fun saveTemplate(int: Int){
}
}

View file

@ -0,0 +1,81 @@
package net.moonleay.etaorion.config
import net.moonleay.etaorion.client.modules.component.ModuleManager
import net.moonleay.etaorion.client.modules.component.MovableModule
import net.moonleay.etaorion.client.modules.component.Module
import java.io.*
import java.util.*
object ModuleConfig {
private val lgr = org.apache.logging.log4j.LogManager.getLogger(ModuleConfig::class.java)
private const val basePath = "./config/EtaOrionFabric/"
fun load(modules: List<Module>) {
val baseDir = File(basePath)
if (!baseDir.exists()) {
save(modules)
return
}
var moduleFile: File
var input: InputStream?
var prop: Properties
for (m in modules) {
moduleFile = File(baseDir, m.name + ".EOF")
if (!moduleFile.exists()) {
save(modules)
return
}
lgr.info("Loading " + m.name + ", File: " + moduleFile)
try {
input = FileInputStream(moduleFile)
prop = Properties()
prop.load(input)
if (m is MovableModule) {
val mm: MovableModule = m
mm.onLoadGfx(
prop.getProperty("enabled").equals("true"),
ModuleManager.getPositionFromname(prop.getProperty("position"))
)
} else {
m.onLoad(
prop.getProperty("enabled").equals("true")
)
}
} catch (e: IOException) {
throw RuntimeException(e)
}
}
lgr.info("Loaded Module Settings")
}
fun save(modules: List<Module>) {
val baseDir = File(basePath)
if (!baseDir.exists()) baseDir.mkdirs()
var moduleFile: File
var output: OutputStream?
var prop: Properties
for (m in modules) {
moduleFile = File(baseDir, m.name + ".EOF")
if (!moduleFile.exists()) {
try {
moduleFile.createNewFile()
} catch (e: IOException) {
throw RuntimeException(e)
}
}
lgr.info("Saving " + m.name + ", File: " + moduleFile)
try {
output = FileOutputStream(moduleFile)
prop = Properties()
prop.setProperty("enabled", if (m.enabled) "true" else "false")
if (m is MovableModule) {
prop.setProperty("position", m.position.Name)
}
prop.store(output, null)
} catch (e: IOException) {
throw RuntimeException(e)
}
}
lgr.info("Saved Module Settings")
}
}

View file

@ -0,0 +1,11 @@
package net.moonleay.etaorion.datagen
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator
internal class DataGenerator : DataGeneratorEntrypoint {
override fun onInitializeDataGenerator(fabricDataGenerator: FabricDataGenerator) {
val pack = fabricDataGenerator.createPack()
pack.addProvider(::LanguageProvider)
}
}

View file

@ -0,0 +1,20 @@
package net.moonleay.etaorion.datagen
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput
import net.fabricmc.fabric.api.datagen.v1.provider.FabricLanguageProvider
class LanguageProvider(dataOutput: FabricDataOutput) : FabricLanguageProvider(dataOutput, "en_us") {
override fun generateTranslations(translationBuilder: TranslationBuilder) {
translationBuilder.add("category.etaorion.autotext", "EtaOrion AutoText")
translationBuilder.add("etaorion.key_binding_0", "Text 0")
translationBuilder.add("etaorion.key_binding_1", "Text 1")
translationBuilder.add("etaorion.key_binding_2", "Text 2")
translationBuilder.add("etaorion.key_binding_3", "Text 3")
translationBuilder.add("etaorion.key_binding_4", "Text 4")
translationBuilder.add("etaorion.key_binding_5", "Text 5")
translationBuilder.add("etaorion.key_binding_6", "Text 6")
translationBuilder.add("etaorion.key_binding_7", "Text 7")
translationBuilder.add("etaorion.key_binding_8", "Text 8")
translationBuilder.add("etaorion.key_binding_9", "Text 9")
}
}

View file

@ -0,0 +1,26 @@
package net.moonleay.etaorion.mixin;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.option.KeybindsScreen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.text.Text;
import net.moonleay.etaorion.client.screen.AutoTextScreen;
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;
@Mixin(ChatScreen.class)
public class AddAutoTextScreenButton extends Screen {
protected AddAutoTextScreenButton(Text title) {
super(title);
}
@Inject(method = "init", at = @At("HEAD"), cancellable = true)
public void addButtons(CallbackInfo ci) {
this.addDrawableChild(ButtonWidget.builder(Text.of("AutoText"), button -> this.client.setScreen(new AutoTextScreen(this))).dimensions(4, 4, 75, 20).build());
this.addDrawableChild(ButtonWidget.builder(Text.of("Key Binds"), button -> this.client.setScreen(new KeybindsScreen(this, MinecraftClient.getInstance().options))).dimensions(4, 25, 75, 20).build());
}
}

View file

@ -0,0 +1,26 @@
package net.moonleay.etaorion.mixin;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.option.OptionsScreen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.text.Text;
import net.moonleay.etaorion.client.screen.OptionScreen;
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;
@Mixin(OptionsScreen.class)
public class AddEtaOrionConfigButton extends Screen {
protected AddEtaOrionConfigButton(Text title) {
super(title);
}
@Inject(at = @At("HEAD"), method = "init")
private void addButton(CallbackInfo ci) {
this.addDrawableChild(ButtonWidget.builder(Text.of("EtaOrion Settings"), button -> this.client.setScreen(new OptionScreen(this))).dimensions(4, 4, 200, 20).build());
}
}

View file

@ -0,0 +1,27 @@
package net.moonleay.etaorion.mixin;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.text.Text;
import net.moonleay.etaorion.client.modules.component.ModuleStorage;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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.CallbackInfoReturnable;
@Mixin(ChatScreen.class)
public abstract class ChatMixin {
private Logger lgr = LogManager.getLogger(ChatMixin.class);
@Inject(method = "sendMessage", at = @At("HEAD"), cancellable = true)
public void checkForFatFinger(String chatText, boolean addToHistory, CallbackInfoReturnable<Boolean> cir) {
if(ModuleStorage.INSTANCE.getAntiFatFingerEnabled() && (chatText.startsWith(".") || chatText.startsWith("7")) && !chatText.startsWith("./")){
cir.setReturnValue(false);
cir.cancel();
MinecraftClient.getInstance().player.sendMessage(Text.of("§cMessage cancelled, was fat-fingered."), false);
lgr.info("Message cancelled, was fat-fingered.");
}
}
}

View file

@ -0,0 +1,23 @@
package net.moonleay.etaorion.mixin;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl;
import net.minecraft.client.option.GameOptions;
import net.minecraft.client.option.KeyBinding;
import net.moonleay.etaorion.util.KeyBindingManagement;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
@Environment(EnvType.CLIENT)
@Mixin(GameOptions.class)
public class GameOptionsMixin implements KeyBindingManagement {
@Mutable
@Shadow @Final public KeyBinding[] allKeys;
public void refreshKeyBindings() {
this.allKeys = KeyBindingRegistryImpl.process(this.allKeys);
}
}

View file

@ -0,0 +1,19 @@
package net.moonleay.etaorion.mixin;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl;
import net.minecraft.client.option.KeyBinding;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.List;
@Environment(EnvType.CLIENT)
@Mixin(KeyBindingRegistryImpl.class)
public interface KeyBindingRegistryImplAccessor {
@Accessor("MODDED_KEY_BINDINGS")
static List<KeyBinding> getKeyBindings() {
throw new AssertionError();
}
}

View file

@ -0,0 +1,25 @@
package net.moonleay.etaorion.mixin;
import net.minecraft.SharedConstants;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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;
@Mixin(SharedConstants.class)
public class LazyDFUMixin {
/**
* author: Andrew Steinborn
* reason: Disables any possibility of enabling DFU "optimizations"
* (This was edited)
*/
private static final Logger lgr = LogManager.getLogger("LazyDFUMixin");
@Inject(method = "enableDataFixerOptimization", at = @At("HEAD"), cancellable = true)
private static void enableDataFixerOptimizations(CallbackInfo ci) {
lgr.info("LazyDFU: skipping DFU");
ci.cancel();
// Turn this method into a no-op.
}
}

View file

@ -0,0 +1,94 @@
package net.moonleay.etaorion.mixin;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.hud.InGameHud;
import net.minecraft.text.Text;
import net.moonleay.etaorion.client.modules.component.ModuleManager;
import net.moonleay.etaorion.client.modules.component.MovableModule;
import net.moonleay.etaorion.client.modules.component.Position;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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;
@Mixin(InGameHud.class)
public abstract class ModuleRenderer {
private Logger lgr = LogManager.getLogger(ModuleRenderer.class);
@Shadow
public abstract TextRenderer getTextRenderer();
@Inject(at = @At("HEAD"), method = "renderStatusEffectOverlay")
private void renderModules(DrawContext context, CallbackInfo ci) {
MinecraftClient mc = MinecraftClient.getInstance();
TextRenderer tr = mc.textRenderer;
int scale = (mc.options.getGuiScale().getValue() == 0 ? 1 : mc.options.getGuiScale().getValue());
int screenWidth = mc.getWindow().getWidth();
int screenHeight = mc.getWindow().getHeight();
int baseYtop = 4;
int baseYcenter = screenHeight / 2 / scale;
int offset = 12;
int index = 0;
int xCentered = screenWidth / 2 / scale;
int bottomY = screenHeight / scale - 4 - tr.fontHeight - (offset * index);
for (MovableModule m : ModuleManager.INSTANCE.getEnabledGfxModules().get(Position.TOPLEFT)) {
context.drawTextWithShadow(tr, Text.of(m.getText4Render()), 4, baseYtop + (offset * index), -1);
++index;
}
index = 0;
for (MovableModule m : ModuleManager.INSTANCE.getEnabledGfxModules().get(Position.TOPCENTER)) {
context.drawCenteredTextWithShadow(tr, Text.of(m.getText4Render()), xCentered, baseYtop + (offset * index), -1);
++index;
}
index = 0;
for (MovableModule m : ModuleManager.INSTANCE.getEnabledGfxModules().get(Position.TOPRIGHT)) {
context.drawTextWithShadow(tr, Text.of(m.getText4Render()), getXRight(m.getText4Render(), screenWidth), baseYtop + (offset * index), -1);
++index;
}
index = 0;
int yBaseCentered = baseYcenter - ((ModuleManager.INSTANCE.getEnabledGfxModules().get(Position.RIGHTCENTER).size() / 2) * 12);
for (MovableModule m : ModuleManager.INSTANCE.getEnabledGfxModules().get(Position.RIGHTCENTER)) {
context.drawTextWithShadow(tr, Text.of(m.getText4Render()), getXRight(m.getText4Render(), screenWidth), yBaseCentered + (offset * index), -1);
++index;
}
index = 0;
for (MovableModule m : ModuleManager.INSTANCE.getEnabledGfxModules().get(Position.BOTTOMRIGHT)) {
context.drawTextWithShadow(tr, Text.of(m.getText4Render()), getXRight(m.getText4Render(), screenWidth), bottomY - (offset * index), -1);
++index;
}
index = 0;
for (MovableModule m : ModuleManager.INSTANCE.getEnabledGfxModules().get(Position.BOTTOMCENTER)) {
context.drawCenteredTextWithShadow(tr, Text.of(m.getText4Render()), xCentered, screenHeight / scale - 4 - 60 - tr.fontHeight - (offset * index), -1);
++index;
}
index = 0;
for (MovableModule m : ModuleManager.INSTANCE.getEnabledGfxModules().get(Position.BOTTOMLEFT)) {
context.drawTextWithShadow(tr, Text.of(m.getText4Render()), 4, bottomY - (offset * index), -1);
++index;
}
index = 0;
yBaseCentered = baseYcenter - ((ModuleManager.INSTANCE.getEnabledGfxModules().get(Position.LEFTCENTER).size() / 2) * 12);
for (MovableModule m : ModuleManager.INSTANCE.getEnabledGfxModules().get(Position.LEFTCENTER)) {
context.drawTextWithShadow(tr, Text.of(m.getText4Render()), 4, yBaseCentered + (offset * index), -1);
++index;
}
}
@Unique
private int getXRight(String txt, int screenWidth) {
return screenWidth / (MinecraftClient.getInstance().options.getGuiScale().getValue() == 0 ? 1 : MinecraftClient.getInstance().options.getGuiScale().getValue()) - 4 - MinecraftClient.getInstance().textRenderer.getWidth(Text.of(txt));
}
}

View file

@ -0,0 +1,23 @@
package net.moonleay.etaorion.mixin;
import net.minecraft.SharedConstants;
import net.minecraft.client.MinecraftClient;
import net.moonleay.etaorion.build.BuildConstants;
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.CallbackInfoReturnable;
@Mixin(MinecraftClient.class)
public class WindowTitleMixin {
@Inject(method = "getWindowTitle", at = @At("HEAD"), cancellable = true)
public void getWindowTitle(CallbackInfoReturnable<String> cir) {
cir.cancel();
String strb = "Eta Orion ver." +
BuildConstants.modVersion + //HCM VER
" for Minecraft " + //MC
SharedConstants.getGameVersion().getName(); //MC VER
cir.setReturnValue(strb);
}
}

View file

@ -0,0 +1,5 @@
package net.moonleay.etaorion.util
interface KeyBindingManagement {
fun refreshKeyBindings()
}