From eb571a9c8ab30da11399899a3675a56ae4dfd1c1 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Sun, 17 Mar 2024 18:26:40 +0200 Subject: [PATCH 01/19] Added a Redis system that lets you do the following things: - Publish messages to specific channels Async/Sync. - Listen to incoming messages from any specific channels. - Connect Also added Env support, unsure if it works. --- build.gradle.kts | 2 + src/main/kotlin/gg/flyte/twilight/Twilight.kt | 8 +++ .../kotlin/gg/flyte/twilight/redis/Redis.kt | 60 +++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 src/main/kotlin/gg/flyte/twilight/redis/Redis.kt diff --git a/build.gradle.kts b/build.gradle.kts index 8c659e8..ddcedd5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -27,6 +27,8 @@ dependencies { api("io.github.cdimascio:dotenv-kotlin:6.4.1") api("org.mongodb:mongodb-driver-kotlin-sync:4.11.0") api("com.google.code.gson:gson:2.10.1") + api("redis.clients:jedis:5.1.2") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0-RC2") implementation(kotlin("reflect")) diff --git a/src/main/kotlin/gg/flyte/twilight/Twilight.kt b/src/main/kotlin/gg/flyte/twilight/Twilight.kt index 7805db4..45225fa 100644 --- a/src/main/kotlin/gg/flyte/twilight/Twilight.kt +++ b/src/main/kotlin/gg/flyte/twilight/Twilight.kt @@ -7,7 +7,9 @@ import gg.flyte.twilight.environment.Environment import gg.flyte.twilight.event.custom.chat.command.ChatClickCommand import gg.flyte.twilight.event.customEventListeners import gg.flyte.twilight.extension.applyForEach +import gg.flyte.twilight.redis.Redis import gg.flyte.twilight.server.ServerSoftware +import org.bukkit.Material import org.bukkit.plugin.java.JavaPlugin class Twilight(javaPlugin: JavaPlugin) { @@ -40,9 +42,15 @@ class Twilight(javaPlugin: JavaPlugin) { fun mongo(init: MongoDB.Settings.() -> Unit = {}) = MongoDB.mongo(MongoDB.Settings().apply(init)) + fun redis(init: Redis.Settings.() -> Unit = {}) = Redis.redis(Redis.Settings().apply(init)) + fun nameCache(init: NameCacheService.Settings.() -> Unit = {}) = NameCacheService.nameCache(NameCacheService.Settings().apply(init)) fun terminate() = customEventListeners.applyForEach { unregister() } } +fun hello(){ + val builder = ItemBuilder(Material.DIAMOND_SWORD) +} + fun twilight(plugin: JavaPlugin, init: Twilight.() -> Unit = {}): Twilight = Twilight(plugin).apply(init) diff --git a/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt b/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt new file mode 100644 index 0000000..bee0070 --- /dev/null +++ b/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt @@ -0,0 +1,60 @@ +package gg.flyte.twilight.redis + +import gg.flyte.twilight.Twilight +import gg.flyte.twilight.environment.Environment +import redis.clients.jedis.Jedis +import redis.clients.jedis.JedisPubSub +import java.util.concurrent.CompletableFuture +import java.util.concurrent.Executor +import java.util.concurrent.Executors + +object Redis { + private lateinit var jedis: Jedis + private val executor: Executor = Executors.newCachedThreadPool() + + fun redis(redis: Settings){ + jedis = Jedis(redis.host, redis.port, redis.timeout) + } + + fun publishSync(channel: String, message: String){ + jedis.publish(channel, message) + } + + fun publish(channel: String, message: String) = CompletableFuture.supplyAsync({ publishSync(channel, message) }, executor) + + class Settings { + var host: String = if (Twilight.usingEnv) Environment.get("REDIS_HOST") else "localhost" + var port: Int = if (Twilight.usingEnv) Environment.get("REDIS_PORT").toInt() else 6379 + var timeout: Int = if (Twilight.usingEnv) Environment.get("REDIS_TIMEOUT").toInt() else 0 + } + + fun addListener(listener: TwilightRedisListener) = jedis.subscribe(listener, listener.channel) + fun addListener(channel: String, block: RedisMessage.() -> Unit) = jedis.subscribe(RedisListener(channel, block), channel) + +} + +data class RedisMessage(val channel: String, val message: String) + +abstract class TwilightRedisListener(val channel: String) : JedisPubSub() { + + override fun onMessage(channel: String?, message: String?) { + channel ?: return + message?: return + if (channel == this.channel) onMessage(message) + } + + abstract fun onMessage(message: String) + +} + +class RedisListener(channel: String, val block: RedisMessage.() -> Unit): TwilightRedisListener(channel) { + + override fun onMessage(message: String) { + block(RedisMessage(channel, message)) + } + +} + + + + From 574b26f12b914d743c07dae871d2c3851e1654e1 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Sun, 17 Mar 2024 18:34:59 +0200 Subject: [PATCH 02/19] Added a Redis system that lets you do the following things: - Publish messages to specific channels Async/Sync. - Listen to incoming messages from any specific channels. - Connect Also added Env support, unsure if it works. --- src/main/kotlin/gg/flyte/twilight/Twilight.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/kotlin/gg/flyte/twilight/Twilight.kt b/src/main/kotlin/gg/flyte/twilight/Twilight.kt index 45225fa..11bfbf3 100644 --- a/src/main/kotlin/gg/flyte/twilight/Twilight.kt +++ b/src/main/kotlin/gg/flyte/twilight/Twilight.kt @@ -49,8 +49,5 @@ class Twilight(javaPlugin: JavaPlugin) { fun terminate() = customEventListeners.applyForEach { unregister() } } -fun hello(){ - val builder = ItemBuilder(Material.DIAMOND_SWORD) -} fun twilight(plugin: JavaPlugin, init: Twilight.() -> Unit = {}): Twilight = Twilight(plugin).apply(init) From 6f7b523c832a3c1820ce3e9faa04cd6fd0338f1e Mon Sep 17 00:00:00 2001 From: BuildTools Date: Sun, 17 Mar 2024 18:48:18 +0200 Subject: [PATCH 03/19] Fixed a small issue, made the sync publish method private in Redis --- src/main/kotlin/gg/flyte/twilight/Twilight.kt | 3 +-- src/main/kotlin/gg/flyte/twilight/redis/Redis.kt | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/gg/flyte/twilight/Twilight.kt b/src/main/kotlin/gg/flyte/twilight/Twilight.kt index 11bfbf3..114471d 100644 --- a/src/main/kotlin/gg/flyte/twilight/Twilight.kt +++ b/src/main/kotlin/gg/flyte/twilight/Twilight.kt @@ -9,7 +9,6 @@ import gg.flyte.twilight.event.customEventListeners import gg.flyte.twilight.extension.applyForEach import gg.flyte.twilight.redis.Redis import gg.flyte.twilight.server.ServerSoftware -import org.bukkit.Material import org.bukkit.plugin.java.JavaPlugin class Twilight(javaPlugin: JavaPlugin) { @@ -38,6 +37,7 @@ class Twilight(javaPlugin: JavaPlugin) { fun env(init: Environment.Settings.() -> Unit = {}) { usingEnv = true Environment.env(Environment.Settings().apply(init)) + } fun mongo(init: MongoDB.Settings.() -> Unit = {}) = MongoDB.mongo(MongoDB.Settings().apply(init)) @@ -49,5 +49,4 @@ class Twilight(javaPlugin: JavaPlugin) { fun terminate() = customEventListeners.applyForEach { unregister() } } - fun twilight(plugin: JavaPlugin, init: Twilight.() -> Unit = {}): Twilight = Twilight(plugin).apply(init) diff --git a/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt b/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt index bee0070..9444b87 100644 --- a/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt +++ b/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt @@ -16,7 +16,7 @@ object Redis { jedis = Jedis(redis.host, redis.port, redis.timeout) } - fun publishSync(channel: String, message: String){ + private fun publishSync(channel: String, message: String){ jedis.publish(channel, message) } @@ -58,3 +58,4 @@ class RedisListener(channel: String, val block: RedisMessage.() -> Unit): Twilig + From d8bc03a94e356633f3d620062fde7288ff867923 Mon Sep 17 00:00:00 2001 From: Itay <102420004+itay64@users.noreply.github.com> Date: Sun, 17 Mar 2024 18:48:34 +0200 Subject: [PATCH 04/19] Update README.md --- README.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/README.md b/README.md index 406a4e7..c891da7 100644 --- a/README.md +++ b/README.md @@ -426,6 +426,56 @@ NameCacheService.uuidFromName("stxphen") Currently the only way to configure your MongoDB "cache" for UUIDs and names, is to have an Environment variable called `NAME_CACHE_COLLECTION` with the value being what you want to call the collection. Don't want to use the Mongo cache? Disable `useMongoCache` in the settings. +# Redis +Twilight has a Redis system that lets you publish messages and listen to incoming messages on any channel you'd like. + +#### Environment variables +You can use the following Environment variables for your MongoDB: +```env +REDIS_HOST="your redis server host" +REDIS_PORT="your redis server port" +REDIS_TIMEOUT="your redis connection timeout" +``` + +#### Builder +When building your Twilight instance, you can specify your host and port like so: +```kotlin +val twilight = twilight(plugin) { + redis { + host = "your redis server host" + port = 6379 // Default Redis Port + timeout = 500 // 500 Milliseconds Timeout + } +} +``` + +From here you can publish messages like so: + +```kotlin +Redis.publish("channel", "message") // Async Publishing +``` + +You are also able to listen to incoming message on specific channels, using the 'TwilightRedisListener' Class: +```kotlin +// Extend the 'TwilightRedisListener' class and override the 'onMessage' function. +class PlayerConnectionRedisListener(): TwilightRedisListener("player_connection") { + override fun onMessage(message: String) { + // do stuff + } +} +Adding The Listner: +```kotlin +Redis.addListener(PlayerConnectionRedisListener()) +``` +Alternativley, instead of extending the listener class, you can add a listener using a block of code, which returns the 'RedisMessage' data class, which contains the channel and the message: +```kotlin +Redis.addListener("cool-channel"){ + val channel = this.channel + val message = this.message +} +``` + + ### Files Extensions #### File.hash() From 326dd9f1f8a9d6f94b6966de82ac477919cc241b Mon Sep 17 00:00:00 2001 From: Itay <102420004+itay64@users.noreply.github.com> Date: Sun, 17 Mar 2024 18:49:50 +0200 Subject: [PATCH 05/19] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c891da7..af6307b 100644 --- a/README.md +++ b/README.md @@ -463,6 +463,7 @@ class PlayerConnectionRedisListener(): TwilightRedisListener("player_connection" // do stuff } } +``` Adding The Listner: ```kotlin Redis.addListener(PlayerConnectionRedisListener()) @@ -470,6 +471,7 @@ Redis.addListener(PlayerConnectionRedisListener()) Alternativley, instead of extending the listener class, you can add a listener using a block of code, which returns the 'RedisMessage' data class, which contains the channel and the message: ```kotlin Redis.addListener("cool-channel"){ + // whatever happens when a message on "cool-channel" is published val channel = this.channel val message = this.message } From 7f39e0440919fa668290b1cf25563e2682dcdfa1 Mon Sep 17 00:00:00 2001 From: Itay <102420004+itay64@users.noreply.github.com> Date: Sun, 17 Mar 2024 18:50:16 +0200 Subject: [PATCH 06/19] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af6307b..88734a6 100644 --- a/README.md +++ b/README.md @@ -458,7 +458,7 @@ Redis.publish("channel", "message") // Async Publishing You are also able to listen to incoming message on specific channels, using the 'TwilightRedisListener' Class: ```kotlin // Extend the 'TwilightRedisListener' class and override the 'onMessage' function. -class PlayerConnectionRedisListener(): TwilightRedisListener("player_connection") { +class PlayerConnectionRedisListener(): TwilightRedisListener("player-connection") { override fun onMessage(message: String) { // do stuff } From 552bb5ef9cf5c0be9a0f3dd42ee377053af4d234 Mon Sep 17 00:00:00 2001 From: Itay <102420004+itay64@users.noreply.github.com> Date: Sun, 17 Mar 2024 22:23:29 +0200 Subject: [PATCH 07/19] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 88734a6..c26e645 100644 --- a/README.md +++ b/README.md @@ -430,7 +430,7 @@ Currently the only way to configure your MongoDB "cache" for UUIDs and names, is Twilight has a Redis system that lets you publish messages and listen to incoming messages on any channel you'd like. #### Environment variables -You can use the following Environment variables for your MongoDB: +You can use the following Environment variables for your Redis Server: ```env REDIS_HOST="your redis server host" REDIS_PORT="your redis server port" From 34a62ac61820b020a76c7bfb57c043dcc4dae99c Mon Sep 17 00:00:00 2001 From: BuildTools Date: Mon, 18 Mar 2024 21:22:12 +0200 Subject: [PATCH 08/19] Added to the Redis System: - Set Function - Get Function - Delete Function (All of those 3 are about String Key-Value pairs) - Made the Listeners functions return the listener itself and added an 'unregister()' function. - Added the listener to the 'RedisMessage' class's parameters to make it possible to unregister the listener from the code block. --- .../kotlin/gg/flyte/twilight/redis/Redis.kt | 47 +++++++++---------- .../kotlin/gg/flyte/twilight/RedisTest.kt | 14 ++++++ 2 files changed, 36 insertions(+), 25 deletions(-) create mode 100644 src/test/kotlin/gg/flyte/twilight/RedisTest.kt diff --git a/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt b/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt index 9444b87..b28032f 100644 --- a/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt +++ b/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt @@ -11,51 +11,48 @@ import java.util.concurrent.Executors object Redis { private lateinit var jedis: Jedis private val executor: Executor = Executors.newCachedThreadPool() - - fun redis(redis: Settings){ + fun redis(redis: Settings) { jedis = Jedis(redis.host, redis.port, redis.timeout) } - - private fun publishSync(channel: String, message: String){ - jedis.publish(channel, message) - } - + private fun publishSync(channel: String, message: String) = jedis.publish(channel, message) fun publish(channel: String, message: String) = CompletableFuture.supplyAsync({ publishSync(channel, message) }, executor) - + private fun setSync(key: String, value: String) = jedis.set(key, value) + fun set(key: String, value: String): CompletableFuture = CompletableFuture.supplyAsync({ setSync(key, value) }, executor) + private fun getSync(key: String) = jedis.get(key) + fun get(key: String): CompletableFuture = CompletableFuture.supplyAsync({ getSync(key) }, executor) + private fun deleteSync(key: String) = jedis.del(key) + fun delete(key: String): CompletableFuture = CompletableFuture.supplyAsync({ deleteSync(key) }, executor) + + fun addListener(listener: TwilightRedisListener): TwilightRedisListener { + jedis.subscribe(listener, listener.channel) + return listener + } + fun addListener(channel: String, block: RedisMessage.() -> Unit): TwilightRedisListener { + val listener = RedisListener(channel, block) + jedis.subscribe(listener, channel) + return listener + } class Settings { var host: String = if (Twilight.usingEnv) Environment.get("REDIS_HOST") else "localhost" var port: Int = if (Twilight.usingEnv) Environment.get("REDIS_PORT").toInt() else 6379 var timeout: Int = if (Twilight.usingEnv) Environment.get("REDIS_TIMEOUT").toInt() else 0 } - - fun addListener(listener: TwilightRedisListener) = jedis.subscribe(listener, listener.channel) - fun addListener(channel: String, block: RedisMessage.() -> Unit) = jedis.subscribe(RedisListener(channel, block), channel) - } -data class RedisMessage(val channel: String, val message: String) +data class RedisMessage(val channel: String, val message: String, val listener: TwilightRedisListener) abstract class TwilightRedisListener(val channel: String) : JedisPubSub() { - override fun onMessage(channel: String?, message: String?) { channel ?: return message?: return if (channel == this.channel) onMessage(message) } - abstract fun onMessage(message: String) - + fun unregister() = unsubscribe() } class RedisListener(channel: String, val block: RedisMessage.() -> Unit): TwilightRedisListener(channel) { - override fun onMessage(message: String) { - block(RedisMessage(channel, message)) + block(RedisMessage(channel, message, this)) } - -} - - - - - +} \ No newline at end of file diff --git a/src/test/kotlin/gg/flyte/twilight/RedisTest.kt b/src/test/kotlin/gg/flyte/twilight/RedisTest.kt new file mode 100644 index 0000000..f9506aa --- /dev/null +++ b/src/test/kotlin/gg/flyte/twilight/RedisTest.kt @@ -0,0 +1,14 @@ +package gg.flyte.twilight + +import gg.flyte.twilight.redis.Redis + +fun addingListenersTest(){ + + val listener = Redis.addListener("cool-channel"){ + println("The following message was received: '$message' on channel '$channel'") + this.listener.unregister() + } + + + +} \ No newline at end of file From 00bc8bd19c342c44695a26f4d367176a9cdf87d3 Mon Sep 17 00:00:00 2001 From: Itay <102420004+itay64@users.noreply.github.com> Date: Mon, 18 Mar 2024 21:35:41 +0200 Subject: [PATCH 09/19] Update README.md --- README.md | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c26e645..1a21475 100644 --- a/README.md +++ b/README.md @@ -448,8 +448,18 @@ val twilight = twilight(plugin) { } } ``` +You can Set/Get/Delete String Key-Value pairs on your Redis server like so: (All of those functions are Async and return a CompleteableFuture) +```kotlin +Redis.set("cool-key", "super-secret-value") + +val value = Redis.get("cool-key") // Returns a completable future + +println("The value is: ${value.get()}") // Prints "The value is: super-secret-value" + +Redis.delete("cool-key") +``` -From here you can publish messages like so: +You can publish messages like so: ```kotlin Redis.publish("channel", "message") // Async Publishing @@ -464,16 +474,16 @@ class PlayerConnectionRedisListener(): TwilightRedisListener("player-connection" } } ``` -Adding The Listner: +You can add add/register the listener like this: (which also returns the listener which lets you unregister if if you'd like) ```kotlin -Redis.addListener(PlayerConnectionRedisListener()) +val listener = Redis.addListener(PlayerConnectionRedisListener()) +listener.unregister() // unregistering the listener. ``` -Alternativley, instead of extending the listener class, you can add a listener using a block of code, which returns the 'RedisMessage' data class, which contains the channel and the message: +Alternativley, instead of extending the listener class, you can add a listener using a block of code, which returns the 'RedisMessage' data class, which contains the channel, the message, and the listener: ```kotlin -Redis.addListener("cool-channel"){ - // whatever happens when a message on "cool-channel" is published - val channel = this.channel - val message = this.message +val listener = Redis.addListener("cool-channel"){ + println("The following message was received: '$message' on channel '$channel'") + this.listener.unregister() // unregistering the listener after we recieved the message. } ``` From 041804ac95c8673fcebcd966be2b48f10fdfd7d3 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Mon, 18 Mar 2024 22:32:51 +0200 Subject: [PATCH 10/19] Specified Return Types --- src/main/kotlin/gg/flyte/twilight/redis/Redis.kt | 2 +- src/test/kotlin/gg/flyte/twilight/RedisTest.kt | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt b/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt index b28032f..edc684d 100644 --- a/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt +++ b/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt @@ -15,7 +15,7 @@ object Redis { jedis = Jedis(redis.host, redis.port, redis.timeout) } private fun publishSync(channel: String, message: String) = jedis.publish(channel, message) - fun publish(channel: String, message: String) = CompletableFuture.supplyAsync({ publishSync(channel, message) }, executor) + fun publish(channel: String, message: String): CompletableFuture = CompletableFuture.supplyAsync({ publishSync(channel, message) }, executor) private fun setSync(key: String, value: String) = jedis.set(key, value) fun set(key: String, value: String): CompletableFuture = CompletableFuture.supplyAsync({ setSync(key, value) }, executor) private fun getSync(key: String) = jedis.get(key) diff --git a/src/test/kotlin/gg/flyte/twilight/RedisTest.kt b/src/test/kotlin/gg/flyte/twilight/RedisTest.kt index f9506aa..a51eea6 100644 --- a/src/test/kotlin/gg/flyte/twilight/RedisTest.kt +++ b/src/test/kotlin/gg/flyte/twilight/RedisTest.kt @@ -10,5 +10,21 @@ fun addingListenersTest(){ } + Redis.set("cool-key", "super-secret-value") + + val future = Redis.get("cool-key") // Returns a Completable Future + + future.thenApplyAsync { + value -> println("The value is: $value") // Prints: "The value is: super-secret-value" + }.exceptionally { + e -> println("An exception occurred: ${e.message}") // Handle the Exception + } + + Thread.sleep(1000) + + Redis.delete("cool-key") + + + } \ No newline at end of file From 1a7ef58071c2e372dd46b038277228d5966f89be Mon Sep 17 00:00:00 2001 From: Itay <102420004+itay64@users.noreply.github.com> Date: Mon, 18 Mar 2024 22:33:17 +0200 Subject: [PATCH 11/19] Update README.md --- README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1a21475..eecd6ba 100644 --- a/README.md +++ b/README.md @@ -452,9 +452,15 @@ You can Set/Get/Delete String Key-Value pairs on your Redis server like so: (All ```kotlin Redis.set("cool-key", "super-secret-value") -val value = Redis.get("cool-key") // Returns a completable future - -println("The value is: ${value.get()}") // Prints "The value is: super-secret-value" +val future = Redis.get("cool-key") // Returns a Completable Future + +future.thenApplyAsync { + value -> println("The value is: $value") // Prints: "The value is: super-secret-value" +}.exceptionally { + e -> println("An exception occurred: ${e.message}") // Handle the Exception +} + +Thread.sleep(1000) Redis.delete("cool-key") ``` From bcfd28c419b19ab877283850eb1677fafe1a070a Mon Sep 17 00:00:00 2001 From: Itay <102420004+itay64@users.noreply.github.com> Date: Mon, 18 Mar 2024 22:35:33 +0200 Subject: [PATCH 12/19] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index eecd6ba..bcb511d 100644 --- a/README.md +++ b/README.md @@ -427,7 +427,7 @@ NameCacheService.uuidFromName("stxphen") Currently the only way to configure your MongoDB "cache" for UUIDs and names, is to have an Environment variable called `NAME_CACHE_COLLECTION` with the value being what you want to call the collection. Don't want to use the Mongo cache? Disable `useMongoCache` in the settings. # Redis -Twilight has a Redis system that lets you publish messages and listen to incoming messages on any channel you'd like. +Twilight has a Redis system that lets you set/get/delete string key value pairs, additionally, you are able to publish messages and listen to incoming messages on any channel you'd like. #### Environment variables You can use the following Environment variables for your Redis Server: @@ -447,6 +447,7 @@ val twilight = twilight(plugin) { timeout = 500 // 500 Milliseconds Timeout } } +#### String Key-Value Pairs ``` You can Set/Get/Delete String Key-Value pairs on your Redis server like so: (All of those functions are Async and return a CompleteableFuture) ```kotlin @@ -464,7 +465,7 @@ Thread.sleep(1000) Redis.delete("cool-key") ``` - +#### Publishing Messages You can publish messages like so: ```kotlin @@ -480,6 +481,7 @@ class PlayerConnectionRedisListener(): TwilightRedisListener("player-connection" } } ``` +# Redis Listeners (PubSub) You can add add/register the listener like this: (which also returns the listener which lets you unregister if if you'd like) ```kotlin val listener = Redis.addListener(PlayerConnectionRedisListener()) From f84b16205a0fb2aae342364231b88d80cefb503d Mon Sep 17 00:00:00 2001 From: Itay <102420004+itay64@users.noreply.github.com> Date: Mon, 18 Mar 2024 22:36:15 +0200 Subject: [PATCH 13/19] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bcb511d..eb98ffe 100644 --- a/README.md +++ b/README.md @@ -447,8 +447,8 @@ val twilight = twilight(plugin) { timeout = 500 // 500 Milliseconds Timeout } } -#### String Key-Value Pairs ``` +#### String Key-Value Pairs You can Set/Get/Delete String Key-Value pairs on your Redis server like so: (All of those functions are Async and return a CompleteableFuture) ```kotlin Redis.set("cool-key", "super-secret-value") From 916020ed7688feed6ffb046d58735a236835dee6 Mon Sep 17 00:00:00 2001 From: Itay <102420004+itay64@users.noreply.github.com> Date: Mon, 18 Mar 2024 22:38:01 +0200 Subject: [PATCH 14/19] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index eb98ffe..dff70da 100644 --- a/README.md +++ b/README.md @@ -471,8 +471,9 @@ You can publish messages like so: ```kotlin Redis.publish("channel", "message") // Async Publishing ``` - -You are also able to listen to incoming message on specific channels, using the 'TwilightRedisListener' Class: +#### Redis Listeners (PubSub) +##### Listen to incoming messages +You are able to listen to incoming message on specific channels, using the 'TwilightRedisListener' Class: ```kotlin // Extend the 'TwilightRedisListener' class and override the 'onMessage' function. class PlayerConnectionRedisListener(): TwilightRedisListener("player-connection") { @@ -481,7 +482,6 @@ class PlayerConnectionRedisListener(): TwilightRedisListener("player-connection" } } ``` -# Redis Listeners (PubSub) You can add add/register the listener like this: (which also returns the listener which lets you unregister if if you'd like) ```kotlin val listener = Redis.addListener(PlayerConnectionRedisListener()) From 9fd4ce15cce13e692a6042eb67d1688d726f3f0e Mon Sep 17 00:00:00 2001 From: Itay <102420004+itay64@users.noreply.github.com> Date: Mon, 18 Mar 2024 22:38:37 +0200 Subject: [PATCH 15/19] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dff70da..6ae1afe 100644 --- a/README.md +++ b/README.md @@ -482,7 +482,7 @@ class PlayerConnectionRedisListener(): TwilightRedisListener("player-connection" } } ``` -You can add add/register the listener like this: (which also returns the listener which lets you unregister if if you'd like) +You can add add/register the listener like this: (which also returns the listener which lets you unregister it if you'd like) ```kotlin val listener = Redis.addListener(PlayerConnectionRedisListener()) listener.unregister() // unregistering the listener. From 22be4e74a185c1426cafc48f828698e3728ecbf5 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Mon, 18 Mar 2024 23:12:08 +0200 Subject: [PATCH 16/19] Added Username/Password Options To Redis --- src/main/kotlin/gg/flyte/twilight/redis/Redis.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt b/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt index edc684d..6e8b10e 100644 --- a/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt +++ b/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt @@ -2,6 +2,7 @@ package gg.flyte.twilight.redis import gg.flyte.twilight.Twilight import gg.flyte.twilight.environment.Environment +import redis.clients.jedis.DefaultJedisClientConfig import redis.clients.jedis.Jedis import redis.clients.jedis.JedisPubSub import java.util.concurrent.CompletableFuture @@ -12,6 +13,11 @@ object Redis { private lateinit var jedis: Jedis private val executor: Executor = Executors.newCachedThreadPool() fun redis(redis: Settings) { + if (redis.isUsingPassword){ + val config = DefaultJedisClientConfig.builder().user(redis.username).password(redis.password).timeoutMillis(redis.timeout).build() + jedis = Jedis(redis.host, redis.port, config) + return + } jedis = Jedis(redis.host, redis.port, redis.timeout) } private fun publishSync(channel: String, message: String) = jedis.publish(channel, message) @@ -36,6 +42,9 @@ object Redis { var host: String = if (Twilight.usingEnv) Environment.get("REDIS_HOST") else "localhost" var port: Int = if (Twilight.usingEnv) Environment.get("REDIS_PORT").toInt() else 6379 var timeout: Int = if (Twilight.usingEnv) Environment.get("REDIS_TIMEOUT").toInt() else 0 + var isUsingPassword: Boolean = if (Twilight.usingEnv) Environment.get("REDIS_USING_PASSWORD").toBoolean() else false + val username: String = if (Twilight.usingEnv && isUsingPassword) Environment.get("REDIS_USERNAME") else "" + var password: String = if (Twilight.usingEnv && isUsingPassword) Environment.get("REDIS_PASSWORD") else "" } } From 3d33db378654708081a9fb6d17e6948f3ad66b1d Mon Sep 17 00:00:00 2001 From: Itay <102420004+itay64@users.noreply.github.com> Date: Mon, 18 Mar 2024 23:17:49 +0200 Subject: [PATCH 17/19] Update README.md --- README.md | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6ae1afe..db76e41 100644 --- a/README.md +++ b/README.md @@ -435,8 +435,19 @@ You can use the following Environment variables for your Redis Server: REDIS_HOST="your redis server host" REDIS_PORT="your redis server port" REDIS_TIMEOUT="your redis connection timeout" +REDIS_USING_PASSWORD="false" +REDIS_USERNAME:"" +REDIS_PASSWORD:"" +``` +Alternativley, if your Redis server requires a Username + Password in order to access, you can use the following: +```env +REDIS_HOST="your redis server host" +REDIS_PORT="your redis server port" +REDIS_TIMEOUT="your redis connection timeout" +REDIS_USING_PASSWORD="true" +REDIS_USERNAME:"coolUsername" +REDIS_PASSWORD:"coolPassword" ``` - #### Builder When building your Twilight instance, you can specify your host and port like so: ```kotlin @@ -445,6 +456,20 @@ val twilight = twilight(plugin) { host = "your redis server host" port = 6379 // Default Redis Port timeout = 500 // 500 Milliseconds Timeout + isUsingPassword = false // False by default + } +} +``` +Alternativley, if your Redis server requires a Username + Password in order to access, you can use the following: +```kotlin +val twilight = twilight(plugin) { + redis { + host = "your redis server host" + port = 6379 // Default Redis Port + timeout = 500 // 500 Milliseconds Timeout + isUsingPassword = true + username = "coolUsername" + password = "coolPassword" } } ``` @@ -495,7 +520,6 @@ val listener = Redis.addListener("cool-channel"){ } ``` - ### Files Extensions #### File.hash() From b0db89f36261069551fb82a46fdcad350179435f Mon Sep 17 00:00:00 2001 From: Josh <43449531+joshbker@users.noreply.github.com> Date: Fri, 5 Apr 2024 13:32:54 +0100 Subject: [PATCH 18/19] refactor: move redis to data package --- src/main/kotlin/gg/flyte/twilight/Twilight.kt | 2 +- src/main/kotlin/gg/flyte/twilight/{redis => data}/Redis.kt | 2 +- src/test/kotlin/gg/flyte/twilight/RedisTest.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/main/kotlin/gg/flyte/twilight/{redis => data}/Redis.kt (99%) diff --git a/src/main/kotlin/gg/flyte/twilight/Twilight.kt b/src/main/kotlin/gg/flyte/twilight/Twilight.kt index 114471d..de3770a 100644 --- a/src/main/kotlin/gg/flyte/twilight/Twilight.kt +++ b/src/main/kotlin/gg/flyte/twilight/Twilight.kt @@ -7,7 +7,7 @@ import gg.flyte.twilight.environment.Environment import gg.flyte.twilight.event.custom.chat.command.ChatClickCommand import gg.flyte.twilight.event.customEventListeners import gg.flyte.twilight.extension.applyForEach -import gg.flyte.twilight.redis.Redis +import gg.flyte.twilight.data.Redis import gg.flyte.twilight.server.ServerSoftware import org.bukkit.plugin.java.JavaPlugin diff --git a/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt b/src/main/kotlin/gg/flyte/twilight/data/Redis.kt similarity index 99% rename from src/main/kotlin/gg/flyte/twilight/redis/Redis.kt rename to src/main/kotlin/gg/flyte/twilight/data/Redis.kt index 6e8b10e..9141e0c 100644 --- a/src/main/kotlin/gg/flyte/twilight/redis/Redis.kt +++ b/src/main/kotlin/gg/flyte/twilight/data/Redis.kt @@ -1,4 +1,4 @@ -package gg.flyte.twilight.redis +package gg.flyte.twilight.data import gg.flyte.twilight.Twilight import gg.flyte.twilight.environment.Environment diff --git a/src/test/kotlin/gg/flyte/twilight/RedisTest.kt b/src/test/kotlin/gg/flyte/twilight/RedisTest.kt index a51eea6..742705c 100644 --- a/src/test/kotlin/gg/flyte/twilight/RedisTest.kt +++ b/src/test/kotlin/gg/flyte/twilight/RedisTest.kt @@ -1,6 +1,6 @@ package gg.flyte.twilight -import gg.flyte.twilight.redis.Redis +import gg.flyte.twilight.data.Redis fun addingListenersTest(){ From d5295a48ca6351da2119de84b270873a90f31a11 Mon Sep 17 00:00:00 2001 From: Josh <43449531+joshbker@users.noreply.github.com> Date: Fri, 5 Apr 2024 13:33:40 +0100 Subject: [PATCH 19/19] chore: bump ver v1.1.10 --- README.md | 6 +++--- build.gradle.kts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c6e3297..fcf75ad 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Maven gg.flyte twilight - 1.1.9 + 1.1.10 ``` @@ -33,14 +33,14 @@ maven { url "https://repo.flyte.gg/releases" } -implementation "gg.flyte:twilight:1.1.9" +implementation "gg.flyte:twilight:1.1.10" ``` Gradle (Kotlin DSL) ```kotlin maven("https://repo.flyte.gg/releases") -implementation("gg.flyte:twilight:1.1.9") +implementation("gg.flyte:twilight:1.1.10") ``` Certain features of Twilight require configuration, which can be done via the Twilight class. To setup a Twilight class instance, you can use the `twilight` function as shown below: diff --git a/build.gradle.kts b/build.gradle.kts index ddcedd5..65c0b68 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } group = "gg.flyte" -version = "1.1.9" +version = "1.1.10" repositories { mavenLocal()