test: Add sack util test
This commit is contained in:
@@ -7,6 +7,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import com.google.devtools.ksp.gradle.KspTaskJvm
|
import com.google.devtools.ksp.gradle.KspTaskJvm
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.google.gson.JsonObject
|
||||||
import moe.nea.licenseextractificator.LicenseDiscoveryTask
|
import moe.nea.licenseextractificator.LicenseDiscoveryTask
|
||||||
import moe.nea.mcautotranslations.gradle.CollectTranslations
|
import moe.nea.mcautotranslations.gradle.CollectTranslations
|
||||||
import net.fabricmc.loom.LoomGradleExtension
|
import net.fabricmc.loom.LoomGradleExtension
|
||||||
@@ -219,7 +221,8 @@ val configuredSourceSet = createIsolatedSourceSet("configured",
|
|||||||
val sodiumSourceSet = createIsolatedSourceSet("sodium")
|
val sodiumSourceSet = createIsolatedSourceSet("sodium")
|
||||||
val citResewnSourceSet = createIsolatedSourceSet("citresewn", isEnabled = false) // TODO: Wait for update
|
val citResewnSourceSet = createIsolatedSourceSet("citresewn", isEnabled = false) // TODO: Wait for update
|
||||||
val yaclSourceSet = createIsolatedSourceSet("yacl")
|
val yaclSourceSet = createIsolatedSourceSet("yacl")
|
||||||
val explosiveEnhancementSourceSet = createIsolatedSourceSet("explosiveEnhancement", isEnabled = false) // TODO: wait for their port
|
val explosiveEnhancementSourceSet =
|
||||||
|
createIsolatedSourceSet("explosiveEnhancement", isEnabled = false) // TODO: wait for their port
|
||||||
val wildfireGenderSourceSet = createIsolatedSourceSet("wildfireGender", isEnabled = false) // TODO: wait on their port
|
val wildfireGenderSourceSet = createIsolatedSourceSet("wildfireGender", isEnabled = false) // TODO: wait on their port
|
||||||
val modmenuSourceSet = createIsolatedSourceSet("modmenu")
|
val modmenuSourceSet = createIsolatedSourceSet("modmenu")
|
||||||
val reiSourceSet = createIsolatedSourceSet("rei")
|
val reiSourceSet = createIsolatedSourceSet("rei")
|
||||||
@@ -344,7 +347,35 @@ mcAutoTranslations {
|
|||||||
translationFunctionResolved.set("moe.nea.firmament.util.trResolved")
|
translationFunctionResolved.set("moe.nea.firmament.util.trResolved")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val downloadTestRepo by tasks.registering(RepoDownload::class) {
|
||||||
|
this.hash.set(project.property("firmament.compiletimerepohash") as String)
|
||||||
|
}
|
||||||
|
|
||||||
|
val updateTestRepo by tasks.registering {
|
||||||
|
outputs.upToDateWhen { false }
|
||||||
|
doLast {
|
||||||
|
val propertiesFile = rootProject.file("gradle.properties")
|
||||||
|
val json =
|
||||||
|
Gson().fromJson(uri("https://api.github.com/repos/NotEnoughUpdates/NotEnoughUpdates-REPO/branches/master")
|
||||||
|
.toURL().readText(), JsonObject::class.java)
|
||||||
|
val latestSha = json["commit"].asJsonObject["sha"].asString
|
||||||
|
var text = propertiesFile.readText()
|
||||||
|
text = text.replace("firmament\\.compiletimerepohash=[^\n]*".toRegex(),
|
||||||
|
"firmament.compiletimerepohash=$latestSha")
|
||||||
|
propertiesFile.writeText(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
tasks.test {
|
tasks.test {
|
||||||
|
val wd =file("build/testWorkDir")
|
||||||
|
workingDir(wd)
|
||||||
|
dependsOn(downloadTestRepo)
|
||||||
|
doFirst {
|
||||||
|
wd.mkdirs()
|
||||||
|
wd.resolve("config").deleteRecursively()
|
||||||
|
systemProperty("firmament.testrepo", downloadTestRepo.flatMap { it.outputDirectory.asFile }.map { it.absolutePath }.get())
|
||||||
|
}
|
||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
41
buildSrc/src/RepoDownload.kt
Normal file
41
buildSrc/src/RepoDownload.kt
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import java.net.URI
|
||||||
|
import java.util.zip.ZipInputStream
|
||||||
|
import org.gradle.api.DefaultTask
|
||||||
|
import org.gradle.api.file.DirectoryProperty
|
||||||
|
import org.gradle.api.provider.Property
|
||||||
|
import org.gradle.api.tasks.Input
|
||||||
|
import org.gradle.api.tasks.OutputDirectory
|
||||||
|
import org.gradle.api.tasks.TaskAction
|
||||||
|
|
||||||
|
abstract class RepoDownload : DefaultTask() {
|
||||||
|
@get:Input
|
||||||
|
abstract val hash: Property<String>
|
||||||
|
|
||||||
|
@get:OutputDirectory
|
||||||
|
abstract val outputDirectory: DirectoryProperty
|
||||||
|
|
||||||
|
init {
|
||||||
|
outputDirectory.convention(project.layout.buildDirectory.dir("extracted-test-repo"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
fun performDownload() {
|
||||||
|
val outputDir = outputDirectory.asFile.get().absoluteFile
|
||||||
|
outputDir.mkdirs()
|
||||||
|
URI("https://github.com/notEnoughUpdates/notEnoughUpdates-rEPO/archive/${hash.get()}.zip").toURL().openStream()
|
||||||
|
.let(::ZipInputStream)
|
||||||
|
.use { zipInput ->
|
||||||
|
while (true) {
|
||||||
|
val entry = zipInput.nextEntry ?: break
|
||||||
|
val destination = outputDir.resolve(
|
||||||
|
entry.name.substringAfter('/')).absoluteFile
|
||||||
|
require(outputDir in generateSequence(destination) { it.parentFile })
|
||||||
|
if (entry.isDirectory) continue
|
||||||
|
destination.parentFile.mkdirs()
|
||||||
|
destination.outputStream().use { output ->
|
||||||
|
zipInput.copyTo(output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# SPDX-FileCopyrightText: 2023 Linnea Gr<EFBFBD>f <nea@nea.moe>
|
# SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
# suppress inspection "UnusedProperty" for whole file
|
# suppress inspection "UnusedProperty" for whole file
|
||||||
@@ -9,3 +9,4 @@ loom.platform=fabric
|
|||||||
archives_base_name=Firmament
|
archives_base_name=Firmament
|
||||||
maven_group=moe.nea.firmament
|
maven_group=moe.nea.firmament
|
||||||
|
|
||||||
|
firmament.compiletimerepohash=a6116d945491d7c57c93d43f51250f93d62d8434
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import moe.nea.firmament.util.TimeMark
|
|||||||
import moe.nea.firmament.util.WarpUtil
|
import moe.nea.firmament.util.WarpUtil
|
||||||
import moe.nea.firmament.util.render.RenderInWorldContext
|
import moe.nea.firmament.util.render.RenderInWorldContext
|
||||||
import moe.nea.firmament.util.skyBlockId
|
import moe.nea.firmament.util.skyBlockId
|
||||||
|
import moe.nea.firmament.util.skyblock.SkyBlockItems
|
||||||
|
|
||||||
object AncestralSpadeSolver : SubscriptionOwner {
|
object AncestralSpadeSolver : SubscriptionOwner {
|
||||||
var lastDing = TimeMark.farPast()
|
var lastDing = TimeMark.farPast()
|
||||||
@@ -29,13 +30,12 @@ object AncestralSpadeSolver : SubscriptionOwner {
|
|||||||
var nextGuess: Vec3d? = null
|
var nextGuess: Vec3d? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
val ancestralSpadeId = SkyblockId("ANCESTRAL_SPADE")
|
|
||||||
private var lastTeleportAttempt = TimeMark.farPast()
|
private var lastTeleportAttempt = TimeMark.farPast()
|
||||||
|
|
||||||
fun isEnabled() =
|
fun isEnabled() =
|
||||||
DianaWaypoints.TConfig.ancestralSpadeSolver
|
DianaWaypoints.TConfig.ancestralSpadeSolver
|
||||||
&& SBData.skyblockLocation == SkyBlockIsland.HUB
|
&& SBData.skyblockLocation == SkyBlockIsland.HUB
|
||||||
&& MC.player?.inventory?.containsAny { it.skyBlockId == ancestralSpadeId } == true // TODO: add a reactive property here
|
&& MC.player?.inventory?.containsAny { it.skyBlockId == SkyBlockItems.ANCESTRAL_SPADE } == true // TODO: add a reactive property here
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
fun onKeyBind(event: WorldKeyboardEvent) {
|
fun onKeyBind(event: WorldKeyboardEvent) {
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
package moe.nea.firmament.repo
|
package moe.nea.firmament.repo
|
||||||
|
|
||||||
import com.mojang.serialization.Dynamic
|
import com.mojang.serialization.Dynamic
|
||||||
@@ -30,186 +28,194 @@ import moe.nea.firmament.Firmament
|
|||||||
import moe.nea.firmament.gui.config.HudMeta
|
import moe.nea.firmament.gui.config.HudMeta
|
||||||
import moe.nea.firmament.gui.config.HudPosition
|
import moe.nea.firmament.gui.config.HudPosition
|
||||||
import moe.nea.firmament.gui.hud.MoulConfigHud
|
import moe.nea.firmament.gui.hud.MoulConfigHud
|
||||||
|
import moe.nea.firmament.repo.RepoManager.initialize
|
||||||
import moe.nea.firmament.util.LegacyTagParser
|
import moe.nea.firmament.util.LegacyTagParser
|
||||||
import moe.nea.firmament.util.MC
|
import moe.nea.firmament.util.MC
|
||||||
import moe.nea.firmament.util.SkyblockId
|
import moe.nea.firmament.util.SkyblockId
|
||||||
|
import moe.nea.firmament.util.TestUtil
|
||||||
import moe.nea.firmament.util.mc.appendLore
|
import moe.nea.firmament.util.mc.appendLore
|
||||||
|
import moe.nea.firmament.util.mc.modifyLore
|
||||||
import moe.nea.firmament.util.mc.setCustomName
|
import moe.nea.firmament.util.mc.setCustomName
|
||||||
import moe.nea.firmament.util.mc.setSkullOwner
|
import moe.nea.firmament.util.mc.setSkullOwner
|
||||||
import moe.nea.firmament.util.mc.modifyLore
|
|
||||||
import moe.nea.firmament.util.skyblockId
|
import moe.nea.firmament.util.skyblockId
|
||||||
|
|
||||||
object ItemCache : IReloadable {
|
object ItemCache : IReloadable {
|
||||||
private val cache: MutableMap<String, ItemStack> = ConcurrentHashMap()
|
private val cache: MutableMap<String, ItemStack> = ConcurrentHashMap()
|
||||||
private val df = Schemas.getFixer()
|
private val df = Schemas.getFixer()
|
||||||
val logger = LogManager.getLogger("${Firmament.logger.name}.ItemCache")
|
val logger = LogManager.getLogger("${Firmament.logger.name}.ItemCache")
|
||||||
var isFlawless = true
|
var isFlawless = true
|
||||||
private set
|
private set
|
||||||
|
|
||||||
private fun NEUItem.get10809CompoundTag(): NbtCompound = NbtCompound().apply {
|
private fun NEUItem.get10809CompoundTag(): NbtCompound = NbtCompound().apply {
|
||||||
put("tag", LegacyTagParser.parse(nbttag))
|
put("tag", LegacyTagParser.parse(nbttag))
|
||||||
putString("id", minecraftItemId)
|
putString("id", minecraftItemId)
|
||||||
putByte("Count", 1)
|
putByte("Count", 1)
|
||||||
putShort("Damage", damage.toShort())
|
putShort("Damage", damage.toShort())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun NbtCompound.transformFrom10809ToModern(): NbtCompound? =
|
private fun NbtCompound.transformFrom10809ToModern(): NbtCompound? =
|
||||||
try {
|
try {
|
||||||
df.update(
|
df.update(
|
||||||
TypeReferences.ITEM_STACK,
|
TypeReferences.ITEM_STACK,
|
||||||
Dynamic(NbtOps.INSTANCE, this),
|
Dynamic(NbtOps.INSTANCE, this),
|
||||||
-1,
|
-1,
|
||||||
SharedConstants.getGameVersion().saveVersion.id
|
SharedConstants.getGameVersion().saveVersion.id
|
||||||
).value as NbtCompound
|
).value as NbtCompound
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
isFlawless = false
|
isFlawless = false
|
||||||
logger.error("Could not data fix up $this", e)
|
logger.error("Could not data fix up $this", e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun brokenItemStack(neuItem: NEUItem?, idHint: SkyblockId? = null): ItemStack {
|
fun brokenItemStack(neuItem: NEUItem?, idHint: SkyblockId? = null): ItemStack {
|
||||||
return ItemStack(Items.PAINTING).apply {
|
return ItemStack(Items.PAINTING).apply {
|
||||||
setCustomName(Text.literal(neuItem?.displayName ?: idHint?.neuItem ?: "null"))
|
setCustomName(Text.literal(neuItem?.displayName ?: idHint?.neuItem ?: "null"))
|
||||||
appendLore(
|
appendLore(
|
||||||
listOf(
|
listOf(
|
||||||
Text.stringifiedTranslatable(
|
Text.stringifiedTranslatable(
|
||||||
"firmament.repo.brokenitem",
|
"firmament.repo.brokenitem",
|
||||||
(neuItem?.skyblockItemId ?: idHint)
|
(neuItem?.skyblockItemId ?: idHint)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun NEUItem.asItemStackNow(): ItemStack {
|
private fun NEUItem.asItemStackNow(): ItemStack {
|
||||||
try {
|
try {
|
||||||
val oldItemTag = get10809CompoundTag()
|
val oldItemTag = get10809CompoundTag()
|
||||||
val modernItemTag = oldItemTag.transformFrom10809ToModern()
|
val modernItemTag = oldItemTag.transformFrom10809ToModern()
|
||||||
?: return brokenItemStack(this)
|
?: return brokenItemStack(this)
|
||||||
val itemInstance =
|
val itemInstance =
|
||||||
ItemStack.fromNbt(MC.defaultRegistries, modernItemTag).getOrNull() ?: return brokenItemStack(this)
|
ItemStack.fromNbt(MC.defaultRegistries, modernItemTag).getOrNull() ?: return brokenItemStack(this)
|
||||||
val extraAttributes = oldItemTag.getCompound("tag").getCompound("ExtraAttributes")
|
val extraAttributes = oldItemTag.getCompound("tag").getCompound("ExtraAttributes")
|
||||||
if (extraAttributes != null)
|
if (extraAttributes != null)
|
||||||
itemInstance.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(extraAttributes))
|
itemInstance.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(extraAttributes))
|
||||||
return itemInstance
|
return itemInstance
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
return brokenItemStack(this)
|
return brokenItemStack(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun NEUItem?.asItemStack(idHint: SkyblockId? = null, loreReplacements: Map<String, String>? = null): ItemStack {
|
fun NEUItem?.asItemStack(idHint: SkyblockId? = null, loreReplacements: Map<String, String>? = null): ItemStack {
|
||||||
if (this == null) return brokenItemStack(null, idHint)
|
if (this == null) return brokenItemStack(null, idHint)
|
||||||
var s = cache[this.skyblockItemId]
|
var s = cache[this.skyblockItemId]
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
s = asItemStackNow()
|
s = asItemStackNow()
|
||||||
cache[this.skyblockItemId] = s
|
cache[this.skyblockItemId] = s
|
||||||
}
|
}
|
||||||
if (!loreReplacements.isNullOrEmpty()) {
|
if (!loreReplacements.isNullOrEmpty()) {
|
||||||
s = s.copy()!!
|
s = s.copy()!!
|
||||||
s.applyLoreReplacements(loreReplacements)
|
s.applyLoreReplacements(loreReplacements)
|
||||||
s.setCustomName(s.name.applyLoreReplacements(loreReplacements))
|
s.setCustomName(s.name.applyLoreReplacements(loreReplacements))
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ItemStack.applyLoreReplacements(loreReplacements: Map<String, String>) {
|
fun ItemStack.applyLoreReplacements(loreReplacements: Map<String, String>) {
|
||||||
modifyLore { lore ->
|
modifyLore { lore ->
|
||||||
lore.map {
|
lore.map {
|
||||||
it.applyLoreReplacements(loreReplacements)
|
it.applyLoreReplacements(loreReplacements)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Text.applyLoreReplacements(loreReplacements: Map<String, String>): Text {
|
fun Text.applyLoreReplacements(loreReplacements: Map<String, String>): Text {
|
||||||
assert(this.siblings.isEmpty())
|
assert(this.siblings.isEmpty())
|
||||||
var string = this.string
|
var string = this.string
|
||||||
loreReplacements.forEach { (find, replace) ->
|
loreReplacements.forEach { (find, replace) ->
|
||||||
string = string.replace("{$find}", replace)
|
string = string.replace("{$find}", replace)
|
||||||
}
|
}
|
||||||
return Text.literal(string).styled { this.style }
|
return Text.literal(string).styled { this.style }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun NEUItem.getIdentifier() = skyblockId.identifier
|
var job: Job? = null
|
||||||
|
|
||||||
var job: Job? = null
|
object ReloadProgressHud : MoulConfigHud(
|
||||||
object ReloadProgressHud : MoulConfigHud(
|
"repo_reload", HudMeta(HudPosition(0.0, 0.0, 1F), Text.literal("Repo Reload"), 180, 18)) {
|
||||||
"repo_reload", HudMeta(HudPosition(0.0, 0.0, 1F), Text.literal("Repo Reload"), 180, 18)) {
|
|
||||||
|
|
||||||
|
|
||||||
var isEnabled = false
|
var isEnabled = false
|
||||||
override fun shouldRender(): Boolean {
|
override fun shouldRender(): Boolean {
|
||||||
return isEnabled
|
return isEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
@get:Bind("current")
|
@get:Bind("current")
|
||||||
var current: Double = 0.0
|
var current: Double = 0.0
|
||||||
|
|
||||||
@get:Bind("label")
|
@get:Bind("label")
|
||||||
var label: String = ""
|
var label: String = ""
|
||||||
|
|
||||||
@get:Bind("max")
|
@get:Bind("max")
|
||||||
var max: Double = 0.0
|
var max: Double = 0.0
|
||||||
|
|
||||||
fun reportProgress(label: String, current: Int, max: Int) {
|
fun reportProgress(label: String, current: Int, max: Int) {
|
||||||
this.label = label
|
this.label = label
|
||||||
this.current = current.toDouble()
|
this.current = current.toDouble()
|
||||||
this.max = max.toDouble()
|
this.max = max.toDouble()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun reload(repository: NEURepository) {
|
override fun reload(repository: NEURepository) {
|
||||||
val j = job
|
val j = job
|
||||||
if (j != null && j.isActive) {
|
if (j != null && j.isActive) {
|
||||||
j.cancel()
|
j.cancel()
|
||||||
}
|
}
|
||||||
cache.clear()
|
cache.clear()
|
||||||
isFlawless = true
|
isFlawless = true
|
||||||
|
if (TestUtil.isInTest) return
|
||||||
|
job = Firmament.coroutineScope.launch {
|
||||||
|
val items = repository.items?.items
|
||||||
|
if (items == null) {
|
||||||
|
ReloadProgressHud.isEnabled = false
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
val recacheItems = I18n.translate("firmament.repo.cache")
|
||||||
|
ReloadProgressHud.reportProgress(recacheItems, 0, items.size)
|
||||||
|
ReloadProgressHud.isEnabled = true
|
||||||
|
var i = 0
|
||||||
|
items.values.forEach {
|
||||||
|
it.asItemStack() // Rebuild cache
|
||||||
|
ReloadProgressHud.reportProgress(recacheItems, i++, items.size)
|
||||||
|
}
|
||||||
|
ReloadProgressHud.isEnabled = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
job = Firmament.coroutineScope.launch {
|
fun coinItem(coinAmount: Int): ItemStack {
|
||||||
val items = repository.items?.items
|
var uuid = UUID.fromString("2070f6cb-f5db-367a-acd0-64d39a7e5d1b")
|
||||||
if (items == null) {
|
var texture =
|
||||||
ReloadProgressHud.isEnabled = false
|
"http://textures.minecraft.net/texture/538071721cc5b4cd406ce431a13f86083a8973e1064d2f8897869930ee6e5237"
|
||||||
return@launch
|
if (coinAmount >= 100000) {
|
||||||
}
|
uuid = UUID.fromString("94fa2455-2881-31fe-bb4e-e3e24d58dbe3")
|
||||||
val recacheItems = I18n.translate("firmament.repo.cache")
|
texture =
|
||||||
ReloadProgressHud.reportProgress(recacheItems, 0, items.size)
|
"http://textures.minecraft.net/texture/c9b77999fed3a2758bfeaf0793e52283817bea64044bf43ef29433f954bb52f6"
|
||||||
ReloadProgressHud.isEnabled = true
|
}
|
||||||
var i = 0
|
if (coinAmount >= 10000000) {
|
||||||
items.values.forEach {
|
uuid = UUID.fromString("0af8df1f-098c-3b72-ac6b-65d65fd0b668")
|
||||||
it.asItemStack() // Rebuild cache
|
texture =
|
||||||
ReloadProgressHud.reportProgress(recacheItems, i++, items.size)
|
"http://textures.minecraft.net/texture/7b951fed6a7b2cbc2036916dec7a46c4a56481564d14f945b6ebc03382766d3b"
|
||||||
}
|
}
|
||||||
ReloadProgressHud.isEnabled = false
|
val itemStack = ItemStack(Items.PLAYER_HEAD)
|
||||||
}
|
itemStack.setCustomName(Text.literal("§r§6" + NumberFormat.getInstance().format(coinAmount) + " Coins"))
|
||||||
}
|
itemStack.setSkullOwner(uuid, texture)
|
||||||
|
return itemStack
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (TestUtil.isInTest) {
|
||||||
|
initialize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun coinItem(coinAmount: Int): ItemStack {
|
|
||||||
var uuid = UUID.fromString("2070f6cb-f5db-367a-acd0-64d39a7e5d1b")
|
|
||||||
var texture =
|
|
||||||
"http://textures.minecraft.net/texture/538071721cc5b4cd406ce431a13f86083a8973e1064d2f8897869930ee6e5237"
|
|
||||||
if (coinAmount >= 100000) {
|
|
||||||
uuid = UUID.fromString("94fa2455-2881-31fe-bb4e-e3e24d58dbe3")
|
|
||||||
texture =
|
|
||||||
"http://textures.minecraft.net/texture/c9b77999fed3a2758bfeaf0793e52283817bea64044bf43ef29433f954bb52f6"
|
|
||||||
}
|
|
||||||
if (coinAmount >= 10000000) {
|
|
||||||
uuid = UUID.fromString("0af8df1f-098c-3b72-ac6b-65d65fd0b668")
|
|
||||||
texture =
|
|
||||||
"http://textures.minecraft.net/texture/7b951fed6a7b2cbc2036916dec7a46c4a56481564d14f945b6ebc03382766d3b"
|
|
||||||
}
|
|
||||||
val itemStack = ItemStack(Items.PLAYER_HEAD)
|
|
||||||
itemStack.setCustomName(Text.literal("§r§6" + NumberFormat.getInstance().format(coinAmount) + " Coins"))
|
|
||||||
itemStack.setSkullOwner(uuid, texture)
|
|
||||||
return itemStack
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
operator fun NbtCompound.set(key: String, value: String) {
|
operator fun NbtCompound.set(key: String, value: String) {
|
||||||
putString(key, value)
|
putString(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun NbtCompound.set(key: String, value: NbtElement) {
|
operator fun NbtCompound.set(key: String, value: NbtElement) {
|
||||||
put(key, value)
|
put(key, value)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.repo
|
package moe.nea.firmament.repo
|
||||||
|
|
||||||
import io.github.moulberry.repo.IReloadable
|
import io.github.moulberry.repo.IReloadable
|
||||||
@@ -12,87 +11,91 @@ import moe.nea.firmament.util.skyblockId
|
|||||||
|
|
||||||
object ItemNameLookup : IReloadable {
|
object ItemNameLookup : IReloadable {
|
||||||
|
|
||||||
fun getItemNameChunks(name: String): Set<String> {
|
fun getItemNameChunks(name: String): Set<String> {
|
||||||
return name.removeColorCodes().split(" ").filterTo(mutableSetOf()) { it.isNotBlank() }
|
return name.removeColorCodes().split(" ").filterTo(mutableSetOf()) { it.isNotBlank() }
|
||||||
}
|
}
|
||||||
|
|
||||||
var nameMap: NavigableMap<String, out Set<SkyblockId>> = TreeMap()
|
var nameMap: NavigableMap<String, out Set<SkyblockId>> = TreeMap()
|
||||||
|
|
||||||
override fun reload(repository: NEURepository) {
|
override fun reload(repository: NEURepository) {
|
||||||
val nameMap = TreeMap<String, MutableSet<SkyblockId>>()
|
val nameMap = TreeMap<String, MutableSet<SkyblockId>>()
|
||||||
repository.items.items.values.forEach { item ->
|
repository.items.items.values.forEach { item ->
|
||||||
getAllNamesForItem(item).forEach { name ->
|
getAllNamesForItem(item).forEach { name ->
|
||||||
val chunks = getItemNameChunks(name)
|
val chunks = getItemNameChunks(name)
|
||||||
chunks.forEach { chunk ->
|
chunks.forEach { chunk ->
|
||||||
val set = nameMap.getOrPut(chunk, ::mutableSetOf)
|
val set = nameMap.getOrPut(chunk, ::mutableSetOf)
|
||||||
set.add(item.skyblockId)
|
set.add(item.skyblockId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.nameMap = nameMap
|
this.nameMap = nameMap
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAllNamesForItem(item: NEUItem): Set<String> {
|
fun getAllNamesForItem(item: NEUItem): Set<String> {
|
||||||
val names = mutableSetOf<String>()
|
val names = mutableSetOf<String>()
|
||||||
names.add(item.displayName)
|
names.add(item.displayName)
|
||||||
if (item.displayName.contains("Enchanted Book")) {
|
if (item.displayName.contains("Enchanted Book")) {
|
||||||
val enchantName = item.lore.firstOrNull()
|
val enchantName = item.lore.firstOrNull()
|
||||||
if (enchantName != null) {
|
if (enchantName != null) {
|
||||||
names.add(enchantName)
|
names.add(enchantName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return names
|
return names
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findItemCandidatesByName(name: String): MutableSet<SkyblockId> {
|
fun findItemCandidatesByName(name: String): MutableSet<SkyblockId> {
|
||||||
val candidates = mutableSetOf<SkyblockId>()
|
val candidates = mutableSetOf<SkyblockId>()
|
||||||
for (chunk in getItemNameChunks(name)) {
|
for (chunk in getItemNameChunks(name)) {
|
||||||
val set = nameMap[chunk] ?: emptySet()
|
val set = nameMap[chunk] ?: emptySet()
|
||||||
candidates.addAll(set)
|
candidates.addAll(set)
|
||||||
}
|
}
|
||||||
return candidates
|
return candidates
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun guessItemByName(
|
fun guessItemByName(
|
||||||
/**
|
/**
|
||||||
* The display name of the item. Color codes will be ignored.
|
* The display name of the item. Color codes will be ignored.
|
||||||
*/
|
*/
|
||||||
name: String,
|
name: String,
|
||||||
/**
|
/**
|
||||||
* Whether the [name] may contain other text, such as reforges, master stars and such.
|
* Whether the [name] may contain other text, such as reforges, master stars and such.
|
||||||
*/
|
*/
|
||||||
mayBeMangled: Boolean
|
mayBeMangled: Boolean
|
||||||
): SkyblockId? {
|
): SkyblockId? {
|
||||||
val cleanName = name.removeColorCodes()
|
val cleanName = name.removeColorCodes()
|
||||||
return findBestItemFromCandidates(
|
return findBestItemFromCandidates(
|
||||||
findItemCandidatesByName(cleanName),
|
findItemCandidatesByName(cleanName),
|
||||||
cleanName,
|
cleanName,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findBestItemFromCandidates(
|
fun findBestItemFromCandidates(
|
||||||
candidates: Iterable<SkyblockId>,
|
candidates: Iterable<SkyblockId>,
|
||||||
name: String, mayBeMangled: Boolean
|
name: String, mayBeMangled: Boolean
|
||||||
): SkyblockId? {
|
): SkyblockId? {
|
||||||
val expectedClean = name.removeColorCodes()
|
val expectedClean = name.removeColorCodes()
|
||||||
var bestMatch: SkyblockId? = null
|
var bestMatch: SkyblockId? = null
|
||||||
var bestMatchLength = -1
|
var bestMatchLength = -1
|
||||||
for (candidate in candidates) {
|
for (candidate in candidates) {
|
||||||
val item = RepoManager.getNEUItem(candidate) ?: continue
|
val item = RepoManager.getNEUItem(candidate) ?: continue
|
||||||
for (name in getAllNamesForItem(item)) {
|
for (name in getAllNamesForItem(item)) {
|
||||||
val actualClean = name.removeColorCodes()
|
val actualClean = name.removeColorCodes()
|
||||||
val matches = if (mayBeMangled) expectedClean == actualClean
|
val matches = if (mayBeMangled) expectedClean == actualClean
|
||||||
else expectedClean.contains(actualClean)
|
else expectedClean.contains(actualClean)
|
||||||
if (!matches) continue
|
if (!matches) continue
|
||||||
if (actualClean.length > bestMatchLength) {
|
if (actualClean.length > bestMatchLength) {
|
||||||
bestMatch = candidate
|
bestMatch = candidate
|
||||||
bestMatchLength = actualClean.length
|
bestMatchLength = actualClean.length
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bestMatch
|
return bestMatch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
RepoManager.initialize()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import io.github.moulberry.repo.NEURepositoryException
|
|||||||
import io.github.moulberry.repo.data.NEUItem
|
import io.github.moulberry.repo.data.NEUItem
|
||||||
import io.github.moulberry.repo.data.NEURecipe
|
import io.github.moulberry.repo.data.NEURecipe
|
||||||
import io.github.moulberry.repo.data.Rarity
|
import io.github.moulberry.repo.data.Rarity
|
||||||
|
import java.nio.file.Path
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import net.minecraft.client.MinecraftClient
|
import net.minecraft.client.MinecraftClient
|
||||||
@@ -14,9 +15,11 @@ import moe.nea.firmament.Firmament
|
|||||||
import moe.nea.firmament.Firmament.logger
|
import moe.nea.firmament.Firmament.logger
|
||||||
import moe.nea.firmament.events.ReloadRegistrationEvent
|
import moe.nea.firmament.events.ReloadRegistrationEvent
|
||||||
import moe.nea.firmament.gui.config.ManagedConfig
|
import moe.nea.firmament.gui.config.ManagedConfig
|
||||||
|
import moe.nea.firmament.util.ErrorUtil
|
||||||
import moe.nea.firmament.util.MC
|
import moe.nea.firmament.util.MC
|
||||||
import moe.nea.firmament.util.MinecraftDispatcher
|
import moe.nea.firmament.util.MinecraftDispatcher
|
||||||
import moe.nea.firmament.util.SkyblockId
|
import moe.nea.firmament.util.SkyblockId
|
||||||
|
import moe.nea.firmament.util.TestUtil
|
||||||
import moe.nea.firmament.util.tr
|
import moe.nea.firmament.util.tr
|
||||||
|
|
||||||
object RepoManager {
|
object RepoManager {
|
||||||
@@ -49,29 +52,32 @@ object RepoManager {
|
|||||||
|
|
||||||
var recentlyFailedToUpdateItemList = false
|
var recentlyFailedToUpdateItemList = false
|
||||||
|
|
||||||
val neuRepo: NEURepository = NEURepository.of(RepoDownloadManager.repoSavedLocation).apply {
|
|
||||||
registerReloadListener(ItemCache)
|
|
||||||
registerReloadListener(ExpLadders)
|
|
||||||
registerReloadListener(ItemNameLookup)
|
|
||||||
ReloadRegistrationEvent.publish(ReloadRegistrationEvent(this))
|
|
||||||
registerReloadListener {
|
|
||||||
Firmament.coroutineScope.launch(MinecraftDispatcher) {
|
|
||||||
if (!trySendClientboundUpdateRecipesPacket()) {
|
|
||||||
logger.warn("Failed to issue a ClientboundUpdateRecipesPacket (to reload REI). This may lead to an outdated item list.")
|
|
||||||
recentlyFailedToUpdateItemList = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val essenceRecipeProvider = EssenceRecipeProvider()
|
val essenceRecipeProvider = EssenceRecipeProvider()
|
||||||
val recipeCache = BetterRepoRecipeCache(essenceRecipeProvider)
|
val recipeCache = BetterRepoRecipeCache(essenceRecipeProvider)
|
||||||
|
|
||||||
init {
|
fun makeNEURepository(path: Path): NEURepository {
|
||||||
neuRepo.registerReloadListener(essenceRecipeProvider)
|
return NEURepository.of(path).apply {
|
||||||
neuRepo.registerReloadListener(recipeCache)
|
registerReloadListener(ItemCache)
|
||||||
|
registerReloadListener(ExpLadders)
|
||||||
|
registerReloadListener(ItemNameLookup)
|
||||||
|
ReloadRegistrationEvent.publish(ReloadRegistrationEvent(this))
|
||||||
|
registerReloadListener {
|
||||||
|
if (TestUtil.isInTest) return@registerReloadListener
|
||||||
|
Firmament.coroutineScope.launch(MinecraftDispatcher) {
|
||||||
|
if (!trySendClientboundUpdateRecipesPacket()) {
|
||||||
|
logger.warn("Failed to issue a ClientboundUpdateRecipesPacket (to reload REI). This may lead to an outdated item list.")
|
||||||
|
recentlyFailedToUpdateItemList = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
registerReloadListener(essenceRecipeProvider)
|
||||||
|
registerReloadListener(recipeCache)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lateinit var neuRepo: NEURepository
|
||||||
|
private set
|
||||||
|
|
||||||
fun getAllRecipes() = neuRepo.items.items.values.asSequence().flatMap { it.recipes }
|
fun getAllRecipes() = neuRepo.items.items.values.asSequence().flatMap { it.recipes }
|
||||||
|
|
||||||
fun getRecipesFor(skyblockId: SkyblockId): Set<NEURecipe> = recipeCache.recipes[skyblockId] ?: setOf()
|
fun getRecipesFor(skyblockId: SkyblockId): Set<NEURecipe> = recipeCache.recipes[skyblockId] ?: setOf()
|
||||||
@@ -106,6 +112,11 @@ object RepoManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun reloadForTest(from: Path) {
|
||||||
|
neuRepo = makeNEURepository(from)
|
||||||
|
reload()
|
||||||
|
}
|
||||||
|
|
||||||
fun reload() {
|
fun reload() {
|
||||||
try {
|
try {
|
||||||
ItemCache.ReloadProgressHud.reportProgress("Reloading from Disk",
|
ItemCache.ReloadProgressHud.reportProgress("Reloading from Disk",
|
||||||
@@ -114,16 +125,24 @@ object RepoManager {
|
|||||||
ItemCache.ReloadProgressHud.isEnabled = true
|
ItemCache.ReloadProgressHud.isEnabled = true
|
||||||
neuRepo.reload()
|
neuRepo.reload()
|
||||||
} catch (exc: NEURepositoryException) {
|
} catch (exc: NEURepositoryException) {
|
||||||
|
ErrorUtil.softError("Failed to reload repository", exc)
|
||||||
MC.sendChat(
|
MC.sendChat(
|
||||||
tr("firmament.repo.reloadfail",
|
tr("firmament.repo.reloadfail",
|
||||||
"Failed to reload repository. This will result in some mod features not working.")
|
"Failed to reload repository. This will result in some mod features not working.")
|
||||||
)
|
)
|
||||||
ItemCache.ReloadProgressHud.isEnabled = false
|
ItemCache.ReloadProgressHud.isEnabled = false
|
||||||
exc.printStackTrace()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var wasInitialized = false
|
||||||
fun initialize() {
|
fun initialize() {
|
||||||
|
if (wasInitialized) return
|
||||||
|
wasInitialized = true
|
||||||
|
System.getProperty("firmament.testrepo")?.let { compTimeRepo ->
|
||||||
|
reloadForTest(Path.of(compTimeRepo))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
neuRepo = makeNEURepository(RepoDownloadManager.repoSavedLocation)
|
||||||
if (Config.autoUpdate) {
|
if (Config.autoUpdate) {
|
||||||
launchAsyncUpdate()
|
launchAsyncUpdate()
|
||||||
} else {
|
} else {
|
||||||
@@ -131,6 +150,12 @@ object RepoManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (TestUtil.isInTest) {
|
||||||
|
initialize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getPotentialStubPetData(skyblockId: SkyblockId): PetData? {
|
fun getPotentialStubPetData(skyblockId: SkyblockId): PetData? {
|
||||||
val parts = skyblockId.neuItem.split(";")
|
val parts = skyblockId.neuItem.split(";")
|
||||||
if (parts.size != 2) {
|
if (parts.size != 2) {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import moe.nea.firmament.Firmament
|
|||||||
@Suppress("NOTHING_TO_INLINE") // Suppressed since i want the logger to not pick up the ErrorUtil stack-frame
|
@Suppress("NOTHING_TO_INLINE") // Suppressed since i want the logger to not pick up the ErrorUtil stack-frame
|
||||||
object ErrorUtil {
|
object ErrorUtil {
|
||||||
var aggressiveErrors = run {
|
var aggressiveErrors = run {
|
||||||
Thread.currentThread().stackTrace.any { it.className.startsWith("org.junit.") } || Firmament.DEBUG
|
TestUtil.isInTest || Firmament.DEBUG
|
||||||
|| ErrorUtil::class.java.desiredAssertionStatus()
|
|| ErrorUtil::class.java.desiredAssertionStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ object MC {
|
|||||||
inline val handledScreen: HandledScreen<*>? get() = instance.currentScreen as? HandledScreen<*>
|
inline val handledScreen: HandledScreen<*>? get() = instance.currentScreen as? HandledScreen<*>
|
||||||
inline val window get() = instance.window
|
inline val window get() = instance.window
|
||||||
inline val currentRegistries: RegistryWrapper.WrapperLookup? get() = world?.registryManager
|
inline val currentRegistries: RegistryWrapper.WrapperLookup? get() = world?.registryManager
|
||||||
val defaultRegistries: RegistryWrapper.WrapperLookup = BuiltinRegistries.createWrapperLookup()
|
val defaultRegistries: RegistryWrapper.WrapperLookup by lazy { BuiltinRegistries.createWrapperLookup() }
|
||||||
inline val currentOrDefaultRegistries get() = currentRegistries ?: defaultRegistries
|
inline val currentOrDefaultRegistries get() = currentRegistries ?: defaultRegistries
|
||||||
val defaultItems: RegistryWrapper.Impl<Item> = defaultRegistries.getOrThrow(RegistryKeys.ITEM)
|
val defaultItems: RegistryWrapper.Impl<Item> = defaultRegistries.getOrThrow(RegistryKeys.ITEM)
|
||||||
var lastWorld: World? = null
|
var lastWorld: World? = null
|
||||||
|
|||||||
5
src/main/kotlin/util/TestUtil.kt
Normal file
5
src/main/kotlin/util/TestUtil.kt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package moe.nea.firmament.util
|
||||||
|
|
||||||
|
object TestUtil {
|
||||||
|
val isInTest = Thread.currentThread().stackTrace.any { it.className.startsWith("org.junit.") }
|
||||||
|
}
|
||||||
@@ -60,8 +60,13 @@ object SackUtil {
|
|||||||
@Subscribe
|
@Subscribe
|
||||||
fun updateFromChat(event: ProcessChatEvent) {
|
fun updateFromChat(event: ProcessChatEvent) {
|
||||||
if (!event.unformattedString.startsWith("[Sacks]")) return
|
if (!event.unformattedString.startsWith("[Sacks]")) return
|
||||||
|
getUpdatesFromMessage(event.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getUpdatesFromMessage(text: Text): List<SackUpdate> {
|
||||||
val update = ChatUpdate()
|
val update = ChatUpdate()
|
||||||
event.text.siblings.forEach(update::updateFromHoverText)
|
text.siblings.forEach(update::updateFromHoverText)
|
||||||
|
return update.updates
|
||||||
}
|
}
|
||||||
|
|
||||||
data class SackUpdate(
|
data class SackUpdate(
|
||||||
|
|||||||
10
src/main/kotlin/util/skyblock/SkyBlockItems.kt
Normal file
10
src/main/kotlin/util/skyblock/SkyBlockItems.kt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package moe.nea.firmament.util.skyblock
|
||||||
|
|
||||||
|
import moe.nea.firmament.util.SkyblockId
|
||||||
|
|
||||||
|
object SkyBlockItems {
|
||||||
|
val ROTTEN_FLESH = SkyblockId("ROTTEN_FLESH")
|
||||||
|
val ENCHANTED_DIAMOND = SkyblockId("ENCHANTED_DIAMOND")
|
||||||
|
val DIAMOND = SkyblockId("DIAMOND")
|
||||||
|
val ANCESTRAL_SPADE = SkyblockId("ANCESTRAL_SPADE")
|
||||||
|
}
|
||||||
29
src/test/kotlin/util/skyblock/SackUtilTest.kt
Normal file
29
src/test/kotlin/util/skyblock/SackUtilTest.kt
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package moe.nea.firmament.test.util.skyblock
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import moe.nea.firmament.test.testutil.ItemResources
|
||||||
|
import moe.nea.firmament.util.skyblock.SackUtil
|
||||||
|
import moe.nea.firmament.util.skyblock.SkyBlockItems
|
||||||
|
|
||||||
|
class SackUtilTest {
|
||||||
|
@Test
|
||||||
|
fun testOneRottenFlesh() {
|
||||||
|
Assertions.assertEquals(
|
||||||
|
listOf(
|
||||||
|
SackUtil.SackUpdate(SkyBlockItems.ROTTEN_FLESH, "Rotten Flesh", 1)
|
||||||
|
),
|
||||||
|
SackUtil.getUpdatesFromMessage(ItemResources.loadText("sacks/gain-rotten-flesh"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testAFewRegularItems() {
|
||||||
|
Assertions.assertEquals(
|
||||||
|
listOf(
|
||||||
|
SackUtil.SackUpdate(SkyBlockItems.ROTTEN_FLESH, "Rotten Flesh", 1)
|
||||||
|
),
|
||||||
|
SackUtil.getUpdatesFromMessage(ItemResources.loadText("sacks/gain-and-lose-regular"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user