2021-01-03 07:21:15 +00:00
package dev.plex.punishment ;
2020-11-06 18:51:47 +00:00
import com.google.common.collect.Lists ;
import com.google.common.collect.Maps ;
2022-02-28 06:28:00 +00:00
import com.google.common.reflect.TypeToken ;
import com.google.gson.Gson ;
2021-01-03 07:21:15 +00:00
import dev.plex.Plex ;
2022-02-04 08:18:07 +00:00
import dev.plex.PlexBase ;
2022-02-22 00:20:22 +00:00
import dev.plex.cache.PlayerCache ;
2022-02-28 06:28:00 +00:00
import dev.plex.player.PlexPlayer ;
2021-01-03 07:21:15 +00:00
import dev.plex.player.PunishedPlayer ;
2022-02-04 08:18:07 +00:00
import dev.plex.util.PlexLog ;
2021-01-03 07:21:15 +00:00
import dev.plex.util.PlexUtils ;
2020-11-06 18:51:47 +00:00
import java.io.File ;
import java.io.FileInputStream ;
import java.io.FileWriter ;
import java.io.IOException ;
2022-02-28 06:28:00 +00:00
import java.lang.reflect.Type ;
2020-11-06 18:51:47 +00:00
import java.nio.charset.StandardCharsets ;
2022-02-05 23:14:23 +00:00
import java.time.LocalDateTime ;
import java.time.temporal.ChronoUnit ;
2020-11-06 18:51:47 +00:00
import java.util.List ;
import java.util.Map ;
2020-11-10 02:47:03 +00:00
import java.util.UUID ;
2022-02-22 00:20:22 +00:00
import java.util.stream.Collectors ;
2022-02-22 09:30:23 +00:00
import org.apache.commons.io.FileUtils ;
import org.bukkit.Bukkit ;
2022-02-28 06:28:00 +00:00
import org.bukkit.entity.Player ;
2022-02-22 09:30:23 +00:00
import org.bukkit.scheduler.BukkitRunnable ;
import org.json.JSONObject ;
import org.json.JSONTokener ;
import redis.clients.jedis.Jedis ;
2020-11-06 18:51:47 +00:00
2022-02-04 08:18:07 +00:00
public class PunishmentManager extends PlexBase
2020-11-06 18:51:47 +00:00
{
2022-02-28 06:28:00 +00:00
private final List < String > bannedIPs = Lists . newArrayList ( ) ;
private final List < String > bannedUsernames = Lists . newArrayList ( ) ;
private final List < UUID > bannedUUIDs = Lists . newArrayList ( ) ;
public void mergeIndefiniteBans ( )
{
this . bannedUsernames . clear ( ) ;
this . bannedIPs . clear ( ) ;
this . bannedUUIDs . clear ( ) ;
this . bannedUUIDs . addAll ( Plex . get ( ) . indefBans . getStringList ( " uuids " ) . stream ( ) . filter ( string - >
{
try
{
UUID uuid = UUID . fromString ( string ) ;
return true ;
} catch ( IllegalArgumentException e )
{
return false ;
}
} ) . map ( UUID : : fromString ) . toList ( ) ) ;
this . bannedIPs . addAll ( Plex . get ( ) . indefBans . getStringList ( " ips " ) ) ;
this . bannedUsernames . addAll ( Plex . get ( ) . indefBans . getStringList ( " usernames " ) ) ;
PlexLog . log ( " Loaded {0} UUID(s), {1} IP(s), and {2} username(s) into the indefinite banned list " , this . bannedUUIDs . size ( ) , this . bannedIPs . size ( ) , this . bannedUsernames . size ( ) ) ;
if ( Plex . get ( ) . getRedisConnection ( ) . isEnabled ( ) )
{
PlexLog . log ( " Resetting redis indefinite bans lists and asynchronously uploading from configuration " ) ;
Plex . get ( ) . getRedisConnection ( ) . runAsync ( jedis - > {
jedis . set ( " indefbanned-uuids " , new Gson ( ) . toJson ( this . bannedUUIDs ) ) ;
jedis . set ( " indefbanned-ips " , new Gson ( ) . toJson ( this . bannedIPs ) ) ;
jedis . set ( " indefbanned-users " , new Gson ( ) . toJson ( this . bannedUsernames ) ) ;
this . bannedIPs . clear ( ) ;
this . bannedUsernames . clear ( ) ;
this . bannedUUIDs . clear ( ) ;
} ) ;
}
}
public boolean isIndefUUIDBanned ( UUID uuid )
{
if ( Plex . get ( ) . getRedisConnection ( ) . isEnabled ( ) )
{
List < UUID > uuids = new Gson ( ) . fromJson ( Plex . get ( ) . getRedisConnection ( ) . getJedis ( ) . get ( " indefbanned-uuids " ) , new TypeToken < List < UUID > > ( ) { } . getType ( ) ) ;
return uuids . contains ( uuid ) ;
}
return this . bannedUUIDs . contains ( uuid ) ;
}
public boolean isIndefIPBanned ( String ip )
{
if ( Plex . get ( ) . getRedisConnection ( ) . isEnabled ( ) )
{
List < String > ips = new Gson ( ) . fromJson ( Plex . get ( ) . getRedisConnection ( ) . getJedis ( ) . get ( " indefbanned-ips " ) , new TypeToken < List < String > > ( ) { } . getType ( ) ) ;
return ips . contains ( ip ) ;
}
return this . bannedIPs . contains ( ip ) ;
}
public boolean isIndefUserBanned ( String username )
{
if ( Plex . get ( ) . getRedisConnection ( ) . isEnabled ( ) )
{
List < String > users = new Gson ( ) . fromJson ( Plex . get ( ) . getRedisConnection ( ) . getJedis ( ) . get ( " indefbanned-users " ) , new TypeToken < List < String > > ( ) { } . getType ( ) ) ;
return users . contains ( username ) ;
}
return this . bannedUsernames . contains ( username ) ;
}
2020-11-06 18:51:47 +00:00
public void insertPunishment ( PunishedPlayer player , Punishment punishment )
{
2020-11-10 04:08:37 +00:00
File file = player . getPunishmentsFile ( ) ;
2020-11-06 18:51:47 +00:00
2022-01-30 21:03:47 +00:00
try
{
2020-11-06 18:51:47 +00:00
if ( isNotEmpty ( file ) )
{
JSONTokener tokener = new JSONTokener ( new FileInputStream ( file ) ) ;
JSONObject object = new JSONObject ( tokener ) ;
object . getJSONObject ( punishment . getPunished ( ) . toString ( ) ) . getJSONArray ( " punishments " ) . put ( punishment . toJSON ( ) ) ;
2022-02-04 08:18:07 +00:00
if ( plugin . getRedisConnection ( ) . isEnabled ( ) )
{
plugin . getRedisConnection ( ) . getJedis ( ) . set ( player . getUuid ( ) , object . toString ( ) ) ;
PlexLog . debug ( " Added " + player . getUuid ( ) + " 's punishment to the Redis database. " ) ;
2022-02-04 19:30:05 +00:00
plugin . getRedisConnection ( ) . getJedis ( ) . close ( ) ;
2022-02-04 08:18:07 +00:00
}
2020-11-06 18:51:47 +00:00
FileWriter writer = new FileWriter ( file ) ;
writer . append ( object . toString ( 8 ) ) ;
writer . flush ( ) ;
writer . close ( ) ;
2022-02-22 09:30:23 +00:00
}
else
2022-01-30 21:03:47 +00:00
{
2020-11-06 18:51:47 +00:00
JSONObject object = new JSONObject ( ) ;
Map < String , List < String > > punishments = Maps . newHashMap ( ) ;
List < String > punishmentList = Lists . newArrayList ( ) ;
punishmentList . add ( punishment . toJSON ( ) ) ;
punishments . put ( " punishments " , punishmentList ) ;
object . put ( punishment . getPunished ( ) . toString ( ) , punishments ) ;
2022-02-04 08:18:07 +00:00
if ( plugin . getRedisConnection ( ) . isEnabled ( ) )
{
plugin . getRedisConnection ( ) . getJedis ( ) . set ( player . getUuid ( ) , object . toString ( ) ) ;
PlexLog . debug ( " Added " + player . getUuid ( ) + " 's punishment to the Redis database. " ) ;
2022-02-04 19:30:05 +00:00
plugin . getRedisConnection ( ) . getJedis ( ) . close ( ) ;
2022-02-04 08:18:07 +00:00
}
2020-11-06 18:51:47 +00:00
FileWriter writer = new FileWriter ( file ) ;
writer . append ( object . toString ( 8 ) ) ;
writer . flush ( ) ;
writer . close ( ) ;
}
2022-02-22 09:30:23 +00:00
}
catch ( IOException e )
2022-01-30 21:03:47 +00:00
{
2020-11-06 18:51:47 +00:00
e . printStackTrace ( ) ;
}
}
2022-01-30 21:03:47 +00:00
private boolean isNotEmpty ( File file )
{
try
{
2020-11-06 18:51:47 +00:00
return ! FileUtils . readFileToString ( file , StandardCharsets . UTF_8 ) . trim ( ) . isEmpty ( ) ;
2022-02-22 09:30:23 +00:00
}
catch ( IOException e )
2022-01-30 21:03:47 +00:00
{
2020-11-06 18:51:47 +00:00
e . printStackTrace ( ) ;
}
return false ;
}
2022-02-22 00:20:22 +00:00
public boolean isBanned ( UUID uuid )
{
2022-02-25 07:50:11 +00:00
return PlayerCache . getPunishedPlayer ( uuid ) . getPunishments ( ) . stream ( ) . anyMatch ( punishment - > punishment . getType ( ) = = PunishmentType . BAN & & punishment . isActive ( ) ) ;
2022-02-22 00:20:22 +00:00
}
public boolean isBanned ( PunishedPlayer player )
{
return isBanned ( UUID . fromString ( player . getUuid ( ) ) ) ;
}
public List < Punishment > getActiveBans ( )
{
List < Punishment > punishments = Lists . newArrayList ( ) ;
Jedis jedis = Plex . get ( ) . getRedisConnection ( ) . getJedis ( ) ;
jedis . keys ( " * " ) . forEach ( key - >
{
try
{
UUID uuid = UUID . fromString ( key ) ;
String jsonPunishmentString = jedis . get ( uuid . toString ( ) ) ;
JSONObject object = new JSONObject ( jsonPunishmentString ) ;
object . getJSONObject ( uuid . toString ( ) ) . getJSONArray ( " punishments " ) . forEach ( json - >
{
Punishment punishment = Punishment . fromJson ( json . toString ( ) ) ;
if ( punishment . isActive ( ) & & punishment . getType ( ) = = PunishmentType . BAN )
{
punishments . add ( punishment ) ;
}
} ) ;
2022-02-22 09:30:23 +00:00
}
2022-02-28 06:28:00 +00:00
catch ( IllegalArgumentException ignored )
2022-02-22 00:20:22 +00:00
{
}
} ) ;
return punishments ;
}
public void unban ( Punishment punishment )
{
this . unban ( punishment . getPunished ( ) ) ;
}
public void unban ( UUID uuid )
{
if ( Plex . get ( ) . getRedisConnection ( ) . isEnabled ( ) )
{
Jedis jedis = Plex . get ( ) . getRedisConnection ( ) . getJedis ( ) ;
String jsonPunishmentString = jedis . get ( uuid . toString ( ) ) ;
JSONObject object = new JSONObject ( jsonPunishmentString ) ;
List < Punishment > punishments = object . getJSONObject ( uuid . toString ( ) ) . getJSONArray ( " punishments " ) . toList ( ) . stream ( ) . map ( obj - > Punishment . fromJson ( obj . toString ( ) ) ) . collect ( Collectors . toList ( ) ) ;
while ( punishments . stream ( ) . anyMatch ( punishment - > punishment . isActive ( ) & & punishment . getType ( ) = = PunishmentType . BAN ) )
{
punishments . stream ( ) . filter ( Punishment : : isActive ) . filter ( punishment - > punishment . getType ( ) = = PunishmentType . BAN ) . findFirst ( ) . ifPresent ( punishment - >
{
int index = punishments . indexOf ( punishment ) ;
punishment . setActive ( false ) ;
punishments . set ( index , punishment ) ;
} ) ;
}
object . getJSONObject ( uuid . toString ( ) ) . getJSONArray ( " punishments " ) . clear ( ) ;
object . getJSONObject ( uuid . toString ( ) ) . getJSONArray ( " punishments " ) . putAll ( punishments . stream ( ) . map ( Punishment : : toJSON ) . collect ( Collectors . toList ( ) ) ) ;
jedis . set ( uuid . toString ( ) , object . toString ( ) ) ;
}
2022-02-25 07:50:11 +00:00
PunishedPlayer player = PlayerCache . getPunishedPlayer ( uuid ) ;
2022-02-22 00:20:22 +00:00
File file = player . getPunishmentsFile ( ) ;
if ( isNotEmpty ( file ) )
{
try ( FileInputStream fis = new FileInputStream ( file ) )
{
JSONTokener tokener = new JSONTokener ( fis ) ;
JSONObject object = new JSONObject ( tokener ) ;
List < Punishment > punishments = object . getJSONObject ( uuid . toString ( ) ) . getJSONArray ( " punishments " ) . toList ( ) . stream ( ) . map ( obj - > Punishment . fromJson ( obj . toString ( ) ) ) . collect ( Collectors . toList ( ) ) ;
while ( punishments . stream ( ) . anyMatch ( punishment - > punishment . isActive ( ) & & punishment . getType ( ) = = PunishmentType . BAN ) )
{
punishments . stream ( ) . filter ( Punishment : : isActive ) . filter ( punishment - > punishment . getType ( ) = = PunishmentType . BAN ) . findFirst ( ) . ifPresent ( punishment - >
{
int index = punishments . indexOf ( punishment ) ;
punishment . setActive ( false ) ;
punishments . set ( index , punishment ) ;
} ) ;
}
object . getJSONObject ( uuid . toString ( ) ) . getJSONArray ( " punishments " ) . clear ( ) ;
object . getJSONObject ( uuid . toString ( ) ) . getJSONArray ( " punishments " ) . putAll ( punishments . stream ( ) . map ( Punishment : : toJSON ) . collect ( Collectors . toList ( ) ) ) ;
FileWriter writer = new FileWriter ( file ) ;
writer . append ( object . toString ( ) ) ;
writer . flush ( ) ;
writer . close ( ) ;
2022-02-22 09:30:23 +00:00
}
catch ( IOException e )
2022-02-22 00:20:22 +00:00
{
e . printStackTrace ( ) ;
}
}
}
2020-11-10 02:47:03 +00:00
private void issuePunishment ( PunishedPlayer player , Punishment punishment )
{
2022-02-22 00:20:22 +00:00
if ( punishment . getType ( ) = = PunishmentType . FREEZE )
2020-11-10 02:47:03 +00:00
{
player . setFrozen ( true ) ;
2022-02-05 23:14:23 +00:00
LocalDateTime now = LocalDateTime . now ( ) ;
LocalDateTime then = punishment . getEndDate ( ) ;
long seconds = ChronoUnit . SECONDS . between ( now , then ) ;
2022-01-30 21:03:47 +00:00
new BukkitRunnable ( )
{
2020-11-10 02:47:03 +00:00
@Override
2022-01-30 21:03:47 +00:00
public void run ( )
{
2020-11-10 02:47:03 +00:00
if ( ! player . isFrozen ( ) )
{
this . cancel ( ) ;
return ;
}
player . setFrozen ( false ) ;
2022-02-25 07:09:55 +00:00
Bukkit . broadcast ( PlexUtils . messageComponent ( " unfrozePlayer " , " Plex " , Bukkit . getOfflinePlayer ( UUID . fromString ( player . getUuid ( ) ) ) . getName ( ) ) ) ;
2020-11-10 02:47:03 +00:00
}
} . runTaskLater ( Plex . get ( ) , 20 * seconds ) ;
2022-02-22 09:30:23 +00:00
}
else if ( punishment . getType ( ) = = PunishmentType . MUTE )
2020-11-10 02:47:03 +00:00
{
player . setMuted ( true ) ;
2022-02-05 23:14:23 +00:00
LocalDateTime now = LocalDateTime . now ( ) ;
LocalDateTime then = punishment . getEndDate ( ) ;
long seconds = ChronoUnit . SECONDS . between ( now , then ) ;
2022-01-30 21:03:47 +00:00
new BukkitRunnable ( )
{
2020-11-10 02:47:03 +00:00
@Override
2022-01-30 21:03:47 +00:00
public void run ( )
{
2022-02-25 08:59:48 +00:00
if ( ! player . isMuted ( ) )
{
this . cancel ( ) ;
return ;
}
2020-11-10 02:47:03 +00:00
player . setMuted ( false ) ;
2022-02-25 08:59:48 +00:00
Bukkit . broadcast ( PlexUtils . messageComponent ( " unmutedPlayer " , " Plex " , Bukkit . getOfflinePlayer ( UUID . fromString ( player . getUuid ( ) ) ) . getName ( ) ) ) ;
2020-11-10 02:47:03 +00:00
}
} . runTaskLater ( Plex . get ( ) , 20 * seconds ) ;
}
}
public void doPunishment ( PunishedPlayer player , Punishment punishment )
{
issuePunishment ( player , punishment ) ;
insertPunishment ( player , punishment ) ;
}
2020-11-06 18:51:47 +00:00
}