Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,89 +12,81 @@ import java.util.regex.Matcher
import java.util.regex.Pattern
import java.util.stream.Stream

private val ACTION_PATTERN = Pattern.compile("(.*) ?\\[(?<action>[A-Z]+?)] ?(?<arguments>.+)", Pattern.CASE_INSENSITIVE)
private val DELAY_PATTERN = Pattern.compile("\\[DELAY=(?<delay>\\d+[a-z])]", Pattern.CASE_INSENSITIVE)
private val CHANCE_PATTERN = Pattern.compile("\\[CHANCE=(?<chance>\\d+)]", Pattern.CASE_INSENSITIVE)
private val RANDOM = SplittableRandom()

class ActionHandler(private val plugin: FrozenJoinPlugin) {

companion object {
private val ACTION_PATTERN = Pattern.compile("(.*) ?\\[(?<action>[A-Z]+?)] ?(?<arguments>.+)", Pattern.CASE_INSENSITIVE)
private val DELAY_PATTERN = Pattern.compile("\\[DELAY=(?<delay>\\d+[a-z])]", Pattern.CASE_INSENSITIVE)
private val CHANCE_PATTERN = Pattern.compile("\\[CHANCE=(?<chance>\\d+)]", Pattern.CASE_INSENSITIVE)
private val RANDOM = SplittableRandom()
}
private val actions: Map<String, Action> = setOf (
MessageAction(),
BroadcastAction()
).associateBy { it.id }

private val actions: MutableMap<String, Action> = mutableMapOf()
private var matcher: Matcher? = null
private var chanceMatcher: Matcher? = null
private var delayMatcher: Matcher? = null
private val matcher: Matcher = ACTION_PATTERN.matcher("")
private val chanceMatcher: Matcher = CHANCE_PATTERN.matcher("")
private val delayMatcher: Matcher = DELAY_PATTERN.matcher("")

init {
load()
}

fun execute(player: Player, input: List<String>) {
input.forEach{ execute(player, it) }
}

fun execute(player: Player, input: String) {
var input = hasChanceAction(input) ?: return
val holder = getDelayAction(input)
input = holder.action

if (matcher == null) {
matcher = ACTION_PATTERN.matcher(input)
} else {
matcher.reset(input)
}
val actionHolder = getDelayAction(
hasChanceAction(input) ?: return
)
val inputAction = actionHolder.action
matcher.reset(inputAction)

if (!matcher.matches()) {
println("Action does not matches regex $input")
println("Action does not matches regex $inputAction")
return
}

val arguments = matcher.group("arguments")
val delay = holder.delay
val delay = actionHolder.delay

val action: Action = actions[matcher.group("action").toUpperCase()] ?: return
Bukkit.getScheduler().runTaskLater(plugin, Runnable { action.run(player, arguments) }, delay)
val actionName = matcher.group("action").toUpperCase()

val action: Action = actions[actionName] ?: return
Bukkit.getScheduler().runTaskLater(
plugin,
Runnable { action.run(player, arguments) },
delay
)
}

private fun hasChanceAction(input: String): String? {
if (chanceMatcher == null) {
chanceMatcher = CHANCE_PATTERN.matcher(input)
} else {
chanceMatcher.reset(input)
}
chanceMatcher.reset(input)
if (!chanceMatcher.find()) {
return input
}
val chance: Int = Integer.valueOf(chanceMatcher.group("chance"))
val chance: Int = Integer.valueOf(
chanceMatcher.group("chance")
)
val value: Int = RANDOM.nextInt(100) + 1
return if (value <= chance) {
input.replace(chanceMatcher.group(), "")
} else null
}

private fun getDelayAction(input: String): ActionHolder {
if (delayMatcher == null) {
delayMatcher = DELAY_PATTERN.matcher(input)
} else {
delayMatcher.reset(input)
}
delayMatcher.reset(input)
if (!delayMatcher.find()) {
return ActionHolder(input, 0L)
}
val delay = delayMatcher.group("delay")
return try {
val time = TimeAPI(delay)
ActionHolder(input.replace(delayMatcher.group(), ""), time.getSeconds() * 20L)
ActionHolder(
action = input.replace(delayMatcher.group(), ""),
delay = time.seconds * 20L
)
} catch (ex: IllegalArgumentException) {
ex.printStackTrace()
ActionHolder(input, 0L)
}
}

private fun load() {
Stream.of<Action>(
MessageAction(),
BroadcastAction()
).forEach { actions[it.id] = it }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ package com.github.frcsty.frozenjoin.action.actions
import org.bukkit.entity.Player

class BroadcastAction : Action {
override val id: String
get() = "BROADCAST"
override val id: String = "BROADCAST"

override fun run(player: Player, data: String) {
for (i in 0..4) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ package com.github.frcsty.frozenjoin.action.actions
import org.bukkit.entity.Player

class MessageAction : Action {
override val id: String
get() = "MESSAGE"
override val id: String = "MESSAGE"

override fun run(player: Player, data: String) {
println(data)
Expand Down
104 changes: 48 additions & 56 deletions src/main/kotlin/com/github/frcsty/frozenjoin/action/time/TimeAPI.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,69 +2,61 @@ package com.github.frcsty.frozenjoin.action.time

import java.util.concurrent.TimeUnit

class TimeAPI {
private var seconds: Long = 0
private const val DAYS_IN_WEEK: Long = 7
private const val DAYS_IN_MONTH: Long = 30
private const val DAYS_IN_YEAR: Long = 365

constructor(time: String) {
reparse(time)
}
class TimeAPI(val seconds: Long) {
constructor(time: String): this(parseTime(time))

constructor(seconds: Long) {
this.seconds = seconds
val nanoseconds: Double by lazy {
TimeUnit.SECONDS.toNanos(seconds).toDouble()
}

fun reparse(time: String): TimeAPI {
seconds = 0
val scanner = TimeScanner(time
.replace(" ", "")
.replace("and", "")
.replace(",", "")
.toLowerCase())
var next: Long
while (scanner.hasNext()) {
next = scanner.nextLong()
seconds += when (scanner.nextString()) {
"s", "sec", "secs", "second", "seconds" -> next
"m", "min", "mins", "minute", "minutes" -> TimeUnit.MINUTES.toSeconds(next)
"h", "hr", "hrs", "hour", "hours" -> TimeUnit.HOURS.toSeconds(next)
"d", "dy", "dys", "day", "days" -> TimeUnit.DAYS.toSeconds(next)
"w", "week", "weeks" -> TimeUnit.DAYS.toSeconds(next * DAYS_IN_WEEK)
"mo", "mon", "mnth", "month", "months" -> TimeUnit.DAYS.toSeconds(next * DAYS_IN_MONTH)
"y", "yr", "yrs", "year", "years" -> TimeUnit.DAYS.toSeconds(next * DAYS_IN_YEAR)
else -> throw IllegalArgumentException()
}
}
return this
val microseconds: Double by lazy {
TimeUnit.SECONDS.toMicros(seconds).toDouble()
}

val nanoseconds: Double
get() = TimeUnit.SECONDS.toNanos(seconds).toDouble()

val microseconds: Double
get() = TimeUnit.SECONDS.toMicros(seconds).toDouble()

val milliseconds: Double
get() = TimeUnit.SECONDS.toMillis(seconds).toDouble()

fun getSeconds(): Long {
return seconds
val milliseconds: Double by lazy {
TimeUnit.SECONDS.toMillis(seconds).toDouble()
}

val minutes: Double get() = seconds / 60.0

val hours: Double get() = seconds / 3600.0

val days: Double get() = seconds / 86400.0

val weeks: Double get() = days / DAYS_IN_WEEK

val months: Double get() = days / DAYS_IN_MONTH

val years: Double get() = days / DAYS_IN_YEAR

companion object {
private const val DAYS_IN_WEEK: Long = 7
private const val DAYS_IN_MONTH: Long = 30
private const val DAYS_IN_YEAR: Long = 365
val minutes: Double by lazy { seconds / 60.0 }

val hours: Double by lazy { seconds / 3600.0 }

val days: Double by lazy { seconds / 86400.0 }

val weeks: Double by lazy { days/ DAYS_IN_WEEK }

val months: Double by lazy { days/ DAYS_IN_MONTH }

val years: Double by lazy { days/ DAYS_IN_YEAR }
}


private fun parseTime(time: String): Long {
var seconds = 0L
val scanner = TimeScanner(
time
.replace(" ", "")
.replace("and", "")
.replace(",", "")
.toLowerCase()
)
var next: Long
while (scanner.hasNext()) {
next = scanner.nextLong()
seconds += when (scanner.nextString()) {
"s", "sec", "secs", "second", "seconds" -> next
"m", "min", "mins", "minute", "minutes" -> TimeUnit.MINUTES.toSeconds(next)
"h", "hr", "hrs", "hour", "hours" -> TimeUnit.HOURS.toSeconds(next)
"d", "dy", "dys", "day", "days" -> TimeUnit.DAYS.toSeconds(next)
"w", "week", "weeks" -> TimeUnit.DAYS.toSeconds(next * DAYS_IN_WEEK)
"mo", "mon", "mnth", "month", "months" -> TimeUnit.DAYS.toSeconds(next * DAYS_IN_MONTH)
"y", "yr", "yrs", "year", "years" -> TimeUnit.DAYS.toSeconds(next * DAYS_IN_YEAR)
else -> throw IllegalArgumentException()
}
}
return seconds
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,35 @@ import java.util.*
import java.util.function.Predicate

internal class TimeScanner(time: String) {
private val time: CharArray
private val time: CharArray = time.toCharArray()
private var index = 0

operator fun hasNext(): Boolean {
return index < time.size - 1
}

fun nextLong(): Long {
return String(next(Predicate { ch: Char? -> Character.isDigit(ch!!) })).toLong()
return String(
next(
Predicate(Char::isDigit)
)
).toLong()
}

fun nextString(): String {
return String(next(Predicate { codePoint: Char -> Character.isAlphabetic(codePoint.toInt()) }))
return String(
next(
Predicate { codePoint: Char ->
Character.isAlphabetic(codePoint.toInt())
}
)
)
}

private fun next(whichSatisfies: Predicate<Char>): CharArray {
val startIndex = index
while (++index < time.size && whichSatisfies.test(time[index]));
return Arrays.copyOfRange(time, startIndex, index)
return time.copyOfRange(startIndex, index)
}

init {
this.time = time.toCharArray()
}
}