blob: e70c382798a12b11f36bc63143fb228c9fea0190 (
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
package moe.nea.firmament.util
import io.github.moulberry.repo.data.Coordinate
import io.github.notenoughupdates.moulconfig.platform.MoulConfigScreenComponent
import java.util.concurrent.ConcurrentLinkedQueue
import kotlin.jvm.optionals.getOrNull
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.Gui
import net.minecraft.client.gui.screens.Screen
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen
import net.minecraft.client.player.LocalPlayer
import net.minecraft.client.renderer.GameRenderer
import net.minecraft.client.renderer.LevelRenderer
import net.minecraft.client.renderer.entity.ItemRenderer
import net.minecraft.client.multiplayer.ClientLevel
import net.minecraft.world.entity.Entity
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraft.nbt.NbtOps
import net.minecraft.network.protocol.game.ServerboundChatCommandPacket
import net.minecraft.data.registries.VanillaRegistries
import net.minecraft.core.Registry
import net.minecraft.resources.ResourceKey
import net.minecraft.core.registries.Registries
import net.minecraft.resources.RegistryOps
import net.minecraft.core.HolderLookup
import net.minecraft.server.packs.resources.ReloadableResourceManager
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.Util
import net.minecraft.core.BlockPos
import net.minecraft.world.level.Level
import moe.nea.firmament.Firmament
import moe.nea.firmament.events.TickEvent
import moe.nea.firmament.events.WorldReadyEvent
import moe.nea.firmament.util.mc.TolerantRegistriesOps
object MC {
private val messageQueue = ConcurrentLinkedQueue<Component>()
init {
TickEvent.subscribe("MC:push") {
if (inGameHud.chat != null && world != null)
while (true) {
inGameHud.chat.addMessage(messageQueue.poll() ?: break)
}
while (true) {
(nextTickTodos.poll() ?: break).invoke()
}
}
WorldReadyEvent.subscribe("MC:ready") {
this.lastWorld
}
}
fun sendChat(text: Component) {
if (TestUtil.isInTest) {
Firmament.logger.info("CHAT: ${text.string}")
return
}
if (instance.isSameThread && inGameHud.chat != null && world != null)
inGameHud.chat.addMessage(text)
else
messageQueue.add(text)
}
@Deprecated("Use checked method instead", replaceWith = ReplaceWith("sendCommand(command)"))
fun sendServerCommand(command: String) {
val nh = player?.connection ?: return
nh.send(
ServerboundChatCommandPacket(
command,
)
)
}
fun sendServerChat(text: String) {
player?.connection?.sendChat(text)
}
fun sendCommand(command: String) {
// TODO: add a queue to this and sendServerChat
ErrorUtil.softCheck("Server commands have an implied /", !command.startsWith("/"))
player?.connection?.sendCommand(command)
}
fun onMainThread(block: () -> Unit) {
if (instance.isSameThread)
block()
else
instance.schedule(block)
}
private val nextTickTodos = ConcurrentLinkedQueue<() -> Unit>()
fun nextTick(function: () -> Unit) {
nextTickTodos.add(function)
}
inline val resourceManager get() = (instance.resourceManager as ReloadableResourceManager)
inline val itemRenderer: ItemRenderer get() = instance.itemRenderer
inline val worldRenderer: LevelRenderer get() = instance.levelRenderer
inline val gameRenderer: GameRenderer get() = instance.gameRenderer
inline val networkHandler get() = player?.connection
inline val instance get() = Minecraft.getInstance()
inline val keyboard get() = instance.keyboardHandler
inline val interactionManager get() = instance.gameMode
inline val textureManager get() = instance.textureManager
inline val options get() = instance.options
inline val inGameHud: Gui get() = instance.gui
inline val font get() = instance.font
inline val soundManager get() = instance.soundManager
inline val player: LocalPlayer? get() = TestUtil.unlessTesting { instance.player }
inline val camera: Entity? get() = instance.cameraEntity
inline val stackInHand: ItemStack get() = player?.mainHandItem ?: ItemStack.EMPTY
inline val world: ClientLevel? get() = TestUtil.unlessTesting { instance.level }
inline val playerName: String get() = player?.name?.unformattedString ?: MC.instance.user.name
inline var screen: Screen?
get() = TestUtil.unlessTesting { instance.screen }
set(value) = instance.setScreen(value)
val screenName get() = screen?.title?.unformattedString?.trim()
inline val handledScreen: AbstractContainerScreen<*>? get() = instance.screen as? AbstractContainerScreen<*>
inline val window get() = instance.window
inline val currentRegistries: HolderLookup.Provider? get() = world?.registryAccess()
val defaultRegistries: HolderLookup.Provider by lazy { VanillaRegistries.createLookup() }
val defaultRegistryNbtOps by lazy { RegistryOps.create(NbtOps.INSTANCE, defaultRegistries) }
inline val currentOrDefaultRegistries get() = currentRegistries ?: defaultRegistries
val currentOrDefaultRegistryNbtOps get() = TolerantRegistriesOps(NbtOps.INSTANCE, currentOrDefaultRegistries)
val defaultItems: HolderLookup.RegistryLookup<Item> by lazy { defaultRegistries.lookupOrThrow(Registries.ITEM) }
var currentTick = 0
var lastWorld: Level? = null
get() {
field = world ?: field
return field
}
private set
val currentMoulConfigContext
get() = (screen as? MoulConfigScreenComponent)?.guiContext
fun openUrl(uri: String) {
Util.getPlatform().openUri(uri)
}
fun <T> unsafeGetRegistryEntry(registry: ResourceKey<out Registry<T>>, identifier: ResourceLocation) =
unsafeGetRegistryEntry(ResourceKey.create(registry, identifier))
fun <T> unsafeGetRegistryEntry(registryKey: ResourceKey<T>): T? {
return currentOrDefaultRegistries
.lookupOrThrow(registryKey.registryKey())
.get(registryKey)
.getOrNull()
?.value()
}
}
val Coordinate.blockPos: BlockPos
get() = BlockPos(x, y, z)
|