basic 2-way communication
This commit is contained in:
parent
51d1f14cd8
commit
4820ac5e04
44
pom.xml
44
pom.xml
|
@ -14,6 +14,7 @@
|
|||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<kotlin.version>2.1.20-Beta2</kotlin.version>
|
||||
<serialization.version>1.8.0</serialization.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
|
@ -21,6 +22,42 @@
|
|||
<defaultGoal>clean package</defaultGoal>
|
||||
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
||||
<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>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
|
@ -83,5 +120,12 @@
|
|||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</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>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -1,4 +1,25 @@
|
|||
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() {
|
||||
|
||||
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() {
|
||||
|
|
|
@ -1,4 +1,35 @@
|
|||
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
|
||||
|
||||
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
|
||||
|
||||
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 ]
|
||||
description: Plugin for proxying chat messages from mc server to site
|
||||
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