11package 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
36import org.bukkit.Bukkit
47import org.bukkit.Location
5- import org.bukkit.plugin.Plugin
68import 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
119import 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