Skip to content

Commit

Permalink
Backend: Add backup repo (#2673)
Browse files Browse the repository at this point in the history
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
  • Loading branch information
CalMWolfs and hannibal002 authored Oct 16, 2024
1 parent e2f7293 commit e883d0c
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 59 deletions.
8 changes: 8 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import net.fabricmc.loom.task.RunGameTask
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import skyhannibuildsystem.ChangelogVerification
import skyhannibuildsystem.DownloadBackupRepo

plugins {
idea
Expand Down Expand Up @@ -96,6 +97,12 @@ val headlessLwjgl by configurations.creating {
isTransitive = false
isVisible = false
}

val includeBackupRepo by tasks.registering(DownloadBackupRepo::class) {
this.outputDirectory.set(layout.buildDirectory.dir("downloadedRepo"))
this.branch = "main"
}

tasks.runClient {
this.javaLauncher.set(
javaToolchains.launcherFor {
Expand Down Expand Up @@ -213,6 +220,7 @@ kotlin {

// Tasks:
tasks.processResources {
from(includeBackupRepo)
inputs.property("version", version)
filesMatching(listOf("mcmod.info", "fabric.mod.json")) {
expand("version" to version)
Expand Down
34 changes: 34 additions & 0 deletions buildSrc/src/main/kotlin/skyhannibuildsystem/DownloadBackupRepo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package skyhannibuildsystem

import org.gradle.api.DefaultTask
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import java.net.URL

// Code taken from NotEnoughUpdates
abstract class DownloadBackupRepo : DefaultTask() {

@get:OutputDirectory
abstract val outputDirectory: DirectoryProperty

@get:Input
abstract var branch: String

@get:Internal
val repoFile get() = outputDirectory.get().asFile.resolve("assets/skyhanni/repo.zip")

@TaskAction
fun downloadRepo() {
val downloadUrl = URL("https://github.com/hannibal002/SkyHanni-Repo/archive/refs/heads/$branch.zip")
val file = repoFile
file.parentFile.mkdirs()
file.outputStream().use { out ->
downloadUrl.openStream().use { inp ->
inp.copyTo(out)
}
}
}
}
114 changes: 70 additions & 44 deletions src/main/java/at/hannibal2/skyhanni/data/repo/RepoManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package at.hannibal2.skyhanni.data.repo

import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigManager
import at.hannibal2.skyhanni.events.DebugDataCollectEvent
import at.hannibal2.skyhanni.events.NeuRepositoryReloadEvent
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
import at.hannibal2.skyhanni.test.command.ErrorManager
Expand All @@ -26,24 +25,27 @@ import java.io.InputStreamReader
import java.io.OutputStreamWriter
import java.net.URL
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.StandardCopyOption
import java.util.concurrent.CompletableFuture
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.time.Duration.Companion.minutes

class RepoManager(private val configLocation: File) {

private val gson get() = ConfigManager.gson
private var latestRepoCommit: String? = null
val repoLocation: File = File(configLocation, "repo")
private var error = false
private var lastRepoUpdate = SimpleTimeMark.now()
private var repoDownloadFailed = false

companion object {

private val config get() = SkyHanniMod.feature.dev.repo

val successfulConstants = mutableListOf<String>()
val unsuccessfulConstants = mutableListOf<String>()
var usingBackupRepo = false

private var lastConstant: String? = null

Expand All @@ -62,7 +64,11 @@ class RepoManager(private val configLocation: File) {
fun loadRepoInformation() {
atomicShouldManuallyReload.set(true)
if (config.repoAutoUpdate) {
fetchRepository(false).thenRun(this::reloadRepository)
fetchRepository(false).thenRun {
if (repoDownloadFailed) {
switchToBackupRepo()
}
}.thenRun { reloadRepository() }
} else {
reloadRepository()
}
Expand All @@ -73,7 +79,10 @@ class RepoManager(private val configLocation: File) {
fun updateRepo() {
atomicShouldManuallyReload.set(true)
checkRepoLocation()
fetchRepository(true).thenRun { this.reloadRepository("Repo updated successfully.") }
fetchRepository(true).thenRun {
if (unsuccessfulConstants.isNotEmpty() || usingBackupRepo) return@thenRun
this.reloadRepository("Repo updated successfully.")
}
}

fun reloadLocalRepo() {
Expand All @@ -84,8 +93,8 @@ class RepoManager(private val configLocation: File) {
private fun fetchRepository(command: Boolean): CompletableFuture<Boolean> {
return CompletableFuture.supplyAsync {
try {
val currentCommitJSON: JsonObject? = getJsonFromFile(File(configLocation, "currentCommit.json"))
latestRepoCommit = null
val currentDownloadedCommit = readCurrentCommit()
var latestRepoCommit: String?
try {
InputStreamReader(URL(getCommitApiUrl()).openStream())
.use { inReader ->
Expand All @@ -97,13 +106,15 @@ class RepoManager(private val configLocation: File) {
e,
"Error while loading data from repo",
"command" to command,
"currentCommitJSON" to currentCommitJSON,
"currentDownloadedCommit" to currentDownloadedCommit,
)
repoDownloadFailed = true
return@supplyAsync false
}
if (latestRepoCommit == null || latestRepoCommit!!.isEmpty()) return@supplyAsync false

val file = File(configLocation, "repo")
if (file.exists() &&
currentCommitJSON?.get("sha")?.asString == latestRepoCommit &&
currentDownloadedCommit == latestRepoCommit &&
unsuccessfulConstants.isEmpty() &&
lastRepoUpdate.passedSince() < 1.minutes
) {
Expand All @@ -114,18 +125,19 @@ class RepoManager(private val configLocation: File) {
return@supplyAsync false
}
lastRepoUpdate = SimpleTimeMark.now()
RepoUtils.recursiveDelete(repoLocation)

repoLocation.mkdirs()
val itemsZip = File(repoLocation, "sh-repo-main.zip")
try {
itemsZip.createNewFile()
} catch (e: IOException) {
return@supplyAsync false
}
itemsZip.createNewFile()

val url = URL(getDownloadUrl(latestRepoCommit))
val urlConnection = url.openConnection()
urlConnection.connectTimeout = 15000
urlConnection.readTimeout = 30000

RepoUtils.recursiveDelete(repoLocation)
repoLocation.mkdirs()

try {
urlConnection.getInputStream().use { `is` ->
FileUtils.copyInputStreamToFile(
Expand All @@ -140,27 +152,26 @@ class RepoManager(private val configLocation: File) {
"url" to url,
"command" to command,
)
repoDownloadFailed = true
return@supplyAsync false
}
RepoUtils.unzipIgnoreFirstFolder(
itemsZip.absolutePath,
repoLocation.absolutePath,
)
if (currentCommitJSON == null || currentCommitJSON["sha"].asString != latestRepoCommit) {
val newCurrentCommitJSON = JsonObject()
newCurrentCommitJSON.addProperty("sha", latestRepoCommit)
try {
writeJson(newCurrentCommitJSON, File(configLocation, "currentCommit.json"))
} catch (ignored: IOException) {
}
if (currentDownloadedCommit == null || currentDownloadedCommit != latestRepoCommit) {
writeCurrentCommit(latestRepoCommit)
}
} catch (e: Exception) {
ErrorManager.logErrorWithData(
e,
"Failed to download SkyHanni Repo",
"command" to command,
)
repoDownloadFailed = true
}
repoDownloadFailed = false
usingBackupRepo = false
true
}
}
Expand Down Expand Up @@ -203,28 +214,18 @@ class RepoManager(private val configLocation: File) {
return comp
}

@SubscribeEvent
fun onDebugDataCollect(event: DebugDataCollectEvent) {
event.title("Repo Status")

if (unsuccessfulConstants.isEmpty() && successfulConstants.isNotEmpty()) {
event.addIrrelevant("Repo working fine")
return
private fun writeCurrentCommit(commit: String?) {
val newCurrentCommitJSON = JsonObject()
newCurrentCommitJSON.addProperty("sha", commit)
try {
writeJson(newCurrentCommitJSON, File(configLocation, "currentCommit.json"))
} catch (ignored: IOException) {
}
}

event.addData {
add("Successful Constants (${successfulConstants.size}):")

add("Unsuccessful Constants (${unsuccessfulConstants.size}):")

for ((i, constant) in unsuccessfulConstants.withIndex()) {
add(" - $constant")
if (i == 5) {
add("...")
break
}
}
}
private fun readCurrentCommit(): String? {
val currentCommitJSON: JsonObject? = getJsonFromFile(File(configLocation, "currentCommit.json"))
return currentCommitJSON?.get("sha")?.asString
}

fun displayRepoStatus(joinEvent: Boolean) {
Expand All @@ -238,6 +239,7 @@ class RepoManager(private val configLocation: File) {
).asComponent(),
)
text.add("§7Repo Auto Update Value: §c${config.repoAutoUpdate}".asComponent())
text.add("§7Backup Repo Value: §c${usingBackupRepo}".asComponent())
text.add("§7If you have Repo Auto Update turned off, please try turning that on.".asComponent())
text.add("§cUnsuccessful Constants §7(${unsuccessfulConstants.size}):".asComponent())

Expand All @@ -248,11 +250,12 @@ class RepoManager(private val configLocation: File) {
}
return
}
val currentCommit = readCurrentCommit()
if (unsuccessfulConstants.isEmpty() && successfulConstants.isNotEmpty()) {
ChatUtils.chat("Repo working fine! Commit hash: $latestRepoCommit", prefixColor = "§a")
ChatUtils.chat("Repo working fine! Commit hash: $currentCommit", prefixColor = "§a")
return
}
ChatUtils.chat("Repo has errors! Commit has: ${latestRepoCommit ?: "null"}", prefixColor = "§c")
ChatUtils.chat("Repo has errors! Commit hash: $currentCommit", prefixColor = "§c")
if (successfulConstants.isNotEmpty()) ChatUtils.chat(
"Successful Constants §7(${successfulConstants.size}):",
prefixColor = "§a",
Expand Down Expand Up @@ -348,4 +351,27 @@ class RepoManager(private val configLocation: File) {
resetRepositoryLocation()
}
}

// Code taken from NotEnoughUpdates
private fun switchToBackupRepo() {
usingBackupRepo = true
println("Attempting to switch to backup repo")

try {
repoLocation.mkdirs()
val destinationFile = File(repoLocation, "sh-repo-main.zip").apply { createNewFile() }
val destinationPath = destinationFile.toPath()

val inputStream = RepoManager::class.java.classLoader.getResourceAsStream("assets/skyhanni/repo.zip")
?: throw IOException("Failed to find backup repo")

Files.copy(inputStream, destinationPath, StandardCopyOption.REPLACE_EXISTING)
RepoUtils.unzipIgnoreFirstFolder(destinationPath.toAbsolutePath().toString(), repoLocation.absolutePath)
writeCurrentCommit("backup-repo")

println("Successfully switched to backup repo")
} catch (e: Exception) {
ErrorManager.logErrorWithData(e, "Failed to switch to backup repo")
}
}
}
28 changes: 14 additions & 14 deletions src/main/java/at/hannibal2/skyhanni/test/DebugCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,14 @@ object DebugCommand {
if (search.equalsIgnoreColor("all")) {
"search for everything:"
} else "search '$search':"
} else "no search specified, only showing interesting stuff:"
} else "no search specified, only showing interesting stuff:",
)

val event = DebugDataCollectEvent(list, search)

// calling default debug stuff
player(event)
repoAutoUpdate(event)
repoLocation(event)
repoData(event)
globalRender(event)
skyblockStatus(event)
profileName(event)
Expand Down Expand Up @@ -144,20 +143,21 @@ object DebugCommand {
}
}

private fun repoAutoUpdate(event: DebugDataCollectEvent) {
event.title("Repo Auto Update")
if (SkyHanniMod.feature.dev.repo.repoAutoUpdate) {
event.addIrrelevant("normal enabled")
} else {
event.addData("The repo does not auto update because auto update is disabled!")
private fun repoData(event: DebugDataCollectEvent) {
event.title("Repo Information")
event.addIrrelevant {
add(" repoAutoUpdate: ${SkyHanniMod.feature.dev.repo.repoAutoUpdate}")
add(" usingBackupRepo: ${RepoManager.usingBackupRepo}")
add(" repoLocation: '${RepoManager.getRepoLocation()}'")
if (RepoManager.unsuccessfulConstants.isNotEmpty()) {
add(" unsuccessful constants:")
for (constant in RepoManager.unsuccessfulConstants) {
add(" - $constant")
}
}
}
}

private fun repoLocation(event: DebugDataCollectEvent) {
event.title("Repo Location")
event.addIrrelevant("repo location: '${RepoManager.getRepoLocation()}'")
}

private fun player(event: DebugDataCollectEvent) {
event.title("Player")
event.addIrrelevant {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.api.event.HandleEvent
import at.hannibal2.skyhanni.config.ConfigManager
import at.hannibal2.skyhanni.config.features.dev.RepoPatternConfig
import at.hannibal2.skyhanni.data.repo.RepoManager
import at.hannibal2.skyhanni.events.ConfigLoadEvent
import at.hannibal2.skyhanni.events.LorenzEvent
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
Expand Down Expand Up @@ -78,7 +79,8 @@ object RepoPatternManager {
}
}

val localLoading: Boolean get() = config.forceLocal.get() || (!insideTest && PlatformUtils.isDevEnvironment)
private val localLoading: Boolean
get() = config.forceLocal.get() || (!insideTest && PlatformUtils.isDevEnvironment) || RepoManager.usingBackupRepo

private val logger = LogManager.getLogger("SkyHanni")

Expand Down

0 comments on commit e883d0c

Please sign in to comment.