Compare commits

...

49 commits

Author SHA1 Message Date
c738a37948
"fix": this seems to do nothing 2024-11-14 18:43:57 +07:00
373736feed
feat: add *info (no arguments) 2024-11-14 16:41:33 +07:00
c0909d54aa
style fix: i forgor the color change 2024-11-14 16:18:17 +07:00
159cb8ce11
refactor: make cloop remove return command name 2024-11-14 16:11:16 +07:00
627b18ebf9
refactor: make whitelist remove by index like in the usage 2024-11-14 16:11:00 +07:00
66dc3b97ec
refactor: refactor PersistentDataUtilities, hopefully it will work ok
i do have a backup so this should be fine if it fails somehow
2024-11-12 20:04:22 +07:00
f322e2dd14
fix: more fix in Main 2024-11-12 19:28:09 +07:00
5e9a1f0917
fix: stopping stuff in Main and IRCPlugin 2024-11-12 16:43:45 +07:00
4ba78b843b
refactor,fix: music stuff, and add music locking (servereval only) 2024-11-12 16:40:46 +07:00
357559ae6e
fix: ignore exceptions in irc queue tick 2024-11-12 16:36:55 +07:00
7363252660
fix: fix loopPosition in Song 2024-11-12 16:09:00 +07:00
4b2b1e9e1a
fix: cool 2024-11-11 20:34:10 +07:00
28012c1194
fix: remove null uuid for extras chat format, which breaks a lot of commands 2024-11-11 17:58:51 +07:00
7b78ce7d06
fix: prevent whitelist from kicking the bot itself 2024-11-10 19:25:42 +07:00
11f478487d
fix: throw CommandException itself in GrepLogPlugin 2024-11-10 12:10:28 +07:00
4f8d5bfff5
fix: makeNewLogFile() in FileLoggerUtilities appending to the file instead of deleting the existing one 2024-11-10 08:31:43 +07:00
3811790c93
feat: *console printdisconnectedcause <true|false>
very useful for debugging
2024-11-07 17:52:12 +07:00
597a694727
fix: (maybe) ACTUALLY fix file logging (for the 69th time) 2024-11-05 16:44:56 +07:00
f561a9c810
refactor (eval): getBotUsername -> getBotInfo & make core() tracked in eval 2024-11-04 19:23:31 +07:00
4b16f12623
fix: mabe 2024-11-04 19:06:43 +07:00
783a7a937e
refactor: improve AuthPlugin by at least a bit 2024-11-04 16:57:28 +07:00
cb86896223
"fix": doesn't work 2024-11-03 19:34:57 +07:00
e62de655ba
fix: the commit before this 2024-11-02 19:30:24 +07:00
0ddf042311
feat: automatically make the bot go down if currentY > maxY 2024-11-02 19:27:08 +07:00
4764a8947e
refactor: make maps in PositionPlugin public for access with servereval 2024-11-02 18:31:28 +07:00
b3615770dc
fix: fix most OOBs, and also fix maxY in WorldPlugin 2024-11-02 18:18:47 +07:00
3ad8b11494
fix: finally fix voicechat 2024-11-02 17:37:09 +07:00
b118d50249
feat: getLatestChatMessage eval function 2024-11-02 17:12:23 +07:00
9e22cdfea5
feat: getBotUsername eval function 2024-11-02 15:29:47 +07:00
c655b5d0cd
chore (default_config.yml): some modifications to the comment at ownerName and backup 2024-11-02 14:37:06 +07:00
71ef35598c
style: use DecimalFormatter on greplog
from now on i am going to have the types on commits because why not
2024-11-02 14:29:02 +07:00
c707309958 Merge branch 'amy' 2024-11-02 12:59:56 +07:00
amy
bf52424792
refactor: fix buildscripts 2024-11-01 11:03:45 -03:00
b1dc8dfc7c Add fallback on translate (ComponentUtilities) 2024-10-30 19:02:11 +07:00
0d73ddd791 Fix newline on SeenCommand 2024-10-30 16:33:29 +07:00
3740a9b45f HOTFIX FIX 2024-10-29 19:28:15 +07:00
2de709c127 HOTFIX EMERGENCY https://files.chipmunk.land/pi0mz7cx.png 2024-10-29 19:22:36 +07:00
feed688a89 Add FilteredPlayer options info into FilterCommand's list 2024-10-29 16:45:25 +07:00
8e188d9ec7 Refactor FilterPlugin's getPlayer, hopefully it works the same 2024-10-28 18:19:35 +07:00
43d12f2471 Escape . in Discord to fix the invite leaking 2024-10-28 16:53:47 +07:00
bff3c2f58d Fix the "Fix the fix that doesn't fix.". 2024-10-27 11:29:55 +07:00
4142875c06 Fix the fix that doesn't fix. 2024-10-26 20:35:46 +07:00
32c3801acf Fix SeenCommand when the same player is online in multiple servers 2024-10-26 18:33:41 +07:00
9b214c7111 Correct the message 2024-10-26 18:18:16 +07:00
743072d8e3 FindAltsCommand 2024-10-26 18:11:28 +07:00
a4f7b0e6a8 forgor to change the thingy to use CommandException 2024-10-26 17:10:36 +07:00
d0f0911f8c Change SeenCommand invalid entry message 2024-10-26 17:08:37 +07:00
ef5ec8dc27 fix 2024-10-26 17:06:43 +07:00
a948ef84e2 unused (for now) 2024-10-26 09:23:49 +07:00
60 changed files with 693 additions and 640 deletions

59
.gitignore vendored
View file

@ -1,55 +1,16 @@
.gradle
**/build/
!src/**/build/
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/dictionaries
.idea/**/shelf
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
.gradle
build/
run/
.idea/misc.xml
gradle
# Ignore Gradle GUI config
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
# Avoid ignore Gradle wrappper properties
!gradle-wrapper.properties
# Cache of project
.gradletasknamecache
# Eclipse Gradle plugin generated files
# Eclipse Core
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath
# IntelliJ IDEA
.idea/
*.iml
*.ipr
*.iws
# Exploits plugin
/src/main/java/land/chipmunk/chayapak/chomens_bot/plugins/ExploitsPlugin.java
src/main/java/me/chayapak1/chomens_bot/plugins/ExploitsPlugin.java
# Testing plugins
/src/main/java/land/chipmunk/chayapak/chomens_bot/plugins/testing
/.idea/modules/
/.idea/modules.xml
src/main/java/me/chayapak1/chomens_bot/plugins/testing

3
.idea/.gitignore vendored
View file

@ -1,3 +0,0 @@
# Default ignored files
/shelf/
/.idea/workspace.xml

View file

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View file

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>ADVENTURE</platformType>
</autoDetectTypes>
</configuration>
</facet>
</component>
</module>

View file

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
</annotationProcessing>
<bytecodeTargetLevel target="17" />
</component>
</project>

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="PROJECT_FILES" />
<option name="description" value="" />
</component>
</project>

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

View file

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="minecraft-libraries" />
<option name="name" value="Minecraft Libraries" />
<option name="url" value="https://libraries.minecraft.net" />
</remote-repository>
<remote-repository>
<option name="id" value="dv8tion" />
<option name="name" value="m2-dv8tion" />
<option name="url" value="https://m2.dv8tion.net/releases" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="maven3" />
<option name="name" value="maven3" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven4" />
<option name="name" value="maven4" />
<option name="url" value="https://maven.maxhenkel.de/repository/public" />
</remote-repository>
<remote-repository>
<option name="id" value="opencollab" />
<option name="name" value="opencollab" />
<option name="url" value="https://repo.opencollab.dev/maven-snapshots/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenLocal" />
<option name="name" value="MavenLocal" />
<option name="url" value="file:$MAVEN_REPOSITORY$/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="opencollab" />
<option name="name" value="opencollab" />
<option name="url" value="https://repo.opencollab.dev/maven-releases/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="https://repo.opencollab.dev/main/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="https://jitpack.io" />
</remote-repository>
</component>
</project>

View file

@ -1,124 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View file

@ -22,6 +22,6 @@ public class ExploitsPlugin {
}
```
Then at the root of the project run `./gradlew shadowJar` for Linux or `gradlew.bat shadowJar` for Windows
Then at the root of the project run `./gradlew build` to build.
The .jar file will be at `build/libs`, to run the bot do `java -jar chomens_bot-rolling-all.jar`

View file

@ -1,11 +1,6 @@
/*
* This file was generated by the Gradle 'init' task.
*/
plugins {
id 'java'
id 'java-library'
id 'maven-publish'
id 'application'
id 'com.github.johnrengelman.shadow' version '8.1.1'
}
@ -16,7 +11,6 @@ java.sourceCompatibility = JavaVersion.VERSION_17
repositories {
mavenLocal()
mavenCentral()
maven {
@ -64,10 +58,8 @@ dependencies {
implementation 'org.concentus:Concentus:1.0-SNAPSHOT'
}
jar {
manifest {
attributes 'Main-Class': 'me.chayapak1.chomens_bot.Main'
}
application {
mainClass = 'me.chayapak1.chomens_bot.Main'
}
tasks.withType(JavaCompile).configureEach {

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View file

@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

5
gradlew vendored
View file

@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@ -84,7 +86,8 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum

186
gradlew.bat vendored
View file

@ -1,92 +1,94 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View file

@ -1,5 +1 @@
/*
* This file was generated by the Gradle 'init' task.
*/
rootProject.name = 'chomens_bot'

View file

@ -41,6 +41,8 @@ public class Bot {
public Session session;
public boolean printDisconnectedCause = false;
public boolean loggedIn = false;
public final ExecutorService executorService = Main.executorService;
@ -251,6 +253,8 @@ public class Bot {
final Throwable cause = disconnectedEvent.getCause();
if (printDisconnectedCause && cause != null) cause.printStackTrace();
// lazy fix #69420
if (cause instanceof OutOfMemoryError) System.exit(1);

View file

@ -43,6 +43,8 @@ public class Main {
private static boolean alreadyStarted = false;
private static boolean stopping = false;
private static final List<Thread> alreadyAddedThreads = new ArrayList<>();
private static JDA jda = null;
@ -187,6 +189,10 @@ public class Main {
// most of these are stolen from HBot
public static void stop () {
if (stopping) return;
stopping = true;
executor.shutdown();
PersistentDataUtilities.stop();
@ -209,17 +215,17 @@ public class Main {
final boolean discordEnabled = config.discord.enabled;
for (Bot bot : copiedList) {
if (discordEnabled) {
final String channelId = bot.discord.servers.get(bot.host + ":" + bot.port);
try {
if (discordEnabled) {
final String channelId = bot.discord.servers.get(bot.host + ":" + bot.port);
bot.discord.sendMessageInstantly("Stopping..", channelId);
}
bot.discord.sendMessageInstantly("Stopping..", channelId);
}
if (ircEnabled) {
bot.irc.quit("Stopping..");
}
if (ircEnabled) bot.irc.quit("Stopping..");
bot.stop();
bot.stop();
} catch (Exception ignored) {}
}
if (jda != null) jda.shutdown();

View file

@ -1,5 +1,6 @@
package me.chayapak1.chomens_bot.chatParsers;
import me.chayapak1.chomens_bot.util.UUIDUtilities;
import org.geysermc.mcprotocollib.auth.GameProfile;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
import me.chayapak1.chomens_bot.Bot;
@ -38,7 +39,7 @@ public class CreayunChatParser implements ChatParser {
final String contents = matcher.group(2);
PlayerEntry sender = bot.players.getEntry(displayName);
if (sender == null) sender = new PlayerEntry(new GameProfile(new UUID(0L, 0L), displayName), GameMode.SURVIVAL, 0, Component.text(displayName), 0L, null, new byte[0], true);
if (sender == null) sender = new PlayerEntry(new GameProfile(UUIDUtilities.getOfflineUUID(displayName), displayName), GameMode.SURVIVAL, 0, Component.text(displayName), 0L, null, new byte[0], true);
return new PlayerMessage(sender, Component.text(displayName), Component.text(contents));
}

View file

@ -1,5 +1,7 @@
package me.chayapak1.chomens_bot.chatParsers;
import me.chayapak1.chomens_bot.util.ComponentUtilities;
import me.chayapak1.chomens_bot.util.UUIDUtilities;
import org.geysermc.mcprotocollib.auth.GameProfile;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
import me.chayapak1.chomens_bot.Bot;
@ -43,9 +45,12 @@ public class KaboomChatParser implements ChatParser {
return null;
}
// final String stringifiedDisplayName = ComponentUtilities.stringify(displayName);
PlayerEntry sender = bot.players.getEntry(Component.empty().append(prefix).append(displayName));
if (sender == null) sender = bot.players.getEntry(prefix.append(displayName)); // old
if (sender == null) sender = new PlayerEntry(new GameProfile(new UUID(0L, 0L), null), GameMode.SURVIVAL, 0, displayName, 0L, null, new byte[0], true); // new and currently using
// if (sender == null) sender = new PlayerEntry(new GameProfile(UUIDUtilities.getOfflineUUID(stringifiedDisplayName), stringifiedDisplayName), GameMode.SURVIVAL, 0, displayName, 0L, null, new byte[0], true); // new and currently using
if (sender == null) return null;
return new PlayerMessage(sender, displayName, contents);
}

View file

@ -52,11 +52,12 @@ public class CloopCommand extends Command {
try {
final int index = context.getInteger(true);
bot.cloop.remove(index);
final CommandLoop cloop = bot.cloop.remove(index);
return Component.translatable(
"Removed cloop %s",
Component.text(index).color(ColorUtilities.getColorByString(bot.config.colorPalette.number))
Component.text(cloop.command()).color(ColorUtilities.getColorByString(bot.config.colorPalette.string))
).color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor));
} catch (IndexOutOfBoundsException | IllegalArgumentException | NullPointerException ignored) {
throw new CommandException(Component.text("Invalid index"));
@ -96,9 +97,7 @@ public class CloopCommand extends Command {
Component.join(JoinConfiguration.newlines(), cloopsComponent)
);
}
default -> {
throw new CommandException(Component.text("Invalid action"));
}
default -> throw new CommandException(Component.text("Invalid action"));
}
}
}

View file

@ -19,7 +19,8 @@ public class ConsoleCommand extends Command {
"Controls stuff about console",
new String[] {
"server <server>",
"logtoconsole <true|false>"
"logtoconsole <true|false>",
"printdisconnectedreason <true|false>"
},
new String[] {},
TrustLevel.OWNER,
@ -56,7 +57,8 @@ public class ConsoleCommand extends Command {
// servers.find(server => server.toLowerCase().includes(args.join(' '))) in js i guess
eachBot.console.consoleServer = servers.stream()
.filter(eachServer -> eachServer.toLowerCase().contains(server))
.toArray(String[]::new)[0];
.findFirst()
.orElse("all");
context.sendOutput(Component.text("Set the console server to " + bot.console.consoleServer).color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor)));
} catch (ArrayIndexOutOfBoundsException e) {
@ -76,6 +78,18 @@ public class ConsoleCommand extends Command {
bool ? Component.text("enabled").color(NamedTextColor.GREEN) : Component.text("disabled").color(NamedTextColor.RED)
).color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor));
}
case "printdisconnectedreason" -> {
context.checkOverloadArgs(2);
final boolean bool = context.getBoolean(true);
bot.printDisconnectedCause = bool;
return Component.translatable(
"Printing the disconnected cause is now %s",
bool ? Component.text("enabled").color(NamedTextColor.GREEN) : Component.text("disabled").color(NamedTextColor.RED)
).color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor));
}
}
return null;

View file

@ -101,11 +101,25 @@ public class FilterCommand extends Command {
for (JsonElement playerElement : FilterPlugin.filteredPlayers) {
final FilteredPlayer player = gson.fromJson(playerElement, FilteredPlayer.class);
Component options = Component.empty().color(NamedTextColor.DARK_GRAY);
if (player.ignoreCase || player.regex) {
final List<Component> args = new ArrayList<>();
if (player.ignoreCase) args.add(Component.text("ignore case"));
if (player.regex) args.add(Component.text("regex"));
options = options.append(Component.text("("));
options = options.append(Component.join(JoinConfiguration.commas(true), args).color(ColorUtilities.getColorByString(bot.config.colorPalette.string)));
options = options.append(Component.text(")"));
}
filtersComponents.add(
Component.translatable(
"%s %s",
"%s %s %s",
Component.text(index).color(ColorUtilities.getColorByString(bot.config.colorPalette.number)),
Component.text(player.playerName).color(ColorUtilities.getColorByString(bot.config.colorPalette.username))
Component.text(player.playerName).color(ColorUtilities.getColorByString(bot.config.colorPalette.username)),
options
).color(NamedTextColor.DARK_GRAY)
);

View file

@ -0,0 +1,95 @@
package me.chayapak1.chomens_bot.commands;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import me.chayapak1.chomens_bot.Bot;
import me.chayapak1.chomens_bot.command.Command;
import me.chayapak1.chomens_bot.command.CommandContext;
import me.chayapak1.chomens_bot.command.CommandException;
import me.chayapak1.chomens_bot.command.TrustLevel;
import me.chayapak1.chomens_bot.data.PlayerEntry;
import me.chayapak1.chomens_bot.plugins.PlayersPersistentDataPlugin;
import me.chayapak1.chomens_bot.util.ColorUtilities;
import net.kyori.adventure.text.Component;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
public class FindAltsCommand extends Command {
public FindAltsCommand() {
super(
"findalts",
"Finds players with the same IP address",
new String[] { "<player>", "<ip>" },
new String[] { "alts", "sameip" },
TrustLevel.PUBLIC,
false
);
}
@Override
public Component execute(CommandContext context) throws Exception {
final Bot bot = context.bot;
boolean argumentIsIP = true;
String targetIP;
final String player = context.getString(true, true);
final PlayerEntry playerEntry = bot.players.getEntry(player);
if (playerEntry == null) targetIP = player;
else {
argumentIsIP = false;
final CompletableFuture<String> future = bot.players.getPlayerIP(playerEntry);
targetIP = future.get(5, TimeUnit.SECONDS);
}
if (targetIP == null) throw new CommandException(Component.text("Could not find player's IP address"));
final Stream<String> matches = PlayersPersistentDataPlugin.playersObject.deepCopy().entrySet() // is calling deepCopy necessary?
.stream()
.filter(
entry -> {
final JsonObject ipsObject = entry
.getValue().getAsJsonObject().getAsJsonObject("ips");
if (ipsObject == null) return false;
final JsonElement currentServerIP = ipsObject.get(bot.host + ":" + bot.port);
if (currentServerIP == null) return false;
return currentServerIP.getAsString().equals(targetIP);
}
)
.map(Map.Entry::getKey);
Component component = Component
.translatable("Possible alts for the %s %s:")
.color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor))
.arguments(
Component.text(argumentIsIP ? "IP" : "player"),
Component.text(player).color(ColorUtilities.getColorByString(bot.config.colorPalette.username))
)
.appendNewline();
int i = 0;
for (String name : matches.toList()) {
component = component
.append(
Component
.text(name)
.color((i++ & 1) == 0 ? ColorUtilities.getColorByString(bot.config.colorPalette.primary) : ColorUtilities.getColorByString(bot.config.colorPalette.secondary))
)
.appendSpace();
}
return component;
}
}

View file

@ -10,7 +10,9 @@ import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import java.io.IOException;
import java.io.RandomAccessFile;
@ -26,11 +28,14 @@ import java.util.Optional;
import java.util.concurrent.TimeUnit;
public class InfoCommand extends Command {
public static final String ORIGINAL_REPOSITORY_URL = "https://code.chipmunk.land/ChomeNS/chomens-bot-java";
public InfoCommand () {
super(
"info",
"Shows an info about various things",
new String[] {
"",
"<creator>",
"<discord>",
"<server>",
@ -49,7 +54,7 @@ public class InfoCommand extends Command {
final Bot bot = context.bot;
final String action = context.getString(false, true, true);
final String action = context.getString(false, false, true);
switch (action) {
case "creator" -> {
@ -199,7 +204,31 @@ public class InfoCommand extends Command {
).color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor));
}
default -> {
throw new CommandException(Component.text("Invalid action"));
return Component.empty()
.color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor))
.append(Component.text("ChomeNS Bot").color(NamedTextColor.YELLOW))
.append(Component.space())
.append(
Component
.translatable(
"is an open-source utility bot and a moderation bot made for " +
"the %s Minecraft server (and its clones) " +
"but also works on vanilla Minecraft servers. " +
"It was originally made for fun but " +
"I got addicted and made it a full blown bot."
)
.arguments(Component.text("Kaboom").style(Style.style().color(NamedTextColor.GRAY).decorate(TextDecoration.BOLD)))
)
.append(Component.newline())
.append(Component.text("Original repository: "))
.append(
Component
.text(ORIGINAL_REPOSITORY_URL)
.color(ColorUtilities.getColorByString(bot.config.colorPalette.string))
.clickEvent(
ClickEvent.openUrl(ORIGINAL_REPOSITORY_URL)
)
);
}
}
}

View file

@ -12,7 +12,6 @@ import me.chayapak1.chomens_bot.song.Loop;
import me.chayapak1.chomens_bot.song.Note;
import me.chayapak1.chomens_bot.song.Song;
import me.chayapak1.chomens_bot.util.*;
import me.chayapak1.chomens_bot.util.*;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.JoinConfiguration;
import net.kyori.adventure.text.TranslatableComponent;
@ -36,8 +35,6 @@ import static me.chayapak1.chomens_bot.util.StringUtilities.isNotNullAndNotBlank
public class MusicCommand extends Command {
private Path root;
private int ratelimit = 0;
public MusicCommand () {
super(
"music",
@ -63,15 +60,11 @@ public class MusicCommand extends Command {
TrustLevel.PUBLIC,
false
);
Main.executor.scheduleAtFixedRate(() -> ratelimit = 0, 0, 5, TimeUnit.SECONDS);
}
@Override
public Component execute(CommandContext context) throws CommandException {
ratelimit++;
if (ratelimit > 10) return null;
if (context.bot.music.locked) throw new CommandException(Component.text("Managing music is currently locked"));
final String action = context.getString(false, true, true);
@ -264,7 +257,7 @@ public class MusicCommand extends Command {
final CompletableFuture<Component> future = bot.core.runTracked(
"minecraft:data get entity " +
UUIDUtilities.selector(context.sender.profile.getId()) +
" SelectedItem.tag.SongItemData.SongData"
" SelectedItem.components.minecraft:custom_data.SongItemData.SongData"
);
if (future == null) {
@ -281,7 +274,7 @@ public class MusicCommand extends Command {
.key()
.equals("arguments.nbtpath.nothing_found")
) {
context.sendOutput(Component.text("Player has no SongItemData -> SongData NBT tag in the selected item").color(NamedTextColor.RED));
context.sendOutput(Component.text("Player has no SongItemData -> SongData NBT tag in their selected item's minecraft:custom_data").color(NamedTextColor.RED));
return output;
}

View file

@ -10,12 +10,16 @@ import me.chayapak1.chomens_bot.command.TrustLevel;
import me.chayapak1.chomens_bot.plugins.PlayersPersistentDataPlugin;
import me.chayapak1.chomens_bot.util.ColorUtilities;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.JoinConfiguration;
import net.kyori.adventure.text.format.NamedTextColor;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
public class SeenCommand extends Command {
public SeenCommand () {
super(
@ -34,25 +38,37 @@ public class SeenCommand extends Command {
final String player = context.getString(true, true);
boolean online = false;
final List<Component> onlineComponents = new ArrayList<>();
for (Bot eachBot : bot.bots) {
if (eachBot.players.getEntry(player) != null) return Component.empty()
.append(Component.text(player))
.append(Component.text(" is currently online on "))
.append(Component.text(eachBot.host + ":" + eachBot.port))
.color(NamedTextColor.RED);
if (eachBot.players.getEntry(player) != null) {
online = true;
onlineComponents.add(
Component.empty()
.append(Component.text(player))
.append(Component.text(" is currently online on "))
.append(Component.text(eachBot.host + ":" + eachBot.port))
.color(NamedTextColor.RED)
);
}
}
if (online) return Component.join(JoinConfiguration.newlines(), onlineComponents);
final JsonElement playerElement = PlayersPersistentDataPlugin.playersObject.get(player);
if (playerElement == null) return Component.translatable(
if (playerElement == null) throw new CommandException(Component.translatable(
"%s was never seen",
Component.text(player)
).color(NamedTextColor.RED);
));
final JsonObject lastSeen = playerElement.getAsJsonObject().get("lastSeen").getAsJsonObject();
final JsonElement time = lastSeen.get("time");
if (time == null) throw new CommandException(Component.text("time is null.. (possible invalid entry)"));
if (time == null) throw new CommandException(Component.text("This player does not have the `lastSeen.time` entry in the database for some reason."));
final DateTime dateTime = new DateTime(time.getAsLong(), DateTimeZone.UTC);

View file

@ -24,7 +24,11 @@ public class ValidateCommand extends Command {
public Component execute(CommandContext context) throws CommandException {
final Bot bot = context.bot;
final String hash = context.fullArgs[0];
final String[] fullArgs = context.fullArgs;
if (fullArgs.length == 0) return null;
final String hash = fullArgs[0];
if (bot.hashing.isCorrectHash(hash, context.userInputCommandName, context.sender)) return Component.text("Valid hash").color(NamedTextColor.GREEN);
else if (bot.hashing.isCorrectOwnerHash(hash, context.userInputCommandName, context.sender)) return Component.text("Valid OwnerHash").color(NamedTextColor.GREEN);

View file

@ -57,18 +57,18 @@ public class WhitelistCommand extends Command {
).color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor));
}
case "remove" -> {
final String player = context.getString(true, true);
try {
final int index = context.getInteger(true);
if (!bot.whitelist.list.contains(player)) throw new CommandException(Component.text("Player doesn't exist in the list"));
final String player = bot.whitelist.remove(index);
if (player.equals(bot.profile.getName())) throw new CommandException(Component.text("Cannot remove the bot"));
bot.whitelist.remove(player);
return Component.translatable(
"Removed %s from the whitelist",
Component.text(player).color(ColorUtilities.getColorByString(bot.config.colorPalette.username))
).color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor));
return Component.translatable(
"Removed %s from the whitelist",
Component.text(player).color(ColorUtilities.getColorByString(bot.config.colorPalette.username))
).color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor));
} catch (IndexOutOfBoundsException | IllegalArgumentException | NullPointerException ignored) {
throw new CommandException(Component.text("Invalid index"));
}
}
case "clear" -> {
context.checkOverloadArgs(1);

View file

@ -15,7 +15,7 @@ public class EvalFunction {
this.bot = bot;
}
public Output execute (Object ...args) { return null; }
public Output execute (Object ...args) throws Exception { return null; }
public static class Output {
public final String message;

View file

@ -10,6 +10,8 @@ public class ChatFunction extends EvalFunction {
@Override
public Output execute(Object... args) {
if (args.length == 0) return null;
final String message = (String) args[0];
bot.chat.send(message);

View file

@ -2,6 +2,11 @@ package me.chayapak1.chomens_bot.evalFunctions;
import me.chayapak1.chomens_bot.Bot;
import me.chayapak1.chomens_bot.data.eval.EvalFunction;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class CoreFunction extends EvalFunction {
public CoreFunction (Bot bot) {
@ -9,11 +14,13 @@ public class CoreFunction extends EvalFunction {
}
@Override
public Output execute(Object... args) {
public Output execute(Object... args) throws Exception {
if (args.length == 0) return null;
final String command = (String) args[0];
bot.core.run(command);
final CompletableFuture<Component> future = bot.core.runTracked(command);
return null;
return new Output(GsonComponentSerializer.gson().serialize(future.get(1, TimeUnit.SECONDS)), true);
}
}

View file

@ -10,6 +10,8 @@ public class CorePlaceBlockFunction extends EvalFunction {
@Override
public Output execute(Object... args) {
if (args.length == 0) return null;
final String command = (String) args[0];
bot.core.runPlaceBlock(command);

View file

@ -0,0 +1,23 @@
package me.chayapak1.chomens_bot.evalFunctions;
import com.google.gson.JsonObject;
import me.chayapak1.chomens_bot.Bot;
import me.chayapak1.chomens_bot.data.eval.EvalFunction;
public class GetBotInfoFunction extends EvalFunction {
public GetBotInfoFunction(Bot bot) {
super("getBotInfo", bot);
}
@Override
public Output execute(Object... args) {
final JsonObject object = new JsonObject();
object.addProperty("usernane", bot.username);
object.addProperty("host", bot.host);
object.addProperty("port", bot.port);
object.addProperty("loggedIn", bot.loggedIn);
return new Output(object.toString(), true);
}
}

View file

@ -0,0 +1,33 @@
package me.chayapak1.chomens_bot.evalFunctions;
import me.chayapak1.chomens_bot.Bot;
import me.chayapak1.chomens_bot.data.eval.EvalFunction;
import me.chayapak1.chomens_bot.plugins.ChatPlugin;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
public class GetLatestChatMessageFunction extends EvalFunction {
private String latestMessage = "";
public GetLatestChatMessageFunction (Bot bot) {
super("getLatestChatMessage", bot);
bot.chat.addListener(new ChatPlugin.Listener() {
@Override
public boolean systemMessageReceived(Component component, String string, String ansi) {
messageReceived(component);
return true;
}
});
}
private void messageReceived (Component component) {
latestMessage = GsonComponentSerializer.gson().serialize(component);
}
@Override
public Output execute(Object... args) {
return new Output(latestMessage, true);
}
}

View file

@ -23,6 +23,8 @@ public class AuthPlugin extends PlayersPlugin.Listener {
private boolean hasCorrectHash;
private PlayerEntry targetPlayer;
private boolean started = false;
public AuthPlugin (Bot bot) {
@ -39,7 +41,7 @@ public class AuthPlugin extends PlayersPlugin.Listener {
return AuthPlugin.this.systemMessageReceived(component);
}
});
bot.executor.scheduleAtFixedRate(this::check, 0, 1, TimeUnit.SECONDS);
bot.executor.scheduleAtFixedRate(this::check, 1, 3, TimeUnit.SECONDS);
}
private String getSanitizedOwnerName() {
@ -50,6 +52,8 @@ public class AuthPlugin extends PlayersPlugin.Listener {
public void playerJoined(PlayerEntry target) {
if (!target.profile.getName().equals(getSanitizedOwnerName()) || !bot.options.useCore) return;
targetPlayer = target;
bot.executor.schedule(() -> sendVerificationMessage(target, true), 2, TimeUnit.SECONDS);
}
@ -110,6 +114,8 @@ public class AuthPlugin extends PlayersPlugin.Listener {
hasCorrectHash = inputHash.equals(hash);
if (hasCorrectHash && targetPlayer != null) bot.chat.tellraw(Component.text("You have been verified").color(NamedTextColor.GREEN), targetPlayer.profile.getId());
return false;
} catch (Exception ignored) {}
@ -117,7 +123,7 @@ public class AuthPlugin extends PlayersPlugin.Listener {
}
private void check() {
if (!started) return;
if (!started || !bot.config.ownerAuthentication.enabled) return;
final PlayerEntry entry = bot.players.getEntry(getSanitizedOwnerName());

View file

@ -26,14 +26,14 @@ public class CloopPlugin {
loopTasks.add(bot.executor.scheduleAtFixedRate(loopTask, 0, interval, TimeUnit.MILLISECONDS));
}
public void remove (int index) {
public CommandLoop remove (int index) {
ScheduledFuture<?> loopTask = loopTasks.remove(index);
if (loopTask != null) {
loopTask.cancel(true);
}
loops.remove(index);
return loops.remove(index);
}
public void clear () {

View file

@ -58,6 +58,7 @@ public class CommandHandlerPlugin {
registerCommand(new IPFilterCommand());
registerCommand(new StopCommand());
registerCommand(new GrepLogCommand());
registerCommand(new FindAltsCommand());
}
public boolean disabled = false;
@ -93,6 +94,8 @@ public class CommandHandlerPlugin {
final String[] splitInput = input.trim().split("\\s+");
if (splitInput.length == 0) return null;
final String commandName = splitInput[0];
final Command command = findCommand(commands, commandName);

View file

@ -374,6 +374,8 @@ public class CorePlugin extends PositionPlugin.Listener {
@Override
public void positionChange (Vector3i position) {
if (bot.position.isGoingDownFromHeightLimit) return;
from = Vector3i.from(
(int) (fromSize.getX() + Math.floor((double) bot.position.position.getX() / 16) * 16),
MathUtilities.clamp(fromSize.getY(), bot.world.minY, bot.world.maxY),

View file

@ -389,7 +389,7 @@ public class DiscordPlugin {
String message;
synchronized (logMessages) {
StringBuilder logMessage = logMessages.get(channelId);
message = logMessage.toString();
message = logMessage.toString().replace(".", "\u200b.\u200b"); // the ZWSP fixes discord.gg showing invite
final int maxLength = 2_000 - ("""
```ansi

View file

@ -7,10 +7,7 @@ import io.socket.client.Socket;
import me.chayapak1.chomens_bot.Bot;
import me.chayapak1.chomens_bot.data.eval.EvalFunction;
import me.chayapak1.chomens_bot.data.eval.EvalOutput;
import me.chayapak1.chomens_bot.evalFunctions.ChatFunction;
import me.chayapak1.chomens_bot.evalFunctions.CoreFunction;
import me.chayapak1.chomens_bot.evalFunctions.CorePlaceBlockFunction;
import me.chayapak1.chomens_bot.evalFunctions.GetPlayerListFunction;
import me.chayapak1.chomens_bot.evalFunctions.*;
import java.util.ArrayList;
import java.util.HashMap;
@ -38,6 +35,8 @@ public class EvalPlugin {
functions.add(new CorePlaceBlockFunction(bot));
functions.add(new ChatFunction(bot));
functions.add(new GetPlayerListFunction(bot));
functions.add(new GetBotInfoFunction(bot));
functions.add(new GetLatestChatMessageFunction(bot));
try {
socket = IO.socket(bot.config.eval.address);
@ -61,16 +60,20 @@ public class EvalPlugin {
socket.on(Socket.EVENT_CONNECT_ERROR, (args) -> connected = false);
for (EvalFunction function : functions) {
socket.on(BRIDGE_PREFIX + function.name, args -> {
final EvalFunction.Output output = function.execute(args);
socket.on(BRIDGE_PREFIX + function.name, args -> new Thread(() -> {
try {
final EvalFunction.Output output = function.execute(args);
if (output == null) return;
if (output == null) return;
socket.emit("functionOutput:" + function.name, output.message, output.parseJSON);
});
socket.emit("functionOutput:" + function.name, output.message, output.parseJSON);
} catch (Exception ignored) {}
}).start());
}
socket.on("codeOutput", (args) -> {
if (args.length < 3) return;
final int id = (int) args[0];
final boolean isError = (boolean) args[1];
final String output = (String) args[2];

View file

@ -55,46 +55,43 @@ public class FilterPlugin extends PlayersPlugin.Listener {
}
private FilteredPlayer getPlayer (String name) {
// mess
// also regex and ignorecase codes from greplog plugin
FilteredPlayer filteredPlayer = null;
for (JsonElement filteredPlayerElement : filteredPlayers) {
final FilteredPlayer _filteredPlayer = gson.fromJson(filteredPlayerElement, FilteredPlayer.class);
final FilteredPlayer filteredPlayer = gson.fromJson(filteredPlayerElement, FilteredPlayer.class);
if (_filteredPlayer.regex) {
Pattern pattern = null;
if (_filteredPlayer.ignoreCase) {
pattern = Pattern.compile(_filteredPlayer.playerName, Pattern.CASE_INSENSITIVE);
} else {
try {
pattern = Pattern.compile(_filteredPlayer.playerName);
} catch (Exception e) {
bot.chat.tellraw(Component.text(e.toString()).color(NamedTextColor.RED));
}
}
if (pattern == null) break;
if (pattern.matcher(name).find()) {
filteredPlayer = _filteredPlayer;
break;
}
} else {
if (_filteredPlayer.ignoreCase) {
if (_filteredPlayer.playerName.toLowerCase().equals(name)) {
filteredPlayer = _filteredPlayer;
break;
}
} else {
if (_filteredPlayer.playerName.equals(name)) {
filteredPlayer = _filteredPlayer;
break;
}
}
if (matchesPlayer(name, filteredPlayer)) {
return filteredPlayer;
}
}
return filteredPlayer;
return null;
}
private boolean matchesPlayer (String name, FilteredPlayer player) {
if (player.regex) {
final Pattern pattern = compilePattern(player);
return pattern != null && pattern.matcher(name).find();
} else {
return compareNames(name, player);
}
}
private Pattern compilePattern (FilteredPlayer player) {
try {
final int flags = player.ignoreCase ? Pattern.CASE_INSENSITIVE : 0;
return Pattern.compile(player.playerName, flags);
} catch (Exception e) {
bot.chat.tellraw(Component.text(e.toString()).color(NamedTextColor.RED));
return null;
}
}
private boolean compareNames (String name, FilteredPlayer player) {
final String playerName = player.ignoreCase ? player.playerName.toLowerCase() : player.playerName;
final String targetName = player.ignoreCase ? name.toLowerCase() : name;
return playerName.equals(targetName);
}
@Override

View file

@ -18,6 +18,7 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.NotDirectoryException;
import java.nio.file.Path;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.regex.Pattern;
@ -104,10 +105,12 @@ public class GrepLogPlugin {
.queue(message -> {
final String url = message.getAttachments().get(0).getUrl();
final DecimalFormat formatter = new DecimalFormat("#,###");
final Component component = Component.translatable("Found %s matches for %s. You can see the results by clicking %s or in the Discord server.")
.color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor))
.arguments(
Component.text(matches).color(ColorUtilities.getColorByString(bot.config.colorPalette.number)),
Component.text(formatter.format(matches)).color(ColorUtilities.getColorByString(bot.config.colorPalette.number)),
Component.text(input).color(ColorUtilities.getColorByString(bot.config.colorPalette.string)),
Component
.text("here")
@ -126,6 +129,9 @@ public class GrepLogPlugin {
context.sendOutput(component);
});
} catch (CommandException e) {
running = false;
throw e;
} catch (FileNotFoundException e) {
running = false;
throw new CommandException(Component.text("File not found"));

View file

@ -4,12 +4,8 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import me.chayapak1.chomens_bot.Bot;
import me.chayapak1.chomens_bot.data.PlayerEntry;
import me.chayapak1.chomens_bot.util.ComponentUtilities;
import me.chayapak1.chomens_bot.util.PersistentDataUtilities;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.JoinConfiguration;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
@ -40,21 +36,12 @@ public class IPFilterPlugin extends PlayersPlugin.Listener {
}
private void check (PlayerEntry target) {
final CompletableFuture<Component> future = bot.core.runTracked("essentials:seen " + target.profile.getIdAsString());
final CompletableFuture<String> future = bot.players.getPlayerIP(target);
if (future == null) return;
future.thenApply(output -> {
final List<Component> children = output.children();
String stringified = ComponentUtilities.stringify(Component.join(JoinConfiguration.separator(Component.space()), children));
if (!stringified.startsWith(" - IP Address: ")) return output;
stringified = stringified.trim().substring(" - IP Address: ".length());
if (stringified.startsWith("/")) stringified = stringified.substring(1);
handleIP(stringified, target);
handleIP(output, target);
return output;
});

View file

@ -169,7 +169,7 @@ public class IRCPlugin extends ListenerAdapter {
}
public void quit (String reason) {
bot.sendIRC().quitServer(reason);
if (bot.isConnected()) bot.sendIRC().quitServer(reason);
}
private void connected (Bot bot) {
@ -202,9 +202,7 @@ public class IRCPlugin extends ListenerAdapter {
bot.sendIRC().message(entry.getKey(), withIRCColors);
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception ignored) {}
}
private void addMessageToQueue (Bot bot, String message) {

View file

@ -56,6 +56,8 @@ public class MusicPlayerPlugin extends Bot.Listener {
private int limit = 0;
public boolean locked = false; // this can be set through servereval
private final String bossbarName = "music";
public BossBarColor bossBarColor;
@ -73,7 +75,7 @@ public class MusicPlayerPlugin extends Bot.Listener {
}
public void loadSong (Path location, PlayerEntry sender) {
if (songQueue.size() > 100) return;
if (songQueue.size() > 500) return;
loaderThread = new SongLoaderThread(location, bot, sender.profile.getName());
@ -90,7 +92,7 @@ public class MusicPlayerPlugin extends Bot.Listener {
}
public void loadSong (URL location, PlayerEntry sender) {
if (songQueue.size() > 100) return;
if (songQueue.size() > 500) return;
limit++;
@ -114,7 +116,7 @@ public class MusicPlayerPlugin extends Bot.Listener {
}
public void loadSong (byte[] data, PlayerEntry sender) {
if (songQueue.size() > 100) return;
if (songQueue.size() > 500) return;
loaderThread = new SongLoaderThread(data, bot, sender.profile.getName());
@ -194,13 +196,9 @@ public class MusicPlayerPlugin extends Bot.Listener {
if (songQueue.isEmpty()) {
stopPlaying();
removeBossBar();
bot.chat.tellraw(
Component
.text("Finished playing every song in the queue")
.color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor))
);
return;
}
if (currentSong.size() > 0) {
currentSong = songQueue.get(0);
currentSong.setTime(0);

View file

@ -1,11 +1,14 @@
package me.chayapak1.chomens_bot.plugins;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import me.chayapak1.chomens_bot.Bot;
import me.chayapak1.chomens_bot.data.PlayerEntry;
import me.chayapak1.chomens_bot.util.PersistentDataUtilities;
import java.time.Instant;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class PlayersPersistentDataPlugin extends PlayersPlugin.Listener {
public static JsonObject playersObject = new JsonObject();
@ -26,12 +29,40 @@ public class PlayersPersistentDataPlugin extends PlayersPlugin.Listener {
@Override
public void playerJoined(PlayerEntry target) {
if (playersObject.has(getName(target))) return;
final JsonElement originalElement = playersObject.get(target.profile.getName());
final JsonObject object = new JsonObject();
object.addProperty("uuid", target.profile.getIdAsString());
object.add("lastSeen", new JsonObject());
JsonObject object;
if (originalElement == null) {
object = new JsonObject();
object.addProperty("uuid", target.profile.getIdAsString());
object.add("ips", new JsonObject());
} else {
object = originalElement.getAsJsonObject();
}
final CompletableFuture<String> future = bot.players.getPlayerIP(target);
if (future == null) {
setPersistentEntry(target, object);
return;
}
future.completeOnTimeout(null, 5, TimeUnit.SECONDS);
future.thenApply(output -> {
if (output != null) {
object.getAsJsonObject("ips").addProperty(bot.host + ":" + bot.port, output);
}
setPersistentEntry(target, object);
return output;
});
}
// is this bad?
private void setPersistentEntry (PlayerEntry target, JsonObject object) {
playersObject.add(getName(target), object);
PersistentDataUtilities.put("players", playersObject);

View file

@ -1,5 +1,7 @@
package me.chayapak1.chomens_bot.plugins;
import me.chayapak1.chomens_bot.util.ComponentUtilities;
import net.kyori.adventure.text.JoinConfiguration;
import org.geysermc.mcprotocollib.network.Session;
import org.geysermc.mcprotocollib.network.event.session.DisconnectedEvent;
import org.geysermc.mcprotocollib.network.packet.Packet;
@ -16,6 +18,7 @@ import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public class PlayersPlugin extends Bot.Listener {
private final Bot bot;
@ -58,6 +61,31 @@ public class PlayersPlugin extends Bot.Listener {
}
}
public CompletableFuture<String> getPlayerIP (PlayerEntry target) {
final CompletableFuture<String> outputFuture = new CompletableFuture<>();
final CompletableFuture<Component> trackedCoreFuture = bot.core.runTracked("essentials:seen " + target.profile.getIdAsString());
if (trackedCoreFuture == null) return null;
trackedCoreFuture.thenApply(output -> {
final List<Component> children = output.children();
String stringified = ComponentUtilities.stringify(Component.join(JoinConfiguration.separator(Component.space()), children));
if (!stringified.startsWith(" - IP Address: ")) return output;
stringified = stringified.trim().substring(" - IP Address: ".length());
if (stringified.startsWith("/")) stringified = stringified.substring(1);
outputFuture.complete(stringified);
return output;
});
return outputFuture;
}
public final PlayerEntry getEntry (UUID uuid) {
for (PlayerEntry candidate : list) {
if (candidate.profile.getId().equals(uuid)) {

View file

@ -30,6 +30,8 @@ public class PositionPlugin extends Bot.Listener {
public Vector3i position = Vector3i.from(0, 0, 0);
public boolean isGoingDownFromHeightLimit = false; // cool variable name
private final Map<Integer, PlayerEntry> entityIdMap = new HashMap<>();
private final Map<Integer, Vector3f> positionMap = new HashMap<>();
private final Map<Integer, Rotation> rotationMap = new HashMap<>();
@ -40,12 +42,23 @@ public class PositionPlugin extends Bot.Listener {
bot.addListener(this);
// notchian clients also does this, sends the position packet every second
bot.executor.scheduleAtFixedRate(() -> bot.session.send(new ServerboundMovePlayerPosPacket(
false,
position.getX(),
position.getY(),
position.getZ()
)), 0, 1, TimeUnit.SECONDS);
bot.executor.scheduleAtFixedRate(() -> {
if (isGoingDownFromHeightLimit) return;
bot.session.send(new ServerboundMovePlayerPosPacket(
false,
position.getX(),
position.getY(),
position.getZ()
));
}, 0, 1, TimeUnit.SECONDS);
bot.tick.addListener(new TickPlugin.Listener() {
@Override
public void onTick() {
handleHeightLimit();
}
});
}
@Override
@ -145,6 +158,52 @@ public class PositionPlugin extends Bot.Listener {
for (Listener listener : listeners) listener.playerMoved(player, position, rotation);
}
// for now this is used in CorePlugin when placing the command block
private void handleHeightLimit () {
final int y = position.getY();
final int minY = bot.world.minY;
final int maxY = bot.world.maxY;
if (y < maxY) {
if (isGoingDownFromHeightLimit) {
isGoingDownFromHeightLimit = false;
for (Listener listener : listeners) { listener.positionChange(position); }
}
return;
}
isGoingDownFromHeightLimit = true;
final Vector3i newPosition = Vector3i.from(
position.getX(),
position.getY() - 2,
position.getZ()
);
position = newPosition;
if (position.getY() > maxY + 500 || position.getY() < minY) {
String command = "/";
if (bot.serverPluginsManager.hasPlugin(ServerPluginsManagerPlugin.ESSENTIALS)) command += "essentials:";
command += String.format("tp ~ %s ~", maxY - 1);
bot.chat.send(command);
return;
}
bot.session.send(new ServerboundMovePlayerPosPacket(
false,
newPosition.getX(),
newPosition.getY(),
newPosition.getZ()
));
}
public Vector3f getPlayerPosition (String playerName) {
int entityId = -1;
for (Map.Entry<Integer, PlayerEntry> entry : entityIdMap.entrySet()) {

View file

@ -58,7 +58,7 @@ public class VoiceChatPlugin extends Bot.Listener {
bot.session.send(new ServerboundCustomPayloadPacket(
Key.key("voicechat:request_secret"),
new FriendlyByteBuf(Unpooled.buffer()).writeInt(17).array()
new FriendlyByteBuf(Unpooled.buffer()).writeInt(18).array()
));
bot.session.send(new ServerboundCustomPayloadPacket(

View file

@ -51,13 +51,7 @@ public class WhitelistPlugin extends PlayersPlugin.Listener {
}
public void add (String player) { list.add(player); }
public void remove (String player) {
list.removeIf(eachPlayer -> eachPlayer.equals(player));
final PlayerEntry entry = bot.players.getEntry(player);
if (entry != null) handle(entry);
}
public String remove (int index) { return list.remove(index); }
public void clear () {
list.removeIf(eachPlayer -> !eachPlayer.equals(bot.profile.getName()));
}
@ -72,7 +66,7 @@ public class WhitelistPlugin extends PlayersPlugin.Listener {
}
public void commandReceived (PlayerEntry entry, String command) {
if (!enabled || list.contains(entry.profile.getName())) return;
if (!enabled || list.contains(entry.profile.getName()) || entry.profile.equals(bot.profile)) return;
if (
command.startsWith("mute") ||
@ -90,7 +84,7 @@ public class WhitelistPlugin extends PlayersPlugin.Listener {
}
private void handle (PlayerEntry entry) {
if (!enabled || list.contains(entry.profile.getName())) return;
if (!enabled || list.contains(entry.profile.getName()) || entry.profile.equals(bot.profile)) return;
bot.filter.doAll(entry);
}

View file

@ -34,14 +34,17 @@ public class WorldPlugin extends Bot.Listener {
private void worldChanged (String dimension) {
final RegistryEntry currentDimension = registry.stream()
.filter(eachDimension -> eachDimension.getId().asString().equals(dimension))
.toArray(RegistryEntry[]::new)[0];
.findFirst()
.orElse(null);
if (currentDimension == null) return;
final NbtMap data = currentDimension.getData();
if (data == null) return;
minY = data.getInt("min_y");
maxY = data.getInt("height");
maxY = data.getInt("height") + minY;
for (Listener listener : listeners) listener.worldChanged(dimension);
}

View file

@ -215,7 +215,8 @@ public class MidiConverter implements Converter {
shiftedInstrument = Arrays.stream(instrumentList)
.filter(ins -> ins.offset == closest)
.toArray(Instrument[]::new)[0];
.findFirst()
.orElse(null);
}
}

View file

@ -17,7 +17,7 @@ public class Song {
public long startTime = 0; // Start time in millis since unix epoch
public long length = 0; // Milliseconds in the song
public long time = 0; // Time since start of song
public long loopPosition = 200; // Milliseconds into the song to start looping
public long loopPosition = 0; // Milliseconds into the song to start looping
public final Map<Long, String> lyrics = new HashMap<>();
@ -80,7 +80,7 @@ public class Song {
*/
public void play () {
if (paused) {
if (loopPosition != 200) bot.music.loop = Loop.CURRENT;
if (loopPosition != 0) bot.music.loop = Loop.CURRENT;
paused = false;
startTime = System.currentTimeMillis() - time;
}

View file

@ -46,7 +46,7 @@ public class SongPlayerConverter implements Converter {
song.length = songLength;
// song.looping = loop > 0;
// song.loopCount = loopCount;
song.loopPosition = loopPosition == 0 ? 200 : loopPosition;
song.loopPosition = loopPosition;
long time = 0;
while (true) {

View file

@ -81,13 +81,15 @@ public class ComponentUtilities {
return map;
}
private static String getOrReturnKey (String key) {
private static String getOrReturnFallback (TranslatableComponent component) {
final String key = component.key();
final String minecraftKey = language.get(key);
final String voiceChatKey = voiceChatLanguage.get(key);
if (minecraftKey != null) return minecraftKey;
else if (voiceChatKey != null) return voiceChatKey;
else return key;
else return component.fallback() != null ? component.fallback() : key;
}
public static String stringify (Component message) { return stringify(message, null); }
@ -257,14 +259,14 @@ public class ComponentUtilities {
}
// messy af
return new PartiallyStringified((lastColor != null ? lastColor : "") + (color != null ? color : "") + (style != null ? style : "") + replacedContent + (ansi ? ansiMap.get("r") : ""), color);
return new PartiallyStringified((lastColor != null ? lastColor : "") + (color != null ? color : "") + (style != null ? style : "") + replacedContent + (ansi ? ansiMap.get("r") : "") + (style != null ? style : ""), color);
}
return new PartiallyStringified(message.content(), null);
}
public static PartiallyStringified stringifyPartially (TranslatableComponent message, boolean motd, boolean ansi, String lastColor, boolean noHex) {
String format = getOrReturnKey(message.key());
String format = getOrReturnFallback(message);
// totallynotskidded from HBot (and changed a bit)
Matcher matcher = ARG_PATTERN.matcher(format);
@ -278,6 +280,8 @@ public class ComponentUtilities {
int i = 0;
while (matcher.find()) {
if (i > 300) break;
if (matcher.group().equals("%%")) {
matcher.appendReplacement(sb, "%");
} else {
@ -303,7 +307,7 @@ public class ComponentUtilities {
}
matcher.appendTail(sb);
return new PartiallyStringified((lastColor != null ? lastColor : "") + color + (style != null && ansi ? style : "") + sb + (ansi ? ansiMap.get("r") : ""), _color);
return new PartiallyStringified((lastColor != null ? lastColor : "") + color + (style != null && ansi ? style : "") + sb + (ansi ? ansiMap.get("r") + (style != null ? style : "") : ""), _color);
}
public static PartiallyStringified stringifyPartially (SelectorComponent message, boolean motd, boolean ansi, String lastColor, boolean noHex) {

View file

@ -2,10 +2,8 @@ package me.chayapak1.chomens_bot.util;
import me.chayapak1.chomens_bot.Main;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@ -17,12 +15,13 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPOutputStream;
// totallynotskidded from HBot
// original source code from hhhzzzsss, specifically HBot.
// source: https://github.com/hhhzzzsss/HBot-Release/blob/main/src/main/java/com/github/hhhzzzsss/hbot/Logger.java
public class FileLoggerUtilities {
public static final Path logDirectory = Path.of("logs");
public static final Path logPath = Paths.get(logDirectory.toString(), "log.txt");
public static BufferedWriter logWriter;
public static OutputStreamWriter logWriter;
public static LocalDate currentLogDate;
public static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("'['dd/MM/yyyy HH:mm:ss']' ");
@ -78,56 +77,49 @@ public class FileLoggerUtilities {
}
}
public static void makeNewLogFile() throws IOException {
public static synchronized void makeNewLogFile() throws IOException {
currentLogDate = LocalDate.now();
if (!Files.exists(logPath)) Files.createFile(logPath);
logWriter = Files.newBufferedWriter(logPath, StandardOpenOption.TRUNCATE_EXISTING);
logWriter = new OutputStreamWriter(Files.newOutputStream(logPath, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING), StandardCharsets.UTF_8);
logWriter.write(currentLogDate.toString() + '\n');
logWriter.flush();
}
public static void openLogFile() throws IOException {
public static synchronized void openLogFile() throws IOException {
currentLogDate = LocalDate.parse(getLogDate(logPath));
logWriter = Files.newBufferedWriter(logPath, StandardOpenOption.APPEND);
logWriter = new OutputStreamWriter(Files.newOutputStream(logPath, StandardOpenOption.CREATE, StandardOpenOption.APPEND), StandardCharsets.UTF_8);
}
public static void compressLogFile() throws IOException {
public static synchronized void compressLogFile() throws IOException {
if (Files.size(logPath) > 100 * 1024 * 1024) { // Will not save because log file is too big
return;
}
final Path path = Paths.get(logDirectory.toString(), getLogDate(logPath) + ".txt.gz");
Files.createFile(path);
InputStream in = Files.newInputStream(logPath);
GZIPOutputStream out = new GZIPOutputStream(Files.newOutputStream(path));
byte[] buffer = new byte[1024];
int size;
while ((size = in.read(buffer)) > 0) {
out.write(buffer, 0, size);
try (
final InputStream in = Files.newInputStream(logPath, StandardOpenOption.READ);
final GZIPOutputStream out = new GZIPOutputStream(Files.newOutputStream(path, StandardOpenOption.CREATE))
) {
byte[] buffer = new byte[1024];
int size;
while ((size = in.read(buffer)) > 0) {
out.write(buffer, 0, size);
}
}
in.close();
out.finish();
out.close();
}
public static String getLogDate(Path path) throws IOException {
BufferedReader reader = Files.newBufferedReader(path);
String date = reader.readLine();
reader.close();
return date;
public static synchronized String getLogDate (Path filePath) throws IOException {
try (final BufferedReader reader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8)) {
return reader.readLine();
}
}
public static boolean logIsCurrent(Path path) throws IOException {
public static synchronized boolean logIsCurrent(Path path) throws IOException {
LocalDate date = LocalDate.now();
return getLogDate(path).equals(date.toString());
}
public static void log(String str) {
public static synchronized void log(String str) {
if (freezeTime > System.currentTimeMillis()) {
return;
}
@ -161,8 +153,7 @@ public class FileLoggerUtilities {
logWriter.write("\n");
}
if (str.length() > 32767) logWriter.write("Message too big, not logging this message"); // should these stuff be hardcoded?
else logWriter.write(getTimePrefix() + str.replaceAll("\\[(\\d+?)x](?=$|[\r\n])", "[/$1x]")); // the replaceAll will prevent conflicts with the duplicate counter
logWriter.write(getTimePrefix() + str.replaceAll("\\[(\\d+?)x](?=$|[\r\n])", "[/$1x]")); // the replaceAll will prevent conflicts with the duplicate counter
logWriter.flush();
duplicateCounter = 1;

View file

@ -4,7 +4,6 @@ import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import me.chayapak1.chomens_bot.Main;
import java.io.BufferedReader;
import java.io.BufferedWriter;
@ -12,10 +11,6 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class PersistentDataUtilities {
public static final Path path = Path.of("persistent.json");
@ -24,33 +19,10 @@ public class PersistentDataUtilities {
public static JsonObject jsonObject = new JsonObject();
private static final Map<String, JsonElement> queue = new ConcurrentHashMap<>();
private static final ScheduledFuture<?> future;
private static boolean stopping = false;
static {
init();
future = Main.executor.scheduleAtFixedRate(() -> {
try {
if (queue.isEmpty()) return;
final Map.Entry<String, JsonElement> entry = queue.entrySet().iterator().next(); // is this the best way to get the first item of the map?
final String property = entry.getKey();
final JsonElement value = entry.getValue();
Main.executorService.submit(() -> {
jsonObject.add(property, value);
write(jsonObject.toString());
queue.remove(property);
});
} catch (Exception e) {
e.printStackTrace();
}
}, 0, 100, TimeUnit.MILLISECONDS);
}
private static void init () {
@ -66,19 +38,17 @@ public class PersistentDataUtilities {
jsonObject = gson.fromJson(reader, JsonObject.class);
}
writer = Files.newBufferedWriter(path, StandardOpenOption.TRUNCATE_EXISTING);
writer = Files.newBufferedWriter(path, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
}
private static void write (String string) {
try {
writer.close();
if (stopping) return; // is this necessary?
// ? how do i clear the file contents without making a completely new writer?
// or is this the only way?
writer = Files.newBufferedWriter(path, StandardOpenOption.TRUNCATE_EXISTING);
try {
writer = Files.newBufferedWriter(path, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
writer.write(string);
writer.flush();
@ -86,27 +56,32 @@ public class PersistentDataUtilities {
}
public static void stop () {
future.cancel(false);
stopping = true;
write(jsonObject.toString());
}
public static void put (String property, JsonElement value) {
Main.executorService.submit(() -> queue.put(property, value));
jsonObject.add(property, value);
write(jsonObject.toString());
}
public static void put (String property, String value) {
Main.executorService.submit(() -> queue.put(property, new JsonPrimitive(value)));
jsonObject.add(property, new JsonPrimitive(value));
write(jsonObject.toString());
}
public static void put (String property, boolean value) {
Main.executorService.submit(() -> queue.put(property, new JsonPrimitive(value)));
jsonObject.add(property, new JsonPrimitive(value));
write(jsonObject.toString());
}
public static void put (String property, int value) {
Main.executorService.submit(() -> queue.put(property, new JsonPrimitive(value)));
jsonObject.add(property, new JsonPrimitive(value));
write(jsonObject.toString());
}
public static void put (String property, char value) {
Main.executorService.submit(() -> queue.put(property, new JsonPrimitive(value)));
jsonObject.add(property, new JsonPrimitive(value));
write(jsonObject.toString());
}
}

View file

@ -16,7 +16,7 @@ internetCheck:
# how backup works is that it checks for the address every 1 minute,
# if the address is reachable it will not start the bot
# if the address is not reachable then it will start the bot
#
# if the bot has already been started and the address is back up it
# will stop the bot (using System.exit(1))
backup:
@ -59,7 +59,8 @@ colorPalette:
number: 'gold'
ownerName: 'green'
ownerName: 'chayapak' # currently this is only used in the console
# you HAVE TO CHANGE THIS if you are hosting another instance of my bot.
ownerName: 'XxChange_mexX'
imposterFormatChecker:
enabled: false