Compare commits

..

120 Commits

Author SHA1 Message Date
mohammed jasem alaajel bae2d970bb added jedis stuff 2021-03-16 18:05:20 +04:00
Govindass 141357b353 make encryption even more informative 2021-02-12 13:03:29 +02:00
Govindass c89e4f1310 Make encryption config more informative & some other things 2021-02-12 12:59:28 +02:00
Govindass 8cda727799 Update config.yml 2021-02-12 12:51:00 +02:00
Govindass ee5a9459bf Update config to be more informative 2021-02-12 12:48:39 +02:00
Govindass b482e0fa7a update siv-mode 2021-02-09 11:55:21 +02:00
Govindass d23956460f 1.3.3 2021-01-26 12:22:53 +02:00
Govindass 470104fc93 Fix set operation on {var::*} 2021-01-26 11:54:49 +02:00
Govindass 0f3ab74d98 Various fixes and improvements 2021-01-26 10:51:31 +02:00
Govindass 358aa66566 Merge branch 'master' of https://github.com/Limework/RediSkript 2020-12-28 10:55:51 +02:00
Govindass 8eb200f614 bump Jedis version from 3.4.0 to 3.4.1 (has important fixes I think) 2020-12-28 10:55:47 +02:00
mohammed jasem alaajel 6ea36c2f37 Update README.md 2020-12-26 16:28:13 +04:00
mohammed jasem alaajel ce3a7e3dcd added reloadconfig to redisreload 2020-12-26 15:09:25 +04:00
mohammed jasem alaajel b0d29ea97d added debug check when error sending message 2020-12-26 15:07:12 +04:00
mohammed jasem alaajel 5692b5d9e4 fixed typo in logs sending.. 2020-12-26 14:47:00 +04:00
mohammed jasem alaajel e5d9d17a23 Merge pull request #11 from Limework/patch-1
new ConnectionController!
2020-12-26 14:04:18 +04:00
mohammed jasem alaajel a96f9b3201 Update RedisController.java 2020-12-26 14:03:27 +04:00
mohammed jasem alaajel bfb8ebc862 Fixed bug where connection manager is keep reconnecting when connection reconnect after failure 2020-12-25 23:27:06 +04:00
mohammed jasem alaajel 029222a068 added replacement for system prinltn messages 2020-12-25 21:43:20 +04:00
mohammed jasem alaajel a2b58798f9 new ConnectionController! 2020-12-23 21:04:23 +04:00
mohammed jasem alaajel 3920b0e844 Update README.md 2020-12-16 14:55:43 +04:00
mohammed jasem alaajel 8d0c324323 Update README.md 2020-12-16 14:55:19 +04:00
Govindass 6b46545813 Merge branch 'master' of https://github.com/Limework/RediSkript 2020-12-15 15:02:30 +02:00
mohammed jasem alaajel 230c2cbb25 cleaned idea / removed typo in groupID 2020-12-14 17:47:17 +04:00
Govindas cd77d558de Update README.md 2020-12-14 15:21:20 +02:00
mohammed jasem alaajel 7716bc9cf5 noticed something weird in releases section that maven was 1 version late!!!!! 2020-12-14 17:19:21 +04:00
mohammed jasem alaajel 49c12da743 fixed maven not compiling correctly 2020-12-14 16:20:17 +04:00
mohammed jasem alaajel faf6a7d76d bumped redis version aswell 2020-12-14 15:13:41 +04:00
mohammed jasem alaajel 370af7bc23 bumped skript + spigot api version 2020-12-14 13:55:01 +04:00
mohammed jasem alaajel 61c6aa03dc Merge pull request #7 from Limework/add-license-1
Create LICENSE
2020-12-03 16:56:10 +04:00
mohammed jasem alaajel b80fcc00dc Create LICENSE 2020-12-03 16:55:42 +04:00
Govindass c6900e352f Reload redis in a separate thread to not lag the main thread 2020-12-03 13:21:16 +02:00
Govindass 2d5d281fe4 Finally fixed connection leak in /reloadredis !!! 2020-12-03 13:07:27 +02:00
Govindass 5699b9445f Improve code quality 2020-12-03 11:55:45 +02:00
Govindass 053bb04918 Remove unnecessary EventHandler 2020-12-03 11:13:03 +02:00
Govindas 2140cd67ff Update README.md 2020-11-28 10:14:19 +02:00
Govindas e9ae0bd50b Update README.md 2020-11-28 10:12:11 +02:00
Govindass 6ea120a85a Optimizations 2020-11-28 10:02:14 +02:00
Govindass 01525e4d63 Merge branch 'master' of https://github.com/Limework/RediSkript 2020-11-26 17:05:11 +02:00
Govindass c63495e201 Some more work on variables (Still very unfinished) 2020-11-26 17:05:07 +02:00
Govindas 265dbfa84d Remove to-do list from readme (refer to issues) 2020-11-25 17:07:30 +02:00
Govindass 6f600cc96e Add cross-server variable editing (I'll make it use {} instead of strings later) 2020-11-25 17:01:11 +02:00
Govindass 1b151dfbbe Allow sending multiple redis messages in one go 2020-11-25 13:53:52 +02:00
Govindass afdb0c3e59 Fix rare error on disable 2020-11-25 13:18:23 +02:00
Govindass ca64ec19db Fix wrong prefix coloring in command 2020-11-12 12:36:12 +02:00
Govindass c0bd63e3cd test 2020-11-03 12:23:00 +02:00
Govindass 705ce16f5d Fix wrong class name & Fully fix sending messages while disabled 2020-11-03 11:29:06 +02:00
Govindass 5a4943bd9d so I found that this threadpool was actually needed, oops
due to it not having threadpool, froze my server at one point
2020-11-02 14:14:38 +02:00
Govindass 211a45ee52 Remove Skript plugin check, as it doesn't load without it anyway 2020-11-02 12:09:18 +02:00
Govindass 1e85072e34 Oops forgot one more console message 2020-10-31 17:12:13 +02:00
Govindass a60cae72e3 Improve console messages 2020-10-31 16:48:42 +02:00
Govindass d4461f09c8 some refactoring, make classes more well-sorted 2020-10-29 10:01:36 +02:00
Govindass dd6b9b6ee6 use HIGHEST priority on disable, so "on script unload" can still work 2020-10-29 09:47:18 +02:00
Govindass 2ee28a5450 Update jarRepositories.xml 2020-10-28 12:20:27 +02:00
Govindass 26b9e0e1d8 Merge branch 'master' of https://github.com/Limework/RediSkript 2020-10-28 12:15:30 +02:00
Govindass 933b85b2d5 try fix maven 2 2020-10-28 12:15:27 +02:00
Govindass 824cf3664c try fix maven 2020-10-28 12:08:44 +02:00
Govindas d02cac7c5d Update README.md 2020-10-28 11:55:00 +02:00
Govindass a520ba6496 Update pom.xml 2020-10-28 11:53:44 +02:00
Govindass 4d265cbf61 Improve debug (thanks ShaneBee) 2020-10-27 09:06:36 +02:00
Govindass 7849efd866 Little questionable improvements (shouldn't hurt anything anyway) 2020-10-24 17:59:48 +03:00
Govindass f80d9b36e7 Make on redis message a synchronous event for thread-safety 2020-10-24 15:19:10 +03:00
Govindass 0c20becfa1 Merge branch 'master' of https://github.com/Limework/RediSkript 2020-10-24 14:33:12 +03:00
Govindass 089fdfd1f3 Update pom.xml 2020-10-24 14:32:55 +03:00
Govindas c4426a692e Update README.md 2020-10-24 14:32:48 +03:00
Govindass ed3ea7b2c7 Remove unneeded threadpool (testing has shown for it to be unneeded) 2020-10-24 13:29:49 +03:00
Govindass 2b00f0908e change useSSL to useTLS, because redis itself refers to it as TLS 2020-10-24 12:35:35 +03:00
Govindass f6c4bbcdce Revert "fixed reload but not tested"
This reverts commit a08ecd93b7.
2020-10-24 12:32:40 +03:00
Govindass ba48fdc564 Revert "Update RedisManager.java"
This reverts commit 6c5d580b16.
2020-10-24 12:32:36 +03:00
Govindass ce47af29f4 Revert "Update RedisManager.java"
This reverts commit b93624bc49.
2020-10-24 12:32:24 +03:00
mohammed jasem alaajel b93624bc49 Update RedisManager.java 2020-10-23 21:01:57 +04:00
mohammed jasem alaajel 6c5d580b16 Update RedisManager.java 2020-10-23 20:45:53 +04:00
mohammed jasem alaajel a08ecd93b7 fixed reload but not tested 2020-10-23 20:37:43 +04:00
Govindass c720433c60 Re-word redis reload command information 2020-10-23 17:50:04 +03:00
Govindass 12ce69d68f Fix critical redis server shutdown bug 2020-10-23 17:48:22 +03:00
Govindass efab085c47 Better 1.8 support & cleanup 2020-10-23 17:21:32 +03:00
Govindass 31db51fce6 Undo synchronous event, broke 1.8 servers completely 2020-10-23 16:55:04 +03:00
Govindass 776ebc9780 add redis message date expression & improve quality of existing expressions & make event guaranteedly synchronous 2020-10-23 16:49:25 +03:00
Govindass 1ef35dfb60 New /reloadredis fully restarts the plugin with reloaded configuration & some code improvements 2020-10-23 14:34:30 +03:00
Govindass 2049616f64 Make json errors easier to debug 2020-10-22 17:44:45 +03:00
Govindass 97aa663bfd Reduce jar size by removing unneeded dependencies 2020-10-22 17:28:00 +03:00
Govindass 4afd5a2dbc Merge branch 'master' of https://github.com/Limework/RediSkript 2020-10-22 14:19:36 +03:00
Govindass 92d89ec76d Remove debug message & Hotfix 2020-10-22 14:19:29 +03:00
Govindas 0ca8712a1a Update README.md 2020-10-22 13:31:38 +03:00
Govindass 216b2635b3 Further fixes & refactoring for release 2020-10-22 13:30:41 +03:00
Govindass df8608802d Fix encryption disabling & some refactoring 2020-10-22 12:32:08 +03:00
Govindass 157e2b08c7 Remove unneeded code 2020-10-18 17:07:37 +03:00
mohammed jasem alaajel 5f4600546e small fix to make sure the connect was killed 2020-07-30 09:35:50 +04:00
mohammed jasem alaajel f4ab43bcb8 added protection to kill current working sub 2020-07-28 10:53:42 +04:00
mohammed jasem alaajel 542884dfe9 added /reloadredis command 2020-07-28 10:44:00 +04:00
ham1255 2e80b57a53 Fixed mongodb url from config is wrong 2020-07-08 12:37:10 +04:00
ham1255 4141bcdfb1 added mongodb, bumped versoin 2020-07-07 18:49:19 +04:00
ham1255 9b24e49f43 new changes. 2020-07-06 22:38:54 +04:00
ham1255 35af0d3b0a Skript counts as softdepend as it make the plugin usable without skript 2020-06-30 12:44:49 +04:00
ham1255 52a2fb4c22 abstract class for guis making for making stuff easier 2020-06-30 12:42:27 +04:00
ham1255 24dafb436d moved some stuff and fixed wrong usage 2020-06-30 11:45:14 +04:00
ham1255 fc1cb590d2 forgot one line xd 2020-06-28 18:41:22 +04:00
ham1255 d9c323bc25 not tested But rewritten the Plugin 2020-06-28 18:40:53 +04:00
ham1255 7a51aef643 Update .gitignore 2020-06-28 16:45:02 +04:00
ham1255 bda20daa4b Delete SkLimework.iml 2020-06-28 16:41:47 +04:00
ham1255 9dca6cfc85 renamed project 2020-06-28 16:39:21 +04:00
ham1255 4c59ab26a4 Merge branch 'master' of https://github.com/Limework/SkLimework 2020-06-26 17:03:14 +04:00
ham1255 39fcccefeb fixed conflict and removed hard coded channels 2020-06-26 17:02:39 +04:00
Govindass 4893d53c74 fix channel syntax conflict with Vixio 2020-06-26 15:58:30 +03:00
ham1255 37edb0d497 added maven to since it will get rewritten soon. 2020-06-22 13:48:44 +04:00
ham1255 39e9536e8f New Reconnector hopefuly works 2020-06-14 17:43:46 +04:00
Govindass 3dffba07df Highly improve encryption security 2020-06-08 16:53:23 +03:00
Govindass 691b47c558 attempt to use SIV 2020-06-08 11:16:16 +03:00
ham1255 fc72c698f4 Fixed loop doesn;'t exist on server shutdown 2020-06-05 13:28:26 +04:00
Govindass 4f79fc29b7 Remove awaitTermination as it was preventing shutdown sometimes 2020-05-30 10:11:43 +03:00
Govindass 13502b818d Finish AES encryption 2020-05-27 16:22:05 +03:00
Govindass e740e2642e Fix forgotten digest 2020-05-27 15:10:26 +03:00
Govindass acdd2c2fdc Add AES-128 encryption 2020-05-27 14:43:16 +03:00
ham1255 46978fc170 ,. 2020-05-18 01:57:36 +04:00
ham1255 8b4af2450c Fixed not reconnecting on redis 4* or higher 2020-05-12 14:35:30 +04:00
ham1255 e634985b87 Added Reconnection for channels sub 2020-05-10 23:10:45 +04:00
ham1255 d82f7f4bd8 Check if error will occure when redis fails 2020-05-10 21:44:10 +04:00
ham1255 2ca77d1007 added ignore 2020-05-10 10:53:54 +04:00
ham1255 670ebd92bf added code 2020-05-10 10:52:06 +04:00
mohammed jassim alajel a4dfcac567 Create README.md 2020-05-10 10:39:19 +04:00
25 changed files with 543 additions and 631 deletions
-32
View File
@@ -1,32 +0,0 @@
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: RediSkript Build
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '8'
distribution: 'adopt'
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Download a Build Artifact
uses: actions/upload-artifact@v2.2.3
with:
# Artifact name
name: RediSkript_JAR
# Destination path
path: target/*.jar
-1
View File
@@ -5,4 +5,3 @@ out
compile compile
*.iml *.iml
*.iml
+21 -47
View File
@@ -1,42 +1,33 @@
RediSkript allows you to communicate between your servers with use of Redis, it's very fast and easy to use.
## RediSkript
Allows you to communicate between your Minecraft servers with use of Redis and Skript, it's very fast and easy to use.
Skript: https://github.com/SkriptLang/Skript Skript: https://github.com/SkriptLang/Skript
RediSkript spigot page: https://www.spigotmc.org/resources/rediskript-communicate-between-servers-with-ease.85067/s RediSkript spigot page: https://www.spigotmc.org/resources/rediskript-communicate-between-servers-with-ease.85067/
Minecraft server version supported: **1.8.8+** (On 1.8, may need to use a fork of Skript) Jedis: https://github.com/redis/jedis
You can transfer any data in the form of text between your servers, you can program it to execute a set of instructions on the server depending on the redis message, etc. This can be used for making scripts that sync data between all servers and much more! You can transfer any data in the form of text between your servers, you can program it to execute a set of instructions on the server depending on the redis message, etc. This can be used for making scripts that sync data between all servers and much more!
It is developed and maintained by Govindas & the team of Govindas Limework developers. It is developed and maintained by Govindas & the team of Govindas Limework developers.
There is only one command: **/reloadredis** it fully reloads the configuration, you can reload IP, password, channels and everything else. Redis Message:
You only need to have matching configuration in every server for communication and a Redis server to connect to. I recommend using a VPS for hosting redis server, but there also are free redis hosting options available.
### Redis Message
``` ```
on redis message: on redis message:
if redis channel is "world": if redis channel is "world":
broadcast "%redis message% %redis channel% %redis message date%" broadcast "%redis message% %redis channel% %redis message date%"
command /sendredis <text> <text>: command /sendredis <text> <text>:
usage: /sendredis <message> <channel> usage: /sendredis <message> <channel>
trigger: trigger:
send redis message arg 1 to channel arg 2 send redis message arg 1 to channel arg 2
send redis message "hello world!" to channel "world" send redis message "hello world!" to channel "world"
``` ```
### Managing variables Managing variables:
``` ```
set variables "test::1", "test::2", "test::3" in channel "global" to 100 set variables "test::1", "test::2", "test::3" in channel "global" to 100
#then use this in any server that listens to "global" redis channel and was online when the above line was executed: #then use this in any server that listens to "global" redis channel and was online when the above line was executed:
send "%{test::*}%" #outputs 100, 100 and 100 send "%{test::*}%" #outputs 100, 100 and 100
add 100 to variables "test::1" and "test::2" in channel "global"
remove 10 from variable "test::1" in channel "global"
delete variables "test::*" in channel "global" delete variables "test::*" in channel "global"
set variable "test::%uuid of player%" in channel "playerdata" to tool of player set variable "test::%uuid of player%" in channel "playerdata" to tool of player
@@ -48,56 +39,39 @@ Syntax:
variable[s] %strings% in [redis] [channel] %string% variable[s] %strings% in [redis] [channel] %string%
``` ```
### Configuration There is only one command: /reloadredis it fully reloads the configuration, you can reload IP, password, channels and everything else.
plugins/RediSkript/config.yml
You only need to have matching configuration in every server for communication and a Redis server to connect to. I recommend using VPS for hosting redis server, I personally use VPS from humbleservers.com.
Configuration:
``` ```
Redis: Redis:
#a secure password that cannot be cracked, please change it! #a secure password that cannot be cracked, please change it!
#it is also recommended to firewall your redis server with iptables so it can only be accessed by specific IP addresses #it is also recommended to firewall your redis server with iptables so it can only be accessed by specific IP addresses
Password: "yHy0d2zdBlRmaSPj3CiBwEv5V3XxBTLTrCsGW7ntBnzhfxPxXJS6Q1aTtR6DSfAtCZr2VxWnsungXHTcF94a4bsWEpGAvjL9XMU" Password: "yHy0d2zdBlRmaSPj3CiBwEv5V3XxBTLTrCsGW7ntBnzhfxPxXJS6Q1aTtR6DSfAtCZr2VxWnsungXHTcF94a4bsWEpGAvjL9XMU"
#hostname of your redis server, you can use free redis hosting (search for it online) if you do not have the ability to host your own redis server
#redis server is very lightweight, takes under 30 MB of RAM usually
Host: "127.0.0.1" Host: "127.0.0.1"
#must be 2 or higher, if you set to lower, the addon will automatically use 2 as a minimum #must be 2 or higher, if you set to lower, the addon will automatically use 2 as a minimum
#do not edit MaxConnections if you do not know what you're doing
#it is only useful to increase this number to account for PING between distant servers and when you are sending a lot of messages constantly
MaxConnections: 2 MaxConnections: 2
#the default Redis port #the default Redis port
Port: 6379 Port: 6379
#time out in milliseconds, how long it should take before it decides that it is unable to connect when sending a message #time out in milliseconds, how long it should take before it decides that it is unable to connect when sending a message
#9000 = 9 seconds #90000 = 90 seconds
TimeOut: 9000 TimeOut: 90000
#also known as SSL, only use this if you're running Redis 6.0.6 or higher, older versions will not work correctly #also known as SSL, only use this if you're running Redis 6.0.6 or higher, older versions will not work correctly
#it encrypts your traffic and makes data exchange between distant servers secure #it encrypts your traffic and makes data exchange between distant servers completely secure
useTLS: false useTLS: false
#EncryptMessages may be useful if you cannot use TLS due to use of older version of Redis or if you're paranoid about privacy and want to double encrypt your messages #may be useful if you cannot use TLS due to use of older version of Redis
#however this will not encrypt the initial authentication password, only the messages sent (use TLS for initial authentication password encryption) #however this will not encrypt the initial authentication password, only the messages sent
#it uses AES-128 SIV encryption which is secure enough for this
#the encryption configuration must be the same across all servers in order to communicate
#use 16 characters long key for AES-128 encryption
#32 characters long key for AES-256 encryption (recommended)
#the AES implementation used in RediSkript uses SIV mode, which makes the same key resistant to cracking for a big count of messages without the need of changing the key very often
EncryptMessages: true EncryptMessages: true
#EncryptionKey and MacKey must be different EncryptionKey: "16CHARACTERS KEY"
EncryptionKey: "32CHARACTERS KEY" MacKey: "16CHARACTERS KEY"
MacKey: "32CHARACTERS KEY"
#the channels from which this server can receive messages #the channels from which this server can receive messages
#you can always send messages to all channels! #you can always send messages to all channels!
#you can add as many channels as you wish! #you can add as many channels as you wish!
#ideal setup is having one global channel and having one channel that represents server name, so you know who to send messages to
#then a few other utility channels up to your needs
Channels: Channels:
- "global" - "Channel1"
- "servername" - "Channel2"
- "Channel3" - "Channel3"
``` ```
## YourKit
YourKit supports open source projects with innovative and intelligent tools for monitoring and profiling Java and .NET applications. YourKit is the creator of [YourKit Java Profiler](https://www.yourkit.com/java/profiler/), [YourKit .NET Profiler](https://www.yourkit.com/.net/profiler/) and [YourKit YouMonitor](https://www.yourkit.com/youmonitor/).
![YourKit](https://www.yourkit.com/images/yklogo.png)
-83
View File
@@ -1,83 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>RediSkript</artifactId>
<groupId>net.limework</groupId>
<version>1.3.7-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>RediSkript-bukkit</artifactId>
<repositories>
<repository>
<id>papermc</id>
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
</repositories>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<outputDirectory>../target</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.github.SkriptLang</groupId>
<artifactId>Skript</artifactId>
<version>2.10.1</version>
<type>jar</type>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.16.5-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.limework</groupId>
<artifactId>RediSkript-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
@@ -1,386 +0,0 @@
package net.limework.rediskript.managers;
import ch.njol.skript.registrations.Classes;
import ch.njol.skript.variables.Variables;
import net.limework.rediskript.RediSkript;
import net.limework.rediskript.data.Encryption;
import net.limework.rediskript.events.RedisMessageEvent;
import org.bukkit.Bukkit;
import org.bukkit.configuration.Configuration;
import org.bukkit.scheduler.BukkitTask;
import org.cryptomator.siv.UnauthenticCiphertextException;
import org.json.JSONArray;
import org.json.JSONObject;
import redis.clients.jedis.*;
import redis.clients.jedis.exceptions.JedisConnectionException;
import javax.crypto.IllegalBlockSizeException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
public class RedisController extends BinaryJedisPubSub implements Runnable {
//Jedis Pool to be used by every another class.
private final JedisPool jedisPool;
//this seems useless unless tls is OFF!
// class author is govindas :/
private final Encryption encryption;
private byte[][] channelsInByte;
private final AtomicBoolean isConnectionBroken;
private final AtomicBoolean isConnecting;
private final RediSkript plugin;
private final BukkitTask ConnectionTask;
public RedisController(RediSkript plugin) {
this.plugin = plugin;
Configuration config = plugin.getConfig();
JedisPoolConfig JConfig = new JedisPoolConfig();
int maxConnections = config.getInt("Redis.MaxConnections");
//do not allow less than 2 max connections as that causes issues
if (maxConnections < 2) {
maxConnections = 2;
}
JConfig.setMaxTotal(maxConnections);
JConfig.setMaxIdle(maxConnections);
JConfig.setMinIdle(1);
JConfig.setBlockWhenExhausted(true);
final String password = config.getString("Redis.Password", "");
if (password.isEmpty()) {
this.jedisPool = new JedisPool(JConfig,
config.getString("Redis.Host", "127.0.0.1"),
config.getInt("Redis.Port", 6379),
config.getInt("Redis.TimeOut", 9000),
config.getBoolean("Redis.useTLS", false));
} else {
this.jedisPool = new JedisPool(JConfig,
config.getString("Redis.Host", "127.0.0.1"),
config.getInt("Redis.Port", 6379),
config.getInt("Redis.TimeOut", 9000),
password,
config.getBoolean("Redis.useTLS", false));
}
encryption = new Encryption(config.getBoolean("Redis.EncryptMessages"),
config.getString("Redis.EncryptionKey"),
config.getString("Redis.MacKey"));
setupChannels(config);
isConnectionBroken = new AtomicBoolean(true);
isConnecting = new AtomicBoolean(false);
//Start the main task on async thread
ConnectionTask = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, this, 0, 20 * 5);
}
@Override
public void run() {
if (!isConnectionBroken.get() || isConnecting.get()) {
return;
}
plugin.sendLogs("Connecting to Redis server...");
isConnecting.set(true);
try (Jedis jedis = jedisPool.getResource()) {
isConnectionBroken.set(false);
plugin.sendLogs("&aConnection to Redis server has established! Success!");
jedis.subscribe(this, channelsInByte);
} catch (Exception e) {
isConnecting.set(false);
isConnectionBroken.set(true);
plugin.sendErrorLogs("Connection to Redis server has failed! Please check your details in the configuration.");
e.printStackTrace();
}
}
public void shutdown() {
ConnectionTask.cancel();
if (this.isSubscribed()) {
try {
this.unsubscribe();
} catch (Exception e) {
plugin.sendErrorLogs("Something went wrong during unsubscribing...");
e.printStackTrace();
}
}
jedisPool.close();
}
@Override
public void onMessage(byte[] channel, byte[] message) {
String channelString = new String(channel, StandardCharsets.UTF_8);
String receivedMessage = null;
try {
//if encryption is enabled, decrypt the message, else just convert binary to string
if (this.encryption.isEncryptionEnabled()) {
try {
receivedMessage = encryption.decrypt(message);
} catch (UnauthenticCiphertextException | IllegalBlockSizeException e) {
e.printStackTrace();
}
} else {
//encryption is disabled, so let's just get the string
receivedMessage = new String(message, StandardCharsets.UTF_8);
}
if (receivedMessage != null) {
JSONObject j = new JSONObject(receivedMessage);
if (j.get("Type").equals("Skript")) {
JSONArray messages = j.getJSONArray("Messages");
RedisMessageEvent event;
for (int i = 0; i < messages.length(); i++) {
event = new RedisMessageEvent(channelString, messages.get(i).toString(), j.getLong("Date"));
//if plugin is disabling, don't call events anymore
if (plugin.isEnabled()) {
RedisMessageEvent finalEvent = event;
Bukkit.getScheduler().runTask(plugin, () -> plugin.getServer().getPluginManager().callEvent(finalEvent));
}
}
} else if (j.get("Type").equals("SkriptVariables")) {
//Transfer variables between servers
JSONArray varNames = j.getJSONArray("Names");
Object inputValue;
String changeValue = null;
JSONArray varValues = null;
if (!j.isNull("Values")) {
varValues = j.getJSONArray("Values");
}
for (int i = 0; i < varNames.length(); i++) {
String varName = varNames.get(i).toString();
if (j.isNull("Values")) {
// only check for SET here, because null has to be ignored in all other cases
if (j.getString("Operation").equals("SET")) {
Variables.setVariable(varName, null, null, false);
}
} else {
if (!varValues.isNull(i)) {
changeValue = varValues.get(i).toString();
}
String[] inputs = changeValue.split("\\^", 2);
inputValue = Classes.deserialize(inputs[0], Base64.getDecoder().decode(inputs[1]));
switch (j.getString("Operation")) {
case "ADD":
if (varName.charAt(varName.length() - 1) == '*') {
plugin.getLogger().log(Level.WARNING, "Adding to {::*} variables in RediSkript is not supported. Variable name: " + varName);
continue;
}
Object variable = Variables.getVariable(varName, null, false);
if (variable == null) {
Variables.setVariable(varName, inputValue, null, false);
} else if (variable instanceof Long) {
if (inputValue instanceof Integer) {
inputValue = Long.valueOf((Integer) inputValue);
}
if (inputValue instanceof Long) {
Variables.setVariable(varName, (Long) variable + (Long) inputValue, null, false);
} else if (inputValue instanceof Double) {
// convert Long variable to Double
variable = Double.valueOf((Long) variable);
Variables.setVariable(varName, (Double) variable + (Double) inputValue, null, false);
} else {
// Not supported input type
plugin.getLogger().log(Level.WARNING, "Unsupported add action of data type (" + inputValue.getClass().getName() + ") on variable: " + varName);
continue;
}
} else if (variable instanceof Double) {
if (inputValue instanceof Integer) {
inputValue = Double.valueOf((Integer) inputValue);
}
if (inputValue instanceof Double) {
Variables.setVariable(varName, (Double) variable + (Double) inputValue, null, false);
} else if (inputValue instanceof Long) {
Variables.setVariable(varName, (Double) variable + ((Long) inputValue).doubleValue(), null, false);
} else {
// Not supported input type
plugin.getLogger().log(Level.WARNING, "Unsupported add action of data type (" + inputValue.getClass().getName() + ") on variable: " + varName);
continue;
}
} else if (variable instanceof Integer) {
if (inputValue instanceof Integer) {
Variables.setVariable(varName, (Integer) variable + (Integer) inputValue, null, false);
} else if (inputValue instanceof Double) {
// convert Integer variable to Double
variable = Double.valueOf((Integer) variable);
Variables.setVariable(varName, (Double) variable + (Double) inputValue, null, false);
} else if (inputValue instanceof Long) {
// convert Integer variable to Long
variable = Long.valueOf((Integer) variable);
Variables.setVariable(varName, (Long) variable + (Long) inputValue, null, false);
}
} else {
// Not supported input type
plugin.getLogger().log(Level.WARNING, "Unsupported variable type in add action (" + variable.getClass().getName() + ") on variable: " + varName);
continue;
}
break;
case "REMOVE":
if (varName.charAt(varName.length() - 1) == '*') {
plugin.getLogger().log(Level.WARNING, "Removing from {::*} variables in RediSkript is not supported. Variable name: " + varName);
continue;
}
variable = Variables.getVariable(varName, null, false);
if (variable == null) {
if (inputValue instanceof Long) {
Variables.setVariable(varName, -(Long) inputValue, null, false);
} else if (inputValue instanceof Double) {
Variables.setVariable(varName, -(Double) inputValue, null, false);
} else if (inputValue instanceof Integer) {
Variables.setVariable(varName, -(Integer) inputValue, null, false);
} else {
// Not supported input type
plugin.getLogger().log(Level.WARNING, "Unsupported remove action of data type (" + inputValue.getClass().getName() + ") on variable: " + varName);
continue;
}
} else if (variable instanceof Long) {
if (inputValue instanceof Integer) {
inputValue = Long.valueOf((Integer) inputValue);
}
if (inputValue instanceof Long) {
Variables.setVariable(varName, (Long) variable - (Long) inputValue, null, false);
} else if (inputValue instanceof Double) {
// convert Long variable to Double
variable = Double.valueOf((Long) variable);
Variables.setVariable(varName, (Double) variable - (Double) inputValue, null, false);
} else {
// Not supported input type
plugin.getLogger().log(Level.WARNING, "Unsupported remove action of data type (" + inputValue.getClass().getName() + ") on variable: " + varName);
continue;
}
} else if (variable instanceof Double) {
if (inputValue instanceof Integer) {
inputValue = Double.valueOf((Integer) inputValue);
}
if (inputValue instanceof Double) {
Variables.setVariable(varName, (Double) variable - (Double) inputValue, null, false);
} else if (inputValue instanceof Long) {
Variables.setVariable(varName, (Double) variable - ((Long) inputValue).doubleValue(), null, false);
}
} else if (variable instanceof Integer) {
if (inputValue instanceof Integer) {
Variables.setVariable(varName, (Integer) variable - (Integer) inputValue, null, false);
} else if (inputValue instanceof Long) {
// convert Integer variable to Long
variable = Long.valueOf((Integer) variable);
Variables.setVariable(varName, (Long) variable - (Long) inputValue, null, false);
} else if (inputValue instanceof Double) {
// convert Integer variable to Double
variable = Double.valueOf((Integer) variable);
Variables.setVariable(varName, (Double) variable - (Double) inputValue, null, false);
}
} else {
// Not supported input type
plugin.getLogger().log(Level.WARNING, "Unsupported variable type in remove action (" + variable.getClass().getName() + ") on variable: " + varName);
continue;
}
break;
case "SET":
//this is needed, because setting a {variable::*} causes weird behavior, like
//1st set operation is no data, 2nd has data, etc.
//if you set it to null before action, it works correctly
if (varName.charAt(varName.length() - 1) == '*') {
Variables.setVariable(varName, null, null, false);
}
Variables.setVariable(varNames.get(i).toString(), inputValue, null, false);
break;
}
}
}
}
}
} catch (Exception e) {
plugin.sendErrorLogs("&cI got a message that was empty from channel " + channelString + " please check your code that you used to send the message. Message content:");
plugin.sendErrorLogs(receivedMessage);
e.printStackTrace();
}
}
public void sendMessage(String[] message, String channel) {
JSONObject json = new JSONObject();
json.put("Messages", new JSONArray(message));
json.put("Type", "Skript");
json.put("Date", System.currentTimeMillis()); //for unique string every time & PING calculations
finishSendMessage(json, channel);
}
public void sendVariables(String[] variableNames, String[] variableValues, String channel, String operation) {
JSONObject json = new JSONObject();
json.put("Names", new JSONArray(variableNames));
if (variableValues != null) {
json.put("Values", new JSONArray(variableValues));
}
json.put("Type", "SkriptVariables");
json.put("Date", System.currentTimeMillis()); //for unique string every time & PING calculations
json.put("Operation", operation);
finishSendMessage(json, channel);
}
public void finishSendMessage(JSONObject json, String channel) {
try {
byte[] message;
if (encryption.isEncryptionEnabled()) {
message = encryption.encrypt(json.toString());
} else {
message = json.toString().getBytes(StandardCharsets.UTF_8);
}
//sending a redis message blocks main thread if there's no more connections available
//so to avoid issues, it's best to do it always on separate thread
if (plugin.isEnabled()) {
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
try (Jedis j = jedisPool.getResource()) {
j.publish(channel.getBytes(StandardCharsets.UTF_8), message);
} catch (Exception e) {
plugin.sendErrorLogs("Error sending redis message!");
e.printStackTrace();
}
});
} else {
//execute sending of redis message on the main thread if plugin is disabling
//so it can still process the sending
try (Jedis j = jedisPool.getResource()) {
j.publish(channel.getBytes(StandardCharsets.UTF_8), message);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (JedisConnectionException exception) {
exception.printStackTrace();
}
}
private void setupChannels(Configuration config) {
List<String> channels = config.getStringList("Channels");
channelsInByte = new byte[channels.size()][1];
for (int x = 0; x < channels.size(); x++) {
channelsInByte[x] = channels.get(x).getBytes(StandardCharsets.UTF_8);
}
}
public Boolean isRedisConnectionOffline() {
return isConnectionBroken.get();
}
// for skript reflect :)
public JedisPool getJedisPool() {
return jedisPool;
}
//
}
-14
View File
@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>RediSkript</artifactId>
<groupId>net.limework</groupId>
<version>1.3.7-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>RediSkript-core</artifactId>
</project>
@@ -1,11 +0,0 @@
package net.limework.rediskript;
import redis.clients.jedis.BinaryJedisPubSub;
public abstract class Subscriber extends BinaryJedisPubSub implements Runnable {
}
+74
View File
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.destroystokyo.paper:paper-api:1.15-R0.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.ow2.asm:asm:7.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.ow2.asm:asm-commons:7.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.ow2.asm:asm-tree:7.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.ow2.asm:asm-analysis:7.1" level="project" />
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.6" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains:annotations:19.0.0" level="project" />
<orderEntry type="library" name="Maven: redis.clients:jedis:3.4.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.github.SkriptLang:Skript:2.5.3" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.destroystokyo.paper:paper-api:1.16.4-R0.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: junit:junit:4.10" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.ow2.asm:asm:8.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.ow2.asm:asm-commons:8.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.ow2.asm:asm-tree:8.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.ow2.asm:asm-analysis:8.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.eclipse.jdt:org.eclipse.jdt.annotation:1.1.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:findbugs:3.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.jcip:jcip-annotations:1.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:bcel-findbugs:6.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jFormatString:2.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: dom4j:dom4j:1.6.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: xml-apis:xml-apis:1.0.b2" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.ow2.asm:asm-debug-all:5.0.2" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.apple:AppleJavaExtensions:1.4" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: jaxen:jaxen:1.1.6" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.sk89q.worldguard:worldguard-legacy:7.0.0-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.bukkit:bukkit:1.13-R0.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.sk89q.worldedit:worldedit-bukkit:7.0.0-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.sk89q.worldedit:worldedit-core:7.0.0-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.sk89q.worldedit.worldedit-libs:core:7.0.0-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: de.schlichtherle:truezip:6.8.3" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: rhino:js:1.7R2" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.sk89q.worldedit.worldedit-libs:bukkit:7.0.0-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.logging.log4j:log4j-slf4j-impl:2.8.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.logging.log4j:log4j-api:2.8.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.sk89q.worldguard:worldguard-core:7.0.0-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.sk89q.intake:intake:4.2-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.sk89q:squirrelid:0.2.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.flywaydb:flyway-core:3.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.khelekore:prtree:1.5.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.sk89q:commandbook:2.3" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.bstats:bstats-bukkit:1.4" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.github.marcelo-mason:PreciousStones:24e3d4bf67b7240ae36b32be10e99d4091938c5c" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: ant-contrib:ant-contrib:1.0b3" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.milkbowl.vault:Vault:1.7.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: io.papermc:paperlib:1.0.5" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: commons-lang:commons-lang:2.6" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:21.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.gson:gson:2.8.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.md-5:bungeecord-chat:1.16-R0.4" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.yaml:snakeyaml:1.27" level="project" />
<orderEntry type="library" name="Maven: redis.clients:jedis:3.5.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.json:json:20201115" level="project" />
<orderEntry type="library" name="Maven: org.cryptomator:siv-mode:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.6.2" level="project" />
</component>
</module>
+84 -30
View File
@@ -6,14 +6,59 @@
<groupId>net.limework</groupId> <groupId>net.limework</groupId>
<artifactId>RediSkript</artifactId> <artifactId>RediSkript</artifactId>
<version>1.3.7-SNAPSHOT</version> <version>1.3.3</version>
<modules> <packaging>jar</packaging>
<module>RediSkript-core</module>
<module>RediSkript-bukkit</module> <build>
</modules> <resources>
<packaging>pom</packaging> <resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<outputDirectory>${project.basedir}/compile</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
<repositories> <repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/org/spigotmc/spigot-api/</url>
</repository>
<repository> <repository>
<id>jitpack.io</id> <id>jitpack.io</id>
<url>https://jitpack.io</url> <url>https://jitpack.io</url>
@@ -22,44 +67,53 @@
<id>commons-pool2</id> <id>commons-pool2</id>
<url>https://mvnrepository.com/artifact/org.apache.commons/commons-pool2</url> <url>https://mvnrepository.com/artifact/org.apache.commons/commons-pool2</url>
</repository> </repository>
<repository>
<id>PaperMC</id>
<url>https://repo.destroystokyo.com/repository/maven-public/</url>
</repository>
<repository>
<id>sk89q</id>
<url>http://maven.sk89q.com/repo</url>
</repository>
</repositories> </repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
<dependencies> <dependencies>
<dependency>
<groupId>com.github.SkriptLang</groupId>
<artifactId>Skript</artifactId>
<version>2.5.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.16.5-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.5.1</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
<groupId>org.json</groupId> <groupId>org.json</groupId>
<artifactId>json</artifactId> <artifactId>json</artifactId>
<version>20220320</version> <version>20201115</version>
<scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>siv-mode</artifactId> <artifactId>siv-mode</artifactId>
<version>1.5.0</version> <version>1.4.1</version>
<scope>compile</scope>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 --> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId> <artifactId>commons-pool2</artifactId>
<version>2.11.1</version> <version>2.6.2</version>
</dependency> <scope>compile</scope>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.4.6</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>
@@ -10,7 +10,6 @@ import net.limework.rediskript.commands.CommandReloadRedis;
import net.limework.rediskript.events.RedisMessageEvent; import net.limework.rediskript.events.RedisMessageEvent;
import net.limework.rediskript.managers.RedisController; import net.limework.rediskript.managers.RedisController;
import net.limework.rediskript.skript.elements.*; import net.limework.rediskript.skript.elements.*;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
@@ -90,12 +89,4 @@ public class RediSkript extends JavaPlugin {
public RedisController getRC() { public RedisController getRC() {
return redisController; return redisController;
} }
//Developer note: This is use for skript-reflect! and also for plugin use for static stuff -> skript effects classes
//DO NOT USE THIS IN NON STATIC CLASSES
public static RediSkript getAPI(){
//this safer than making static.
return (RediSkript) Bukkit.getServer().getPluginManager().getPlugin("RediSkript");
}
} }
@@ -1,5 +1,6 @@
package net.limework.rediskript.data; package net.limework.rediskript.data;
import org.bukkit.configuration.Configuration;
import org.cryptomator.siv.SivMode; import org.cryptomator.siv.SivMode;
import org.cryptomator.siv.UnauthenticCiphertextException; import org.cryptomator.siv.UnauthenticCiphertextException;
@@ -8,17 +9,17 @@ import java.nio.charset.StandardCharsets;
public class Encryption { public class Encryption {
private final boolean encryptionEnabled; private boolean encryptionEnabled;
private String encryptionKey; private String encryptionKey;
private String macKey; private String macKey;
private final SivMode AES_SIV = new SivMode(); private final SivMode AES_SIV = new SivMode();
public Encryption(boolean encryptionEnabled, String encryptionKey, String macKey){ public Encryption(Configuration config){
this.encryptionEnabled = encryptionEnabled; encryptionEnabled = config.getBoolean("Redis.EncryptMessages");
if (this.encryptionEnabled) { if (encryptionEnabled) {
// AES encryption // AES encryption
this.encryptionKey = encryptionKey; encryptionKey = config.getString("Redis.EncryptionKey");
this.macKey = macKey; macKey = config.getString("Redis.MacKey");
} }
} }
@@ -0,0 +1,258 @@
package net.limework.rediskript.managers;
import ch.njol.skript.registrations.Classes;
import ch.njol.skript.variables.Variables;
import net.limework.rediskript.RediSkript;
import net.limework.rediskript.data.Encryption;
import net.limework.rediskript.events.RedisMessageEvent;
import org.bukkit.Bukkit;
import org.bukkit.configuration.Configuration;
import org.bukkit.scheduler.BukkitTask;
import org.cryptomator.siv.UnauthenticCiphertextException;
import org.json.JSONArray;
import org.json.JSONObject;
import redis.clients.jedis.*;
import redis.clients.jedis.exceptions.JedisConnectionException;
import javax.crypto.IllegalBlockSizeException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
public class RedisController extends BinaryJedisPubSub implements Runnable {
//Jedis Pool to be used by every another class.
private final JedisPool jedisPool;
//this seems useless unless tls is OFF!
private final Encryption encryption;
private byte[][] channelsInByte;
private final AtomicBoolean isConnectionBroken;
private final AtomicBoolean isConnecting;
private final RediSkript plugin;
private final BukkitTask ConnectionTask;
public RedisController(RediSkript plugin) {
this.plugin = plugin;
Configuration config = plugin.getConfig();
JedisPoolConfig JConfig = new JedisPoolConfig();
int maxConnections = config.getInt("Redis.MaxConnections");
//do not allow less than 2 max connections as that causes issues
if (maxConnections < 2) { maxConnections = 2; }
JConfig.setMaxTotal(maxConnections);
JConfig.setMaxIdle(maxConnections);
JConfig.setMinIdle(1);
JConfig.setBlockWhenExhausted(true);
this.jedisPool = new JedisPool(JConfig,
config.getString("Redis.Host"),
config.getInt("Redis.Port"),
config.getInt("Redis.TimeOut"),
config.getString("Redis.Password"),
config.getBoolean("Redis.useTLS"));
encryption = new Encryption(config);
setupChannels(config);
isConnectionBroken = new AtomicBoolean(true);
isConnecting = new AtomicBoolean(false);
//Start the main task on async thread
ConnectionTask = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, this, 0, 20 * 5);
}
@Override
public void run() {
if (!isConnectionBroken.get() || isConnecting.get()) {
return;
}
plugin.sendLogs("Connecting to Redis server...");
isConnecting.set(true);
try (Jedis jedis = jedisPool.getResource()) {
isConnectionBroken.set(false);
plugin.sendLogs("&aConnection to Redis server has established! Success!");
jedis.subscribe(this, channelsInByte);
} catch (Exception e) {
isConnecting.set(false);
isConnectionBroken.set(true);
plugin.sendErrorLogs("Connection to Redis server has failed! Please check your details in the configuration.");
e.printStackTrace();
}
}
public void shutdown() {
ConnectionTask.cancel();
if (this.isSubscribed()) {
try {
this.unsubscribe();
} catch (Exception e) {
plugin.sendErrorLogs("Something went wrong during unsubscribing...");
e.printStackTrace();
}
}
jedisPool.close();
}
@Override
public void onMessage(byte[] channel, byte[] message){
String channelString = new String(channel, StandardCharsets.UTF_8);
String receivedMessage = null;
try {
//if encryption is enabled, decrypt the message, else just convert binary to string
if (this.encryption.isEncryptionEnabled()) {
try {
receivedMessage = encryption.decrypt(message);
} catch (UnauthenticCiphertextException | IllegalBlockSizeException e) {
e.printStackTrace();
}
} else {
//encryption is disabled, so let's just get the string
receivedMessage = new String(message, StandardCharsets.UTF_8);
}
if (receivedMessage != null) {
JSONObject j = new JSONObject(receivedMessage);
if (j.get("Type").equals("Skript")) {
JSONArray messages = j.getJSONArray("Messages");
RedisMessageEvent event;
for (int i = 0; i < messages.length(); i++) {
event = new RedisMessageEvent(channelString, messages.get(i).toString(), j.getLong("Date"));
//if plugin is disabling, don't call events anymore
if (plugin.isEnabled()) {
RedisMessageEvent finalEvent = event;
Bukkit.getScheduler().runTask(plugin, () -> plugin.getServer().getPluginManager().callEvent(finalEvent));
}
}
} else if (j.get("Type").equals("SkriptVariables")) {
//Transfer variables between servers
JSONArray variableNames = j.getJSONArray("Names");
Object inputValue;
String changeValue = null;
JSONArray variableValues = null;
if (!j.isNull("Values")) {
variableValues = j.getJSONArray("Values");
}
for (int i = 0; i < variableNames.length(); i++) {
if (j.isNull("Values")) {
//only check for SET here, because null has to be ignored in all other cases
if (j.getString("Operation").equals("SET")) {
Variables.setVariable(variableNames.get(i).toString(), null, null, false);
}
} else {
if (!variableValues.isNull(i)) {
changeValue = variableValues.get(i).toString();
}
String[] inputs = changeValue.split("\\^", 2);
inputValue = Classes.deserialize(inputs[0], Base64.getDecoder().decode(inputs[1]));
switch (j.getString("Operation")) {
case "ADD":
//I will add this once someone tells me how to remove from Skript variable
//because using SET operation has issues with inconvertible types (Double and Long)
//variable = (Variable) Variables.getVariable(variableNames.get(i).toString(), null, false);
// variable.change(null, (Object[]) inputValue, Changer.ChangeMode.REMOVE);
case "REMOVE":
//I will add this once someone tells me how to remove from Skript variable
//because using SET operation has issues with inconvertible types (Double and Long)
//variable = (Variable) Variables.getVariable(variableNames.get(i).toString(), null, false);
// variable.change(null, (Object[]) inputValue, Changer.ChangeMode.REMOVE);
break;
case "SET":
String variableName = variableNames.get(i).toString();
//this is needed, because setting a {variable::*} causes weird behavior, like
//1st set operation is no data, 2nd has data, etc.
//if you set it to null before action, it works correctly
if (variableName.charAt(variableName.length()-1) == '*') {
Variables.setVariable(variableName, null, null, false);
}
Variables.setVariable(variableNames.get(i).toString(), inputValue, null, false);
}
}
}
}
}
} catch (Exception e) {
plugin.sendErrorLogs("&cI got a message that was empty from channel " + channelString + " please check your code that you used to send the message. Message content:");
plugin.sendErrorLogs(receivedMessage);
e.printStackTrace();
}
}
public void sendMessage(String[] message, String channel) {
JSONObject json = new JSONObject();
json.put("Messages", new JSONArray(message));
json.put("Type", "Skript");
json.put("Date", System.currentTimeMillis()); //for unique string every time & PING calculations
finishSendMessage(json, channel);
}
public void sendVariables(String[] variableNames, String[] variableValues, String channel, String operation) {
JSONObject json = new JSONObject();
json.put("Names", new JSONArray(variableNames));
if (variableValues != null) {
json.put("Values", new JSONArray(variableValues));
}
json.put("Type", "SkriptVariables");
json.put("Date", System.currentTimeMillis()); //for unique string every time & PING calculations
json.put("Operation", operation);
finishSendMessage(json, channel);
}
public void finishSendMessage(JSONObject json, String channel) {
try {
byte[] message;
if (encryption.isEncryptionEnabled()) {
message = encryption.encrypt(json.toString());
} else {
message = json.toString().getBytes(StandardCharsets.UTF_8);
}
//sending a redis message blocks main thread if there's no more connections available
//so to avoid issues, it's best to do it always on separate thread
if (plugin.isEnabled()) {
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
try (BinaryJedis j = jedisPool.getResource()) {
j.publish(channel.getBytes(StandardCharsets.UTF_8), message);
} catch (Exception e) {
plugin.sendErrorLogs("Error sending redis message!");
e.printStackTrace();
}
});
} else {
//execute sending of redis message on the main thread if plugin is disabling
//so it can still process the sending
try (BinaryJedis j = jedisPool.getResource()) {
j.publish(channel.getBytes(StandardCharsets.UTF_8), message);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (JedisConnectionException exception) {
exception.printStackTrace();
}
}
private void setupChannels(Configuration config) {
List<String> channels = config.getStringList("Channels");
channelsInByte = new byte[channels.size()][1];
for (int x = 0; x < channels.size(); x++) {
channelsInByte[x] = channels.get(x).getBytes(StandardCharsets.UTF_8);
}
}
public Boolean isRedisConnectionOffline() {
return isConnectionBroken.get();
}
}
@@ -23,7 +23,7 @@ public class EffSendMessage extends Effect {
@Override @Override
protected void execute(Event event) { protected void execute(Event event) {
RediSkript plugin = RediSkript.getAPI(); RediSkript plugin = (RediSkript) Bukkit.getPluginManager().getPlugin("RediSkript");
String[] message = this.message.getAll(event); String[] message = this.message.getAll(event);
String channel = this.channel.getSingle(event); String channel = this.channel.getSingle(event);
@@ -29,7 +29,10 @@ public class ExprChannel extends SimpleExpression<String> {
@Override @Override
public boolean init(final Expression<?>[] expressions, final int matchedPattern, final Kleenean isDelayed, final SkriptParser.ParseResult parseResult) { public boolean init(final Expression<?>[] expressions, final int matchedPattern, final Kleenean isDelayed, final SkriptParser.ParseResult parseResult) {
if (!ScriptLoader.isCurrentEvent(RedisMessageEvent.class)) {
Skript.error("Cannot use 'redis channel' outside of a redis message event", ErrorQuality.SEMANTIC_ERROR);
return false;
}
return true; return true;
} }
@@ -0,0 +1,46 @@
package net.limework.rediskript.skript.elements;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser;
import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.util.Kleenean;
import org.bukkit.event.Event;
import org.eclipse.jdt.annotation.Nullable;
import redis.clients.jedis.Jedis;
@SuppressWarnings("unchecked")
public class ExprJedis extends SimpleExpression<Jedis> {
static {
}
private Jedis jedis;
@Nullable
@Override
protected Jedis[] get(Event event) {
return new Jedis[]{jedis};
}
@Override
public boolean isSingle() {
return true;
}
@Override
public Class<? extends Jedis> getReturnType() {
return Jedis.class;
}
@Override
public String toString(@Nullable Event event, boolean b) {
return null;
}
@Override
public boolean init(Expression<?>[] expressions, int i, Kleenean kleenean, SkriptParser.ParseResult parseResult) {
return false;
}
}
@@ -31,7 +31,10 @@ public class ExprMessage extends SimpleExpression<String> {
@Override @Override
public boolean init(final Expression<?>[] expressions, final int matchedPattern, final Kleenean isDelayed, final SkriptParser.ParseResult parseResult) { public boolean init(final Expression<?>[] expressions, final int matchedPattern, final Kleenean isDelayed, final SkriptParser.ParseResult parseResult) {
if (!ScriptLoader.isCurrentEvent(RedisMessageEvent.class)) {
Skript.error("Cannot use 'redis message' outside of a redis message event", ErrorQuality.SEMANTIC_ERROR);
return false;
}
return true; return true;
} }
@@ -32,7 +32,10 @@ public class ExprMessageDate extends SimpleExpression<Date> {
@Override @Override
public boolean init(final Expression<?>[] expressions, final int matchedPattern, final Kleenean isDelayed, final SkriptParser.ParseResult parseResult) { public boolean init(final Expression<?>[] expressions, final int matchedPattern, final Kleenean isDelayed, final SkriptParser.ParseResult parseResult) {
if (!ScriptLoader.isCurrentEvent(RedisMessageEvent.class)) {
Skript.error("Cannot use 'redis message date' outside of a redis message event", ErrorQuality.SEMANTIC_ERROR);
return false;
}
return true; return true;
} }
@Override @Override
@@ -73,7 +73,7 @@ public class ExprVariableInChannel extends SimpleExpression<Object> {
@Override @Override
public Class<?>[] acceptChange(Changer.ChangeMode mode) { public Class<?>[] acceptChange(Changer.ChangeMode mode) {
//if (mode == Changer.ChangeMode.DELETE || mode == Changer.ChangeMode.SET || mode == Changer.ChangeMode.ADD || mode == Changer.ChangeMode.REMOVE) //if (mode == Changer.ChangeMode.DELETE || mode == Changer.ChangeMode.SET || mode == Changer.ChangeMode.ADD || mode == Changer.ChangeMode.REMOVE)
if (mode == Changer.ChangeMode.DELETE || mode == Changer.ChangeMode.SET || mode == Changer.ChangeMode.ADD || mode == Changer.ChangeMode.REMOVE) if (mode == Changer.ChangeMode.DELETE || mode == Changer.ChangeMode.SET)
return CollectionUtils.array(Object.class); return CollectionUtils.array(Object.class);
return null; return null;
@@ -0,0 +1,33 @@
package net.limework.rediskript.skript.elements;
import ch.njol.skript.classes.ClassInfo;
import ch.njol.skript.classes.Parser;
import ch.njol.skript.registrations.Classes;
import redis.clients.jedis.Jedis;
public class Types {
static {
Classes.registerClass(
new ClassInfo<>(Jedis.class, "jedis")
.user("JedisInstances?")
.parser(new Parser<Jedis>() {
@Override
public String toString(Jedis t, int i) {
return t.toString();
}
@Override
public String toVariableNameString(Jedis t) {
return t.toString();
}
@Override
public String getVariableNamePattern() {
return "jedis:+";
}
}));
}
}
@@ -23,13 +23,13 @@ Redis:
#the encryption configuration must be the same across all servers in order to communicate #the encryption configuration must be the same across all servers in order to communicate
#use 16 characters long key for AES-128 encryption #use 16 characters long key for AES-128 encryption
#32 characters long key for AES-256 encryption (recommended) #32 characters long key for AES-256 encryption
#AES-128 is faster, but less secure (but it is not crackable by today's technology as of 2020, may be crackable by quantum computers) #AES-128 is faster, but less secure (but it is not crackable by today's technology as of 2020, may be crackable by quantum computers)
#the AES implementation used in RediSkript uses SIV mode, which makes the same key resistant to cracking for a big count of messages without the need of changing the key very often #the AES implementation used in RediSkript uses SIV mode, which makes the same key resistant to cracking for a big count of messages without the need of changing the key very often
EncryptMessages: true EncryptMessages: true
#EncryptionKey and MacKey must be different #EncryptionKey and MacKey must be different
EncryptionKey: "32CHARACTERS KEY" EncryptionKey: "16CHARACTERS KEY"
MacKey: "32CHARACTERS KEY" MacKey: "16CHARACTERS KEY"
#the channels from which this server can receive messages #the channels from which this server can receive messages
@@ -41,4 +41,4 @@ Redis:
Channels: Channels:
- "global" - "global"
- "servername" - "servername"
- "Channel3" - "Channel3"
@@ -1,10 +1,9 @@
main: net.limework.rediskript.RediSkript main: net.limework.rediskript.RediSkript
name: RediSkript name: ${project.name}
version: ${project.version} version: ${project.version}
authors: [Govindas, ham1255, DaemonicKing, limework.net] authors: [Govindas, ham1255, DaemonicKing, limework.net]
api-version: 1.13 api-version: 1.13
depend: [Skript] depend: [Skript]
commands: commands:
reloadredis: reloadredis:
description: "Reload redis configuration & restart the connection." description: "Reload redis configuration & restart the connection."
permission: reload.redis