basic 2-way communication
This commit is contained in:
parent
51d1f14cd8
commit
4820ac5e04
44
pom.xml
44
pom.xml
|
@ -14,6 +14,7 @@
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>17</java.version>
|
<java.version>17</java.version>
|
||||||
<kotlin.version>2.1.20-Beta2</kotlin.version>
|
<kotlin.version>2.1.20-Beta2</kotlin.version>
|
||||||
|
<serialization.version>1.8.0</serialization.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
@ -21,6 +22,42 @@
|
||||||
<defaultGoal>clean package</defaultGoal>
|
<defaultGoal>clean package</defaultGoal>
|
||||||
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
|
<version>1.8</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-plugin</id>
|
||||||
|
<phase>install</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>run</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<target>
|
||||||
|
<copy file="${project.build.directory}/${project.build.finalName}.jar"
|
||||||
|
todir="/home/leca/Downloads/test-server/plugins"/>
|
||||||
|
</target>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<!-- <plugin>-->
|
||||||
|
<!-- <groupId>org.apache.maven.plugins</groupId>-->
|
||||||
|
<!-- <artifactId>maven-shade-plugin</artifactId>-->
|
||||||
|
<!-- <version>3.2.4</version> <!– Use the latest version –>-->
|
||||||
|
<!-- <executions>-->
|
||||||
|
<!-- <execution>-->
|
||||||
|
<!-- <phase>package</phase>-->
|
||||||
|
<!-- <goals>-->
|
||||||
|
<!-- <goal>shade</goal>-->
|
||||||
|
<!-- </goals>-->
|
||||||
|
<!-- <configuration>-->
|
||||||
|
<!-- <createDependencyReducedPom>false</createDependencyReducedPom>-->
|
||||||
|
<!-- </configuration>-->
|
||||||
|
<!-- </execution>-->
|
||||||
|
<!-- </executions>-->
|
||||||
|
<!-- </plugin>-->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
<artifactId>kotlin-maven-plugin</artifactId>
|
<artifactId>kotlin-maven-plugin</artifactId>
|
||||||
|
@ -83,5 +120,12 @@
|
||||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||||
<version>${kotlin.version}</version>
|
<version>${kotlin.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.kafka</groupId>
|
||||||
|
<artifactId>kafka-clients</artifactId>
|
||||||
|
<version>3.9.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
package org.foxarmy.chatProxy
|
package org.foxarmy.chatProxy
|
||||||
|
|
||||||
class ChatListener {
|
import com.google.gson.Gson
|
||||||
|
import org.bukkit.event.EventHandler
|
||||||
|
import org.bukkit.event.Listener
|
||||||
|
import org.bukkit.event.player.AsyncPlayerChatEvent
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
class ChatListener(private val kafkaClient: KafkaClient) : Listener{
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun onChat(event: AsyncPlayerChatEvent) {
|
||||||
|
val player = event.player
|
||||||
|
val message = event.message
|
||||||
|
val timestamp = Instant.now().epochSecond
|
||||||
|
|
||||||
|
val data = MessageJson(player.name, message, "server", timestamp)
|
||||||
|
val gson = Gson()
|
||||||
|
val gsonData = gson.toJson(data)
|
||||||
|
|
||||||
|
kafkaClient.sendData(gsonData)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -5,7 +5,15 @@ import org.bukkit.plugin.java.JavaPlugin
|
||||||
class ChatProxy : JavaPlugin() {
|
class ChatProxy : JavaPlugin() {
|
||||||
|
|
||||||
override fun onEnable() {
|
override fun onEnable() {
|
||||||
// Plugin startup logic
|
saveDefaultConfig()
|
||||||
|
reloadConfig()
|
||||||
|
val kafkaClient = KafkaClient(this, config.getStringList("kafkaBrokers"))
|
||||||
|
server.pluginManager.registerEvents(ChatListener(kafkaClient), this)
|
||||||
|
|
||||||
|
this.getCommand("chatproxy")?.setExecutor(Commands(this))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDisable() {
|
override fun onDisable() {
|
||||||
|
|
|
@ -1,4 +1,35 @@
|
||||||
package org.foxarmy.chatProxy
|
package org.foxarmy.chatProxy
|
||||||
|
|
||||||
class Commands {
|
import org.bukkit.command.Command
|
||||||
|
import org.bukkit.command.CommandExecutor
|
||||||
|
import org.bukkit.command.CommandSender
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class Commands(private val plugin: JavaPlugin) : CommandExecutor {
|
||||||
|
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
|
||||||
|
if (!sender.hasPermission("chatproxy.use")) {
|
||||||
|
sender.sendMessage("You do not have permission to use this command.")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (args.isEmpty()) {
|
||||||
|
sender.sendMessage("Usage: /chatproxy <subcommand>")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
when (args[0].lowercase(Locale.getDefault())) {
|
||||||
|
"reload" -> {
|
||||||
|
reloadConfig(sender)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
sender.sendMessage("Unknown subcommand. Usage: /chatproxy <reload>")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private fun reloadConfig(sender: CommandSender) {
|
||||||
|
plugin.reloadConfig()
|
||||||
|
sender.sendMessage("Configuration reloaded successfully.")
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,60 @@
|
||||||
package org.foxarmy.chatProxy
|
package org.foxarmy.chatProxy
|
||||||
|
|
||||||
class KafkaClient {
|
import com.google.gson.Gson
|
||||||
|
import org.apache.kafka.clients.consumer.Consumer
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecord
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecords
|
||||||
|
import org.apache.kafka.clients.consumer.KafkaConsumer
|
||||||
|
import org.apache.kafka.clients.producer.KafkaProducer
|
||||||
|
import org.apache.kafka.clients.producer.Producer
|
||||||
|
import org.apache.kafka.clients.producer.ProducerRecord
|
||||||
|
import org.apache.kafka.common.serialization.StringDeserializer
|
||||||
|
import org.apache.kafka.common.serialization.StringSerializer
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.player.AsyncPlayerChatEvent
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin
|
||||||
|
import java.time.Duration
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class KafkaClient(plugin: JavaPlugin, brokers: List<String>) {
|
||||||
|
private val consumer: Consumer<String, String>
|
||||||
|
private val producer: Producer<String, String>
|
||||||
|
|
||||||
|
init {
|
||||||
|
Thread.currentThread().contextClassLoader = null;
|
||||||
|
val props = Properties()
|
||||||
|
|
||||||
|
props["bootstrap.servers"] = brokers
|
||||||
|
props["group.id"] = "chat-listener"
|
||||||
|
props["key.deserializer"] = StringDeserializer::class.java.name
|
||||||
|
props["value.deserializer"] = StringDeserializer::class.java.name
|
||||||
|
props["key.serializer"] = StringSerializer::class.java.canonicalName
|
||||||
|
props["value.serializer"] = StringSerializer::class.java.canonicalName
|
||||||
|
|
||||||
|
producer = KafkaProducer<String, String>(props)
|
||||||
|
consumer = KafkaConsumer<String, String>(props)
|
||||||
|
|
||||||
|
consumer.subscribe(listOf("chatMessage"))
|
||||||
|
listenForMessages(plugin)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun listenForMessages(plugin: JavaPlugin) {
|
||||||
|
Bukkit.getScheduler().runTaskTimer(
|
||||||
|
plugin, Runnable {
|
||||||
|
val records: ConsumerRecords<String, String> = consumer.poll(Duration.ofMillis(100))
|
||||||
|
for (record: ConsumerRecord<String, String> in records) {
|
||||||
|
val recordJSON = Gson().fromJson(record.value(), MessageJson::class.java)
|
||||||
|
if (recordJSON.origin == "server") continue
|
||||||
|
Bukkit.broadcastMessage("<${recordJSON.author}> ${recordJSON.content}")
|
||||||
|
recordJSON.origin = "server"
|
||||||
|
sendData(recordJSON.toString())
|
||||||
|
}
|
||||||
|
}, 0L, 20L
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sendData(data: String) {
|
||||||
|
val futureResult = producer.send(ProducerRecord<String, String>("chatMessage", data))
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
package org.foxarmy.chatProxy
|
package org.foxarmy.chatProxy
|
||||||
|
|
||||||
class MessageJson {
|
data class MessageJson(val author: String, val content: String, var origin: String, val timestamp: Long)
|
||||||
}
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
kafkaBrokers:
|
||||||
|
- localhost:9092
|
||||||
|
- kafka:9092
|
|
@ -6,3 +6,15 @@ prefix: Chatproxy
|
||||||
authors: [ leca ]
|
authors: [ leca ]
|
||||||
description: Plugin for proxying chat messages from mc server to site
|
description: Plugin for proxying chat messages from mc server to site
|
||||||
website: https://git.foxarmy.org/leca/Chatproxy
|
website: https://git.foxarmy.org/leca/Chatproxy
|
||||||
|
commands:
|
||||||
|
chatproxy:
|
||||||
|
description: Chat proxy commands
|
||||||
|
usage: /<command> <subcommand>
|
||||||
|
aliases: [ cprox ]
|
||||||
|
permission: chatproxy.use
|
||||||
|
permission-message: You do not have permission to use this command.
|
||||||
|
reload:
|
||||||
|
description: Reload plugin's configuration
|
||||||
|
usage: /<command> reload
|
||||||
|
permission: chatproxy.reload
|
||||||
|
permission-message: You do not have permission to reload configuration.
|
Loading…
Reference in New Issue