melijn / melijn-bot Goto Github PK
View Code? Open in Web Editor NEWA multipurpose discord bot written in kotlin, using jda
Home Page: https://melijn.com
License: GNU Affero General Public License v3.0
A multipurpose discord bot written in kotlin, using jda
Home Page: https://melijn.com
License: GNU Affero General Public License v3.0
Porting the osu command from melijn to the rewrite, this should include the following functionality:
getCooldownTypes in DefaultCooldownProvider.kt
is wrong.
port the old permission system, discord's one is shite.
depends on customizable messages, logchannels and permissions
see mikbot as an example
It would be preferable for users to be able to opt-in to harsher (or less harsh) filtering methods for the name normalization feature.
For example, an english-speaking community may want to restrict names to only ASCII.
This feature calls for a proper settings system though, as we likely don't want to shove everything in the guild_settings
table when more and more options are added for the diverse set of guild-level features.
I cloned the repo and edited the env files and docker-compose.yml to fit my configuration, however, after starting the server, Melijn gets in a crash loop with this error:
melijn | Invalid maximum heap size: -Xmx
melijn | Error: Could not create the Java Virtual Machine.
melijn | Error: A fatal exception has occurred. Program will exit.
I'm guessing I have to set the maximum allowed JVM heap size somewhere, but I can't find any ENV variable nor bootup string/arguments for it.
As it is desirable to attract external developers to help improve melijn, instructions on how to run the bot should be added to the README.
If you add a validate block to a KordExUtils
Arguments.function, it won't get run. It still runs the validity check in the KordExUtils
function, but will not check whether the Valid
block added to the function is correct.
Example:
val amount by availableCurrency("triedBettingNothing", "triedOverBetting") {
name = "bet"
description = "amount to bet"
validate {
val totalBet = this.value * xtimes
val balance = balanceManager.get(this.context.user).balance
failIf(tr("triedOverBetting", xtimes, this.value)) { true }
}
}
this will run perfectly fine even though it should always fail.
This catcommandregistry implementation should provide support for:
Because the database implementation doesn't exist yet you may hardcode some examples in with comments that indicate where the database calls should go, user and guild prefixes should be string sets, user and guild aliases would be a Map<String, String>
2023-08-26 13:11:36 ERROR c.k.k.e.commands.chat.ChatCommand | Error during execution of latex command (MessageReceivedEvent)
org.scilab.forge.jlatexmath.XMLResourceParseException: DefaultTeXFont.xml: error reading font 'fonts/latin/jlm_cmr10.ttf'. Error message: Problem reading font data.
at org.scilab.forge.jlatexmath.DefaultTeXFontParser.createFont(DefaultTeXFontParser.java:393)
at org.scilab.forge.jlatexmath.DefaultTeXFontParser.createFont(DefaultTeXFontParser.java:363)
at org.scilab.forge.jlatexmath.FontInfo.getFont(FontInfo.java:309)
at org.scilab.forge.jlatexmath.DefaultTeXFont.getChar(DefaultTeXFont.java:324)
at org.scilab.forge.jlatexmath.DefaultTeXFont.getChar(DefaultTeXFont.java:284)
at org.scilab.forge.jlatexmath.DefaultTeXFont.getChar(DefaultTeXFont.java:292)
at org.scilab.forge.jlatexmath.DefaultTeXFont.getDefaultChar(DefaultTeXFont.java:341)
at org.scilab.forge.jlatexmath.CharAtom.getChar(CharAtom.java:116)
at org.scilab.forge.jlatexmath.CharAtom.createBox(CharAtom.java:91)
at org.scilab.forge.jlatexmath.TeXFormula.createBox(TeXFormula.java:582)
at org.scilab.forge.jlatexmath.TeXFormula.access$100(TeXFormula.java:94)
at org.scilab.forge.jlatexmath.TeXFormula$TeXIconBuilder.build(TeXFormula.java:762)
at org.scilab.forge.jlatexmath.TeXFormula.createTeXIcon(TeXFormula.java:796)
at org.scilab.forge.jlatexmath.TeXFormula.createBufferedImage(TeXFormula.java:901)
at me.melijn.bot.commands.MathExtension$setup$14$1.invokeSuspend(MathExtension.kt:197)
at me.melijn.bot.commands.MathExtension$setup$14$1.invoke(MathExtension.kt)
at me.melijn.bot.commands.MathExtension$setup$14$1.invoke(MathExtension.kt)
at com.kotlindiscord.kord.extensions.commands.chat.ChatCommand$call$2.invokeSuspend(ChatCommand.kt:467)
at com.kotlindiscord.kord.extensions.commands.chat.ChatCommand$call$2.invoke(ChatCommand.kt)
at com.kotlindiscord.kord.extensions.commands.chat.ChatCommand$call$2.invoke(ChatCommand.kt)
at com.kotlindiscord.kord.extensions.types.Lockable$DefaultImpls.withLock(Lockable.kt:24)
at com.kotlindiscord.kord.extensions.commands.Command.withLock(Command.kt:46)
at com.kotlindiscord.kord.extensions.commands.chat.ChatCommand.call$suspendImpl(ChatCommand.kt:385)
at com.kotlindiscord.kord.extensions.commands.chat.ChatCommand.call(ChatCommand.kt)
at com.kotlindiscord.kord.extensions.commands.chat.ChatCommand.call$default(ChatCommand.kt:378)
at com.kotlindiscord.kord.extensions.commands.chat.ChatCommandRegistry.handleEvent$suspendImpl(ChatCommandRegistry.kt:229)
at com.kotlindiscord.kord.extensions.commands.chat.ChatCommandRegistry$handleEvent$1.invokeSuspend(ChatCommandRegistry.kt)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)
needs logchannel
Allow linking your anilist profile to your discord account
Commands for viewing information about
/Open to additions\
ideally we should be able to track any fediverse feed but focussing on mastodon and other twitter-like feeds is enough for now
The bot needs a database implementation of some sort.
Preferably using some library so we don't need to maintain some raw SQL language. (eg. jetbrains exposed)
Database instances should be shared via Koin dependency injection.
We might also need an annotation processor to generate the koin stuff.
There should be a caching layer somehow that sets and gets from redis without having to manually do these kind of operations as it's a lot of repetitive error-prone work
Stack trace:
melijn | 2022-11-13 18:16:11 INFO me.melijn.bot.services.StartupService | Done recovering music for shard #0
melijn | 2022-11-13 18:17:19 INFO me.melijn.bot.music.MusicManager | New trackManager for 958807531017367632
melijn | 2022-11-13 18:17:19 ERROR [Koin] | Instance creation error : could not create instance for [Singleton:'me.melijn.bot.web.api.WebManager',binds:me.melijn.bot.web.api.WebManager]: java.lang.NumberFormatException: For input string: "host"
melijn | java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
melijn | java.base/java.lang.Integer.parseInt(Integer.java:660)
melijn | java.base/java.lang.Integer.parseInt(Integer.java:778)
melijn | me.melijn.kordkommons.environment.BotSettings$int$1$1.invoke(BotSettings.kt:53)
melijn | me.melijn.kordkommons.environment.BotSettings$int$1$1.invoke(BotSettings.kt:53)
melijn | me.melijn.kordkommons.environment.BotSettings.getValue(BotSettings.kt:83)
melijn | me.melijn.kordkommons.environment.BotSettings.int$lambda-7(BotSettings.kt:53)
melijn | me.melijn.gen.Settings$HttpProxy.getPort(Settings.kt:87)
melijn | me.melijn.bot.web.api.WebManager$proxiedHttpClient$1$1.invoke(WebManager.kt:45)
melijn | me.melijn.bot.web.api.WebManager$proxiedHttpClient$1$1.invoke(WebManager.kt:43)
melijn | io.ktor.client.HttpClientConfig$engine$1.invoke(HttpClientConfig.kt:32)
melijn | io.ktor.client.HttpClientConfig$engine$1.invoke(HttpClientConfig.kt:30)
melijn | io.ktor.client.engine.okhttp.OkHttp.create(OkHttp.kt:31)
melijn | io.ktor.client.HttpClientKt.HttpClient(HttpClient.kt:41)
melijn | me.melijn.bot.web.api.WebManager.<init>(WebManager.kt:41)
melijn | me.melijn.gen.InjectionKoinModule1$module$1$23.invoke(InjectionKoinModule1.kt:55)
melijn | me.melijn.gen.InjectionKoinModule1$module$1$23.invoke(InjectionKoinModule1.kt:55)
melijn | org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:54)
melijn | org.koin.core.instance.SingleInstanceFactory.create(SingleInstanceFactory.kt:46)
melijn | org.koin.core.instance.SingleInstanceFactory$get$1.invoke(SingleInstanceFactory.kt:53)
melijn | org.koin.core.instance.SingleInstanceFactory$get$1.invoke(SingleInstanceFactory.kt:51)
melijn | org.koin.mp.KoinPlatformTools.synchronized(KoinPlatformTools.kt:20)
melijn | org.koin.core.instance.SingleInstanceFactory.get(SingleInstanceFactory.kt:51)
melijn | org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:111)
melijn | org.koin.core.scope.Scope.resolveValue(Scope.kt:255)
melijn | org.koin.core.scope.Scope.resolveInstance(Scope.kt:242)
melijn | org.koin.core.scope.Scope.get(Scope.kt:205)
melijn | me.melijn.bot.music.TrackLoader$special$$inlined$inject$default$2.invoke(KoinComponent.kt:74)
melijn | kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
melijn | me.melijn.bot.music.TrackLoader.getWebManager(TrackLoader.kt:18)
melijn | me.melijn.bot.music.TrackLoader.searchTracks(TrackLoader.kt:37)
melijn | me.melijn.bot.music.TrackLoader.searchTracks$default(TrackLoader.kt:31)
melijn | me.melijn.bot.commands.music.MusicExtension$setup$22$1.invokeSuspend(MusicExtension.kt:587)
melijn | me.melijn.bot.commands.music.MusicExtension$setup$22$1.invoke(MusicExtension.kt)
melijn | me.melijn.bot.commands.music.MusicExtension$setup$22$1.invoke(MusicExtension.kt)
melijn | com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommand.run(PublicSlashCommand.kt:108)
melijn | com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommand$run$1.invokeSuspend(PublicSlashCommand.kt)
melijn | kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:138)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:112)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.access$loop(SuspendFunctionGun.kt:14)
melijn | io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:62)
melijn | kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:138)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:112)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.access$loop(SuspendFunctionGun.kt:14)
melijn | io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:62)
melijn | kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:138)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:112)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.access$loop(SuspendFunctionGun.kt:14)
melijn | io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:62)
melijn | kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:138)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:112)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.access$loop(SuspendFunctionGun.kt:14)
melijn | io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:62)
melijn | kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:138)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:112)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.access$loop(SuspendFunctionGun.kt:14)
melijn | io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:62)
melijn | kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:138)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:112)
melijn | io.ktor.util.pipeline.SuspendFunctionGun.access$loop(SuspendFunctionGun.kt:14)
melijn | io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:62)
melijn | kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
melijn | kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
melijn | kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
melijn | kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
melijn | kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
melijn | kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
Melijn tries to parse the
# tested with squid proxy, squid proxy can have an ip whitelist, idk if any docker password proxies exist
# if they do pls create and issue for it xd
# Proxy is used for fetching user supplied urls (may be ip loggers trying to start a DOS/DDOS)
PROXY_ENABLED=FALSE
PROXY_HOST=host
PROXY_PORT=host
variables even if PROXY_ENABLED
is set to false. Setting them to 127.0.0.1
and 80
made the error disappear, even though I'm not running any proxy locally - which I suppose is correct because the proxy setting is not enabled and thus no connection is attempted. I think it should also avoid parsing, or at the very least have acceptable values by default, since host:host
is not valid and causes this issue.
Thanks again!
While looking at the env file, I saw this entry:
# If empty, the bot will register global slash commands, otherwise guild commands to the configured server
PROCESS_TESTINGSERVERID=
I decided to leave it empty because I wanted to try having it register global slash commands. However, this error comes up and Melijn just crashes:
melijn | 2022-11-13 17:48:06 INFO me.melijn.bot.Melijn | Starting Melijn..
melijn | 2022-11-13 17:48:06 INFO me.melijn.bot.Melijn | [hostName] localhost
melijn | Exception in thread "main" java.lang.NumberFormatException: For input string: ""
melijn | at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
melijn | at java.base/java.lang.Long.parseLong(Long.java:724)
melijn | at java.base/java.lang.Long.parseLong(Long.java:839)
melijn | at me.melijn.kordkommons.environment.BotSettings$long$1$1.invoke(BotSettings.kt:49)
melijn | at me.melijn.kordkommons.environment.BotSettings$long$1$1.invoke(BotSettings.kt:49)
melijn | at me.melijn.kordkommons.environment.BotSettings.getValue(BotSettings.kt:83)
melijn | at me.melijn.kordkommons.environment.BotSettings.long$lambda-6(BotSettings.kt:49)
melijn | at me.melijn.gen.Settings$Process.getTestingServerId(Settings.kt:24)
melijn | at me.melijn.bot.Melijn$susInit$botInstance$1$5.invokeSuspend(Melijn.kt:136)
melijn | at me.melijn.bot.Melijn$susInit$botInstance$1$5.invoke(Melijn.kt)
melijn | at me.melijn.bot.Melijn$susInit$botInstance$1$5.invoke(Melijn.kt)
melijn | at com.kotlindiscord.kord.extensions.builders.ExtensibleBotBuilder.applicationCommands(ExtensibleBotBuilder.kt:266)
melijn | at me.melijn.bot.Melijn$susInit$botInstance$1.invokeSuspend(Melijn.kt:132)
melijn | at me.melijn.bot.Melijn$susInit$botInstance$1.invoke(Melijn.kt)
melijn | at me.melijn.bot.Melijn$susInit$botInstance$1.invoke(Melijn.kt)
melijn | at com.kotlindiscord.kord.extensions.ExtensibleBotKt.ExtensibleBot(ExtensibleBot.kt:469)
melijn | at me.melijn.bot.Melijn.susInit(Melijn.kt:57)
melijn | at me.melijn.bot.MelijnKt.main(Melijn.kt:210)
melijn | at me.melijn.bot.MelijnKt$main$2.invoke(Melijn.kt)
melijn | at me.melijn.bot.MelijnKt$main$2.invoke(Melijn.kt)
melijn | at kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt$createCoroutineUnintercepted$$inlined$createCoroutineFromSuspendFunction$IntrinsicsKt__IntrinsicsJvmKt$1.invokeSuspend(IntrinsicsJvm.kt:205)
melijn | at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
melijn | at kotlin.coroutines.ContinuationKt.startCoroutine(Continuation.kt:115)
melijn | at kotlin.coroutines.jvm.internal.RunSuspendKt.runSuspend(RunSuspend.kt:19)
melijn | at me.melijn.bot.MelijnKt.main(Melijn.kt)
melijn exited with code 1
From this line, especially, I saw that it still tries to parse the testingServerId string even if it's empty:
melijn | at me.melijn.gen.Settings$Process.getTestingServerId(Settings.kt:24)
Anyways, thanks for the awesome work! Melijn is great :)
Discord allows argument inputs that cause integer (Int) overflows, these are currently not properly handled by the SlashCommandParser
.
Feel free to create a draft pr if you want to start porting something so no 2 people are trying to do the same thing.
Website ui and command interface to manage these, depends on adding some scripting lang to bot-kommons
We need a persistant cooldown and ratelimit system so that long cooldowns are retained accross bot instances and restarts.
broke after upgrading to 1.7.10.
Needs to be looked into and resolved
prefixes support is partly done and is tracked by issue #4
Remove invoke and response will be dropped, this can be replaced with an automatic channel purger in the future
Aliases will be dropped
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.