✨ Sync message to SN
This commit is contained in:
@@ -2,12 +2,14 @@ package dev.solsynth.snConnect
|
|||||||
|
|
||||||
import dev.solsynth.snConnect.commands.SnCommand
|
import dev.solsynth.snConnect.commands.SnCommand
|
||||||
import dev.solsynth.snConnect.commands.SnCommandCompleter
|
import dev.solsynth.snConnect.commands.SnCommandCompleter
|
||||||
import dev.solsynth.snConnect.models.*
|
import dev.solsynth.snConnect.listeners.SnChatListener
|
||||||
|
import dev.solsynth.snConnect.models.SnChatMessage
|
||||||
|
import dev.solsynth.snConnect.models.WebSocketPacket
|
||||||
|
import dev.solsynth.snConnect.services.SnMessageService
|
||||||
import dev.solsynth.snConnect.services.SnService
|
import dev.solsynth.snConnect.services.SnService
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import net.md_5.bungee.api.ChatColor
|
import net.md_5.bungee.api.ChatColor
|
||||||
import net.md_5.bungee.api.chat.BaseComponent
|
|
||||||
import net.md_5.bungee.api.chat.ClickEvent
|
import net.md_5.bungee.api.chat.ClickEvent
|
||||||
import net.md_5.bungee.api.chat.ComponentBuilder
|
import net.md_5.bungee.api.chat.ComponentBuilder
|
||||||
import net.md_5.bungee.api.chat.HoverEvent
|
import net.md_5.bungee.api.chat.HoverEvent
|
||||||
@@ -15,22 +17,26 @@ import net.md_5.bungee.api.chat.TextComponent
|
|||||||
import net.milkbowl.vault.economy.Economy
|
import net.milkbowl.vault.economy.Economy
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
import org.bukkit.Bukkit.getOnlinePlayers
|
import org.bukkit.Bukkit.getOnlinePlayers
|
||||||
import org.bukkit.Color
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin
|
import org.bukkit.plugin.java.JavaPlugin
|
||||||
|
|
||||||
|
|
||||||
class SolarNetworkConnect : JavaPlugin() {
|
class SolarNetworkConnect : JavaPlugin() {
|
||||||
private var economy: Economy? = null
|
private var economy: Economy? = null
|
||||||
private var sn: SnService? = null
|
private var sn: SnService? = null
|
||||||
|
private var messageService: SnMessageService? = null
|
||||||
private var syncChatRooms: List<String> = emptyList()
|
private var syncChatRooms: List<String> = emptyList()
|
||||||
|
private var destinationChatId: String? = null
|
||||||
|
|
||||||
private fun handleWebSocketPacket(packet: WebSocketPacket) {
|
private fun handleWebSocketPacket(packet: WebSocketPacket) {
|
||||||
logger.info("Received WebSocket packet: type=${packet.type}")
|
// logger.info("Received WebSocket packet: type=${packet.type}")
|
||||||
if (packet.type.startsWith("messages") && packet.data != null) {
|
if (packet.type.startsWith("messages") && packet.data != null) {
|
||||||
try {
|
try {
|
||||||
when (packet.type) {
|
when (packet.type) {
|
||||||
"messages.new" -> {
|
"messages.new" -> {
|
||||||
val message = SnChatMessage.fromJson(packet.data)
|
val message = SnChatMessage.fromJson(packet.data)
|
||||||
|
// Ignore automated accounts
|
||||||
|
if (message.sender.account.automatedId.isNullOrBlank()) return;
|
||||||
|
// Only some rooms got synced
|
||||||
if (syncChatRooms.isEmpty() || syncChatRooms.contains(message.chatRoomId)) {
|
if (syncChatRooms.isEmpty() || syncChatRooms.contains(message.chatRoomId)) {
|
||||||
val roomName = message.chatRoom.name ?: "DM"
|
val roomName = message.chatRoom.name ?: "DM"
|
||||||
val senderName = message.sender.account.nick
|
val senderName = message.sender.account.nick
|
||||||
@@ -82,6 +88,10 @@ class SolarNetworkConnect : JavaPlugin() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (messageService != null && destinationChatId != null) {
|
||||||
|
server.pluginManager.registerEvents(SnChatListener(messageService!!, destinationChatId!!), this)
|
||||||
|
}
|
||||||
|
|
||||||
Bukkit.getPluginCommand("solar")!!.setExecutor(SnCommand(this.sn!!, this.economy))
|
Bukkit.getPluginCommand("solar")!!.setExecutor(SnCommand(this.sn!!, this.economy))
|
||||||
Bukkit.getPluginCommand("solar")!!.tabCompleter = SnCommandCompleter()
|
Bukkit.getPluginCommand("solar")!!.tabCompleter = SnCommandCompleter()
|
||||||
|
|
||||||
@@ -102,9 +112,12 @@ class SolarNetworkConnect : JavaPlugin() {
|
|||||||
val clientId = config.getString("sn.client_id") ?: return false;
|
val clientId = config.getString("sn.client_id") ?: return false;
|
||||||
val clientSecret = config.getString("sn.client_secret") ?: return false;
|
val clientSecret = config.getString("sn.client_secret") ?: return false;
|
||||||
val botApiKey = config.getString("sn.bot_secret");
|
val botApiKey = config.getString("sn.bot_secret");
|
||||||
val syncRooms = config.getStringList("chat.sync_chat_rooms")
|
val destination = config.getString("chat.outgoing_room") ?: return false;
|
||||||
|
val syncRooms = config.getStringList("chat.sync_rooms")
|
||||||
syncChatRooms = syncRooms
|
syncChatRooms = syncRooms
|
||||||
|
destinationChatId = destination
|
||||||
sn = SnService(baseUrl, clientId, clientSecret, botApiKey);
|
sn = SnService(baseUrl, clientId, clientSecret, botApiKey);
|
||||||
|
messageService = SnMessageService(sn!!)
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
sn!!.connectWebSocketAsFlow().collect { packet ->
|
sn!!.connectWebSocketAsFlow().collect { packet ->
|
||||||
handleWebSocketPacket(packet)
|
handleWebSocketPacket(packet)
|
||||||
|
@@ -1,39 +0,0 @@
|
|||||||
package dev.solsynth.snConnect
|
|
||||||
|
|
||||||
import dev.solsynth.snConnect.services.SnService
|
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import kotlinx.coroutines.withTimeoutOrNull
|
|
||||||
|
|
||||||
class WebSocketTester {
|
|
||||||
companion object {
|
|
||||||
@JvmStatic
|
|
||||||
fun main(args: Array<String>) {
|
|
||||||
if (args.size < 4) {
|
|
||||||
println("Usage: WebSocketTester <baseUrl> <clientId> <clientSecret> <botApiKey>")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val baseUrl = args[0]
|
|
||||||
val clientId = args[1]
|
|
||||||
val clientSecret = args[2]
|
|
||||||
val botApiKey = if (args[3] == "null") null else args[3]
|
|
||||||
|
|
||||||
runBlocking {
|
|
||||||
val service = SnService(baseUrl, clientId, clientSecret, botApiKey)
|
|
||||||
println("Starting WebSocket test for $baseUrl")
|
|
||||||
|
|
||||||
val result = withTimeoutOrNull(30000L) { // 30 seconds timeout
|
|
||||||
service.connectWebSocketAsFlow().collect { packet ->
|
|
||||||
println("Received packet: type=${packet.type}, endpoint=${packet.endpoint}, data=${packet.data}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == null) {
|
|
||||||
println("WebSocket test timed out")
|
|
||||||
} else {
|
|
||||||
println("WebSocket test completed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,29 @@
|
|||||||
|
package dev.solsynth.snConnect.listeners
|
||||||
|
|
||||||
|
import dev.solsynth.snConnect.services.SnMessageService
|
||||||
|
import org.bukkit.event.EventHandler
|
||||||
|
import org.bukkit.event.Listener
|
||||||
|
import org.bukkit.event.player.AsyncPlayerChatEvent
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent
|
||||||
|
|
||||||
|
class SnChatListener(private val messageService: SnMessageService, private val destinationChatId: String) : Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun onPlayerChat(event: AsyncPlayerChatEvent) {
|
||||||
|
val message = "${event.player.name}: ${event.message}"
|
||||||
|
messageService.sendMessage(destinationChatId, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun onPlayerJoin(event: PlayerJoinEvent) {
|
||||||
|
val message = "${event.player.name} joined the game."
|
||||||
|
messageService.sendMessage(destinationChatId, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun onPlayerQuit(event: PlayerQuitEvent) {
|
||||||
|
val message = "${event.player.name} left the game."
|
||||||
|
messageService.sendMessage(destinationChatId, message)
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,40 @@
|
|||||||
|
package dev.solsynth.snConnect.services
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
|
import java.io.IOException
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SnMessageRequest(
|
||||||
|
val content: String,
|
||||||
|
val nonce: String
|
||||||
|
)
|
||||||
|
|
||||||
|
class SnMessageService(private val sn: SnService) {
|
||||||
|
private val json = Json {
|
||||||
|
ignoreUnknownKeys = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sendMessage(chatRoomId: String, content: String) {
|
||||||
|
val body = SnMessageRequest(content, UUID.randomUUID().toString())
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url(sn.getUrl("sphere", "/chat/$chatRoomId/messages"))
|
||||||
|
.post(json.encodeToString(body).toRequestBody("application/json".toMediaTypeOrNull()))
|
||||||
|
.apply {
|
||||||
|
sn.botApiKey?.let { header("Authorization", "Bearer $it") }
|
||||||
|
}
|
||||||
|
.build()
|
||||||
|
|
||||||
|
sn.client.newCall(request).execute().use { response ->
|
||||||
|
if (!response.isSuccessful) {
|
||||||
|
val responseBody = response.body?.string() ?: "No body"
|
||||||
|
throw IOException("Unexpected code $response: $responseBody")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -12,7 +12,7 @@ import okhttp3.Response
|
|||||||
import okio.ByteString
|
import okio.ByteString
|
||||||
import java.util.logging.Logger
|
import java.util.logging.Logger
|
||||||
|
|
||||||
class SnService(private val baseUrl: String, val clientId: String, val clientSecret: String, private val botApiKey: String?) {
|
class SnService(private val baseUrl: String, val clientId: String, val clientSecret: String, val botApiKey: String?) {
|
||||||
val client = OkHttpClient.Builder().build();
|
val client = OkHttpClient.Builder().build();
|
||||||
private val logger = Logger.getLogger(SnService::class.java.name)
|
private val logger = Logger.getLogger(SnService::class.java.name)
|
||||||
|
|
||||||
|
@@ -1,4 +1,9 @@
|
|||||||
sn:
|
sn:
|
||||||
endpoint: https://api.sn.solsynth.dev
|
endpoint: https://api.solian.app
|
||||||
client_id: highland-mc
|
client_id: goatcraft
|
||||||
client_secret: 12345678
|
client_secret: 12345678
|
||||||
|
bot_secret: 114.514.19198
|
||||||
|
destination_chat_id: some_chat_id
|
||||||
|
chat:
|
||||||
|
sync_rooms: []
|
||||||
|
outgoing_room: 00000000-0000-0000-0000-00000000008b
|
||||||
|
Reference in New Issue
Block a user