mirror of
https://github.com/HMCore/Orbot.git
synced 2026-01-21 09:23:05 +00:00
Compare commits
1 Commits
refactor-t
...
not-sure
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8b148c4c7 |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,7 +1,6 @@
|
|||||||
servers.json
|
servers.json
|
||||||
config.json
|
admin.json
|
||||||
service_channels.json
|
service_channels.json
|
||||||
*.hprof
|
*.hprof
|
||||||
/build/
|
/build
|
||||||
/.gradle/
|
/.gradle
|
||||||
/.idea/
|
|
||||||
12
.idea/HytaleUpdateBot.iml
generated
Normal file
12
.idea/HytaleUpdateBot.iml
generated
Normal 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>
|
||||||
1
.idea/dictionaries/wulkanat.xml
generated
1
.idea/dictionaries/wulkanat.xml
generated
@@ -2,7 +2,6 @@
|
|||||||
<dictionary name="wulkanat">
|
<dictionary name="wulkanat">
|
||||||
<words>
|
<words>
|
||||||
<w>crosspost</w>
|
<w>crosspost</w>
|
||||||
<w>hytale</w>
|
|
||||||
</words>
|
</words>
|
||||||
</dictionary>
|
</dictionary>
|
||||||
</component>
|
</component>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal 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>
|
||||||
175
.idea/workspace.xml
generated
175
.idea/workspace.xml
generated
@@ -4,9 +4,9 @@
|
|||||||
<option name="autoReloadType" value="SELECTIVE" />
|
<option name="autoReloadType" value="SELECTIVE" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="1aabf22b-2f57-46ac-9973-367d8668ffd3" name="Default Changelist" comment="no idea what that did">
|
<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$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" 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" />
|
<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>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@@ -31,6 +31,11 @@
|
|||||||
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
|
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
|
||||||
<item name="HytaleUpdateBot" type="f1a62948:ProjectNode" />
|
<item name="HytaleUpdateBot" type="f1a62948:ProjectNode" />
|
||||||
</path>
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
|
||||||
|
<item name="HytaleUpdateBot" type="f1a62948:ProjectNode" />
|
||||||
|
<item name="Tasks" type="e4a08cd1:TasksNode" />
|
||||||
|
</path>
|
||||||
</expand>
|
</expand>
|
||||||
<select />
|
<select />
|
||||||
</tree_state>
|
</tree_state>
|
||||||
@@ -51,7 +56,7 @@
|
|||||||
<component name="Git.Settings">
|
<component name="Git.Settings">
|
||||||
<option name="RECENT_BRANCH_BY_REPOSITORY">
|
<option name="RECENT_BRANCH_BY_REPOSITORY">
|
||||||
<map>
|
<map>
|
||||||
<entry key="$PROJECT_DIR$" value="not-sure" />
|
<entry key="$PROJECT_DIR$" value="add-twitter-integration" />
|
||||||
</map>
|
</map>
|
||||||
</option>
|
</option>
|
||||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||||
@@ -60,7 +65,7 @@
|
|||||||
<setting file="file://$PROJECT_DIR$/build.gradle" root0="SKIP_INSPECTION" />
|
<setting file="file://$PROJECT_DIR$/build.gradle" root0="SKIP_INSPECTION" />
|
||||||
</component>
|
</component>
|
||||||
<component name="MacroExpansionManager">
|
<component name="MacroExpansionManager">
|
||||||
<option name="directoryName" value="o7p0t8es" />
|
<option name="directoryName" value="5kk4ojxu" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectId" id="1g2oQiuUv1Bu6ZCW2NSVzB1V6Sc" />
|
<component name="ProjectId" id="1g2oQiuUv1Bu6ZCW2NSVzB1V6Sc" />
|
||||||
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
|
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
|
||||||
@@ -71,26 +76,27 @@
|
|||||||
<component name="PropertiesComponent">
|
<component name="PropertiesComponent">
|
||||||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
||||||
<property name="SHARE_PROJECT_CONFIGURATION_FILES" 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.last.edited" value="Modules" />
|
||||||
<property name="project.structure.proportion" value="0.15" />
|
<property name="project.structure.proportion" value="0.15" />
|
||||||
<property name="project.structure.side.proportion" value="0.2" />
|
<property name="project.structure.side.proportion" value="0.2" />
|
||||||
<property name="settings.editor.selected.configurable" value="reference.settingsdialog.project.gradle" />
|
<property name="settings.editor.selected.configurable" value="reference.settingsdialog.project.gradle" />
|
||||||
</component>
|
</component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="MoveKotlinTopLevelDeclarationsDialog.RECENTS_KEY">
|
|
||||||
<recent name="de.wulkanat" />
|
|
||||||
</key>
|
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
|
||||||
<recent name="E:\Projects\Kotlin_Proj\HytaleUpdateBot\build\libs" />
|
|
||||||
<recent name="E:\Projects\Kotlin_Proj\HytaleUpdateBot\src" />
|
|
||||||
</key>
|
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
<recent name="E:\Projects\Kotlin_Proj\HytaleUpdateBot" />
|
<recent name="E:\Projects\Kotlin_Proj\HytaleUpdateBot" />
|
||||||
<recent name="E:\Projects\Kotlin_Proj\HytaleUpdateBot\src\main\kotlin\de\wulkanat" />
|
<recent name="E:\Projects\Kotlin_Proj\HytaleUpdateBot\src\main\kotlin\de\wulkanat" />
|
||||||
</key>
|
</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>
|
||||||
</component>
|
</component>
|
||||||
<component name="RunManager" selected="Application.MainKt">
|
<component name="RunManager" selected="Gradle.HytaleUpdateBot [fatJar]">
|
||||||
<configuration name="HytaleUpdateBot [build]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
<configuration name="HytaleUpdateBot [build]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
||||||
<ExternalSystemSettings>
|
<ExternalSystemSettings>
|
||||||
<option name="executionName" />
|
<option name="executionName" />
|
||||||
@@ -173,10 +179,11 @@
|
|||||||
</configuration>
|
</configuration>
|
||||||
<recent_temporary>
|
<recent_temporary>
|
||||||
<list>
|
<list>
|
||||||
<item itemvalue="Gradle.HytaleUpdateBot [fatJar]" />
|
<item itemvalue="Application.MainKt" />
|
||||||
<item itemvalue="Gradle.HytaleUpdateBot [build]" />
|
|
||||||
<item itemvalue="Gradle.HytaleUpdateBot [clean]" />
|
|
||||||
<item itemvalue="JAR Application.HytaleUpdateBot-all-1.0-SNAPSHOT.jar" />
|
<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>
|
</list>
|
||||||
</recent_temporary>
|
</recent_temporary>
|
||||||
</component>
|
</component>
|
||||||
@@ -227,28 +234,136 @@
|
|||||||
<option name="project" value="LOCAL" />
|
<option name="project" value="LOCAL" />
|
||||||
<updated>1601042375685</updated>
|
<updated>1601042375685</updated>
|
||||||
</task>
|
</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 />
|
<servers />
|
||||||
</component>
|
</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">
|
<component name="VcsManagerConfiguration">
|
||||||
<MESSAGE value="Add auto publish feature" />
|
<MESSAGE value="Add auto publish feature" />
|
||||||
<MESSAGE value="[1.1]" />
|
<MESSAGE value="[1.1]" />
|
||||||
<MESSAGE value="Add service announcement channel" />
|
<MESSAGE value="Add service announcement channel" />
|
||||||
<MESSAGE value="fix crash on missing permission add removeInactive command" />
|
<MESSAGE value="fix crash on missing permission add removeInactive command" />
|
||||||
<MESSAGE value="prepare twitter integration" />
|
<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="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" />
|
||||||
</component>
|
</component>
|
||||||
<component name="XDebuggerManager">
|
<component name="XDebuggerManager">
|
||||||
<breakpoint-manager>
|
<breakpoint-manager>
|
||||||
|
|||||||
12
README.md
12
README.md
@@ -31,17 +31,15 @@ the bot should message you on Discord.
|
|||||||
|
|
||||||
*Note:* You need to invite the bot into a server before it can message you.
|
*Note:* You need to invite the bot into a server before it can message you.
|
||||||
|
|
||||||
Run it once (it should crash or print an error), so `config.json`, `servers.json` and `service_channels.json`
|
Run it once (it should crash or print an error), so `admin.json`, `servers.json` and `service_channels.json`
|
||||||
are being created.
|
are being created.
|
||||||
Add your Discord ID `adminId` (not name), Bot token `token`, and update frequency `updateMs` to the `config.json`,
|
Add your Discord ID `adminId` (not name), Bot token `token`, and update frequency `updateMs` to the `admin.json`,
|
||||||
optionally you can add your own messages for when the bot is looking and when it can't reach Hytale Servers.
|
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
|
If you verified that everything works correctly, you can start the server in the background, on Linux that is
|
||||||
`nohup java -Xmx1024m -jar [server-file-name]`. To stop it you can either type `!stop` in the Admin Console (Discord PM) or
|
`nohup java -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]`
|
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
|
## Compiling yourself
|
||||||
I developed it under Windows, and had some trouble compiling it on Linux. You mileage may vary.
|
I developed it under Windows, and had some trouble compiling it on Linux. You mileage may vary.
|
||||||
@@ -59,7 +57,7 @@ I developed it under Windows, and had some trouble compiling it on Linux. You mi
|
|||||||
| !help | | Show a help dialog with all these commands |
|
| !help | | Show a help dialog with all these commands |
|
||||||
|
|
||||||
These commands will only work by private messaging the bot (and will be ignored if they don't
|
These commands will only work by private messaging the bot (and will be ignored if they don't
|
||||||
come from the admin registered in the `config.json`.
|
come from the admin registered in the `admin.json`.
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
@@ -69,4 +67,4 @@ we were over the official Hytale Twitter.
|
|||||||
## Other
|
## Other
|
||||||
|
|
||||||
Thanks to [Forcellrus](https://github.com/Forcellrus/Discord-Auto-Publisher) for discovering a way to auto publish messages
|
Thanks to [Forcellrus](https://github.com/Forcellrus/Discord-Auto-Publisher) for discovering a way to auto publish messages
|
||||||
in news channels
|
in news channels
|
||||||
47
build.gradle
Normal file
47
build.gradle
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
plugins {
|
||||||
|
id 'org.jetbrains.kotlin.jvm' version '1.3.61'
|
||||||
|
id 'org.jetbrains.kotlin.plugin.serialization' version '1.3.61'
|
||||||
|
}
|
||||||
|
|
||||||
|
group 'de.wulkanat'
|
||||||
|
version '1.4.2'
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
|
||||||
|
|
||||||
|
compile 'net.dv8tion:JDA:4.2.0_189'
|
||||||
|
compile 'org.jsoup:jsoup:1.13.1'
|
||||||
|
compile "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.14.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
compileKotlin {
|
||||||
|
kotlinOptions.jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
compileTestKotlin {
|
||||||
|
kotlinOptions.jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
manifest {
|
||||||
|
attributes('Main-Class': 'de.wulkanat.MainKt')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task fatJar(type: Jar) {
|
||||||
|
baseName = project.name + '-all'
|
||||||
|
from((configurations.compile.findAll { !it.path.endsWith(".pom") }).collect {
|
||||||
|
it.isDirectory() ? it : zipTree(it)
|
||||||
|
})
|
||||||
|
with jar
|
||||||
|
manifest {
|
||||||
|
attributes 'Main-Class': 'de.wulkanat.MainKt',
|
||||||
|
'Implementation-Version': version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'kotlinx-serialization'
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
val kotlinVersion = "1.4.10"
|
|
||||||
|
|
||||||
kotlin("jvm") version kotlinVersion
|
|
||||||
kotlin("plugin.serialization") version kotlinVersion
|
|
||||||
|
|
||||||
id("org.jetbrains.kotlin.kapt") version kotlinVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
group = "de.wulkanat"
|
|
||||||
version = "2.0.0"
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
jcenter()
|
|
||||||
maven("https://kotlin.bintray.com/koltinx")
|
|
||||||
maven("https://dl.bintray.com/kordlib/Kord")
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
testImplementation(kotlin("test-junit"))
|
|
||||||
|
|
||||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
|
||||||
|
|
||||||
implementation("org.jsoup:jsoup:1.13.1")
|
|
||||||
|
|
||||||
implementation("dev.kord:kord-common:0.7.0-RC")
|
|
||||||
implementation("com.gitlab.kordlib.kordx:kordx-commands-runtime-kord:0.3.4")
|
|
||||||
implementation("com.gitlab.kordlib:kordx.emoji:0.4.0")
|
|
||||||
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1")
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2")
|
|
||||||
|
|
||||||
kapt("com.gitlab.kordlib.kordx:kordx-commands-processor:0.3.4")
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.test {
|
|
||||||
useJUnit()
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.withType<KotlinCompile> {
|
|
||||||
kotlinOptions.jvmTarget = "1.8"
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.withType<Jar> {
|
|
||||||
manifest {
|
|
||||||
attributes(mapOf(Pair("Main-Class", "de.wulkanat.MainKt")))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.create<Jar>("fatJar") {
|
|
||||||
archiveBaseName.set("${project.name}-all")
|
|
||||||
manifest {
|
|
||||||
attributes["Implementation-Version"] = archiveVersion
|
|
||||||
attributes["Main-Class"] = "de.wulkanat.MainKt"
|
|
||||||
}
|
|
||||||
from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) })
|
|
||||||
with(tasks.jar.get() as CopySpec)
|
|
||||||
}
|
|
||||||
5
gradle/wrapper/gradle-wrapper.properties
vendored
5
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,6 @@
|
|||||||
|
#Thu Aug 13 18:41:46 CEST 2020
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
2
settings.gradle
Normal file
2
settings.gradle
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
rootProject.name = 'HytaleUpdateBot'
|
||||||
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
rootProject.name = "HytaleUpdateBot"
|
|
||||||
|
|
||||||
@@ -1,82 +1,141 @@
|
|||||||
package de.wulkanat
|
package de.wulkanat
|
||||||
|
|
||||||
import com.gitlab.kordlib.common.entity.Snowflake
|
import kotlinx.serialization.json.Json
|
||||||
import com.gitlab.kordlib.core.Kord
|
import kotlinx.serialization.json.JsonConfiguration
|
||||||
import com.gitlab.kordlib.core.behavior.channel.createEmbed
|
import net.dv8tion.jda.api.EmbedBuilder
|
||||||
import com.gitlab.kordlib.core.entity.User
|
import net.dv8tion.jda.api.JDA
|
||||||
import com.gitlab.kordlib.rest.builder.message.EmbedBuilder
|
import net.dv8tion.jda.api.entities.Activity
|
||||||
import de.wulkanat.files.Config
|
import net.dv8tion.jda.api.entities.MessageEmbed
|
||||||
import de.wulkanat.files.ServiceChannels
|
import net.dv8tion.jda.api.entities.User
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import java.awt.Color
|
import java.awt.Color
|
||||||
|
|
||||||
object Admin {
|
object Admin {
|
||||||
var jda: Kord? = null
|
val userId: Long
|
||||||
|
val token: String
|
||||||
|
val updateMs: Long
|
||||||
|
val message: String
|
||||||
|
val offlineMessage: String
|
||||||
|
|
||||||
|
init {
|
||||||
|
val admin = Json(JsonConfiguration.Stable).parse(AdminFile.serializer(), ADMIN_FILE.readText())
|
||||||
|
userId = admin.adminId
|
||||||
|
token = admin.token
|
||||||
|
updateMs = admin.updateMs
|
||||||
|
message = admin.watchingMessage
|
||||||
|
offlineMessage = admin.offlineMessage
|
||||||
|
}
|
||||||
|
|
||||||
|
var jda: JDA? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
|
|
||||||
GlobalScope.launch {
|
admin = value?.retrieveUserById(userId)?.complete()
|
||||||
admin = value?.getUser(Snowflake(Config.adminId))
|
if (admin == null) {
|
||||||
if (admin == null) {
|
kotlin.io.println("Connection to de.wulkanat.Admin failed!")
|
||||||
kotlin.io.println("Connection to de.wulkanat.Admin failed!")
|
} else {
|
||||||
} else {
|
kotlin.io.println("Connected to ${admin!!.name}. No further errors will be printed here.")
|
||||||
kotlin.io.println("Connected to ${admin!!.username}. No further errors will be printed here.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var admin: User? = null
|
var admin: User? = null
|
||||||
|
|
||||||
suspend fun println(msg: String) {
|
fun println(msg: String) {
|
||||||
sendDevMessage(msg) {
|
sendDevMessage(
|
||||||
title = msg
|
EmbedBuilder()
|
||||||
color = Color.WHITE
|
.setTitle(msg)
|
||||||
}
|
.setColor(Color.WHITE)
|
||||||
|
.build(),
|
||||||
|
msg
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun error(msg: String, error: String, author: User? = null) {
|
fun printlnBlocking(msg: String) {
|
||||||
sendDevMessage("$msg\n\n$error") {
|
senDevMessageBlocking(
|
||||||
title = msg
|
EmbedBuilder()
|
||||||
description = error
|
.setTitle(msg)
|
||||||
color = Color.RED
|
.setColor(Color.WHITE)
|
||||||
author?.let { author {
|
.build(),
|
||||||
name = it.tag
|
msg
|
||||||
icon = it.avatar.url
|
)
|
||||||
url = it.avatar.url
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun warning(msg: String) {
|
fun error(msg: String, error: String, author: User? = null) {
|
||||||
sendDevMessage(msg) {
|
sendDevMessage(
|
||||||
title = msg
|
EmbedBuilder()
|
||||||
color = Color.YELLOW
|
.setTitle(msg)
|
||||||
}
|
.setDescription(error)
|
||||||
|
.setColor(Color.RED)
|
||||||
|
.run {
|
||||||
|
if (author == null) {
|
||||||
|
this
|
||||||
|
} else {
|
||||||
|
this.setAuthor(author.asTag, author.avatarUrl, author.avatarUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.build()
|
||||||
|
, "$msg\n\n${error}"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun info() {
|
fun errorBlocking(msg: String, error: Exception) {
|
||||||
sendDevMessage("Now watching for new Hytale BlogPosts") {
|
senDevMessageBlocking(
|
||||||
title = "Now watching for new Hytale Blogposts every ${Config.updateMs / 1000}s"
|
EmbedBuilder()
|
||||||
description = """
|
.setTitle(msg)
|
||||||
${ServiceChannels.getServerNames().joinToString("\n")}
|
.setDescription(error.message)
|
||||||
|
.setColor(Color.RED)
|
||||||
**_Service Channels_**
|
.build()
|
||||||
${ServiceChannels.getServiceChannelServers().joinToString("\n")}
|
, "$msg\n\n${error.message}"
|
||||||
""".trimIndent()
|
)
|
||||||
color = Color.GREEN
|
}
|
||||||
}
|
|
||||||
|
fun warning(msg: String) {
|
||||||
|
sendDevMessage(
|
||||||
|
EmbedBuilder()
|
||||||
|
.setTitle(msg)
|
||||||
|
.setColor(Color.YELLOW)
|
||||||
|
.build(),
|
||||||
|
msg
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun info() {
|
||||||
|
sendDevMessage(
|
||||||
|
EmbedBuilder()
|
||||||
|
.setTitle("Now watching for new Hytale Blogposts every ${updateMs / 1000}s")
|
||||||
|
.setDescription("""
|
||||||
|
${Channels.getServerNames().joinToString("\n")}
|
||||||
|
|
||||||
|
**_Service Channels_**
|
||||||
|
${Channels.getServiceChannelServers().joinToString("\n")}
|
||||||
|
""".trimIndent())
|
||||||
|
.setColor(Color.GREEN)
|
||||||
|
.build(),
|
||||||
|
"Now watching for new Hytale BlogPosts"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun silent(msg: String) {
|
fun silent(msg: String) {
|
||||||
kotlin.io.println(msg)
|
kotlin.io.println(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend inline fun sendDevMessage(fallback: String, crossinline embed: EmbedBuilder.() -> Unit) {
|
private fun senDevMessageBlocking(messageEmbed: MessageEmbed, fallback: String) {
|
||||||
val devChannel = admin?.getDmChannel() ?: kotlin.run {
|
admin = jda!!.retrieveUserById(userId).complete()
|
||||||
|
val devChannel = admin?.openPrivateChannel() ?: kotlin.run {
|
||||||
kotlin.io.println(fallback)
|
kotlin.io.println(fallback)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
devChannel.createEmbed(embed)
|
devChannel.complete()
|
||||||
|
.sendMessage(messageEmbed).complete()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sendDevMessage(messageEmbed: MessageEmbed, fallback: String) {
|
||||||
|
val devChannel = admin?.openPrivateChannel() ?: kotlin.run {
|
||||||
|
kotlin.io.println(fallback)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
devChannel.queue {
|
||||||
|
it.sendMessage(messageEmbed).queue()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
91
src/main/kotlin/de/wulkanat/AdminCli.kt
Normal file
91
src/main/kotlin/de/wulkanat/AdminCli.kt
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
package de.wulkanat
|
||||||
|
|
||||||
|
import de.wulkanat.model.BlogPostPreview
|
||||||
|
import net.dv8tion.jda.api.hooks.ListenerAdapter
|
||||||
|
import de.wulkanat.web.SiteWatcher
|
||||||
|
import net.dv8tion.jda.api.EmbedBuilder
|
||||||
|
import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent
|
||||||
|
import java.awt.Color
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
class AdminCli : ListenerAdapter() {
|
||||||
|
val prefix = "!"
|
||||||
|
|
||||||
|
override fun onPrivateMessageReceived(event: PrivateMessageReceivedEvent) {
|
||||||
|
val msg = event.message.contentRaw
|
||||||
|
if (event.author.idLong != Admin.userId ||
|
||||||
|
!msg.startsWith(prefix)
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val command = Regex("[^\\s`]+|`[^`]*`").findAll(msg.removePrefix("!")).toList()
|
||||||
|
|
||||||
|
when (command[0].value) {
|
||||||
|
"stop" -> exitProcess(1)
|
||||||
|
"fakeUpdate" -> {
|
||||||
|
SiteWatcher.newestBlog = BlogPostPreview(
|
||||||
|
title = "FakePost",
|
||||||
|
imgUrl = "",
|
||||||
|
fullPostUrl = "",
|
||||||
|
author = "wulkanat",
|
||||||
|
date = "now",
|
||||||
|
description = "Lorem Ipsum"
|
||||||
|
)
|
||||||
|
|
||||||
|
Admin.println("Posting on next update cycle.")
|
||||||
|
}
|
||||||
|
"info" -> {
|
||||||
|
Admin.info()
|
||||||
|
}
|
||||||
|
"serviceMessage" -> {
|
||||||
|
if (command.size != 3) {
|
||||||
|
Admin.println("Enclose message and title in backticks (`)")
|
||||||
|
} else {
|
||||||
|
Channels.sendServiceMessage(command[1].value.trim('`'), command[2].value.trim('`'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"refreshList" -> {
|
||||||
|
Channels.channels = Channels.refreshChannelsFromDisk()
|
||||||
|
Channels.serviceChannels = Channels.refreshServiceChannelsFromDisk()
|
||||||
|
Admin.info()
|
||||||
|
}
|
||||||
|
"removeInactive" -> {
|
||||||
|
Channels.channels.removeAll { channel ->
|
||||||
|
Channels.testServerId(channel.id) ?: run {
|
||||||
|
Admin.println("Removed ${channel.id}")
|
||||||
|
null
|
||||||
|
} == null
|
||||||
|
}
|
||||||
|
Admin.info()
|
||||||
|
Channels.saveChannels()
|
||||||
|
}
|
||||||
|
"help" -> {
|
||||||
|
event.message.channel.sendMessage(
|
||||||
|
EmbedBuilder()
|
||||||
|
.setTitle("Help")
|
||||||
|
.setColor(Color.YELLOW)
|
||||||
|
.setAuthor(Admin.admin?.name, Admin.admin?.avatarUrl, Admin.admin?.avatarUrl)
|
||||||
|
.setDescription(
|
||||||
|
"""
|
||||||
|
**${prefix}stop**
|
||||||
|
Stop the bot
|
||||||
|
**${prefix}fakeUpdate**
|
||||||
|
Post a fake update to every registered channel (can be used if bot missed the update)
|
||||||
|
**${prefix}info**
|
||||||
|
Show an overview over all registered channels
|
||||||
|
**${prefix}serviceMessage [title] [message]**
|
||||||
|
Show a service message (update info etc) to all registered service channels
|
||||||
|
**${prefix}refreshList**
|
||||||
|
Refresh server list from disk
|
||||||
|
**${prefix}removeInactive**
|
||||||
|
Remove inactive channels
|
||||||
|
**${prefix}help**
|
||||||
|
Show this message
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
).queue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
package de.wulkanat.files
|
package de.wulkanat
|
||||||
|
|
||||||
import com.gitlab.kordlib.core.Kord
|
import de.wulkanat.extensions.crosspost
|
||||||
import com.gitlab.kordlib.core.entity.Embed
|
|
||||||
import com.gitlab.kordlib.rest.builder.message.EmbedBuilder
|
|
||||||
import de.wulkanat.*
|
|
||||||
import kotlinx.serialization.list
|
import kotlinx.serialization.list
|
||||||
import net.dv8tion.jda.api.EmbedBuilder
|
import net.dv8tion.jda.api.EmbedBuilder
|
||||||
import net.dv8tion.jda.api.JDA
|
import net.dv8tion.jda.api.JDA
|
||||||
@@ -12,8 +9,8 @@ import net.dv8tion.jda.api.entities.MessageEmbed
|
|||||||
import net.dv8tion.jda.api.entities.TextChannel
|
import net.dv8tion.jda.api.entities.TextChannel
|
||||||
import java.awt.Color
|
import java.awt.Color
|
||||||
|
|
||||||
object ServiceChannels {
|
object Channels {
|
||||||
var client: Kord? = null
|
var jda: JDA? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of (ServerID, ChannelID)
|
* List of (ServerID, ChannelID)
|
||||||
@@ -21,13 +18,13 @@ object ServiceChannels {
|
|||||||
var channels: MutableList<DiscordChannel> = refreshChannelsFromDisk()
|
var channels: MutableList<DiscordChannel> = refreshChannelsFromDisk()
|
||||||
var serviceChannels: MutableList<ServiceChannel> = refreshServiceChannelsFromDisk()
|
var serviceChannels: MutableList<ServiceChannel> = refreshServiceChannelsFromDisk()
|
||||||
|
|
||||||
fun sentToAll(messageEmbed: Embed) {
|
fun sentToAll(messageEmbed: MessageEmbed) {
|
||||||
if (client == null)
|
if (jda == null)
|
||||||
return
|
return
|
||||||
|
|
||||||
for (channel_pair in channels) {
|
for (channel_pair in channels) {
|
||||||
try {
|
try {
|
||||||
val channel = client!!.getTextChannelById(channel_pair.id) ?: continue
|
val channel = jda!!.getTextChannelById(channel_pair.id) ?: continue
|
||||||
val customMessage = channel_pair.message?.message ?: ""
|
val customMessage = channel_pair.message?.message ?: ""
|
||||||
|
|
||||||
if (channel_pair.mentionedRole != null) {
|
if (channel_pair.mentionedRole != null) {
|
||||||
@@ -69,14 +66,13 @@ object ServiceChannels {
|
|||||||
.build()
|
.build()
|
||||||
|
|
||||||
for (channelInfo in serviceChannels) {
|
for (channelInfo in serviceChannels) {
|
||||||
val channel = client!!.getTextChannelById(channelInfo.id)
|
val channel = jda!!.getTextChannelById(channelInfo.id)
|
||||||
|
|
||||||
channel?.sendMessage(serviceMessage)?.queue()
|
channel?.sendMessage(serviceMessage)?.queue()
|
||||||
}
|
}
|
||||||
|
|
||||||
Admin.println("Service message distributed to ${serviceChannels.size} channels.")
|
Admin.println("Service message distributed to ${serviceChannels.size} channels.")
|
||||||
Admin.sendDevMessage(
|
Admin.sendDevMessage(serviceMessage, """
|
||||||
serviceMessage, """
|
|
||||||
***************
|
***************
|
||||||
SERVICE MESSAGE
|
SERVICE MESSAGE
|
||||||
|
|
||||||
@@ -84,13 +80,12 @@ object ServiceChannels {
|
|||||||
-------
|
-------
|
||||||
$message
|
$message
|
||||||
***************
|
***************
|
||||||
""".trimIndent()
|
""".trimIndent())
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkEveryonePermission() {
|
fun checkEveryonePermission() {
|
||||||
for (channel_pair in channels) {
|
for (channel_pair in channels) {
|
||||||
val channel = client!!.getTextChannelById(channel_pair.id) ?: continue
|
val channel = jda!!.getTextChannelById(channel_pair.id) ?: continue
|
||||||
|
|
||||||
if (channel_pair.mentionedRole == "everyone" &&
|
if (channel_pair.mentionedRole == "everyone" &&
|
||||||
channel.guild.selfMember.hasPermission(Permission.MESSAGE_MENTION_EVERYONE)
|
channel.guild.selfMember.hasPermission(Permission.MESSAGE_MENTION_EVERYONE)
|
||||||
@@ -116,11 +111,11 @@ object ServiceChannels {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getServerNames(server: Long? = null): List<String> {
|
fun getServerNames(server: Long? = null): List<String> {
|
||||||
if (client == null)
|
if (jda == null)
|
||||||
return listOf()
|
return listOf()
|
||||||
|
|
||||||
return channels.filter { server == null || (client!!.getTextChannelById(it.id)?.guild?.idLong == server) }.map {
|
return channels.filter { server == null || (jda!!.getTextChannelById(it.id)?.guild?.idLong == server) }.map {
|
||||||
val channel = client!!.getTextChannelById(it.id)
|
val channel = jda!!.getTextChannelById(it.id)
|
||||||
if (channel == null) {
|
if (channel == null) {
|
||||||
Admin.warning("Channel ${it.id} is no longer active!")
|
Admin.warning("Channel ${it.id} is no longer active!")
|
||||||
return@map "**${it.id}** *(inactive)*"
|
return@map "**${it.id}** *(inactive)*"
|
||||||
@@ -142,17 +137,17 @@ object ServiceChannels {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getServiceChannelServers(server: Long? = null): List<String> {
|
fun getServiceChannelServers(server: Long? = null): List<String> {
|
||||||
if (client == null)
|
if (jda == null)
|
||||||
return listOf()
|
return listOf()
|
||||||
|
|
||||||
return serviceChannels.filter { server == null || (client!!.getTextChannelById(it.id)?.guild?.idLong == server) }.map {
|
return serviceChannels.filter { server == null || (jda!!.getTextChannelById(it.id)?.guild?.idLong == server) }.map {
|
||||||
val channel = client!!.getTextChannelById(it.id)
|
val channel = jda!!.getTextChannelById(it.id)
|
||||||
"**${channel?.guild?.name ?: it.id}** #${channel?.name ?: "(inactive)"}"
|
"**${channel?.guild?.name ?: it.id}** #${channel?.name ?: "(inactive)"}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testServerId(id: Long): TextChannel? {
|
fun testServerId(id: Long): TextChannel? {
|
||||||
return client?.getTextChannelById(id)
|
return jda?.getTextChannelById(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addChannel(id: Long, role: String?): DiscordChannel? {
|
fun addChannel(id: Long, role: String?): DiscordChannel? {
|
||||||
@@ -10,7 +10,7 @@ import java.io.File
|
|||||||
@Serializable
|
@Serializable
|
||||||
data class DiscordChannel(
|
data class DiscordChannel(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
var mentionedRole: Long? = null,
|
var mentionedRole: String? = null,
|
||||||
var autoPublish: Boolean = false,
|
var autoPublish: Boolean = false,
|
||||||
var message: CustomMessage? = null
|
var message: CustomMessage? = null
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,11 +7,9 @@ object DiscordRpc {
|
|||||||
var jda: JDA? = null
|
var jda: JDA? = null
|
||||||
|
|
||||||
fun updatePresence(available: Boolean) {
|
fun updatePresence(available: Boolean) {
|
||||||
// jda ?: return
|
jda ?: return
|
||||||
|
|
||||||
// jda!!.presence.activity = Activity.watching(if (available) Admin.message else Admin.offlineMessage)
|
jda!!.presence.activity = Activity.watching(if (available) Admin.message else Admin.offlineMessage)
|
||||||
// jda!!.presence.isIdle = !available
|
jda!!.presence.isIdle = !available
|
||||||
// noop
|
|
||||||
if (available) Admin.println("Back online") else Admin.error("Gone offline", "Can't reach Hytale server")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package de.wulkanat
|
package de.wulkanat
|
||||||
|
|
||||||
import de.wulkanat.files.ServiceChannels
|
|
||||||
import net.dv8tion.jda.api.JDABuilder
|
import net.dv8tion.jda.api.JDABuilder
|
||||||
import net.dv8tion.jda.api.entities.Activity
|
import net.dv8tion.jda.api.entities.Activity
|
||||||
import net.dv8tion.jda.api.requests.GatewayIntent
|
import net.dv8tion.jda.api.requests.GatewayIntent
|
||||||
@@ -19,7 +18,7 @@ fun main() {
|
|||||||
builder.addEventListener(OwnerCli())
|
builder.addEventListener(OwnerCli())
|
||||||
builder.awaitReady()
|
builder.awaitReady()
|
||||||
|
|
||||||
ServiceChannels.client = builder
|
Channels.jda = builder
|
||||||
Admin.jda = builder
|
Admin.jda = builder
|
||||||
DiscordRpc.jda = builder
|
DiscordRpc.jda = builder
|
||||||
Admin.info()
|
Admin.info()
|
||||||
@@ -35,7 +34,7 @@ fun main() {
|
|||||||
|
|
||||||
timer("Updater", daemon = true, initialDelay = 0L, period = Admin.updateMs) {
|
timer("Updater", daemon = true, initialDelay = 0L, period = Admin.updateMs) {
|
||||||
if (SiteWatcher.hasNewBlogPost()) {
|
if (SiteWatcher.hasNewBlogPost()) {
|
||||||
ServiceChannels.sentToAll(SiteWatcher.newestBlog!!.toMessageEmbed())
|
Channels.sentToAll(SiteWatcher.newestBlog!!.toMessageEmbed())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
306
src/main/kotlin/de/wulkanat/OwnerCli.kt
Normal file
306
src/main/kotlin/de/wulkanat/OwnerCli.kt
Normal file
@@ -0,0 +1,306 @@
|
|||||||
|
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.hooks.ListenerAdapter
|
||||||
|
|
||||||
|
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) {
|
||||||
|
val msg = event.message.contentRaw
|
||||||
|
// Only accept admin requests
|
||||||
|
if (event.message.member?.hasPermission(Permission.ADMINISTRATOR) != true || !msg.startsWith(prefix)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val command = msg.removePrefix(prefix).split(Regex("\\s+"))
|
||||||
|
val channelId = event.message.channel.idLong
|
||||||
|
|
||||||
|
when (command.first()) {
|
||||||
|
"add" -> {
|
||||||
|
val result = Channels.addChannel(channelId, null)
|
||||||
|
if (result == null) {
|
||||||
|
event.message.channel.sendMessage("Already added.").queue()
|
||||||
|
} else {
|
||||||
|
event.message.channel.sendMessage("Added.").queue()
|
||||||
|
Admin.info()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"remove" -> {
|
||||||
|
val result = Channels.channels.removeAll { it.id == channelId }
|
||||||
|
Channels.saveChannels()
|
||||||
|
if (result) {
|
||||||
|
event.message.channel.sendMessage("Removed.").queue()
|
||||||
|
} else {
|
||||||
|
event.message.channel.sendMessage("This channel is not registered.").queue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"publish" -> {
|
||||||
|
val result = Channels.channels.find { it.id == channelId }
|
||||||
|
if (result != null) {
|
||||||
|
if (command.size > 1 && listOf("on", "off").contains(command[1])) {
|
||||||
|
result.autoPublish = command[1] == "on"
|
||||||
|
Channels.saveChannels()
|
||||||
|
|
||||||
|
event.message.channel.sendMessage("Auto publish is now ${command[1]}").queue()
|
||||||
|
} else {
|
||||||
|
event.message.channel.sendMessage("Usage: `${prefix}publish [on|off]`")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
event.message.channel.sendMessage("Channel not registered.").queue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"ping" -> {
|
||||||
|
val result = Channels.channels.find { it.id == channelId }
|
||||||
|
if (result != null) {
|
||||||
|
if (command.size > 1) {
|
||||||
|
val roles = event.message.guild.getRolesByName(command[1], false)
|
||||||
|
result.mentionedRole = when {
|
||||||
|
command[1] == "everyone" -> {
|
||||||
|
event.message.channel.sendMessage("Now pinging everyone.").queue()
|
||||||
|
"everyone"
|
||||||
|
}
|
||||||
|
command[1] == "none" -> {
|
||||||
|
event.message.channel.sendMessage("Now pinging none.").queue()
|
||||||
|
null
|
||||||
|
}
|
||||||
|
roles.firstOrNull() != null -> {
|
||||||
|
event.message.channel.sendMessage("Now pinging ${roles.first().name}").queue()
|
||||||
|
roles.first().id
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
event.message.channel.sendMessage("Unknown role.").queue()
|
||||||
|
result.mentionedRole
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Channels.saveChannels()
|
||||||
|
} else {
|
||||||
|
event.message.channel.sendMessage("Usage: `${prefix}ping [everyone|none|roleName]`")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
event.message.channel.sendMessage("Channel is not registered.").queue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"setMessage" -> {
|
||||||
|
val result = Channels.channels.find { it.id == channelId }
|
||||||
|
if (result != null) {
|
||||||
|
if (command.size > 1) {
|
||||||
|
val message = event.message.contentRaw.removePrefix("${prefix}setMessage").trim()
|
||||||
|
result.message = CustomMessage(message)
|
||||||
|
Channels.saveChannels()
|
||||||
|
event.message.channel.sendMessage("Set `$message` as message.").queue()
|
||||||
|
} else {
|
||||||
|
event.message.channel.sendMessage("Usage: `${prefix}setMessage [message]`")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
event.message.channel.sendMessage("Channel is not registered.").queue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"resetMessage" -> {
|
||||||
|
val result = Channels.channels.find { it.id == channelId }
|
||||||
|
if (result != null) {
|
||||||
|
result.message = null
|
||||||
|
Channels.saveChannels()
|
||||||
|
event.message.channel.sendMessage("Reset to no message.").queue()
|
||||||
|
} else {
|
||||||
|
event.message.channel.sendMessage("Channel is not registered.").queue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"serviceChannel" -> {
|
||||||
|
if (command.size > 1 && listOf("add", "remove").contains(command[1])) {
|
||||||
|
if (command[1] == "add") {
|
||||||
|
if (Channels.serviceChannels.find { it.id == channelId } != null) {
|
||||||
|
event.message.channel.sendMessage("Already a service channel.").queue()
|
||||||
|
} else {
|
||||||
|
Channels.serviceChannels.add(ServiceChannel(channelId))
|
||||||
|
Channels.saveChannels()
|
||||||
|
event.message.channel.sendMessage("Added as service channel.").queue()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
event.message.channel.sendMessage(
|
||||||
|
if (Channels.serviceChannels.removeAll { it.id == channelId }) "Channel removed."
|
||||||
|
else "Not a service channel."
|
||||||
|
).queue()
|
||||||
|
}
|
||||||
|
Channels.saveChannels()
|
||||||
|
} else {
|
||||||
|
event.message.channel.sendMessage("Usage: `${prefix}serviceChannel [add|remove]`")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
"publishMessage" -> {
|
||||||
|
val result = Channels.channels.find { it.id == channelId }
|
||||||
|
if (result != null) {
|
||||||
|
if (result.message != null) {
|
||||||
|
if (command.size > 1 && listOf("on", "off").contains(command[1])) {
|
||||||
|
result.message?.pushAnnouncement = command[1] == "on"
|
||||||
|
Channels.saveChannels()
|
||||||
|
|
||||||
|
event.message.channel.sendMessage("Auto publish (message) is now ${command[1]}").queue()
|
||||||
|
} else {
|
||||||
|
event.message.channel.sendMessage("Usage: `${prefix}publishMessage [on|off]`")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
event.message.channel.sendMessage("Channel has no custom message.").queue()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
event.message.channel.sendMessage("Channel not registered.").queue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"info" -> {
|
||||||
|
event.message.channel.sendMessage(
|
||||||
|
EmbedBuilder()
|
||||||
|
.setTitle("Server overview")
|
||||||
|
.setColor(Color.GREEN)
|
||||||
|
.setDescription("""
|
||||||
|
${Channels.getServerNames(event.message.guild.idLong).joinToString("\n")}
|
||||||
|
|
||||||
|
**_Service Channels_**
|
||||||
|
${Channels.getServiceChannelServers(event.message.guild.idLong).joinToString("\n")}
|
||||||
|
""".trimIndent())
|
||||||
|
.setAuthor(Admin.admin?.name, Admin.admin?.avatarUrl, Admin.admin?.avatarUrl)
|
||||||
|
.build()
|
||||||
|
).queue()
|
||||||
|
}
|
||||||
|
"report" -> {
|
||||||
|
val errorReport = event.message.contentRaw.removePrefix("${prefix}report")
|
||||||
|
Admin.error(event.message.guild.name, errorReport, event.author)
|
||||||
|
event.message.channel.sendMessage(
|
||||||
|
EmbedBuilder()
|
||||||
|
.setTitle("Error Report Received")
|
||||||
|
.setColor(Color.RED)
|
||||||
|
.setDescription(errorReport)
|
||||||
|
.setAuthor(Admin.admin?.name, Admin.admin?.avatarUrl, Admin.admin?.avatarUrl)
|
||||||
|
.build()
|
||||||
|
).queue()
|
||||||
|
}
|
||||||
|
"help" -> {
|
||||||
|
event.message.channel.sendMessage(
|
||||||
|
EmbedBuilder()
|
||||||
|
.setTitle("Help")
|
||||||
|
.setColor(Color.YELLOW)
|
||||||
|
.setAuthor(Admin.admin?.name, Admin.admin?.avatarUrl, Admin.admin?.avatarUrl)
|
||||||
|
.setDescription(
|
||||||
|
"""
|
||||||
|
**${prefix}add**
|
||||||
|
Add this channel to the notified list
|
||||||
|
**${prefix}serviceChannel [add|remove]**
|
||||||
|
Add or remove this channel to receive service message from the bot developer (recommended)
|
||||||
|
**${prefix}remove**
|
||||||
|
Remove this channel to the notified list
|
||||||
|
**${prefix}publish [on|off]**
|
||||||
|
[Community|Partner|Verified only] Auto publish the message if in an announcement channel
|
||||||
|
**${prefix}ping [none|everyone|roleName]**
|
||||||
|
What role to ping
|
||||||
|
**${prefix}setMessage [message]**
|
||||||
|
Set a custom message to show
|
||||||
|
**${prefix}resetMessage**
|
||||||
|
Reset the message
|
||||||
|
**${prefix}info**
|
||||||
|
Show an overview about all channels registered on this server
|
||||||
|
**${prefix}report**
|
||||||
|
Report an issue to the Bot Admin (this will share your user name so they can contact you)
|
||||||
|
**${prefix}help**
|
||||||
|
Show this message
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
).queue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*
|
||||||
|
}*/
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
@file:AutoWired
|
|
||||||
|
|
||||||
package de.wulkanat.cli
|
|
||||||
|
|
||||||
import com.gitlab.kordlib.core.entity.channel.DmChannel
|
|
||||||
import com.gitlab.kordlib.kordx.commands.annotation.AutoWired
|
|
||||||
import com.gitlab.kordlib.kordx.commands.argument.primitive.BooleanArgument
|
|
||||||
import com.gitlab.kordlib.kordx.commands.argument.text.StringArgument
|
|
||||||
import com.gitlab.kordlib.kordx.commands.kord.model.precondition.precondition
|
|
||||||
import com.gitlab.kordlib.kordx.commands.kord.model.prefix.kord
|
|
||||||
import com.gitlab.kordlib.kordx.commands.kord.model.prefix.mention
|
|
||||||
import com.gitlab.kordlib.kordx.commands.kord.model.respondEmbed
|
|
||||||
import com.gitlab.kordlib.kordx.commands.kord.module.module
|
|
||||||
import com.gitlab.kordlib.kordx.commands.model.command.invoke
|
|
||||||
import com.gitlab.kordlib.kordx.commands.model.prefix.literal
|
|
||||||
import com.gitlab.kordlib.kordx.commands.model.prefix.or
|
|
||||||
import com.gitlab.kordlib.kordx.commands.model.prefix.prefix
|
|
||||||
import de.wulkanat.Admin
|
|
||||||
import de.wulkanat.extensions.alsoIf
|
|
||||||
import de.wulkanat.extensions.isBotAdmin
|
|
||||||
import de.wulkanat.files.ServiceChannels
|
|
||||||
import de.wulkanat.model.BlogPostPreview
|
|
||||||
import de.wulkanat.web.SiteWatcher
|
|
||||||
|
|
||||||
val prefixes = prefix {
|
|
||||||
kord { mention() or literal("%!") }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun adminCommands() = module("admin-commands") {
|
|
||||||
precondition { author.isBotAdmin && channel.asChannelOrNull() is DmChannel }
|
|
||||||
|
|
||||||
command("stop") {
|
|
||||||
invoke {
|
|
||||||
respond("Shutting down...")
|
|
||||||
kord.shutdown()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
command("info") {
|
|
||||||
invoke {
|
|
||||||
Admin.info()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
command("fakeUpdate") {
|
|
||||||
invoke {
|
|
||||||
respond("THIS WILL CAUSE A MESSAGE ON **ALL** SERVERS.\nContinue? [y/n]")
|
|
||||||
if (read(BooleanArgument(trueValue = "y", falseValue = "n"))) {
|
|
||||||
respond("Sending fake update on next cycle")
|
|
||||||
|
|
||||||
SiteWatcher.newestBlog = BlogPostPreview(
|
|
||||||
title = "FakePost",
|
|
||||||
imgUrl = "",
|
|
||||||
fullPostUrl = "",
|
|
||||||
author = "wulkanat",
|
|
||||||
date = "now",
|
|
||||||
description = "Lorem Ipsum"
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
respond("Aborting")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
command("serviceMessage") {
|
|
||||||
invoke {
|
|
||||||
respond("What's the title?")
|
|
||||||
val title = read(StringArgument)
|
|
||||||
respond("What's the message?")
|
|
||||||
val message = read(StringArgument)
|
|
||||||
respondEmbed {
|
|
||||||
this.title = title
|
|
||||||
description = message
|
|
||||||
footer {
|
|
||||||
text = "Is that correct? [y/n]"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (read(BooleanArgument(trueValue = "y", falseValue = "n"))) {
|
|
||||||
respond("Sending")
|
|
||||||
ServiceChannels.sendServiceMessage(title, message)
|
|
||||||
} else {
|
|
||||||
respond("Aborting")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
command("refreshList") {
|
|
||||||
invoke {
|
|
||||||
ServiceChannels.channels = ServiceChannels.refreshChannelsFromDisk()
|
|
||||||
ServiceChannels.serviceChannels = ServiceChannels.refreshServiceChannelsFromDisk()
|
|
||||||
Admin.info()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
command("removeInactive") {
|
|
||||||
invoke {
|
|
||||||
respondEmbed {
|
|
||||||
title = "Channels removed"
|
|
||||||
|
|
||||||
ServiceChannels.channels.removeAll { channel ->
|
|
||||||
(ServiceChannels.testServerId(channel.id) == null).alsoIf(true) {
|
|
||||||
field { name = channel.id.toString() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ServiceChannels.saveChannels()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
18
src/main/kotlin/de/wulkanat/cli/ArgumentType.kt
Normal file
18
src/main/kotlin/de/wulkanat/cli/ArgumentType.kt
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
216
src/main/kotlin/de/wulkanat/cli/Cli.kt
Normal file
216
src/main/kotlin/de/wulkanat/cli/Cli.kt
Normal 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 = { _, _, _ -> }
|
||||||
|
}
|
||||||
52
src/main/kotlin/de/wulkanat/cli/CliDiscordExtension.kt
Normal file
52
src/main/kotlin/de/wulkanat/cli/CliDiscordExtension.kt
Normal 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()
|
||||||
|
}
|
||||||
7
src/main/kotlin/de/wulkanat/cli/CliPublic.kt
Normal file
7
src/main/kotlin/de/wulkanat/cli/CliPublic.kt
Normal 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
|
||||||
|
}
|
||||||
23
src/main/kotlin/de/wulkanat/cli/Command.kt
Normal file
23
src/main/kotlin/de/wulkanat/cli/Command.kt
Normal 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 = " ")}"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
@file:AutoWired
|
|
||||||
|
|
||||||
package de.wulkanat.cli
|
|
||||||
|
|
||||||
import com.gitlab.kordlib.common.entity.Permission
|
|
||||||
import com.gitlab.kordlib.kordx.commands.annotation.AutoWired
|
|
||||||
import com.gitlab.kordlib.kordx.commands.argument.primitive.BooleanArgument
|
|
||||||
import com.gitlab.kordlib.kordx.commands.argument.text.StringArgument
|
|
||||||
import com.gitlab.kordlib.kordx.commands.kord.argument.RoleArgument
|
|
||||||
import com.gitlab.kordlib.kordx.commands.kord.model.precondition.precondition
|
|
||||||
import com.gitlab.kordlib.kordx.commands.kord.model.respondEmbed
|
|
||||||
import com.gitlab.kordlib.kordx.commands.kord.module.module
|
|
||||||
import com.gitlab.kordlib.kordx.commands.model.command.invoke
|
|
||||||
import de.wulkanat.Admin
|
|
||||||
import de.wulkanat.CustomMessage
|
|
||||||
import de.wulkanat.ServiceChannel
|
|
||||||
import de.wulkanat.files.ServiceChannels
|
|
||||||
import java.awt.Color
|
|
||||||
|
|
||||||
// TODO: channel argument?
|
|
||||||
fun ownerCommands() = module("owner-commands") {
|
|
||||||
precondition {
|
|
||||||
message.getAuthorAsMember()?.getPermissions()?.contains(Permission.Administrator) ?: false
|
|
||||||
}
|
|
||||||
|
|
||||||
command("add") {
|
|
||||||
invoke {
|
|
||||||
if (ServiceChannels.addChannel(channel.id.longValue, null) == null) {
|
|
||||||
respond("Already added.")
|
|
||||||
} else {
|
|
||||||
respond("Added.")
|
|
||||||
Admin.info()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
command("remove") {
|
|
||||||
invoke {
|
|
||||||
val result = ServiceChannels.channels.removeAll { it.id == channel.id.longValue }
|
|
||||||
ServiceChannels.saveChannels()
|
|
||||||
if (result) {
|
|
||||||
respond("Removed.")
|
|
||||||
} else {
|
|
||||||
respond("This channel is not registered.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
command("publish") {
|
|
||||||
invoke(BooleanArgument(trueValue = "on", falseValue = "off")) { doAutoPublish ->
|
|
||||||
ServiceChannels.channels.find { it.id == channel.id.longValue }?.also {
|
|
||||||
it.autoPublish = doAutoPublish
|
|
||||||
ServiceChannels.saveChannels()
|
|
||||||
} ?: respond("Channel not registered")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
command("ping") {
|
|
||||||
invoke(RoleArgument) { role ->
|
|
||||||
ServiceChannels.channels.find { it.id == channel.id.longValue }?.also {
|
|
||||||
// TODO: @everyone
|
|
||||||
it.mentionedRole = role.id.longValue
|
|
||||||
ServiceChannels.saveChannels()
|
|
||||||
} ?: respond("Channel not registered")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
command("setMessage") {
|
|
||||||
invoke(StringArgument) { message ->
|
|
||||||
ServiceChannels.channels.find { it.id == channel.id.longValue}?.also {
|
|
||||||
it.message = CustomMessage(message)
|
|
||||||
respond("Set `$message` as a message.")
|
|
||||||
} ?: respond("Channel not registered!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
command("resetMessage") {
|
|
||||||
invoke {
|
|
||||||
ServiceChannels.channels.find { it.id == channel.id.longValue }?.also {
|
|
||||||
it.message = null
|
|
||||||
respond("Reset to no message")
|
|
||||||
} ?: respond("Channel not registered!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
command("serviceChannel") {
|
|
||||||
invoke(BooleanArgument(trueValue = "add", falseValue = "remove")) { addChannel ->
|
|
||||||
if (addChannel) {
|
|
||||||
ServiceChannels.serviceChannels.find { it.id == channel.id.longValue }?.also {
|
|
||||||
respond("Already a service channel")
|
|
||||||
} ?: run {
|
|
||||||
ServiceChannels.serviceChannels.add(ServiceChannel(channel.id.longValue))
|
|
||||||
respond("Added as a service channel")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
respond(if (ServiceChannels.serviceChannels.removeAll { it.id == channel.id.longValue })
|
|
||||||
"Channel removed" else "Not a service channel")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
command("publishMessage") {
|
|
||||||
invoke(BooleanArgument(trueValue = "on", falseValue = "off")) { doAutoPublish ->
|
|
||||||
ServiceChannels.channels.find { it.id == channel.id.longValue }?.also {
|
|
||||||
it.message?.pushAnnouncement = doAutoPublish
|
|
||||||
ServiceChannels.saveChannels()
|
|
||||||
respond("Auto publish is now ${if (doAutoPublish) "on" else "off"}")
|
|
||||||
} ?: respond("Channel not registered!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
command("info") {
|
|
||||||
invoke {
|
|
||||||
respondEmbed {
|
|
||||||
title = "Server Overview"
|
|
||||||
color = Color.GREEN
|
|
||||||
description = """
|
|
||||||
${ServiceChannels.getServerNames(guild?.id?.longValue).joinToString("\n")}
|
|
||||||
|
|
||||||
**_Service Channels_**
|
|
||||||
${ServiceChannels.getServiceChannelServers(guild?.id?.longValue).joinToString("\n")}
|
|
||||||
""".trimIndent()
|
|
||||||
Admin.admin?.let {
|
|
||||||
author {
|
|
||||||
name = it.username
|
|
||||||
icon = it.avatar.url
|
|
||||||
url = "https://github.com/wulkanat/BlogShot"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
command("report") {
|
|
||||||
invoke {
|
|
||||||
respond("What is the error you encountered?")
|
|
||||||
val errorReport = read(StringArgument)
|
|
||||||
respondEmbed {
|
|
||||||
title = "Error Report Preview"
|
|
||||||
color = Color.RED
|
|
||||||
description = errorReport
|
|
||||||
message.author?.let {
|
|
||||||
author {
|
|
||||||
name = it.username
|
|
||||||
icon = it.avatar.url
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
respond("Send? [y/n]")
|
|
||||||
if (read(BooleanArgument(trueValue = "y", falseValue = "n"))) {
|
|
||||||
respond("Sent")
|
|
||||||
Admin.error(guild?.asGuildOrNull()?.name ?: "Unknown Guild", errorReport, author)
|
|
||||||
} else {
|
|
||||||
respond("Aborting")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package de.wulkanat.extensions
|
|
||||||
|
|
||||||
inline fun <T> Boolean.alsoIf(other: T, body: () -> Unit): Boolean {
|
|
||||||
if (this == other) {
|
|
||||||
body()
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package de.wulkanat.extensions
|
|
||||||
|
|
||||||
import com.gitlab.kordlib.core.entity.User
|
|
||||||
import de.wulkanat.files.Config
|
|
||||||
|
|
||||||
val User.isBotAdmin: Boolean
|
|
||||||
get() = id.longValue == Config.adminId
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package de.wulkanat.files
|
|
||||||
|
|
||||||
import de.wulkanat.files.concept.SerializableObject
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
|
|
||||||
object Config : SerializableObject<Config.Data>("config.json", Data(), Data.serializer()) {
|
|
||||||
val adminId: Long
|
|
||||||
get() = instance.adminId
|
|
||||||
val token: String
|
|
||||||
get() = instance.token
|
|
||||||
val updateMs: Long
|
|
||||||
get() = instance.updateMs
|
|
||||||
val watchingMessage: String
|
|
||||||
get() = instance.watchingMessage
|
|
||||||
val offlineMessage: String
|
|
||||||
get() = instance.offlineMessage
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class Data(
|
|
||||||
val adminId: Long = 12345,
|
|
||||||
val token: String = "12345",
|
|
||||||
val updateMs: Long = 30000,
|
|
||||||
val watchingMessage: String = "for new Blogposts",
|
|
||||||
val offlineMessage: String = "CONNECTION FAILED"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
package de.wulkanat.files
|
|
||||||
|
|
||||||
object Servers {
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package de.wulkanat.files.concept
|
|
||||||
|
|
||||||
import de.wulkanat.extensions.ensureExists
|
|
||||||
import kotlinx.serialization.KSerializer
|
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
abstract class SerializableObject<T>(
|
|
||||||
fileName: String,
|
|
||||||
defaultText: T? = null,
|
|
||||||
private val childSerializer: KSerializer<T>
|
|
||||||
) {
|
|
||||||
private val json = Json { allowStructuredMapKeys = true }
|
|
||||||
private val file = File(fileName).ensureExists(defaultText?.let { json.encodeToString(childSerializer, it) })
|
|
||||||
var instance: T = json.decodeFromString(childSerializer, file.readText())
|
|
||||||
|
|
||||||
fun refresh() {
|
|
||||||
instance = json.decodeFromString(childSerializer, file.readText())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun save() {
|
|
||||||
file.writeText(json.encodeToString(childSerializer, instance))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,8 +3,6 @@ package de.wulkanat.web
|
|||||||
import de.wulkanat.Admin
|
import de.wulkanat.Admin
|
||||||
import de.wulkanat.DiscordRpc
|
import de.wulkanat.DiscordRpc
|
||||||
import de.wulkanat.model.BlogPostPreview
|
import de.wulkanat.model.BlogPostPreview
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
@@ -13,14 +11,9 @@ object SiteWatcher {
|
|||||||
var newestBlog: BlogPostPreview? = null
|
var newestBlog: BlogPostPreview? = null
|
||||||
private var siteOnline = false
|
private var siteOnline = false
|
||||||
|
|
||||||
suspend fun hasNewBlogPost(): Boolean {
|
fun hasNewBlogPost(): Boolean {
|
||||||
try {
|
try {
|
||||||
val doc = withContext(Dispatchers.IO) {
|
val doc = Jsoup.connect(BLOG_INDEX_URL).get()
|
||||||
// solved by `withContext`
|
|
||||||
// https://stackoverflow.com/a/63332658
|
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
|
||||||
Jsoup.connect(BLOG_INDEX_URL).get()
|
|
||||||
}
|
|
||||||
val newBlog = BlogPostParser.getFistBlog(doc)
|
val newBlog = BlogPostParser.getFistBlog(doc)
|
||||||
|
|
||||||
if (newestBlog == newBlog) {
|
if (newestBlog == newBlog) {
|
||||||
|
|||||||
8
twitter.json
Normal file
8
twitter.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"env": "dev",
|
||||||
|
"accessToken": "1075173710557011968-OfPSjYUF6IDYtOl8yeo1x1EzXVlZWD",
|
||||||
|
"accessTokenSecret": "ikcLkku0lSNMVY7kgWcj7j7tfk3IHpHUYIkvJACp0zZXh",
|
||||||
|
"apiKey": "8rm4wAHVLXYauBbRDKAVro0kw",
|
||||||
|
"apiSecretKey": "vPZgiPxwqqHZXQGMPyxyuQrg8y45t1fAlOar9DpVlPa10JRAfC",
|
||||||
|
"bearerToken": "AAAAAAAAAAAAAAAAAAAAAJNnHwEAAAAAKVRDEbr2dzzum2wswMGOyJOQHJw%3DgniWSdhaXgcey4XBHQckZSVVXtP6y83wAp0sxnSp3CwbWpXoA3"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user