mirror of
https://github.com/HMCore/Orbot.git
synced 2025-12-12 13:56:18 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a78c2343da | ||
|
|
490a5dcd41 | ||
|
|
5969a2f221 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,6 +1,6 @@
|
|||||||
servers.json
|
servers.json
|
||||||
admin.json
|
admin.json
|
||||||
test.json
|
service_channels.json
|
||||||
*.hprof
|
*.hprof
|
||||||
/build
|
/build
|
||||||
/.gradle
|
/.gradle
|
||||||
102
.idea/workspace.xml
generated
102
.idea/workspace.xml
generated
@@ -1,9 +1,20 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="1aabf22b-2f57-46ac-9973-367d8668ffd3" name="Default Changelist" comment="[1.1]">
|
<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$/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/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" />
|
||||||
@@ -84,10 +95,10 @@
|
|||||||
<component name="FileTemplateManagerImpl">
|
<component name="FileTemplateManagerImpl">
|
||||||
<option name="RECENT_TEMPLATES">
|
<option name="RECENT_TEMPLATES">
|
||||||
<list>
|
<list>
|
||||||
<option value="Kotlin Object" />
|
|
||||||
<option value="Kotlin File" />
|
|
||||||
<option value="Class" />
|
<option value="Class" />
|
||||||
<option value="Kotlin Class" />
|
<option value="Kotlin Class" />
|
||||||
|
<option value="Kotlin Object" />
|
||||||
|
<option value="Kotlin File" />
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
@@ -104,7 +115,7 @@
|
|||||||
<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$/src" />
|
<property name="last_opened_file_path" value="$PROJECT_DIR$/build/libs" />
|
||||||
<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" />
|
||||||
@@ -115,6 +126,7 @@
|
|||||||
<recent name="de.wulkanat" />
|
<recent name="de.wulkanat" />
|
||||||
</key>
|
</key>
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
|
<recent name="E:\Projects\Kotlin_Proj\HytaleUpdateBot\build\libs" />
|
||||||
<recent name="E:\Projects\Kotlin_Proj\HytaleUpdateBot\src" />
|
<recent name="E:\Projects\Kotlin_Proj\HytaleUpdateBot\src" />
|
||||||
</key>
|
</key>
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
@@ -122,7 +134,7 @@
|
|||||||
<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>
|
||||||
</component>
|
</component>
|
||||||
<component name="RunManager" selected="Gradle.HytaleUpdateBot [fatJar]">
|
<component name="RunManager" selected="Kotlin.MainKt">
|
||||||
<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" />
|
||||||
@@ -199,8 +211,8 @@
|
|||||||
</configuration>
|
</configuration>
|
||||||
<recent_temporary>
|
<recent_temporary>
|
||||||
<list>
|
<list>
|
||||||
<item itemvalue="Gradle.HytaleUpdateBot [fatJar]" />
|
|
||||||
<item itemvalue="Kotlin.MainKt" />
|
<item itemvalue="Kotlin.MainKt" />
|
||||||
|
<item itemvalue="Gradle.HytaleUpdateBot [fatJar]" />
|
||||||
<item itemvalue="Gradle.HytaleUpdateBot [build]" />
|
<item itemvalue="Gradle.HytaleUpdateBot [build]" />
|
||||||
<item itemvalue="Gradle.HytaleUpdateBot [clean]" />
|
<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" />
|
||||||
@@ -232,7 +244,14 @@
|
|||||||
<option name="project" value="LOCAL" />
|
<option name="project" value="LOCAL" />
|
||||||
<updated>1597438052596</updated>
|
<updated>1597438052596</updated>
|
||||||
</task>
|
</task>
|
||||||
<option name="localTasksCounter" value="3" />
|
<task id="LOCAL-00003" summary="[1.1]">
|
||||||
|
<created>1597438317540</created>
|
||||||
|
<option name="number" value="00003" />
|
||||||
|
<option name="presentableId" value="LOCAL-00003" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1597438317540</updated>
|
||||||
|
</task>
|
||||||
|
<option name="localTasksCounter" value="4" />
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="VcsManagerConfiguration">
|
<component name="VcsManagerConfiguration">
|
||||||
@@ -241,10 +260,10 @@
|
|||||||
<option name="LAST_COMMIT_MESSAGE" value="[1.1]" />
|
<option name="LAST_COMMIT_MESSAGE" value="[1.1]" />
|
||||||
</component>
|
</component>
|
||||||
<component name="WindowStateProjectService">
|
<component name="WindowStateProjectService">
|
||||||
<state x="552" y="179" key="#Project_Structure" timestamp="1597434105164">
|
<state x="552" y="179" key="#Project_Structure" timestamp="1597687666334">
|
||||||
<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="1597434105164" />
|
<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="-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>
|
||||||
@@ -253,10 +272,10 @@
|
|||||||
<screen x="0" y="0" width="1920" height="1040" />
|
<screen x="0" y="0" width="1920" height="1040" />
|
||||||
</state>
|
</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="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="1597428556346">
|
<state x="690" y="268" key="#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog" timestamp="1597831342920">
|
||||||
<screen x="0" y="0" width="1920" height="1040" />
|
<screen x="0" y="0" width="1920" height="1040" />
|
||||||
</state>
|
</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="1597428556346" />
|
<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">
|
<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" />
|
<screen x="0" y="0" width="1920" height="1040" />
|
||||||
</state>
|
</state>
|
||||||
@@ -265,50 +284,54 @@
|
|||||||
<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="1597438290366">
|
<state x="569" y="115" key="CommitChangelistDialog2" timestamp="1597438316655">
|
||||||
<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="1597438290366" />
|
<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 width="1876" height="161" key="GridCell.Tab.0.bottom" timestamp="1597438298864">
|
<state x="740" y="238" key="FileChooserDialogImpl" timestamp="1597605616287">
|
||||||
|
<screen x="0" y="0" width="1920" height="1040" />
|
||||||
|
</state>
|
||||||
|
<state x="740" y="238" key="FileChooserDialogImpl/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597605616287" />
|
||||||
|
<state width="1876" height="161" key="GridCell.Tab.0.bottom" timestamp="1597839551368">
|
||||||
<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="1597438298864" />
|
<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="1876" height="161" key="GridCell.Tab.0.center" timestamp="1597438298864">
|
<state width="1876" height="161" key="GridCell.Tab.0.center" timestamp="1597839551368">
|
||||||
<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="1597438298864" />
|
<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="1876" height="161" key="GridCell.Tab.0.left" timestamp="1597438298864">
|
<state width="1876" height="161" key="GridCell.Tab.0.left" timestamp="1597839551368">
|
||||||
<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="1597438298864" />
|
<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="1876" height="161" key="GridCell.Tab.0.right" timestamp="1597438298864">
|
<state width="1876" height="161" key="GridCell.Tab.0.right" timestamp="1597839551368">
|
||||||
<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="1597438298864" />
|
<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="1006" height="588" key="GridCell.Tab.1.bottom" timestamp="1597366506508">
|
<state width="1876" height="348" key="GridCell.Tab.1.bottom" timestamp="1597837225399">
|
||||||
<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="1006" height="588" key="GridCell.Tab.1.bottom/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597366506508" />
|
<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="1006" height="588" key="GridCell.Tab.1.center" timestamp="1597366506506">
|
<state width="1876" height="348" key="GridCell.Tab.1.center" timestamp="1597837225398">
|
||||||
<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="1006" height="588" key="GridCell.Tab.1.center/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597366506506" />
|
<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="1006" height="588" key="GridCell.Tab.1.left" timestamp="1597366506505">
|
<state width="1876" height="348" key="GridCell.Tab.1.left" timestamp="1597837225398">
|
||||||
<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="1006" height="588" key="GridCell.Tab.1.left/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597366506505" />
|
<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="1006" height="588" key="GridCell.Tab.1.right" timestamp="1597366506507">
|
<state width="1876" height="348" key="GridCell.Tab.1.right" timestamp="1597837225399">
|
||||||
<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="1006" height="588" key="GridCell.Tab.1.right/0.0.1920.1040/1920.-213.2560.1400/-1050.105.1050.1640@0.0.1920.1040" timestamp="1597366506507" />
|
<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 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>
|
||||||
@@ -318,20 +341,33 @@
|
|||||||
</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="1597438121430">
|
<state x="552" y="254" key="Vcs.Push.Dialog.v2" timestamp="1597438319085">
|
||||||
<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="1597438121430" />
|
<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="2582" y="100" key="new project wizard" timestamp="1597605657341">
|
||||||
|
<screen x="1920" y="-213" width="2560" height="1400" />
|
||||||
|
</state>
|
||||||
|
<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" />
|
||||||
</state>
|
</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="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="1597363843473">
|
<state x="623" y="225" width="672" height="678" key="search.everywhere.popup" timestamp="1597702900013">
|
||||||
<screen x="0" y="0" width="1920" height="1040" />
|
<screen x="0" y="0" width="1920" height="1040" />
|
||||||
</state>
|
</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="1597363843473" />
|
<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>
|
||||||
|
<breakpoints>
|
||||||
|
<line-breakpoint enabled="true" type="kotlin-line">
|
||||||
|
<url>file://$PROJECT_DIR$/src/main/kotlin/de/wulkanat/AdminCli.kt</url>
|
||||||
|
<line>18</line>
|
||||||
|
<option name="timeStamp" value="1" />
|
||||||
|
</line-breakpoint>
|
||||||
|
</breakpoints>
|
||||||
|
</breakpoint-manager>
|
||||||
<watches-manager>
|
<watches-manager>
|
||||||
<configuration name="JetRunConfigurationType">
|
<configuration name="JetRunConfigurationType">
|
||||||
<watch expression="((org.jsoup.nodes.Element.NodeList)((Document)doc).childNodes).get(2)" custom="org.jsoup.nodes.Element.NodeList,org.jsoup.nodes.Document" />
|
<watch expression="((org.jsoup.nodes.Element.NodeList)((Document)doc).childNodes).get(2)" custom="org.jsoup.nodes.Element.NodeList,org.jsoup.nodes.Document" />
|
||||||
|
|||||||
116
README.md
116
README.md
@@ -1,80 +1,66 @@
|
|||||||
# BlogShot
|
# BlogShot
|
||||||
A bot that automatically polls the newest blogpost from [Hytale News Tab](https://www.hytale.com/news) and posts a message into servers if there is a new one.
|
A bot that automatically polls the newest blogpost from [Hytale News Tab](https://www.hytale.com/news) and posts a message into servers if there is a new one.
|
||||||
## Setup
|
## Add to your server
|
||||||
Okay, this isn't really meant for you to setup, if you want it though it first is easier to just dm me on Twitter [@tale_talk](https://twitter.com/tale_talk) so I can add you to the server list.
|
Click [this](https://discord.com/api/oauth2/authorize?client_id=743447329901641799&permissions=150528&scope=bot) link to invite
|
||||||
If you *really* want to set it up yourself, fine.
|
the bot to your server. Please note that only people with *Administrator* permission will be able to
|
||||||
* first go to the release tab, download the jar, and put it in a folder
|
configure it.
|
||||||
* Add two files in the root of the repo, an `admin.json` and a `servers.json`.
|
|
||||||
Add your Discord ID (not name), Bot token, and update frequency to the `admin.json`:
|
You can type `%!info` to get an overview over all available commands.
|
||||||
```json
|
## Commands
|
||||||
{
|
|
||||||
"adminId": 12345678910,
|
| **Command** | **Arguments** | **Info** |
|
||||||
"token": "AOGH@(AKnjsfjiJijaig3ijgG92jaij",
|
|------------------|--------------------------------------------------------|---------------------------------------------------------------------------------------------------|
|
||||||
"updateMs":30000
|
| %!add | | Add current channel to the notified list |
|
||||||
}
|
| %!remove | | Remove current channel to the notified list |
|
||||||
```
|
| %!publish | on | off | [Community|Partner|Verified only] Auto publish the message if in an announcement channel |
|
||||||
* add your servers to `servers.json`
|
| %!ping | none | everyone | roleName | What role to ping |
|
||||||
```json
|
| %!setMessage | message | Set a custom message when a blogpost arrives |
|
||||||
[
|
| %!resetMessage | | Reset the custom message to none |
|
||||||
{
|
| %!serviceChannel | add | remove | Add/remove channel from service notification list |
|
||||||
"id": 15050067772322222,
|
| %!publishMessage | on | off | [Community|Partner|Verified only] Auto publish the custom message if in an announcement channel |
|
||||||
"mentionedRole": "everyone",
|
| %!info | | Show an overview about all channels registered on this server |
|
||||||
"autoPublish":true
|
| %!report | Your message | Report an issue to the Bot Admin (this will share your user name so they can contact you) |
|
||||||
},
|
| %!help | | Show a help dialog with all these commands |
|
||||||
{
|
|
||||||
"id": 74050067772325222,
|
## Self Hosting
|
||||||
"mentionedRole": null,
|
Okay, this isn't really meant for you to setup, but if you *really* want to set it up yourself, fine.
|
||||||
"autoPublish":false
|
Go to the release tab, download the jar, and put it in a folder.
|
||||||
},
|
|
||||||
{
|
Start the server with `java -jar [server-file-name]` If you put in everything correctly,
|
||||||
"id": 74050067772325222,
|
the bot should message you on Discord.
|
||||||
"mentionedRole": "74036067771625222",
|
|
||||||
"autoPublish":false
|
*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 `admin.json`, `servers.json` and `service_channels.json`
|
||||||
```
|
are being created.
|
||||||
* add a `test.json` with the same schema as the `server.json`. When
|
Add your Discord ID `adminId` (not name), Bot token `token`, and update frequency `updateMs` to the `admin.json`,
|
||||||
you enable test mode, the servers from there will be used instead allowing
|
optionally you can add your own messages for when the bot is looking and when it can't reach Hytale Servers.
|
||||||
you to test if it works.
|
|
||||||
|
If you verified that everything works correctly, you can start the server in the background, on Linux that is
|
||||||
|
`nohup java -jar [server-file-name]`. To stop it you can either type `!stop` in the Admin Console (Discord PM) or
|
||||||
|
if the bot is unresponsive the the PID of it through `ps -ef` and `kill [pid]`
|
||||||
|
|
||||||
|
|
||||||
## 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.
|
||||||
|
|
||||||
## Admin commands
|
## Admin commands
|
||||||
|
|
||||||
Start the server with `java -jar [server-file-name]` If you put in everything correctly, the bot should message you on Discord.
|
| **Command** | **Arguments** | **Info** |
|
||||||
### Adding Servers
|
|------------------|-------|---------------------|
|
||||||
Please edit the JSON file.
|
| !info | | Show all registered channels and servers. |
|
||||||
You can force an update by calling
|
| !stop | | Stop the server (useful when running in `nohup`) |
|
||||||
```
|
| !serviceMessage | message | Send a service message to all registered channels |
|
||||||
%!refreshList
|
| !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) |
|
||||||
### Testing
|
|
||||||
Switching between test and production files
|
|
||||||
```
|
|
||||||
%!testMode
|
|
||||||
%!fakeUpdate
|
|
||||||
```
|
|
||||||
```
|
|
||||||
%!productionMode
|
|
||||||
```
|
|
||||||
**WARNING**: Initiating a fake update is not being cancelled by switching
|
|
||||||
to production.
|
|
||||||
### Stop the server from within Discord
|
|
||||||
```
|
|
||||||
%!stop
|
|
||||||
```
|
|
||||||
### Show servers, channels and roles
|
|
||||||
```
|
|
||||||
%!info
|
|
||||||
```
|
|
||||||
|
|
||||||
These commands will work in every channel, but will be ignored if they don't come from you, however the bot will always respond in a private message.
|
These commands will only work by private messaging the bot (and will be ignored if they don't
|
||||||
It will also print errors directly in a Discord private message.
|
come from the admin registered in the `admin.json`.
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
Mainly reaction roles for convenience, self setup on invite to server, Twitter integration.
|
Mainly reaction roles for convenience, Twitter integration to either be even faster or to brag how much faster
|
||||||
|
we were over the official Hytale Twitter.
|
||||||
|
|
||||||
## Other
|
## Other
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group 'de.wulkanat'
|
group 'de.wulkanat'
|
||||||
version '1.1'
|
version '1.4'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|||||||
@@ -13,29 +13,16 @@ object Admin {
|
|||||||
val userId: Long
|
val userId: Long
|
||||||
val token: String
|
val token: String
|
||||||
val updateMs: Long
|
val updateMs: Long
|
||||||
|
val message: String
|
||||||
var testModeEnabled: Boolean = false
|
val offlineMessage: String
|
||||||
set(value) {
|
|
||||||
if (field == value)
|
|
||||||
return
|
|
||||||
|
|
||||||
field = value
|
|
||||||
|
|
||||||
if (value) {
|
|
||||||
jda?.presence?.setPresence(Activity.of(Activity.ActivityType.DEFAULT, "Testing mode, hold on..."), true)
|
|
||||||
} else {
|
|
||||||
jda?.presence?.setPresence(Activity.watching("for new Blogposts"), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
Channels.channels = Channels.refreshFromDisk()
|
|
||||||
Admin.info()
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val admin = Json(JsonConfiguration.Stable).parse(AdminFile.serializer(), ADMIN_FILE.readText())
|
val admin = Json(JsonConfiguration.Stable).parse(AdminFile.serializer(), ADMIN_FILE.readText())
|
||||||
userId = admin.adminId
|
userId = admin.adminId
|
||||||
token = admin.token
|
token = admin.token
|
||||||
updateMs = admin.updateMs
|
updateMs = admin.updateMs
|
||||||
|
message = admin.watchingMessage
|
||||||
|
offlineMessage = admin.offlineMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
var jda: JDA? = null
|
var jda: JDA? = null
|
||||||
@@ -49,7 +36,7 @@ object Admin {
|
|||||||
kotlin.io.println("Connected to ${admin!!.name}. No further errors will be printed here.")
|
kotlin.io.println("Connected to ${admin!!.name}. No further errors will be printed here.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private var admin: User? = null
|
var admin: User? = null
|
||||||
|
|
||||||
fun println(msg: String) {
|
fun println(msg: String) {
|
||||||
sendDevMessage(
|
sendDevMessage(
|
||||||
@@ -71,12 +58,19 @@ object Admin {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun error(msg: String, error: String) {
|
fun error(msg: String, error: String, author: User? = null) {
|
||||||
sendDevMessage(
|
sendDevMessage(
|
||||||
EmbedBuilder()
|
EmbedBuilder()
|
||||||
.setTitle(msg)
|
.setTitle(msg)
|
||||||
.setDescription(error)
|
.setDescription(error)
|
||||||
.setColor(Color.RED)
|
.setColor(Color.RED)
|
||||||
|
.run {
|
||||||
|
if (author == null) {
|
||||||
|
this
|
||||||
|
} else {
|
||||||
|
this.setAuthor(author.asTag, author.avatarUrl, author.avatarUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
.build()
|
.build()
|
||||||
, "$msg\n\n${error}"
|
, "$msg\n\n${error}"
|
||||||
)
|
)
|
||||||
@@ -107,7 +101,12 @@ object Admin {
|
|||||||
sendDevMessage(
|
sendDevMessage(
|
||||||
EmbedBuilder()
|
EmbedBuilder()
|
||||||
.setTitle("Now watching for new Hytale Blogposts every ${updateMs / 1000}s")
|
.setTitle("Now watching for new Hytale Blogposts every ${updateMs / 1000}s")
|
||||||
.setDescription(Channels.getServerNames().joinToString("\n"))
|
.setDescription("""
|
||||||
|
${Channels.getServerNames().joinToString("\n")}
|
||||||
|
|
||||||
|
**_Service Channels_**
|
||||||
|
${Channels.getServiceChannelServers().joinToString("\n")}
|
||||||
|
""".trimIndent())
|
||||||
.setColor(Color.GREEN)
|
.setColor(Color.GREEN)
|
||||||
.build(),
|
.build(),
|
||||||
"Now watching for new Hytale BlogPosts"
|
"Now watching for new Hytale BlogPosts"
|
||||||
@@ -129,7 +128,7 @@ object Admin {
|
|||||||
.sendMessage(messageEmbed).complete()
|
.sendMessage(messageEmbed).complete()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendDevMessage(messageEmbed: MessageEmbed, fallback: String) {
|
fun sendDevMessage(messageEmbed: MessageEmbed, fallback: String) {
|
||||||
val devChannel = admin?.openPrivateChannel() ?: kotlin.run {
|
val devChannel = admin?.openPrivateChannel() ?: kotlin.run {
|
||||||
kotlin.io.println(fallback)
|
kotlin.io.println(fallback)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
package de.wulkanat
|
package de.wulkanat
|
||||||
|
|
||||||
import de.wulkanat.model.BlogPostPreview
|
import de.wulkanat.model.BlogPostPreview
|
||||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent
|
|
||||||
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.events.ExceptionEvent
|
|
||||||
import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent
|
import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
class Cli : ListenerAdapter() {
|
class AdminCli : ListenerAdapter() {
|
||||||
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 ||
|
||||||
@@ -16,9 +14,9 @@ class Cli : ListenerAdapter() {
|
|||||||
) {
|
) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val command = msg.removePrefix("!").split(Regex("\\s+"))
|
val command = Regex("[^\\s`]+|`[^`]*`").findAll(msg.removePrefix("!")).toList()
|
||||||
|
|
||||||
when (command[0]) {
|
when (command[0].value) {
|
||||||
"stop" -> exitProcess(1)
|
"stop" -> exitProcess(1)
|
||||||
"fakeUpdate" -> {
|
"fakeUpdate" -> {
|
||||||
SiteWatcher.newestBlog = BlogPostPreview(
|
SiteWatcher.newestBlog = BlogPostPreview(
|
||||||
@@ -35,16 +33,18 @@ class Cli : ListenerAdapter() {
|
|||||||
"info" -> {
|
"info" -> {
|
||||||
Admin.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" -> {
|
"refreshList" -> {
|
||||||
Channels.channels = Channels.refreshFromDisk()
|
Channels.channels = Channels.refreshChannelsFromDisk()
|
||||||
|
Channels.serviceChannels = Channels.refreshServiceChannelsFromDisk()
|
||||||
Admin.info()
|
Admin.info()
|
||||||
}
|
}
|
||||||
"testMode" -> {
|
|
||||||
Admin.testModeEnabled = true
|
|
||||||
}
|
|
||||||
"productionMode" -> {
|
|
||||||
Admin.testModeEnabled = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,43 +4,88 @@ import de.wulkanat.extensions.crosspost
|
|||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonConfiguration
|
import kotlinx.serialization.json.JsonConfiguration
|
||||||
import kotlinx.serialization.list
|
import kotlinx.serialization.list
|
||||||
|
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
|
||||||
|
|
||||||
object Channels {
|
object Channels {
|
||||||
var jda: JDA? = null
|
var jda: JDA? = null
|
||||||
val json = Json(JsonConfiguration.Stable)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of (ServerID, ChannelID)
|
* List of (ServerID, ChannelID)
|
||||||
*/
|
*/
|
||||||
var channels: MutableList<DiscordChannel> = refreshFromDisk()
|
var channels: MutableList<DiscordChannel> = refreshChannelsFromDisk()
|
||||||
|
var serviceChannels: MutableList<ServiceChannel> = refreshServiceChannelsFromDisk()
|
||||||
|
|
||||||
fun sentToAll(messageEmbed: MessageEmbed) {
|
fun sentToAll(messageEmbed: MessageEmbed) {
|
||||||
if (jda == null)
|
if (jda == null)
|
||||||
return
|
return
|
||||||
|
|
||||||
for (channel_pair in channels) {
|
for (channel_pair in channels) {
|
||||||
val channel = jda!!.getTextChannelById(channel_pair.id) ?: continue
|
try {
|
||||||
|
val channel = jda!!.getTextChannelById(channel_pair.id) ?: continue
|
||||||
|
val customMessage = channel_pair.message?.message ?: ""
|
||||||
|
|
||||||
if (channel_pair.mentionedRole != null) {
|
if (channel_pair.mentionedRole != null) {
|
||||||
val message = if (channel_pair.mentionedRole == "everyone") {
|
val message = if (channel_pair.mentionedRole == "everyone") {
|
||||||
"New Blogpost @everyone"
|
"@everyone $customMessage"
|
||||||
} else {
|
} else {
|
||||||
"New Blogpost <@&${channel_pair.mentionedRole}>"
|
"<@&${channel_pair.mentionedRole}> $customMessage"
|
||||||
|
}
|
||||||
|
channel.sendMessage(message).queue {
|
||||||
|
if (channel_pair.message?.pushAnnouncement == true) {
|
||||||
|
it.crosspost().queue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (channel_pair.message != null) {
|
||||||
|
channel.sendMessage(customMessage).queue {
|
||||||
|
if (channel_pair.message?.pushAnnouncement == true) {
|
||||||
|
it.crosspost().queue()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
channel.sendMessage(message).queue()
|
channel.sendMessage(messageEmbed).queue {
|
||||||
}
|
if (channel_pair.autoPublish) {
|
||||||
channel.sendMessage(messageEmbed).queue {
|
it.crosspost().queue()
|
||||||
if (channel_pair.autoPublish) {
|
}
|
||||||
it.crosspost().queue()
|
|
||||||
}
|
}
|
||||||
|
} catch (e: ErrorResponseException) {
|
||||||
|
Admin.error("Error in server", e.message ?: e.localizedMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun sendServiceMessage(title: String, message: String) {
|
||||||
|
val serviceMessage = EmbedBuilder()
|
||||||
|
.setTitle(title)
|
||||||
|
.setDescription(message)
|
||||||
|
.setColor(Color.WHITE)
|
||||||
|
.setAuthor(Admin.admin?.name, Admin.admin?.avatarUrl, Admin.admin?.avatarUrl)
|
||||||
|
.setFooter("This was sent by a human.")
|
||||||
|
.build()
|
||||||
|
|
||||||
|
for (channelInfo in serviceChannels) {
|
||||||
|
val channel = jda!!.getTextChannelById(channelInfo.id)
|
||||||
|
|
||||||
|
channel?.sendMessage(serviceMessage)?.queue()
|
||||||
|
}
|
||||||
|
|
||||||
|
Admin.println("Service message distributed to ${serviceChannels.size} channels.")
|
||||||
|
Admin.sendDevMessage(serviceMessage, """
|
||||||
|
***************
|
||||||
|
SERVICE MESSAGE
|
||||||
|
|
||||||
|
$title
|
||||||
|
-------
|
||||||
|
$message
|
||||||
|
***************
|
||||||
|
""".trimIndent())
|
||||||
|
}
|
||||||
|
|
||||||
fun checkEveryonePermission() {
|
fun checkEveryonePermission() {
|
||||||
for (channel_pair in channels) {
|
for (channel_pair in channels) {
|
||||||
val channel = jda!!.getTextChannelById(channel_pair.id) ?: continue
|
val channel = jda!!.getTextChannelById(channel_pair.id) ?: continue
|
||||||
@@ -56,21 +101,23 @@ object Channels {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun refreshFromDisk(): MutableList<DiscordChannel> {
|
fun refreshChannelsFromDisk(): MutableList<DiscordChannel> {
|
||||||
return json.parse(
|
return json.parse(
|
||||||
DiscordChannel.serializer().list, (if (Admin.testModeEnabled) {
|
DiscordChannel.serializer().list, (SERVERS_FILE).readText()
|
||||||
TEST_FILE
|
|
||||||
} else {
|
|
||||||
SERVERS_FILE
|
|
||||||
}).readText()
|
|
||||||
).toMutableList()
|
).toMutableList()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getServerNames(): List<String> {
|
fun refreshServiceChannelsFromDisk(): MutableList<ServiceChannel> {
|
||||||
|
return json.parse(
|
||||||
|
ServiceChannel.serializer().list, (SERVICE_CHANNELS_FILE).readText()
|
||||||
|
).toMutableList()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getServerNames(server: Long? = null): List<String> {
|
||||||
if (jda == null)
|
if (jda == null)
|
||||||
return listOf()
|
return listOf()
|
||||||
|
|
||||||
return channels.map {
|
return channels.filter { server == null || (jda!!.getTextChannelById(it.id)?.guild?.idLong == server) }.map {
|
||||||
val channel = jda!!.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!")
|
||||||
@@ -80,9 +127,25 @@ object Channels {
|
|||||||
val role = when (it.mentionedRole) {
|
val role = when (it.mentionedRole) {
|
||||||
null -> ""
|
null -> ""
|
||||||
"everyone" -> " @everyone"
|
"everyone" -> " @everyone"
|
||||||
else -> " @${channel.guild.getRoleById(it.mentionedRole)?.name}"
|
else -> " @${channel.guild.getRoleById(it.mentionedRole ?: "")?.name}"
|
||||||
}
|
}
|
||||||
"**${channel.guild.name}**\n#${channel.name}${role}"
|
val publish = if (it.autoPublish) " (publish)" else ""
|
||||||
|
"**${channel.guild.name}** #${channel.name}${role}${publish}${if (it.message == null) {
|
||||||
|
""
|
||||||
|
} else {
|
||||||
|
"\n*${it.message!!.message}*${if (it.message!!.pushAnnouncement) " (publish)" else ""}"
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getServiceChannelServers(server: Long? = null): List<String> {
|
||||||
|
if (jda == null)
|
||||||
|
return listOf()
|
||||||
|
|
||||||
|
return serviceChannels.filter { server == null || (jda!!.getTextChannelById(it.id)?.guild?.idLong == server) }.map {
|
||||||
|
val channel = jda!!.getTextChannelById(it.id)
|
||||||
|
"**${channel?.guild?.name ?: it.id}** #${channel?.name ?: "(inactive)"}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,17 +153,28 @@ object Channels {
|
|||||||
return jda?.getTextChannelById(id)
|
return jda?.getTextChannelById(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addChannel(id: Long, role: String?) {
|
fun addChannel(id: Long, role: String?): DiscordChannel? {
|
||||||
channels.add(DiscordChannel(id, role))
|
if (channels.find { it.id == id } != null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
val out = DiscordChannel(id, role)
|
||||||
|
channels.add(out)
|
||||||
saveChannels()
|
saveChannels()
|
||||||
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveChannels() {
|
fun saveChannels() {
|
||||||
SERVERS_FILE.writeText(
|
SERVERS_FILE.writeText(
|
||||||
json.stringify(
|
json.stringify(
|
||||||
DiscordChannel.serializer().list,
|
DiscordChannel.serializer().list,
|
||||||
channels
|
channels
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
SERVICE_CHANNELS_FILE.writeText(
|
||||||
|
json.stringify(
|
||||||
|
ServiceChannel.serializer().list,
|
||||||
|
serviceChannels
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,22 +1,43 @@
|
|||||||
package de.wulkanat
|
package de.wulkanat
|
||||||
|
|
||||||
|
import de.wulkanat.extensions.ensureExists
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonConfiguration
|
||||||
|
import kotlinx.serialization.list
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class DiscordChannel(
|
data class DiscordChannel(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
val mentionedRole: String? = null,
|
var mentionedRole: String? = null,
|
||||||
val autoPublish: Boolean = false
|
var autoPublish: Boolean = false,
|
||||||
|
var message: CustomMessage? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ServiceChannel(
|
||||||
|
val id: Long
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CustomMessage(
|
||||||
|
var message: String,
|
||||||
|
var pushAnnouncement: Boolean = false
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class AdminFile(
|
data class AdminFile(
|
||||||
val adminId: Long,
|
val adminId: Long = 12345,
|
||||||
val token: String,
|
val token: String = "12345",
|
||||||
val updateMs: Long
|
val updateMs: Long = 30000,
|
||||||
|
val watchingMessage: String = "for new Blogposts",
|
||||||
|
val offlineMessage: String = "CONNECTION FAILED"
|
||||||
)
|
)
|
||||||
|
|
||||||
val SERVERS_FILE = File("servers.json")
|
val json = Json(JsonConfiguration.Stable)
|
||||||
val TEST_FILE = File("test.json")
|
|
||||||
val ADMIN_FILE = File("admin.json")
|
val SERVERS_FILE = File("servers.json").ensureExists(json.stringify(DiscordChannel.serializer().list, listOf()))
|
||||||
|
val SERVICE_CHANNELS_FILE =
|
||||||
|
File("service_channels.json").ensureExists(json.stringify(ServiceChannel.serializer().list, listOf()))
|
||||||
|
val ADMIN_FILE = File("admin.json").ensureExists(json.stringify(AdminFile.serializer(), AdminFile()))
|
||||||
|
|||||||
15
src/main/kotlin/de/wulkanat/DiscordRpc.kt
Normal file
15
src/main/kotlin/de/wulkanat/DiscordRpc.kt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package de.wulkanat
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.JDA
|
||||||
|
import net.dv8tion.jda.api.entities.Activity
|
||||||
|
|
||||||
|
object DiscordRpc {
|
||||||
|
var jda: JDA? = null
|
||||||
|
|
||||||
|
fun updatePresence(available: Boolean) {
|
||||||
|
jda ?: return
|
||||||
|
|
||||||
|
jda!!.presence.activity = Activity.watching(if (available) Admin.message else Admin.offlineMessage)
|
||||||
|
jda!!.presence.isIdle = !available
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,15 +10,17 @@ fun main() {
|
|||||||
val builder = JDABuilder.createLight(
|
val builder = JDABuilder.createLight(
|
||||||
Admin.token,
|
Admin.token,
|
||||||
GatewayIntent.GUILD_MESSAGES, GatewayIntent.DIRECT_MESSAGES)
|
GatewayIntent.GUILD_MESSAGES, GatewayIntent.DIRECT_MESSAGES)
|
||||||
.setActivity(Activity.watching("for new Blogposts"))
|
.setActivity(Activity.watching(Admin.message))
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
builder.addEventListener(Cli())
|
builder.addEventListener(AdminCli())
|
||||||
builder.addEventListener(ErrorHandler())
|
builder.addEventListener(ErrorHandler())
|
||||||
|
builder.addEventListener(OwnerCli())
|
||||||
builder.awaitReady()
|
builder.awaitReady()
|
||||||
|
|
||||||
Channels.jda = builder
|
Channels.jda = builder
|
||||||
Admin.jda = builder
|
Admin.jda = builder
|
||||||
|
DiscordRpc.jda = builder
|
||||||
Admin.info()
|
Admin.info()
|
||||||
|
|
||||||
Runtime.getRuntime().addShutdownHook(object : Thread() {
|
Runtime.getRuntime().addShutdownHook(object : Thread() {
|
||||||
|
|||||||
215
src/main/kotlin/de/wulkanat/OwnerCli.kt
Normal file
215
src/main/kotlin/de/wulkanat/OwnerCli.kt
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
package de.wulkanat
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.EmbedBuilder
|
||||||
|
import net.dv8tion.jda.api.Permission
|
||||||
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent
|
||||||
|
import net.dv8tion.jda.api.hooks.ListenerAdapter
|
||||||
|
import java.awt.Color
|
||||||
|
|
||||||
|
class OwnerCli : ListenerAdapter() {
|
||||||
|
private val 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/main/kotlin/de/wulkanat/extensions/File.kt
Normal file
11
src/main/kotlin/de/wulkanat/extensions/File.kt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package de.wulkanat.extensions
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
fun File.ensureExists(defaultText: String? = null): File {
|
||||||
|
if (!this.exists()) {
|
||||||
|
this.createNewFile()
|
||||||
|
this.writeText(defaultText ?: return this)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package de.wulkanat.web
|
package de.wulkanat.web
|
||||||
|
|
||||||
import de.wulkanat.Admin
|
import de.wulkanat.Admin
|
||||||
|
import de.wulkanat.DiscordRpc
|
||||||
import de.wulkanat.model.BlogPostPreview
|
import de.wulkanat.model.BlogPostPreview
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
@@ -8,10 +9,9 @@ import java.io.IOException
|
|||||||
object SiteWatcher {
|
object SiteWatcher {
|
||||||
private const val BLOG_INDEX_URL = "https://www.hytale.com/news"
|
private const val BLOG_INDEX_URL = "https://www.hytale.com/news"
|
||||||
var newestBlog: BlogPostPreview? = null
|
var newestBlog: BlogPostPreview? = null
|
||||||
|
private var siteOnline = false
|
||||||
|
|
||||||
fun hasNewBlogPost(): Boolean {
|
fun hasNewBlogPost(): Boolean {
|
||||||
Admin.silent("Updating...")
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val doc = Jsoup.connect(BLOG_INDEX_URL).get()
|
val doc = Jsoup.connect(BLOG_INDEX_URL).get()
|
||||||
val newBlog = BlogPostParser.getFistBlog(doc)
|
val newBlog = BlogPostParser.getFistBlog(doc)
|
||||||
@@ -28,10 +28,17 @@ object SiteWatcher {
|
|||||||
}
|
}
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Admin.error("Connection to Hytale Server failed", e.message ?: e.localizedMessage)
|
Admin.error("Connection to Hytale Server failed", e.message ?: e.localizedMessage)
|
||||||
|
siteOnline = false
|
||||||
|
DiscordRpc.updatePresence(siteOnline)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (siteOnline) {
|
||||||
|
siteOnline = true
|
||||||
|
DiscordRpc.updatePresence(siteOnline)
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user