2 Commits

Author SHA1 Message Date
Wieland Schöbl
fcaa8377c1 Move connection failed message to Admin 2021-01-08 15:41:37 +01:00
Wieland Schöbl
4c4e4dc992 Update README.md 2020-10-28 16:24:26 +01:00
14 changed files with 43 additions and 588 deletions

View File

@@ -1,12 +0,0 @@
<?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>

View File

@@ -2,6 +2,7 @@
<dictionary name="wulkanat">
<words>
<w>crosspost</w>
<w>hytale</w>
</words>
</dictionary>
</component>

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?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>

167
.idea/workspace.xml generated
View File

@@ -4,9 +4,9 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="1aabf22b-2f57-46ac-9973-367d8668ffd3" name="Default Changelist" comment="">
<list default="true" id="1aabf22b-2f57-46ac-9973-367d8668ffd3" name="Default Changelist" comment="no idea what that did">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" 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" />
<change beforePath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/DiscordRpc.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/DiscordRpc.kt" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -31,11 +31,6 @@
<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>
@@ -56,7 +51,7 @@
<component name="Git.Settings">
<option name="RECENT_BRANCH_BY_REPOSITORY">
<map>
<entry key="$PROJECT_DIR$" value="add-twitter-integration" />
<entry key="$PROJECT_DIR$" value="not-sure" />
</map>
</option>
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
@@ -65,7 +60,7 @@
<setting file="file://$PROJECT_DIR$/build.gradle" root0="SKIP_INSPECTION" />
</component>
<component name="MacroExpansionManager">
<option name="directoryName" value="5kk4ojxu" />
<option name="directoryName" value="o7p0t8es" />
</component>
<component name="ProjectId" id="1g2oQiuUv1Bu6ZCW2NSVzB1V6Sc" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
@@ -76,27 +71,26 @@
<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$/src/main/kotlin/de/wulkanat/cli" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/build/libs" />
<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]">
<component name="RunManager" selected="Application.MainKt">
<configuration name="HytaleUpdateBot [build]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
<ExternalSystemSettings>
<option name="executionName" />
@@ -179,11 +173,10 @@
</configuration>
<recent_temporary>
<list>
<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]" />
<item itemvalue="Gradle.HytaleUpdateBot [clean]" />
<item itemvalue="JAR Application.HytaleUpdateBot-all-1.0-SNAPSHOT.jar" />
</list>
</recent_temporary>
</component>
@@ -234,136 +227,28 @@
<option name="project" value="LOCAL" />
<updated>1601042375685</updated>
</task>
<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" />
<option name="localTasksCounter" value="6" />
<servers />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
<option name="oldMeFiltersMigrated" value="true" />
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="Add auto publish feature" />
<MESSAGE value="[1.1]" />
<MESSAGE value="Add service announcement channel" />
<MESSAGE value="fix crash on missing permission&#10;add removeInactive command" />
<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="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="1601148661909" />
<state x="-1050" y="581" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1597352463714">
<screen x="-1050" y="105" width="1050" height="1640" />
</state>
<state x="-1050" y="581" key="#com.intellij.execution.impl.EditConfigurationsDialog/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@-1050.105.1050.1640" timestamp="1597352463714" />
<state x="640" y="249" key="#com.intellij.openapi.updateSettings.impl.PluginUpdateInfoDialog" timestamp="1597933755909">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="640" y="249" key="#com.intellij.openapi.updateSettings.impl.PluginUpdateInfoDialog/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597933755909" />
<state x="633" y="446" key="#com.intellij.refactoring.move.MoveHandler.SelectRefactoringDialog" timestamp="1597362173063">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="633" y="446" key="#com.intellij.refactoring.move.MoveHandler.SelectRefactoringDialog/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597362173063" />
<state x="690" y="268" key="#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog" timestamp="1597831342920">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="690" y="268" key="#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597831342920" />
<state x="739" y="173" width="484" height="693" key="#org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui.MoveKotlinTopLevelDeclarationsDialog" timestamp="1597362199927">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="739" y="173" width="484" height="693" key="#org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui.MoveKotlinTopLevelDeclarationsDialog/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597362199927" />
<state x="128" y="270" width="490" height="591" key="#xdebugger.evaluate" timestamp="1597332665464">
<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="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="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="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="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="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="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="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>
<state width="1006" height="588" key="GridCell.Tab.1.bottom/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.bottom/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597840755247" />
<state width="1876" height="348" key="GridCell.Tab.1.center" timestamp="1597840755246">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1006" height="588" key="GridCell.Tab.1.center/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.center/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597840755246" />
<state width="1876" height="348" key="GridCell.Tab.1.left" timestamp="1597840755246">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1006" height="588" key="GridCell.Tab.1.left/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.left/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597840755246" />
<state width="1876" height="348" key="GridCell.Tab.1.right" timestamp="1597840755247">
<screen x="0" y="0" width="1920" height="1040" />
</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>
<state x="672" y="237" key="MultipleFileMergeDialog/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597438068748" />
<state x="94" y="257" key="SettingsEditor" timestamp="1597361509050">
<screen x="0" y="0" width="1920" height="1040" />
</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="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="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>
<state x="777" y="434" key="com.intellij.openapi.vcs.update.UpdateOrStatusOptionsDialogupdate-v2/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1601042455663" />
<state x="497" y="233" key="new project wizard" timestamp="1597841063797">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="497" y="233" key="new project wizard/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597841063797" />
<state x="2582" y="100" key="new project wizard/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@1920.-213.2560.1400" timestamp="1597605657341" />
<state x="616" y="240" key="run.anything.popup" timestamp="1597325088886">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="616" y="240" key="run.anything.popup/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597325088886" />
<state x="623" y="225" width="672" height="678" key="search.everywhere.popup" timestamp="1597702900013">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="623" y="225" width="672" height="678" key="search.everywhere.popup/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597702900013" />
<option name="LAST_COMMIT_MESSAGE" value="prepare twitter integration" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>

View File

@@ -37,9 +37,11 @@ Add your Discord ID `adminId` (not name), Bot token `token`, and update frequenc
optionally you can add your own messages for when the bot is looking and when it can't reach Hytale Servers.
If you verified that everything works correctly, you can start the server in the background, on Linux that is
`nohup java -jar [server-file-name]`. To stop it you can either type `!stop` in the Admin Console (Discord PM) or
`nohup java -Xmx1024m -jar [server-file-name]`. To stop it you can either type `!stop` in the Admin Console (Discord PM) or
if the bot is unresponsive the the PID of it through `ps -ef` and `kill [pid]`
I'm not 100% certain how much RAM the bot needs, default is typically `-Xmx256m`, and that lead to some issues, `-Xmx512m` is probably plenty, because my server has
tons of unused ram I set it to `-Xmx2048m`, just try and look what works for you.
## Compiling yourself
I developed it under Windows, and had some trouble compiling it on Linux. You mileage may vary.
@@ -67,4 +69,4 @@ we were over the official Hytale Twitter.
## Other
Thanks to [Forcellrus](https://github.com/Forcellrus/Discord-Auto-Publisher) for discovering a way to auto publish messages
in news channels
in news channels

View File

@@ -4,7 +4,7 @@ plugins {
}
group 'de.wulkanat'
version '1.4.2'
version '1.4.3'
repositories {
mavenCentral()

View File

@@ -7,9 +7,11 @@ object DiscordRpc {
var jda: JDA? = null
fun updatePresence(available: Boolean) {
jda ?: return
// jda ?: return
jda!!.presence.activity = Activity.watching(if (available) Admin.message else Admin.offlineMessage)
jda!!.presence.isIdle = !available
// jda!!.presence.activity = Activity.watching(if (available) Admin.message else Admin.offlineMessage)
// jda!!.presence.isIdle = !available
// noop
if (available) Admin.println("Back online") else Admin.error("Gone offline", "Can't reach Hytale server")
}
}

View File

@@ -1,103 +1,12 @@
package de.wulkanat
import de.wulkanat.cli.Cli
import de.wulkanat.cli.makeCli
import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent
import net.dv8tion.jda.api.EmbedBuilder
import net.dv8tion.jda.api.Permission
import net.dv8tion.jda.api.events.message.MessageReceivedEvent
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) {
@@ -302,5 +211,5 @@ object OwnerCliStuff {
).queue()
}
}
}*
}*/
}
}

View File

@@ -1,18 +0,0 @@
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

@@ -1,216 +0,0 @@
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

@@ -1,52 +0,0 @@
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

@@ -1,7 +0,0 @@
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

@@ -1,23 +0,0 @@
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 = " ")}"
}
}

View File

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