3 Commits

Author SHA1 Message Date
Wieland Schöbl
a8b148c4c7 no idea what that did 2021-01-08 15:30:22 +01:00
Wieland Schöbl
8b98d4ba3c fix connection failed message not disappearing 2020-09-25 16:04:31 +02:00
Wieland Schöbl
0877883e3c fix crash 2020-08-31 20:03:05 +02:00
18 changed files with 615 additions and 111 deletions

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

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

View File

@@ -1,6 +1,22 @@
<component name="ProjectCodeStyleConfiguration"> <component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173"> <code_scheme name="Project" version="173">
<JetCodeStyleSettings> <JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
<package name="java.util" alias="false" withSubpackages="false" />
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
<package name="io.ktor" alias="false" withSubpackages="true" />
</value>
</option>
<option name="PACKAGES_IMPORT_LAYOUT">
<value>
<package name="" alias="false" withSubpackages="true" />
<package name="java" alias="false" withSubpackages="true" />
<package name="javax" alias="false" withSubpackages="true" />
<package name="kotlin" alias="false" withSubpackages="true" />
<package name="" alias="true" withSubpackages="true" />
</value>
</option>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings> </JetCodeStyleSettings>
<codeStyleSettings language="kotlin"> <codeStyleSettings language="kotlin">

6
.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
</component>
</project>

2
.idea/misc.xml generated
View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>

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

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

199
.idea/workspace.xml generated
View File

@@ -1,20 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager"> <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="">
<change afterPath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/DiscordRpc.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/extensions/File.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
<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$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/build.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/build.gradle" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/Admin.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/Admin.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/AdminCli.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/AdminCli.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/Channels.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/Channels.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/DataIO.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/DataIO.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/Main.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/Main.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" /> <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/web/SiteWatcher.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/kotlin/de/wulkanat/web/SiteWatcher.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" />
@@ -39,52 +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="Source Sets" type="e897c970:GradleViewContributor$SourceSetsNode" />
</path>
<path> <path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" /> <item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="HytaleUpdateBot" type="f1a62948:ProjectNode" /> <item name="HytaleUpdateBot" type="f1a62948:ProjectNode" />
<item name="Tasks" type="e4a08cd1:TasksNode" /> <item name="Tasks" type="e4a08cd1:TasksNode" />
</path> </path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="HytaleUpdateBot" type="f1a62948:ProjectNode" />
<item name="Tasks" type="e4a08cd1:TasksNode" />
<item name="build" type="c8890929:TasksNode$1" />
</path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="HytaleUpdateBot" type="f1a62948:ProjectNode" />
<item name="Tasks" type="e4a08cd1:TasksNode" />
<item name="build setup" type="c8890929:TasksNode$1" />
</path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="HytaleUpdateBot" type="f1a62948:ProjectNode" />
<item name="Tasks" type="e4a08cd1:TasksNode" />
<item name="documentation" type="c8890929:TasksNode$1" />
</path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="HytaleUpdateBot" type="f1a62948:ProjectNode" />
<item name="Tasks" type="e4a08cd1:TasksNode" />
<item name="help" type="c8890929:TasksNode$1" />
</path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="HytaleUpdateBot" type="f1a62948:ProjectNode" />
<item name="Tasks" type="e4a08cd1:TasksNode" />
<item name="other" type="c8890929:TasksNode$1" />
</path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="HytaleUpdateBot" type="f1a62948:ProjectNode" />
<item name="Tasks" type="e4a08cd1:TasksNode" />
<item name="verification" type="c8890929:TasksNode$1" />
</path>
</expand> </expand>
<select /> <select />
</tree_state> </tree_state>
@@ -103,38 +54,49 @@
</option> </option>
</component> </component>
<component name="Git.Settings"> <component name="Git.Settings">
<option name="RECENT_BRANCH_BY_REPOSITORY">
<map>
<entry key="$PROJECT_DIR$" value="add-twitter-integration" />
</map>
</option>
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component> </component>
<component name="HighlightingSettingsPerFile">
<setting file="file://$PROJECT_DIR$/build.gradle" root0="SKIP_INSPECTION" />
</component>
<component name="MacroExpansionManager">
<option name="directoryName" value="5kk4ojxu" />
</component>
<component name="ProjectId" id="1g2oQiuUv1Bu6ZCW2NSVzB1V6Sc" /> <component name="ProjectId" id="1g2oQiuUv1Bu6ZCW2NSVzB1V6Sc" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" /> <component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectViewState"> <component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showExcludedFiles" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<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="Kotlin.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" />
@@ -151,7 +113,9 @@
</option> </option>
<option name="vmOptions" /> <option name="vmOptions" />
</ExternalSystemSettings> </ExternalSystemSettings>
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled> <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" /> <method v="2" />
</configuration> </configuration>
<configuration name="HytaleUpdateBot [clean]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true"> <configuration name="HytaleUpdateBot [clean]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
@@ -170,7 +134,9 @@
</option> </option>
<option name="vmOptions" /> <option name="vmOptions" />
</ExternalSystemSettings> </ExternalSystemSettings>
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled> <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" /> <method v="2" />
</configuration> </configuration>
<configuration name="HytaleUpdateBot [fatJar]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true"> <configuration name="HytaleUpdateBot [fatJar]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
@@ -189,7 +155,9 @@
</option> </option>
<option name="vmOptions" /> <option name="vmOptions" />
</ExternalSystemSettings> </ExternalSystemSettings>
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled> <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" /> <method v="2" />
</configuration> </configuration>
<configuration name="HytaleUpdateBot-all-1.0-SNAPSHOT.jar" type="JarApplication" temporary="true"> <configuration name="HytaleUpdateBot-all-1.0-SNAPSHOT.jar" type="JarApplication" temporary="true">
@@ -211,14 +179,15 @@
</configuration> </configuration>
<recent_temporary> <recent_temporary>
<list> <list>
<item itemvalue="Kotlin.MainKt" /> <item itemvalue="Application.MainKt" />
<item itemvalue="Gradle.HytaleUpdateBot [fatJar]" />
<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>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="project-level" UseSingleDictionary="true" transferred="true" />
<component name="SvnConfiguration"> <component name="SvnConfiguration">
<configuration /> <configuration />
</component> </component>
@@ -251,23 +220,52 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1597438317540</updated> <updated>1597438317540</updated>
</task> </task>
<option name="localTasksCounter" value="4" /> <task id="LOCAL-00004" summary="Add service announcement channel">
<created>1597839954908</created>
<option name="number" value="00004" />
<option name="presentableId" value="LOCAL-00004" />
<option name="project" value="LOCAL" />
<updated>1597839954909</updated>
</task>
<task id="LOCAL-00005" summary="prepare twitter integration">
<created>1601042375685</created>
<option name="number" value="00005" />
<option name="presentableId" value="LOCAL-00005" />
<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" />
<servers /> <servers />
</component> </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]" />
<option name="LAST_COMMIT_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>
<component name="WindowStateProjectService"> <component name="WindowStateProjectService">
<state x="552" y="179" key="#Project_Structure" timestamp="1597687666334"> <state x="552" y="179" key="#Project_Structure" timestamp="1601148661909">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
<state x="552" y="179" key="#Project_Structure/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597687666334" /> <state x="552" y="179" key="#Project_Structure/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1601148661909" />
<state x="-1050" y="581" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1597352463714"> <state x="-1050" y="581" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1597352463714">
<screen x="-1050" y="105" width="1050" height="1640" /> <screen x="-1050" y="105" width="1050" height="1640" />
</state> </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="-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"> <state x="633" y="446" key="#com.intellij.refactoring.move.MoveHandler.SelectRefactoringDialog" timestamp="1597362173063">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
@@ -284,54 +282,58 @@
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </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="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="1597438316655"> <state x="569" y="115" key="CommitChangelistDialog2" timestamp="1601042670025">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </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="1597438316655" /> <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"> <state x="740" y="238" key="FileChooserDialogImpl" timestamp="1597605616287">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </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 x="740" y="238" key="FileChooserDialogImpl/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597605616287" />
<state width="1876" height="161" key="GridCell.Tab.0.bottom" timestamp="1597839551368"> <state width="1877" height="161" key="GridCell.Tab.0.bottom" timestamp="1601059408217">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </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="1006" height="588" key="GridCell.Tab.0.bottom/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@-1050.105.1050.1640" timestamp="1597351329412" />
<state width="1876" height="161" key="GridCell.Tab.0.bottom/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597839551368" /> <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="1876" height="161" key="GridCell.Tab.0.center" timestamp="1597839551368"> <state width="1877" height="161" key="GridCell.Tab.0.center" timestamp="1601059408216">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </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="1006" height="588" key="GridCell.Tab.0.center/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@-1050.105.1050.1640" timestamp="1597351329411" />
<state width="1876" height="161" key="GridCell.Tab.0.center/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597839551368" /> <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="1876" height="161" key="GridCell.Tab.0.left" timestamp="1597839551368"> <state width="1877" height="161" key="GridCell.Tab.0.left" timestamp="1601059408216">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </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="1006" height="588" key="GridCell.Tab.0.left/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@-1050.105.1050.1640" timestamp="1597351329411" />
<state width="1876" height="161" key="GridCell.Tab.0.left/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597839551368" /> <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="1876" height="161" key="GridCell.Tab.0.right" timestamp="1597839551368"> <state width="1877" height="161" key="GridCell.Tab.0.right" timestamp="1601059408216">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </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="1006" height="588" key="GridCell.Tab.0.right/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@-1050.105.1050.1640" timestamp="1597351329411" />
<state width="1876" height="161" key="GridCell.Tab.0.right/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597839551368" /> <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="1597837225399"> <state width="1876" height="348" key="GridCell.Tab.1.bottom" timestamp="1597840755247">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </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="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="1597837225399" /> <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="1597837225398"> <state width="1876" height="348" key="GridCell.Tab.1.center" timestamp="1597840755246">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </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="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="1597837225398" /> <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="1597837225398"> <state width="1876" height="348" key="GridCell.Tab.1.left" timestamp="1597840755246">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </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="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="1597837225398" /> <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="1597837225399"> <state width="1876" height="348" key="GridCell.Tab.1.right" timestamp="1597840755247">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </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="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="1597837225399" /> <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"> <state x="672" y="237" key="MultipleFileMergeDialog" timestamp="1597438068748">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </state>
@@ -341,13 +343,18 @@
</state> </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="-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="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="1597438319085"> <state x="552" y="254" key="Vcs.Push.Dialog.v2" timestamp="1601042674727">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </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="1597438319085" /> <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="2582" y="100" key="new project wizard" timestamp="1597605657341"> <state x="777" y="434" key="com.intellij.openapi.vcs.update.UpdateOrStatusOptionsDialogupdate-v2" timestamp="1601042455663">
<screen x="1920" y="-213" width="2560" height="1400" /> <screen x="0" y="0" width="1920" height="1040" />
</state> </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="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"> <state x="616" y="240" key="run.anything.popup" timestamp="1597325088886">
<screen x="0" y="0" width="1920" height="1040" /> <screen x="0" y="0" width="1920" height="1040" />
@@ -363,7 +370,7 @@
<breakpoints> <breakpoints>
<line-breakpoint enabled="true" type="kotlin-line"> <line-breakpoint enabled="true" type="kotlin-line">
<url>file://$PROJECT_DIR$/src/main/kotlin/de/wulkanat/AdminCli.kt</url> <url>file://$PROJECT_DIR$/src/main/kotlin/de/wulkanat/AdminCli.kt</url>
<line>18</line> <line>22</line>
<option name="timeStamp" value="1" /> <option name="timeStamp" value="1" />
</line-breakpoint> </line-breakpoint>
</breakpoints> </breakpoints>

View File

@@ -53,6 +53,8 @@ I developed it under Windows, and had some trouble compiling it on Linux. You mi
| !serviceMessage | message | Send a service message to all registered channels | | !serviceMessage | message | Send a service message to all registered channels |
| !fakeUpdate | | Cause a fake update (**WARNING**: This will show on **ALL** registered servers) | | !fakeUpdate | | Cause a fake update (**WARNING**: This will show on **ALL** registered servers) |
| !refreshList | | Refresh servers and service channels from disk (if you manually edit the JSON files) | | !refreshList | | Refresh servers and service channels from disk (if you manually edit the JSON files) |
| !removeInactive | | Remove inactive channels |
| !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 `admin.json`. come from the admin registered in the `admin.json`.

View File

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

View File

@@ -3,14 +3,18 @@ package de.wulkanat
import de.wulkanat.model.BlogPostPreview import de.wulkanat.model.BlogPostPreview
import net.dv8tion.jda.api.hooks.ListenerAdapter import net.dv8tion.jda.api.hooks.ListenerAdapter
import de.wulkanat.web.SiteWatcher import de.wulkanat.web.SiteWatcher
import net.dv8tion.jda.api.EmbedBuilder
import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent
import java.awt.Color
import kotlin.system.exitProcess import kotlin.system.exitProcess
class AdminCli : ListenerAdapter() { class AdminCli : ListenerAdapter() {
val prefix = "!"
override fun onPrivateMessageReceived(event: PrivateMessageReceivedEvent) { override fun onPrivateMessageReceived(event: PrivateMessageReceivedEvent) {
val msg = event.message.contentRaw val msg = event.message.contentRaw
if (event.author.idLong != Admin.userId || if (event.author.idLong != Admin.userId ||
!msg.startsWith("!") !msg.startsWith(prefix)
) { ) {
return return
} }
@@ -45,6 +49,43 @@ class AdminCli : ListenerAdapter() {
Channels.serviceChannels = Channels.refreshServiceChannelsFromDisk() Channels.serviceChannels = Channels.refreshServiceChannelsFromDisk()
Admin.info() 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()
}
} }
} }
} }

View File

@@ -1,15 +1,12 @@
package de.wulkanat package de.wulkanat
import de.wulkanat.extensions.crosspost import de.wulkanat.extensions.crosspost
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration
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
import net.dv8tion.jda.api.Permission import net.dv8tion.jda.api.Permission
import net.dv8tion.jda.api.entities.MessageEmbed import net.dv8tion.jda.api.entities.MessageEmbed
import net.dv8tion.jda.api.entities.TextChannel import net.dv8tion.jda.api.entities.TextChannel
import net.dv8tion.jda.api.exceptions.ErrorResponseException
import java.awt.Color import java.awt.Color
object Channels { object Channels {
@@ -53,8 +50,8 @@ object Channels {
it.crosspost().queue() it.crosspost().queue()
} }
} }
} catch (e: ErrorResponseException) { } catch (e: Exception) {
Admin.error("Error in server", e.message ?: e.localizedMessage) Admin.error("Error in server ${channel_pair.id}", e.message ?: e.localizedMessage)
} }
} }
} }

View File

@@ -1,12 +1,103 @@
package de.wulkanat package de.wulkanat
import net.dv8tion.jda.api.EmbedBuilder import de.wulkanat.cli.Cli
import net.dv8tion.jda.api.Permission import de.wulkanat.cli.makeCli
import net.dv8tion.jda.api.events.message.MessageReceivedEvent import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent
import net.dv8tion.jda.api.hooks.ListenerAdapter import net.dv8tion.jda.api.hooks.ListenerAdapter
import java.awt.Color
class OwnerCli : 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 = "%!" private val prefix = "%!"
override fun onMessageReceived(event: MessageReceivedEvent) { override fun onMessageReceived(event: MessageReceivedEvent) {
@@ -211,5 +302,5 @@ class OwnerCli : ListenerAdapter() {
).queue() ).queue()
} }
} }
} }*
} }*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -34,7 +34,7 @@ object SiteWatcher {
return false return false
} }
if (siteOnline) { if (!siteOnline) {
siteOnline = true siteOnline = true
DiscordRpc.updatePresence(siteOnline) DiscordRpc.updatePresence(siteOnline)
} }

8
twitter.json Normal file
View File

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