Skip to content

Commit 0a8d277

Browse files
authored
Merge pull request #322 from Score2/master
[6.0.11][publish] Added module expansion-application-console.
2 parents a70de28 + 2cd5c4d commit 0a8d277

File tree

7 files changed

+293
-7
lines changed

7 files changed

+293
-7
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
dependencies {
2+
compileOnly(project(":common"))
3+
compileOnly(project(":platform:platform-application"))
4+
5+
implementation("net.minecrell:terminalconsoleappender:1.3.0")
6+
implementation("org.apache.logging.log4j:log4j-api:2.17.2")
7+
implementation("org.apache.logging.log4j:log4j-core:2.17.2")
8+
implementation("org.apache.logging.log4j:log4j-iostreams:2.17.2")
9+
implementation("org.apache.logging.log4j:log4j-slf4j18-impl:2.17.2")
10+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package taboolib.platform
2+
3+
import taboolib.common.platform.Awake
4+
import taboolib.common.platform.Platform
5+
import taboolib.common.platform.PlatformSide
6+
import taboolib.common.platform.ProxyCommandSender
7+
import taboolib.common.platform.command.*
8+
import taboolib.common.platform.command.component.CommandBase
9+
import taboolib.common.platform.service.PlatformCommand
10+
import taboolib.platform.AppConsole.logger
11+
12+
/**
13+
* @author Score2
14+
* @since 2022/06/07 23:43
15+
*/
16+
@Awake
17+
@PlatformSide([Platform.APPLICATION])
18+
class AppCommand : PlatformCommand {
19+
20+
companion object {
21+
22+
val unknownCommandMessage get() = System.getProperty("taboolib.application.command.unknown.message")
23+
?: "§cUnknown command.".apply { System.setProperty("taboolib.application.command.unknown.message", this) }
24+
25+
val commands = mutableSetOf<Command>()
26+
27+
fun register(command: Command) {
28+
commands.add(command)
29+
}
30+
31+
fun unregister(name: String) {
32+
val command = commands.find { it.command.aliases.contains(name) } ?: return
33+
unregister(name)
34+
}
35+
36+
fun unregister(command: Command) {
37+
commands.remove(command)
38+
}
39+
40+
fun runCommand(content: String) {
41+
if (content.isBlank()) {
42+
return
43+
}
44+
val label = if (content.contains(" ")) content.substringBefore(" ") else content
45+
val command = commands.find { it.aliases.contains(label) } ?: return logger.info(unknownCommandMessage)
46+
val args = if (content.contains(" ")) content.substringAfter(" ").split(" ") else listOf()
47+
48+
command.executor.execute(AppConsole, command.command, label, args.toTypedArray())
49+
}
50+
51+
fun suggest(content: String): List<String> {
52+
fun suggestion() = commands.flatMap { it.aliases }
53+
54+
if (content.isBlank()) {
55+
return suggestion()
56+
}
57+
val label = if (content.contains(" ")) content.substringBefore(" ") else content
58+
59+
val command =
60+
commands.find { it.aliases.contains(label) } ?: return suggestion().filter { it.startsWith(label) }
61+
62+
return if (content.contains(" ")) {
63+
command.completer.execute(
64+
AppConsole,
65+
command.command,
66+
label,
67+
content.substringAfter(" ").split(" ").toTypedArray()
68+
) ?: listOf()
69+
} else {
70+
listOf()
71+
}
72+
}
73+
}
74+
75+
76+
data class Command(
77+
val command: CommandStructure,
78+
val executor: CommandExecutor,
79+
val completer: CommandCompleter,
80+
val commandBuilder: CommandBase.() -> Unit
81+
) {
82+
83+
val aliases get() = listOf(command.name, *command.aliases.toTypedArray())
84+
85+
fun register() =
86+
AppCommand.register(this)
87+
88+
fun unregister() =
89+
AppCommand.unregister(this)
90+
91+
}
92+
93+
override fun registerCommand(
94+
command: CommandStructure,
95+
executor: CommandExecutor,
96+
completer: CommandCompleter,
97+
commandBuilder: CommandBase.() -> Unit
98+
) {
99+
register(Command(command, executor, completer, commandBuilder))
100+
}
101+
102+
override fun unknownCommand(sender: ProxyCommandSender, command: String, state: Int) {
103+
sender.sendMessage("§7$command§r§c§o<--[HERE]")
104+
}
105+
106+
override fun unregisterCommand(label: String) {
107+
unregister(commands.find { it.command.aliases.contains(label) } ?: return)
108+
}
109+
110+
override fun unregisterCommands() {
111+
commands.forEach {
112+
unregister(it)
113+
}
114+
}
115+
116+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package taboolib.platform
2+
3+
import net.minecrell.terminalconsole.SimpleTerminalConsole
4+
import org.apache.logging.log4j.Level
5+
import org.apache.logging.log4j.LogManager
6+
import org.apache.logging.log4j.io.IoBuilder
7+
import org.jline.reader.Candidate
8+
import org.jline.reader.LineReader
9+
import org.jline.reader.LineReaderBuilder
10+
import taboolib.common.LifeCycle
11+
import taboolib.common.TabooLibCommon
12+
import taboolib.common.platform.Awake
13+
import taboolib.common.platform.Platform
14+
import taboolib.common.platform.PlatformSide
15+
import taboolib.common.platform.ProxyCommandSender
16+
import taboolib.common.platform.command.command
17+
import taboolib.common.platform.function.pluginId
18+
import taboolib.common.platform.function.pluginVersion
19+
20+
/**
21+
* @author Score2
22+
* @since 2022/06/08 13:37
23+
*/
24+
@Awake
25+
@PlatformSide([Platform.APPLICATION])
26+
object AppConsole : SimpleTerminalConsole(), ProxyCommandSender {
27+
28+
val logger = LogManager.getLogger(AppConsole::class.java)
29+
30+
override var isOp = true
31+
override val name = "CONSOLE"
32+
override val origin: Any = this
33+
34+
@Awake(LifeCycle.LOAD)
35+
fun load() {
36+
System.setOut(IoBuilder.forLogger(logger).setLevel(Level.INFO).buildPrintStream())
37+
System.setErr(IoBuilder.forLogger(logger).setLevel(Level.WARN).buildPrintStream())
38+
39+
command("about", description = "about this server") {
40+
execute<ProxyCommandSender> { sender, context, argument ->
41+
sender.sendMessage("§r$pluginId v$pluginVersion")
42+
sender.sendMessage("§rThere are console application booting by §cTabooLib")
43+
}
44+
}
45+
command("help", aliases = listOf("?"), description = "suggest commands") {
46+
execute<ProxyCommandSender> { sender, context, argument ->
47+
sender.sendMessage("§rRegisted §a${AppCommand.commands.size} §rcommands, list:")
48+
AppCommand.commands.forEach {
49+
sender.sendMessage("§r✦ §a${it.command.name}§r<${it.command.aliases.joinToString()}> §8- §2${it.command.description}")
50+
}
51+
}
52+
}
53+
command("stop", aliases = listOf("shutdown"), description = "stop the server") {
54+
execute<ProxyCommandSender> { sender, context, argument ->
55+
TabooLibCommon.testCancel()
56+
}
57+
}
58+
}
59+
60+
@Awake(LifeCycle.ENABLE)
61+
fun enable() {
62+
object : Thread("console handler") {
63+
override fun run() {
64+
AppConsole.start()
65+
}
66+
}.run {
67+
isDaemon = true
68+
start()
69+
}
70+
}
71+
72+
override fun isRunning(): Boolean {
73+
return !TabooLibCommon.isStopped()
74+
}
75+
76+
override fun buildReader(builder: LineReaderBuilder): LineReader {
77+
builder
78+
.appName(pluginId)
79+
.completer { reader, line, candidates ->
80+
val buffer = line.line()
81+
AppCommand.suggest(buffer).forEach {
82+
candidates.add(Candidate(it))
83+
}
84+
85+
}
86+
.option(LineReader.Option.COMPLETE_IN_WORD, true);
87+
88+
return super.buildReader(builder)
89+
}
90+
91+
override fun runCommand(command: String) {
92+
AppCommand.runCommand(command)
93+
}
94+
95+
override fun shutdown() {
96+
TabooLibCommon.testCancel()
97+
}
98+
99+
override fun hasPermission(permission: String): Boolean {
100+
return true
101+
}
102+
103+
override fun isOnline(): Boolean {
104+
return true
105+
}
106+
107+
override fun performCommand(command: String): Boolean {
108+
AppCommand.runCommand(command)
109+
return true
110+
}
111+
112+
override fun sendMessage(message: String) {
113+
logger.info(message)
114+
}
115+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
log4j.skipJansi=true
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Configuration status="WARN" packages="net.minecrell.terminalconsole">
3+
<Appenders>
4+
<TerminalConsole name="TerminalConsole">
5+
<PatternLayout pattern="[%d{HH:mm:ss} %style{%highlight{%level}{FATAL=red dark, ERROR=red, WARN=yellow bright, INFO=cyan bright, DEBUG=green, TRACE=white}}] %minecraftFormatting{%msg}%n"/>
6+
</TerminalConsole>
7+
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
8+
<PatternLayout pattern="[%d{HH:mm:ss.SSS} %t/%level] %minecraftFormatting{%msg}{strip}%n"/>
9+
<Policies>
10+
<TimeBasedTriggeringPolicy/>
11+
<OnStartupTriggeringPolicy/>
12+
</Policies>
13+
</RollingRandomAccessFile>
14+
</Appenders>
15+
<Loggers>
16+
<Root level="INFO">
17+
<AppenderRef ref="TerminalConsole"/>
18+
<AppenderRef ref="File"/>
19+
</Root>
20+
</Loggers>
21+
</Configuration>

platform/platform-application/src/main/kotlin/taboolib/platform/AppIO.kt

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,18 @@ class AppIO : PlatformIO {
2424
val date: String
2525
get() = DateFormatUtils.format(System.currentTimeMillis(), "HH:mm:ss")
2626

27-
override val pluginId: String
28-
get() = "application"
27+
val isLog4jEnabled by lazy {
28+
try {
29+
Class.forName("org.apache.log4j.Logger")
30+
true
31+
} catch (e: ClassNotFoundException) {
32+
false
33+
}
34+
}
35+
36+
override var pluginId = "application"
2937

30-
override val pluginVersion: String
31-
get() = "application"
38+
override var pluginVersion = "application"
3239

3340
override val isPrimaryThread: Boolean
3441
get() = true
@@ -38,15 +45,30 @@ class AppIO : PlatformIO {
3845
}
3946

4047
override fun info(vararg message: Any?) {
41-
message.filterNotNull().forEach { println("[${date}][INFO] $it") }
48+
message.filterNotNull().forEach {
49+
if (isLog4jEnabled)
50+
println(it)
51+
else
52+
println("[${date}][INFO] $it")
53+
}
4254
}
4355

4456
override fun severe(vararg message: Any?) {
45-
message.filterNotNull().forEach { println("[${date}][ERROR] $it") }
57+
message.filterNotNull().forEach {
58+
if (isLog4jEnabled)
59+
println(it)
60+
else
61+
println("[${date}][ERROR] $it")
62+
}
4663
}
4764

4865
override fun warning(vararg message: Any?) {
49-
message.filterNotNull().forEach { println("[${date}][WARN] $it") }
66+
message.filterNotNull().forEach {
67+
if (isLog4jEnabled)
68+
println(it)
69+
else
70+
println("[${date}][WARN] $it")
71+
}
5072
}
5173

5274
override fun releaseResourceFile(path: String, replace: Boolean): File {

settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ fun importExtensions() {
4141
include("expansion:expansion-geek-tool")
4242
include("expansion:expansion-lang-tools")
4343
include("expansion:expansion-ioc")
44+
include("expansion:expansion-application-console")
4445
// 从 common-5 中移除
4546
include("expansion:expansion-javascript")
4647
}

0 commit comments

Comments
 (0)