Skip to content

Commit 2fca26e

Browse files
committed
add /namehistory
1 parent 186e7cd commit 2fca26e

File tree

8 files changed

+126
-5
lines changed

8 files changed

+126
-5
lines changed

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ plugins {
99
}
1010

1111
group = "net.azisaba.spicyazisaban"
12-
version = "0.2.1-${getBranch()}-${getGitHash()}${if (hasUncommittedChanges()) "-debug" else ""}"
12+
version = "0.3.0-${getBranch()}-${getGitHash()}${if (hasUncommittedChanges()) "-debug" else ""}"
1313

1414
java {
1515
toolchain.languageVersion.set(JavaLanguageVersion.of(17))

cli/src/main/kotlin/net/azisaba/spicyAzisaBan/cli/CLIMain.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import net.azisaba.spicyAzisaBan.cli.commands.CLICautionCommand
1111
import net.azisaba.spicyAzisaBan.cli.commands.CLIGroupCommand
1212
import net.azisaba.spicyAzisaBan.cli.commands.CLIKickCommand
1313
import net.azisaba.spicyAzisaBan.cli.commands.CLIMuteCommand
14+
import net.azisaba.spicyAzisaBan.cli.commands.CLINameHistoryCommand
1415
import net.azisaba.spicyAzisaBan.cli.commands.CLISeenCommand
1516
import net.azisaba.spicyAzisaBan.cli.commands.CLISimpleAsyncCommand
1617
import net.azisaba.spicyAzisaBan.cli.commands.CLIUnpunishCommand
@@ -40,6 +41,7 @@ object CLIMain {
4041
CLISeenCommand,
4142
CLIUnpunishCommand,
4243
CLIWarningCommand,
44+
CLINameHistoryCommand,
4345
)
4446
parser.parse(args)
4547
} catch (e: Throwable) {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package net.azisaba.spicyAzisaBan.cli.commands
2+
3+
import kotlinx.cli.ArgType
4+
import kotlinx.cli.ExperimentalCli
5+
import kotlinx.cli.Subcommand
6+
import net.azisaba.spicyAzisaBan.cli.SpicyAzisaBanCLI
7+
import net.azisaba.spicyAzisaBan.cli.actor.CLIActor
8+
import net.azisaba.spicyAzisaBan.commands.NameHistoryCommand
9+
import kotlin.system.exitProcess
10+
11+
@OptIn(ExperimentalCli::class)
12+
object CLINameHistoryCommand: Subcommand("name-history", "Show name history of a player") {
13+
private val player by argument(ArgType.String, "player", "Player name")
14+
15+
override fun execute() {
16+
SpicyAzisaBanCLI().doEnable()
17+
NameHistoryCommand.execute(CLIActor, arrayOf(player))
18+
exitProcess(0)
19+
}
20+
}

common/src/main/kotlin/net/azisaba/spicyAzisaBan/SABMessages.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,5 +386,11 @@ object SABMessages {
386386
val lockdown get() = obj.getMessage("lockdown", defObj.getMessage("lockdown"))
387387
val lockdownJoinAttempt get() = obj.getMessage("lockdownJoinAttempt", defObj.getMessage("lockdownJoinAttempt"))
388388
}
389+
390+
object NameHistory {
391+
private val defObj get() = Commands.defObj.getObj("namehistory")
392+
private val obj get() = Commands.obj.getObj("namehistory")
393+
val usage get() = obj.getMessage("usage", defObj.getMessage("usage"))
394+
}
389395
}
390396
}

common/src/main/kotlin/net/azisaba/spicyAzisaBan/SpicyAzisaBan.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import net.azisaba.spicyAzisaBan.commands.IPMuteCommand
2525
import net.azisaba.spicyAzisaBan.commands.KickCommand
2626
import net.azisaba.spicyAzisaBan.commands.LockdownCommand
2727
import net.azisaba.spicyAzisaBan.commands.MuteCommand
28+
import net.azisaba.spicyAzisaBan.commands.NameHistoryCommand
2829
import net.azisaba.spicyAzisaBan.commands.NoteCommand
2930
import net.azisaba.spicyAzisaBan.commands.ProofsCommand
3031
import net.azisaba.spicyAzisaBan.commands.SABCommand
@@ -68,7 +69,7 @@ abstract class SpicyAzisaBan {
6869
lateinit var connection: SQLConnection
6970
lateinit var settings: Settings
7071
var lockdown = false
71-
72+
7273
companion object {
7374
val LOGGER: Logger = Logger.getLogger("SpicyAzisaBan")
7475
@JvmStatic
@@ -82,7 +83,7 @@ abstract class SpicyAzisaBan {
8283
private val startTime = System.currentTimeMillis()
8384
@JvmStatic
8485
fun getUptime(): String = Util.unProcessTime(System.currentTimeMillis() - startTime)
85-
86+
8687
// Range: 0 - 99999
8788
// 0: off
8889
// 1: on
@@ -134,7 +135,7 @@ abstract class SpicyAzisaBan {
134135
LOGGER.info("Connected.")
135136
}
136137
}
137-
138+
138139
open fun doEnable() {
139140
if (SABConfig.debugBuild) debugLevel = 5
140141
if (SABConfig.prefix.contains("\\s+".toRegex())) throw IllegalArgumentException("prefix (in config.yml) contains whitespace")
@@ -198,8 +199,9 @@ abstract class SpicyAzisaBan {
198199
instance.registerCommand(DelProofCommand)
199200
instance.registerCommand(ProofsCommand)
200201
instance.registerCommand(LockdownCommand)
202+
instance.registerCommand(NameHistoryCommand)
201203
}
202-
204+
203205
fun shutdownTimer() {
204206
timer.cancel()
205207
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package net.azisaba.spicyAzisaBan.commands
2+
3+
import net.azisaba.spicyAzisaBan.SABMessages
4+
import net.azisaba.spicyAzisaBan.SABMessages.replaceVariables
5+
import net.azisaba.spicyAzisaBan.SpicyAzisaBan
6+
import net.azisaba.spicyAzisaBan.common.Actor
7+
import net.azisaba.spicyAzisaBan.common.command.Command
8+
import net.azisaba.spicyAzisaBan.sql.SQLConnection
9+
import net.azisaba.spicyAzisaBan.util.Util.filtr
10+
import net.azisaba.spicyAzisaBan.util.Util.send
11+
import net.azisaba.spicyAzisaBan.util.Util.sendErrorMessage
12+
import net.azisaba.spicyAzisaBan.util.Util.translate
13+
import util.kt.promise.rewrite.catch
14+
import util.kt.promise.rewrite.component1
15+
import util.kt.promise.rewrite.component2
16+
import util.promise.rewrite.Promise
17+
import xyz.acrylicstyle.sql.options.FindOptions
18+
import java.util.UUID
19+
20+
object NameHistoryCommand : Command() {
21+
override val name = "namehistory"
22+
override val permission = "sab.namehistory"
23+
24+
override fun execute(actor: Actor, args: Array<String>) {
25+
if (!actor.hasPermission(permission)) {
26+
return actor.send(SABMessages.General.missingPermissions.replaceVariables().translate())
27+
}
28+
if (args.isEmpty()) return actor.send(SABMessages.Commands.NameHistory.usage.replaceVariables().translate())
29+
getUUIDs(args[0])
30+
.then { pair ->
31+
pair.first to pair.second.map { uuid ->
32+
SpicyAzisaBan.instance
33+
.connection
34+
.usernameHistory
35+
.findAll(FindOptions.Builder().addWhere("uuid", uuid.toString()).build())
36+
.then { it.sortedBy { td -> td.getLong("last_seen") }.map { td -> td.getString("name") } }
37+
}.map(Promise<List<String>>::complete)
38+
}
39+
.thenDo { pair ->
40+
pair.second.forEach { names ->
41+
names.mapIndexed { i, s ->
42+
val isLast = names.lastIndex == i
43+
if (pair.first.contains(s)) {
44+
"§${if (isLast) 'a' else 'b'}§n$s§r"
45+
} else {
46+
if (isLast) {
47+
"§a$s"
48+
} else {
49+
"§e$s"
50+
}
51+
}
52+
}.joinToString("§7 -> ").let { actor.send(it) }
53+
}
54+
}
55+
.catch { actor.sendErrorMessage(it) }
56+
.complete()
57+
}
58+
59+
private fun getUUIDs(name: String): Promise<Pair<List<String>, List<UUID>>> = Promise.create { (resolve, reject) ->
60+
try {
61+
val sql = "SELECT `name`, `uuid` FROM `usernameHistory` WHERE LOWER(`name`) LIKE LOWER(?)"
62+
val start = System.currentTimeMillis()
63+
SpicyAzisaBan.instance.connection.connection.prepareStatement(sql).use { stmt ->
64+
stmt.setString(1, name)
65+
SQLConnection.logSql(sql, start, name)
66+
val names = mutableListOf<String>()
67+
val uuids = mutableListOf<UUID>()
68+
stmt.executeQuery().use { rs ->
69+
while (rs.next()) {
70+
names.add(rs.getString("name"))
71+
uuids.add(UUID.fromString(rs.getString("uuid")))
72+
}
73+
}
74+
resolve(names.distinct() to uuids.distinct())
75+
}
76+
} catch (t: Throwable) {
77+
reject(t)
78+
}
79+
}
80+
81+
override fun onTabComplete(actor: Actor, args: Array<String>): Collection<String> {
82+
if (args.isEmpty()) return emptyList()
83+
return SpicyAzisaBan.instance.getPlayers().map { it.name }.filtr(args[0])
84+
}
85+
}

common/src/main/kotlin/net/azisaba/spicyAzisaBan/sql/SQLConnection.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ class SQLConnection(host: String, name: String, user:String, password: String):
2828
SpicyAzisaBan.debug("Executed SQL: $s (took $time ms)", 3)
2929
}
3030

31+
fun logSql(s: String, time: Long, vararg params: Any) {
32+
SpicyAzisaBan.debug("Executed SQL: '$s' with params: ${params.toList()} (took $time ms)", 3)
33+
}
34+
3135
fun logSql(s: String, params: Array<out Any>) {
3236
SpicyAzisaBan.debug("Executing SQL: '$s' with params: ${params.toList()}", 3)
3337
}

common/src/main/resources/spicyazisaban/messages.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,3 +433,5 @@ commands:
433433
# Available variables for (enabled|disabled)Lockdown: default, %ACTOR% (actor who toggled the lockdown)
434434
enabledLockdown: "%PREFIX%&e&o%ACTOR%&r&7がサーバーロックダウンを&e有効&7にしました。"
435435
disabledLockdown: "%PREFIX%&e&o%ACTOR%&r&7がサーバーロックダウンを&e無効&7にしました。"
436+
namehistory:
437+
usage: "%PREFIX%&a使用法: /%CMD_PREFIX%namehistory <player>"

0 commit comments

Comments
 (0)