Skip to content
This repository has been archived by the owner on Sep 2, 2024. It is now read-only.

Commit

Permalink
part 3 (mm syntax highlighting!)
Browse files Browse the repository at this point in the history
  • Loading branch information
homchom committed Nov 29, 2023
1 parent ec5b21e commit af516e2
Show file tree
Hide file tree
Showing 42 changed files with 512 additions and 250 deletions.
2 changes: 1 addition & 1 deletion src/main/java/io/github/homchom/recode/RecodeDispatcher.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.github.homchom.recode

import io.github.homchom.recode.ui.sendSystemToast
import io.github.homchom.recode.ui.translateText
import io.github.homchom.recode.ui.text.translateText
import kotlinx.coroutines.*
import java.util.concurrent.ConcurrentLinkedQueue
import java.util.concurrent.Executor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import io.github.homchom.recode.event.Listenable
import io.github.homchom.recode.event.Requester
import io.github.homchom.recode.event.createEvent
import io.github.homchom.recode.ui.sendSystemToast
import io.github.homchom.recode.ui.translateText
import io.github.homchom.recode.ui.text.translateText
import io.github.homchom.recode.util.computeNullable
import io.github.homchom.recode.util.coroutines.cancelAndLog
import kotlinx.coroutines.*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ class TrialScope @DelicateCoroutinesApi constructor(
}

/**
* Returns a non-null [TestResult.value] or fails the trial.
* @return a non-null [TestResult.value] or fails the trial.
*/
operator fun <T : Any> TestResult<T>.unaryPlus() = value ?: fail()

Expand All @@ -194,12 +194,12 @@ class TrialScope @DelicateCoroutinesApi constructor(
fun fail(): Nothing = nullableScope.fail()

/**
* Returns an instant [TrialResult] with [value]. Use this when a trial does not end asynchronously.
* @return an instant [TrialResult] with [value]. Use this when a trial does not end asynchronously.
*/
fun <R : Any> instant(value: R?) = TrialResult(value)

/**
* Returns the asynchronous [TrialResult] of [block] ran in its own [TrialScope].
* @return the asynchronous [TrialResult] of [block] ran in its own [TrialScope].
*/
fun <R : Any> suspending(block: suspend TrialScope.() -> R?) =
TrialResult(block, coroutineScope, hidden)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ package io.github.homchom.recode.feature.social

import io.github.homchom.recode.MOD_NAME
import io.github.homchom.recode.render.ColorPalette
import io.github.homchom.recode.ui.style
import io.github.homchom.recode.ui.translateText
import io.github.homchom.recode.ui.text.literalText
import io.github.homchom.recode.ui.text.style
import io.github.homchom.recode.ui.text.toNative
import io.github.homchom.recode.ui.text.translateText
import io.github.homchom.recode.util.regex.regex
import net.minecraft.client.GuiMessageTag

Expand All @@ -19,7 +21,11 @@ private val stackRegex = regex {
fun stackedMessageTag(amount: Int) = GuiMessageTag(
ColorPalette.AQUA.hex,
GuiMessageTag.Icon.CHAT_MODIFIED,
translateText("chat.tag.recode.stacked", style().aqua(), arrayOf(amount)),
translateText(
"chat.tag.recode.stacked",
style().aqua(),
arrayOf(literalText(amount))
).toNative(),
"$stackTagPrefix$amount"
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import io.github.homchom.recode.feature.feature
import io.github.homchom.recode.id
import io.github.homchom.recode.render.IntegralColor
import io.github.homchom.recode.render.toColor
import io.github.homchom.recode.ui.style
import io.github.homchom.recode.ui.text
import io.github.homchom.recode.ui.text.style
import io.github.homchom.recode.ui.text.text
import io.github.homchom.recode.ui.text.toNative
import net.fabricmc.fabric.api.resource.ResourceManagerHelper
import net.fabricmc.fabric.api.resource.ResourcePackActivationType

Expand All @@ -26,7 +27,7 @@ private fun registerBuiltInResourcePack(
text {
literal("[$MOD_ID] ")
translate("resourcePack.recode.$id", style().color(displayColor))
},
}.toNative(),
activationType
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ import io.github.homchom.recode.hypercube.CommandAliasGroup
import io.github.homchom.recode.hypercube.DFValueMeta
import io.github.homchom.recode.hypercube.dfValueMeta
import io.github.homchom.recode.mixin.render.chat.CommandSuggestionsAccessor
import io.github.homchom.recode.render.HexColor
import io.github.homchom.recode.ui.TextBuilder
import io.github.homchom.recode.ui.deserializeToNative
import io.github.homchom.recode.ui.style
import io.github.homchom.recode.ui.text.*
import io.github.homchom.recode.util.Computation
import io.github.homchom.recode.util.map
import io.github.homchom.recode.util.regex.regex
import net.kyori.adventure.text.minimessage.MiniMessage
import net.minecraft.network.chat.Component
import net.kyori.adventure.text.BuildableComponent
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.TextComponent
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack

Expand Down Expand Up @@ -68,7 +66,6 @@ class ExpressionHighlighter {

// TODO: new color scheme?
private val colors = listOf(
0xffffff,
0xffd600,
0x33ff00,
0x00ffe0,
Expand Down Expand Up @@ -141,63 +138,44 @@ class ExpressionHighlighter {
}

private fun highlightString(string: String, parseMiniMessage: Boolean = true): HighlightedExpression {
val result = if (parseMiniMessage) {
object : HighlightBuilder {
private val builder = StringBuilder()

override fun append(text: String, depth: Int, depthIncreased: Boolean) {
val tag = if (depthIncreased) "<color:${colorAt(depth)}>" else "</color>"
builder.append("$tag$text")
}

override fun build() = MiniMessage.miniMessage().deserializeToNative(builder.toString())
}
} else {
object : HighlightBuilder {
private val builder = TextBuilder()

override fun append(text: String, depth: Int, depthIncreased: Boolean) {
builder.literal(text, style().color(colors[depth % colors.size]))
}

override fun build() = builder.result
}
}

val builder = TextBuilder()
var sliceStart = 0
var depth = 0
var code = ""

for (match in codeRegex.findAll(string)) {
val depthIncreased = code.endsWith('(') || sliceStart == 0
result.append(string.substring(sliceStart, match.range.first), depth, depthIncreased)

code = match.value
if (code.length > 1) {
val codeName = if (code.endsWith('(')) {
code.substring(1, code.lastIndex)
} else {
code.drop(1)
}
builder.literal(string.substring(sliceStart, match.range.first), styleAt(depth))

val code = match.value
if (code.length > 1 && code.drop(1) !in codes) {
val codeName = code.drop(1)
if (codeName !in codes) return Computation.Failure("Invalid text code: %$codeName")
}

if (code == ")") {
if (depth > 0) depth--
} else depth++
result.append(string.substring(match.range), depth, code != ")")
builder.literal(string.substring(match.range), styleAt(depth))
if (code.endsWith('(')) depth++ else {
if (depth > 0) depth--
}

sliceStart = match.range.last + 1
}

return Computation.Success(result.build())
if (parseMiniMessage) builder.raw.mapChildren { text ->
if (text is TextComponent && text.style().isEmpty) {
MiniMessageHighlighter.highlight(text.content()) as BuildableComponent<*, *>
} else {
text
}
}

return Computation.Success(builder.build())
}

private fun highlightCommand(input: String, info: CommandInfo, splitIndex: Int): HighlightedExpression {
val root = Component.literal(input.substring(0, splitIndex))
.withStyle(CommandSuggestionsAccessor.getCommandStyle())
val root = Component.text(input.substring(0, splitIndex))
.style(CommandSuggestionsAccessor.getCommandVanillaStyle().toAdventure())
var string = input.substring(splitIndex)

if (info.highlightedArgumentIndex > 0) {
Expand All @@ -214,14 +192,17 @@ class ExpressionHighlighter {
}
}

return highlightString(string).map(root::append)
return highlightString(string).map { result ->
text {
append(root)
append(result)
}
}
}

private fun colorAt(depth: Int) = HexColor(colors[depth % colors.size])

private interface HighlightBuilder {
fun append(text: String, depth: Int, depthIncreased: Boolean)

fun build(): Component
private fun styleAt(depth: Int) = if (depth == 0) {
style()
} else {
style().color(colors[depth - 1 % colors.size])
}
}
2 changes: 1 addition & 1 deletion src/main/java/io/github/homchom/recode/game/GameTime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ package io.github.homchom.recode.game
import kotlin.time.Duration.Companion.milliseconds

/**
* Returns this integer as a [kotlin.time.Duration] in ticks, where 20 ticks = 1 second.
* @return this integer as a [kotlin.time.Duration] in ticks, where 20 ticks = 1 second.
*/
val Int.ticks get() = milliseconds * 50
15 changes: 10 additions & 5 deletions src/main/java/io/github/homchom/recode/game/ItemExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@
package io.github.homchom.recode.game

import io.github.homchom.recode.mixin.game.ItemStackAccessor
import io.github.homchom.recode.ui.mergedWith
import io.github.homchom.recode.ui.text.mergeStyle
import io.github.homchom.recode.ui.text.toAdventure
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer
import net.minecraft.nbt.Tag
import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack

/**
* @return this [ItemStack]'s "lore" (description), found in its tooltip, as a list of [Component]s.
*/
fun ItemStack.lore(): List<Component> {
val loreTag = tag
?.getCompoundOrNull("display")
Expand All @@ -16,9 +21,9 @@ fun ItemStack.lore(): List<Component> {

return buildList(loreTag.size) {
for (index in 0..<loreTag.size) {
// TODO: can this throw?
val text = Component.Serializer.fromJson(loreTag.getString(index)) ?: continue
add(text.mergedWith(ItemStackAccessor.getLoreStyle()))
val text = JSONComponentSerializer.json().deserializeOrNull(loreTag.getString(index)) ?: continue
val style = ItemStackAccessor.getLoreVanillaStyle().toAdventure()
add(text.mergeStyle(style))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import io.github.homchom.recode.game.getCompoundOrNull
import io.github.homchom.recode.game.getStringOrNull
import io.github.homchom.recode.game.lore
import io.github.homchom.recode.logError
import net.minecraft.network.chat.Component
import net.kyori.adventure.text.Component
import net.minecraft.world.item.ItemStack

fun ItemStack.dfValueMeta(): DFValueMeta? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import io.github.homchom.recode.multiplayer.DisconnectFromServerEvent
import io.github.homchom.recode.multiplayer.JoinServerEvent
import io.github.homchom.recode.multiplayer.ReceiveChatMessageEvent
import io.github.homchom.recode.multiplayer.username
import io.github.homchom.recode.ui.matchEntireUnstyled
import io.github.homchom.recode.ui.text.matchEntirePlain
import io.github.homchom.recode.util.Case
import io.github.homchom.recode.util.regex.regex
import kotlinx.coroutines.flow.map
Expand All @@ -36,7 +36,7 @@ val JoinDFDetector = detector("DF join",
failOn(disconnect)

val patch = +test(messages, unlimited) { (text) ->
patchRegex.matchEntireUnstyled(text)?.groupValues?.get(1)
patchRegex.matchEntirePlain(text)?.groupValues?.get(1)
}

val locateMessage = StateMessages.Locate.request(mc.player!!.username, true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import io.github.homchom.recode.event.trial.trial
import io.github.homchom.recode.hypercube.state.DFStateDetectors
import io.github.homchom.recode.multiplayer.ReceiveChatMessageEvent
import io.github.homchom.recode.multiplayer.sendCommand
import io.github.homchom.recode.ui.equalsUnstyled
import io.github.homchom.recode.ui.matchesUnstyled
import io.github.homchom.recode.ui.unstyledString
import io.github.homchom.recode.ui.text.equalsPlain
import io.github.homchom.recode.ui.text.matchesPlain
import io.github.homchom.recode.ui.text.plainText
import io.github.homchom.recode.util.regex.cachedRegex
import io.github.homchom.recode.util.regex.regex

Expand All @@ -19,7 +19,7 @@ val ChatLocalRequester = requester("/chat local", DFStateDetectors.ChangeMode, t
tests = { (text), _, _ ->
val message = "$MAIN_ARROW Chat is now set to Local. You will only see messages from players on " +
"your plot. Use /chat to change it again."
text.equalsUnstyled(message).instantUnitOrNull()
text.equalsPlain(message).instantUnitOrNull()
}
))

Expand All @@ -35,7 +35,7 @@ val ClientTimeRequester = requester("/time", DFStateDetectors.ChangeMode, trial(
null as Long?,
start = { time -> sendCommand("time $time") },
tests = { context, time, _: Boolean ->
timeRegex(time).matchesUnstyled(context.value).instantUnitOrNull()
timeRegex(time).matchesPlain(context.value).instantUnitOrNull()
}
))

Expand All @@ -44,7 +44,7 @@ val FlightRequesters = toggleRequesterGroup("/fly", DFStateDetectors, trial(
Unit,
start = { sendCommand("fly") },
tests = { message, _, _ ->
val enabled = when (message().unstyledString) {
val enabled = when (message().plainText) {
"$MAIN_ARROW Flight enabled." -> true
"$MAIN_ARROW Flight disabled." -> false
else -> fail()
Expand All @@ -70,8 +70,8 @@ val LagSlayerRequesters = toggleRequesterGroup("/lagslayer", DFStateDetectors.Ch
start = { sendCommand("lagslayer") },
tests = { (message), _, _ ->
val enabled = when {
lsEnabledRegex.matchesUnstyled(message) -> true
lsDisabledRegex.matchesUnstyled(message) -> false
lsEnabledRegex.matchesPlain(message) -> true
lsDisabledRegex.matchesPlain(message) -> false
else -> fail()
}
instant(enabled)
Expand All @@ -83,7 +83,7 @@ val NightVisionRequesters = toggleRequesterGroup("/nightvis", DFStateDetectors.C
Unit,
start = { sendCommand("nightvis") },
tests = { (message), _, _ ->
val enabled = when (message.unstyledString) {
val enabled = when (message.plainText) {
"$MAIN_ARROW Enabled night vision." -> true
"$MAIN_ARROW Disabled night vision." -> false
else -> fail()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package io.github.homchom.recode.hypercube.message
import io.github.homchom.recode.event.Requester
import io.github.homchom.recode.hypercube.state.DFStateDetectors
import io.github.homchom.recode.multiplayer.sendCommand
import io.github.homchom.recode.ui.equalsUnstyled
import io.github.homchom.recode.ui.matchEntireUnstyled
import io.github.homchom.recode.ui.text.equalsPlain
import io.github.homchom.recode.ui.text.matchEntirePlain
import io.github.homchom.recode.util.regex.namedGroupValues
import io.github.homchom.recode.util.regex.regex
import net.minecraft.network.chat.Component
import net.kyori.adventure.text.Component
import kotlin.time.Duration
import kotlin.time.Duration.Companion.hours
import kotlin.time.Duration.Companion.minutes
Expand All @@ -25,7 +25,7 @@ object CodeMessages {
)
{
override fun match(input: Component): SupportTime? {
if (input.equalsUnstyled("Error: You are not in a session.")) {
if (input.equalsPlain("Error: You are not in a session.")) {
return SupportTime(null)
}

Expand All @@ -35,7 +35,7 @@ object CodeMessages {
val minutes by digit * 2
val seconds by digit * 2
}
val values = regex.matchEntireUnstyled(input)?.namedGroupValues ?: return null
val values = regex.matchEntirePlain(input)?.namedGroupValues ?: return null

val hours = values["hours"].toIntOrNull()?.hours ?: return null
val minutes = values["minutes"].toIntOrNull()?.minutes ?: return null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import io.github.homchom.recode.multiplayer.ReceiveChatMessageEvent
import io.github.homchom.recode.util.Matcher
import io.github.homchom.recode.util.matcherOf
import io.github.homchom.recode.util.splitByHumps
import net.minecraft.network.chat.Component
import net.kyori.adventure.text.Component

sealed interface MessageParser<T : Any, out R : ParsedMessage> : Matcher<Component, R>, Detector<T, R>

Expand Down
Loading

0 comments on commit af516e2

Please sign in to comment.