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-10-22 09:32:08 +00:00
import net.limework.data.Encryption ;
2020-06-28 14:40:53 +00:00
import net.limework.core.events.RedisMessageEvent ;
2020-07-28 06:44:00 +00:00
import net.md_5.bungee.api.chat.TextComponent ;
2020-05-10 06:52:06 +00:00
import org.bukkit.Bukkit ;
import org.bukkit.ChatColor ;
2020-07-28 06:44:00 +00:00
import org.bukkit.command.Command ;
import org.bukkit.command.CommandExecutor ;
import org.bukkit.command.CommandSender ;
2020-06-28 14:40:53 +00:00
import org.bukkit.configuration.Configuration ;
2020-07-28 06:44:00 +00:00
import org.bukkit.entity.Player ;
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-07-28 06:44:00 +00:00
public class RedisManager extends BinaryJedisPubSub implements Runnable , CommandExecutor {
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 ;
2020-07-30 05:35:50 +00:00
private AtomicBoolean isKilled = new AtomicBoolean ( ) ;
2020-06-28 14:40:53 +00:00
//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 ) ;
private AtomicBoolean isRedisOnline = new AtomicBoolean ( ) ;
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 ( ) ;
JConfig . setMaxTotal ( config . getInt ( " Redis.MaxConnections " ) ) ;
JConfig . setMaxIdle ( config . getInt ( " Redis.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.useSSL " ) ) ;
RedisService = Executors . newFixedThreadPool ( config . getInt ( " Redis.Threads " ) ) ;
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-07-30 05:35:50 +00:00
isKilled . set ( false ) ;
2020-05-10 19:10:45 +00:00
try {
2020-06-14 13:43:46 +00:00
message ( " &e[Jedis] &cConnecting to redis........... " ) ;
2020-06-28 14:40:53 +00:00
if ( ! this . subscribeJedis . isConnected ( ) ) this . subscribeJedis = this . jedisPool . getResource ( ) ;
2020-06-14 13:43:46 +00:00
isRedisOnline . set ( true ) ;
message ( " &e[Jedis] &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 + + ) {
channelsInByte [ x ] = channels . get ( x ) . getBytes ( ) ;
}
} 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-06-26 13:02:39 +00:00
} catch ( Exception e ) {
2020-06-14 13:43:46 +00:00
message ( " &e[Jedis] &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
isRedisOnline . set ( false ) ;
}
try {
Thread . sleep ( 1000 ) ;
} catch ( InterruptedException e ) {
e . printStackTrace ( ) ;
2020-05-10 19:10:45 +00:00
}
2020-07-30 05:35:50 +00:00
if ( isKilled . get ( ) ) break ;
2020-05-10 19:10:45 +00:00
}
2020-05-10 06:52:06 +00:00
}
2020-06-26 13:02:39 +00:00
private void message ( String message ) {
2020-06-14 13:43:46 +00:00
plugin . getLogger ( ) . info ( ChatColor . translateAlternateColorCodes ( '&' , message ) ) ;
}
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-05-10 06:52:06 +00:00
try {
2020-10-22 09:32:08 +00:00
String receivedMessage = null ;
//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 ) ;
2020-10-22 10:30:41 +00:00
System . out . println ( receivedMessage ) ;
2020-10-22 09:32:08 +00:00
}
if ( receivedMessage ! = null ) {
JSONObject j = new JSONObject ( receivedMessage ) ;
//System.out.println("Message got from channel: "+channel +" and the Message: " +json.toString());
plugin . getServer ( ) . getPluginManager ( ) . callEvent ( new RedisMessageEvent ( channelString , j . getString ( " Message " ) ) ) ;
2020-06-08 13:53:23 +00:00
}
2020-05-10 06:52:06 +00:00
} catch ( Exception e ) {
e . printStackTrace ( ) ;
2020-10-22 10:30:41 +00:00
Bukkit . getLogger ( ) . warning ( ChatColor . translateAlternateColorCodes ( '&' , " &2[&aRedisk&a] &cI got a message that was empty from channel " + channelString + " please check your code that you used to send the message. ^ ignore the error. " ) ) ;
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-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-05-10 19:10:45 +00:00
2020-06-14 13:43:46 +00:00
public boolean IsRedisOnline ( ) {
return isRedisOnline . get ( ) ;
}
2020-06-28 14:40:53 +00:00
public JedisPool getJedisPool ( ) {
return jedisPool ;
}
public ExecutorService getRedisService ( ) {
return RedisService ;
}
public AtomicBoolean getIsShuttingDown ( ) {
return isShuttingDown ;
}
public AtomicBoolean getIsRedisOnline ( ) {
return isRedisOnline ;
}
public Encryption getEncryption ( ) {
return encryption ;
}
2020-07-28 06:44:00 +00:00
2020-10-22 09:32:08 +00:00
// the /reloadredis command
2020-07-28 06:44:00 +00:00
@Override
public boolean onCommand ( CommandSender sender , Command cmd , String lable , String [ ] args ) {
if ( sender instanceof Player ) {
sender . sendMessage ( TextComponent . fromLegacyText ( ChatColor . translateAlternateColorCodes ( '&'
2020-10-22 09:32:08 +00:00
, " &cYou cannot execute this command. " ) ) ) ;
2020-07-28 06:44:00 +00:00
return true ;
}
2020-07-30 05:35:50 +00:00
isKilled . set ( true ) ;
2020-07-28 06:53:42 +00:00
try {
if ( this . subscribeJedis ! = null ) {
this . unsubscribe ( ) ;
this . subscribeJedis . close ( ) ;
}
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
2020-07-28 06:44:00 +00:00
start ( ) ;
return false ;
}
2020-06-28 14:40:53 +00:00
}