aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAppability <appable@icloud.com>2022-10-23 12:00:05 -0700
committerAppability <appable@icloud.com>2022-10-23 12:00:05 -0700
commit0576a7f5304565bb58a499b8ccdcda31ed587dc4 (patch)
tree766fad4c88ec8be5b142e338f097b67aa7322234 /src
parent4f25e7948c7e85151a80c17f7d2b25b72675cecf (diff)
downloadAmbientAddons-0576a7f5304565bb58a499b8ccdcda31ed587dc4.tar.gz
AmbientAddons-0576a7f5304565bb58a499b8ccdcda31ed587dc4.tar.bz2
AmbientAddons-0576a7f5304565bb58a499b8ccdcda31ed587dc4.zip
ping command and display
Diffstat (limited to 'src')
-rw-r--r--src/main/kotlin/com/ambientaddons/AmbientAddons.kt13
-rw-r--r--src/main/kotlin/com/ambientaddons/commands/PingCommand.kt23
-rw-r--r--src/main/kotlin/com/ambientaddons/config/Config.kt18
-rw-r--r--src/main/kotlin/com/ambientaddons/features/display/PingOverlay.kt155
-rw-r--r--src/main/kotlin/com/ambientaddons/gui/GuiElement.kt6
-rw-r--r--src/main/kotlin/com/ambientaddons/gui/MoveGui.kt5
-rw-r--r--src/main/kotlin/com/ambientaddons/utils/Extensions.kt7
7 files changed, 217 insertions, 10 deletions
diff --git a/src/main/kotlin/com/ambientaddons/AmbientAddons.kt b/src/main/kotlin/com/ambientaddons/AmbientAddons.kt
index 7b481ce..9f63b13 100644
--- a/src/main/kotlin/com/ambientaddons/AmbientAddons.kt
+++ b/src/main/kotlin/com/ambientaddons/AmbientAddons.kt
@@ -1,7 +1,9 @@
import com.ambientaddons.commands.AmbientCommand
+import com.ambientaddons.commands.PingCommand
import com.ambientaddons.config.Config
import com.ambientaddons.config.PersistentData
import com.ambientaddons.features.display.CatOverlay
+import com.ambientaddons.features.display.PingOverlay
import com.ambientaddons.features.display.WitherShieldOverlay
import com.ambientaddons.features.dungeon.*
import com.ambientaddons.features.dungeon.terminals.MelodyHelper
@@ -47,7 +49,10 @@ class AmbientAddons {
@Mod.EventHandler
fun onInit(event: FMLInitializationEvent) {
- ClientCommandHandler.instance.registerCommand(AmbientCommand())
+ listOf(
+ AmbientCommand(),
+ PingCommand()
+ ).forEach(ClientCommandHandler.instance::registerCommand)
listOf(
this,
SBLocation,
@@ -66,11 +71,13 @@ class AmbientAddons {
DungeonHighlights,
Trapper,
CrimsonFishing,
- CatOverlay
+ CatOverlay,
+ PingOverlay
).forEach(MinecraftForge.EVENT_BUS::register)
keyBinds.values.forEach(ClientRegistry::registerKeyBinding)
guiElements = listOf(
- CatOverlay.element
+ CatOverlay.element,
+ PingOverlay.element
)
}
diff --git a/src/main/kotlin/com/ambientaddons/commands/PingCommand.kt b/src/main/kotlin/com/ambientaddons/commands/PingCommand.kt
new file mode 100644
index 0000000..a3d68cb
--- /dev/null
+++ b/src/main/kotlin/com/ambientaddons/commands/PingCommand.kt
@@ -0,0 +1,23 @@
+package com.ambientaddons.commands
+
+import com.ambientaddons.config.Config
+import com.ambientaddons.features.display.PingOverlay
+import com.ambientaddons.utils.Extensions.withModPrefix
+import com.ambientaddons.utils.SBLocation
+import gg.essential.universal.UChat
+import net.minecraft.command.CommandBase
+import net.minecraft.command.ICommandSender
+
+class PingCommand : CommandBase() {
+ override fun getCommandName() = "ping"
+
+ override fun getCommandAliases() = listOf("amping")
+
+ override fun getCommandUsage(sender: ICommandSender?) = "/$commandName"
+
+ override fun getRequiredPermissionLevel() = 0
+
+ override fun processCommand(sender: ICommandSender?, args: Array<String>) {
+ PingOverlay.sendPing(true)
+ }
+} \ No newline at end of file
diff --git a/src/main/kotlin/com/ambientaddons/config/Config.kt b/src/main/kotlin/com/ambientaddons/config/Config.kt
index 4e4c39f..db2c327 100644
--- a/src/main/kotlin/com/ambientaddons/config/Config.kt
+++ b/src/main/kotlin/com/ambientaddons/config/Config.kt
@@ -37,6 +37,9 @@ object Config : Vigilant(
var cat = true
var witherShieldDisplay = 0
+ var shouldPing = 0
+ var pingDisplay = 0
+
var terminatorCps = 0
var cancelInteractions = false
var closeSecretChests = false
@@ -191,6 +194,21 @@ object Config : Vigilant(
description = "Displays remaining wither shield duration",
options = listOf("Off", "Default", "Shadow", "Outline")
)
+ subcategory("Ping and TPS") {
+ selector(
+ ::shouldPing,
+ name = "Enable ping",
+ description = "Enables ping in command and display. This requires sending packets to the server.",
+ options = listOf("Off", "In Skyblock", "On Hypixel", "Always")
+ )
+ selector(
+ ::pingDisplay,
+ name = "Ping and TPS display",
+ description = "Displays current ping and TPS. Ping requires ",
+ options = listOf("Off", "Default", "Shadow", "Outline")
+ )
+ }
+
}
category("Dungeon") {
diff --git a/src/main/kotlin/com/ambientaddons/features/display/PingOverlay.kt b/src/main/kotlin/com/ambientaddons/features/display/PingOverlay.kt
new file mode 100644
index 0000000..d8689be
--- /dev/null
+++ b/src/main/kotlin/com/ambientaddons/features/display/PingOverlay.kt
@@ -0,0 +1,155 @@
+package com.ambientaddons.features.display
+
+import AmbientAddons.Companion.config
+import AmbientAddons.Companion.mc
+import com.ambientaddons.events.ReceivePacketEvent
+import com.ambientaddons.gui.GuiElement
+import com.ambientaddons.utils.Alignment
+import com.ambientaddons.utils.Extensions.renderWidth
+import com.ambientaddons.utils.Extensions.withModPrefix
+import com.ambientaddons.utils.SBLocation
+import com.ambientaddons.utils.dungeon.TextStyle
+import com.ambientaddons.utils.render.OverlayUtils
+import gg.essential.universal.UChat
+import net.minecraft.client.renderer.GlStateManager
+import net.minecraft.network.play.client.C16PacketClientStatus
+import net.minecraft.network.play.server.S01PacketJoinGame
+import net.minecraft.network.play.server.S03PacketTimeUpdate
+import net.minecraft.network.play.server.S37PacketStatistics
+import net.minecraftforge.client.event.RenderGameOverlayEvent
+import net.minecraftforge.event.world.WorldEvent
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import net.minecraftforge.fml.common.gameevent.TickEvent
+import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent
+import kotlin.math.max
+
+// Modified from SkytilsMod/Skytils, under AGPL 3.0
+object PingOverlay {
+ val element = GuiElement("ping", 55, 20)
+ private val alpha = 1 / 3.0
+ private var averageTps: Double? = null
+ private var tpsCount = 0
+ private var lastTpsSample: Long? = null
+
+ private var averagePing: Double? = null
+ private var pingCount = 0
+ private var pingStartTime: Long? = null
+
+ private var ticks = 0
+ private var isPinging = false
+ private var chatNextPing = false
+
+ @SubscribeEvent
+ fun onPacketReceived(event: ReceivePacketEvent) {
+ if (event.packet is S03PacketTimeUpdate) {
+ val currentTime = System.currentTimeMillis()
+ lastTpsSample?.let { lastTime ->
+ val time = currentTime - lastTime
+ val instantTps = (20000.0 / time).coerceIn(0.0, 20.0)
+ tpsCount++
+ averageTps = instantTps * alpha + (averageTps ?: instantTps) * (1 - alpha)
+ }
+ lastTpsSample = currentTime
+ } else if (config.shouldPing != 0 && event.packet is S37PacketStatistics) {
+ isPinging = false
+ pingStartTime?.let { startTime ->
+ val instantPing = (System.nanoTime() - startTime) / 1e6
+ pingCount++
+ averagePing = instantPing * alpha + (averagePing ?: instantPing) * (1 - alpha)
+ }
+ if (chatNextPing) {
+ printPing()
+ chatNextPing = false
+ }
+ } else if (event.packet is S01PacketJoinGame) reset()
+ }
+
+ @SubscribeEvent
+ fun onWorldLoad(event: WorldEvent.Load) {
+ reset()
+ }
+
+ private fun reset() {
+ isPinging = false
+ tpsCount = 0
+ averageTps = null
+ pingCount = 0
+ averagePing = null
+ }
+
+ private fun printPing() {
+ val pingValue = averagePing?.let { "${colorizePing(it) }%.1f".format(it) } ?: "§e?"
+ val tpsValue = averageTps?.let { "${colorizeTps(it) }%.1f".format(it) } ?: "§e?"
+ if (shouldPing()) {
+ UChat.chat("$pingValue §7ms ($tpsValue §7tps)".withModPrefix())
+ } else {
+ UChat.chat("$tpsValue §7tps".withModPrefix())
+ }
+ }
+
+ fun sendPing(isFromCommand: Boolean) {
+ if (isFromCommand) chatNextPing = true
+ if (!isPinging) {
+ isPinging = true
+ mc.thePlayer.sendQueue.networkManager.sendPacket(C16PacketClientStatus(C16PacketClientStatus.EnumState.REQUEST_STATS),
+ {
+ pingStartTime = System.nanoTime()
+ }
+ )
+ } else if (isFromCommand && !shouldPing()) {
+ UChat.chat("§cAlready pinging!".withModPrefix())
+ }
+ }
+
+ @SubscribeEvent
+ fun onTick(event: ClientTickEvent) {
+ if (!shouldPing() || event.phase != TickEvent.Phase.START) return
+ if (ticks % 40 == 0) {
+ sendPing(false)
+ }
+ ticks++
+ }
+
+ private fun colorizeTps(tps: Double) = when {
+ (tps > 19) -> "§a"
+ (tps > 18) -> "§2"
+ (tps > 17) -> "§e"
+ (tps > 15) -> "§6"
+ else -> "§c"
+ }
+
+ private fun colorizePing(ping: Double) = when {
+ (ping < 50) -> "§a"
+ (ping < 100) -> "§2"
+ (ping < 150) -> "§e"
+ (ping < 250) -> "§6"
+ else -> "§c"
+ }
+
+ private fun shouldPing(): Boolean =
+ mc.theWorld != null && (config.shouldPing == 3 || (config.shouldPing == 2 && SBLocation.onHypixel) || (config.shouldPing == 1 && SBLocation.inSkyblock))
+
+ @SubscribeEvent
+ fun onRenderOverlay(event: RenderGameOverlayEvent) {
+ if (config.pingDisplay == 0 || event.type != RenderGameOverlayEvent.ElementType.TEXT) return
+ val textStyle = TextStyle.fromInt(config.pingDisplay - 1) ?: return
+ GlStateManager.pushMatrix()
+ GlStateManager.translate(element.position.x, element.position.y, 500.0)
+ GlStateManager.scale(element.position.scale, element.position.scale, 1.0)
+ val tpsValue = averageTps?.let { "${colorizeTps(it) }%.1f".format(it) } ?: "§e?"
+ if (shouldPing()) {
+ val pingValue = averagePing?.let { "${colorizePing(it)}%.1f".format(it) } ?: "§e?"
+ val valueWidth = max(pingValue.renderWidth(), tpsValue.renderWidth())
+ OverlayUtils.drawString(0, 0, "§bPing:", textStyle, Alignment.Left)
+ OverlayUtils.drawString(0, 10, "§bTPS:", textStyle, Alignment.Left)
+ OverlayUtils.drawString(30 + valueWidth, 0, pingValue, textStyle, Alignment.Right)
+ OverlayUtils.drawString(30 + valueWidth, 10, tpsValue, textStyle, Alignment.Right)
+ } else {
+ OverlayUtils.drawString(0, 0, "§bTPS:", textStyle, Alignment.Left)
+ OverlayUtils.drawString(30 + tpsValue.renderWidth(), 0, tpsValue, textStyle, Alignment.Right)
+ }
+ GlStateManager.popMatrix()
+ }
+
+
+}
diff --git a/src/main/kotlin/com/ambientaddons/gui/GuiElement.kt b/src/main/kotlin/com/ambientaddons/gui/GuiElement.kt
index c398464..7cb65e3 100644
--- a/src/main/kotlin/com/ambientaddons/gui/GuiElement.kt
+++ b/src/main/kotlin/com/ambientaddons/gui/GuiElement.kt
@@ -1,5 +1,6 @@
package com.ambientaddons.gui
+import AmbientAddons.Companion.guiElements
import AmbientAddons.Companion.persistentData
import com.ambientaddons.utils.render.OverlayUtils
import gg.essential.universal.UResolution
@@ -33,8 +34,9 @@ class GuiElement(val name: String, private val width: Int, private val height: I
val renderWidth = width * position.scale
val renderHeight = height * position.scale
GlStateManager.translate(position.x - padding * renderWidth, position.y - padding * renderWidth, 400.0)
- val color = if (isInsideElement(mouseX, mouseY)) Color(255, 255, 255, 128) else Color(128, 128, 128, 128)
- OverlayUtils.renderRect(0.0, 0.0, renderWidth * (1 + padding * 2), renderHeight * (1 + padding * 2), color)
+ val color = if (guiElements.find { it.isInsideElement(mouseX, mouseY) } == this)
+ Color(255, 255, 255, 128) else Color(128, 128, 128, 128)
+ OverlayUtils.renderRect(0.0, 0.0, renderWidth * (1 + padding * 2), renderHeight * (1 + padding * 2), color)
GlStateManager.popMatrix()
}
diff --git a/src/main/kotlin/com/ambientaddons/gui/MoveGui.kt b/src/main/kotlin/com/ambientaddons/gui/MoveGui.kt
index 33c96e7..61bb41b 100644
--- a/src/main/kotlin/com/ambientaddons/gui/MoveGui.kt
+++ b/src/main/kotlin/com/ambientaddons/gui/MoveGui.kt
@@ -11,6 +11,7 @@ import net.minecraft.client.renderer.GlStateManager
import org.lwjgl.input.Mouse
import org.lwjgl.opengl.Display
import java.awt.Color
+import kotlin.math.sign
class MoveGui : GuiScreen() {
private var currentElement: GuiElement? = null
@@ -53,12 +54,12 @@ class MoveGui : GuiScreen() {
override fun handleMouseInput() {
super.handleMouseInput()
val (mouseX, mouseY) = getMouseCoordinates()
+ val dScroll = (Mouse.getEventDWheel().sign * 0.1).takeIf { it != 0.0 } ?: return
currentElement = guiElements.find { it.isInsideElement(mouseX, mouseY) }?.apply {
clickOffsetX = mouseX - position.x
clickOffsetY = mouseY - position.y
- val scrollAmount = Mouse.getEventDWheel()
val oldScale = position.scale
- val newScale = (position.scale + scrollAmount / 7200.0).coerceAtLeast(0.1)
+ val newScale = (position.scale + dScroll).coerceAtLeast(0.1)
position.x = mouseX + (newScale / oldScale) * (position.x - mouseX)
position.y = mouseY + (newScale / oldScale) * (position.y - mouseY)
position.scale = newScale
diff --git a/src/main/kotlin/com/ambientaddons/utils/Extensions.kt b/src/main/kotlin/com/ambientaddons/utils/Extensions.kt
index 3da5767..ef4bcf1 100644
--- a/src/main/kotlin/com/ambientaddons/utils/Extensions.kt
+++ b/src/main/kotlin/com/ambientaddons/utils/Extensions.kt
@@ -1,5 +1,6 @@
package com.ambientaddons.utils
+import AmbientAddons.Companion.mc
import com.ambientaddons.utils.Extensions.enchants
import com.ambientaddons.utils.Extensions.extraAttributes
import com.ambientaddons.utils.Extensions.skyblockID
@@ -31,9 +32,9 @@ object Extensions {
?: ""
}
- fun String.withModPrefix(): String {
- return "§9§lAmbient §7» §r${this}"
- }
+ fun String.withModPrefix(): String = "§9§lAmbient §7» §r${this}"
+
+ fun String.renderWidth(): Int = mc.fontRendererObj.getStringWidth(this)
val GuiScreen.chest: ContainerChest?
get() = (this as? GuiChest)?.inventorySlots as? ContainerChest