TotalFreedomMod/src/main/java/me/totalfreedom/totalfreedommod/bridge/CoreProtectBridge.java

462 lines
17 KiB
Java

package me.totalfreedom.totalfreedommod.bridge;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.player.PlayerData;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import net.coreprotect.CoreProtect;
import net.coreprotect.CoreProtectAPI;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
public class CoreProtectBridge extends FreedomService
{
public static Map<Player, FUtil.PaginationList<String>> HISTORY_MAP = new HashMap<>();
private final List<String> tables = Arrays.asList("co_sign", "co_session", "co_container", "co_block");
private final HashMap<String, Long> cooldown = new HashMap<>();
private CoreProtectAPI coreProtectAPI = null;
private BukkitTask wiper;
public static Long getSecondsLeft(long prevTime, int timeAdd)
{
return prevTime / 1000L + timeAdd - System.currentTimeMillis() / 1000L;
}
// Unix timestamp converter taken from Functions class in CoreProtect, not my code
public static String getTimeAgo(int logTime, int currentTime)
{
StringBuilder message = new StringBuilder();
double timeSince = (double)currentTime - ((double)logTime + 0.0D);
timeSince /= 60.0D;
if (timeSince < 60.0D)
{
message.append((new DecimalFormat("0.00")).format(timeSince)).append("/m ago");
}
if (message.length() == 0)
{
timeSince /= 60.0D;
if (timeSince < 24.0D)
{
message.append((new DecimalFormat("0.00")).format(timeSince)).append("/h ago");
}
}
if (message.length() == 0)
{
timeSince /= 24.0D;
message.append((new DecimalFormat("0.00")).format(timeSince)).append("/d ago");
}
return message.toString();
}
@Override
public void onStart()
{
}
@Override
public void onStop()
{
}
public CoreProtect getCoreProtect()
{
CoreProtect coreProtect = null;
try
{
final Plugin coreProtectPlugin = Bukkit.getServer().getPluginManager().getPlugin("CoreProtect");
assert coreProtectPlugin != null;
if (coreProtectPlugin instanceof CoreProtect)
{
coreProtect = (CoreProtect)coreProtectPlugin;
}
}
catch (Exception ex)
{
FLog.severe(ex);
}
return coreProtect;
}
public CoreProtectAPI getCoreProtectAPI()
{
if (coreProtectAPI == null)
{
try
{
final CoreProtect coreProtect = getCoreProtect();
coreProtectAPI = coreProtect.getAPI();
// Check if the plugin or api is not enabled, if so, return null
if (!coreProtect.isEnabled() || !coreProtectAPI.isEnabled())
{
return null;
}
}
catch (Exception ex)
{
FLog.severe(ex);
}
}
return coreProtectAPI;
}
public boolean isEnabled()
{
final CoreProtect coreProtect = getCoreProtect();
return coreProtect != null && coreProtect.isEnabled();
}
// Rollback the specified player's edits that were in the last 24 hours.
public void rollback(final String name)
{
final CoreProtectAPI coreProtect = getCoreProtectAPI();
if (!isEnabled())
{
return;
}
new BukkitRunnable()
{
@Override
public void run()
{
coreProtect.performRollback(86400, Collections.singletonList(name), null, null, null, null, 0, null);
}
}.runTaskAsynchronously(plugin);
}
// Reverts a rollback for the specified player's edits that were in the last 24 hours.
public void restore(final String name)
{
final CoreProtectAPI coreProtect = getCoreProtectAPI();
if (!isEnabled())
{
return;
}
new BukkitRunnable()
{
@Override
public void run()
{
coreProtect.performRestore(86400, Collections.singletonList(name), null, null, null, null, 0, null);
}
}.runTaskAsynchronously(plugin);
}
public File getDatabase()
{
if (!isEnabled())
{
return null;
}
return (new File(getCoreProtect().getDataFolder(), "database.db"));
}
public double getDBSize()
{
double bytes = getDatabase().length();
double kilobytes = (bytes / 1024);
double megabytes = (kilobytes / 1024);
return (megabytes / 1024);
}
// Wipes DB for the specified world
public void clearDatabase(World world)
{
clearDatabase(world, false);
}
// Wipes DB for the specified world
public void clearDatabase(World world, Boolean shutdown)
{
if (!ConfigEntry.COREPROTECT_MYSQL_ENABLED.getBoolean())
{
return;
}
final CoreProtect coreProtect = getCoreProtect();
if (coreProtect == null)
{
return;
}
/* As CoreProtect doesn't have an API method for deleting all of the data for a specific world
we have to do this manually via SQL */
Connection connection;
try
{
String host = ConfigEntry.COREPROTECT_MYSQL_HOST.getString();
String port = ConfigEntry.COREPROTECT_MYSQL_PORT.getString();
String username = ConfigEntry.COREPROTECT_MYSQL_USERNAME.getString();
String password = ConfigEntry.COREPROTECT_MYSQL_PASSWORD.getString();
String database = ConfigEntry.COREPROTECT_MYSQL_DATABASE.getString();
String url = host + ":" + port + "/" + database + "?user=" + username + "&password=" + password + "&useSSL=false";
connection = DriverManager.getConnection("jdbc:sql://" + url);
final PreparedStatement statement = connection.prepareStatement("SELECT id FROM co_world WHERE world = ?");
statement.setQueryTimeout(30);
// Obtain world ID from CoreProtect database
statement.setString(1, world.getName());
ResultSet resultSet = statement.executeQuery();
String worldID = null;
while (resultSet.next())
{
worldID = String.valueOf(resultSet.getInt("id"));
}
// Ensure the world ID is not null
if (worldID == null)
{
FLog.warning("Failed to obtain the world ID for the " + world.getName());
return;
}
// Iterate through each table and delete their data if the world ID matches
for (String table : tables)
{
final PreparedStatement statement1 = connection.prepareStatement("DELETE FROM ? WHERE wid = ?");
statement1.setString(1, table);
statement1.setString(2, worldID);
statement1.executeQuery();
}
connection.close();
}
catch (SQLException e)
{
FLog.warning("Failed to delete the CoreProtect data for the " + world.getName());
}
// This exits for flatlands wipes
if (shutdown)
{
server.shutdown();
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerInteract(PlayerInteractEvent event)
{
Player player = event.getPlayer();
PlayerData data = plugin.pl.getData(player);
Block block = event.getClickedBlock();
final CoreProtectAPI coreProtect = getCoreProtectAPI();
if (data.hasInspection())
{
if (event.getAction() == Action.LEFT_CLICK_BLOCK)
{
if (block != null)
{
event.setCancelled(true);
int cooldownTime = 3;
if (cooldown.containsKey(player.getName()))
{
long secondsLeft = getSecondsLeft(cooldown.get(player.getName()), cooldownTime);
if (secondsLeft > 0L)
{
event.setCancelled(true);
player.sendMessage(ChatColor.RED + String.valueOf(secondsLeft) + " seconds left before next query.");
return;
}
}
List<String[]> lookup = coreProtect.blockLookup(block, -1);
if (!plugin.al.isAdmin(player))
{
cooldown.put(player.getName(), System.currentTimeMillis());
}
if (lookup != null)
{
if (lookup.isEmpty())
{
player.sendMessage(net.md_5.bungee.api.ChatColor.of("#30ade4") + "Block Inspector " + ChatColor.WHITE + "- " + "No block data found for this location");
return;
}
HISTORY_MAP.remove(event.getPlayer());
HISTORY_MAP.put(event.getPlayer(), new FUtil.PaginationList<>(10));
FUtil.PaginationList<String> paged = HISTORY_MAP.get(event.getPlayer());
player.sendMessage("---- " + net.md_5.bungee.api.ChatColor.of("#30ade4") + "Block Inspector" + ChatColor.WHITE + " ---- "
+ ChatColor.GRAY + "(x" + block.getX() + "/" + "y" + block.getY() + "/" + "z" + block.getZ() + ")");
for (String[] value : lookup)
{
CoreProtectAPI.ParseResult result = coreProtect.parseResult(value);
BlockData bl = result.getBlockData();
String s;
String st = "";
if (result.getActionString().equals("Placement"))
{
s = " placed ";
}
else if (result.getActionString().equals("Removal"))
{
s = " broke ";
}
else
{
s = " interacted with ";
}
if (result.isRolledBack())
{
st += "§m";
}
int time = (int)(System.currentTimeMillis() / 1000L);
paged.add(ChatColor.GRAY + getTimeAgo(result.getTime(), time) + ChatColor.WHITE + " - " + net.md_5.bungee.api.ChatColor.of("#30ade4")
+ st + result.getPlayer() + ChatColor.WHITE + st + s + net.md_5.bungee.api.ChatColor.of("#30ade4") + st + bl.getMaterial().toString().toLowerCase());
}
List<String> page = paged.getPage(1);
for (String entries : page)
{
player.sendMessage(entries);
}
player.sendMessage("Page 1/" + paged.getPageCount() + " | To index through the pages, type " + net.md_5.bungee.api.ChatColor.of("#30ade4") + "/ins history <page>");
}
}
}
else if (event.getAction() == Action.RIGHT_CLICK_BLOCK)
{
if (block != null)
{
if (data.hasInspection())
{
BlockState blockState = block.getRelative(event.getBlockFace()).getState();
Block placedBlock = blockState.getBlock();
event.setCancelled(true);
List<String[]> lookup = coreProtect.blockLookup(placedBlock, -1);
if (lookup.isEmpty())
{
lookup = coreProtect.blockLookup(block, -1);
}
int cooldownTime = 3;
if (cooldown.containsKey(player.getName()))
{
long secondsLeft = getSecondsLeft(cooldown.get(player.getName()), cooldownTime);
if (secondsLeft > 0L)
{
event.setCancelled(true);
player.sendMessage(ChatColor.RED + String.valueOf(secondsLeft) + " seconds left before next query.");
return;
}
}
if (!plugin.al.isAdmin(player))
{
cooldown.put(player.getName(), System.currentTimeMillis());
}
if (lookup != null)
{
if (lookup.isEmpty())
{
player.sendMessage(net.md_5.bungee.api.ChatColor.of("#30ade4") + "Block Inspector " + ChatColor.WHITE + "- " + "No block data found for this location");
return;
}
HISTORY_MAP.remove(event.getPlayer());
HISTORY_MAP.put(event.getPlayer(), new FUtil.PaginationList<>(10));
FUtil.PaginationList<String> paged = HISTORY_MAP.get(event.getPlayer());
player.sendMessage("---- " + net.md_5.bungee.api.ChatColor.of("#30ade4") + "Block Inspector" + ChatColor.WHITE + " ---- "
+ ChatColor.GRAY + "(x" + block.getX() + "/" + "y" + block.getY() + "/" + "z" + block.getZ() + ")");
for (String[] value : lookup)
{
CoreProtectAPI.ParseResult result = coreProtect.parseResult(value);
BlockData bl = result.getBlockData();
String s;
String st = "";
if (result.getActionString().equals("Placement"))
{
s = " placed ";
}
else if (result.getActionString().equals("Removal"))
{
s = " broke ";
}
else
{
s = " interacted with ";
}
if (result.isRolledBack())
{
st += "§m";
}
int time = (int)(System.currentTimeMillis() / 1000L);
paged.add(ChatColor.GRAY + getTimeAgo(result.getTime(), time) + ChatColor.WHITE + " - " + net.md_5.bungee.api.ChatColor.of("#30ade4")
+ st + result.getPlayer() + ChatColor.WHITE + st + s + net.md_5.bungee.api.ChatColor.of("#30ade4") + st + bl.getMaterial().toString().toLowerCase());
}
List<String> page = paged.getPage(1);
for (String entries : page)
{
player.sendMessage(entries);
}
player.sendMessage("Page 1/" + paged.getPageCount() + " | To index through the pages, type " + net.md_5.bungee.api.ChatColor.of("#30ade4") + "/ins history <page>");
}
}
}
}
}
}
}