aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ10a1n15 <45315647+j10a1n15@users.noreply.github.com>2024-10-02 16:45:32 +0200
committerGitHub <noreply@github.com>2024-10-02 16:45:32 +0200
commit140219f75b361fce1d9dec265f78b70202d06d3b (patch)
treeea8dd8ae2427ebb6a74e42d6267dd7847ad858d6
parentab7b3269eb8a5b3869331fa94663b1ddfebe80b2 (diff)
downloadskyhanni-140219f75b361fce1d9dec265f78b70202d06d3b.tar.gz
skyhanni-140219f75b361fce1d9dec265f78b70202d06d3b.tar.bz2
skyhanni-140219f75b361fce1d9dec265f78b70202d06d3b.zip
Backend: Alert Clock Offsets (#2623)
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com> Co-authored-by: CalMWolfs <cwolfson58@gmail.com>
-rw-r--r--build.gradle.kts4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/ComputerTimeOffset.kt122
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt13
4 files changed, 147 insertions, 1 deletions
diff --git a/build.gradle.kts b/build.gradle.kts
index 71a882ac9..3e3b002ff 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -171,6 +171,9 @@ dependencies {
implementation("net.hypixel:mod-api:0.3.1")
+ // getting clock offset
+ shadowImpl("commons-net:commons-net:3.8.0")
+
detektPlugins("org.notenoughupdates:detektrules:1.0.0")
detektPlugins(project(":detekt"))
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.23.7")
@@ -279,6 +282,7 @@ tasks.shadowJar {
relocate("io.github.notenoughupdates.moulconfig", "at.hannibal2.skyhanni.deps.moulconfig")
relocate("moe.nea.libautoupdate", "at.hannibal2.skyhanni.deps.libautoupdate")
relocate("com.jagrosh.discordipc", "at.hannibal2.skyhanni.deps.discordipc")
+ relocate("org.apache.commons.net", "at.hannibal2.skyhanni.deps.commons.net")
}
tasks.jar {
archiveClassifier.set("nodeps")
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java
index 9d503c398..df1ae1da5 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/MiscConfig.java
@@ -334,4 +334,13 @@ public class MiscConfig {
@ConfigEditorBoolean
@FeatureToggle
public boolean userluckEnabled = true;
+
+ @Expose
+ @ConfigOption(name = "Computer Time Offset Warning",
+ desc = "Sends a Chat Warning if your computer time is not synchronized with the actual time.\n" +
+ "§cMaking sure your computer time is correct is important for SkyHanni to display times correctly."
+ )
+ @ConfigEditorBoolean
+ @FeatureToggle
+ public boolean warnAboutPcTimeOffset = true;
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ComputerTimeOffset.kt b/src/main/java/at/hannibal2/skyhanni/utils/ComputerTimeOffset.kt
new file mode 100644
index 000000000..83ea15ecc
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ComputerTimeOffset.kt
@@ -0,0 +1,122 @@
+package at.hannibal2.skyhanni.utils
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.events.DebugDataCollectEvent
+import at.hannibal2.skyhanni.events.ProfileJoinEvent
+import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
+import at.hannibal2.skyhanni.test.command.ErrorManager
+import at.hannibal2.skyhanni.utils.TimeUtils.format
+import kotlinx.coroutines.launch
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import org.apache.commons.net.ntp.NTPUDPClient
+import java.net.InetAddress
+import kotlin.concurrent.thread
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.Duration.Companion.seconds
+
+@SkyHanniModule
+object ComputerTimeOffset {
+ private var offsetMillis: Duration? = null
+
+ private val config get() = SkyHanniMod.feature.misc.warnAboutPcTimeOffset
+
+ private val offsetFixLinks by lazy {
+ when {
+ OSUtils.isWindows -> {
+ "https://support.microsoft.com/en-us/windows/how-to-set-your-time-and-time-zone-dfaa7122-479f-5b98-2a7b-fa0b6e01b261"
+ }
+
+ OSUtils.isLinux -> "https://unix.stackexchange.com/a/79116"
+ OSUtils.isMac -> "https://support.apple.com/guide/mac-help/set-the-date-and-time-automatically-mchlp2996/mac"
+ else -> null
+ }
+ }
+
+ init {
+ thread {
+ while (true) {
+ Thread.sleep(1000)
+ detectTimeChange()
+ }
+ }
+ }
+
+ private fun checkOffset() {
+ val wasOffsetBefore = (offsetMillis?.absoluteValue ?: 0.seconds) > 5.seconds
+ SkyHanniMod.coroutineScope.launch {
+ offsetMillis = getNtpOffset("time.google.com")
+ offsetMillis?.let {
+ tryDisplayOffset(wasOffsetBefore)
+ }
+ }
+ }
+
+ private fun getNtpOffset(ntpServer: String): Duration? = try {
+ val client = NTPUDPClient()
+ val address = InetAddress.getByName(ntpServer)
+ val timeInfo = client.getTime(address)
+
+ timeInfo.computeDetails()
+ timeInfo.offset.milliseconds
+ } catch (e: Exception) {
+ if (LorenzUtils.inSkyBlock && config) ErrorManager.logErrorWithData(
+ e, "Failed to get NTP offset",
+ "server" to ntpServer,
+ )
+ else e.printStackTrace()
+ null
+ }
+
+ private var lastSystemTime = System.currentTimeMillis()
+
+ private fun detectTimeChange() {
+ val currentSystemTime = System.currentTimeMillis()
+ val timeDifference = (currentSystemTime - lastSystemTime).milliseconds
+ lastSystemTime = currentSystemTime
+
+ val expectedDuration = 1.seconds
+ val deviation = timeDifference - expectedDuration
+
+ if (deviation.absoluteValue > 1.seconds) {
+ checkOffset()
+ }
+ }
+
+ @SubscribeEvent
+ fun onProfileJoin(event: ProfileJoinEvent) {
+ DelayedRun.runDelayed(5.seconds) {
+ checkOffset()
+ }
+ }
+
+ private fun tryDisplayOffset(wasOffsetBefore: Boolean) {
+ if (!config || !LorenzUtils.onHypixel) return
+ val offsetMillis = offsetMillis ?: return
+ if (offsetMillis.absoluteValue < 5.seconds) {
+ if (wasOffsetBefore) {
+ ChatUtils.chat("Congratulations! Your computer's clock is now accurate.")
+ }
+ return
+ }
+
+ ChatUtils.clickableLinkChat(
+ "Your computer's clock is off by ${offsetMillis.absoluteValue.format()}.\n" +
+ "§ePlease update your time settings. Many features may not function correctly until you do.\n" +
+ "§eClick here for instructions on how to fix your clock.",
+ offsetFixLinks ?: return,
+ prefixColor = "§c",
+ )
+ }
+
+ @SubscribeEvent
+ fun onDebugCollect(event: DebugDataCollectEvent) {
+ event.title("Time Offset")
+ val relevant = offsetMillis?.absoluteValue?.let { it < 100.milliseconds } ?: true
+ if (relevant) {
+ event.addData(offsetMillis.toString())
+ } else {
+ event.addIrrelevant(offsetMillis.toString())
+ }
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt
index e209e0ce9..5b42c5dc6 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt
@@ -7,6 +7,17 @@ import java.net.URI
object OSUtils {
+ val isWindows: Boolean
+ val isMac: Boolean
+ val isLinux: Boolean
+
+ init {
+ val os = System.getProperty("os.name")
+ isWindows = os.contains("win", ignoreCase = true)
+ isMac = os.contains("mac", ignoreCase = true)
+ isLinux = os.contains("linux", ignoreCase = true)
+ }
+
@JvmStatic
fun openBrowser(url: String) {
val desktopSupported = Desktop.isDesktopSupported()
@@ -17,7 +28,7 @@ object OSUtils {
} catch (e: IOException) {
ErrorManager.logErrorWithData(
e, "Error while opening website.",
- "url" to url
+ "url" to url,
)
}
} else {