Skip to content

Commit

Permalink
Improve upon //signsearch
Browse files Browse the repository at this point in the history
  • Loading branch information
Nickster258 committed Jun 17, 2020
1 parent e0054ea commit 24e20e5
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 38 deletions.
17 changes: 11 additions & 6 deletions src/main/kotlin/Find.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ import com.sk89q.worldedit.function.RegionFunction
import com.sk89q.worldedit.function.RegionMaskingFilter
import com.sk89q.worldedit.function.operation.Operations
import com.sk89q.worldedit.function.visitor.RegionVisitor
import com.sk89q.worldedit.math.BlockVector3
import com.sk89q.worldedit.util.formatting.component.InvalidComponentException
import com.sk89q.worldedit.util.formatting.text.TextComponent
import org.bukkit.entity.Player
import java.util.*
import kotlin.collections.HashMap
import kotlin.math.ceil

val findResults = HashMap<UUID, MutableList<BlockVector3>>()
val findResults = HashMap<UUID, MutableList<LocationContainer>>()

@CommandAlias("/find")
@Description("Find some shid in selecton")
Expand Down Expand Up @@ -60,21 +60,26 @@ class Find(private val worldEdit: WorldEdit) : BaseCommand() {
} catch (e: IncompleteRegionException) {
throw RedstoneToolsException(MAKE_SELECTION_FIRST)
}
val locations = mutableListOf<BlockVector3>()
val locations = mutableListOf<LocationContainer>()
val maskFactory = MaskFactory(worldEdit)
val parserContext = ParserContext().apply {
extent = session.selectionWorld
}
val blockMask = maskFactory.parseFromInput(arg, parserContext)
val regionFunction = RegionFunction { position ->
locations.add(position)
locations.add(LocationContainer(position, TextComponent.of(position.toString())))
false
}
val regionMaskingFilter = RegionMaskingFilter(blockMask, regionFunction)
val regionVisitor = RegionVisitor(selection, regionMaskingFilter)
Operations.complete(regionVisitor)
findResults[player.uniqueId] = locations
page(BukkitAdapter.adapt(player), 1)
if (locations.isNotEmpty()) {
findResults[player.uniqueId] = locations
page(BukkitAdapter.adapt(player), 1)
} else {
findResults.remove(player.uniqueId)
player.printInfo(TextComponent.of("No results found."))
}
}
}

Expand Down
30 changes: 20 additions & 10 deletions src/main/kotlin/RedstoneTools.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package redstonetools

import co.aikar.commands.*
import com.sk89q.worldedit.WorldEdit
import com.sk89q.worldedit.WorldEditException
import com.sk89q.worldedit.bukkit.WorldEditPlugin
import com.sk89q.worldedit.extension.factory.MaskFactory
import com.sk89q.worldedit.math.BlockVector3
Expand All @@ -27,14 +28,17 @@ class RedstoneTools : JavaPlugin() {
args: List<String>,
throwable: Throwable
): Boolean {
val exception = throwable as? RedstoneToolsException
if (exception == null) {
logger.log(Level.SEVERE, "Error in ACF", throwable)
return false
return when (throwable) {
is RedstoneToolsException, is WorldEditException -> {
val message = throwable.message ?: "Something went wrong."
sender.sendMessage("${ChatColor.DARK_GRAY}[${ChatColor.GRAY}RedstoneTools${ChatColor.DARK_GRAY}]${ChatColor.GRAY} $message")
true
}
else -> {
logger.log(Level.SEVERE, "Error in ACF", throwable)
false
}
}
val message = exception.message ?: "Something went wrong."
sender.sendMessage("${ChatColor.DARK_GRAY}[${ChatColor.GRAY}RedstoneTools${ChatColor.DARK_GRAY}]${ChatColor.GRAY} $message")
return true
}

override fun onEnable() {
Expand Down Expand Up @@ -130,7 +134,9 @@ class MaskCompletionHandler(worldEdit: WorldEdit) :
}
}

class LocationsPaginationBox(private val locations: MutableList<BlockVector3>, title: String, command: String) :
data class LocationContainer(val location: BlockVector3, val match: TextComponent)

class LocationsPaginationBox(private val locations: MutableList<LocationContainer>, title: String, command: String) :
PaginationBox("${ChatColor.LIGHT_PURPLE}$title", command) {

init {
Expand All @@ -139,9 +145,13 @@ class LocationsPaginationBox(private val locations: MutableList<BlockVector3>, t

override fun getComponent(number: Int): Component {
if (number > locations.size) throw IllegalArgumentException("Invalid location index.")
return TextComponent.of("${number+1}: ${locations[number]}")
return TextComponent.of("${number+1}: ")
.append(locations[number].match)
.color(TextColor.LIGHT_PURPLE)
.clickEvent(ClickEvent.runCommand("/tp ${locations[number].x} ${locations[number].y} ${locations[number].z}"))
.clickEvent(ClickEvent.runCommand("/tp" +
" ${locations[number].location.x}" +
" ${locations[number].location.y}" +
" ${locations[number].location.z}"))
.hoverEvent(HoverEvent.showText(TextComponent.of("Click to teleport")))
}

Expand Down
63 changes: 44 additions & 19 deletions src/main/kotlin/SignSearch.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,19 @@ import com.sk89q.worldedit.function.RegionMaskingFilter
import com.sk89q.worldedit.function.mask.BlockCategoryMask
import com.sk89q.worldedit.function.operation.Operations
import com.sk89q.worldedit.function.visitor.RegionVisitor
import com.sk89q.worldedit.math.BlockVector3
import com.sk89q.worldedit.util.formatting.component.InvalidComponentException
import com.sk89q.worldedit.util.formatting.text.TextComponent
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent
import com.sk89q.worldedit.util.formatting.text.format.TextColor
import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSerializer
import com.sk89q.worldedit.world.block.BaseBlock
import com.sk89q.worldedit.world.block.BlockCategories
import org.bukkit.entity.Player
import java.util.*
import kotlin.collections.HashMap
import kotlin.math.ceil

val searchResults = HashMap<UUID, MutableList<BlockVector3>>()
val searchResults = HashMap<UUID, MutableList<LocationContainer>>()

@CommandAlias("/signsearch|/ss")
@Description("Search for text of signs within a selection using a regular expression")
Expand All @@ -45,8 +47,8 @@ class SignSearch(private val worldEdit: WorldEdit) : BaseCommand() {
player: Player,
page: Int
) {
val locations = searchResults[player.uniqueId] ?: throw RedstoneToolsException(MAKE_SELECTION_FIRST)
val paginationBox = LocationsPaginationBox(locations, "Search Results", "//signsearch -p %page%")
val results = searchResults[player.uniqueId] ?: throw RedstoneToolsException(MAKE_SELECTION_FIRST)
val paginationBox = LocationsPaginationBox(results, "Search Results", "//signsearch -p %page%")
val component = try {
paginationBox.create(page)
} catch (e: InvalidComponentException) {
Expand All @@ -67,36 +69,59 @@ class SignSearch(private val worldEdit: WorldEdit) : BaseCommand() {
} catch (e: IncompleteRegionException) {
throw RedstoneToolsException(MAKE_SELECTION_FIRST)
}
val matches = mutableListOf<BlockVector3>()
val matchMap = mutableListOf<LocationContainer>()
val blockMask = BlockCategoryMask(session.selectionWorld, BlockCategories.SIGNS)
val regionFunction = RegionFunction { position ->
val baseBlock = session.selectionWorld.getFullBlock(position)
if (baseBlock.hasNbtData()) {
val compoundTag = baseBlock.nbtData!!
val content = buildString {
for (i in 1..4) {
val textTag = compoundTag.value["Text$i"] as StringTag
val component = GsonComponentSerializer.INSTANCE.deserialize(textTag.value) as TextComponent
append(component.getAllContent())
}
}
if (content.contains(pattern)) {
matches.add(position)
}
val parsedMatch = parseMatch(baseBlock, pattern)
if (parsedMatch != null) {
matchMap.add(LocationContainer(position, parsedMatch))
}
false
}
val regionMaskingFilter = RegionMaskingFilter(blockMask, regionFunction)
val regionVisitor = RegionVisitor(selection, regionMaskingFilter)
Operations.complete(regionVisitor)
if (matches.isNotEmpty()) {
searchResults[player.uniqueId] = matches
if (matchMap.isNotEmpty()) {
searchResults[player.uniqueId] = matchMap
page(BukkitAdapter.adapt(player), 1)
} else {
searchResults.remove(player.uniqueId)
player.printInfo(TextComponent.of("No results found."))
}
}

private fun parseMatch(baseBlock: BaseBlock, pattern: Regex): TextComponent? {
if (!baseBlock.hasNbtData()) {
return null
}
val compoundTag = baseBlock.nbtData!!
var localMatch: TextComponent? = null
buildString {
for (i in 1..4) {
val textTag = compoundTag.value["Text$i"] as StringTag
val component = GsonComponentSerializer.INSTANCE.deserialize(textTag.value) as TextComponent
val currentLine = component.getAllContent()
append("${currentLine}\n")
val localMatches = pattern.find(currentLine)
if (localMatches != null) {
localMatch = TextComponent.of("Line $i: ")
.color(TextColor.GRAY)
.append(currentLine.getHighlightedReplacement(localMatches.groupValues.first()))
break
}
}
}.removeSuffix("\n").apply {
if (localMatch != null) {
return localMatch
} else {
val match = pattern.find(this) ?: return null
return TextComponent.of("Multi-line match")
.color(TextColor.GRAY)
.hoverEvent(HoverEvent.showText(getHighlightedReplacement(match.groupValues.first())))
}
}
}
}

class SearchPageCompletionHandler :
Expand Down
18 changes: 15 additions & 3 deletions src/main/kotlin/Util.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
package redstonetools

import com.sk89q.worldedit.util.formatting.text.TextComponent
import com.sk89q.worldedit.util.formatting.text.format.TextColor

fun TextComponent.getAllContent(): String {
return if (this.children().isEmpty()) {
fun TextComponent.getAllContent(): String =
if (this.children().isEmpty()) {
this.content()
} else {
this.children().filterIsInstance<TextComponent>().joinToString(separator = "") { textComponent ->
textComponent.getAllContent()
}
}
}

fun String.getHighlightedReplacement(replacement: String): TextComponent =
TextComponent.of(this.substringBefore(replacement))
.color(TextColor.WHITE)
.append(
TextComponent.of(replacement)
.color(TextColor.YELLOW)
)
.append(
TextComponent.of(this.substringAfter(replacement))
.color(TextColor.WHITE)
)

0 comments on commit 24e20e5

Please sign in to comment.