Giter Site home page Giter Site logo

devsrsouza / kotlinbukkitapi Goto Github PK

View Code? Open in Web Editor NEW
154.0 154.0 20.0 896 KB

KotlinBukkitAPI is an API for Bukkit/SpigotAPI using the cool and nifty features Kotlin has to make your life more easier.

License: MIT License

Kotlin 100.00%
bukkit dsl kotlin minecraft spigot

kotlinbukkitapi's People

Contributors

devnatan avatar devsrsouza avatar mrpowergamerbr avatar smallshen avatar tomocrafter avatar winx64 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kotlinbukkitapi's Issues

Pagination documentation?

I want to try it but I had no clue, here's what I've written:

menu(+"Main Page", 3, true) {
	val list = (1..100).toMutableList().asObservable()
	val prev = slot(3, 1, item(Material.DIAMOND_SWORD).displayName("Previous Page")) {}
	val next = slot(3, 9, item(Material.GOLD_INGOT).displayName(+"Next Page")) {}

	list.observe {
		logger.info(it.toString())
	}

	pagination(list, prev, next) {}
	openToPlayer(sender)
}

Suppose we have a situation that we want to write a pagination to list past players recorded in the database and check their criminal records (bruh) and stuff, how do you know which player did you clicked in the menu? Also, is it possible we can use fragment frames like in Android so that we can compose the menu from different smaller pieces?

[Commands] add support for handling exceptions

Description

If the command executor throws an error, executors will not run anymore due to the coroutineScope being canceled.

Proposal

I propose that you should catch the executor block and have an exception handler for the command that is also used by its children and have a default exception handler, something like Bukkit's "An internal error occurred whilst executing this command".

Command Arguments material()

in Command Arguments, there is a material() function to get material

it would be better to change all letter to uppercase when checking, due to all materials in Material enum is uppercase, and I think forName() method is case sensitive.

for example:
"/mycommand air" doesn't work, but "/mycommand AIR" works

Location serialization does not work

Stacktrace

java.lang.IllegalStateException: Must call beginStructure() and use returned Decoder
	at com.charleskorn.kaml.YamlContextualInput.decodeValue(YamlInput.kt:279) ~[?:?]
	at kotlinx.serialization.encoding.AbstractDecoder.decodeString(AbstractDecoder.kt:41) ~[?:?]
	at com.charleskorn.kaml.YamlMapLikeInputBase$decodeString$1.invoke(YamlInput.kt:300) ~[?:?]
	at com.charleskorn.kaml.YamlMapLikeInputBase$decodeString$1.invoke(YamlInput.kt:287) ~[?:?]
	at com.charleskorn.kaml.YamlMapLikeInputBase.fromCurrentValue(YamlInput.kt:313) ~[?:?]
	at com.charleskorn.kaml.YamlMapLikeInputBase.decodeString(YamlInput.kt:300) ~[?:?]
	at br.com.devsrsouza.kotlinbukkitapi.serialization.serializers.LocationSerializer.deserialize(LocationSerializer.kt:20) ~[?:?]
	at br.com.devsrsouza.kotlinbukkitapi.serialization.serializers.LocationSerializer.deserialize(LocationSerializer.kt:13) ~[?:?]

Repository conflicts with paperweight

I use paperweight to get paper api + nms, but when I add http://nexus.devsrsouza.com.br/repository/maven-public/ repository, paperweight can't find minecraft on his own repo

Support Coroutines Flow in Menu DSL

The Menu DSL should support Coroutines Flow.

For slots could be something like this:

val stateFlow: StateFlow<ItemStack>

slot(1, 5, null) {
  onRender {
     showingItem = stateFlow.value
  }
  onFlowChange(stateFlow) { value ->
    showingItem = value
    player.msg("Hi!")
  }
}

EventDSL problem

Please fix this

[14:12:54 ERROR]: Could not pass event CreatureSpawnEvent to HappySpawners v1.0.0
java.lang.ClassCastException: org.bukkit.event.entity.CreatureSpawnEvent cannot be cast to org.bukkit.event.entity.SpawnerSpawnEvent
        at me.devnatan.happymc.spawners.HappySpawners$listener$1$$special$$inlined$event$4.execute(EventDSL.kt:20) ~[?:?]

Support invoke

There is a operator fun called "invoke"

after simply adding

operator fun <T> T.invoke(block : T.() -> Unit) : T {
    return this.apply(block)
}

could achieve

player {
    displayName = "name"
    msg("message")
    etc...
}
sender {
    msg("anything")
}
event<PlayerMoveEvent> {
    isCancelled = true
    player {
        msg("You can move yet")
        etc...
    }
}

makes code cleaner, get rid of with(player) or player.apply { }

it works for anything after that three lines but might effect some classes that already have invoke fun

val component = ComponentBuilder()
component {
    append("wow")
    etc...
}

it looks like the component in net.md_5.bungee.api.chat.ComponentBuilder having a dsl support but actually no

Integration into server Jar File

Is that possible to write KotlinBukkitAPI classes into Spigot or paper's server Jar file. That would be easier for people who widely use this plugin, so they don't need copy plugin file to plugins folder.

Possible to support BungeeCord

Is that Possible to have a BungeeCord Support
That would be useful too.

Also please have documents on exposed cause that is a bit complex

Incompatibility with Java 16

[12:34:02] [Thread-11/ERROR]: [KotlinBukkitAPI] Could not download Artifact{groupId='org.jetbrains.kotlin', artifactId='kotlin-stdlib', version='1.4.0', repoBaseURL='maven'}
java.util.concurrent.CompletionException: java.lang.NoClassDefFoundError: Could not initialize class me.bristermitten.pdm.util.ClassLoaderReflection
	at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:314) ~[?:?]
	at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:319) ~[?:?]
	at java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:718) ~[?:?]
	at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506) ~[?:?]
	at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1769) ~[?:?]
	at java.lang.Thread.run(Thread.java:831) [?:?]
Caused by: java.lang.NoClassDefFoundError: Could not initialize class me.bristermitten.pdm.util.ClassLoaderReflection
	at me.bristermitten.pdm.DependencyLoader.loadDependency(DependencyLoader.java:46) ~[?:?]
	at java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:714) ~[?:?]
	... 3 more
[12:34:02] [Thread-8/ERROR]: [KotlinBukkitAPI] Could not download Artifact{groupId='org.jetbrains.kotlinx', artifactId='kotlinx-coroutines-core', version='1.3.9', repoBaseURL='maven'}
java.util.concurrent.CompletionException: java.lang.NoClassDefFoundError: Could not initialize class me.bristermitten.pdm.util.ClassLoaderReflection
	at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:314) ~[?:?]
	at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:319) ~[?:?]
	at java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:718) ~[?:?]
	at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506) ~[?:?]
	at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1769) ~[?:?]
	at java.lang.Thread.run(Thread.java:831) [?:?]
Caused by: java.lang.NoClassDefFoundError: Could not initialize class me.bristermitten.pdm.util.ClassLoaderReflection
	at me.bristermitten.pdm.DependencyLoader.loadDependency(DependencyLoader.java:46) ~[?:?]
	at java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:714) ~[?:?]
	... 3 more
[12:34:02] [Server thread/ERROR]: Could not load 'plugins/KotlinBukkitAPI-0.2.0-SNAPSHOT-b131.jar' in folder 'plugins'
org.bukkit.plugin.InvalidPluginException: java.util.concurrent.CompletionException: java.lang.NoClassDefFoundError: Could not initialize class me.bristermitten.pdm.util.ClassLoaderReflection
	at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:151) ~[patched_1.16.5.jar:git-Paper-683]
	at org.bukkit.plugin.SimplePluginManager.loadPlugin(SimplePluginManager.java:397) ~[patched_1.16.5.jar:git-Paper-683]
	at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:305) ~[patched_1.16.5.jar:git-Paper-683]
	at org.bukkit.craftbukkit.v1_16_R3.CraftServer.loadPlugins(CraftServer.java:389) ~[patched_1.16.5.jar:git-Paper-683]
	at net.minecraft.server.v1_16_R3.DedicatedServer.init(DedicatedServer.java:252) ~[patched_1.16.5.jar:git-Paper-683]
	at net.minecraft.server.v1_16_R3.MinecraftServer.w(MinecraftServer.java:1066) ~[patched_1.16.5.jar:git-Paper-683]
	at net.minecraft.server.v1_16_R3.MinecraftServer.lambda$a$0(MinecraftServer.java:290) ~[patched_1.16.5.jar:git-Paper-683]
	at java.lang.Thread.run(Thread.java:831) [?:?]
Caused by: java.util.concurrent.CompletionException: java.lang.NoClassDefFoundError: Could not initialize class me.bristermitten.pdm.util.ClassLoaderReflection
	at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:314) ~[?:?]
	at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:319) ~[?:?]
	at java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:718) ~[?:?]
	at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506) ~[?:?]
	at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1769) ~[?:?]
	... 1 more
Caused by: java.lang.NoClassDefFoundError: Could not initialize class me.bristermitten.pdm.util.ClassLoaderReflection
	at me.bristermitten.pdm.DependencyLoader.loadDependency(DependencyLoader.java:46) ~[?:?]
	at java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:714) ~[?:?]
	at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506) ~[?:?]
	at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1769) ~[?:?]
	... 1 more

Could be on my end, however I've only observed this happening while on Java 16. I'm aware that a big part of the API is to keep it compatible with 1.8 and similar versions but it'd be nice if it was compatible with Java 16 as well, if possible.

eventFlow causing listeners to be unregistered

Hi, I am new to Kotlin and the KotlinBukkitAPI, so it's entirely possible this issue is being caused by a misunderstanding of Kotlin or this API. I am not new to Java or Spigot plugins, and have been working with them for a few years now.

I have a plugin that registers listeners during the LifecycleEvent.ENABLE phase, namely:

events {
    event<EntityPortalEnterEvent> {
        logger.info("Hello from EntityPortalEnterEvent!")
    }
    event<PlayerPortalEvent> {
        // [... some code...]
        pluginCoroutineScope.launch {
            val changedWorldEvent = withTimeoutOrNull(5000) {
                eventFlow<PlayerChangedWorldEvent>(priority = EventPriority.HIGHEST)
                    .filter { it.player == player }
                    .onEach { delay(1000) }
                    .first()
            } ?: return@launch
            // [... do some stuff with changedWorldEvent...]
            // [ !!! ]
        }
    }
}

Here's my problem: every time the eventFlow finishes and the code reaches the [ !!! ], every listener in my plugin is unregistered, and I don't know why. If I comment out the eventFlow code, the listeners are NOT unregistered.

I confirmed this by creating a command:

command("spl") {
    executor {
        EntityPortalEnterEvent.getHandlerList().registeredListeners.forEach { sender.sendMessage("L: $it") }
    }
}

Executing this command before going through a portal correctly returns 1 registered listener for the EntityPortalEnterEvent. Then after I go through a portal and trigger the PlayerPortalEvent and eventFlow, the command returns nothing, meaning the listener was unregistered.

Any help would be appreciated.

Continuous kotlin.jvm.KotlinReflectionNotSupportedError

Log message:

[15:56:42 ERROR]: Could not pass event PlayerMoveEvent to KotlinBukkitAPI v0.1.0-SNAPSHOT
kotlin.jvm.KotlinReflectionNotSupportedError: Kotlin reflection implementation is not found at runtime. Make sure you have kotlin-reflect.jar in the classpath
        at kotlin.jvm.internal.ClassReference.error(ClassReference.kt:79) ~[?:?]
        at kotlin.jvm.internal.ClassReference.isInstance(ClassReference.kt:33) ~[?:?]
        at kotlin.reflect.full.KClasses.safeCast(KClasses.kt:269) ~[?:?]
        at br.com.devsrsouza.kotlinbukkitapi.controllers.PlayerController$onEnable$$inlined$event$2.execute(ExEvent.kt:27) ~[?:?]
        at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80) ~[patched_1.15.2.jar:git-Paper-155]
        at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70) ~[patched_1.15.2.jar:git-Paper-155]
        at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:607) ~[patched_1.15.2.jar:git-Paper-155]
        at net.minecraft.server.v1_15_R1.PlayerConnection.a(PlayerConnection.java:1115) ~[patched_1.15.2.jar:git-Paper-155]
        at net.minecraft.server.v1_15_R1.PacketPlayInFlying.a(SourceFile:122) ~[patched_1.15.2.jar:git-Paper-155]
        at net.minecraft.server.v1_15_R1.PacketPlayInFlying$PacketPlayInPositionLook.a(SourceFile:18) ~[patched_1.15.2.jar:git-Paper-155]
        at net.minecraft.server.v1_15_R1.PlayerConnectionUtils.lambda$ensureMainThread$0(PlayerConnectionUtils.java:23) ~[patched_1.15.2.jar:git-Paper-155]
        at net.minecraft.server.v1_15_R1.TickTask.run(SourceFile:18) ~[patched_1.15.2.jar:git-Paper-155]
        at net.minecraft.server.v1_15_R1.IAsyncTaskHandler.executeTask(IAsyncTaskHandler.java:136) ~[patched_1.15.2.jar:git-Paper-155]
        at net.minecraft.server.v1_15_R1.IAsyncTaskHandlerReentrant.executeTask(SourceFile:23) ~[patched_1.15.2.jar:git-Paper-155]
        at net.minecraft.server.v1_15_R1.IAsyncTaskHandler.executeNext(IAsyncTaskHandler.java:109) ~[patched_1.15.2.jar:git-Paper-155]
        at net.minecraft.server.v1_15_R1.MinecraftServer.ba(MinecraftServer.java:1038) ~[patched_1.15.2.jar:git-Paper-155]
        at net.minecraft.server.v1_15_R1.MinecraftServer.executeNext(MinecraftServer.java:1031) ~[patched_1.15.2.jar:git-Paper-155]
        at net.minecraft.server.v1_15_R1.IAsyncTaskHandler.awaitTasks(IAsyncTaskHandler.java:119) ~[patched_1.15.2.jar:git-Paper-155]
        at net.minecraft.server.v1_15_R1.MinecraftServer.sleepForTick(MinecraftServer.java:1015) ~[patched_1.15.2.jar:git-Paper-155]
        at net.minecraft.server.v1_15_R1.MinecraftServer.run(MinecraftServer.java:938) ~[patched_1.15.2.jar:git-Paper-155]
        at java.lang.Thread.run(Unknown Source) [?:1.8.0_241]

build.gradle

plugins {
    id 'java'
    id 'org.jetbrains.kotlin.jvm' version '1.3.71'
    id 'kr.entree.spigradle' version '1.2.3'
}

group 'org.example'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
    maven { url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") }
    maven { url = 'https://oss.sonatype.org/content/repositories/snapshots' }
    maven {
        name = "KotlinBukkitAPI"
        url = "http://nexus.devsrsouza.com.br/repository/maven-public/"
    }
    jitpack() // For vault
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    testCompile group: 'junit', name: 'junit', version: '4.12'
    implementation "org.jetbrains.kotlin:kotlin-reflect"

    compileOnly spigot()
    compileOnly vault()
    compileOnly("br.com.devsrsouza.kotlinbukkitapi:core:0.1.0-SNAPSHOT") // core
}

spigot {
    ...
    apiVersion = '1.15'
    load = POST_WORLD
    depends = ['KotlinBukkitAPI'...]
    ...
}

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

Events Snippet:

events {
     if (config.getBoolean("drops.player-head.enable", true))
        event<PlayerDeathEvent> {
            val player = this.entity
            this.drops.add(item(Material.PLAYER_HEAD).meta<SkullMeta> { owningPlayer = player })
        }
}

Outdated Bukkit API

Any reason why Bukkit API is very outdated in this project? I think it should be latest version, but I guess there's valid reason for it being outdated. If it isn't intentional, I could PR version bump for it.

All server listeners being unregistered.

What happened

I've recently been testing my server systems using KotlinBukkitAPI. And I noticed that every time I logged into the server, the events worked.
But if I tried to do the exact same process I did for this event, it did not work.

I used this to test:

events {
    event<PlayerJoinEvent> {
        player.sendMessage("joined, KotlinBukkitAPI")
    }
}

Bukkit.getServer().pluginManager.registerEvents(object: Listener {
    @EventHandler
    fun on(e: PlayerJoinEvent) {
        e.player.sendMessage("joined, PluginManager")
    }
}, this)

I turned and they both worked, the two messages disappeared. But when I left the server and entered again, nothing happened.
And then I started looking for the problem, and I found it.

The problem

It is located in this class:

interface OnlinePlayerCollection : MutableCollection<Player>, KListener<Plugin> {

More specifically in this line:

The unregisterAll() method is called, correctly, but its reference is not correct.
The unregisterAll() that should be called is that of br.com.devsrsouza.kotlinbukkitapi.extensions, and what is being called is the org.bukkit.event.HandlerList#unregisterAll.

Solution

This is resolved by adding the correct import br.com.devsrsouza.kotlinbukkitapi.extensions.unregisterAll to the file.

Please resolve this as soon as possible because KotlinBukkitAPI, with this, is unusable.

Expose vendor as separate plugin too

Hi, I also package my own Kotlin runtime (in fact an entire classpath plugin to store all vendor code) and there's some kind of discrepancy with my Coroutine too. I used a newer version of Kotlinx.coroutine and I saw an error on the console [02:36:10 WARN]: [stevefan1999-proto] Loaded class kotlin.coroutines.Continuation from KotlinBukkitAPI v0.1.0-SNAPSHOT which is not a depend, softdepend or loadbefore of this plugin. which means we are mixing class loaders.

This is not good as it means some vague error such as apparent-from-same-package-but-actually-cross-class-loader thingy will occur. So I suggest isolating all vendor code (e.g. Kotlin, Kotlinx, Exposed) also into a depend/softdepend?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.