From e5c22fa8eec995cd2e5c1857dd489f991cca60f0 Mon Sep 17 00:00:00 2001 From: stephen seaton-blanchard Date: Wed, 25 Sep 2024 11:23:18 -0500 Subject: [PATCH 1/3] Updates plugins Adds support for a default icon --- .gitignore | 34 +++++++++++++++++++ build.gradle.kts | 7 ++-- .../signmarkers/watcher/SignWatcher.java | 33 ++++++++++-------- src/main/resources/plugin.yml | 2 +- 4 files changed, 58 insertions(+), 18 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e02ceaf --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +### Java template +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +### Example user template template +### Example user template + +# IntelliJ project files +.idea +*.iml +out +gen diff --git a/build.gradle.kts b/build.gradle.kts index 4eab542..c27a64b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,10 +6,10 @@ plugins { group = "dev.kugge" -version = "0.0.1" +version = "0.0.2" java { - toolchain.languageVersion.set(JavaLanguageVersion.of(17)) + toolchain.languageVersion.set(JavaLanguageVersion.of(21)) } repositories { @@ -18,11 +18,12 @@ repositories { maven("https://jitpack.io") maven("https://oss.sonatype.org/content/groups/public/") maven("https://papermc.io/repo/repository/maven-public/") + maven("https://repo.bluecolored.de/releases") } dependencies { compileOnly("dev.folia:folia-api:1.19.4-R0.1-SNAPSHOT") - compileOnly("com.github.BlueMap-Minecraft:BlueMapAPI:v2.4.0") + compileOnly ("de.bluecolored.bluemap:BlueMapAPI:2.7.2") } tasks.compileJava { diff --git a/src/main/java/dev/kugge/signmarkers/watcher/SignWatcher.java b/src/main/java/dev/kugge/signmarkers/watcher/SignWatcher.java index 6fcafd9..04e8883 100644 --- a/src/main/java/dev/kugge/signmarkers/watcher/SignWatcher.java +++ b/src/main/java/dev/kugge/signmarkers/watcher/SignWatcher.java @@ -10,6 +10,7 @@ import org.bukkit.event.block.SignChangeEvent; import com.flowpowered.math.vector.Vector3d; import com.flowpowered.math.vector.Vector2i; + import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; @@ -18,26 +19,30 @@ public class SignWatcher implements Listener { @EventHandler public void onSignWrite(SignChangeEvent event) { + // Check for existing sign at position xyz and delete it Component header = event.line(0); if (header == Component.empty() || header == null) return; if (!header.toString().contains("[map]")) return; + // Don't require a line 3, in fact require a secondary tag and loop through for tags hell have defaults for [text] [poi] [map] etc. Component cicon = event.line(3); if (cicon == Component.empty() || cicon == null) return; String icon = "./markers/" + LegacyComponentSerializer.legacySection().serialize(cicon) + ".png"; File iconFile = new File(SignMarkers.webRoot + "/" + icon); - if (!iconFile.exists()) return; - - Vector2i anchor; - try { - BufferedImage image = ImageIO.read(iconFile); - int width = image.getWidth(); - int height = image.getHeight(); - anchor = new Vector2i(height/2, width/2); - } catch (IOException e) { - e.printStackTrace(); - return; + Vector2i anchor = new Vector2i(25, 45); + if (!iconFile.exists()) { + icon = "./assets/poi.svg"; + } else { + try { + BufferedImage image = ImageIO.read(iconFile); + int width = image.getWidth(); + int height = image.getHeight(); + anchor = new Vector2i(height / 2, width / 2); + } catch (IOException e) { + e.printStackTrace(); + return; + } } Component clabel1 = event.line(1); @@ -45,16 +50,16 @@ public void onSignWrite(SignChangeEvent event) { Component clabel2 = event.line(2); String label = LegacyComponentSerializer.legacySection().serialize(clabel1) - + LegacyComponentSerializer.legacySection().serialize(clabel2); + + LegacyComponentSerializer.legacySection().serialize(clabel2); Block block = event.getBlock(); Vector3d pos = new Vector3d(block.getX(), block.getY(), block.getZ()); String id = "marker-" + pos.getX() + "-" + pos.getY() + "-" + pos.getZ(); - POIMarker marker = POIMarker.builder().label(label).position(pos).icon(icon, anchor).maxDistance(100000).build(); + POIMarker marker = new POIMarker(label, pos, icon, anchor); SignMarkers.markerSet.get(block.getWorld()).put(id, marker); - // Delete [map] and icon lines + // Leave [Map] and Icon in but don't add them to marker event.line(0, Component.empty()); event.line(3, Component.empty()); } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 565cc36..9cc35cd 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: BlueMapSignMarkers version: ${version} main: dev.kugge.signmarkers.SignMarkers -api-version: 1.19 +api-version: 1.21.1 folia-supported: true authors: [kugge] depend: [BlueMap] From 19f9ab07dd534c7541a66bf2886c1749e6d12d21 Mon Sep 17 00:00:00 2001 From: stephen seaton-blanchard Date: Sun, 29 Sep 2024 21:26:35 -0500 Subject: [PATCH 2/3] Rename .java to .kt --- .../signmarkers/watcher/{SignWatcher.java => SignWatcher.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/java/dev/kugge/signmarkers/watcher/{SignWatcher.java => SignWatcher.kt} (100%) diff --git a/src/main/java/dev/kugge/signmarkers/watcher/SignWatcher.java b/src/main/java/dev/kugge/signmarkers/watcher/SignWatcher.kt similarity index 100% rename from src/main/java/dev/kugge/signmarkers/watcher/SignWatcher.java rename to src/main/java/dev/kugge/signmarkers/watcher/SignWatcher.kt From 1b0ee53c55e599c5b57e3adf66e9f8fc4668d5dd Mon Sep 17 00:00:00 2001 From: stephen seaton-blanchard Date: Sun, 29 Sep 2024 21:26:35 -0500 Subject: [PATCH 3/3] Made a bit of a refactor --- build.gradle.kts | 28 ++++- settings.gradle | 8 +- .../dev/kugge/signmarkers/SignMarkers.java | 74 ++++++++++--- .../java/dev/kugge/signmarkers/models/Tag.kt | 8 ++ .../dev/kugge/signmarkers/models/TagList.kt | 15 +++ .../kugge/signmarkers/util/AvailableTags.kt | 7 ++ .../kugge/signmarkers/util/MarkerFactory.kt | 44 ++++++++ .../kugge/signmarkers/util/MarkerManager.kt | 26 +++++ .../dev/kugge/signmarkers/util/TagFactory.kt | 23 ++++ .../watcher/SignDestroyWatcher.java | 30 ------ .../kugge/signmarkers/watcher/SignWatcher.kt | 101 ++++++++---------- src/main/resources/farm.svg | 1 + src/main/resources/house.svg | 1 + src/main/resources/monster.svg | 1 + src/main/resources/views/header.html | 3 + .../kugge/signmarkers/util/TagFactoryTest.kt | 28 +++++ .../kugge/signmarkers/watcher/SignWatcher.kt | 23 ++++ 17 files changed, 317 insertions(+), 104 deletions(-) create mode 100644 src/main/java/dev/kugge/signmarkers/models/Tag.kt create mode 100644 src/main/java/dev/kugge/signmarkers/models/TagList.kt create mode 100644 src/main/java/dev/kugge/signmarkers/util/AvailableTags.kt create mode 100644 src/main/java/dev/kugge/signmarkers/util/MarkerFactory.kt create mode 100644 src/main/java/dev/kugge/signmarkers/util/MarkerManager.kt create mode 100644 src/main/java/dev/kugge/signmarkers/util/TagFactory.kt delete mode 100644 src/main/java/dev/kugge/signmarkers/watcher/SignDestroyWatcher.java create mode 100644 src/main/resources/farm.svg create mode 100644 src/main/resources/house.svg create mode 100644 src/main/resources/monster.svg create mode 100644 src/main/resources/views/header.html create mode 100644 src/test/java/dev/kugge/signmarkers/util/TagFactoryTest.kt create mode 100644 src/test/java/dev/kugge/signmarkers/watcher/SignWatcher.kt diff --git a/build.gradle.kts b/build.gradle.kts index c27a64b..1ef3f59 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,12 +1,17 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21 + plugins { `java-library` id("com.github.johnrengelman.shadow") version "8.0.0" id("xyz.jpenilla.run-paper") version "2.0.1" + id("idea") + kotlin("jvm") } group = "dev.kugge" -version = "0.0.2" +version = "0.0.3" java { toolchain.languageVersion.set(JavaLanguageVersion.of(21)) @@ -15,20 +20,29 @@ java { repositories { mavenLocal() mavenCentral() + maven("https://repo.bluecolored.de/releases") maven("https://jitpack.io") maven("https://oss.sonatype.org/content/groups/public/") maven("https://papermc.io/repo/repository/maven-public/") - maven("https://repo.bluecolored.de/releases") } dependencies { compileOnly("dev.folia:folia-api:1.19.4-R0.1-SNAPSHOT") compileOnly ("de.bluecolored.bluemap:BlueMapAPI:2.7.2") + implementation("net.pwall.mustache:kotlin-mustache:0.12") + implementation(kotlin("stdlib")) + testImplementation(platform("org.junit:junit-bom:5.11.1")) + testImplementation("org.junit.jupiter:junit-jupiter") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") + testImplementation("org.mockito:mockito-core:3.+") + testImplementation("net.kyori:adventure-api:4.13.0") + testImplementation("dev.folia:folia-api:1.19.4-R0.1-SNAPSHOT") + testImplementation ("de.bluecolored.bluemap:BlueMapAPI:2.7.2") } tasks.compileJava { options.encoding = Charsets.UTF_8.name() - options.release.set(17) + options.release.set(21) } tasks.processResources { @@ -37,6 +51,7 @@ tasks.processResources { tasks.shadowJar { archiveFileName.set("SignMarkers-${project.version}.jar") + mergeServiceFiles() } tasks.jar { @@ -46,3 +61,10 @@ tasks.jar { tasks.assemble { dependsOn(tasks.shadowJar) } + +tasks.test { + useJUnitPlatform() + testLogging { + events("passed", "skipped", "failed") + } +} diff --git a/settings.gradle b/settings.gradle index f1e5cc8..1806463 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,6 @@ -rootProject.name = 'BlueMapSignMarkers' - +pluginManagement { + plugins { + id 'org.jetbrains.kotlin.jvm' version '2.0.20' + } +} +rootProject.name = 'BlueMapSignMarkers' \ No newline at end of file diff --git a/src/main/java/dev/kugge/signmarkers/SignMarkers.java b/src/main/java/dev/kugge/signmarkers/SignMarkers.java index 791fd8a..2544854 100644 --- a/src/main/java/dev/kugge/signmarkers/SignMarkers.java +++ b/src/main/java/dev/kugge/signmarkers/SignMarkers.java @@ -4,13 +4,13 @@ import de.bluecolored.bluemap.api.BlueMapMap; import de.bluecolored.bluemap.api.gson.MarkerGson; import de.bluecolored.bluemap.api.markers.MarkerSet; -import dev.kugge.signmarkers.watcher.SignDestroyWatcher; import dev.kugge.signmarkers.watcher.SignWatcher; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.plugin.java.JavaPlugin; import java.io.*; +import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -32,9 +32,35 @@ public void onEnable() { loadWorldMarkerSet(world); registerWorld(world); } - BlueMapAPI.onEnable(api -> webRoot = api.getWebApp().getWebRoot()); + BlueMapAPI.onEnable(api -> { + // This is a path object + webRoot = api.getWebApp().getWebRoot(); + // Add images in resources to webRoot/assets/ + + // Target directory for assets + Path assetsDir = webRoot.resolve("assets/SignMarkers"); + + // Ensure the assets directory exists + try { + if (!Files.exists(assetsDir)) { + Files.createDirectories(assetsDir); + } + } catch (IOException e) { + e.printStackTrace(); + return; + } + + // Add images from resources to the assets directory + try { + copyResourceToAssets("house.svg", assetsDir); + copyResourceToAssets("monster.svg", assetsDir); + copyResourceToAssets("farm.svg", assetsDir); + // Add more images as necessary + } catch (IOException e) { + e.printStackTrace(); + } + }); Bukkit.getPluginManager().registerEvents(new SignWatcher(), this); - Bukkit.getPluginManager().registerEvents(new SignDestroyWatcher(), this); } @Override @@ -42,6 +68,30 @@ public void onDisable() { for (World world : Bukkit.getWorlds()) saveWorldMarkerSet(world); } + /** + * Copies a resource image to the webRoot/assets/ directory. + * + * @param resourceName The name of the resource file (e.g., "image1.png"). + * @param targetDir The directory to copy the image to. + * @throws IOException If something goes wrong during file operations. + */ + private void copyResourceToAssets(String resourceName, Path targetDir) throws IOException { + // Get the resource as an input stream + InputStream resourceStream = getClass().getResourceAsStream("/" + resourceName); + + if (resourceStream == null) { + throw new IOException("Resource not found: " + resourceName); + } + + // Create the target file in the assets directory + Path targetFile = targetDir.resolve(resourceName); + if (!Files.exists(targetFile)) { + // Copy the resource to the target directory + Files.copy(resourceStream, targetFile); + } + resourceStream.close(); + } + private void createFiles() { for (World world : Bukkit.getWorlds()) { String name = "marker-set-" + world.getName() + ".json"; @@ -80,15 +130,15 @@ private void loadWorldMarkerSet(World world) { private void registerWorld(World world) { BlueMapAPI.onEnable(api -> - api.getWorld(world).ifPresent(blueWorld -> { - for (BlueMapMap map : blueWorld.getMaps()) { - String label = "sign-markers-" + world.getName(); - MarkerSet set = markerSet.get(world); - if (set == null) set = MarkerSet.builder().label(label).build(); - map.getMarkerSets().put(label, set); - markerSet.put(world, set); - } - }) + api.getWorld(world).ifPresent(blueWorld -> { + for (BlueMapMap map : blueWorld.getMaps()) { + String label = "sign-markers-" + world.getName(); + MarkerSet set = markerSet.get(world); + if (set == null) set = MarkerSet.builder().label(label).build(); + map.getMarkerSets().put(label, set); + markerSet.put(world, set); + } + }) ); } } diff --git a/src/main/java/dev/kugge/signmarkers/models/Tag.kt b/src/main/java/dev/kugge/signmarkers/models/Tag.kt new file mode 100644 index 0000000..84ee3eb --- /dev/null +++ b/src/main/java/dev/kugge/signmarkers/models/Tag.kt @@ -0,0 +1,8 @@ +package dev.kugge.signmarkers.models + + +class Tag(val name: String, val value: String?) { + fun contains(str: String): Boolean { + return name.contains(str); + } +} \ No newline at end of file diff --git a/src/main/java/dev/kugge/signmarkers/models/TagList.kt b/src/main/java/dev/kugge/signmarkers/models/TagList.kt new file mode 100644 index 0000000..4748227 --- /dev/null +++ b/src/main/java/dev/kugge/signmarkers/models/TagList.kt @@ -0,0 +1,15 @@ +package dev.kugge.signmarkers.models + +class TagList : ArrayList() { + fun contains(name: String): Boolean { + return this.any { it.name == name } + } + + fun findByName(name: String): Tag? { + return this.find { it.name == name } + } + + operator fun get(name: String): Tag? { + return findByName(name) + } +} \ No newline at end of file diff --git a/src/main/java/dev/kugge/signmarkers/util/AvailableTags.kt b/src/main/java/dev/kugge/signmarkers/util/AvailableTags.kt new file mode 100644 index 0000000..43c5138 --- /dev/null +++ b/src/main/java/dev/kugge/signmarkers/util/AvailableTags.kt @@ -0,0 +1,7 @@ +package dev.kugge.signmarkers.util + +enum class AvailableTags(val value: String) { + POI("poi"), + ICON("icon"), + TEXT("text") +} \ No newline at end of file diff --git a/src/main/java/dev/kugge/signmarkers/util/MarkerFactory.kt b/src/main/java/dev/kugge/signmarkers/util/MarkerFactory.kt new file mode 100644 index 0000000..536b4cc --- /dev/null +++ b/src/main/java/dev/kugge/signmarkers/util/MarkerFactory.kt @@ -0,0 +1,44 @@ +package dev.kugge.signmarkers.util + +import com.flowpowered.math.vector.Vector2i +import com.flowpowered.math.vector.Vector3d +import de.bluecolored.bluemap.api.markers.HtmlMarker +import de.bluecolored.bluemap.api.markers.Marker +import de.bluecolored.bluemap.api.markers.POIMarker +import dev.kugge.signmarkers.models.TagList +import net.pwall.mustache.Template + +class MarkerFactory { + fun build(tags: TagList, text: String, coords: Vector3d): Marker? { + if (tags.contains(AvailableTags.POI.value)) { + var icon = "assets/poi.svg"; + var iconSize = Vector2i(25.0, 45.0); + + if (tags.contains(AvailableTags.ICON.value)) { + val tag = tags.get(AvailableTags.ICON.value); + println(tag) + if (tag != null) { + println(tag.value) + if (tag.value != null) { + icon = "assets/SignMarkers/${tag.value}.svg" + } + } + } + + return POIMarker(text, coords, icon, iconSize) + } + + if (tags.contains(AvailableTags.TEXT.value)) { + val inputStream = this.javaClass.classLoader.getResourceAsStream("views/header.html") ?: return null + + val htmlTemplate = Template.parse( + inputStream + ); + data class Text(val text: String); + val htmlText = htmlTemplate.processToString(Text(text)) + return HtmlMarker(text, coords, htmlText) + } + + return null + } +} \ No newline at end of file diff --git a/src/main/java/dev/kugge/signmarkers/util/MarkerManager.kt b/src/main/java/dev/kugge/signmarkers/util/MarkerManager.kt new file mode 100644 index 0000000..fb24f83 --- /dev/null +++ b/src/main/java/dev/kugge/signmarkers/util/MarkerManager.kt @@ -0,0 +1,26 @@ +package dev.kugge.signmarkers.util + +import com.flowpowered.math.vector.Vector3d +import de.bluecolored.bluemap.api.markers.Marker +import dev.kugge.signmarkers.SignMarkers +import org.bukkit.block.Block + +class MarkerManager (var block: Block) { + val pos = Vector3d(block.x.toDouble(), block.y.toDouble(), block.z.toDouble()) + val id = "marker-" + pos.x + "-" + pos.y + "-" + pos.z + + fun addMarker(marker: Marker){ + val id = "marker-" + pos.x + "-" + pos.y + "-" + pos.z + SignMarkers.markerSet[block.world]!!.put(id, marker) + } + + fun deleteMarker(){ + // delete old marker + val markerSet = SignMarkers.markerSet[block.world] ?: return + + val marker = markerSet[id] + if (marker != null) { + markerSet.remove(id) + } + } +} \ No newline at end of file diff --git a/src/main/java/dev/kugge/signmarkers/util/TagFactory.kt b/src/main/java/dev/kugge/signmarkers/util/TagFactory.kt new file mode 100644 index 0000000..2874dcf --- /dev/null +++ b/src/main/java/dev/kugge/signmarkers/util/TagFactory.kt @@ -0,0 +1,23 @@ +package dev.kugge.signmarkers.util + +import dev.kugge.signmarkers.models.Tag +import dev.kugge.signmarkers.models.TagList + +class TagFactory { + var tagRegex = Regex("\\[(\\w+)(?:=(.*?))?]") + + fun parseTags(text: String): TagList { + val tags = TagList() + tagRegex.findAll(text).forEach { match -> + println(match.value); + val name = match.groupValues[1] + val value = match.groupValues.getOrNull(2) + tags.add(Tag(name, value)) + } + return tags; + } + + fun stripTags(text: String): String { + return text.replace(tagRegex, "") + } +} \ No newline at end of file diff --git a/src/main/java/dev/kugge/signmarkers/watcher/SignDestroyWatcher.java b/src/main/java/dev/kugge/signmarkers/watcher/SignDestroyWatcher.java deleted file mode 100644 index cb27fa6..0000000 --- a/src/main/java/dev/kugge/signmarkers/watcher/SignDestroyWatcher.java +++ /dev/null @@ -1,30 +0,0 @@ -package dev.kugge.signmarkers.watcher; - - -import com.flowpowered.math.vector.Vector3d; -import de.bluecolored.bluemap.api.markers.Marker; -import de.bluecolored.bluemap.api.markers.MarkerSet; -import dev.kugge.signmarkers.SignMarkers; -import org.bukkit.block.Block; -import org.bukkit.block.Sign; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockBreakEvent; - -public class SignDestroyWatcher implements Listener { - @EventHandler - public void onSignDestroy(BlockBreakEvent event) { - Block block = event.getBlock(); - if (!(block.getState() instanceof Sign)) return; - - MarkerSet set = SignMarkers.markerSet.get(block.getWorld()); - if (set == null) return; - - Vector3d pos = new Vector3d(block.getX(), block.getY(), block.getZ()); - String id = "marker-" + pos.getX() + "-" + pos.getY() + "-" + pos.getZ(); - - Marker marker = set.get(id); - if (marker == null) return; - set.remove(id); - } -} diff --git a/src/main/java/dev/kugge/signmarkers/watcher/SignWatcher.kt b/src/main/java/dev/kugge/signmarkers/watcher/SignWatcher.kt index 04e8883..46f757b 100644 --- a/src/main/java/dev/kugge/signmarkers/watcher/SignWatcher.kt +++ b/src/main/java/dev/kugge/signmarkers/watcher/SignWatcher.kt @@ -1,66 +1,53 @@ -package dev.kugge.signmarkers.watcher; +package dev.kugge.signmarkers.watcher + +import com.flowpowered.math.vector.Vector3d +import dev.kugge.signmarkers.util.MarkerFactory +import dev.kugge.signmarkers.util.MarkerManager +import dev.kugge.signmarkers.util.TagFactory +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.TextComponent +import org.bukkit.block.Sign +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +import org.bukkit.event.block.BlockBreakEvent +import org.bukkit.event.block.SignChangeEvent + +class SignWatcher : Listener { + private val markerFactory = MarkerFactory() -import de.bluecolored.bluemap.api.markers.POIMarker; -import dev.kugge.signmarkers.SignMarkers; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -import org.bukkit.block.Block; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.block.SignChangeEvent; -import com.flowpowered.math.vector.Vector3d; -import com.flowpowered.math.vector.Vector2i; - -import javax.imageio.ImageIO; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; - -public class SignWatcher implements Listener { @EventHandler - public void onSignWrite(SignChangeEvent event) { - // Check for existing sign at position xyz and delete it - Component header = event.line(0); - if (header == Component.empty() || header == null) return; - if (!header.toString().contains("[map]")) return; - - // Don't require a line 3, in fact require a secondary tag and loop through for tags hell have defaults for [text] [poi] [map] etc. - Component cicon = event.line(3); - if (cicon == Component.empty() || cicon == null) return; - - String icon = "./markers/" + LegacyComponentSerializer.legacySection().serialize(cicon) + ".png"; - File iconFile = new File(SignMarkers.webRoot + "/" + icon); - Vector2i anchor = new Vector2i(25, 45); - if (!iconFile.exists()) { - icon = "./assets/poi.svg"; - } else { - try { - BufferedImage image = ImageIO.read(iconFile); - int width = image.getWidth(); - int height = image.getHeight(); - anchor = new Vector2i(height / 2, width / 2); - } catch (IOException e) { - e.printStackTrace(); - return; + fun onSignWrite(event: SignChangeEvent) { + val tf = TagFactory() + val lines = event.lines().map(fun(it: Component): String { + if (it is TextComponent) { + return it.content(); } - } + return "" + }).joinToString("\n") - Component clabel1 = event.line(1); - if (clabel1 == Component.empty() || clabel1 == null) return; + println("#########################") + println(lines) + val tags = tf.parseTags(lines) + if (tags.isEmpty()) return - Component clabel2 = event.line(2); - String label = LegacyComponentSerializer.legacySection().serialize(clabel1) - + LegacyComponentSerializer.legacySection().serialize(clabel2); + val block = event.block + val pos = Vector3d(block.x.toFloat(), block.y.toFloat(), block.z.toFloat()) - Block block = event.getBlock(); - Vector3d pos = new Vector3d(block.getX(), block.getY(), block.getZ()); + val text = tf.stripTags(lines); + println("#########################") + println(text) + val marker = markerFactory.build(tags, text, pos) ?: return - String id = "marker-" + pos.getX() + "-" + pos.getY() + "-" + pos.getZ(); - POIMarker marker = new POIMarker(label, pos, icon, anchor); - SignMarkers.markerSet.get(block.getWorld()).put(id, marker); + val markerManager = MarkerManager(block) + markerManager.addMarker(marker); + } + + @EventHandler + fun onSignDestroy(event: BlockBreakEvent) { + val block = event.block + if (block.state !is Sign) return - // Leave [Map] and Icon in but don't add them to marker - event.line(0, Component.empty()); - event.line(3, Component.empty()); + val markerManager = MarkerManager(block) + markerManager.deleteMarker() } -} +} \ No newline at end of file diff --git a/src/main/resources/farm.svg b/src/main/resources/farm.svg new file mode 100644 index 0000000..9e8563c --- /dev/null +++ b/src/main/resources/farm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/main/resources/house.svg b/src/main/resources/house.svg new file mode 100644 index 0000000..d56df31 --- /dev/null +++ b/src/main/resources/house.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/main/resources/monster.svg b/src/main/resources/monster.svg new file mode 100644 index 0000000..132d3fe --- /dev/null +++ b/src/main/resources/monster.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/main/resources/views/header.html b/src/main/resources/views/header.html new file mode 100644 index 0000000..59aed82 --- /dev/null +++ b/src/main/resources/views/header.html @@ -0,0 +1,3 @@ +
+ {{text}} +
\ No newline at end of file diff --git a/src/test/java/dev/kugge/signmarkers/util/TagFactoryTest.kt b/src/test/java/dev/kugge/signmarkers/util/TagFactoryTest.kt new file mode 100644 index 0000000..3365ce8 --- /dev/null +++ b/src/test/java/dev/kugge/signmarkers/util/TagFactoryTest.kt @@ -0,0 +1,28 @@ +package dev.kugge.signmarkers.util + +import org.junit.jupiter.api.Test + +import org.junit.jupiter.api.Assertions.* + +class TagFactoryTest { + + @Test + fun parseTags() { + val tags = TagFactory().parseTags("[map] This is my map item") + assertNotNull(tags) + assert(tags.size > 0) + assert(tags.contains("map")) + assert(tags.findByName("map")?.value == "") + } + + @Test + fun testThatTagsWithValuesStoreCorrectly(){ + val tags = TagFactory().parseTags("[map=This]") + assertNotNull(tags) + assert(tags.size > 0) + assert(tags.contains("map")) + assertNotNull(tags.findByName("map")?.value) + assert(tags.findByName("map")?.value == "This") + assertFalse(tags.findByName("map")?.value == "Not") + } +} \ No newline at end of file diff --git a/src/test/java/dev/kugge/signmarkers/watcher/SignWatcher.kt b/src/test/java/dev/kugge/signmarkers/watcher/SignWatcher.kt new file mode 100644 index 0000000..aed92cf --- /dev/null +++ b/src/test/java/dev/kugge/signmarkers/watcher/SignWatcher.kt @@ -0,0 +1,23 @@ +package dev.kugge.signmarkers.watcher + +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.TextComponent +import org.bukkit.block.Block +import org.bukkit.entity.Player +import org.bukkit.event.block.SignChangeEvent +import org.junit.jupiter.api.Test +import org.mockito.Mockito + +internal class SignWatcherTest { + @Test + fun onSignWrite() { + val blockMock = Mockito.mock(Block::class.java) + val playerMock = Mockito.mock(Player::class.java) + val watcher = SignWatcher() + val adventureLines = ArrayList() + val tc = Mockito.mock(TextComponent::class.java) + Mockito.`when`(tc.toString()).thenReturn("[map] this is my component") + adventureLines.add(tc) + watcher.onSignWrite(SignChangeEvent(blockMock, playerMock, adventureLines)) + } +} \ No newline at end of file