Skip to content

Commit d1b41a6

Browse files
author
Administrator
committed
fix fancyholograms
1 parent 0e16b87 commit d1b41a6

3 files changed

Lines changed: 30 additions & 197 deletions

File tree

build.gradle.kts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ repositories {
3535
dependencies {
3636
compileOnly("org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT")
3737
compileOnly(kotlin("stdlib"))
38+
compileOnly(fileTree("libs") {
39+
include("*.jar")
40+
})
3841
}
3942

4043
tasks.withType<JavaCompile> {
@@ -81,4 +84,4 @@ tasks.register("publishMatrixApi") {
8184
group = "publishing"
8285
description = "Publish MatrixLib API artifact to the shared local repository."
8386
dependsOn("publishAllPublicationsToMatrixPublicRepository")
84-
}
87+
}

libs/FancyHolograms-2.9.1.jar

1.02 MB
Binary file not shown.
Lines changed: 26 additions & 196 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
package com.y54895.matrixlib.api.hologram.internal
22

3+
import de.oliver.fancyholograms.api.FancyHologramsPlugin
4+
import de.oliver.fancyholograms.api.data.TextHologramData
5+
import de.oliver.fancyholograms.api.hologram.Hologram
36
import org.bukkit.Bukkit
47
import org.bukkit.Location
5-
import org.bukkit.plugin.Plugin
68
import taboolib.common.platform.function.warning
7-
import java.lang.reflect.Constructor
8-
import java.lang.reflect.Method
9-
import java.lang.reflect.Modifier
10-
import java.util.Optional
119
import java.util.concurrent.ConcurrentHashMap
1210

13-
internal class FancyHologramsAdapter private constructor(
14-
private val bridge: ApiBridge
15-
) : MatrixHologramAdapter {
11+
internal class FancyHologramsAdapter : MatrixHologramAdapter {
1612

1713
override val name: String = "FancyHolograms"
1814

19-
private val holograms = ConcurrentHashMap<String, Any>()
15+
private val holograms = ConcurrentHashMap<String, Hologram>()
16+
private val hologramManager = FancyHologramsPlugin.get().hologramManager
2017

2118
override fun createOrUpdate(entry: MatrixRenderedHologram) {
2219
if (entry.lines.isEmpty()) {
@@ -31,12 +28,13 @@ internal class FancyHologramsAdapter private constructor(
3128
}
3229

3330
runCatching {
34-
val hologramData = bridge.getDataMethod.invoke(hologram) ?: return@runCatching
35-
bridge.setLocationMethod.invoke(hologramData, entry.location)
36-
bridge.setTextMethod.invoke(hologramData, entry.lines)
37-
bridge.forceUpdateMethod.invoke(hologram)
38-
bridge.queueUpdateMethod.invoke(hologram)
39-
bridge.refreshForViewersMethod?.invoke(hologram)
31+
val hologramData = hologram.data
32+
hologramData.setLocation(entry.location)
33+
if (hologramData is TextHologramData) {
34+
hologramData.setText(entry.lines)
35+
}
36+
hologram.forceUpdate()
37+
hologram.queueUpdate()
4038
holograms[entry.qualifiedId] = hologram
4139
}.onFailure {
4240
warning("MatrixLib failed to update FancyHolograms hologram ${entry.qualifiedId}: ${it.message}")
@@ -46,14 +44,10 @@ internal class FancyHologramsAdapter private constructor(
4644
}
4745

4846
override fun remove(qualifiedId: String) {
49-
val manager = manager() ?: return
5047
val hologram = holograms.remove(qualifiedId) ?: findHologram(qualifiedId)
5148
runCatching {
52-
when {
53-
bridge.removeByNameMethod != null -> bridge.removeByNameMethod.invoke(manager, qualifiedId)
54-
hologram != null && bridge.removeByHologramMethod != null -> {
55-
bridge.removeByHologramMethod.invoke(manager, hologram)
56-
}
49+
if (hologram != null) {
50+
hologramManager.removeHologram(hologram)
5751
}
5852
}.onFailure {
5953
warning("MatrixLib failed to remove FancyHolograms hologram $qualifiedId: ${it.message}")
@@ -66,36 +60,23 @@ internal class FancyHologramsAdapter private constructor(
6660
}
6761

6862
private fun create(entry: MatrixRenderedHologram) {
69-
val manager = manager() ?: return
7063
runCatching {
71-
val hologramData = bridge.textHologramDataConstructor.newInstance(entry.qualifiedId, entry.location)
72-
bridge.setTextMethod.invoke(hologramData, entry.lines)
64+
val hologramData = TextHologramData(entry.qualifiedId, entry.location)
65+
hologramData.setText(entry.lines)
7366

74-
val hologram = bridge.createMethod.invoke(manager, hologramData) ?: return@runCatching
75-
bridge.setPersistent(hologram, hologramData)
76-
bridge.addHologramMethod.invoke(manager, hologram)
77-
bridge.forceUpdateMethod.invoke(hologram)
78-
bridge.queueUpdateMethod.invoke(hologram)
79-
bridge.refreshForViewersMethod?.invoke(hologram)
67+
val hologram = hologramManager.create(hologramData) ?: return@runCatching
68+
hologramManager.addHologram(hologram)
69+
hologram.forceUpdate()
70+
hologram.queueUpdate()
8071
holograms[entry.qualifiedId] = hologram
8172
}.onFailure {
8273
warning("MatrixLib failed to create FancyHolograms hologram ${entry.qualifiedId}: ${it.message}")
8374
}
8475
}
8576

86-
private fun manager(): Any? {
77+
private fun findHologram(id: String): Hologram? {
8778
return runCatching {
88-
bridge.hologramManagerGetter.invoke(bridge.managerOwner)
89-
}.getOrNull()
90-
}
91-
92-
private fun findHologram(id: String): Any? {
93-
val manager = manager() ?: return null
94-
return runCatching {
95-
when (val result = bridge.getHologramMethod.invoke(manager, id)) {
96-
is Optional<*> -> result.orElse(null)
97-
else -> result
98-
}
79+
hologramManager.getHologram(id).orElse(null)
9980
}.getOrNull()
10081
}
10182

@@ -105,162 +86,11 @@ internal class FancyHologramsAdapter private constructor(
10586
val plugin = Bukkit.getPluginManager().getPlugin("FancyHolograms")
10687
?.takeIf { it.isEnabled } ?: return null
10788

108-
val bridge = listOf(
109-
PackageLayout(
110-
basePackage = "de.oliver.fancyholograms",
111-
apiPackage = "de.oliver.fancyholograms.api"
112-
),
113-
PackageLayout(
114-
basePackage = "com.fancyinnovations.fancyholograms",
115-
apiPackage = "com.fancyinnovations.fancyholograms.api"
116-
)
117-
).firstNotNullOfOrNull { layout ->
118-
buildBridge(plugin, layout)
119-
}
120-
121-
if (bridge == null) {
122-
warning("MatrixLib could not resolve a compatible FancyHolograms API bridge.")
123-
return null
124-
}
125-
return FancyHologramsAdapter(bridge)
126-
}
127-
128-
private fun buildBridge(plugin: Plugin, layout: PackageLayout): ApiBridge? {
129-
val loader = plugin.javaClass.classLoader
130-
13189
return runCatching {
132-
val textHologramDataClass = Class.forName("${layout.apiPackage}.data.TextHologramData", false, loader)
133-
val hologramClass = Class.forName("${layout.apiPackage}.hologram.Hologram", false, loader)
134-
val hologramDataClass = Class.forName("${layout.apiPackage}.data.HologramData", false, loader)
135-
136-
val managerOwner = resolveManagerOwner(plugin, layout.basePackage, loader)
137-
val hologramManagerGetter = managerOwner.javaClass.methods.firstOrNull { method ->
138-
method.name == "getHologramManager" && method.parameterCount == 0
139-
} ?: throw IllegalStateException("getHologramManager() is not available")
140-
val managerClass = hologramManagerGetter.returnType
141-
142-
val getHologramMethod = managerClass.getMethod("getHologram", String::class.java)
143-
val createMethod = managerClass.methods.first { method ->
144-
method.name == "create" &&
145-
method.parameterCount == 1 &&
146-
method.parameterTypes[0].isAssignableFrom(hologramDataClass)
147-
}
148-
val addHologramMethod = managerClass.methods.first { method ->
149-
method.name == "addHologram" &&
150-
method.parameterCount == 1 &&
151-
method.parameterTypes[0].isAssignableFrom(hologramClass)
152-
}
153-
val removeByNameMethod = managerClass.methods.firstOrNull { method ->
154-
method.name == "removeHologram" &&
155-
method.parameterCount == 1 &&
156-
method.parameterTypes[0] == String::class.java
157-
}
158-
val removeByHologramMethod = managerClass.methods.firstOrNull { method ->
159-
method.name == "removeHologram" &&
160-
method.parameterCount == 1 &&
161-
method.parameterTypes[0].isAssignableFrom(hologramClass)
162-
}
163-
164-
val textHologramDataConstructor = textHologramDataClass.getConstructor(
165-
String::class.java,
166-
Location::class.java
167-
)
168-
val setTextMethod = textHologramDataClass.methods.first { method ->
169-
method.name == "setText" && method.parameterCount == 1
170-
}
171-
val setLocationMethod = hologramDataClass.getMethod("setLocation", Location::class.java)
172-
val getDataMethod = hologramClass.getMethod("getData")
173-
val queueUpdateMethod = hologramClass.getMethod("queueUpdate")
174-
val forceUpdateMethod = hologramClass.getMethod("forceUpdate")
175-
val refreshForViewersMethod = hologramClass.methods.firstOrNull { method ->
176-
method.name == "refreshForViewers" && method.parameterCount == 0
177-
}
178-
val setPersistentOnHologramMethod = hologramClass.methods.firstOrNull { method ->
179-
method.name == "setPersistent" &&
180-
method.parameterCount == 1 &&
181-
isBooleanParameter(method)
182-
}
183-
val setPersistentOnDataMethod = hologramDataClass.methods.firstOrNull { method ->
184-
method.name == "setPersistent" &&
185-
method.parameterCount == 1 &&
186-
isBooleanParameter(method)
187-
}
188-
189-
ApiBridge(
190-
managerOwner = managerOwner,
191-
hologramManagerGetter = hologramManagerGetter,
192-
getHologramMethod = getHologramMethod,
193-
createMethod = createMethod,
194-
addHologramMethod = addHologramMethod,
195-
removeByNameMethod = removeByNameMethod,
196-
removeByHologramMethod = removeByHologramMethod,
197-
textHologramDataConstructor = textHologramDataConstructor,
198-
setTextMethod = setTextMethod,
199-
setLocationMethod = setLocationMethod,
200-
getDataMethod = getDataMethod,
201-
queueUpdateMethod = queueUpdateMethod,
202-
forceUpdateMethod = forceUpdateMethod,
203-
refreshForViewersMethod = refreshForViewersMethod,
204-
setPersistentOnHologramMethod = setPersistentOnHologramMethod,
205-
setPersistentOnDataMethod = setPersistentOnDataMethod
206-
)
90+
FancyHologramsAdapter()
20791
}.onFailure {
208-
warning("MatrixLib FancyHolograms bootstrap failed for ${layout.apiPackage}: ${it.message}")
92+
warning("MatrixLib FancyHolograms bootstrap failed: ${it.message}")
20993
}.getOrNull()
21094
}
211-
212-
private fun resolveManagerOwner(plugin: Plugin, basePackage: String, loader: ClassLoader): Any {
213-
val pluginSingleton = listOf(
214-
"$basePackage.FancyHologramsPlugin",
215-
"$basePackage.FancyHolograms"
216-
).firstNotNullOfOrNull { className ->
217-
runCatching { Class.forName(className, false, loader) }.getOrNull()
218-
?.methods
219-
?.firstOrNull { method ->
220-
method.name == "get" &&
221-
method.parameterCount == 0 &&
222-
Modifier.isStatic(method.modifiers)
223-
}
224-
?.let { method -> runCatching { method.invoke(null) }.getOrNull() }
225-
}
226-
return pluginSingleton ?: plugin
227-
}
228-
229-
private fun isBooleanParameter(method: Method): Boolean {
230-
val parameterType = method.parameterTypes.singleOrNull() ?: return false
231-
return parameterType == Boolean::class.javaPrimitiveType || parameterType == Boolean::class.javaObjectType
232-
}
233-
}
234-
235-
private data class PackageLayout(
236-
val basePackage: String,
237-
val apiPackage: String
238-
)
239-
240-
private data class ApiBridge(
241-
val managerOwner: Any,
242-
val hologramManagerGetter: Method,
243-
val getHologramMethod: Method,
244-
val createMethod: Method,
245-
val addHologramMethod: Method,
246-
val removeByNameMethod: Method?,
247-
val removeByHologramMethod: Method?,
248-
val textHologramDataConstructor: Constructor<*>,
249-
val setTextMethod: Method,
250-
val setLocationMethod: Method,
251-
val getDataMethod: Method,
252-
val queueUpdateMethod: Method,
253-
val forceUpdateMethod: Method,
254-
val refreshForViewersMethod: Method?,
255-
val setPersistentOnHologramMethod: Method?,
256-
val setPersistentOnDataMethod: Method?
257-
) {
258-
259-
fun setPersistent(hologram: Any, hologramData: Any) {
260-
when {
261-
setPersistentOnHologramMethod != null -> setPersistentOnHologramMethod.invoke(hologram, false)
262-
setPersistentOnDataMethod != null -> setPersistentOnDataMethod.invoke(hologramData, false)
263-
}
264-
}
26595
}
266-
}
96+
}

0 commit comments

Comments
 (0)