blob: 6e497efcae3e8b277dae9bd78b4ba44894827c5a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
package at.hannibal2.skyhanni.test.hotswap
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.utils.ChatUtils
import at.hannibal2.skyhanni.utils.DelayedRun
import at.hannibal2.skyhanni.utils.ReflectionUtils.makeAccessible
import at.hannibal2.skyhanni.utils.ReflectionUtils.removeFinal
import moe.nea.hotswapagentforge.forge.ClassDefinitionEvent
import moe.nea.hotswapagentforge.forge.HotswapEvent
import moe.nea.hotswapagentforge.forge.HotswapFinishedEvent
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class HotswapSupportImpl : HotswapSupportHandle {
override fun load() {
MinecraftForge.EVENT_BUS.register(this)
println("Hotswap Client in Skyhanni loaded")
}
@SubscribeEvent
fun onHotswapClass(event: ClassDefinitionEvent.Redefinition) {
val instance = SkyHanniMod.modules.find { it.javaClass.name == event.fullyQualifiedName } ?: return
val primaryConstructor = runCatching { instance.javaClass.getDeclaredConstructor() }.getOrNull()
DelayedRun.onThread.execute {
ChatUtils.chat("Refreshing event subscriptions for module $instance!")
MinecraftForge.EVENT_BUS.unregister(instance)
if (primaryConstructor == null) {
MinecraftForge.EVENT_BUS.register(instance)
} else {
SkyHanniMod.modules.remove(instance)
primaryConstructor.isAccessible = true
val newInstance = primaryConstructor.newInstance()
ChatUtils.chat("Reconstructing $instance -> $newInstance!")
val instanceField = runCatching { instance.javaClass.getDeclaredField("INSTANCE") }.getOrNull()
?.takeIf { it.type == instance.javaClass }
?.makeAccessible()
?.removeFinal()
if (instanceField != null) {
ChatUtils.chat("Re-injected static instance $newInstance!")
instanceField.set(null, newInstance)
}
SkyHanniMod.modules.add(newInstance)
MinecraftForge.EVENT_BUS.register(newInstance)
}
}
}
@SubscribeEvent
fun onHotswapDetected(event: HotswapFinishedEvent) {
ChatUtils.chat("Hotswap finished!")
}
override fun isLoaded(): Boolean {
return HotswapEvent.isReady()
}
}
|