2020-06-30 07:45:14 +00:00
package net.limework.core.managers ;
2020-05-10 06:52:06 +00:00
2020-10-22 10:30:41 +00:00
import net.limework.core.RediSkript ;
2020-06-28 14:40:53 +00:00
import net.limework.core.events.RedisMessageEvent ;
2020-10-23 11:34:30 +00:00
import net.limework.data.Encryption ;
2020-05-10 06:52:06 +00:00
import org.bukkit.Bukkit ;
import org.bukkit.ChatColor ;
2020-06-28 14:40:53 +00:00
import org.bukkit.configuration.Configuration ;
2020-06-08 13:53:23 +00:00
import org.cryptomator.siv.UnauthenticCiphertextException ;
2020-05-10 06:52:06 +00:00
import org.json.JSONObject ;
2020-06-08 13:53:23 +00:00
import redis.clients.jedis.BinaryJedis ;
import redis.clients.jedis.BinaryJedisPubSub ;
2020-06-28 14:40:53 +00:00
import redis.clients.jedis.JedisPool ;
import redis.clients.jedis.JedisPoolConfig ;
2020-05-10 06:52:06 +00:00
2020-06-08 13:53:23 +00:00
import javax.crypto.IllegalBlockSizeException ;
2020-10-22 09:32:08 +00:00
import java.nio.charset.StandardCharsets ;
2020-05-10 06:52:06 +00:00
import java.util.List ;
2020-06-28 14:40:53 +00:00
import java.util.concurrent.ExecutorService ;
import java.util.concurrent.Executors ;
2020-06-14 13:43:46 +00:00
import java.util.concurrent.atomic.AtomicBoolean ;
2020-05-10 06:52:06 +00:00
2020-10-23 11:34:30 +00:00
public class RedisManager extends BinaryJedisPubSub implements Runnable {
2020-05-10 19:10:45 +00:00
2020-10-22 10:30:41 +00:00
private RediSkript plugin ;
2020-05-10 19:10:45 +00:00
2020-06-28 14:40:53 +00:00
private JedisPool jedisPool ;
private ExecutorService RedisService ;
//sub
private BinaryJedis subscribeJedis ;
2020-06-08 13:53:23 +00:00
private List < String > channels ;
2020-06-14 13:43:46 +00:00
private AtomicBoolean isShuttingDown = new AtomicBoolean ( false ) ;
2020-06-28 14:40:53 +00:00
private Encryption encryption ;
2020-06-14 13:43:46 +00:00
2020-05-10 19:10:45 +00:00
2020-10-22 10:30:41 +00:00
public RedisManager ( RediSkript plugin ) {
2020-05-10 06:52:06 +00:00
this . plugin = plugin ;
2020-06-28 14:40:53 +00:00
Configuration config = this . plugin . getConfig ( ) ;
JedisPoolConfig JConfig = new JedisPoolConfig ( ) ;
2020-10-24 10:29:49 +00:00
int maxConnections = config . getInt ( " Redis.MaxConnections " ) ;
if ( maxConnections < 2 ) { maxConnections = 2 ; }
JConfig . setMaxTotal ( maxConnections ) ;
JConfig . setMaxIdle ( maxConnections ) ;
2020-06-28 14:40:53 +00:00
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 " ) ,
2020-10-24 09:35:35 +00:00
config . getBoolean ( " Redis.useTLS " ) ) ;
2020-10-24 10:29:49 +00:00
RedisService = Executors . newSingleThreadExecutor ( ) ;
2020-07-28 06:44:00 +00:00
try {
this . subscribeJedis = this . jedisPool . getResource ( ) ;
} catch ( Exception ignored ) {
}
2020-06-28 14:40:53 +00:00
this . channels = config . getStringList ( " Channels " ) ;
encryption = new Encryption ( config ) ;
}
2020-07-28 06:44:00 +00:00
public void start ( ) {
2020-06-28 14:40:53 +00:00
this . RedisService . execute ( this ) ;
2020-05-10 19:10:45 +00:00
}
2020-05-10 17:44:10 +00:00
2020-05-10 19:10:45 +00:00
@Override
2020-06-26 13:02:39 +00:00
public void run ( ) {
while ( ! isShuttingDown . get ( ) ) {
2020-05-10 19:10:45 +00:00
try {
2020-10-23 13:49:25 +00:00
plugin . getLogger ( ) . info ( ChatColor . translateAlternateColorCodes ( '&' , " &2[&aRediSkript&a] &cConnecting to redis... " ) ) ;
2020-06-28 14:40:53 +00:00
if ( ! this . subscribeJedis . isConnected ( ) ) this . subscribeJedis = this . jedisPool . getResource ( ) ;
2020-10-23 13:49:25 +00:00
plugin . getLogger ( ) . info ( ChatColor . translateAlternateColorCodes ( '&' , " &2[&aRediSkript&a] &aRedis connected! " ) ) ;
2020-06-26 13:02:39 +00:00
int byteArr2dSize = 1 ;
byte [ ] [ ] channelsInByte = new byte [ channels . size ( ) ] [ byteArr2dSize ] ;
boolean reInitializeByteArray ;
// Loop that reInitialize array IF array size is not enough
do {
reInitializeByteArray = false ;
try {
/* Data Initialization for channelsInByte array from List<String> channels */
for ( int x = 0 ; x < channels . size ( ) ; x + + ) {
2020-10-22 11:19:29 +00:00
channelsInByte [ x ] = channels . get ( x ) . getBytes ( StandardCharsets . UTF_8 ) ;
2020-06-26 13:02:39 +00:00
}
} catch ( ArrayIndexOutOfBoundsException ex ) {
reInitializeByteArray = true ;
/* Increase the current 2d array size to increase 1 and reinitialize the array*/
byteArr2dSize + = 1 ;
channelsInByte = new byte [ channels . size ( ) ] [ byteArr2dSize ] ;
}
} while ( reInitializeByteArray ) ;
2020-06-28 14:40:53 +00:00
this . subscribeJedis . subscribe ( this , channelsInByte ) ;
2020-10-24 10:29:49 +00:00
2020-06-26 13:02:39 +00:00
} catch ( Exception e ) {
2020-10-23 13:49:25 +00:00
plugin . getLogger ( ) . warning ( ChatColor . translateAlternateColorCodes ( '&' , " &2[&aRediSkript&a] &cConnection to redis has failed! &ereconnecting... " ) ) ;
2020-07-28 06:44:00 +00:00
if ( this . subscribeJedis ! = null ) {
this . subscribeJedis . close ( ) ;
}
2020-06-14 13:43:46 +00:00
}
try {
Thread . sleep ( 1000 ) ;
} catch ( InterruptedException e ) {
e . printStackTrace ( ) ;
2020-05-10 19:10:45 +00:00
}
}
2020-05-10 06:52:06 +00:00
}
@Override
2020-06-08 13:53:23 +00:00
public void onMessage ( byte [ ] channel , byte [ ] message ) {
2020-10-22 10:30:41 +00:00
String channelString = new String ( channel , StandardCharsets . UTF_8 ) ;
2020-10-22 14:44:45 +00:00
String receivedMessage = null ;
2020-05-10 06:52:06 +00:00
try {
2020-10-22 09:32:08 +00:00
//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 ) ;
//System.out.println("Message got from channel: "+channel +" and the Message: " +json.toString());
2020-10-23 13:49:25 +00:00
RedisMessageEvent event = new RedisMessageEvent ( channelString , j . getString ( " Message " ) , j . getLong ( " Date " ) ) ;
2020-10-24 12:19:10 +00:00
Bukkit . getScheduler ( ) . runTask ( plugin , ( ) - > plugin . getServer ( ) . getPluginManager ( ) . callEvent ( event ) ) ;
2020-06-08 13:53:23 +00:00
}
2020-05-10 06:52:06 +00:00
} catch ( Exception e ) {
e . printStackTrace ( ) ;
2020-10-22 14:44:45 +00:00
Bukkit . getLogger ( ) . warning ( ChatColor . translateAlternateColorCodes ( '&' , " &2[&aRediSkript&a] &cI got a message that was empty from channel " + channelString + " please check your code that you used to send the message. Message content: " ) ) ;
Bukkit . getLogger ( ) . warning ( receivedMessage ) ;
2020-05-10 06:52:06 +00:00
}
}
2020-06-26 13:02:39 +00:00
public void shutdown ( ) {
2020-06-14 13:43:46 +00:00
this . isShuttingDown . set ( true ) ;
2020-07-28 06:44:00 +00:00
if ( this . subscribeJedis ! = null ) {
2020-07-06 18:38:54 +00:00
this . unsubscribe ( ) ;
this . subscribeJedis . close ( ) ;
2020-10-23 14:48:22 +00:00
this . jedisPool . getResource ( ) . close ( ) ;
2020-07-06 18:38:54 +00:00
}
2020-06-28 14:40:53 +00:00
this . RedisService . shutdown ( ) ;
2020-07-06 18:38:54 +00:00
2020-05-10 06:52:06 +00:00
}
2020-10-23 13:49:25 +00:00
public void reload ( ) {
2020-10-24 09:32:40 +00:00
this . shutdown ( ) ;
plugin . startRedis ( true ) ;
2020-10-23 13:49:25 +00:00
}
2020-05-10 19:10:45 +00:00
2020-06-28 14:40:53 +00:00
public JedisPool getJedisPool ( ) {
return jedisPool ;
}
2020-10-23 11:34:30 +00:00
public Encryption getEncryption ( ) {
return encryption ;
2020-07-28 06:44:00 +00:00
}
2020-06-28 14:40:53 +00:00
}