no idea what that did

This commit is contained in:
Wieland Schöbl
2021-01-08 15:30:22 +01:00
parent 8b98d4ba3c
commit a8b148c4c7
10 changed files with 499 additions and 38 deletions

12
.idea/HytaleUpdateBot.iml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="HytaleUpdateBot:main" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="de.wulkanat" external.system.module.version="1.4.2" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/HytaleUpdateBot.iml" filepath="$PROJECT_DIR$/.idea/HytaleUpdateBot.iml" />
</modules>
</component>
</project>

90
.idea/workspace.xml generated
View File

@@ -4,11 +4,9 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="1aabf22b-2f57-46ac-9973-367d8668ffd3" name="Default Changelist" comment="fix crash on missing permission&#10;add removeInactive command">
<change afterPath="$PROJECT_DIR$/.idea/compiler.xml" afterDir="false" />
<list default="true" id="1aabf22b-2f57-46ac-9973-367d8668ffd3" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/build.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/build.gradle" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/web/SiteWatcher.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/web/SiteWatcher.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/OwnerCli.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/OwnerCli.kt" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -33,6 +31,11 @@
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="HytaleUpdateBot" type="f1a62948:ProjectNode" />
</path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="HytaleUpdateBot" type="f1a62948:ProjectNode" />
<item name="Tasks" type="e4a08cd1:TasksNode" />
</path>
</expand>
<select />
</tree_state>
@@ -61,6 +64,9 @@
<component name="HighlightingSettingsPerFile">
<setting file="file://$PROJECT_DIR$/build.gradle" root0="SKIP_INSPECTION" />
</component>
<component name="MacroExpansionManager">
<option name="directoryName" value="5kk4ojxu" />
</component>
<component name="ProjectId" id="1g2oQiuUv1Bu6ZCW2NSVzB1V6Sc" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectViewState">
@@ -70,24 +76,25 @@
<component name="PropertiesComponent">
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/build/libs" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/cli" />
<property name="project.structure.last.edited" value="Modules" />
<property name="project.structure.proportion" value="0.15" />
<property name="project.structure.side.proportion" value="0.2" />
<property name="settings.editor.selected.configurable" value="reference.settingsdialog.project.gradle" />
</component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="E:\Projects\Kotlin_Proj\HytaleUpdateBot" />
<recent name="E:\Projects\Kotlin_Proj\HytaleUpdateBot\src\main\kotlin\de\wulkanat" />
</key>
<key name="MoveKotlinTopLevelDeclarationsDialog.RECENTS_KEY">
<recent name="de.wulkanat" />
</key>
<key name="CopyFile.RECENT_KEYS">
<recent name="E:\Projects\Kotlin_Proj\HytaleUpdateBot\src\main\kotlin\de\wulkanat\cli" />
<recent name="E:\Projects\Kotlin_Proj\HytaleUpdateBot\build\libs" />
<recent name="E:\Projects\Kotlin_Proj\HytaleUpdateBot\src" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="E:\Projects\Kotlin_Proj\HytaleUpdateBot" />
<recent name="E:\Projects\Kotlin_Proj\HytaleUpdateBot\src\main\kotlin\de\wulkanat" />
</key>
</component>
<component name="RunManager" selected="Gradle.HytaleUpdateBot [fatJar]">
<configuration name="HytaleUpdateBot [build]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
@@ -106,7 +113,9 @@
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
<configuration name="HytaleUpdateBot [clean]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
@@ -125,7 +134,9 @@
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
<configuration name="HytaleUpdateBot [fatJar]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
@@ -144,7 +155,9 @@
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
<configuration name="HytaleUpdateBot-all-1.0-SNAPSHOT.jar" type="JarApplication" temporary="true">
@@ -166,14 +179,15 @@
</configuration>
<recent_temporary>
<list>
<item itemvalue="Kotlin.MainKt" />
<item itemvalue="Gradle.HytaleUpdateBot [fatJar]" />
<item itemvalue="Gradle.HytaleUpdateBot [build]" />
<item itemvalue="Gradle.HytaleUpdateBot [clean]" />
<item itemvalue="Application.MainKt" />
<item itemvalue="JAR Application.HytaleUpdateBot-all-1.0-SNAPSHOT.jar" />
<item itemvalue="Gradle.HytaleUpdateBot [fatJar]" />
<item itemvalue="Gradle.HytaleUpdateBot [clean]" />
<item itemvalue="Gradle.HytaleUpdateBot [build]" />
</list>
</recent_temporary>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="project-level" UseSingleDictionary="true" transferred="true" />
<component name="SvnConfiguration">
<configuration />
</component>
@@ -220,7 +234,14 @@
<option name="project" value="LOCAL" />
<updated>1601042375685</updated>
</task>
<option name="localTasksCounter" value="6" />
<task id="LOCAL-00006" summary="fix connection failed message not disappearing">
<created>1601042672099</created>
<option name="number" value="00006" />
<option name="presentableId" value="LOCAL-00006" />
<option name="project" value="LOCAL" />
<updated>1601042672099</updated>
</task>
<option name="localTasksCounter" value="7" />
<servers />
</component>
<component name="VcsManagerConfiguration">
@@ -229,13 +250,14 @@
<MESSAGE value="Add service announcement channel" />
<MESSAGE value="fix crash on missing permission&#10;add removeInactive command" />
<MESSAGE value="prepare twitter integration" />
<option name="LAST_COMMIT_MESSAGE" value="prepare twitter integration" />
<MESSAGE value="fix connection failed message not disappearing" />
<option name="LAST_COMMIT_MESSAGE" value="fix connection failed message not disappearing" />
</component>
<component name="WindowStateProjectService">
<state x="552" y="179" key="#Project_Structure" timestamp="1597687666334">
<state x="552" y="179" key="#Project_Structure" timestamp="1601148661909">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="552" y="179" key="#Project_Structure/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597687666334" />
<state x="552" y="179" key="#Project_Structure/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1601148661909" />
<state x="-1050" y="581" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1597352463714">
<screen x="-1050" y="105" width="1050" height="1640" />
</state>
@@ -260,34 +282,34 @@
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="128" y="270" width="490" height="591" key="#xdebugger.evaluate/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597332665464" />
<state x="569" y="115" key="CommitChangelistDialog2" timestamp="1598896749015">
<state x="569" y="115" key="CommitChangelistDialog2" timestamp="1601042670025">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="569" y="115" key="CommitChangelistDialog2/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1598896749015" />
<state x="569" y="115" key="CommitChangelistDialog2/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1601042670025" />
<state x="740" y="238" key="FileChooserDialogImpl" timestamp="1597605616287">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="740" y="238" key="FileChooserDialogImpl/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597605616287" />
<state width="1876" height="161" key="GridCell.Tab.0.bottom" timestamp="1598896802046">
<state width="1877" height="161" key="GridCell.Tab.0.bottom" timestamp="1601059408217">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1006" height="588" key="GridCell.Tab.0.bottom/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@-1050.105.1050.1640" timestamp="1597351329412" />
<state width="1876" height="161" key="GridCell.Tab.0.bottom/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1598896802046" />
<state width="1876" height="161" key="GridCell.Tab.0.center" timestamp="1598896802046">
<state width="1877" height="161" key="GridCell.Tab.0.bottom/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1601059408217" />
<state width="1877" height="161" key="GridCell.Tab.0.center" timestamp="1601059408216">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1006" height="588" key="GridCell.Tab.0.center/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@-1050.105.1050.1640" timestamp="1597351329411" />
<state width="1876" height="161" key="GridCell.Tab.0.center/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1598896802046" />
<state width="1876" height="161" key="GridCell.Tab.0.left" timestamp="1598896802046">
<state width="1877" height="161" key="GridCell.Tab.0.center/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1601059408216" />
<state width="1877" height="161" key="GridCell.Tab.0.left" timestamp="1601059408216">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1006" height="588" key="GridCell.Tab.0.left/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@-1050.105.1050.1640" timestamp="1597351329411" />
<state width="1876" height="161" key="GridCell.Tab.0.left/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1598896802046" />
<state width="1876" height="161" key="GridCell.Tab.0.right" timestamp="1598896802046">
<state width="1877" height="161" key="GridCell.Tab.0.left/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1601059408216" />
<state width="1877" height="161" key="GridCell.Tab.0.right" timestamp="1601059408216">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1006" height="588" key="GridCell.Tab.0.right/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@-1050.105.1050.1640" timestamp="1597351329411" />
<state width="1876" height="161" key="GridCell.Tab.0.right/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1598896802046" />
<state width="1877" height="161" key="GridCell.Tab.0.right/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1601059408216" />
<state width="1876" height="348" key="GridCell.Tab.1.bottom" timestamp="1597840755247">
<screen x="0" y="0" width="1920" height="1040" />
</state>
@@ -308,6 +330,10 @@
</state>
<state width="1006" height="588" key="GridCell.Tab.1.right/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@-1050.105.1050.1640" timestamp="1597351329412" />
<state width="1876" height="348" key="GridCell.Tab.1.right/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597840755247" />
<state x="540" y="255" key="IDE.errors.dialog" timestamp="1601148874155">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="540" y="255" key="IDE.errors.dialog/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1601148874155" />
<state x="672" y="237" key="MultipleFileMergeDialog" timestamp="1597438068748">
<screen x="0" y="0" width="1920" height="1040" />
</state>
@@ -317,10 +343,10 @@
</state>
<state x="-1040" y="568" key="SettingsEditor/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@-1050.105.1050.1640" timestamp="1597353858648" />
<state x="94" y="257" key="SettingsEditor/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597361509050" />
<state x="552" y="254" key="Vcs.Push.Dialog.v2" timestamp="1597839957675">
<state x="552" y="254" key="Vcs.Push.Dialog.v2" timestamp="1601042674727">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="552" y="254" key="Vcs.Push.Dialog.v2/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597839957675" />
<state x="552" y="254" key="Vcs.Push.Dialog.v2/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1601042674727" />
<state x="777" y="434" key="com.intellij.openapi.vcs.update.UpdateOrStatusOptionsDialogupdate-v2" timestamp="1601042455663">
<screen x="0" y="0" width="1920" height="1040" />
</state>

View File

@@ -1,12 +1,103 @@
package de.wulkanat
import net.dv8tion.jda.api.EmbedBuilder
import net.dv8tion.jda.api.Permission
import net.dv8tion.jda.api.events.message.MessageReceivedEvent
import de.wulkanat.cli.Cli
import de.wulkanat.cli.makeCli
import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent
import net.dv8tion.jda.api.hooks.ListenerAdapter
import java.awt.Color
class OwnerCli : ListenerAdapter() {
private val cli: Cli<PrivateMessageReceivedEvent> = makeCli(prefix = "!") {
command name "add" does "Add this channel to the notified list" through ::OwnerCliStuff.addChannel
command name "remove" does "Remove this channel to the notified list" through removeChannel
command name "publish" with { required literal argument with "on" or "off" } does
"[Community|Partner|Verified only] Auto publish the message if in an announcement channel" through publish
command name "ping" with { required string argument } does "What role to ping" through ping
command name "setMessage" with { required string argument } does "Set a custom message to show" through setMessage
}
}
object OwnerCliStuff {
private fun addChannel(_required: List<String>, _optional: MutableMap<String, String>, event: PrivateMessageReceivedEvent) {
val result = Channels.addChannel(event.channel.idLong, null)
if (result == null) {
event.message.channel.sendMessage("Already added.").queue()
} else {
event.message.channel.sendMessage("Added.").queue()
Admin.info()
}
}
private val removeChannel =
{ _: List<String>, _: MutableMap<String, String>, event: PrivateMessageReceivedEvent ->
val result = Channels.channels.removeAll { it.id == event.channel.idLong }
Channels.saveChannels()
if (result) {
event.message.channel.sendMessage("Removed.").queue()
} else {
event.message.channel.sendMessage("This channel is not registered.").queue()
}
}
private val publish =
publish@{ required: List<String>, _: MutableMap<String, String>, event: PrivateMessageReceivedEvent ->
val channel = Channels.channels.find { it.id == event.channel.idLong } ?: run {
event.message.channel.sendMessage("Channel not registered.").queue()
return@publish
}
channel.autoPublish = required.first() == "on"
Channels.saveChannels()
event.message.channel.sendMessage("Auto publish is now ${required.first()}").queue()
}
private val ping =
ping@{ required: List<String>, _: MutableMap<String, String>, event: PrivateMessageReceivedEvent ->
val channel = Channels.channels.find { it.id == event.channel.idLong } ?: run {
event.message.channel.sendMessage("Channel is not registered.").queue()
return@ping
}
val roleName = required.first()
val role = event.message.guild.getRolesByName(required.first(), false).firstOrNull()
channel.mentionedRole = when {
roleName == "everyone" -> {
event.message.channel.sendMessage("Now pinging $roleName.").queue()
roleName
}
roleName == "none" -> {
event.message.channel.sendMessage("Now pinging $roleName.").queue()
null
}
role != null -> {
event.message.channel.sendMessage("Now pinging ${role.name}").queue()
role.id
}
else -> {
event.message.channel.sendMessage("Unknown role.").queue()
channel.mentionedRole
}
}
Channels.saveChannels()
}
private val setMessage =
setMessage@{ required: List<String>, _: MutableMap<String, String>, event: PrivateMessageReceivedEvent ->
val result = Channels.channels.find { it.id == event.channel.channelId } ?: run {
event.message.channel.sendMessage("Channel is not registered.").queue()
return@setMessage
}
val message = required.first()
result.message = CustomMessage(message)
Channels.saveChannels()
event.message.channel.sendMessage("Set `$message` as message.").queue()
}
}
/*class OwnerCli2 : ListenerAdapter() {
private val prefix = "%!"
override fun onMessageReceived(event: MessageReceivedEvent) {
@@ -211,5 +302,5 @@ class OwnerCli : ListenerAdapter() {
).queue()
}
}
}
}
}*
}*/

View File

@@ -0,0 +1,18 @@
package de.wulkanat.cli
enum class ArgumentType(val match: Regex, val stringName: String) {
INT(Regex("\\d+"), "int"),
FLOAT(Regex("\\d+(?:.\\d+)?"), "float"),
STRING(Regex("[\\s\\S]+"), "string"),
BOOLEAN(Regex("true|false"), "bool"),
LITERAL(Regex("[\\s\\S]+"), "literal"),
EXISTS(Regex("[\\s\\S]+"), "existence");
fun usage(literals: Map<String, List<String>>, name: String): String {
return when (this) {
LITERAL -> "${literals[name]?.joinToString(separator = "|")}"
EXISTS -> ""
else -> stringName
}
}
}

View File

@@ -0,0 +1,216 @@
package de.wulkanat.cli
class Cli<T>(var prefix: String = ".") {
val commands = mutableMapOf<String, Command<T>>()
fun parse(
command: String,
passThrough: T,
helpMessage: (Cli<T>) -> Unit = {},
commandMisuse: (Command<T>, String) -> Unit = { _, _ -> }
): Boolean? {
if (!command.startsWith(prefix)) return false // not a command
val msg =
Regex("[^\\s`]+|`[^`]*`").findAll(command.removePrefix(prefix)).toList().map { it.value }
if (msg[0] == "help") {
helpMessage(this)
return true
}
val realCommand = commands[msg[0]] ?: return false // command not found
val (required, optional) = realCommand.arguments
if (msg.size < required.list.size + 1) {
commandMisuse(realCommand, "Too few arguments!")
return null
}
val requiredOut: MutableList<String> = mutableListOf()
val optionalOut: MutableMap<String, String> = mutableMapOf()
for (i in 1..required.list.size) {
val (name, type) = required.list[i - 1]
requiredOut.add(
when (type) {
ArgumentType.LITERAL -> required.literals[name]?.find { it == msg[i] }?.toString()
else -> type.match.matchEntire(msg[i])?.value
} ?: kotlin.run {
commandMisuse(realCommand, "Argument '${msg[i]}' is not of type ${type.stringName}!")
return@parse null
}
)
}
var i = required.list.size + 1
while (i < required.list.size + 1) {
val key = optional.shorts[msg[i]] ?: msg[i]
val value = optional.list[optional.shorts[msg[i]] ?: msg[i]] ?: kotlin.run {
commandMisuse(realCommand, "Unknown optional argument '$key'")
return@parse null
}
optionalOut[key] = when (value) {
ArgumentType.LITERAL -> optional.literals[key]?.find { it == msg[i] }?.toString()
else -> value.match.matchEntire(msg[i])?.value
} ?: kotlin.run {
commandMisuse(realCommand, "Argument '$key' is not of type ${value.stringName}!")
return@parse null
}
i += if (value == ArgumentType.EXISTS) 1 else 2
}
realCommand.action(requiredOut, optionalOut, passThrough)
return true // success
}
fun usage(): String {
return commands.map { "$prefix${it.value.usage()}" }.joinToString("\n")
}
infix fun prefix(func: Cli<T>.() -> Unit): Cli<T> {
func()
return this
}
inner class CommandBuilder {
infix fun name(name: String): CommandBuilder2 {
return CommandBuilder2(name)
}
}
inner class CommandBuilder2(val name: String) {
val argumentBuilder = ArgumentBuilder()
var descriptionLocal = ""
infix fun does(description: String): DoesHelper {
descriptionLocal = description
return DoesHelper()
}
inner class DoesHelper {
infix fun through(action: (required: List<String>, optional: MutableMap<String, String>, passthrough: T) -> Unit): Command<T> {
return Command(name, descriptionLocal, action, argumentBuilder).also { commands[name] = it }
}
}
infix fun with(action: ArgumentBuilder.() -> Unit): CommandBuilder2 {
argumentBuilder.action()
return this
}
inner class ArgumentBuilder {
val required = RequiredArgHelper()
val optional = OptionalArgHelper()
operator fun component1() = required
operator fun component2() = optional
inner class RequiredArgHelper {
val list: MutableList<Pair<String, ArgumentType>> = mutableListOf()
val literals: MutableMap<String, MutableList<String>> = mutableMapOf()
infix fun int(name: String) {
list.add(Pair(name, ArgumentType.INT))
}
infix fun float(name: String) {
list.add(Pair(name, ArgumentType.FLOAT))
}
infix fun string(name: String) {
list.add(Pair(name, ArgumentType.STRING))
}
infix fun literal(name: String): LiteralHelper {
list.add(Pair(name, ArgumentType.LITERAL))
return LiteralHelper(name)
}
infix fun bool(name: String) {
list.add(Pair(name, ArgumentType.BOOLEAN))
}
inner class LiteralHelper(val name: String) {
infix fun with(literalsList: String): LiteralHelperHelper {
val list = mutableListOf(literalsList)
literals[name] = list
return LiteralHelperHelper(list)
}
inner class LiteralHelperHelper(private val listListList: MutableList<String>) {
infix fun or(other: String): LiteralHelperHelper {
listListList.add(other)
return this
}
}
}
}
inner class OptionalArgHelper {
val list: MutableMap<String, ArgumentType> = mutableMapOf()
val shorts: MutableMap<String, String> = mutableMapOf()
val literals: MutableMap<String, List<String>> = mutableMapOf()
inner class ShortsHelper(val name: String, val shortsMap: MutableMap<String, String>) {
infix fun short(shortName: String) {
shortsMap[shortName] = name
}
}
infix fun int(name: String): ShortsHelper {
list[name] = ArgumentType.INT
return ShortsHelper(name, shorts)
}
infix fun float(name: String): ShortsHelper {
list[name] = ArgumentType.FLOAT
return ShortsHelper(name, shorts)
}
infix fun string(name: String): ShortsHelper {
list[name] = ArgumentType.STRING
return ShortsHelper(name, shorts)
}
infix fun bool(name: String): ShortsHelper {
list[name] = ArgumentType.BOOLEAN
return ShortsHelper(name, shorts)
}
infix fun literal(name: String): LiteralHelper {
list[name] = ArgumentType.LITERAL
return LiteralHelper(name)
}
infix fun existence(name: String): ShortsHelper {
list[name] = ArgumentType.EXISTS
return ShortsHelper(name, shorts)
}
inner class LiteralHelper(val name: String) {
infix fun with(literalsList: String): LiteralHelperHelper {
val list = mutableListOf<String>()
literals[name] = list
return LiteralHelperHelper(list)
}
inner class LiteralHelperHelper(private val listListList: MutableList<String>) {
infix fun or(other: String): LiteralHelperHelper {
listListList.add(other)
return this
}
}
}
}
}
}
val argument = "REQUIRED_TYPE"
val command = CommandBuilder()
val nothing: (List<String>, MutableMap<String, String>, T) -> Unit = { _, _, _ -> }
}

View File

@@ -0,0 +1,52 @@
package de.wulkanat.cli
import net.dv8tion.jda.api.EmbedBuilder
import net.dv8tion.jda.api.entities.MessageEmbed
fun <T> Command<T>.discordUsage(): String {
return "${name}_ ${arguments.required.list
.joinToString(separator = " ") {
"**[**${it.first/*it.second.discordUsage(
arguments.required.literals,
it.first
)*/}**]**"
}} ${arguments.optional.list
.map {
"--${it.key}${arguments.optional.shorts[name]?.let { short -> " _-${short}_ " } ?: ""
}${if (it.value == ArgumentType.EXISTS) "" else " **<**${it.value.stringName}**>**"}"
}
.joinToString(separator = " ")}"
}
fun ArgumentType.discordUsage(literals: Map<String, List<String>>, name: String): String {
return when (this) {
ArgumentType.LITERAL -> "${literals[name]?.joinToString(separator = "**|**")}"
ArgumentType.EXISTS -> ""
else -> stringName
}
}
fun <T> Command<T>.discordUsageEmbed(footer: String?): MessageEmbed {
return EmbedBuilder()
.setTitle("Usage:")
.setDescription("_${discordUsage()}")
.also { builder -> footer?.let { builder.setFooter(footer) } }
.build()
}
fun <T> Cli<T>.discordUsage(): String {
return commands.map { "_$prefix${it.value.discordUsage()}" }.joinToString("\n")
}
fun <T> Cli<T>.discordUsageEmbed(): MessageEmbed {
return EmbedBuilder()
.setTitle("Help")
.also {
commands.map { Pair(it.value.description, "_$prefix${it.value.discordUsage()}") }
.forEach { (title, description) ->
it.addField(title, description, false)
}
}
.setFooter("Commands are case-sensitive.")
.build()
}

View File

@@ -0,0 +1,7 @@
package de.wulkanat.cli
fun <T>makeCli(prefix: String = "!", func: Cli<T>.() -> Unit): Cli<T> {
val cli = Cli<T>(prefix)
cli.func()
return cli
}

View File

@@ -0,0 +1,23 @@
package de.wulkanat.cli
class Command<T>(
val name: String,
val description: String,
val action: (required: List<String>, optional: MutableMap<String, String>, passthrough: T) -> Unit,
val arguments: Cli<T>.CommandBuilder2.ArgumentBuilder
) {
fun usage(): String {
return "$name ${arguments.required.list
.joinToString(separator = " ") {
"[${it.second.usage(
arguments.required.literals,
it.first
)}]"
}} ${arguments.optional.list
.map {
"--${it.key}${arguments.optional.shorts[name]?.let { short -> " -$short " } ?: ""
}${if (it.value == ArgumentType.EXISTS) "" else " <${it.value.stringName}>"}"
}
.joinToString(separator = " ")}"
}
}

8
twitter.json Normal file
View File

@@ -0,0 +1,8 @@
{
"env": "dev",
"accessToken": "1075173710557011968-OfPSjYUF6IDYtOl8yeo1x1EzXVlZWD",
"accessTokenSecret": "ikcLkku0lSNMVY7kgWcj7j7tfk3IHpHUYIkvJACp0zZXh",
"apiKey": "8rm4wAHVLXYauBbRDKAVro0kw",
"apiSecretKey": "vPZgiPxwqqHZXQGMPyxyuQrg8y45t1fAlOar9DpVlPa10JRAfC",
"bearerToken": "AAAAAAAAAAAAAAAAAAAAAJNnHwEAAAAAKVRDEbr2dzzum2wswMGOyJOQHJw%3DgniWSdhaXgcey4XBHQckZSVVXtP6y83wAp0sxnSp3CwbWpXoA3"
}