Skip to content

Commit

Permalink
Release 1.0.1 (#24)
Browse files Browse the repository at this point in the history
* Fix Source Command Repo Link and fix typo (#17)

* Fixed repo link

* Fixed typo

* Fix production error handler (#19)

* Add twitch integration only in production (#21)

* Removed docsdex submodule (#22)

* Fix Error handler for slash commands (#23)

* Fix production error handler

* Make @NyCodeGHG happy

* Fix detekt issues

* Replace work around in favour of Kord release

* Respond with Embed on unkown tag (#25)

* Removed docsdex submodule

* Fix embed

* Remove unused method

* Variables in Tags (#26)

* Added calculation parser

* Added check task to ci

* Added calc command

* Added pow functionality

* Fixed formatting

* Added tag variables

* Added http variable

* Add tag with variable creation only by bot owners

* Added floating number support

* Fixed calc command

* Fixed exception handling

* Fix formatting

Co-authored-by: NyCode <[email protected]>
  • Loading branch information
DRSchlaubi and NyCodeGHG authored Feb 1, 2021
1 parent 80e11dc commit 7a6f863
Show file tree
Hide file tree
Showing 38 changed files with 1,158 additions and 60 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ jobs:
~/build
~/.gradle
- name: Build with Gradle
run: ./gradlew compileKotlin detektMain
run: ./gradlew compileKotlin detektMain check
3 changes: 0 additions & 3 deletions .gitmodules

This file was deleted.

4 changes: 2 additions & 2 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ plugins {
kotlin("plugin.serialization") version "1.4.21"
id("io.gitlab.arturbosch.detekt") version "1.15.0"
application
antlr
}

group = "de.nycode"
Expand Down Expand Up @@ -77,6 +78,15 @@ dependencies {
implementation("com.vladsch.flexmark", "flexmark-html2md-converter", "0.60.2")

detektPlugins("io.gitlab.arturbosch.detekt", "detekt-formatting", "1.15.0")

antlr("org.antlr", "antlr4", "4.9.1")

testImplementation(kotlin("test"))
testImplementation(kotlin("test-junit5"))
testRuntimeOnly("org.junit.jupiter", "junit-jupiter-engine", "5.6.0")
testRuntimeOnly("org.slf4j", "slf4j-simple", "1.7.30")
testImplementation("org.jetbrains.kotlinx", "kotlinx-coroutines-test", "1.4.2")
testImplementation("com.willowtreeapps.assertk", "assertk-jvm", "0.23")
}

// Kotlin dsl
Expand All @@ -92,4 +102,13 @@ tasks {
// Target version of the generated JVM bytecode. It is used for type resolution.
this.jvmTarget = "1.8"
}

generateGrammarSource {
outputDirectory = File("${project.buildDir}/generated-src/antlr/main/de/nycode/bankobot/variables")
arguments = arguments + listOf("-visitor", "-package", "de.nycode.bankobot.variables")
}

test {
useJUnitPlatform()
}
}
15 changes: 15 additions & 0 deletions src/main/antlr/Calculation.g4
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
grammar Calculation;

root: expression;

expression: '(' expression ')' #Parentheses
| left=expression operator='^' right=expression #Squared
| left=expression operator='*' right=expression #Multiply
| left=expression operator='/' right=expression #Divide
| left=expression operator='+' right=expression #Plus
| left=expression operator='-' right=expression #Minus
| NUMBER #Number
;

NUMBER: [0-9]+('.'[0-9]+)?;
WHITESPACE: [ \t\r\n]+ -> skip;
6 changes: 4 additions & 2 deletions src/main/kotlin/de/nycode/bankobot/BankoBot.kt
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,10 @@ object BankoBot : CoroutineScope {
with(BankoBotContextConverter) {
messageDeleteListener()
}
on<ReadyEvent> {
twitchIntegration()
if (Config.ENVIRONMENT == Environment.PRODUCTION) {
on<ReadyEvent> {
twitchIntegration()
}
}
}
}
Expand Down
39 changes: 24 additions & 15 deletions src/main/kotlin/de/nycode/bankobot/command/ErrorHandlers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ package de.nycode.bankobot.command
import de.nycode.bankobot.utils.Embeds
import de.nycode.bankobot.utils.Embeds.createEmbed
import de.nycode.bankobot.utils.HastebinUtil
import dev.kord.core.behavior.channel.MessageChannelBehavior
import dev.kord.core.behavior.channel.createMessage
import dev.kord.core.behavior.edit
import dev.kord.core.entity.Message
import dev.kord.core.entity.Guild
import dev.kord.core.entity.Member
import dev.kord.core.entity.channel.TextChannel
import dev.kord.core.event.message.MessageCreateEvent
import dev.kord.x.commands.kord.model.context.KordCommandEvent
Expand All @@ -41,6 +43,7 @@ import dev.kord.x.commands.model.processor.ErrorHandler
import kotlinx.datetime.Clock
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.coroutineContext

private val kordHandler = KordErrorHandler()
Expand All @@ -62,7 +65,6 @@ abstract class AbstractErrorHandler :
}

object DebugErrorHandler : AbstractErrorHandler() {

override suspend fun CommandProcessor.exceptionThrown(
event: MessageCreateEvent,
command: Command<KordCommandEvent>,
Expand All @@ -75,8 +77,7 @@ object DebugErrorHandler : AbstractErrorHandler() {
/**
* Implementation of [ErrorHandler] that reports an error log to hastebin.
*/
object HastebinErrorHandler :
ErrorHandler<MessageCreateEvent, MessageCreateEvent, KordCommandEvent> {
object HastebinErrorHandler : AbstractErrorHandler() {
override suspend fun CommandProcessor.exceptionThrown(
event: MessageCreateEvent,
command: Command<KordCommandEvent>,
Expand All @@ -95,7 +96,11 @@ object HastebinErrorHandler :
HastebinUtil.postToHastebin(
collectErrorInformation(
exception,
event.message,
event.message.content,
event.message.channel,
event.message.getGuild(),
@Suppress("UnsafeCallOnNullableType") // slash commands will always have a member
event.message.getAuthorAsMember()!!,
Thread.currentThread()
)
)
Expand All @@ -106,23 +111,27 @@ object HastebinErrorHandler :
}
}

@Suppress("BlockingMethodInNonBlockingContext") // How is StringBuilder#append() blocking?!
private suspend fun collectErrorInformation(
@Suppress("BlockingMethodInNonBlockingContext",
"LongParameterList") // How is StringBuilder#append() blocking?!
suspend fun collectErrorInformation(
e: Exception,
context: Message,
content: String,
channel: MessageChannelBehavior,
guild: Guild,
executor: Member,
thread: Thread,
coroutine: CoroutineContext? = null,
): String {
val coroutineContext = coroutine ?: coroutineContext
val kord = channel.kord
val information = StringBuilder()
information.append("Input: ").append(context.content)
val channel = context.channel.asChannel()
val guild = context.getGuild()
information.append("Input: ").append(content).appendLine()
information.append("Guild: ").append(guild.name).append('(').append(guild.id.value)
.appendLine(')')
val executor = context.author
information.append("Executor: ").append('@').append(executor?.tag).append('(')
.append(executor?.id?.value)
information.append("Executor: ").append('@').append(executor.tag).append('(')
.append(executor.id.value)
.appendLine(')')
val selfMember = guild.getMember(context.kord.selfId)
val selfMember = guild.getMember(kord.selfId)
information.append("Permissions: ").appendLine(selfMember.getPermissions().code)

if (channel is TextChannel) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* MIT License
*
* Copyright (c) 2021 BankoBot Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/

package de.nycode.bankobot.command

import de.nycode.bankobot.variables.parsers.InvalidExpressionException
import de.nycode.bankobot.variables.parsers.calc.CalcExpression
import dev.kord.core.event.message.MessageCreateEvent
import dev.kord.x.commands.argument.Argument
import dev.kord.x.commands.argument.result.ArgumentResult

val MathExpressionArgument: Argument<CalcExpression, MessageCreateEvent> =
InternalMathExpressionArgument()

internal class InternalMathExpressionArgument(override val name: String = "expression") :
Argument<CalcExpression, MessageCreateEvent> {
override suspend fun parse(
text: String,
fromIndex: Int,
context: MessageCreateEvent
): ArgumentResult<CalcExpression> {
val expression = CalcExpression(text.substring(fromIndex))
return try {
expression.getResult()
ArgumentResult.Success(expression, text.length - fromIndex)
} catch (exception: InvalidExpressionException) {
ArgumentResult.Failure(exception.message ?: "Unknown error", exception.position)
} catch (exception: Exception) {
ArgumentResult.Failure(exception.message ?: "Unknown error", 0)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,13 @@ import dev.kord.common.entity.optional.Optional
import dev.kord.common.entity.optional.OptionalSnowflake
import dev.kord.common.entity.optional.optional
import dev.kord.common.entity.optional.optionalSnowflake
import dev.kord.core.Kord
import dev.kord.core.behavior.InteractionResponseBehavior
import dev.kord.core.cache.data.MessageData
import dev.kord.core.cache.data.ReactionData
import dev.kord.core.entity.Message
import dev.kord.core.entity.interaction.Interaction
import dev.kord.core.event.Event
import dev.kord.core.event.interaction.InteractionCreateEvent
import dev.kord.core.event.message.MessageCreateEvent
import dev.kord.x.commands.argument.Argument
Expand All @@ -48,6 +52,14 @@ import mu.KotlinLogging

private val LOG = KotlinLogging.logger {}

@OptIn(KordPreview::class)
data class InteractionErrorEvent constructor(
val response: InteractionResponseBehavior,
val interaction: Interaction,
override val kord: Kord,
override val shard: Int
) : Event

@OptIn(KordPreview::class)
object InteractionEventHandler : EventHandler<InteractionCreateEvent> {
override val context: ProcessorContext<InteractionCreateEvent, MessageCreateEvent, KordCommandEvent>
Expand All @@ -59,12 +71,13 @@ object InteractionEventHandler : EventHandler<InteractionCreateEvent> {

val interaction = event.interaction

interaction.acknowledge(true)
val ack = interaction.acknowledge(true)
val errorEvent by lazy { InteractionErrorEvent(ack, interaction, event.kord, event.shard) }

val commandName = interaction.command.name
val command = getCommand(context, commandName) ?: return with(KordInteractionErrorHandler) {
notFound(
event,
errorEvent,
commandName
)
}
Expand All @@ -85,6 +98,7 @@ object InteractionEventHandler : EventHandler<InteractionCreateEvent> {
@Suppress("UNCHECKED_CAST")
val arguments =
command.arguments as List<Argument<*, MessageCreateEvent>>
val invoke by lazy { interaction.buildInvokeString() }

val result =
parseArguments(interaction.command, arguments, messageCreate)
Expand All @@ -93,8 +107,8 @@ object InteractionEventHandler : EventHandler<InteractionCreateEvent> {
is ArgumentsResult.Failure -> return with(KordInteractionErrorHandler) {
val rejection = ErrorHandler.RejectedArgument(
command,
event,
"<slash command invocation>",
errorEvent,
invoke,
result.atChar,
result.argument,
result.failure.reason
Expand All @@ -108,7 +122,7 @@ object InteractionEventHandler : EventHandler<InteractionCreateEvent> {
command.invoke(commandEvent, items)
} catch (exception: Exception) {
LOG.catching(exception)
with(KordInteractionErrorHandler) { exceptionThrown(event, command, exception) }
with(KordInteractionErrorHandler) { exceptionThrown(errorEvent, command, exception) }
}
}

Expand All @@ -118,12 +132,18 @@ object InteractionEventHandler : EventHandler<InteractionCreateEvent> {
event: MessageCreateEvent,
): ArgumentsResult<MessageCreateEvent> {
val items = mutableListOf<Any?>()
var indexTrim = 2 + command.name.length // /<command>
arguments.forEachIndexed { index, argument ->
val option = command.options[argument.name.toLowerCase()]
// each argument is prefix by " <name>:"
indexTrim += argument.name.length + 2
val argumentText =
command.options[argument.name.toLowerCase()]?.value?.toString() ?: "" // "" for optionals
option?.value?.toString()
?: "" // "" for optionals
when (val result = argument.parse(argumentText, 0, event)) {
is ArgumentResult.Success -> {
items += result.item
indexTrim += result.newIndex + 1 // space after the argument
}
is ArgumentResult.Failure -> return ArgumentsResult.Failure(
event,
Expand All @@ -132,7 +152,7 @@ object InteractionEventHandler : EventHandler<InteractionCreateEvent> {
arguments,
index,
argumentText,
result.atChar
result.atChar + indexTrim
)
}
}
Expand Down Expand Up @@ -167,3 +187,19 @@ object InteractionEventHandler : EventHandler<InteractionCreateEvent> {
return MessageCreateEvent(message, interaction.guildId, member, shard, interaction.supplier)
}
}

@OptIn(KordPreview::class)
private fun Interaction.buildInvokeString(): String {
val builder = StringBuilder("/")
builder.append(command.name) // command

val options =
command.options
.toList()
.joinToString(prefix = " ", separator = " ") { (name, value) ->
"$name: ${value.value}"
}
builder.append(options)

return builder.toString()
}
Loading

0 comments on commit 7a6f863

Please sign in to comment.