CoreProtect v20.0 release

This commit is contained in:
Intelli 2021-07-16 12:13:54 -06:00
parent 415d7b323a
commit 48ef18e2c8
173 changed files with 25072 additions and 1 deletions

View File

@ -1,6 +1,6 @@
![CoreProtect](https://userfolio.com/uploads/coreprotect-banner-v19.png)
[![Artistic License 2.0](https://img.shields.io/github/license/PlayPro/CoreProtect?&logo=github)](License)
[![Artistic License 2.0](https://img.shields.io/github/license/PlayPro/CoreProtect?&logo=github)](LICENSE)
[![Join us on Discord](https://img.shields.io/discord/348680641560313868.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/b4DZ4jy)
[![Netlify Status](https://api.netlify.com/api/v1/badges/c1d26a0f-65c5-4e4b-95d7-e08af671ab67/deploy-status)](https://app.netlify.com/sites/coreprotect/deploys)

87
build.gradle Normal file
View File

@ -0,0 +1,87 @@
import org.apache.tools.ant.filters.ReplaceTokens
plugins {
id 'java'
id 'com.github.johnrengelman.shadow' version '6.0.0'
id 'com.palantir.git-version' version '0.12.3'
}
group = 'net.coreprotect'
String projectVersion = '20.0'
String projectBranch = ''
version = projectVersion // `version` might be modified, we don't always want that (e.g. plugin.yml)
description = 'Provides block protection for your server.'
sourceCompatibility = '1.8'
if (System.getenv("BUILD_NUMBER") != null) {
// Being built in Jenkins, append Build ID
version += "-${System.getenv("BUILD_NUMBER")}"
} else if (!(version ==~ '^[^.]*\\.[^.]*\\.[^.]*$')) { // Thanks https://stackoverflow.com/a/9949200/1709894
// Append the Git hash if 'version' has less than two periods
version += "-${gitVersion()}"
}
logger.info("Building version $version")
repositories {
jcenter()
maven { url = 'https://hub.spigotmc.org/nexus/content/groups/public/' }
maven { url = 'https://oss.sonatype.org/content/repositories/snapshots/' }
maven { url = 'https://papermc.io/repo/repository/maven-public/' }
maven { url = 'https://repo.codemc.org/repository/maven-public/' }
maven { url = 'https://maven.sk89q.com/repo/' }
}
dependencies {
compileOnly('com.sk89q.worldedit:worldedit-bukkit:7.0.0-SNAPSHOT') {
exclude group: 'org.bukkit'
}
compileOnly 'org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT'
implementation 'org.bstats:bstats-bukkit-lite:1.7'
}
jar {
archiveClassifier.set("original")
}
artifacts {
archives shadowJar
}
shadowJar {
dependencies {
// #toString because #getGroup technically returns an Object
relocate('org.bstats', project.group.toString())
}
archiveClassifier.set(null)
}
ext {
author = 'Intelli'
resourceTokens = [
'project.version': projectVersion,
'project.branch': projectBranch,
]
}
processResources {
include 'plugin.yml'
// Whole lotta boilerplate to get the same functionality as Maven here.
// Replace this if Gradle ever lets us configure the filter before filtering.
filter(new Transformer<String, String>() {
@Override
String transform(String s) {
ReplaceTokens replaceTokens = new ReplaceTokens(new StringReader(s))
replaceTokens.setBeginToken('${')
replaceTokens.setEndToken('}')
resourceTokens.forEach { key, val ->
def token = new ReplaceTokens.Token()
token.setKey(key.toString())
token.setValue(val.toString())
replaceTokens.addConfiguredToken(token)
}
return replaceTokens.readLines().join('\n')
}
})
}

124
pom.xml Executable file
View File

@ -0,0 +1,124 @@
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>net.coreprotect</groupId>
<artifactId>CoreProtect</artifactId>
<version>20.0</version>
<properties>
<project.branch></project.branch>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*:*:*</artifact>
<excludes>
<exclude>**/*.java</exclude>
<exclude>**/*.c</exclude>
<exclude>META-INF/maven/**</exclude>
<exclude>META-INF/services/**</exclude>
</excludes>
</filter>
</filters>
<relocations>
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>net.coreprotect</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<!--
<repository>
<id>public</id>
<url>http://repo.mvdw-software.be/content/groups/public/</url>
</repository>
-->
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
</repository>
<repository>
<id>paper-repo</id>
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
<repository>
<id>codemc-repo</id>
<url>https://repo.codemc.org/repository/maven-public/</url>
</repository>
<repository>
<id>sk89q-repo</id>
<url>http://maven.sk89q.com/repo/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.17-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!--
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.17-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
-->
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit-lite</artifactId>
<version>1.8</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId>
<version>7.0.0-SNAPSHOT</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,199 @@
package net.coreprotect;
import java.io.File;
import org.bstats.bukkit.MetricsLite;
import org.bukkit.Bukkit;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin;
import net.coreprotect.command.CommandHandler;
import net.coreprotect.command.TabHandler;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.consumer.process.Process;
import net.coreprotect.language.Language;
import net.coreprotect.language.Phrase;
import net.coreprotect.listener.ListenerHandler;
import net.coreprotect.thread.CacheHandler;
import net.coreprotect.thread.NetworkHandler;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public final class CoreProtect extends JavaPlugin {
private static CoreProtect instance;
/**
* Get the instance of CoreProtect
*
* @return This CoreProtect instance
*/
public static CoreProtect getInstance() {
return instance;
}
private CoreProtectAPI api = new CoreProtectAPI();
/**
* Get the CoreProtect API
*
* @return The CoreProtect API
*/
public CoreProtectAPI getAPI() {
return api;
}
@Override
public void onEnable() {
instance = this;
ConfigHandler.path = this.getDataFolder().getPath() + File.separator;
Language.loadPhrases();
boolean start = performVersionChecks();
if (start) {
try {
Consumer.initialize(); // Prepare consumer (keep this here)
new ListenerHandler(this);
getCommand("coreprotect").setExecutor(CommandHandler.getInstance());
getCommand("coreprotect").setTabCompleter(new TabHandler());
getCommand("core").setExecutor(CommandHandler.getInstance());
getCommand("core").setTabCompleter(new TabHandler());
getCommand("co").setExecutor(CommandHandler.getInstance());
getCommand("co").setTabCompleter(new TabHandler());
boolean exists = (new File(ConfigHandler.path)).exists();
if (!exists) {
new File(ConfigHandler.path).mkdir();
}
start = ConfigHandler.performInitialization(true); // Perform any necessary initialization
}
catch (Exception e) {
e.printStackTrace();
start = false;
}
}
if (start) {
PluginDescriptionFile pluginDescription = this.getDescription();
Util.sendConsoleComponentStartup(Bukkit.getServer().getConsoleSender(), Phrase.build(Phrase.ENABLE_SUCCESS, ConfigHandler.EDITION_NAME));
if (Config.getGlobal().MYSQL) {
Chat.console(Phrase.build(Phrase.USING_MYSQL));
}
else {
Chat.console(Phrase.build(Phrase.USING_SQLITE));
}
Chat.console("--------------------");
Chat.console(Phrase.build(Phrase.ENJOY_COREPROTECT, pluginDescription.getName()));
Chat.console(Phrase.build(Phrase.LINK_DISCORD, "www.coreprotect.net/discord/"));
Chat.console("--------------------");
getServer().getScheduler().scheduleSyncDelayedTask(this, () -> {
try {
Thread networkHandler = new Thread(new NetworkHandler(true, true));
networkHandler.start();
}
catch (Exception e) {
e.printStackTrace();
}
}, 0);
Thread cacheCleanUpThread = new Thread(new CacheHandler());
cacheCleanUpThread.start();
Consumer.startConsumer();
// Enabling bStats
try {
new MetricsLite(this, 2876);
}
catch (Exception e) {
// Failed to connect to bStats server or something else went wrong.
}
}
else {
Chat.console(Phrase.build(Phrase.ENABLE_FAILED, ConfigHandler.EDITION_NAME));
getServer().getPluginManager().disablePlugin(this);
}
}
@Override
public void onDisable() {
safeShutdown(this);
}
private static boolean performVersionChecks() {
try {
String[] bukkitVersion = Bukkit.getServer().getBukkitVersion().split("-|\\.");
if (Util.newVersion(bukkitVersion[0] + "." + bukkitVersion[1], ConfigHandler.SPIGOT_VERSION)) {
Chat.console(Phrase.build(Phrase.VERSION_REQUIRED, "Spigot", ConfigHandler.SPIGOT_VERSION));
return false;
}
String[] javaVersion = (System.getProperty("java.version").replaceAll("[^0-9.]", "") + ".0").split("\\.");
if (Util.newVersion(javaVersion[0] + "." + javaVersion[1], ConfigHandler.JAVA_VERSION)) {
Chat.console(Phrase.build(Phrase.VERSION_REQUIRED, "Java", ConfigHandler.JAVA_VERSION));
return false;
}
if (ConfigHandler.EDITION_BRANCH.length() == 0) {
Chat.sendConsoleMessage(Color.RED + "[CoreProtect] " + Phrase.build(Phrase.INVALID_BRANCH_1));
Chat.sendConsoleMessage(Color.GREY + "[CoreProtect] " + Phrase.build(Phrase.INVALID_BRANCH_2));
Chat.sendConsoleMessage(Color.GREY + "[CoreProtect] " + Phrase.build(Phrase.INVALID_BRANCH_3));
return false;
}
ConfigHandler.SERVER_VERSION = Integer.parseInt(bukkitVersion[1]);
}
catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
private static void safeShutdown(CoreProtect plugin) {
try {
ConfigHandler.serverRunning = false;
long shutdownTime = System.currentTimeMillis();
long alertTime = shutdownTime + (10 * 1000);
if (ConfigHandler.converterRunning) {
Chat.console(Phrase.build(Phrase.FINISHING_CONVERSION));
}
else {
Chat.console(Phrase.build(Phrase.FINISHING_LOGGING));
}
while ((Consumer.isRunning() || ConfigHandler.converterRunning) && !ConfigHandler.purgeRunning) {
long time = System.currentTimeMillis();
if (time >= alertTime) {
if (!ConfigHandler.converterRunning) {
int consumerId = (Consumer.currentConsumer == 1) ? 1 : 0;
int consumerCount = Consumer.getConsumerSize(consumerId) + Process.getCurrentConsumerSize();
Chat.console(Phrase.build(Phrase.LOGGING_ITEMS, String.format("%,d", consumerCount)));
}
alertTime = alertTime + (30 * 1000);
}
else if (!ConfigHandler.databaseReachable && (time - shutdownTime) >= (5 * 60 * 1000)) {
Chat.console(Phrase.build(Phrase.DATABASE_UNREACHABLE));
break;
}
else if ((time - shutdownTime) >= (15 * 60 * 1000)) {
Chat.console(Phrase.build(Phrase.LOGGING_TIME_LIMIT));
break;
}
Thread.sleep(100);
}
Chat.console(Phrase.build(Phrase.DISABLE_SUCCESS, "CoreProtect v" + plugin.getDescription().getVersion()));
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,515 @@
package net.coreprotect;
import java.sql.Connection;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import net.coreprotect.config.Config;
import net.coreprotect.consumer.Queue;
import net.coreprotect.database.Database;
import net.coreprotect.database.Lookup;
import net.coreprotect.database.Rollback;
import net.coreprotect.database.lookup.BlockLookupAPI;
import net.coreprotect.language.Phrase;
import net.coreprotect.listener.player.InventoryChangeListener;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Util;
public class CoreProtectAPI extends Queue {
public class ParseResult {
String[] parse;
public ParseResult(String[] data) {
parse = data;
}
public int getActionId() {
return Integer.parseInt(parse[7]);
}
public String getActionString() {
int actionID = Integer.parseInt(parse[7]);
String result = "unknown";
if (actionID == 0) {
result = "break";
}
else if (actionID == 1) {
result = "place";
}
else if (actionID == 2) {
result = "click";
}
else if (actionID == 3) {
result = "kill";
}
return result;
}
@Deprecated
public int getData() {
return Integer.parseInt(parse[6]);
}
public String getPlayer() {
return parse[1];
}
@Deprecated
public int getTime() {
return Integer.parseInt(parse[0]);
}
public long getTimestamp() {
return Long.parseLong(parse[0]) * 1000L;
}
public Material getType() {
int actionID = this.getActionId();
int type = Integer.parseInt(parse[5]);
String typeName;
if (actionID == 3) {
typeName = Util.getEntityType(type).name();
}
else {
typeName = Util.getType(type).name().toLowerCase(Locale.ROOT);
typeName = Util.nameFilter(typeName, this.getData());
}
return Util.getType(typeName);
}
public BlockData getBlockData() {
String blockData = parse[12];
if (blockData.length() == 0) {
return getType().createBlockData();
}
return Bukkit.getServer().createBlockData(blockData);
}
public int getX() {
return Integer.parseInt(parse[2]);
}
public int getY() {
return Integer.parseInt(parse[3]);
}
public int getZ() {
return Integer.parseInt(parse[4]);
}
public boolean isRolledBack() {
return Integer.parseInt(parse[8]) == 1;
}
public String worldName() {
return Util.getWorldName(Integer.parseInt(parse[9]));
}
}
private static List<Object> parseList(List<Object> list) {
List<Object> result = new ArrayList<>();
if (list != null) {
for (Object value : list) {
if (value instanceof Material || value instanceof EntityType) {
result.add(value);
}
else if (value instanceof Integer) {
Material material = Util.getType((Integer) value);
result.add(material);
}
}
}
return result;
}
public int APIVersion() {
return 7;
}
public List<String[]> blockLookup(Block block, int time) {
if (Config.getGlobal().API_ENABLED) {
return BlockLookupAPI.performLookup(block, time);
}
return null;
}
public boolean hasPlaced(String user, Block block, int time, int offset) {
// Determine if a user has placed a block at this location in the last # of seconds.
boolean match = false;
if (Config.getGlobal().API_ENABLED) {
int unixTimestamp = (int) (System.currentTimeMillis() / 1000L);
int offsetTime = unixTimestamp - offset;
List<String[]> check = blockLookup(block, time);
for (String[] value : check) {
ParseResult result = parseResult(value);
if (user.equalsIgnoreCase(result.getPlayer()) && result.getActionId() == 1 && result.getTime() <= offsetTime) {
match = true;
break;
}
}
}
return match;
}
public boolean hasRemoved(String user, Block block, int time, int offset) {
// Determine if a user has removed a block at this location in the last # of seconds.
boolean match = false;
if (Config.getGlobal().API_ENABLED) {
int unixTimestamp = (int) (System.currentTimeMillis() / 1000L);
int offsetTime = unixTimestamp - offset;
List<String[]> check = blockLookup(block, time);
for (String[] value : check) {
ParseResult result = parseResult(value);
if (user.equalsIgnoreCase(result.getPlayer()) && result.getActionId() == 0 && result.getTime() <= offsetTime) {
match = true;
break;
}
}
}
return match;
}
public boolean isEnabled() {
return Config.getGlobal().API_ENABLED;
}
public boolean logChat(Player player, String message) {
if (Config.getGlobal().API_ENABLED && player != null && Config.getConfig(player.getWorld()).PLAYER_MESSAGES) {
if (message != null) {
if (message.length() > 0 && !message.startsWith("/")) {
int time = (int) (System.currentTimeMillis() / 1000L);
Queue.queuePlayerChat(player, message, time);
return true;
}
}
}
return false;
}
public boolean logCommand(Player player, String command) {
if (Config.getGlobal().API_ENABLED && player != null && Config.getConfig(player.getWorld()).PLAYER_COMMANDS) {
if (command != null) {
if (command.length() > 0 && command.startsWith("/")) {
int time = (int) (System.currentTimeMillis() / 1000L);
Queue.queuePlayerCommand(player, command, time);
return true;
}
}
}
return false;
}
public boolean logInteraction(String user, Location location) {
if (Config.getGlobal().API_ENABLED) {
if (user != null && location != null) {
if (user.length() > 0) {
Queue.queuePlayerInteraction(user, location.getBlock().getState());
return true;
}
}
}
return false;
}
public boolean logContainerTransaction(String user, Location location) {
if (Config.getGlobal().API_ENABLED) {
return InventoryChangeListener.inventoryTransaction(user, location, null);
}
return false;
}
public boolean logPlacement(String user, Location location, Material type, BlockData blockData) {
if (Config.getGlobal().API_ENABLED) {
if (user != null && location != null) {
if (user.length() > 0) {
Block block = location.getBlock();
BlockState blockState = block.getState();
String blockDataString = null;
if (blockData != null) {
blockDataString = blockData.getAsString();
}
Queue.queueBlockPlace(user, blockState, block.getType(), null, type, -1, 0, blockDataString);
return true;
}
}
}
return false;
}
@Deprecated
public boolean logPlacement(String user, Location location, Material type, byte data) {
if (Config.getGlobal().API_ENABLED) {
if (user != null && location != null) {
if (user.length() > 0) {
Queue.queueBlockPlace(user, location.getBlock().getState(), location.getBlock().getType(), null, type, data, 1, null);
return true;
}
}
}
return false;
}
public boolean logRemoval(String user, Location location, Material type, BlockData blockData) {
if (Config.getGlobal().API_ENABLED) {
if (user != null && location != null) {
if (user.length() > 0) {
String blockDataString = null;
if (blockData != null) {
blockDataString = blockData.getAsString();
}
Block block = location.getBlock();
Database.containerBreakCheck(user, block.getType(), block, null, location);
Queue.queueBlockBreak(user, location.getBlock().getState(), type, blockDataString, 0);
return true;
}
}
}
return false;
}
@Deprecated
public boolean logRemoval(String user, Location location, Material type, byte data) {
if (Config.getGlobal().API_ENABLED) {
if (user != null && location != null) {
if (user.length() > 0) {
Queue.queueBlockBreak(user, location.getBlock().getState(), type, type.createBlockData().getAsString(), data);
return true;
}
}
}
return false;
}
public ParseResult parseResult(String[] results) {
return new ParseResult(results);
}
public List<String[]> performLookup(int time, List<String> restrictUsers, List<String> excludeUsers, List<Object> restrictBlocks, List<Object> excludeBlocks, List<Integer> actionList, int radius, Location radiusLocation) {
if (Config.getGlobal().API_ENABLED) {
return processData(time, radius, radiusLocation, parseList(restrictBlocks), parseList(excludeBlocks), restrictUsers, excludeUsers, actionList, 0, 1, -1, -1, false);
}
return null;
}
@Deprecated
public List<String[]> performLookup(String user, int time, int radius, Location location, List<Object> restrict, List<Object> exclude) {
if (Config.getGlobal().API_ENABLED) {
return processData(user, time, radius, location, parseList(restrict), parseList(exclude), 0, 1, -1, -1, false);
}
return null;
}
public List<String[]> performPartialLookup(int time, List<String> restrictUsers, List<String> excludeUsers, List<Object> restrictBlocks, List<Object> excludeBlocks, List<Integer> actionList, int radius, Location radiusLocation, int limitOffset, int limitCount) {
if (Config.getGlobal().API_ENABLED) {
return processData(time, radius, radiusLocation, parseList(restrictBlocks), parseList(excludeBlocks), restrictUsers, excludeUsers, actionList, 0, 1, limitOffset, limitCount, true);
}
return null;
}
@Deprecated
public List<String[]> performPartialLookup(String user, int time, int radius, Location location, List<Object> restrict, List<Object> exclude, int limitOffset, int limitCount) {
if (Config.getGlobal().API_ENABLED) {
return processData(user, time, radius, location, parseList(restrict), parseList(exclude), 0, 1, limitOffset, limitCount, true);
}
return null;
}
public void performPurge(int time) {
Server server = Bukkit.getServer();
server.dispatchCommand(server.getConsoleSender(), "co purge t:" + time + "s");
}
public List<String[]> performRestore(int time, List<String> restrictUsers, List<String> excludeUsers, List<Object> restrictBlocks, List<Object> excludeBlocks, List<Integer> actionList, int radius, Location radiusLocation) {
if (Config.getGlobal().API_ENABLED) {
return processData(time, radius, radiusLocation, parseList(restrictBlocks), parseList(excludeBlocks), restrictUsers, excludeUsers, actionList, 1, 2, -1, -1, false);
}
return null;
}
@Deprecated
public List<String[]> performRestore(String user, int time, int radius, Location location, List<Object> restrict, List<Object> exclude) {
if (Config.getGlobal().API_ENABLED) {
return processData(user, time, radius, location, parseList(restrict), parseList(exclude), 1, 2, -1, -1, false);
}
return null;
}
public List<String[]> performRollback(int time, List<String> restrictUsers, List<String> excludeUsers, List<Object> restrictBlocks, List<Object> excludeBlocks, List<Integer> actionList, int radius, Location radiusLocation) {
if (Config.getGlobal().API_ENABLED) {
return processData(time, radius, radiusLocation, parseList(restrictBlocks), parseList(excludeBlocks), restrictUsers, excludeUsers, actionList, 0, 2, -1, -1, false);
}
return null;
}
@Deprecated
public List<String[]> performRollback(String user, int time, int radius, Location location, List<Object> restrict, List<Object> exclude) {
if (Config.getGlobal().API_ENABLED) {
return processData(user, time, radius, location, parseList(restrict), parseList(exclude), 0, 2, -1, -1, false);
}
return null;
}
private List<String[]> processData(int time, int radius, Location location, List<Object> restrictBlocks, List<Object> excludeBlocks, List<String> restrictUsers, List<String> excludeUsers, List<Integer> actionList, int action, int lookup, int offset, int rowCount, boolean useLimit) {
// You need to either specify time/radius or time/user
List<String[]> result = new ArrayList<>();
List<String> uuids = new ArrayList<>();
if (restrictUsers == null) {
restrictUsers = new ArrayList<>();
}
if (excludeUsers == null) {
excludeUsers = new ArrayList<>();
}
if (actionList == null) {
actionList = new ArrayList<>();
}
if (actionList.size() == 0 && restrictBlocks.size() > 0) {
boolean addedMaterial = false;
boolean addedEntity = false;
for (Object argBlock : restrictBlocks) {
if (argBlock instanceof Material && !addedMaterial) {
actionList.add(0);
actionList.add(1);
addedMaterial = true;
}
else if (argBlock instanceof EntityType && !addedEntity) {
actionList.add(3);
addedEntity = true;
}
}
}
if (actionList.size() == 0) {
actionList.add(0);
actionList.add(1);
}
actionList.removeIf(actionListItem -> actionListItem > 3);
if (restrictUsers.size() == 0) {
restrictUsers.add("#global");
}
int unixTimestamp = (int) (System.currentTimeMillis() / 1000L);
int timePeriod = unixTimestamp - time;
if (radius < 1) {
radius = -1;
}
if (restrictUsers.contains("#global") && radius == -1) {
return null;
}
if (radius > -1 && location == null) {
return null;
}
try {
Connection connection = Database.getConnection(false, 1000);
if (connection != null) {
Statement statement = connection.createStatement();
boolean restrictWorld = false;
if (radius > 0) {
restrictWorld = true;
}
if (location == null) {
restrictWorld = false;
}
Integer[] argRadius = null;
if (location != null && radius > 0) {
int xMin = location.getBlockX() - radius;
int xMax = location.getBlockX() + radius;
int zMin = location.getBlockZ() - radius;
int zMax = location.getBlockZ() + radius;
argRadius = new Integer[] { radius, xMin, xMax, -1, -1, zMin, zMax, 0 };
}
if (lookup == 1) {
if (location != null) {
restrictWorld = true;
}
if (useLimit) {
result = Lookup.performPartialLookup(statement, null, uuids, restrictUsers, restrictBlocks, excludeBlocks, excludeUsers, actionList, location, argRadius, timePeriod, offset, rowCount, restrictWorld, true);
}
else {
result = Lookup.performLookup(statement, null, uuids, restrictUsers, restrictBlocks, excludeBlocks, excludeUsers, actionList, location, argRadius, timePeriod, restrictWorld, true);
}
}
else {
if (!Bukkit.isPrimaryThread()) {
boolean verbose = false;
result = Rollback.performRollbackRestore(statement, null, uuids, restrictUsers, null, restrictBlocks, excludeBlocks, excludeUsers, actionList, location, argRadius, timePeriod, restrictWorld, false, verbose, action, 0);
}
}
statement.close();
connection.close();
}
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
@Deprecated
private List<String[]> processData(String user, int time, int radius, Location location, List<Object> restrictBlocks, List<Object> excludeBlocks, int action, int lookup, int offset, int rowCount, boolean useLimit) {
ArrayList<String> restrictUsers = new ArrayList<>();
if (user != null) {
restrictUsers.add(user);
}
return processData(time, radius, location, restrictBlocks, excludeBlocks, restrictUsers, null, null, action, lookup, offset, rowCount, useLimit);
}
public void testAPI() {
Chat.console(Phrase.build(Phrase.API_TEST));
}
}

View File

@ -0,0 +1,139 @@
package net.coreprotect.bukkit;
import java.util.List;
import java.util.Map;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.Sign;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Directional;
import org.bukkit.entity.Entity;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.utility.Util;
public class BukkitAdapter implements BukkitInterface {
public static BukkitInterface ADAPTER;
public static final int BUKKIT_v1_13 = 13;
public static final int BUKKIT_v1_14 = 14;
public static final int BUKKIT_v1_15 = 15;
public static final int BUKKIT_v1_16 = 16;
public static final int BUKKIT_v1_17 = 17;
public static void loadAdapter() {
switch (ConfigHandler.SERVER_VERSION) {
case BUKKIT_v1_13:
case BUKKIT_v1_14:
BukkitAdapter.ADAPTER = new BukkitAdapter();
break;
case BUKKIT_v1_15:
BukkitAdapter.ADAPTER = new Bukkit_v1_15();
break;
case BUKKIT_v1_16:
BukkitAdapter.ADAPTER = new Bukkit_v1_16();
break;
case BUKKIT_v1_17:
default:
BukkitAdapter.ADAPTER = new Bukkit_v1_17();
break;
}
}
@Override
public String parseLegacyName(String name) {
return name;
}
@Override
public int getLegacyBlockId(Material material) {
return -1;
}
@Override
public boolean getEntityMeta(LivingEntity entity, List<Object> info) {
return false;
}
@Override
public boolean setEntityMeta(Entity entity, Object value, int count) {
return false;
}
@Override
public boolean getItemMeta(ItemMeta itemMeta, List<Map<String, Object>> list, List<List<Map<String, Object>>> metadata, int slot) {
return false;
}
@Override
public boolean setItemMeta(Material rowType, ItemStack itemstack, List<Map<String, Object>> map) {
return false;
}
@Override
public boolean isAttached(Block block, Block scanBlock, BlockData blockData, int scanMin) {
if (blockData instanceof Directional) {
return (scanMin < 5 && scanBlock.getRelative(((Directional) blockData).getFacing().getOppositeFace()).getLocation().equals(block.getLocation()));
}
return true; // unvalidated attachments default to true
}
@Override
public boolean isWall(BlockData blockData) {
return false;
}
@Override
public void sendSignChange(Player player, Sign sign) {
return;
}
@Override
public int getMinHeight(World world) {
return 0;
}
@Override
public Material getBucketContents(Material material) {
return Material.AIR;
}
@Override
public boolean isItemFrame(Material material) {
return (material == Material.ITEM_FRAME);
}
@Override
public Material getFrameType(Entity entity) {
return Material.ITEM_FRAME;
}
@Override
public Class<?> getFrameClass(Material material) {
return ItemFrame.class;
}
@Override
public boolean isGlowing(Sign sign) {
return false;
}
@Override
public void setGlowing(Sign sign, boolean set) {
return;
}
@Override
public boolean isInvisible(Material material) {
return Util.isAir(material);
}
}

View File

@ -0,0 +1,53 @@
package net.coreprotect.bukkit;
import java.util.List;
import java.util.Map;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.Sign;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
public interface BukkitInterface {
public Material getBucketContents(Material material);
public Material getFrameType(Entity entity);
public Class<?> getFrameClass(Material material);
public String parseLegacyName(String name);
public boolean getEntityMeta(LivingEntity entity, List<Object> info);
public boolean setEntityMeta(Entity entity, Object value, int count);
public boolean getItemMeta(ItemMeta itemMeta, List<Map<String, Object>> list, List<List<Map<String, Object>>> metadata, int slot);
public boolean setItemMeta(Material rowType, ItemStack itemstack, List<Map<String, Object>> map);
public boolean isAttached(Block block, Block scanBlock, BlockData blockData, int scanMin);
public boolean isWall(BlockData blockData);
public boolean isItemFrame(Material material);
public boolean isGlowing(Sign sign);
public boolean isInvisible(Material material);
public int getMinHeight(World world);
public int getLegacyBlockId(Material material);
public void sendSignChange(Player player, Sign sign);
public void setGlowing(Sign sign, boolean b);
}

View File

@ -0,0 +1,105 @@
package net.coreprotect.bukkit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.bukkit.Material;
import org.bukkit.block.Sign;
import org.bukkit.entity.Bee;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SuspiciousStewMeta;
import org.bukkit.potion.PotionEffect;
public class Bukkit_v1_15 extends BukkitAdapter implements BukkitInterface {
@Override
public boolean getEntityMeta(LivingEntity entity, List<Object> info) {
if (entity instanceof Bee) {
Bee bee = (Bee) entity;
info.add(bee.getAnger());
info.add(bee.hasNectar());
info.add(bee.hasStung());
}
else {
return false;
}
return true;
}
@Override
public boolean setEntityMeta(Entity entity, Object value, int count) {
if (entity instanceof Bee) {
Bee bee = (Bee) entity;
if (count == 0) {
int set = (int) value;
bee.setAnger(set);
}
else if (count == 1) {
boolean set = (Boolean) value;
bee.setHasNectar(set);
}
else if (count == 2) {
boolean set = (Boolean) value;
bee.setHasStung(set);
}
}
else {
return false;
}
return true;
}
@Override
public boolean getItemMeta(ItemMeta itemMeta, List<Map<String, Object>> list, List<List<Map<String, Object>>> metadata, int slot) {
if (itemMeta instanceof SuspiciousStewMeta) {
SuspiciousStewMeta meta = (SuspiciousStewMeta) itemMeta;
SuspiciousStewMeta subMeta = meta.clone();
meta.clearCustomEffects();
list.add(meta.serialize());
metadata.add(list);
if (subMeta.hasCustomEffects()) {
for (PotionEffect effect : subMeta.getCustomEffects()) {
list = new ArrayList<>();
list.add(effect.serialize());
metadata.add(list);
}
}
}
else {
return false;
}
return true;
}
@Override
public boolean setItemMeta(Material rowType, ItemStack itemstack, List<Map<String, Object>> map) {
if ((rowType == Material.SUSPICIOUS_STEW)) {
for (Map<String, Object> suspiciousStewData : map) {
SuspiciousStewMeta meta = (SuspiciousStewMeta) itemstack.getItemMeta();
PotionEffect effect = new PotionEffect(suspiciousStewData);
meta.addCustomEffect(effect, true);
itemstack.setItemMeta(meta);
}
}
else {
return false;
}
return true;
}
@Override
public void sendSignChange(Player player, Sign sign) {
player.sendSignChange(sign.getLocation(), sign.getLines(), sign.getColor());
}
}

View File

@ -0,0 +1,118 @@
package net.coreprotect.bukkit;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Directional;
import org.bukkit.block.data.FaceAttachable;
import org.bukkit.block.data.type.Wall;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Piglin;
import org.bukkit.entity.Zoglin;
import net.coreprotect.model.BlockGroup;
public class Bukkit_v1_16 extends Bukkit_v1_15 implements BukkitInterface {
public Bukkit_v1_16() {
BlockGroup.TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP, Material.SOUL_TORCH, Material.TWISTING_VINES, Material.CRIMSON_FUNGUS, Material.WARPED_FUNGUS, Material.CRIMSON_ROOTS, Material.WARPED_ROOTS, Material.NETHER_SPROUTS, Material.CRIMSON_SIGN, Material.WARPED_SIGN));
BlockGroup.TRACK_BOTTOM = new HashSet<>(Arrays.asList(Material.WEEPING_VINES));
BlockGroup.TRACK_SIDE = new HashSet<>(Arrays.asList(Material.WALL_TORCH, Material.REDSTONE_WALL_TORCH, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.ACTIVATOR_RAIL, Material.WHITE_BED, Material.ORANGE_BED, Material.MAGENTA_BED, Material.LIGHT_BLUE_BED, Material.YELLOW_BED, Material.LIME_BED, Material.PINK_BED, Material.GRAY_BED, Material.LIGHT_GRAY_BED, Material.CYAN_BED, Material.PURPLE_BED, Material.BLUE_BED, Material.BROWN_BED, Material.GREEN_BED, Material.RED_BED, Material.BLACK_BED, Material.LADDER, Material.ACACIA_WALL_SIGN, Material.BIRCH_WALL_SIGN, Material.DARK_OAK_WALL_SIGN, Material.JUNGLE_WALL_SIGN, Material.OAK_WALL_SIGN, Material.SPRUCE_WALL_SIGN, Material.VINE, Material.COCOA, Material.TRIPWIRE_HOOK, Material.WHITE_WALL_BANNER, Material.ORANGE_WALL_BANNER, Material.MAGENTA_WALL_BANNER, Material.LIGHT_BLUE_WALL_BANNER, Material.YELLOW_WALL_BANNER, Material.LIME_WALL_BANNER, Material.PINK_WALL_BANNER, Material.GRAY_WALL_BANNER, Material.LIGHT_GRAY_WALL_BANNER, Material.CYAN_WALL_BANNER, Material.PURPLE_WALL_BANNER, Material.BLUE_WALL_BANNER, Material.BROWN_WALL_BANNER, Material.GREEN_WALL_BANNER, Material.RED_WALL_BANNER, Material.BLACK_WALL_BANNER, Material.SOUL_WALL_TORCH, Material.CRIMSON_WALL_SIGN, Material.WARPED_WALL_SIGN));
BlockGroup.DOORS = new HashSet<>(Arrays.asList(Material.OAK_DOOR, Material.SPRUCE_DOOR, Material.BIRCH_DOOR, Material.JUNGLE_DOOR, Material.ACACIA_DOOR, Material.DARK_OAK_DOOR, Material.CRIMSON_DOOR, Material.WARPED_DOOR));
BlockGroup.BUTTONS = new HashSet<>(Arrays.asList(Material.STONE_BUTTON, Material.OAK_BUTTON, Material.ACACIA_BUTTON, Material.BIRCH_BUTTON, Material.DARK_OAK_BUTTON, Material.JUNGLE_BUTTON, Material.SPRUCE_BUTTON, Material.POLISHED_BLACKSTONE_BUTTON, Material.CRIMSON_BUTTON, Material.WARPED_BUTTON));
BlockGroup.PRESSURE_PLATES = new HashSet<>(Arrays.asList(Material.STONE_PRESSURE_PLATE, Material.ACACIA_PRESSURE_PLATE, Material.BIRCH_PRESSURE_PLATE, Material.DARK_OAK_PRESSURE_PLATE, Material.HEAVY_WEIGHTED_PRESSURE_PLATE, Material.JUNGLE_PRESSURE_PLATE, Material.LIGHT_WEIGHTED_PRESSURE_PLATE, Material.OAK_PRESSURE_PLATE, Material.SPRUCE_PRESSURE_PLATE, Material.CRIMSON_PRESSURE_PLATE, Material.WARPED_PRESSURE_PLATE, Material.POLISHED_BLACKSTONE_PRESSURE_PLATE));
BlockGroup.VINES = new HashSet<>(Arrays.asList(Material.VINE, Material.WEEPING_VINES, Material.TWISTING_VINES));
BlockGroup.LIGHTABLES = new HashSet<>(Arrays.asList(Material.CAMPFIRE, Material.SOUL_CAMPFIRE));
BlockGroup.FIRE = new HashSet<>(Arrays.asList(Material.FIRE, Material.SOUL_FIRE));
BlockGroup.LANTERNS = new HashSet<>(Arrays.asList(Material.LANTERN, Material.SOUL_LANTERN));
BlockGroup.SOUL_BLOCKS = new HashSet<>(Arrays.asList(Material.SOUL_SAND, Material.SOUL_SOIL));
BlockGroup.INTERACT_BLOCKS = new HashSet<>(Arrays.asList(Material.SPRUCE_FENCE_GATE, Material.BIRCH_FENCE_GATE, Material.JUNGLE_FENCE_GATE, Material.DARK_OAK_FENCE_GATE, Material.ACACIA_FENCE_GATE, Material.DISPENSER, Material.NOTE_BLOCK, Material.CHEST, Material.FURNACE, Material.LEVER, Material.REPEATER, Material.ACACIA_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.DARK_OAK_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.OAK_TRAPDOOR, Material.OAK_FENCE_GATE, Material.BREWING_STAND, Material.ANVIL, Material.CHIPPED_ANVIL, Material.DAMAGED_ANVIL, Material.ENDER_CHEST, Material.TRAPPED_CHEST, Material.COMPARATOR, Material.HOPPER, Material.DROPPER, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.GRINDSTONE, Material.LOOM, Material.SMOKER, Material.CARTOGRAPHY_TABLE, Material.CRIMSON_FENCE_GATE, Material.WARPED_FENCE_GATE, Material.CRIMSON_TRAPDOOR, Material.WARPED_TRAPDOOR));
BlockGroup.SAFE_INTERACT_BLOCKS = new HashSet<>(Arrays.asList(Material.LEVER, Material.ACACIA_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.DARK_OAK_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.OAK_TRAPDOOR, Material.OAK_FENCE_GATE, Material.SPRUCE_FENCE_GATE, Material.BIRCH_FENCE_GATE, Material.JUNGLE_FENCE_GATE, Material.DARK_OAK_FENCE_GATE, Material.ACACIA_FENCE_GATE, Material.CRIMSON_FENCE_GATE, Material.WARPED_FENCE_GATE, Material.CRIMSON_TRAPDOOR, Material.WARPED_TRAPDOOR));
BlockGroup.UPDATE_STATE = new HashSet<>(Arrays.asList(Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FURNACE, Material.BLAST_FURNACE, Material.SMOKER, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.GLOWSTONE, Material.JACK_O_LANTERN, Material.REPEATER, Material.REDSTONE_LAMP, Material.BEACON, Material.COMPARATOR, Material.DAYLIGHT_DETECTOR, Material.REDSTONE_BLOCK, Material.HOPPER, Material.CHEST, Material.TRAPPED_CHEST, Material.ACTIVATOR_RAIL, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.SHROOMLIGHT, Material.RESPAWN_ANCHOR, Material.CRYING_OBSIDIAN, Material.TARGET));
BlockGroup.NON_ATTACHABLE = new HashSet<>(Arrays.asList(Material.AIR, Material.CAVE_AIR, Material.BARRIER, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.WATER, Material.LAVA, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.LADDER, Material.RAIL, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.SNOW, Material.SUGAR_CANE, Material.NETHER_PORTAL, Material.REPEATER, Material.KELP, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH));
}
@Override
public boolean getEntityMeta(LivingEntity entity, List<Object> info) {
if (entity instanceof Piglin) {
Piglin piglin = (Piglin) entity;
info.add(piglin.isBaby());
}
else if (entity instanceof Zoglin) {
Zoglin zoglin = (Zoglin) entity;
info.add(zoglin.isBaby());
}
else if (super.getEntityMeta(entity, info)) {
return true;
}
else {
return false;
}
return true;
}
@Override
public boolean setEntityMeta(Entity entity, Object value, int count) {
if (entity instanceof Piglin) {
Piglin piglin = (Piglin) entity;
if (count == 0) {
boolean set = (Boolean) value;
piglin.setBaby(set);
}
}
else if (entity instanceof Zoglin) {
Zoglin zoglin = (Zoglin) entity;
if (count == 0) {
boolean set = (Boolean) value;
zoglin.setBaby(set);
}
}
else if (super.setEntityMeta(entity, value, count)) {
return true;
}
else {
return false;
}
return true;
}
@Override
public boolean isAttached(Block block, Block scanBlock, BlockData blockData, int scanMin) {
if (blockData instanceof Directional && blockData instanceof FaceAttachable) {
Directional directional = (Directional) blockData;
FaceAttachable faceAttachable = (FaceAttachable) blockData;
boolean scanButton = false;
switch (faceAttachable.getAttachedFace()) {
case WALL:
scanButton = (scanMin < 5 && scanBlock.getRelative(directional.getFacing().getOppositeFace()).getLocation().equals(block.getLocation()));
break;
case FLOOR:
scanButton = (scanMin == 5);
break;
case CEILING:
scanButton = (scanMin == 6);
break;
default:
break;
}
return scanButton;
}
return true; // unvalidated attachments default to true
}
@Override
public boolean isWall(BlockData blockData) {
return (blockData instanceof Wall);
}
}

View File

@ -0,0 +1,222 @@
package net.coreprotect.bukkit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Sign;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.PointedDripstone;
import org.bukkit.entity.Axolotl;
import org.bukkit.entity.Entity;
import org.bukkit.entity.GlowItemFrame;
import org.bukkit.entity.Goat;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BundleMeta;
import org.bukkit.inventory.meta.ItemMeta;
import net.coreprotect.model.BlockGroup;
import net.coreprotect.utility.Util;
public class Bukkit_v1_17 extends Bukkit_v1_16 implements BukkitInterface {
public Bukkit_v1_17() {
BlockGroup.TRACK_ANY = new HashSet<>(Arrays.asList(Material.MOVING_PISTON, Material.LEVER, Material.BELL, Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER, Material.GLOW_LICHEN));
BlockGroup.TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP, Material.SOUL_TORCH, Material.TWISTING_VINES, Material.CRIMSON_FUNGUS, Material.WARPED_FUNGUS, Material.CRIMSON_ROOTS, Material.WARPED_ROOTS, Material.NETHER_SPROUTS, Material.CRIMSON_SIGN, Material.WARPED_SIGN, Material.AZALEA, Material.FLOWERING_AZALEA, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF));
BlockGroup.TRACK_TOP_BOTTOM = new HashSet<>(Arrays.asList(Material.POINTED_DRIPSTONE, Material.BIG_DRIPLEAF_STEM));
BlockGroup.TRACK_BOTTOM = new HashSet<>(Arrays.asList(Material.WEEPING_VINES, Material.CAVE_VINES, Material.CAVE_VINES_PLANT, Material.HANGING_ROOTS));
BlockGroup.VINES = new HashSet<>(Arrays.asList(Material.VINE, Material.WEEPING_VINES, Material.TWISTING_VINES, Material.CAVE_VINES));
BlockGroup.CANDLES = new HashSet<>(Arrays.asList(Material.CANDLE, Material.BLACK_CANDLE, Material.BLUE_CANDLE, Material.BROWN_CANDLE, Material.CYAN_CANDLE, Material.GRAY_CANDLE, Material.GREEN_CANDLE, Material.LIGHT_BLUE_CANDLE, Material.LIGHT_GRAY_CANDLE, Material.LIME_CANDLE, Material.MAGENTA_CANDLE, Material.ORANGE_CANDLE, Material.PINK_CANDLE, Material.PURPLE_CANDLE, Material.RED_CANDLE, Material.WHITE_CANDLE, Material.YELLOW_CANDLE, Material.CANDLE_CAKE, Material.BLACK_CANDLE_CAKE, Material.BLUE_CANDLE_CAKE, Material.BROWN_CANDLE_CAKE, Material.CYAN_CANDLE_CAKE, Material.GRAY_CANDLE_CAKE, Material.GREEN_CANDLE_CAKE, Material.LIGHT_BLUE_CANDLE_CAKE, Material.LIGHT_GRAY_CANDLE_CAKE, Material.LIME_CANDLE_CAKE, Material.MAGENTA_CANDLE_CAKE, Material.ORANGE_CANDLE_CAKE, Material.PINK_CANDLE_CAKE, Material.PURPLE_CANDLE_CAKE, Material.RED_CANDLE_CAKE, Material.WHITE_CANDLE_CAKE, Material.YELLOW_CANDLE_CAKE));
BlockGroup.AMETHYST = new HashSet<>(Arrays.asList(Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER));
BlockGroup.UPDATE_STATE = new HashSet<>(Arrays.asList(Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FURNACE, Material.BLAST_FURNACE, Material.SMOKER, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.GLOWSTONE, Material.JACK_O_LANTERN, Material.REPEATER, Material.REDSTONE_LAMP, Material.BEACON, Material.COMPARATOR, Material.DAYLIGHT_DETECTOR, Material.REDSTONE_BLOCK, Material.HOPPER, Material.CHEST, Material.TRAPPED_CHEST, Material.ACTIVATOR_RAIL, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.SHROOMLIGHT, Material.RESPAWN_ANCHOR, Material.CRYING_OBSIDIAN, Material.TARGET, Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER, Material.CAVE_VINES, Material.CAVE_VINES_PLANT, Material.GLOW_LICHEN, Material.LIGHT, Material.LAVA_CAULDRON));
BlockGroup.NON_ATTACHABLE = new HashSet<>(Arrays.asList(Material.AIR, Material.CAVE_AIR, Material.BARRIER, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.WATER, Material.LAVA, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.LADDER, Material.RAIL, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.SNOW, Material.SUGAR_CANE, Material.NETHER_PORTAL, Material.REPEATER, Material.KELP, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.LIGHT, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF, Material.BIG_DRIPLEAF_STEM, Material.GLOW_LICHEN, Material.HANGING_ROOTS));
BlockGroup.VERTICAL_TOP_BOTTOM = new HashSet<>(Arrays.asList(Material.BIG_DRIPLEAF_STEM));
}
@Override
public String parseLegacyName(String name) {
switch (name) {
case "GRASS_PATH":
name = "DIRT_PATH";
break;
default:
break;
}
return name;
}
@Override
public int getLegacyBlockId(Material material) {
switch (material) {
case DIRT_PATH:
return Util.getBlockId("GRASS_PATH", false);
default:
return -1;
}
}
@Override
public boolean getEntityMeta(LivingEntity entity, List<Object> info) {
if (entity instanceof Axolotl) {
Axolotl axolotl = (Axolotl) entity;
info.add(axolotl.getVariant());
}
else if (entity instanceof Goat) {
Goat goat = (Goat) entity;
info.add(goat.isScreaming());
}
else if (super.getEntityMeta(entity, info)) {
return true;
}
else {
return false;
}
return true;
}
@Override
public boolean setEntityMeta(Entity entity, Object value, int count) {
if (entity instanceof Axolotl) {
Axolotl axolotl = (Axolotl) entity;
if (count == 0) {
org.bukkit.entity.Axolotl.Variant set = (org.bukkit.entity.Axolotl.Variant) value;
axolotl.setVariant(set);
}
}
else if (entity instanceof Goat) {
Goat goat = (Goat) entity;
if (count == 0) {
boolean set = (Boolean) value;
goat.setScreaming(set);
}
}
else if (super.setEntityMeta(entity, value, count)) {
return true;
}
else {
return false;
}
return true;
}
@Override
public boolean getItemMeta(ItemMeta itemMeta, List<Map<String, Object>> list, List<List<Map<String, Object>>> metadata, int slot) {
if (itemMeta instanceof BundleMeta) {
BundleMeta meta = (BundleMeta) itemMeta;
BundleMeta subMeta = (BundleMeta) meta.clone();
meta.setItems(null);
list.add(meta.serialize());
metadata.add(list);
if (subMeta.hasItems()) {
list = new ArrayList<>();
for (ItemStack itemStack : subMeta.getItems()) {
Map<String, Object> itemMap = Util.serializeItemStack(itemStack, slot);
if (itemMap.size() > 0) {
list.add(itemMap);
}
}
metadata.add(list);
}
}
else if (super.getItemMeta(itemMeta, list, metadata, slot)) {
return true;
}
else {
return false;
}
return true;
}
@Override
public boolean setItemMeta(Material rowType, ItemStack itemstack, List<Map<String, Object>> map) {
if ((rowType == Material.BUNDLE)) {
BundleMeta meta = (BundleMeta) itemstack.getItemMeta();
for (Map<String, Object> itemData : map) {
ItemStack itemStack = Util.unserializeItemStack(itemData);
if (itemStack != null) {
meta.addItem(itemStack);
}
}
itemstack.setItemMeta(meta);
}
else if (super.setItemMeta(rowType, itemstack, map)) {
return true;
}
else {
return false;
}
return true;
}
@Override
public boolean isAttached(Block block, Block scanBlock, BlockData blockData, int scanMin) {
if (blockData instanceof PointedDripstone) {
PointedDripstone pointedDripstone = (PointedDripstone) blockData;
BlockFace blockFace = pointedDripstone.getVerticalDirection();
boolean adjacent = scanBlock.getRelative(blockFace.getOppositeFace()).getLocation().equals(block.getLocation());
if (!adjacent) {
return false;
}
}
else if (!super.isAttached(block, scanBlock, blockData, scanMin)) {
return false;
}
return true;
}
@Override
public int getMinHeight(World world) {
return world.getMinHeight();
}
@Override
public Material getBucketContents(Material material) {
return (material == Material.POWDER_SNOW_BUCKET ? Material.POWDER_SNOW : Material.AIR);
}
@Override
public boolean isItemFrame(Material material) {
return (material == Material.ITEM_FRAME || material == Material.GLOW_ITEM_FRAME);
}
@Override
public Material getFrameType(Entity entity) {
return (entity instanceof GlowItemFrame) ? Material.GLOW_ITEM_FRAME : Material.ITEM_FRAME;
}
@Override
public Class<?> getFrameClass(Material material) {
return (material == Material.GLOW_ITEM_FRAME) ? GlowItemFrame.class : ItemFrame.class;
}
@Override
public boolean isGlowing(Sign sign) {
return sign.isGlowingText();
}
@Override
public void setGlowing(Sign sign, boolean set) {
sign.setGlowingText(set);
}
@Override
public boolean isInvisible(Material material) {
return material.isAir() || material == Material.LIGHT;
}
}

View File

@ -0,0 +1,47 @@
package net.coreprotect.command;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class ApplyCommand {
protected static void runCommand(CommandSender user, Command command, boolean permission, String[] args) {
try {
if (ConfigHandler.lastRollback.get(user.getName()) != null) {
List<Object> list = ConfigHandler.lastRollback.get(user.getName());
int time = (Integer) list.get(0);
args = (String[]) list.get(1);
Location location = (Location) list.get(2);
boolean valid = false;
for (int i = 0; i < args.length; i++) {
if (args[i].equals("#preview")) {
valid = true;
args[i] = args[i].replaceAll("#preview", "");
}
}
if (!valid) {
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_ROLLBACK, Selector.FIRST));
}
else {
ConfigHandler.lastRollback.remove(user.getName());
RollbackRestoreCommand.runCommand(user, command, permission, args, location, time);
}
}
else {
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_ROLLBACK, Selector.FIRST));
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,47 @@
package net.coreprotect.command;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class CancelCommand {
protected static void runCommand(CommandSender user, Command command, boolean permission, String[] args) {
try {
if (ConfigHandler.lastRollback.get(user.getName()) != null) {
List<Object> list = ConfigHandler.lastRollback.get(user.getName());
int time = (Integer) list.get(0);
args = (String[]) list.get(1);
Location location = (Location) list.get(2);
boolean valid = false;
for (int i = 0; i < args.length; i++) {
if (args[i].equals("#preview")) {
valid = true;
args[i] = args[i].replaceAll("#preview", "#preview_cancel");
}
}
if (!valid) {
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_ROLLBACK, Selector.FIRST));
}
else {
ConfigHandler.lastRollback.remove(user.getName());
RollbackRestoreCommand.runCommand(user, command, permission, args, location, time);
}
}
else {
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_ROLLBACK, Selector.FIRST));
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,129 @@
package net.coreprotect.command;
import java.util.Locale;
import org.bukkit.command.CommandSender;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
public class HelpCommand {
protected static void runCommand(CommandSender player, boolean permission, String[] args) {
int resultc = args.length;
if (permission) {
if (resultc > 1) {
String helpcommand_original = args[1];
String helpcommand = args[1].toLowerCase(Locale.ROOT);
helpcommand = helpcommand.replaceAll("[^a-zA-Z]", "");
Chat.sendMessage(player, Color.WHITE + "----- " + Color.DARK_AQUA + Phrase.build(Phrase.HELP_HEADER, "CoreProtect") + Color.WHITE + " -----");
if (helpcommand.equals("help")) {
Chat.sendMessage(player, Color.DARK_AQUA + "/co help " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_LIST));
}
else if (helpcommand.equals("inspect") || helpcommand.equals("inspector") || helpcommand.equals("in")) {
Chat.sendMessage(player, Color.DARK_AQUA + Phrase.build(Phrase.HELP_INSPECT_1));
Chat.sendMessage(player, "* " + Phrase.build(Phrase.HELP_INSPECT_2));
Chat.sendMessage(player, "* " + Phrase.build(Phrase.HELP_INSPECT_3));
Chat.sendMessage(player, "* " + Phrase.build(Phrase.HELP_INSPECT_4));
Chat.sendMessage(player, "* " + Phrase.build(Phrase.HELP_INSPECT_5));
Chat.sendMessage(player, "* " + Phrase.build(Phrase.HELP_INSPECT_6));
Chat.sendMessage(player, Color.GREY + Color.ITALIC + Phrase.build(Phrase.HELP_INSPECT_7));
}
else if (helpcommand.equals("params") || helpcommand.equals("param") || helpcommand.equals("parameters") || helpcommand.equals("parameter")) {
Chat.sendMessage(player, Color.DARK_AQUA + "/co lookup " + Color.GREY + "<params> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_1, Selector.FIRST));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "u:<users> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_2, Selector.FIRST));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "t:<time> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_3, Selector.FIRST));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "r:<radius> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_4, Selector.FIRST));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "a:<action> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_5, Selector.FIRST));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "i:<include> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_6, Selector.FIRST));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "e:<exclude> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_7, Selector.FIRST));
Chat.sendMessage(player, Color.GREY + Color.ITALIC + Phrase.build(Phrase.HELP_PARAMETER, "/co help <param>"));
}
else if (helpcommand.equals("rollback") || helpcommand.equals("rollbacks") || helpcommand.equals("rb") || helpcommand.equals("ro")) {
Chat.sendMessage(player, Color.DARK_AQUA + "/co rollback " + Color.GREY + "<params> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_1, Selector.SECOND));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "u:<users> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_2, Selector.SECOND));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "t:<time> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_3, Selector.SECOND));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "r:<radius> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_4, Selector.SECOND));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "a:<action> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_5, Selector.SECOND));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "i:<include> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_6, Selector.SECOND));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "e:<exclude> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_7, Selector.SECOND));
Chat.sendMessage(player, Color.GREY + Color.ITALIC + Phrase.build(Phrase.HELP_PARAMETER, "/co help <param>"));
}
else if (helpcommand.equals("restore") || helpcommand.equals("restores") || helpcommand.equals("re") || helpcommand.equals("rs")) {
Chat.sendMessage(player, Color.DARK_AQUA + "/co restore " + Color.GREY + "<params> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_1, Selector.THIRD));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "u:<users> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_2, Selector.THIRD));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "t:<time> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_3, Selector.THIRD));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "r:<radius> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_4, Selector.THIRD));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "a:<action> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_5, Selector.THIRD));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "i:<include> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_6, Selector.THIRD));
Chat.sendMessage(player, Color.DARK_AQUA + "| " + Color.GREY + "e:<exclude> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PARAMS_7, Selector.THIRD));
Chat.sendMessage(player, Color.GREY + Color.ITALIC + Phrase.build(Phrase.HELP_PARAMETER, "/co help <param>"));
}
else if (helpcommand.equals("lookup") || helpcommand.equals("lookups") || helpcommand.equals("l")) {
Chat.sendMessage(player, Color.DARK_AQUA + "/co lookup <params>");
Chat.sendMessage(player, Color.DARK_AQUA + "/co l <params> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_LOOKUP_1));
Chat.sendMessage(player, Color.DARK_AQUA + "/co lookup <page> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_LOOKUP_2));
Chat.sendMessage(player, Color.GREY + Color.ITALIC + Phrase.build(Phrase.HELP_PARAMETER, "/co help params"));
}
else if (helpcommand.equals("purge") || helpcommand.equals("purges")) {
Chat.sendMessage(player, Color.DARK_AQUA + "/co purge t:<time> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PURGE_1));
Chat.sendMessage(player, Color.GREY + Color.ITALIC + "" + Phrase.build(Phrase.HELP_PURGE_2, "/co purge t:30d"));
}
else if (helpcommand.equals("reload")) {
Chat.sendMessage(player, Color.DARK_AQUA + "/co reload " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_RELOAD_COMMAND));
}
else if (helpcommand.equals("status")) {
Chat.sendMessage(player, Color.DARK_AQUA + "/co status " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_STATUS));
}
else if (helpcommand.equals("teleport")) {
Chat.sendMessage(player, Color.DARK_AQUA + "/co teleport <world> <x> <y> <z> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_TELEPORT));
}
else if (helpcommand.equals("u") || helpcommand.equals("user") || helpcommand.equals("users") || helpcommand.equals("uuser") || helpcommand.equals("uusers")) {
Chat.sendMessage(player, Color.DARK_AQUA + "/co lookup u:<users> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_USER_1));
Chat.sendMessage(player, Color.GREY + Color.ITALIC + Phrase.build(Phrase.HELP_USER_2));
}
else if (helpcommand.equals("t") || helpcommand.equals("time") || helpcommand.equals("ttime")) {
Chat.sendMessage(player, Color.DARK_AQUA + "/co lookup t:<time> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_TIME_1));
Chat.sendMessage(player, Color.GREY + Color.ITALIC + Phrase.build(Phrase.HELP_TIME_2));
}
else if (helpcommand.equals("r") || helpcommand.equals("radius") || helpcommand.equals("rradius")) {
Chat.sendMessage(player, Color.DARK_AQUA + "/co lookup r:<radius> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_RADIUS_1));
Chat.sendMessage(player, Color.GREY + Color.ITALIC + Phrase.build(Phrase.HELP_RADIUS_2));
}
else if (helpcommand.equals("a") || helpcommand.equals("action") || helpcommand.equals("actions") || helpcommand.equals("aaction")) {
Chat.sendMessage(player, Color.DARK_AQUA + "/co lookup a:<action> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_ACTION_1));
Chat.sendMessage(player, Color.GREY + Color.ITALIC + Phrase.build(Phrase.HELP_ACTION_2));
}
else if (helpcommand.equals("i") || helpcommand.equals("include") || helpcommand.equals("iinclude") || helpcommand.equals("b") || helpcommand.equals("block") || helpcommand.equals("blocks") || helpcommand.equals("bblock") || helpcommand.equals("bblocks")) {
Chat.sendMessage(player, Color.DARK_AQUA + "/co lookup i:<include> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_INCLUDE_1));
Chat.sendMessage(player, Color.GREY + Color.ITALIC + Phrase.build(Phrase.HELP_INCLUDE_2));
Chat.sendMessage(player, Color.GREY + Color.ITALIC + Phrase.build(Phrase.LINK_WIKI_BLOCK, "https://coreprotect.net/wiki-blocks"));
Chat.sendMessage(player, Color.GREY + Color.ITALIC + Phrase.build(Phrase.LINK_WIKI_ENTITY, "https://coreprotect.net/wiki-entities"));
}
else if (helpcommand.equals("e") || helpcommand.equals("exclude") || helpcommand.equals("eexclude")) {
Chat.sendMessage(player, Color.DARK_AQUA + "/co lookup e:<exclude> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_EXCLUDE_1));
Chat.sendMessage(player, Color.GREY + Color.ITALIC + Phrase.build(Phrase.HELP_EXCLUDE_2));
Chat.sendMessage(player, Color.GREY + Color.ITALIC + Phrase.build(Phrase.LINK_WIKI_BLOCK, "https://coreprotect.net/wiki-blocks"));
}
else {
Chat.sendMessage(player, Color.WHITE + Phrase.build(Phrase.HELP_NO_INFO, Color.WHITE, "/co help " + helpcommand_original));
}
}
else {
Chat.sendMessage(player, Color.WHITE + "----- " + Color.DARK_AQUA + Phrase.build(Phrase.HELP_HEADER, "CoreProtect") + Color.WHITE + " -----");
Chat.sendMessage(player, Color.DARK_AQUA + "/co help " + Color.GREY + "<command> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_COMMAND));
Chat.sendMessage(player, Color.DARK_AQUA + "/co " + Color.GREY + "inspect " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_INSPECT_COMMAND));
Chat.sendMessage(player, Color.DARK_AQUA + "/co " + Color.GREY + "rollback " + Color.DARK_AQUA + "<params> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_ROLLBACK_COMMAND));
Chat.sendMessage(player, Color.DARK_AQUA + "/co " + Color.GREY + "restore " + Color.DARK_AQUA + "<params> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_RESTORE_COMMAND));
Chat.sendMessage(player, Color.DARK_AQUA + "/co " + Color.GREY + "lookup " + Color.DARK_AQUA + "<params> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_LOOKUP_COMMAND));
Chat.sendMessage(player, Color.DARK_AQUA + "/co " + Color.GREY + "purge " + Color.DARK_AQUA + "<params> " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_PURGE_COMMAND));
Chat.sendMessage(player, Color.DARK_AQUA + "/co " + Color.GREY + "reload " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_RELOAD_COMMAND));
Chat.sendMessage(player, Color.DARK_AQUA + "/co " + Color.GREY + "status " + Color.WHITE + "- " + Phrase.build(Phrase.HELP_STATUS_COMMAND));
}
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
}
}
}

View File

@ -0,0 +1,53 @@
package net.coreprotect.command;
import org.bukkit.command.CommandSender;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class InspectCommand {
protected static void runCommand(CommandSender player, boolean permission, String[] args) {
if (permission) {
int command = -1;
ConfigHandler.inspecting.putIfAbsent(player.getName(), false);
if (args.length > 1) {
String action = args[1];
if (action.equalsIgnoreCase("on")) {
command = 1;
}
else if (action.equalsIgnoreCase("off")) {
command = 0;
}
}
if (!ConfigHandler.inspecting.get(player.getName())) {
if (command == 0) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INSPECTOR_ERROR, Selector.SECOND)); // already disabled
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INSPECTOR_TOGGLED, Selector.FIRST)); // now enabled
ConfigHandler.inspecting.put(player.getName(), true);
}
}
else {
if (command == 1) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INSPECTOR_ERROR, Selector.FIRST)); // already enabled
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INSPECTOR_TOGGLED, Selector.SECOND)); // now disabled
ConfigHandler.inspecting.put(player.getName(), false);
}
}
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
}
}
}

View File

@ -0,0 +1,993 @@
package net.coreprotect.command;
import java.sql.Connection;
import java.sql.Statement;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.Database;
import net.coreprotect.database.Lookup;
import net.coreprotect.database.lookup.BlockLookup;
import net.coreprotect.database.lookup.ChestTransactionLookup;
import net.coreprotect.database.lookup.InteractionLookup;
import net.coreprotect.database.lookup.PlayerLookup;
import net.coreprotect.database.lookup.SignMessageLookup;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.ChatMessage;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class LookupCommand {
protected static void runCommand(CommandSender player, Command command, boolean permission, String[] args) {
int resultc = args.length;
args = CommandHandler.parsePage(args);
Location lo = CommandHandler.parseLocation(player, args);
// List<String> arg_uuids = new ArrayList<String>();
List<String> argUsers = CommandHandler.parseUsers(args);
Integer[] argRadius = CommandHandler.parseRadius(args, player, lo);
int argNoisy = CommandHandler.parseNoisy(args);
List<Integer> argAction = CommandHandler.parseAction(args);
List<Object> argBlocks = CommandHandler.parseRestricted(player, args, argAction);
List<Object> argExclude = CommandHandler.parseExcluded(player, args, argAction);
List<String> argExcludeUsers = CommandHandler.parseExcludedUsers(player, args);
String ts = CommandHandler.parseTimeString(args);
int rbseconds = CommandHandler.parseTime(args);
int argWid = CommandHandler.parseWorld(args, true, true);
int parseRows = CommandHandler.parseRows(args);
boolean count = CommandHandler.parseCount(args);
boolean worldedit = CommandHandler.parseWorldEdit(args);
boolean forceglobal = CommandHandler.parseForceGlobal(args);
boolean pageLookup = false;
if (argBlocks == null || argExclude == null || argExcludeUsers == null) {
return;
}
int argExcluded = argExclude.size();
int argRestricted = argBlocks.size();
/* check for invalid block/entity combinations (include) */
boolean hasBlock = false;
boolean hasEntity = false;
for (Object arg : argBlocks) {
if (arg instanceof Material) {
hasBlock = true;
}
else if (arg instanceof EntityType) {
hasEntity = true;
if (argAction.size() == 0) {
argAction.add(3);
}
else if (!argAction.contains(3)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_INCLUDE_COMBO));
return;
}
}
}
/* check for invalid block/entity combinations (exclude) */
for (Object arg : argExclude) {
if (arg instanceof Material) {
hasBlock = true;
}
else if (arg instanceof EntityType) {
hasEntity = true;
if (argAction.size() == 0) {
argAction.add(3);
}
else if (!argAction.contains(3)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_INCLUDE_COMBO));
return;
}
}
}
if (hasBlock && hasEntity) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_INCLUDE_COMBO));
return;
}
if (argWid == -1) {
String worldName = CommandHandler.parseWorldName(args, true);
Chat.sendMessage(player, new ChatMessage(Phrase.build(Phrase.WORLD_NOT_FOUND, worldName)).build());
return;
}
int type = 0;
if (ConfigHandler.lookupType.get(player.getName()) != null) {
type = ConfigHandler.lookupType.get(player.getName());
}
if (type == 0 && resultc > 1) {
type = 4;
}
else if (resultc > 2) {
type = 4;
}
else if (resultc > 1) {
pageLookup = true;
String dat = args[1];
if (dat.contains(":")) {
String[] split = dat.split(":");
String check1 = split[0].replaceAll("[^a-zA-Z_]", "");
String check2 = "";
if (split.length > 1) {
check2 = split[1].replaceAll("[^a-zA-Z_]", "");
}
if (check1.length() > 0 || check2.length() > 0) {
type = 4;
pageLookup = false;
}
}
else {
String check1 = dat.replaceAll("[^a-zA-Z_]", "");
if (check1.length() > 0) {
type = 4;
pageLookup = false;
}
}
}
if (argAction.contains(6) || argAction.contains(7) || argAction.contains(8) || argAction.contains(9) || argAction.contains(10)) {
pageLookup = true;
}
if (!permission) {
if (!pageLookup || !player.hasPermission("coreprotect.inspect")) {
Chat.sendMessage(player, new ChatMessage(Phrase.build(Phrase.NO_PERMISSION)).build());
return;
}
}
if (ConfigHandler.converterRunning) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
return;
}
if (ConfigHandler.purgeRunning) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
return;
}
if (resultc < 2) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_PARAMETERS, "/co l <params>"));
return;
}
if (argAction.contains(-1)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_ACTION));
return;
}
if (worldedit && argRadius == null) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_SELECTION, "WorldEdit"));
return;
}
if (argRadius != null && argRadius[0] == -1) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_RADIUS));
return;
}
if (ConfigHandler.lookupThrottle.get(player.getName()) != null) {
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(player.getName());
if ((boolean) lookupThrottle[0] || ((System.currentTimeMillis() - (long) lookupThrottle[1])) < 50) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
return;
}
}
boolean allPermission = false;
if (args[0].equals("near") && player.hasPermission("coreprotect.lookup.near")) {
allPermission = true;
}
if (!allPermission) {
if (!pageLookup && (argAction.size() == 0 || (argAction.size() == 1 && (argAction.contains(0) || argAction.contains(1)))) && !player.hasPermission("coreprotect.lookup.block")) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
if (argAction.contains(2) && !player.hasPermission("coreprotect.lookup.click")) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
if (argAction.contains(3) && !player.hasPermission("coreprotect.lookup.kill")) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
if (argAction.contains(4) && !player.hasPermission("coreprotect.lookup.container")) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
if (argAction.contains(6) && !player.hasPermission("coreprotect.lookup.chat")) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
if (argAction.contains(7) && !player.hasPermission("coreprotect.lookup.command")) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
if (argAction.contains(8) && !player.hasPermission("coreprotect.lookup.session")) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
if (argAction.contains(9) && !player.hasPermission("coreprotect.lookup.username")) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
if (argAction.contains(10) && !player.hasPermission("coreprotect.lookup.sign")) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
if (argAction.contains(11) && !player.hasPermission("coreprotect.lookup.item")) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
}
if (argAction.contains(6) || argAction.contains(7) || argAction.contains(8) || argAction.contains(9) || argAction.contains(10)) {
if (argAction.contains(9) && (argRadius != null || argWid > 0 || worldedit)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INCOMPATIBLE_ACTION, "r:"));
return;
}
if (argBlocks.size() > 0) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INCOMPATIBLE_ACTION, "i:"));
return;
}
if (argExclude.size() > 0) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INCOMPATIBLE_ACTION, "e:"));
return;
}
}
if (rbseconds <= 0 && !pageLookup && type == 4 && (argBlocks.size() > 0 || argUsers.size() > 0)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_LOOKUP_TIME, Selector.FIRST));
return;
}
if (type == 1) {
boolean defaultRe = true;
int p = 0;
int re = 7;
if (parseRows > 0) {
re = parseRows;
}
if (resultc > 1) {
String pages = args[1];
if (pages.contains(":")) {
String[] data = pages.split(":");
pages = data[0];
String results = "";
if (data.length > 1) {
results = data[1];
}
results = results.replaceAll("[^0-9]", "");
if (results.length() > 0 && results.length() < 10) {
int r = Integer.parseInt(results);
if (r > 0) {
re = r;
defaultRe = false;
}
}
}
pages = pages.replaceAll("[^0-9]", "");
if (pages.length() > 0 && pages.length() < 10) {
int pa = Integer.parseInt(pages);
if (pa > 0) {
p = pa;
}
}
}
if (re > 1000) {
re = 1000;
}
if (re > 100 && !(player instanceof ConsoleCommandSender)) {
re = 100;
}
if (p <= 0) {
p = 1;
}
String lcommand = ConfigHandler.lookupCommand.get(player.getName());
String[] data = lcommand.split("\\.");
int x = Integer.parseInt(data[0]);
int y = Integer.parseInt(data[1]);
int z = Integer.parseInt(data[2]);
int wid = Integer.parseInt(data[3]);
int x2 = Integer.parseInt(data[4]);
int y2 = Integer.parseInt(data[5]);
int z2 = Integer.parseInt(data[6]);
if (defaultRe) {
re = Integer.parseInt(data[7]);
}
String bc = x + "." + y + "." + z + "." + wid + "." + x2 + "." + y2 + "." + z2 + "." + re;
ConfigHandler.lookupCommand.put(player.getName(), bc);
String world = Util.getWorldName(wid);
double dx = 0.5 * (x + x2);
double dy = 0.5 * (y + y2);
double dz = 0.5 * (z + z2);
final Location location = new Location(Bukkit.getServer().getWorld(world), dx, dy, dz);
final CommandSender player2 = player;
final int p2 = p;
final int finalLimit = re;
class BasicThread implements Runnable {
@Override
public void run() {
try {
ConfigHandler.lookupThrottle.put(player2.getName(), new Object[] { true, System.currentTimeMillis() });
Connection connection = Database.getConnection(true);
if (connection != null) {
Statement statement = connection.createStatement();
String blockdata = ChestTransactionLookup.performLookup(command.getName(), statement, location, player2, p2, finalLimit, false);
if (blockdata.contains("\n")) {
for (String b : blockdata.split("\n")) {
Chat.sendComponent(player2, b);
}
}
else {
Chat.sendComponent(player2, blockdata);
}
statement.close();
connection.close();
}
else {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
}
}
catch (Exception e) {
e.printStackTrace();
}
ConfigHandler.lookupThrottle.put(player2.getName(), new Object[] { false, System.currentTimeMillis() });
}
}
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
}
else if (type == 2 || type == 3 || type == 7 || type == 8) {
boolean defaultRe = true;
int page = 1;
int re = 7;
if (parseRows > 0) {
re = parseRows;
}
if (resultc > 1) {
String pages = args[1];
if (pages.contains(":")) {
String[] data = pages.split(":");
pages = data[0];
String results = "";
if (data.length > 1) {
results = data[1];
}
results = results.replaceAll("[^0-9]", "");
if (results.length() > 0 && results.length() < 10) {
int r = Integer.parseInt(results);
if (r > 0) {
re = r;
defaultRe = false;
}
}
}
pages = pages.replaceAll("[^0-9]", "");
if (pages.length() > 0 && pages.length() < 10) {
int p = Integer.parseInt(pages);
if (p > 0) {
page = p;
}
}
}
if (re > 1000) {
re = 1000;
}
if (re > 100 && !(player instanceof ConsoleCommandSender)) {
re = 100;
}
// String bc = x+"."+y+"."+z+"."+wid+"."+rstring+"."+lookup_user;
String lcommand = ConfigHandler.lookupCommand.get(player.getName());
String[] data = lcommand.split("\\.");
int x = Integer.parseInt(data[0]);
int y = Integer.parseInt(data[1]);
int z = Integer.parseInt(data[2]);
int wid = Integer.parseInt(data[3]);
int lookupType = Integer.parseInt(data[4]);
if (defaultRe) {
re = Integer.parseInt(data[5]);
}
String bc = x + "." + y + "." + z + "." + wid + "." + lookupType + "." + re;
ConfigHandler.lookupCommand.put(player.getName(), bc);
String world = Util.getWorldName(wid);
final Block fblock = Bukkit.getServer().getWorld(world).getBlockAt(x, y, z);// .getLocation();
final BlockState fblockstate = fblock.getState();
final CommandSender player2 = player;
final int p2 = page;
final int finalLimit = re;
final int t = type;
class BasicThread implements Runnable {
@Override
public void run() {
try {
ConfigHandler.lookupThrottle.put(player2.getName(), new Object[] { true, System.currentTimeMillis() });
Connection connection = Database.getConnection(true);
if (connection != null) {
Statement statement = connection.createStatement();
if (t == 8) {
List<String> signData = SignMessageLookup.performLookup(command.getName(), statement, fblockstate.getLocation(), player2, p2, finalLimit);
for (String signMessage : signData) {
String bypass = null;
if (signMessage.contains("\n")) {
String[] split = signMessage.split("\n");
signMessage = split[0];
bypass = split[1];
}
if (signMessage.length() > 0) {
Chat.sendComponent(player2, signMessage, bypass);
}
}
}
else {
String blockdata = null;
if (t == 7) {
blockdata = InteractionLookup.performLookup(command.getName(), statement, fblock, player2, 0, p2, finalLimit);
}
else {
blockdata = BlockLookup.performLookup(command.getName(), statement, fblockstate, player2, 0, p2, finalLimit);
}
if (blockdata.contains("\n")) {
for (String b : blockdata.split("\n")) {
Chat.sendComponent(player2, b);
}
}
else if (blockdata.length() > 0) {
Chat.sendComponent(player2, blockdata);
}
}
statement.close();
connection.close();
}
else {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
}
}
catch (Exception e) {
e.printStackTrace();
}
ConfigHandler.lookupThrottle.put(player2.getName(), new Object[] { false, System.currentTimeMillis() });
}
}
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
}
else if (type == 4 || type == 5) {
boolean defaultRe = true;
int pa = 1;
int re = 4;
if (argAction.contains(6) || argAction.contains(7) || argAction.contains(9)) {
re = 7;
}
if (parseRows > 0) {
re = parseRows;
}
if (type == 5) {
if (resultc > 1) {
String pages = args[1];
if (pages.contains(":")) {
String[] data = pages.split(":");
pages = data[0];
String results = "";
if (data.length > 1) {
results = data[1];
}
results = results.replaceAll("[^0-9]", "");
if (results.length() > 0 && results.length() < 10) {
int r = Integer.parseInt(results);
if (r > 0) {
re = r;
defaultRe = false;
}
}
}
pages = pages.replaceAll("[^0-9]", "");
if (pages.length() > 0 && pages.length() < 10) {
int p = Integer.parseInt(pages);
if (p > 0) {
pa = p;
}
}
}
}
if (re > 1000) {
re = 1000;
}
if (re > 100 && !(player instanceof ConsoleCommandSender)) {
re = 100;
}
int g = 1;
if (argUsers.contains("#global")) {
if (argRadius == null) {
g = 0;
}
}
if (g == 1 && (pageLookup || argBlocks.size() > 0 || argUsers.size() > 0 || (argUsers.size() == 0 && argRadius != null))) {
Integer MAX_RADIUS = Config.getGlobal().MAX_RADIUS;
if (argRadius != null) {
int radiusValue = argRadius[0];
if (radiusValue > MAX_RADIUS && MAX_RADIUS > 0) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MAXIMUM_RADIUS, MAX_RADIUS.toString(), Selector.FIRST));
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.GLOBAL_LOOKUP));
return;
}
}
if (argUsers.size() == 0) {
argUsers.add("#global");
}
List<String> rollbackusers = argUsers;
int c = 0;
for (String ruser : rollbackusers) {
List<Player> players = Bukkit.getServer().matchPlayer(ruser);
for (Player p : players) {
if (p.getName().equalsIgnoreCase(ruser)) {
rollbackusers.set(c, p.getName());
}
}
c++;
}
int cs = -1;
int x = 0;
int y = 0;
int z = 0;
int wid = 0;
if (type == 5) {
String lcommand = ConfigHandler.lookupCommand.get(player.getName());
String[] data = lcommand.split("\\.");
x = Integer.parseInt(data[0]);
y = Integer.parseInt(data[1]);
z = Integer.parseInt(data[2]);
wid = Integer.parseInt(data[3]);
cs = Integer.parseInt(data[4]);
// arg_radius = Integer.parseInt(data[5]);
argNoisy = Integer.parseInt(data[5]);
argExcluded = Integer.parseInt(data[6]);
argRestricted = Integer.parseInt(data[7]);
argWid = Integer.parseInt(data[8]);
if (defaultRe) {
re = Integer.parseInt(data[9]);
}
rollbackusers = ConfigHandler.lookupUlist.get(player.getName());
argBlocks = ConfigHandler.lookupBlist.get(player.getName());
argExclude = ConfigHandler.lookupElist.get(player.getName());
argExcludeUsers = ConfigHandler.lookupEUserlist.get(player.getName());
argAction = ConfigHandler.lookupAlist.get(player.getName());
argRadius = ConfigHandler.lookupRadius.get(player.getName());
ts = ConfigHandler.lookupTime.get(player.getName());
rbseconds = 1;
}
else {
if (lo != null) {
x = lo.getBlockX();
z = lo.getBlockZ();
wid = Util.getWorldId(lo.getWorld().getName());
}
if (rollbackusers.size() == 1 && rollbackusers.contains("#global") && argAction.contains(9)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_PARAMETERS, "/co l a:username u:<user>"));
return;
}
if (rollbackusers.contains("#container")) {
if (argAction.contains(6) || argAction.contains(7) || argAction.contains(8) || argAction.contains(9) || argAction.contains(10)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_USERNAME, "#container"));
return;
}
boolean valid = false;
if (ConfigHandler.lookupType.get(player.getName()) != null) {
int lookupType = ConfigHandler.lookupType.get(player.getName());
if (lookupType == 1) {
valid = true;
}
else if (lookupType == 5) {
if (ConfigHandler.lookupUlist.get(player.getName()).contains("#container")) {
valid = true;
}
}
}
if (valid) {
if (!player.hasPermission("coreprotect.lookup.container") && !allPermission) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
String lcommand = ConfigHandler.lookupCommand.get(player.getName());
String[] data = lcommand.split("\\.");
x = Integer.parseInt(data[0]);
y = Integer.parseInt(data[1]);
z = Integer.parseInt(data[2]);
wid = Integer.parseInt(data[3]);
argAction.add(5);
argRadius = null;
argWid = 0;
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_CONTAINER));
return;
}
}
}
final List<String> rollbackusers2 = rollbackusers;
int unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
if (cs == -1) {
if (rbseconds <= 0) {
cs = 0;
}
else {
cs = unixtimestamp - rbseconds;
}
}
final int stime = cs;
final Integer[] radius = argRadius;
try {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.LOOKUP_SEARCHING));
final CommandSender player2 = player;
final int finalX = x;
final int finalY = y;
final int finalZ = z;
final int finalWid = wid;
final int finalArgWid = argWid;
final int noisy = argNoisy;
final String rtime = ts;
final int excluded = argExcluded;
final int restricted = argRestricted;
// final List<String> uuid_list = arg_uuids;
final List<Object> blist = argBlocks;
final List<Object> elist = argExclude;
final List<String> euserlist = argExcludeUsers;
final int page = pa;
final int displayResults = re;
final int typeLookup = type;
final Location finalLocation = lo;
final List<Integer> finalArgAction = argAction;
final boolean finalCount = count;
class BasicThread2 implements Runnable {
@Override
public void run() {
try {
ConfigHandler.lookupThrottle.put(player2.getName(), new Object[] { true, System.currentTimeMillis() });
List<String> uuidList = new ArrayList<>();
Location location = finalLocation;
boolean exists = false;
String bc = finalX + "." + finalY + "." + finalZ + "." + finalWid + "." + stime + "." + noisy + "." + excluded + "." + restricted + "." + finalArgWid + "." + displayResults;
ConfigHandler.lookupCommand.put(player2.getName(), bc);
ConfigHandler.lookupPage.put(player2.getName(), page);
ConfigHandler.lookupTime.put(player2.getName(), rtime);
ConfigHandler.lookupType.put(player2.getName(), 5);
ConfigHandler.lookupElist.put(player2.getName(), elist);
ConfigHandler.lookupEUserlist.put(player2.getName(), euserlist);
ConfigHandler.lookupBlist.put(player2.getName(), blist);
ConfigHandler.lookupUlist.put(player2.getName(), rollbackusers2);
ConfigHandler.lookupAlist.put(player2.getName(), finalArgAction);
ConfigHandler.lookupRadius.put(player2.getName(), radius);
Connection connection = Database.getConnection(true);
if (connection != null) {
Statement statement = connection.createStatement();
String baduser = "";
for (String check : rollbackusers2) {
if ((!check.equals("#global") && !check.equals("#container")) || finalArgAction.contains(9)) {
exists = PlayerLookup.playerExists(connection, check);
if (!exists) {
baduser = check;
break;
}
else if (finalArgAction.contains(9)) {
if (ConfigHandler.uuidCache.get(check.toLowerCase(Locale.ROOT)) != null) {
String uuid = ConfigHandler.uuidCache.get(check.toLowerCase(Locale.ROOT));
uuidList.add(uuid);
}
}
}
else {
exists = true;
}
}
if (exists) {
for (String check : euserlist) {
if (!check.equals("#global")) {
exists = PlayerLookup.playerExists(connection, check);
if (!exists) {
baduser = check;
break;
}
}
else {
baduser = "#global";
exists = false;
}
}
}
if (exists) {
List<String> userList = new ArrayList<>();
if (!finalArgAction.contains(9)) {
userList = rollbackusers2;
}
int unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
boolean restrict_world = false;
if (radius != null) {
restrict_world = true;
}
if (location == null) {
restrict_world = false;
}
if (finalArgWid > 0) {
restrict_world = true;
location = new Location(Bukkit.getServer().getWorld(Util.getWorldName(finalArgWid)), finalX, finalY, finalZ);
}
else if (location != null) {
location = new Location(Bukkit.getServer().getWorld(Util.getWorldName(finalWid)), finalX, finalY, finalZ);
}
long rowMax = (long) page * displayResults;
long pageStart = rowMax - displayResults;
int rows = 0;
boolean checkRows = true;
if (typeLookup == 5 && page > 1) {
rows = ConfigHandler.lookupRows.get(player2.getName());
if (pageStart < rows) {
checkRows = false;
}
}
if (checkRows) {
rows = Lookup.countLookupRows(statement, player2, uuidList, userList, blist, elist, euserlist, finalArgAction, location, radius, stime, restrict_world, true);
ConfigHandler.lookupRows.put(player2.getName(), rows);
}
if (finalCount) {
String row_format = NumberFormat.getInstance().format(rows);
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.LOOKUP_ROWS_FOUND, row_format, (rows == 1 ? Selector.FIRST : Selector.SECOND)));
}
else if (pageStart < rows) {
List<String[]> lookupList = Lookup.performPartialLookup(statement, player2, uuidList, userList, blist, elist, euserlist, finalArgAction, location, radius, stime, (int) pageStart, displayResults, restrict_world, true);
Chat.sendMessage(player2, Color.WHITE + "----- " + Color.DARK_AQUA + Phrase.build(Phrase.LOOKUP_HEADER, "CoreProtect") + Color.WHITE + " -----");
if (finalArgAction.contains(6) || finalArgAction.contains(7)) { // Chat/command
for (String[] data : lookupList) {
String time = data[0];
String dplayer = data[1];
String message = data[2];
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
Chat.sendComponent(player2, timeago + " " + Color.WHITE + "- " + Color.DARK_AQUA + dplayer + ": " + Color.WHITE, message);
}
}
else if (finalArgAction.contains(8)) { // login/logouts
for (String[] data : lookupList) {
String time = data[0];
String dplayer = data[1];
int wid = Integer.parseInt(data[2]);
int x = Integer.parseInt(data[3]);
int y = Integer.parseInt(data[4]);
int z = Integer.parseInt(data[5]);
int action = Integer.parseInt(data[6]);
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
double time_length = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, false).replaceAll("[^0-9]", "").length() * 1.50;
int padding = (int) (time_length + 12.50);
String leftPadding = StringUtils.leftPad("", padding, ' ');
Chat.sendComponent(player2, timeago + " " + Color.WHITE + "- " + Color.DARK_AQUA + Phrase.build(Phrase.LOOKUP_LOGIN, Color.DARK_AQUA + dplayer + Color.WHITE, (action != 0 ? Selector.FIRST : Selector.SECOND)));
Chat.sendComponent(player2, Color.WHITE + leftPadding + Color.GREY + "^ " + Util.getCoordinates(command.getName(), wid, x, y, z, true, true) + "");
}
}
else if (finalArgAction.contains(9)) { // username-changes
for (String[] data : lookupList) {
String time = data[0];
String user = ConfigHandler.uuidCacheReversed.get(data[1]);
String username = data[2];
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
Chat.sendComponent(player2, timeago + " " + Color.WHITE + "- " + Phrase.build(Phrase.LOOKUP_USERNAME, Color.DARK_AQUA + user + Color.WHITE, Color.DARK_AQUA + username + Color.WHITE));
}
}
else if (finalArgAction.contains(10)) { // sign messages
for (String[] data : lookupList) {
String time = data[0];
String dplayer = data[1];
int wid = Integer.parseInt(data[2]);
int x = Integer.parseInt(data[3]);
int y = Integer.parseInt(data[4]);
int z = Integer.parseInt(data[5]);
String message = data[6];
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
double time_length = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, false).replaceAll("[^0-9]", "").length() * 1.50;
int padding = (int) (time_length + 12.50);
String leftPadding = StringUtils.leftPad("", padding, ' ');
Chat.sendComponent(player2, timeago + " " + Color.WHITE + "- " + Color.DARK_AQUA + dplayer + ": " + Color.WHITE, message);
Chat.sendComponent(player2, Color.WHITE + leftPadding + Color.GREY + "^ " + Util.getCoordinates(command.getName(), wid, x, y, z, true, true) + "");
}
}
else {
for (String[] data : lookupList) {
int drb = Integer.parseInt(data[8]);
String rbd = "";
if (drb == 1) {
rbd = Color.STRIKETHROUGH;
}
String time = data[0];
String dplayer = data[1];
int x = Integer.parseInt(data[2]);
int y = Integer.parseInt(data[3]);
int z = Integer.parseInt(data[4]);
String dtype = data[5];
int ddata = Integer.parseInt(data[6]);
int daction = Integer.parseInt(data[7]);
int wid = Integer.parseInt(data[9]);
int amount = Integer.parseInt(data[10]);
String tag = Color.WHITE + "-";
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
double timeLength = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, false).replaceAll("[^0-9]", "").length() * 1.50;
int padding = (int) (timeLength + 12.50);
String leftPadding = StringUtils.leftPad("", padding, ' ');
String dname = "";
boolean isPlayer = false;
if (daction == 3 && !finalArgAction.contains(11) && amount == -1) {
int dTypeInt = Integer.parseInt(dtype);
if (dTypeInt == 0) {
if (ConfigHandler.playerIdCacheReversed.get(ddata) == null) {
UserStatement.loadName(connection, ddata);
}
dname = ConfigHandler.playerIdCacheReversed.get(ddata);
isPlayer = true;
}
else {
dname = Util.getEntityType(dTypeInt).name();
}
}
else {
dname = Util.getType(Integer.parseInt(dtype)).name().toLowerCase(Locale.ROOT);
dname = Util.nameFilter(dname, ddata);
}
if (dname.length() > 0 && !isPlayer) {
dname = "minecraft:" + dname.toLowerCase(Locale.ROOT) + "";
}
// Hide "minecraft:" for now.
if (dname.contains("minecraft:")) {
String[] blockNameSplit = dname.split(":");
dname = blockNameSplit[1];
}
// Functions.sendMessage(player2, timeago+" " + ChatColors.WHITE + "- " + ChatColors.DARK_AQUA+rbd+""+dplayer+" " + ChatColors.WHITE+rbd+""+a+" " + ChatColors.DARK_AQUA+rbd+"#"+dtype+ChatColors.WHITE + ". " + ChatColors.GREY + "(x"+x+"/y"+y+"/z"+z+")");
Phrase phrase = Phrase.LOOKUP_BLOCK;
String selector = Selector.FIRST;
String action = "a:block";
if (finalArgAction.contains(4) || finalArgAction.contains(5) || finalArgAction.contains(11) || amount > -1) {
if (daction == 2 || daction == 3) {
phrase = Phrase.LOOKUP_ITEM; // {picked up|dropped}
selector = (daction != 2 ? Selector.FIRST : Selector.SECOND);
action = "a:inventory";
}
else if (daction == 4 || daction == 5) {
phrase = Phrase.LOOKUP_STORAGE; // {deposited|withdrew}
selector = (daction != 4 ? Selector.FIRST : Selector.SECOND);
action = "a:inventory";
}
else {
phrase = Phrase.LOOKUP_CONTAINER; // {added|removed}
selector = (daction != 0 ? Selector.FIRST : Selector.SECOND);
action = "a:container";
}
Chat.sendComponent(player2, timeago + " " + tag + " " + Phrase.build(phrase, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, "x" + amount, Color.DARK_AQUA + rbd + dname + Color.WHITE, selector));
}
else {
if (daction == 2 || daction == 3) {
phrase = Phrase.LOOKUP_INTERACTION; // {clicked|killed}
selector = (daction != 3 ? Selector.FIRST : Selector.SECOND);
action = (daction == 2 ? "a:click" : "a:kill");
}
else {
phrase = Phrase.LOOKUP_BLOCK; // {placed|broke}
selector = (daction != 0 ? Selector.FIRST : Selector.SECOND);
}
// tag = ChatColors.RED + "-";
Chat.sendComponent(player2, timeago + " " + tag + " " + Phrase.build(phrase, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, Color.DARK_AQUA + rbd + dname + Color.WHITE, selector));
}
boolean itemLookup = finalArgAction.contains(4) && finalArgAction.contains(11);
action = (finalArgAction.size() == 0 || itemLookup ? " (" + action + ")" : "");
Chat.sendComponent(player2, Color.WHITE + leftPadding + Color.GREY + "^ " + Util.getCoordinates(command.getName(), wid, x, y, z, true, true) + Color.GREY + Color.ITALIC + action);
}
}
if (rows > displayResults) {
int total_pages = (int) Math.ceil(rows / (displayResults + 0.0));
if (finalArgAction.contains(6) || finalArgAction.contains(7) || finalArgAction.contains(9)) {
Chat.sendMessage(player2, "-----");
}
Chat.sendComponent(player2, Util.getPageNavigation(command.getName(), page, total_pages) + "| " + Phrase.build(Phrase.LOOKUP_VIEW_PAGE, Color.WHITE, "/co l <page>"));
}
}
else if (rows > 0) {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_RESULTS_PAGE, Selector.FIRST));
}
else {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_RESULTS));
}
}
else {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.USER_NOT_FOUND, baduser));
}
statement.close();
connection.close();
}
else {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
}
}
catch (Exception e) {
e.printStackTrace();
}
ConfigHandler.lookupThrottle.put(player2.getName(), new Object[] { false, System.currentTimeMillis() });
}
}
Runnable runnable = new BasicThread2();
Thread thread = new Thread(runnable);
thread.start();
}
catch (Exception e) {
e.printStackTrace();
}
}
else {
// Functions.sendMessage(player, ChatColors.RED + "You did not specify a lookup radius.");
if (argUsers.size() == 0 && argBlocks.size() == 0 && (argWid > 0 || forceglobal)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_LOOKUP_USER, Selector.FIRST));
return;
}
else if (argUsers.size() == 0 && argBlocks.size() == 0 && argRadius == null) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_LOOKUP_USER, Selector.SECOND));
return;
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_PARAMETERS, "/co l <params>"));
}
}
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_PARAMETERS, "/co l <params>"));
}
}
}

View File

@ -0,0 +1,384 @@
package net.coreprotect.command;
import java.io.File;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.database.Database;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.patch.Patch;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.ChatMessage;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class PurgeCommand extends Consumer {
protected static void runCommand(final CommandSender player, boolean permission, String[] args) {
int resultc = args.length;
Location location = CommandHandler.parseLocation(player, args);
final Integer[] argRadius = CommandHandler.parseRadius(args, player, location);
final int seconds = CommandHandler.parseTime(args);
final int argWid = CommandHandler.parseWorld(args, false, false);
final List<Integer> argAction = CommandHandler.parseAction(args);
final List<Integer> supportedActions = Arrays.asList();
if (ConfigHandler.converterRunning) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
return;
}
if (ConfigHandler.purgeRunning) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
return;
}
if (!permission) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
if (resultc <= 1) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_PARAMETERS, "/co purge t:<time>"));
return;
}
if (seconds <= 0) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_PARAMETERS, "/co purge t:<time>"));
return;
}
if (argRadius != null) {
Chat.sendMessage(player, new ChatMessage(Phrase.build(Phrase.INVALID_WORLD)).build());
return;
}
if (argWid == -1) {
String worldName = CommandHandler.parseWorldName(args, false);
Chat.sendMessage(player, new ChatMessage(Phrase.build(Phrase.WORLD_NOT_FOUND, worldName)).build());
return;
}
for (int action : argAction) {
if (!supportedActions.contains(action)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ACTION_NOT_SUPPORTED));
// Functions.sendMessage(player, new ChatMessage("Please specify a valid purge action.").build());
return;
}
}
if (player instanceof Player && seconds < 2592000) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_MINIMUM_TIME, "30", Selector.FIRST)); // 30 days
return;
}
else if (seconds < 86400) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_MINIMUM_TIME, "24", Selector.SECOND)); // 24 hours
return;
}
boolean optimizeCheck = false;
for (String arg : args) {
if (arg.trim().equalsIgnoreCase("#optimize")) {
optimizeCheck = true;
break;
}
}
final boolean optimize = optimizeCheck;
class BasicThread implements Runnable {
@Override
public void run() {
try {
int timestamp = (int) (System.currentTimeMillis() / 1000L);
int ptime = timestamp - seconds;
long removed = 0;
Connection connection = null;
for (int i = 0; i <= 5; i++) {
connection = Database.getConnection(false, 500);
if (connection != null) {
break;
}
Thread.sleep(1000);
}
if (connection == null) {
Chat.sendGlobalMessage(player, Phrase.build(Phrase.DATABASE_BUSY));
return;
}
if (argWid > 0) {
String worldName = CommandHandler.parseWorldName(args, false);
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_STARTED, worldName));
}
else {
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_STARTED, "#global"));
}
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_NOTICE_1));
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_NOTICE_2));
ConfigHandler.purgeRunning = true;
while (!Consumer.pausedSuccess) {
Thread.sleep(1);
}
Consumer.isPaused = true;
String query = "";
PreparedStatement preparedStmt = null;
boolean abort = false;
String purgePrefix = "tmp_" + ConfigHandler.prefix;
if (!Config.getGlobal().MYSQL) {
query = "ATTACH DATABASE '" + ConfigHandler.path + ConfigHandler.sqlite + ".tmp' AS tmp_db";
preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
preparedStmt.close();
purgePrefix = "tmp_db." + ConfigHandler.prefix;
}
Integer[] lastVersion = Patch.getDatabaseVersion(connection, true);
boolean newVersion = Util.newVersion(lastVersion, Util.getInternalPluginVersion());
if (newVersion && !ConfigHandler.EDITION_BRANCH.contains("-dev")) {
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_FAILED));
Consumer.isPaused = false;
ConfigHandler.purgeRunning = false;
return;
}
if (!Config.getGlobal().MYSQL) {
for (String table : ConfigHandler.databaseTables) {
try {
query = "DROP TABLE IF EXISTS " + purgePrefix + table + "";
preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
preparedStmt.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
Database.createDatabaseTables(purgePrefix, true);
}
List<String> purgeTables = Arrays.asList("sign", "container", "item", "skull", "session", "chat", "command", "entity", "block");
List<String> worldTables = Arrays.asList("sign", "container", "item", "session", "chat", "command", "block");
List<String> excludeTables = Arrays.asList("database_lock"); // don't insert data into these tables
for (String table : ConfigHandler.databaseTables) {
String tableName = table.replaceAll("_", " ");
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_PROCESSING, tableName));
if (!Config.getGlobal().MYSQL) {
String columns = "";
ResultSet rs = connection.createStatement().executeQuery("SELECT * FROM " + purgePrefix + table);
ResultSetMetaData resultSetMetaData = rs.getMetaData();
int columnCount = resultSetMetaData.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
String name = resultSetMetaData.getColumnName(i);
if (columns.length() == 0) {
columns = name;
}
else {
columns = columns + "," + name;
}
}
rs.close();
boolean error = false;
if (!excludeTables.contains(table)) {
try {
String timeLimit = "";
if (purgeTables.contains(table)) {
if (argWid > 0 && worldTables.contains(table)) {
timeLimit = " WHERE (wid = '" + argWid + "' AND time >= '" + ptime + "') OR wid != '" + argWid + "'";
}
else if (argWid == 0) {
timeLimit = " WHERE time >= '" + ptime + "'";
}
}
query = "INSERT INTO " + purgePrefix + table + " SELECT " + columns + " FROM " + ConfigHandler.prefix + table + timeLimit;
preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
preparedStmt.close();
}
catch (Exception e) {
error = true;
e.printStackTrace();
}
}
if (error) {
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_ERROR, tableName));
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_REPAIRING));
try {
query = "DELETE FROM " + purgePrefix + table;
preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
preparedStmt.close();
}
catch (Exception e) {
e.printStackTrace();
}
try {
query = "REINDEX " + ConfigHandler.prefix + table;
preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
preparedStmt.close();
}
catch (Exception e) {
e.printStackTrace();
}
try {
String index = " NOT INDEXED";
query = "INSERT INTO " + purgePrefix + table + " SELECT " + columns + " FROM " + ConfigHandler.prefix + table + index;
preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
preparedStmt.close();
}
catch (Exception e) {
e.printStackTrace();
abort = true;
break;
}
try {
boolean purge = purgeTables.contains(table);
String worldRestriction = "";
if (argWid > 0 && worldTables.contains(table)) {
worldRestriction = " AND wid = '" + argWid + "'";
}
else if (argWid > 0) {
purge = false;
}
if (purge) {
query = "DELETE FROM " + purgePrefix + table + " WHERE time < '" + ptime + "'" + worldRestriction;
preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
preparedStmt.close();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
if (purgeTables.contains(table)) {
int oldCount = 0;
try {
query = "SELECT COUNT(*) as count FROM " + ConfigHandler.prefix + table + " LIMIT 0, 1";
preparedStmt = connection.prepareStatement(query);
ResultSet resultSet = preparedStmt.executeQuery();
while (resultSet.next()) {
oldCount = resultSet.getInt("count");
}
resultSet.close();
preparedStmt.close();
}
catch (Exception e) {
e.printStackTrace();
}
int new_count = 0;
try {
query = "SELECT COUNT(*) as count FROM " + purgePrefix + table + " LIMIT 0, 1";
preparedStmt = connection.prepareStatement(query);
ResultSet resultSet = preparedStmt.executeQuery();
while (resultSet.next()) {
new_count = resultSet.getInt("count");
}
resultSet.close();
preparedStmt.close();
}
catch (Exception e) {
e.printStackTrace();
}
removed = removed + (oldCount - new_count);
}
}
if (Config.getGlobal().MYSQL) {
try {
boolean purge = purgeTables.contains(table);
String worldRestriction = "";
if (argWid > 0 && worldTables.contains(table)) {
worldRestriction = " AND wid = '" + argWid + "'";
}
else if (argWid > 0) {
purge = false;
}
if (purge) {
query = "DELETE FROM " + ConfigHandler.prefix + table + " WHERE time < '" + ptime + "'" + worldRestriction;
preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
removed = removed + preparedStmt.getUpdateCount();
preparedStmt.close();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
if (Config.getGlobal().MYSQL && optimize) {
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_OPTIMIZING));
for (String table : ConfigHandler.databaseTables) {
query = "OPTIMIZE LOCAL TABLE " + ConfigHandler.prefix + table + "";
preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
preparedStmt.close();
}
}
connection.close();
if (abort) {
if (!Config.getGlobal().MYSQL) {
(new File(ConfigHandler.path + ConfigHandler.sqlite + ".tmp")).delete();
}
ConfigHandler.loadDatabase();
Chat.sendGlobalMessage(player, Color.RED + Phrase.build(Phrase.PURGE_ABORTED));
Consumer.isPaused = false;
ConfigHandler.purgeRunning = false;
return;
}
if (!Config.getGlobal().MYSQL) {
(new File(ConfigHandler.path + ConfigHandler.sqlite)).delete();
(new File(ConfigHandler.path + ConfigHandler.sqlite + ".tmp")).renameTo(new File(ConfigHandler.path + ConfigHandler.sqlite));
}
ConfigHandler.loadDatabase();
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_SUCCESS));
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_ROWS, NumberFormat.getInstance().format(removed), (removed == 1 ? Selector.FIRST : Selector.SECOND)));
}
catch (Exception e) {
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_FAILED));
e.printStackTrace();
}
Consumer.isPaused = false;
ConfigHandler.purgeRunning = false;
}
}
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
}
}

View File

@ -0,0 +1,66 @@
package net.coreprotect.command;
import org.bukkit.command.CommandSender;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.language.Phrase;
import net.coreprotect.thread.NetworkHandler;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
public class ReloadCommand {
protected static void runCommand(final CommandSender player, boolean permission, String[] args) {
if (permission) {
if (ConfigHandler.converterRunning) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
return;
}
if (ConfigHandler.purgeRunning) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
return;
}
if (ConfigHandler.lookupThrottle.get(player.getName()) != null) {
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(player.getName());
if ((boolean) lookupThrottle[0] || ((System.currentTimeMillis() - (long) lookupThrottle[1])) < 100) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
return;
}
}
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { true, System.currentTimeMillis() });
class BasicThread implements Runnable {
@Override
public void run() {
try {
if (Consumer.isPaused) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.RELOAD_STARTED));
}
while (Consumer.isPaused) {
Thread.sleep(1);
}
Consumer.isPaused = true;
ConfigHandler.performInitialization(false);
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.RELOAD_SUCCESS));
Thread networkHandler = new Thread(new NetworkHandler(false, false));
networkHandler.start();
}
catch (Exception e) {
e.printStackTrace();
}
Consumer.isPaused = false;
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { false, System.currentTimeMillis() });
}
}
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
}
}
}

View File

@ -0,0 +1,455 @@
package net.coreprotect.command;
import java.sql.Connection;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Chest;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.ContainerRollback;
import net.coreprotect.database.Database;
import net.coreprotect.database.Rollback;
import net.coreprotect.database.lookup.PlayerLookup;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class RollbackRestoreCommand {
protected static void runCommand(CommandSender player, Command command, boolean permission, String[] args, Location argLocation, int forceSeconds) {
Location lo = (argLocation != null ? argLocation : CommandHandler.parseLocation(player, args));
List<String> argUuids = new ArrayList<>();
List<String> argUsers = CommandHandler.parseUsers(args);
Integer[] argRadius = CommandHandler.parseRadius(args, player, lo);
int argNoisy = CommandHandler.parseNoisy(args);
List<Integer> argAction = CommandHandler.parseAction(args);
List<Object> argBlocks = CommandHandler.parseRestricted(player, args, argAction);
List<Object> argExclude = CommandHandler.parseExcluded(player, args, argAction);
List<String> argExcludeUsers = CommandHandler.parseExcludedUsers(player, args);
String ts = CommandHandler.parseTimeString(args);
int rbSeconds = CommandHandler.parseTime(args);
int argWid = CommandHandler.parseWorld(args, true, true);
boolean count = CommandHandler.parseCount(args);
boolean worldedit = CommandHandler.parseWorldEdit(args);
boolean forceglobal = CommandHandler.parseForceGlobal(args);
int preview = CommandHandler.parsePreview(args);
String corecommand = args[0].toLowerCase(Locale.ROOT);
if (argBlocks == null || argExclude == null || argExcludeUsers == null) {
return;
}
/* check for invalid block/entity combinations (include) */
boolean hasBlock = false;
boolean hasEntity = false;
for (Object arg : argBlocks) {
if (arg instanceof Material) {
hasBlock = true;
}
else if (arg instanceof EntityType) {
hasEntity = true;
if (argAction.size() == 0) {
argAction.add(3);
}
else if (!argAction.contains(3)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_INCLUDE_COMBO));
return;
}
}
}
/* check for invalid block/entity combinations (exclude) */
for (Object arg : argExclude) {
if (arg instanceof Material) {
hasBlock = true;
}
else if (arg instanceof EntityType) {
hasEntity = true;
if (argAction.size() == 0) {
argAction.add(3);
}
else if (!argAction.contains(3)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_INCLUDE_COMBO));
return;
}
}
}
if (hasBlock && hasEntity) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_INCLUDE_COMBO));
return;
}
if (count) {
LookupCommand.runCommand(player, command, permission, args);
return;
}
if (ConfigHandler.converterRunning) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
return;
}
if (ConfigHandler.purgeRunning) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
return;
}
if (argWid == -1) {
String worldName = CommandHandler.parseWorldName(args, true);
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.WORLD_NOT_FOUND, worldName));
return;
}
if (preview > 0 && (!(player instanceof Player))) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PREVIEW_IN_GAME));
return;
}
if (argAction.contains(-1)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_ACTION));
return;
}
if (worldedit && argRadius == null) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_SELECTION, "WorldEdit"));
return;
}
if (argRadius != null && argRadius[0] == -1) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_RADIUS));
return;
}
if (ConfigHandler.activeRollbacks.get(player.getName()) != null) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_IN_PROGRESS));
return;
}
if (ConfigHandler.lookupThrottle.get(player.getName()) != null) {
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(player.getName());
if ((boolean) lookupThrottle[0] || ((System.currentTimeMillis() - (long) lookupThrottle[1])) < 100) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
return;
}
}
if (preview > 1 && forceSeconds <= 0) {
preview = 1;
}
if (permission) {
int a = 0;
if (corecommand.equals("restore") || corecommand.equals("rs") || corecommand.equals("re")) {
a = 1;
}
final int finalAction = a;
int DEFAULT_RADIUS = Config.getGlobal().DEFAULT_RADIUS;
if ((player instanceof Player || player instanceof BlockCommandSender) && argRadius == null && DEFAULT_RADIUS > 0 && !forceglobal) {
Location location = lo;
int xmin = location.getBlockX() - DEFAULT_RADIUS;
int xmax = location.getBlockX() + DEFAULT_RADIUS;
int zmin = location.getBlockZ() - DEFAULT_RADIUS;
int zmax = location.getBlockZ() + DEFAULT_RADIUS;
argRadius = new Integer[] { DEFAULT_RADIUS, xmin, xmax, -1, -1, zmin, zmax, 0 };
}
// if (arg_radius==-2)arg_radius = -1;
int g = 1;
if (argUsers.contains("#global")) {
if (argRadius == null) {
g = 0;
}
}
if (argUsers.size() == 0 && (argWid > 0 || forceglobal) && argRadius == null) {
if (finalAction == 0) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_ROLLBACK_USER, Selector.FIRST));
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_ROLLBACK_USER, Selector.SECOND));
}
return;
}
if (g == 1 && (argUsers.size() > 0 || (argUsers.size() == 0 && argRadius != null))) {
Integer MAX_RADIUS = Config.getGlobal().MAX_RADIUS;
if (argRadius != null) {
int radiusValue = argRadius[0];
if (radiusValue > MAX_RADIUS && MAX_RADIUS > 0) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MAXIMUM_RADIUS, MAX_RADIUS.toString(), (finalAction == 0 ? Selector.SECOND : Selector.THIRD)));
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.GLOBAL_ROLLBACK, "r:#global", (finalAction == 0 ? Selector.FIRST : Selector.SECOND)));
return;
}
}
if (argAction.size() > 0) {
if (argAction.contains(4)) {
if (argUsers.contains("#global") || (argUsers.size() == 0 && argRadius == null)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_ACTION_USER));
return;
}
else if (preview > 0) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PREVIEW_CONTAINER));
return;
}
}
if (argAction.contains(8) || argAction.contains(11) || (!argAction.contains(0) && !argAction.contains(1) && !argAction.contains(3) && !argAction.contains(4))) {
if (finalAction == 0) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ACTION_NOT_SUPPORTED));
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ACTION_NOT_SUPPORTED));
}
return;
}
}
if (argUsers.size() == 0) {
argUsers.add("#global");
}
List<String> rollbackusers = argUsers;
int c = 0;
for (String ruser : rollbackusers) {
List<Player> players = Bukkit.getServer().matchPlayer(ruser);
for (Player p : players) {
if (p.getName().equalsIgnoreCase(ruser)) {
rollbackusers.set(c, p.getName());
}
}
c++;
}
int wid = 0;
int x = 0;
int y = 0;
int z = 0;
if (rollbackusers.contains("#container")) {
boolean valid = false;
if (ConfigHandler.lookupType.get(player.getName()) != null) {
int lookupType = ConfigHandler.lookupType.get(player.getName());
if (lookupType == 1) {
valid = true;
}
else if (lookupType == 5) {
if (ConfigHandler.lookupUlist.get(player.getName()).contains("#container")) {
valid = true;
}
}
}
if (valid) {
if (preview > 0) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PREVIEW_CONTAINER));
return;
}
else {
String lcommand = ConfigHandler.lookupCommand.get(player.getName());
String[] data = lcommand.split("\\.");
x = Integer.parseInt(data[0]);
y = Integer.parseInt(data[1]);
z = Integer.parseInt(data[2]);
wid = Integer.parseInt(data[3]);
argAction.add(5);
argRadius = null;
argWid = 0;
lo = new Location(Bukkit.getServer().getWorld(Util.getWorldName(wid)), x, y, z);
Block block = lo.getBlock();
if (block.getState() instanceof Chest) {
BlockFace[] blockFaces = new BlockFace[] { BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST };
for (BlockFace face : blockFaces) {
if (block.getRelative(face, 1).getState() instanceof Chest) {
Block relative = block.getRelative(face, 1);
int x2 = relative.getX();
int z2 = relative.getZ();
double newX = (x + x2) / 2.0;
double newZ = (z + z2) / 2.0;
lo.setX(newX);
lo.setZ(newZ);
break;
}
}
}
}
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_CONTAINER));
return;
}
}
final List<String> rollbackusers2 = rollbackusers;
if (rbSeconds > 0) {
int unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
int seconds = unixtimestamp - rbSeconds;
if (forceSeconds > 0) {
seconds = forceSeconds;
}
final int stime = seconds;
final Integer[] radius = argRadius;
try {
final CommandSender player2 = player;
final int noisy = argNoisy;
final String rtime = ts;
final List<String> uuidList = argUuids;
final List<Object> blist = argBlocks;
final List<Object> elist = argExclude;
final List<String> euserlist = argExcludeUsers;
final Location locationFinal = lo;
final int finalArgWid = argWid;
final List<Integer> finalArgAction = argAction;
final String[] finalArgs = args;
final int finalPreview = preview;
ConfigHandler.activeRollbacks.put(player.getName(), true);
class BasicThread2 implements Runnable {
@Override
public void run() {
try {
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { true, System.currentTimeMillis() });
int action = finalAction;
Location location = locationFinal;
Connection connection = Database.getConnection(false, 1000);
if (connection != null) {
Statement statement = connection.createStatement();
String baduser = "";
boolean exists = false;
for (String check : rollbackusers2) {
if (!check.equals("#global") && !check.equals("#container")) {
exists = PlayerLookup.playerExists(connection, check);
if (!exists) {
baduser = check;
break;
}
}
else {
exists = true;
}
}
if (exists) {
for (String check : euserlist) {
if (!check.equals("#global")) {
exists = PlayerLookup.playerExists(connection, check);
if (!exists) {
baduser = check;
break;
}
}
else {
baduser = "#global";
exists = false;
}
}
}
if (exists) {
boolean restrictWorld = false;
if (radius != null) {
restrictWorld = true;
}
if (location == null) {
restrictWorld = false;
}
if (finalArgWid > 0) {
restrictWorld = true;
location = new Location(Bukkit.getServer().getWorld(Util.getWorldName(finalArgWid)), 0, 0, 0);
}
boolean verbose = false;
if (noisy == 1) {
verbose = true;
}
String users = "";
for (String value : rollbackusers2) {
if (users.length() == 0) {
users = "" + value + "";
}
else {
users = users + ", " + value;
}
}
if (users.equals("#global") && restrictWorld) {
// chat output only, don't pass into any functions
users = "#" + location.getWorld().getName();
}
if (finalPreview == 2) {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PREVIEW_CANCELLING));
}
else if (finalPreview == 1) {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_STARTED, users, Selector.THIRD));
}
else if (action == 0) {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_STARTED, users, Selector.FIRST));
}
else {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_STARTED, users, Selector.SECOND));
}
if (finalArgAction.contains(5)) {
ContainerRollback.performContainerRollbackRestore(statement, player2, uuidList, rollbackusers2, rtime, blist, elist, euserlist, finalArgAction, location, radius, stime, restrictWorld, false, verbose, action);
}
else {
Rollback.performRollbackRestore(statement, player2, uuidList, rollbackusers2, rtime, blist, elist, euserlist, finalArgAction, location, radius, stime, restrictWorld, false, verbose, action, finalPreview);
if (finalPreview < 2) {
List<Object> list = new ArrayList<>();
list.add(stime);
list.add(finalArgs);
list.add(locationFinal);
ConfigHandler.lastRollback.put(player2.getName(), list);
}
}
}
else {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.USER_NOT_FOUND, baduser));
}
statement.close();
connection.close();
}
else {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
}
}
catch (Exception e) {
e.printStackTrace();
}
if (ConfigHandler.activeRollbacks.get(player2.getName()) != null) {
ConfigHandler.activeRollbacks.remove(player2.getName());
}
ConfigHandler.lookupThrottle.put(player2.getName(), new Object[] { false, System.currentTimeMillis() });
}
}
Runnable runnable = new BasicThread2();
Thread thread = new Thread(runnable);
thread.start();
}
catch (Exception e) {
e.printStackTrace();
}
}
else {
if (finalAction == 0) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_LOOKUP_TIME, Selector.SECOND));
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_LOOKUP_TIME, Selector.THIRD));
}
}
}
else {
if (finalAction == 0) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_ROLLBACK_RADIUS, Selector.FIRST)); // rollback
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_ROLLBACK_RADIUS, Selector.SECOND)); // restore
}
}
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
}
}
}

View File

@ -0,0 +1,133 @@
package net.coreprotect.command;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginDescriptionFile;
import net.coreprotect.CoreProtect;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.consumer.process.Process;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.patch.Patch;
import net.coreprotect.thread.NetworkHandler;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
public class StatusCommand {
private static ConcurrentHashMap<String, Boolean> alert = new ConcurrentHashMap<>();
protected static void runCommand(CommandSender player, boolean permission, String[] args) {
if (!permission) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
class BasicThread implements Runnable {
@Override
public void run() {
try {
CoreProtect instance = CoreProtect.getInstance();
PluginDescriptionFile pdfFile = instance.getDescription();
String versionCheck = "";
if (Config.getGlobal().CHECK_UPDATES) {
String latestVersion = NetworkHandler.latestVersion();
if (latestVersion != null) {
versionCheck = " (" + Phrase.build(Phrase.LATEST_VERSION, "v" + latestVersion) + ")";
}
}
Chat.sendMessage(player, Color.WHITE + "----- " + Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "-----");
Chat.sendMessage(player, Color.DARK_AQUA + Phrase.build(Phrase.STATUS_VERSION, Color.WHITE, ConfigHandler.EDITION_NAME + " v" + pdfFile.getVersion() + ".") + versionCheck);
String donationKey = NetworkHandler.donationKey();
if (donationKey != null) {
Chat.sendMessage(player, Color.DARK_AQUA + Phrase.build(Phrase.STATUS_LICENSE, Color.WHITE, Phrase.build(Phrase.VALID_DONATION_KEY)) + " (" + donationKey + ")");
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + Phrase.build(Phrase.STATUS_LICENSE, Color.WHITE, Phrase.build(Phrase.INVALID_DONATION_KEY)) + Color.GREY + Color.ITALIC + " (" + Phrase.build(Phrase.CHECK_CONFIG) + ")");
}
/*
CoreProtect show RAM usage
Items processed (since server start)
Items processed (last 60 minutes)
*/
// Using MySQL/SQLite (Database Size: 587MB)
String firstVersion = Patch.getFirstVersion();
if (firstVersion.length() > 0) {
firstVersion = " (" + Phrase.build(Phrase.FIRST_VERSION, firstVersion) + ")";
}
if (Config.getGlobal().MYSQL) {
Chat.sendMessage(player, Color.DARK_AQUA + Phrase.build(Phrase.STATUS_DATABASE, Color.WHITE, "MySQL") + firstVersion);
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + Phrase.build(Phrase.STATUS_DATABASE, Color.WHITE, "SQLite") + firstVersion);
}
if (ConfigHandler.worldeditEnabled) {
Chat.sendMessage(player, Color.DARK_AQUA + Phrase.build(Phrase.STATUS_INTEGRATION, Color.WHITE, "WorldEdit", Selector.FIRST));
}
else if (instance.getServer().getPluginManager().getPlugin("WorldEdit") != null) {
Chat.sendMessage(player, Color.DARK_AQUA + Phrase.build(Phrase.STATUS_INTEGRATION, Color.WHITE, "WorldEdit", Selector.SECOND));
}
try {
int consumerCount = 0;
int currentConsumerSize = Process.getCurrentConsumerSize();
if (currentConsumerSize == 0) {
consumerCount = Consumer.getConsumerSize(0) + Consumer.getConsumerSize(1);
}
else {
int consumerId = (Consumer.currentConsumer == 1) ? 1 : 0;
consumerCount = Consumer.getConsumerSize(consumerId) + currentConsumerSize;
}
if (consumerCount >= 1 && (player instanceof Player)) {
if (Config.getConfig(((Player) player).getWorld()).PLAYER_COMMANDS) {
consumerCount = consumerCount - 1;
}
}
Chat.sendMessage(player, Color.DARK_AQUA + Phrase.build(Phrase.STATUS_CONSUMER, Color.WHITE, String.format("%,d", consumerCount), (consumerCount == 1 ? Selector.FIRST : Selector.SECOND)));
}
catch (Exception e) {
e.printStackTrace();
}
// Functions.sendMessage(player, Color.DARK_AQUA + "Website: " + Color.WHITE + "www.coreprotect.net/updates/");
// Functions.sendMessage(player, Color.DARK_AQUA + Phrase.build(Phrase.LINK_DISCORD, Color.WHITE + "www.coreprotect.net/discord/").replaceFirst(":", ":" + Color.WHITE));
Chat.sendMessage(player, Color.DARK_AQUA + Phrase.build(Phrase.LINK_DISCORD, Color.WHITE, "www.coreprotect.net/discord/"));
Chat.sendMessage(player, Color.DARK_AQUA + Phrase.build(Phrase.LINK_PATREON, Color.WHITE, "www.patreon.com/coreprotect/"));
if (player.isOp() && alert.get(player.getName()) == null) {
alert.put(player.getName(), true);
if (instance.getServer().getPluginManager().getPlugin("CoreEdit") == null) {
Thread.sleep(500);
/*
Functions.sendMessage(player, Color.WHITE + "----- " + Color.DARK_AQUA + "Recommended Plugin " + Color.WHITE + "-----");
Functions.sendMessage(player, Color.DARK_AQUA + "Notice: " + Color.WHITE + "Enjoy CoreProtect? Check out CoreEdit!");
Functions.sendMessage(player, Color.DARK_AQUA + "Download: " + Color.WHITE + "www.coreedit.net/download/");
*/
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
}
}

View File

@ -0,0 +1,407 @@
package net.coreprotect.command;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import net.coreprotect.config.ConfigHandler;
public class TabHandler implements TabCompleter {
// private static String[] COMMANDS = new String[] { "help", "inspect", "rollback", "restore", "lookup", "purge", "reload", "status", "near", "undo" }; // max 10!
private static String[] HELP = new String[] { "inspect", "rollback", "restore", "lookup", "purge", "teleport", "status", "params", "users", "time", "radius", "action", "include", "exclude" };
private static String[] PARAMS = new String[] { "user:", "time:", "radius:", "action:", "include:", "exclude:", "#container" };
private static String[] ACTIONS = new String[] { "block", "+block", "-block", "click", "kill", "container", "chat", "command", "+inventory", "-inventory", "inventory", "item", "+item", "-item", "sign", "session", "+session", "-session", "username" };
private static String[] NUMBERS = new String[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
private static String[] TIMES = new String[] { "w", "d", "h", "m", "s" };
private static ArrayList<String> materials = null;
@Override
public List<String> onTabComplete(CommandSender sender, Command cmd, String label, String[] args) {
if (!(sender instanceof Player) || args.length == 0) {
return null;
}
if (args.length == 1) {
String argument = args[0].toLowerCase(Locale.ROOT);
List<String> completions = new ArrayList<>();
if (sender.hasPermission("coreprotect.help")) {
completions.add("help");
}
if (sender.hasPermission("coreprotect.inspect")) {
completions.add("inspect");
}
if (sender.hasPermission("coreprotect.rollback")) {
completions.add("rollback");
}
if (sender.hasPermission("coreprotect.restore")) {
completions.add("restore");
}
if (sender.hasPermission("coreprotect.lookup")) {
completions.add("lookup");
}
if (sender.hasPermission("coreprotect.purge")) {
completions.add("purge");
}
if (sender.hasPermission("coreprotect.reload")) {
completions.add("reload");
}
if (sender.hasPermission("coreprotect.status")) {
completions.add("status");
}
if (sender.hasPermission("coreprotect.lookup.near")) {
completions.add("near");
}
if (sender.hasPermission("coreprotect.restore")) {
completions.add("undo");
}
return StringUtil.copyPartialMatches(argument, completions, new ArrayList<>(completions.size()));
}
else if (args.length > 1) {
String argument0 = args[0].toLowerCase(Locale.ROOT);
String argument1 = args[1].toLowerCase(Locale.ROOT);
String currentArg = args[args.length - 1].toLowerCase(Locale.ROOT).trim();
String lastArg = args[args.length - 2].toLowerCase(Locale.ROOT).trim();
boolean hasUser = false;
boolean hasAction = false;
boolean hasInclude = false;
boolean hasExclude = false;
boolean hasRadius = false;
boolean hasTime = false;
boolean hasContainer = false;
boolean hasCount = false;
boolean hasPreview = false;
boolean hasPage = false;
boolean validContainer = false;
boolean pageLookup = false;
if (ConfigHandler.lookupType.get(sender.getName()) != null && ConfigHandler.lookupPage.get(sender.getName()) != null) {
pageLookup = true;
}
for (int i = 1; i < args.length; i++) {
String arg = args[i].toLowerCase(Locale.ROOT);
if (arg.equals("#container")) {
hasContainer = true;
}
else if (arg.equals("#count") || arg.equals("#sum")) {
hasCount = true;
}
else if (arg.equals("#preview")) {
hasPreview = true;
}
else if ((!arg.contains(":") && !args[i - 1].contains(":") && args.length > (i + 1)) || arg.contains("u:") || arg.contains("user:") || arg.contains("users:") || arg.contains("p:")) {
hasUser = true;
}
else if (arg.contains("page:")) {
hasPage = true;
}
else if (arg.contains("a:") || arg.contains("action:")) {
hasAction = true;
}
else if (arg.contains("i:") || arg.contains("include:") || arg.contains("item:") || arg.contains("items:") || arg.contains("b:") || arg.contains("block:") || arg.contains("blocks:")) {
hasInclude = true;
}
else if (arg.contains("t:") || arg.contains("time:")) {
hasTime = true;
}
else if (arg.contains("e:") || arg.contains("exclude:")) {
hasExclude = true;
}
else if (arg.contains("r:") || arg.contains("radius:")) {
hasRadius = true;
}
}
if (!hasContainer) {
if (ConfigHandler.lookupType.get(sender.getName()) != null) {
int lookupType = ConfigHandler.lookupType.get(sender.getName());
if (lookupType == 1) {
validContainer = true;
}
else if (lookupType == 5) {
if (ConfigHandler.lookupUlist.get(sender.getName()).contains("#container")) {
validContainer = true;
}
}
}
}
if (lastArg.equals("a:") || lastArg.equals("action:")) {
List<String> completions = new ArrayList<>(Arrays.asList(ACTIONS));
return StringUtil.copyPartialMatches(currentArg, completions, new ArrayList<>(completions.size()));
}
else if (currentArg.startsWith("a:") || currentArg.startsWith("action:")) {
String arg = "";
String[] split = currentArg.split(":", 2);
String filter = split[0] + ":";
if (split.length > 1) {
arg = split[1];
}
List<String> completions = new ArrayList<>(Arrays.asList(ACTIONS));
for (int index = 0; index < completions.size(); index++) {
completions.set(index, filter + completions.get(index));
}
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
}
else if (lastArg.equals("u:") || lastArg.equals("user:") || lastArg.equals("users:") || lastArg.equals("p:")) {
return null;
}
else if (currentArg.startsWith("u:") || currentArg.startsWith("user:") || currentArg.startsWith("users:") || currentArg.startsWith("p:")) {
String arg = "";
String[] split = currentArg.split(":", 2);
String filter = split[0] + ":";
if (split.length > 1) {
arg = split[1];
}
List<String> completions = Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList());
for (int index = 0; index < completions.size(); index++) {
completions.set(index, filter + completions.get(index));
}
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
}
else if (lastArg.equals("t:") || lastArg.equals("time:") || currentArg.startsWith("t:") || currentArg.startsWith("time:")) {
String filter = lastArg;
String arg = "";
if (currentArg.contains(":")) {
String[] split = currentArg.split(":", 2);
filter = split[0] + ":";
if (split.length > 1) {
arg = split[1];
}
}
else {
filter = "";
arg = currentArg;
}
List<String> completions = new ArrayList<>();
if (arg.chars().allMatch(Character::isDigit)) {
boolean addNumbers = true;
if (currentArg.length() > 0) {
char lastChar = currentArg.charAt(currentArg.length() - 1);
if (Character.isDigit(lastChar)) {
completions.addAll(Arrays.asList(TIMES));
addNumbers = false;
}
}
if (addNumbers) {
completions.addAll(Arrays.asList(NUMBERS));
}
}
completions = new ArrayList<>(completions);
for (int index = 0; index < completions.size(); index++) {
completions.set(index, filter + arg + completions.get(index));
}
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
}
else if (lastArg.equals("page:") || currentArg.startsWith("page:")) {
String filter = lastArg;
String arg = "";
if (currentArg.contains(":")) {
String[] split = currentArg.split(":", 2);
filter = split[0] + ":";
if (split.length > 1) {
arg = split[1];
}
}
else {
filter = "";
arg = currentArg;
}
if (arg.chars().allMatch(Character::isDigit)) {
List<String> completions = new ArrayList<>(Arrays.asList(NUMBERS));
if (arg.length() < 1) {
for (int index = 0; index < completions.size(); index++) {
completions.set(index, filter + arg + completions.get(index));
}
if (arg.length() == 0) {
completions.remove(0);
}
}
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
}
}
else if (lastArg.equals("r:") || lastArg.equals("radius:") || currentArg.startsWith("r:") || currentArg.startsWith("radius:")) {
String filter = lastArg;
String arg = "";
if (currentArg.contains(":")) {
String[] split = currentArg.split(":", 2);
filter = split[0] + ":";
if (split.length > 1) {
arg = split[1];
}
}
else {
filter = "";
arg = currentArg;
}
if (!argument0.equals("purge") && arg.chars().allMatch(Character::isDigit)) {
List<String> completions = new ArrayList<>(Arrays.asList(NUMBERS));
if (arg.length() < 2) {
for (int index = 0; index < completions.size(); index++) {
completions.set(index, filter + arg + completions.get(index));
}
}
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
}
else if (argument0.equals("purge") || arg.startsWith("#")) {
ArrayList<String> params = new ArrayList<>();
params.add("#global");
if (!argument0.equals("purge") && sender.getServer().getPluginManager().getPlugin("WorldEdit") != null) {
params.add("#worldedit");
}
List<World> worlds = sender.getServer().getWorlds();
for (World world : worlds) {
params.add("#" + world.getName());
}
List<String> completions = new ArrayList<>(params);
for (int index = 0; index < completions.size(); index++) {
completions.set(index, filter + completions.get(index));
}
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
}
}
else if (lastArg.equals("i:") || lastArg.equals("include:") || lastArg.equals("item:") || lastArg.equals("items:") || lastArg.equals("b:") || lastArg.equals("block:") || lastArg.equals("blocks:") || currentArg.startsWith("i:") || currentArg.startsWith("include:") || currentArg.startsWith("item:") || currentArg.startsWith("items:") || currentArg.startsWith("b:") || currentArg.startsWith("block:") || currentArg.startsWith("blocks:") || lastArg.equals("e:") || lastArg.equals("exclude:") || currentArg.startsWith("e:") || currentArg.startsWith("exclude:")) {
String filter = lastArg;
String arg = "";
if (currentArg.contains(":")) {
String[] split = currentArg.split(":", 2);
filter = split[0] + ":";
if (split.length > 1) {
arg = split[1];
}
}
else {
filter = "";
arg = currentArg;
}
if (materials == null) {
List<Material> addList = Arrays.asList(Material.ARMOR_STAND);
List<Material> excludeList = Arrays.asList(Material.GRASS);
Set<String> materialList = new HashSet<>();
Material[] materialValues = Material.values();
for (Material material : materialValues) {
if (material.isBlock() || material.isItem()) {
materialList.add(material.name().toLowerCase(Locale.ROOT));
}
}
for (Material exclude : excludeList) {
materialList.remove(exclude.name().toLowerCase(Locale.ROOT));
}
for (Material add : addList) {
materialList.add(add.name().toLowerCase(Locale.ROOT));
}
materials = new ArrayList<>(materialList);
}
List<String> completions = new ArrayList<>(materials);
for (int index = 0; index < completions.size(); index++) {
completions.set(index, filter + completions.get(index));
}
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
}
else if (args.length == 2) {
if (argument0.equals("help")) {
List<String> completions = new ArrayList<>(Arrays.asList(HELP));
return StringUtil.copyPartialMatches(argument1, completions, new ArrayList<>(completions.size()));
}
else if (argument0.equals("purge")) {
List<String> completions = new ArrayList<>(Arrays.asList("t:", "r:"));
return StringUtil.copyPartialMatches(argument1, completions, new ArrayList<>(completions.size()));
}
else if (argument0.equals("l") || argument0.equals("lookup") || argument0.equals("rollback") || argument0.equals("rb") || argument0.equals("ro") || argument0.equals("restore") || argument0.equals("rs") || argument0.equals("re")) {
List<String> completions = new ArrayList<>(filterParams(true, argument0, argument1, hasUser, hasAction, hasInclude, hasExclude, hasRadius, hasTime, hasContainer, hasCount, hasPreview, pageLookup, validContainer));
completions.addAll(Bukkit.getOnlinePlayers().stream().filter(player -> player.getName().toLowerCase(Locale.ROOT).startsWith(argument1)).map(Player::getName).collect(Collectors.toList()));
return StringUtil.copyPartialMatches(argument1, completions, new ArrayList<>(completions.size()));
}
}
else if (args.length == 3 && argument0.equals("purge")) {
if (argument1.startsWith("t:")) {
List<String> completions = new ArrayList<>(Arrays.asList("r:"));
return StringUtil.copyPartialMatches(args[2].toLowerCase(Locale.ROOT), completions, new ArrayList<>(completions.size()));
}
else if (argument1.startsWith("r:")) {
List<String> completions = new ArrayList<>(Arrays.asList("t:"));
return StringUtil.copyPartialMatches(args[2].toLowerCase(Locale.ROOT), completions, new ArrayList<>(completions.size()));
}
return Arrays.asList("");
}
else if (argument0.equals("l") || argument0.equals("lookup") || argument0.equals("rollback") || argument0.equals("rb") || argument0.equals("ro") || argument0.equals("restore") || argument0.equals("rs") || argument0.equals("re")) {
if ((!argument0.equals("l") && !argument0.equals("lookup")) || !hasPage) {
ArrayList<String> params = filterParams(false, argument0, currentArg, hasUser, hasAction, hasInclude, hasExclude, hasRadius, hasTime, hasContainer, hasCount, hasPreview, pageLookup, validContainer);
List<String> completions = new ArrayList<>(params);
return StringUtil.copyPartialMatches(currentArg, completions, new ArrayList<>(completions.size()));
}
}
}
return Arrays.asList("");
}
private ArrayList<String> filterParams(boolean firstParam, String lastArgument, String argument, boolean hasUser, boolean hasAction, boolean hasInclude, boolean hasExclude, boolean hasRadius, boolean hasTime, boolean hasContainer, boolean hasCount, boolean hasPreview, boolean pageLookup, boolean validContainer) {
ArrayList<String> params = new ArrayList<>();
for (String param : PARAMS) {
if (param.equals("user:") && !hasUser) {
params.add(param);
}
else if (param.equals("action:") && !hasAction) {
params.add(param);
}
else if (param.equals("include:") && !hasInclude) {
params.add(param);
}
else if (param.equals("exclude:") && !hasExclude) {
params.add(param);
}
else if (param.equals("radius:") && !hasRadius) {
params.add(param);
}
else if (param.equals("time:") && !hasTime) {
params.add(param);
}
else if (param.equals("#container") && !hasContainer && !hasRadius && validContainer) {
params.add(param);
}
}
if (firstParam && pageLookup && (lastArgument.equals("l") || lastArgument.equals("lookup"))) {
params.add("page:");
}
else if (!firstParam && argument.startsWith("#")) {
if (!hasCount) {
params.add("#count");
}
if (!hasPreview) {
params.add("#preview");
}
}
return params;
}
}

View File

@ -0,0 +1,110 @@
package net.coreprotect.command;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.language.Phrase;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.ChatMessage;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class TeleportCommand {
protected static void runCommand(CommandSender player, boolean permission, String[] args) {
int resultc = args.length;
if (!permission) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
if (!(player instanceof Player)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.TELEPORT_PLAYERS));
return;
}
if (ConfigHandler.teleportThrottle.get(player.getName()) != null) {
Object[] lookupThrottle = ConfigHandler.teleportThrottle.get(player.getName());
if ((boolean) lookupThrottle[0] || ((System.currentTimeMillis() - (long) lookupThrottle[1])) < 500) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.COMMAND_THROTTLED));
return;
}
}
if (resultc < 3) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_PARAMETERS, "/co teleport <world> <x> <y> <z>"));
return;
}
String worldName = args[1];
int wid = Util.matchWorld(worldName);
if (wid == -1 && resultc >= 5) {
Chat.sendMessage(player, new ChatMessage(Phrase.build(Phrase.WORLD_NOT_FOUND, worldName)).build());
return;
}
Location location = ((Player) player).getLocation().clone();
World world = location.getWorld();
if (wid > -1) {
world = Bukkit.getServer().getWorld(Util.getWorldName(wid));
}
String x = null;
String y = null;
String z = null;
for (int i = 1; i < args.length; i++) {
if (i == 1 && wid > -1) {
continue;
}
if (x == null) {
x = args[i].replaceAll("[^0-9.\\-]", "");
}
else if (z == null) {
z = args[i].replaceAll("[^0-9.\\-]", "");
}
else if (y == null) {
y = z;
z = args[i].replaceAll("[^0-9.\\-]", "");
}
}
if (y == null) {
if (location.getBlockY() > 63) {
location.setY(63);
}
y = Double.toString(location.getY());
}
String xValidate = x.replaceAll("[^.\\-]", "");
String yValidate = y.replaceAll("[^.\\-]", "");
String zValidate = z.replaceAll("[^.\\-]", "");
if ((x.length() == 0 || x.length() >= 12 || x.equals(xValidate)) || (y.length() == 0 || y.length() >= 12 || y.equals(yValidate)) || (z.length() == 0 || z.length() >= 12 || z.equals(zValidate))) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_PARAMETERS, "/co teleport <world> <x> <y> <z>"));
return;
}
location.setWorld(world);
location.setX(Double.parseDouble(x));
location.setY(Double.parseDouble(y));
location.setZ(Double.parseDouble(z));
int chunkX = location.getBlockX() >> 4;
int chunkZ = location.getBlockZ() >> 4;
if (location.getWorld().isChunkLoaded(chunkX, chunkZ) == false) {
location.getWorld().getChunkAt(location);
}
// Teleport the player to a safe location
Util.performSafeTeleport(((Player) player), location, true);
ConfigHandler.teleportThrottle.put(player.getName(), new Object[] { false, System.currentTimeMillis() });
}
}

View File

@ -0,0 +1,53 @@
package net.coreprotect.command;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class UndoCommand {
protected static void runCommand(CommandSender user, Command command, boolean permission, String[] args) {
try {
if (ConfigHandler.lastRollback.get(user.getName()) != null) {
List<Object> list = ConfigHandler.lastRollback.get(user.getName());
int time = (Integer) list.get(0);
args = (String[]) list.get(1);
Location location = (Location) list.get(2);
for (String arg : args) {
if (arg.equals("#preview")) {
CancelCommand.runCommand(user, command, permission, args);
return;
}
}
boolean valid = true;
if (args[0].equals("rollback") || args[0].equals("rb") || args[0].equals("ro")) {
args[0] = "restore";
}
else if (args[0].equals("restore") || args[0].equals("rs") || args[0].equals("re")) {
args[0] = "rollback";
}
else {
valid = false;
}
if (valid) {
ConfigHandler.lastRollback.remove(user.getName());
RollbackRestoreCommand.runCommand(user, command, permission, args, location, time);
}
}
else {
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_ROLLBACK, Selector.SECOND));
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,56 @@
package net.coreprotect.command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.World;
import net.coreprotect.worldedit.WorldEditLogger;
public class WorldEditHandler {
protected static Integer[] runWorldEditCommand(CommandSender user) {
Integer[] result = null;
try {
WorldEditPlugin worldEdit = WorldEditLogger.getWorldEdit(user.getServer());
if (worldEdit != null && user instanceof Player) {
LocalSession session = worldEdit.getSession((Player) user);
World world = session.getSelectionWorld();
if (world != null) {
Region region = session.getSelection(world);
if (region != null && world.getName().equals(((Player) user).getWorld().getName())) {
BlockVector3 block = region.getMinimumPoint();
int x = block.getBlockX();
int y = block.getBlockY();
int z = block.getBlockZ();
int width = region.getWidth();
int height = region.getHeight();
int length = region.getLength();
int max = width;
if (height > max) {
max = height;
}
if (length > max) {
max = length;
}
int xMin = x;
int xMax = x + (width - 1);
int yMin = y;
int yMax = y + (height - 1);
int zMin = z;
int zMax = z + (length - 1);
result = new Integer[] { max, xMin, xMax, yMin, yMax, zMin, zMax, 1 };
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
}

View File

@ -0,0 +1,466 @@
package net.coreprotect.config;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.CompletableFuture;
import org.bukkit.Bukkit;
import org.bukkit.World;
import net.coreprotect.CoreProtect;
import net.coreprotect.language.Language;
public class Config extends Language {
private static final Map<String, String[]> HEADERS = new HashMap<>();
private static final Map<String, String> DEFAULT_VALUES = new LinkedHashMap<>();
private static final Map<String, Config> CONFIG_BY_WORLD_NAME = new HashMap<>();
private static final WeakHashMap<World, Config> CONFIG_BY_WORLD = new WeakHashMap<>();
private static final String DEFAULT_FILE_HEADER = "# CoreProtect Config";
public static final String LINE_SEPARATOR = "\n";
private static final Config GLOBAL = new Config();
private final HashMap<String, String> config;
private Config defaults;
public String DONATION_KEY;
public String PREFIX;
public String MYSQL_HOST;
public String MYSQL_DATABASE;
public String MYSQL_USERNAME;
public String MYSQL_PASSWORD;
public String LANGUAGE;
public boolean HOVER_EVENTS;
public boolean DATABASE_LOCK;
public boolean HOPPER_FILTER_META;
public boolean MYSQL;
public boolean CHECK_UPDATES;
public boolean API_ENABLED;
public boolean VERBOSE;
public boolean ROLLBACK_ITEMS;
public boolean ROLLBACK_ENTITIES;
public boolean SKIP_GENERIC_DATA;
public boolean BLOCK_PLACE;
public boolean BLOCK_BREAK;
public boolean NATURAL_BREAK;
public boolean BLOCK_MOVEMENT;
public boolean PISTONS;
public boolean BLOCK_BURN;
public boolean BLOCK_IGNITE;
public boolean EXPLOSIONS;
public boolean ENTITY_CHANGE;
public boolean ENTITY_KILLS;
public boolean SIGN_TEXT;
public boolean BUCKETS;
public boolean LEAF_DECAY;
public boolean TREE_GROWTH;
public boolean MUSHROOM_GROWTH;
public boolean VINE_GROWTH;
public boolean PORTALS;
public boolean WATER_FLOW;
public boolean LAVA_FLOW;
public boolean LIQUID_TRACKING;
public boolean ITEM_TRANSACTIONS;
public boolean ITEM_DROPS;
public boolean ITEM_PICKUPS;
public boolean HOPPER_TRANSACTIONS;
public boolean PLAYER_INTERACTIONS;
public boolean PLAYER_MESSAGES;
public boolean PLAYER_COMMANDS;
public boolean PLAYER_SESSIONS;
public boolean USERNAME_CHANGES;
public boolean WORLDEDIT;
public int MYSQL_PORT;
public int DEFAULT_RADIUS;
public int MAX_RADIUS;
static {
DEFAULT_VALUES.put("donation-key", "");
DEFAULT_VALUES.put("use-mysql", "false");
DEFAULT_VALUES.put("table-prefix", "co_");
DEFAULT_VALUES.put("mysql-host", "127.0.0.1");
DEFAULT_VALUES.put("mysql-port", "3306");
DEFAULT_VALUES.put("mysql-database", "database");
DEFAULT_VALUES.put("mysql-username", "root");
DEFAULT_VALUES.put("mysql-password", "");
DEFAULT_VALUES.put("language", "en");
DEFAULT_VALUES.put("check-updates", "true");
DEFAULT_VALUES.put("api-enabled", "true");
DEFAULT_VALUES.put("verbose", "true");
DEFAULT_VALUES.put("default-radius", "10");
DEFAULT_VALUES.put("max-radius", "100");
DEFAULT_VALUES.put("rollback-items", "true");
DEFAULT_VALUES.put("rollback-entities", "true");
DEFAULT_VALUES.put("skip-generic-data", "true");
DEFAULT_VALUES.put("block-place", "true");
DEFAULT_VALUES.put("block-break", "true");
DEFAULT_VALUES.put("natural-break", "true");
DEFAULT_VALUES.put("block-movement", "true");
DEFAULT_VALUES.put("pistons", "true");
DEFAULT_VALUES.put("block-burn", "true");
DEFAULT_VALUES.put("block-ignite", "true");
DEFAULT_VALUES.put("explosions", "true");
DEFAULT_VALUES.put("entity-change", "true");
DEFAULT_VALUES.put("entity-kills", "true");
DEFAULT_VALUES.put("sign-text", "true");
DEFAULT_VALUES.put("buckets", "true");
DEFAULT_VALUES.put("leaf-decay", "true");
DEFAULT_VALUES.put("tree-growth", "true");
DEFAULT_VALUES.put("mushroom-growth", "true");
DEFAULT_VALUES.put("vine-growth", "true");
DEFAULT_VALUES.put("portals", "true");
DEFAULT_VALUES.put("water-flow", "true");
DEFAULT_VALUES.put("lava-flow", "true");
DEFAULT_VALUES.put("liquid-tracking", "true");
DEFAULT_VALUES.put("item-transactions", "true");
DEFAULT_VALUES.put("item-drops", "true");
DEFAULT_VALUES.put("item-pickups", "true");
DEFAULT_VALUES.put("hopper-transactions", "true");
DEFAULT_VALUES.put("player-interactions", "true");
DEFAULT_VALUES.put("player-messages", "true");
DEFAULT_VALUES.put("player-commands", "true");
DEFAULT_VALUES.put("player-sessions", "true");
DEFAULT_VALUES.put("username-changes", "true");
DEFAULT_VALUES.put("worldedit", "true");
HEADERS.put("donation-key", new String[] { "# CoreProtect is donationware. For more information, visit our project page." });
HEADERS.put("use-mysql", new String[] { "# MySQL is optional and not required.", "# If you prefer to use MySQL, enable the following and fill out the fields." });
HEADERS.put("language", new String[] { "# If modified, will automatically attempt to translate languages phrases.", "# List of language codes: https://coreprotect.net/languages/" });
HEADERS.put("check-updates", new String[] { "# If enabled, CoreProtect will check for updates when your server starts up.", "# If an update is available, you'll be notified via your server console.", });
HEADERS.put("api-enabled", new String[] { "# If enabled, other plugins will be able to utilize the CoreProtect API.", });
HEADERS.put("verbose", new String[] { "# If enabled, extra data is displayed during rollbacks and restores.", "# Can be manually triggered by adding \"#verbose\" to your rollback command." });
HEADERS.put("default-radius", new String[] { "# If no radius is specified in a rollback or restore, this value will be", "# used as the radius. Set to \"0\" to disable automatically adding a radius." });
HEADERS.put("max-radius", new String[] { "# The maximum radius that can be used in a command. Set to \"0\" to disable.", "# To run a rollback or restore without a radius, you can use \"r:#global\"." });
HEADERS.put("rollback-items", new String[] { "# If enabled, items taken from containers (etc) will be included in rollbacks." });
HEADERS.put("rollback-entities", new String[] { "# If enabled, entities, such as killed animals, will be included in rollbacks." });
HEADERS.put("skip-generic-data", new String[] { "# If enabled, generic data, like zombies burning in daylight, won't be logged." });
HEADERS.put("block-place", new String[] { "# Logs blocks placed by players." });
HEADERS.put("block-break", new String[] { "# Logs blocks broken by players." });
HEADERS.put("natural-break", new String[] { "# Logs blocks that break off of other blocks; for example, a sign or torch", "# falling off of a dirt block that a player breaks. This is required for", "# beds/doors to properly rollback." });
HEADERS.put("block-movement", new String[] { "# Properly track block movement, such as sand or gravel falling." });
HEADERS.put("pistons", new String[] { "# Properly track blocks moved by pistons." });
HEADERS.put("block-burn", new String[] { "# Logs blocks that burn up in a fire." });
HEADERS.put("block-ignite", new String[] { "# Logs when a block naturally ignites, such as from fire spreading." });
HEADERS.put("explosions", new String[] { "# Logs explosions, such as TNT and Creepers." });
HEADERS.put("entity-change", new String[] { "# Track when an entity changes a block, such as an Enderman destroying blocks." });
HEADERS.put("entity-kills", new String[] { "# Logs killed entities, such as killed cows and enderman." });
HEADERS.put("sign-text", new String[] { "# Logs text on signs. If disabled, signs will be blank when rolled back." });
HEADERS.put("buckets", new String[] { "# Logs lava and water sources placed/removed by players who are using buckets." });
HEADERS.put("leaf-decay", new String[] { "# Logs natural tree leaf decay." });
HEADERS.put("tree-growth", new String[] { "# Logs tree growth. Trees are linked to the player who planted the sappling." });
HEADERS.put("mushroom-growth", new String[] { "# Logs mushroom growth." });
HEADERS.put("vine-growth", new String[] { "# Logs natural vine growth." });
HEADERS.put("portals", new String[] { "# Logs when portals such as Nether portals generate naturally." });
HEADERS.put("water-flow", new String[] { "# Logs water flow. If water destroys other blocks, such as torches,", "# this allows it to be properly rolled back." });
HEADERS.put("lava-flow", new String[] { "# Logs lava flow. If lava destroys other blocks, such as torches,", "# this allows it to be properly rolled back." });
HEADERS.put("liquid-tracking", new String[] { "# Allows liquid to be properly tracked and linked to players.", "# For example, if a player places water which flows and destroys torches,", "# it can all be properly restored by rolling back that single player." });
HEADERS.put("item-transactions", new String[] { "# Track item transactions, such as when a player takes items from", "# a chest, furnace, or dispenser." });
HEADERS.put("item-drops", new String[] { "# Logs items dropped by players." });
HEADERS.put("item-pickups", new String[] { "# Logs items picked up by players." });
HEADERS.put("hopper-transactions", new String[] { "# Track all hopper transactions, such as when a hopper removes items from a", "# chest, furnace, or dispenser." });
HEADERS.put("player-interactions", new String[] { "# Track player interactions, such as when a player opens a door, presses", "# a button, or opens a chest. Player interactions can't be rolled back." });
HEADERS.put("player-messages", new String[] { "# Logs messages that players send in the chat." });
HEADERS.put("player-commands", new String[] { "# Logs all commands used by players." });
HEADERS.put("player-sessions", new String[] { "# Logs the logins and logouts of players." });
HEADERS.put("username-changes", new String[] { "# Logs when a player changes their Minecraft username." });
HEADERS.put("worldedit", new String[] { "# Logs changes made via the plugin \"WorldEdit\" if it's in use on your server." });
}
private void readValues() {
this.HOVER_EVENTS = this.getBoolean("hover-events", true);
this.DATABASE_LOCK = this.getBoolean("database-lock", true);
this.HOPPER_FILTER_META = this.getBoolean("hopper-filter-meta", false);
this.DONATION_KEY = this.getString("donation-key");
this.MYSQL = this.getBoolean("use-mysql");
this.PREFIX = this.getString("table-prefix");
this.MYSQL_HOST = this.getString("mysql-host");
this.MYSQL_PORT = this.getInt("mysql-port");
this.MYSQL_DATABASE = this.getString("mysql-database");
this.MYSQL_USERNAME = this.getString("mysql-username");
this.MYSQL_PASSWORD = this.getString("mysql-password");
this.LANGUAGE = this.getString("language");
this.CHECK_UPDATES = this.getBoolean("check-updates");
this.API_ENABLED = this.getBoolean("api-enabled");
this.VERBOSE = this.getBoolean("verbose");
this.DEFAULT_RADIUS = this.getInt("default-radius");
this.MAX_RADIUS = this.getInt("max-radius");
this.ROLLBACK_ITEMS = this.getBoolean("rollback-items");
this.ROLLBACK_ENTITIES = this.getBoolean("rollback-entities");
this.SKIP_GENERIC_DATA = this.getBoolean("skip-generic-data");
this.BLOCK_PLACE = this.getBoolean("block-place");
this.BLOCK_BREAK = this.getBoolean("block-break");
this.NATURAL_BREAK = this.getBoolean("natural-break");
this.BLOCK_MOVEMENT = this.getBoolean("block-movement");
this.PISTONS = this.getBoolean("pistons");
this.BLOCK_BURN = this.getBoolean("block-burn");
this.BLOCK_IGNITE = this.getBoolean("block-ignite");
this.EXPLOSIONS = this.getBoolean("explosions");
this.ENTITY_CHANGE = this.getBoolean("entity-change");
this.ENTITY_KILLS = this.getBoolean("entity-kills");
this.SIGN_TEXT = this.getBoolean("sign-text");
this.BUCKETS = this.getBoolean("buckets");
this.LEAF_DECAY = this.getBoolean("leaf-decay");
this.TREE_GROWTH = this.getBoolean("tree-growth");
this.MUSHROOM_GROWTH = this.getBoolean("mushroom-growth");
this.VINE_GROWTH = this.getBoolean("vine-growth");
this.PORTALS = this.getBoolean("portals");
this.WATER_FLOW = this.getBoolean("water-flow");
this.LAVA_FLOW = this.getBoolean("lava-flow");
this.LIQUID_TRACKING = this.getBoolean("liquid-tracking");
this.ITEM_TRANSACTIONS = this.getBoolean("item-transactions");
this.ITEM_DROPS = this.getBoolean("item-drops");
this.ITEM_PICKUPS = this.getBoolean("item-pickups");
this.HOPPER_TRANSACTIONS = this.getBoolean("hopper-transactions");
this.PLAYER_INTERACTIONS = this.getBoolean("player-interactions");
this.PLAYER_MESSAGES = this.getBoolean("player-messages");
this.PLAYER_COMMANDS = this.getBoolean("player-commands");
this.PLAYER_SESSIONS = this.getBoolean("player-sessions");
this.USERNAME_CHANGES = this.getBoolean("username-changes");
this.WORLDEDIT = this.getBoolean("worldedit");
}
public static void init() throws IOException {
parseConfig(loadFiles(ConfigFile.CONFIG));
// pass variables to ConfigFile.parseConfig(ConfigFile.loadFiles());
}
public static Config getGlobal() {
return GLOBAL;
}
// returns a world specific config if it exists, otherwise the global config
public static Config getConfig(final World world) {
Config ret = CONFIG_BY_WORLD.get(world);
if (ret == null) {
ret = CONFIG_BY_WORLD_NAME.getOrDefault(world.getName(), GLOBAL);
CONFIG_BY_WORLD.put(world, ret);
}
return ret;
}
public Config() {
this.config = new LinkedHashMap<>();
}
public void setDefaults(final Config defaults) {
this.defaults = defaults;
}
private String get(final String key, final String dfl) {
String configured = this.config.get(key);
if (configured == null) {
if (dfl != null) {
return dfl;
}
if (this.defaults == null) {
configured = DEFAULT_VALUES.get(key);
}
else {
configured = this.defaults.config.getOrDefault(key, DEFAULT_VALUES.get(key));
}
}
return configured;
}
private boolean getBoolean(final String key) {
final String configured = this.get(key, null);
return configured != null && configured.startsWith("t");
}
private boolean getBoolean(final String key, final boolean dfl) {
final String configured = this.get(key, null);
return configured == null ? dfl : configured.startsWith("t");
}
private int getInt(final String key) {
return this.getInt(key, 0);
}
private int getInt(final String key, final int dfl) {
String configured = this.get(key, null);
if (configured == null) {
return dfl;
}
configured = configured.replaceAll("[^0-9]", "");
return configured.isEmpty() ? 0 : Integer.parseInt(configured);
}
private String getString(final String key) {
final String configured = this.get(key, null);
return configured == null ? "" : configured;
}
public void clearConfig() {
this.config.clear();
}
public void loadDefaults() {
this.clearConfig();
this.readValues();
}
public void load(final InputStream in) throws IOException {
// if we fail reading, we will not corrupt our current config.
final Map<String, String> newConfig = new LinkedHashMap<>(this.config.size());
ConfigFile.load(in, newConfig, false);
this.clearConfig();
this.config.putAll(newConfig);
this.readValues();
}
private static Map<String, byte[]> loadFiles(String fileName) throws IOException {
final CoreProtect plugin = CoreProtect.getInstance();
final File configFolder = plugin.getDataFolder();
if (!configFolder.exists()) {
configFolder.mkdirs();
}
final Map<String, byte[]> map = new HashMap<>();
final File globalFile = new File(configFolder, fileName);
if (globalFile.exists()) {
// we always add options to the global config
final byte[] data = Files.readAllBytes(globalFile.toPath());
map.put("config", data);
// can't modify GLOBAL, we're likely off-main here
final Config temp = new Config();
temp.load(new ByteArrayInputStream(data));
temp.addMissingOptions(globalFile);
}
else {
final Config temp = new Config();
temp.loadDefaults();
temp.addMissingOptions(globalFile);
}
for (final File worldConfigFile : configFolder.listFiles((File file) -> file.getName().endsWith(".yml"))) {
final String name = worldConfigFile.getName();
if (name.equals(ConfigFile.CONFIG) || name.equals(ConfigFile.LANGUAGE)) {
continue;
}
map.put(name.substring(0, name.length() - ".yml".length()), Files.readAllBytes(worldConfigFile.toPath()));
}
return map;
}
// this should only be called on the main thread
private static void parseConfig(final Map<String, byte[]> data) {
if (!Bukkit.isPrimaryThread()) {
// we call reloads asynchronously
// for now this solution is good enough to ensure we only modify on the main thread
final CompletableFuture<Void> complete = new CompletableFuture<>();
Bukkit.getScheduler().runTask(CoreProtect.getInstance(), () -> {
try {
parseConfig(data);
}
catch (final Throwable thr) {
if (thr instanceof ThreadDeath) {
throw (ThreadDeath) thr;
}
complete.completeExceptionally(thr);
return;
}
complete.complete(null);
});
complete.join();
return;
}
CONFIG_BY_WORLD_NAME.clear();
CONFIG_BY_WORLD.clear();
// we need to load global first since it is used for config defaults
final byte[] defaultData = data.get("config");
if (defaultData != null) {
try {
GLOBAL.load(new ByteArrayInputStream(defaultData));
}
catch (final IOException ex) {
throw new RuntimeException(ex); // shouldn't happen
}
}
else {
GLOBAL.loadDefaults();
}
for (final Map.Entry<String, byte[]> entry : data.entrySet()) {
final String worldName = entry.getKey();
if (worldName.equals("config")) {
continue;
}
final byte[] fileData = entry.getValue();
final Config config = new Config();
config.setDefaults(GLOBAL);
try {
config.load(new ByteArrayInputStream(fileData));
}
catch (final IOException ex) {
throw new RuntimeException(ex); // shouldn't happen
}
CONFIG_BY_WORLD_NAME.put(worldName, config);
}
}
public void addMissingOptions(final File file) throws IOException {
final boolean writeHeader = !file.exists() || file.length() == 0;
try (final FileOutputStream fout = new FileOutputStream(file, true)) {
OutputStreamWriter out = new OutputStreamWriter(new BufferedOutputStream(fout), StandardCharsets.UTF_8);
if (writeHeader) {
out.append(DEFAULT_FILE_HEADER);
out.append(LINE_SEPARATOR);
}
for (final Map.Entry<String, String> entry : DEFAULT_VALUES.entrySet()) {
final String key = entry.getKey();
final String defaultValue = entry.getValue();
final String configuredValue = this.config.get(key);
if (configuredValue != null) {
continue;
}
final String[] header = HEADERS.get(key);
if (header != null) {
out.append(LINE_SEPARATOR);
for (final String headerLine : header) {
out.append(headerLine);
out.append(LINE_SEPARATOR);
}
}
out.append(key);
out.append(": ");
out.append(defaultValue);
out.append(LINE_SEPARATOR);
}
out.close();
}
}
}

View File

@ -0,0 +1,214 @@
package net.coreprotect.config;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import net.coreprotect.CoreProtect;
import net.coreprotect.language.Language;
import net.coreprotect.language.Phrase;
public class ConfigFile extends Config {
public static final String CONFIG = "config.yml";
public static final String LANGUAGE = "language.yml";
public static final String LANGUAGE_CACHE = ".language";
private static final TreeMap<String, String> DEFAULT_VALUES = new TreeMap<>();
private static final TreeMap<String, String> USER_VALUES = new TreeMap<>();
private static final String DEFAULT_FILE_HEADER = "# CoreProtect Language File (en)";
private final HashMap<String, String> lang;
public static void init(String fileName) throws IOException {
for (Phrase phrase : Phrase.values()) {
DEFAULT_VALUES.put(phrase.name(), phrase.getPhrase());
USER_VALUES.put(phrase.name(), phrase.getUserPhrase());
}
boolean isCache = fileName.startsWith(".");
loadFiles(fileName, isCache);
}
public ConfigFile() {
this.lang = new LinkedHashMap<>();
}
public void load(final InputStream in, String fileName, boolean isCache) throws IOException {
// if we fail reading, we will not corrupt our current config.
final Map<String, String> newConfig = new LinkedHashMap<>(this.lang.size());
ConfigFile.load(in, newConfig, true);
this.lang.clear();
this.lang.putAll(newConfig);
for (final Entry<String, String> entry : this.lang.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (DEFAULT_VALUES.containsKey(key) && value.length() > 0 && (!isCache || DEFAULT_VALUES.get(key).equals(USER_VALUES.get(key)))) {
Phrase phrase = Phrase.valueOf(key);
if (!isCache) {
Language.setUserPhrase(phrase, value);
}
Language.setTranslatedPhrase(phrase, value);
}
}
}
// this function will close in
public static void load(final InputStream in, final Map<String, String> config, boolean forceCase) throws IOException {
try (final InputStream in0 = in) {
BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
if (line.startsWith("#")) {
continue;
}
final int split = line.indexOf(':');
if (split == -1) {
continue;
}
String key = line.substring(0, split).trim();
String value = line.substring(split + 1).trim();
// Strip out single and double quotes from the start/end of the value
if (value.length() >= 2 && value.startsWith("'") && value.endsWith("'")) {
value = value.replaceAll("^'|'$", "");
value = value.replace("''", "'");
value = value.replace("\\'", "'");
value = value.replace("\\\\", "\\");
}
else if (value.length() >= 2 && value.startsWith("\"") && value.endsWith("\"")) {
value = value.replaceAll("^\"|\"$", "");
value = value.replace("\\\"", "\"");
value = value.replace("\\\\", "\\");
}
if (forceCase) {
key = key.toUpperCase(Locale.ROOT);
}
config.put(key, value);
}
reader.close();
}
}
private static Map<String, byte[]> loadFiles(String fileName, boolean isCache) throws IOException {
final CoreProtect plugin = CoreProtect.getInstance();
final File configFolder = plugin.getDataFolder();
if (!configFolder.exists()) {
configFolder.mkdirs();
}
final Map<String, byte[]> map = new HashMap<>();
final File globalFile = new File(configFolder, fileName);
if (globalFile.exists()) {
// we always add options to the global config
final byte[] data = Files.readAllBytes(globalFile.toPath());
map.put("config", data);
final ConfigFile temp = new ConfigFile();
temp.load(new ByteArrayInputStream(data), fileName, isCache);
temp.addMissingOptions(globalFile);
}
else {
final ConfigFile temp = new ConfigFile();
temp.addMissingOptions(globalFile);
}
return map;
}
@Override
public void addMissingOptions(final File file) throws IOException {
if (file.getName().startsWith(".")) {
return;
}
final boolean writeHeader = !file.exists() || file.length() == 0;
try (final FileOutputStream fout = new FileOutputStream(file, true)) {
OutputStreamWriter out = new OutputStreamWriter(new BufferedOutputStream(fout), StandardCharsets.UTF_8);
if (writeHeader) {
out.append(DEFAULT_FILE_HEADER);
out.append(Config.LINE_SEPARATOR);
}
for (final Entry<String, String> entry : DEFAULT_VALUES.entrySet()) {
final String key = entry.getKey();
final String defaultValue = entry.getValue().replaceAll("\"", "\\\\\"");
final String configuredValue = this.lang.get(key);
if (configuredValue != null) {
continue;
}
out.append(Config.LINE_SEPARATOR);
out.append(key);
out.append(": ");
out.append("\"" + defaultValue + "\"");
}
out.close();
}
}
public static void modifyLine(String fileName, String oldLine, String newLine) {
try {
Path path = Paths.get(ConfigHandler.path + fileName);
List<String> lines = Files.readAllLines(path);
for (int i = 0; i < lines.size(); i++) {
if (lines.get(i).equalsIgnoreCase(oldLine)) {
if (newLine.length() > 0) {
lines.set(i, newLine);
}
else {
lines.remove(i);
}
break;
}
}
if (lines.size() > 0) {
String lastLine = lines.get(lines.size() - 1); // append the final line to prevent a line separator from being added
Files.write(path, (lines.remove(lines.size() - 1).isEmpty() ? lines : lines), StandardCharsets.UTF_8);
Files.write(path, lastLine.getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
lines.clear();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void resetCache(String cacheName, String fileName) throws IOException {
File file = new File(CoreProtect.getInstance().getDataFolder(), cacheName);
if (file.length() > 0) {
new FileOutputStream(file).close();
init(fileName);
}
}
}

View File

@ -0,0 +1,408 @@
package net.coreprotect.config;
import java.io.File;
import java.io.RandomAccessFile;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import net.coreprotect.bukkit.BukkitAdapter;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.consumer.Queue;
import net.coreprotect.database.Database;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.model.BlockGroup;
import net.coreprotect.patch.Patch;
import net.coreprotect.spigot.SpigotAdapter;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class ConfigHandler extends Queue {
public static int SERVER_VERSION = 0;
public static final int EDITION_VERSION = 2;
public static final String EDITION_BRANCH = Util.getBranch();
public static final String EDITION_NAME = Util.getPluginName();
public static final String JAVA_VERSION = "1.8";
public static final String SPIGOT_VERSION = "1.14";
public static String path = "plugins/CoreProtect/";
public static String sqlite = "database.db";
public static String host = "127.0.0.1";
public static int port = 3306;
public static String database = "database";
public static String username = "root";
public static String password = "";
public static String prefix = "co_";
public static final boolean isSpigot = Util.isSpigot();
public static final boolean isPaper = Util.isPaper();
public static volatile boolean serverRunning = false;
public static volatile boolean converterRunning = false;
public static volatile boolean purgeRunning = false;
public static volatile boolean worldeditEnabled = false;
public static volatile boolean databaseReachable = true;
public static volatile int worldId = 0;
public static volatile int materialId = 0;
public static volatile int blockdataId = 0;
public static volatile int entityId = 0;
public static volatile int artId = 0;
private static <K, V> Map<K, V> syncMap() {
return Collections.synchronizedMap(new HashMap<>());
}
public static Map<String, Integer> worlds = syncMap();
public static Map<Integer, String> worldsReversed = syncMap();
public static Map<String, Integer> materials = syncMap();
public static Map<Integer, String> materialsReversed = syncMap();
public static Map<String, Integer> blockdata = syncMap();
public static Map<Integer, String> blockdataReversed = syncMap();
public static Map<String, Integer> entities = syncMap();
public static Map<Integer, String> entitiesReversed = syncMap();
public static Map<String, Integer> art = syncMap();
public static Map<Integer, String> artReversed = syncMap();
public static Map<String, int[]> rollbackHash = syncMap();
public static Map<String, Boolean> inspecting = syncMap();
public static Map<String, Boolean> blacklist = syncMap();
public static Map<String, Integer> loggingChest = syncMap();
public static Map<String, Integer> loggingItem = syncMap();
public static ConcurrentHashMap<String, List<Object>> transactingChest = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, List<ItemStack[]>> oldContainer = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, List<ItemStack>> itemsDrop = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, List<ItemStack>> itemsPickup = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, Boolean> hopperAbort = new ConcurrentHashMap<>();
public static Map<String, List<ItemStack[]>> forceContainer = syncMap();
public static Map<String, Integer> lookupType = syncMap();
public static Map<String, Object[]> lookupThrottle = syncMap();
public static Map<String, Object[]> teleportThrottle = syncMap();
public static Map<String, Integer> lookupPage = syncMap();
public static Map<String, String> lookupCommand = syncMap();
public static Map<String, List<Object>> lookupBlist = syncMap();
public static Map<String, List<Object>> lookupElist = syncMap();
public static Map<String, List<String>> lookupEUserlist = syncMap();
public static Map<String, List<String>> lookupUlist = syncMap();
public static Map<String, List<Integer>> lookupAlist = syncMap();
public static Map<String, Integer[]> lookupRadius = syncMap();
public static Map<String, String> lookupTime = syncMap();
public static Map<String, Integer> lookupRows = syncMap();
public static Map<String, String> uuidCache = syncMap();
public static Map<String, String> uuidCacheReversed = syncMap();
public static Map<String, Integer> playerIdCache = syncMap();
public static Map<Integer, String> playerIdCacheReversed = syncMap();
public static Map<String, List<Object>> lastRollback = syncMap();
public static Map<String, Boolean> activeRollbacks = syncMap();
public static Map<UUID, Object[]> entityBlockMapper = syncMap();
public static ConcurrentHashMap<String, String> language = new ConcurrentHashMap<>();
public static List<String> databaseTables = new ArrayList<>();
private static void checkPlayers(Connection connection) {
ConfigHandler.playerIdCache.clear();
ConfigHandler.playerIdCacheReversed.clear();
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
if (ConfigHandler.playerIdCache.get(player.getName().toLowerCase(Locale.ROOT)) == null) {
UserStatement.loadId(connection, player.getName(), player.getUniqueId().toString());
}
}
}
private static void loadBlacklist() {
try {
ConfigHandler.blacklist.clear();
String blacklist = ConfigHandler.path + "blacklist.txt";
boolean exists = (new File(blacklist)).exists();
if (exists) {
RandomAccessFile blfile = new RandomAccessFile(blacklist, "rw");
long blc = blfile.length();
if (blc > 0) {
while (blfile.getFilePointer() < blfile.length()) {
String blacklistUser = blfile.readLine().replaceAll(" ", "").toLowerCase(Locale.ROOT);
if (blacklistUser.length() > 0) {
ConfigHandler.blacklist.put(blacklistUser, true);
}
}
}
blfile.close();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
private static void loadConfig() {
try {
Config.init();
ConfigFile.init(ConfigFile.LANGUAGE); // load user phrases
ConfigFile.init(ConfigFile.LANGUAGE_CACHE); // load translation cache
// Enforce "co_" table prefix if using SQLite.
if (!Config.getGlobal().MYSQL) {
Config.getGlobal().PREFIX = "co_";
}
ConfigHandler.host = Config.getGlobal().MYSQL_HOST;
ConfigHandler.port = Config.getGlobal().MYSQL_PORT;
ConfigHandler.database = Config.getGlobal().MYSQL_DATABASE;
ConfigHandler.username = Config.getGlobal().MYSQL_USERNAME;
ConfigHandler.password = Config.getGlobal().MYSQL_PASSWORD;
ConfigHandler.prefix = Config.getGlobal().PREFIX;
ConfigHandler.loadBlacklist(); // Load the blacklist file if it exists.
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void loadDatabase() {
if (!Config.getGlobal().MYSQL) {
try {
File tempFile = File.createTempFile("CoreProtect_" + System.currentTimeMillis(), ".tmp");
tempFile.setExecutable(true);
boolean canExecute = false;
try {
canExecute = tempFile.canExecute();
}
catch (Exception exception) {
// execute access denied by security manager
}
if (!canExecute) {
File tempFolder = new File("cache");
boolean exists = tempFolder.exists();
if (!exists) {
tempFolder.mkdir();
}
System.setProperty("java.io.tmpdir", "cache");
}
tempFile.delete();
}
catch (Exception e) {
e.printStackTrace();
}
}
if (ConfigHandler.serverRunning) {
Consumer.resetConnection = true;
}
Database.createDatabaseTables(ConfigHandler.prefix, false);
}
public static void loadTypes(Statement statement) {
try {
String query = "SELECT id,material FROM " + ConfigHandler.prefix + "material_map";
ResultSet rs = statement.executeQuery(query);
ConfigHandler.materials.clear();
ConfigHandler.materialsReversed.clear();
materialId = 0;
while (rs.next()) {
int id = rs.getInt("id");
String material = rs.getString("material");
ConfigHandler.materials.put(material, id);
ConfigHandler.materialsReversed.put(id, material);
if (id > materialId) {
materialId = id;
}
}
rs.close();
query = "SELECT id,data FROM " + ConfigHandler.prefix + "blockdata_map";
rs = statement.executeQuery(query);
ConfigHandler.blockdata.clear();
ConfigHandler.blockdataReversed.clear();
blockdataId = 0;
while (rs.next()) {
int id = rs.getInt("id");
String data = rs.getString("data");
ConfigHandler.blockdata.put(data, id);
ConfigHandler.blockdataReversed.put(id, data);
if (id > blockdataId) {
blockdataId = id;
}
}
rs.close();
query = "SELECT id,art FROM " + ConfigHandler.prefix + "art_map";
rs = statement.executeQuery(query);
ConfigHandler.art.clear();
ConfigHandler.artReversed.clear();
artId = 0;
while (rs.next()) {
int id = rs.getInt("id");
String art = rs.getString("art");
ConfigHandler.art.put(art, id);
ConfigHandler.artReversed.put(id, art);
if (id > artId) {
artId = id;
}
}
rs.close();
query = "SELECT id,entity FROM " + ConfigHandler.prefix + "entity_map";
rs = statement.executeQuery(query);
ConfigHandler.entities.clear();
ConfigHandler.entitiesReversed.clear();
entityId = 0;
while (rs.next()) {
int id = rs.getInt("id");
String entity = rs.getString("entity");
ConfigHandler.entities.put(entity, id);
ConfigHandler.entitiesReversed.put(id, entity);
if (id > entityId) {
entityId = id;
}
}
rs.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void loadWorlds(Statement statement) {
try {
String query = "SELECT id,world FROM " + ConfigHandler.prefix + "world";
ResultSet rs = statement.executeQuery(query);
ConfigHandler.worlds.clear();
ConfigHandler.worldsReversed.clear();
worldId = 0;
while (rs.next()) {
int id = rs.getInt("id");
String world = rs.getString("world");
ConfigHandler.worlds.put(world, id);
ConfigHandler.worldsReversed.put(id, world);
if (id > worldId) {
worldId = id;
}
}
rs.close();
List<World> worlds = Bukkit.getServer().getWorlds();
for (World world : worlds) {
String worldname = world.getName();
if (ConfigHandler.worlds.get(worldname) == null) {
int id = worldId + 1;
ConfigHandler.worlds.put(worldname, id);
ConfigHandler.worldsReversed.put(id, worldname);
worldId = id;
Queue.queueWorldInsert(id, worldname);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
private static boolean checkDatabaseLock(Statement statement) {
try {
if (Config.getGlobal().DATABASE_LOCK) {
boolean locked = true;
boolean lockMessage = false;
int unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
int waitTime = unixtimestamp + 15;
while (locked) {
locked = false;
unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
int checkTime = unixtimestamp - 15;
String query = "SELECT * FROM " + ConfigHandler.prefix + "database_lock WHERE rowid='1' AND status='1' AND time >= '" + checkTime + "' LIMIT 1";
ResultSet rs = statement.executeQuery(query);
while (rs.next()) {
if (unixtimestamp < waitTime) {
if (!lockMessage) {
Chat.sendConsoleMessage("[CoreProtect] " + Phrase.build(Phrase.DATABASE_LOCKED_1));
lockMessage = true;
}
Thread.sleep(1000);
}
else {
Chat.sendConsoleMessage(Color.RED + "[CoreProtect] " + Phrase.build(Phrase.DATABASE_LOCKED_2));
Chat.sendConsoleMessage(Color.GREY + "[CoreProtect] " + Phrase.build(Phrase.DATABASE_LOCKED_3));
Chat.sendConsoleMessage(Color.GREY + "[CoreProtect] " + Phrase.build(Phrase.DATABASE_LOCKED_4));
return false;
}
locked = true;
}
rs.close();
}
}
}
catch (Exception e) {
e.printStackTrace();
}
return true;
}
public static boolean performInitialization(boolean startup) {
try {
BukkitAdapter.loadAdapter();
SpigotAdapter.loadAdapter();
BlockGroup.initialize();
ConfigHandler.loadConfig(); // Load (or create) the configuration file.
ConfigHandler.loadDatabase(); // Initialize MySQL and create tables if necessary.
Connection connection = Database.getConnection(true, 0);
Statement statement = connection.createStatement();
ConfigHandler.checkPlayers(connection);
ConfigHandler.loadWorlds(statement); // Load world ID's into memory.
ConfigHandler.loadTypes(statement); // Load material ID's into memory.
// Initialize WorldEdit logging
if (Util.checkWorldEdit()) {
PluginManager pluginManager = Bukkit.getServer().getPluginManager();
Plugin worldEditPlugin = pluginManager.getPlugin("WorldEdit");
if (worldEditPlugin != null && worldEditPlugin.isEnabled()) {
Util.loadWorldEdit();
}
}
else if (ConfigHandler.worldeditEnabled) {
Util.unloadWorldEdit();
}
ConfigHandler.serverRunning = true; // Set as running before patching
boolean validVersion = Patch.versionCheck(statement); // Minor upgrades & version check
boolean databaseLock = true;
if (startup) {
// Check that database isn't already in use
databaseLock = ConfigHandler.checkDatabaseLock(statement);
}
statement.close();
connection.close();
return validVersion && databaseLock;
}
catch (Exception e) {
e.printStackTrace();
}
return false;
}
}

View File

@ -0,0 +1,166 @@
package net.coreprotect.consumer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Bukkit;
import org.bukkit.block.BlockState;
import org.bukkit.inventory.ItemStack;
import net.coreprotect.CoreProtect;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.process.Process;
public class Consumer extends Process implements Runnable, Thread.UncaughtExceptionHandler {
public static volatile boolean resetConnection = false;
public static volatile int currentConsumer = 0;
public static volatile boolean isPaused = false;
public static volatile boolean transacting = false;
public static volatile boolean interrupt = false;
private static volatile boolean running = false;
protected static volatile boolean pausedSuccess = false;
public static ConcurrentHashMap<Integer, ArrayList<Object[]>> consumer = new ConcurrentHashMap<>(4, 0.75f, 2);
// public static ConcurrentHashMap<Integer, Integer[]> consumer_id = new ConcurrentHashMap<>();
public static Map<Integer, Integer[]> consumer_id = Collections.synchronizedMap(new HashMap<>());
public static ConcurrentHashMap<Integer, Map<Integer, String[]>> consumerUsers = new ConcurrentHashMap<>(4, 0.75f, 2);
@Deprecated
public static ConcurrentHashMap<Integer, Map<Integer, String>> consumerStrings = new ConcurrentHashMap<>(4, 0.75f, 2);
@Deprecated
public static ConcurrentHashMap<Integer, Map<Integer, Object[]>> consumerSigns = new ConcurrentHashMap<>(4, 0.75f, 2);
@Deprecated
public static ConcurrentHashMap<Integer, Map<Integer, ItemStack[]>> consumerContainers = new ConcurrentHashMap<>(4, 0.75f, 2);
@Deprecated
public static ConcurrentHashMap<Integer, Map<Integer, Object>> consumerInventories = new ConcurrentHashMap<>(4, 0.75f, 2);
@Deprecated
public static ConcurrentHashMap<Integer, Map<Integer, List<BlockState>>> consumerBlockList = new ConcurrentHashMap<>(4, 0.75f, 2);
@Deprecated
public static ConcurrentHashMap<Integer, Map<Integer, List<Object[]>>> consumerObjectArrayList = new ConcurrentHashMap<>(4, 0.75f, 2);
@Deprecated
public static ConcurrentHashMap<Integer, Map<Integer, List<Object>>> consumerObjectList = new ConcurrentHashMap<>(4, 0.75f, 2);
public static ConcurrentHashMap<Integer, Map<Integer, Object>> consumerObjects = new ConcurrentHashMap<>(4, 0.75f, 2);
// ^merge maps into single object based map
private static void errorDelay() {
try {
Thread.sleep(30000); // 30 seconds
}
catch (Exception e) {
e.printStackTrace();
}
}
protected static int newConsumerId(int consumer) {
int id = Consumer.consumer_id.get(consumer)[0];
Consumer.consumer_id.put(consumer, new Integer[] { id + 1, 1 });
return id;
}
public static int getConsumerSize(int id) {
if (id == 0 || id == 1) {
return Consumer.consumer.get(id).size();
}
return 0;
}
public static void initialize() {
Consumer.consumer.put(0, new ArrayList<>());
Consumer.consumer.put(1, new ArrayList<>());
Consumer.consumer_id.put(0, new Integer[] { 0, 0 });
Consumer.consumer_id.put(1, new Integer[] { 0, 0 });
Consumer.consumerUsers.put(0, new HashMap<>());
Consumer.consumerUsers.put(1, new HashMap<>());
Consumer.consumerObjects.put(0, new HashMap<>());
Consumer.consumerObjects.put(1, new HashMap<>());
Consumer.consumerStrings.put(0, new HashMap<>());
Consumer.consumerStrings.put(1, new HashMap<>());
Consumer.consumerSigns.put(0, new HashMap<>());
Consumer.consumerSigns.put(1, new HashMap<>());
Consumer.consumerInventories.put(0, new HashMap<>());
Consumer.consumerInventories.put(1, new HashMap<>());
Consumer.consumerBlockList.put(0, new HashMap<>());
Consumer.consumerBlockList.put(1, new HashMap<>());
Consumer.consumerObjectArrayList.put(0, new HashMap<>());
Consumer.consumerObjectArrayList.put(1, new HashMap<>());
Consumer.consumerObjectList.put(0, new HashMap<>());
Consumer.consumerObjectList.put(1, new HashMap<>());
Consumer.consumerContainers.put(0, new HashMap<>());
Consumer.consumerContainers.put(1, new HashMap<>());
}
public static boolean isRunning() {
return running;
}
private static void pauseConsumer(int process_id) {
try {
while ((ConfigHandler.serverRunning || ConfigHandler.converterRunning) && (Consumer.isPaused || ConfigHandler.purgeRunning || Consumer.consumer_id.get(process_id)[1] == 1)) {
pausedSuccess = true;
if (Consumer.isPaused || ConfigHandler.purgeRunning) {
if (connection != null) {
connection.close();
connection = null;
}
}
Thread.sleep(100);
}
}
catch (Exception e) {
e.printStackTrace();
}
pausedSuccess = false;
}
@Override
public void run() {
running = true;
boolean lastRun = false;
while (ConfigHandler.serverRunning || ConfigHandler.converterRunning || !lastRun) {
if (!ConfigHandler.serverRunning && !ConfigHandler.converterRunning) {
lastRun = true;
}
try {
int process_id = 0;
if (currentConsumer == 0) {
currentConsumer = 1;
}
else {
process_id = 1;
currentConsumer = 0;
}
Thread.sleep(500);
pauseConsumer(process_id);
Process.processConsumer(process_id, lastRun);
}
catch (Exception e) {
e.printStackTrace();
errorDelay();
}
}
running = false;
}
@Override
public void uncaughtException(Thread thread, Throwable e) {
running = false;
e.printStackTrace();
Bukkit.getPluginManager().disablePlugin(CoreProtect.getInstance());
}
public static void startConsumer() {
if (running == false) {
Thread consumerThread = new Thread(new Consumer());
consumerThread.setUncaughtExceptionHandler(new Consumer());
consumerThread.start();
}
}
}

View File

@ -0,0 +1,407 @@
package net.coreprotect.consumer;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.Bisected.Half;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import net.coreprotect.CoreProtect;
import net.coreprotect.bukkit.BukkitAdapter;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.process.Process;
import net.coreprotect.listener.block.BlockUtil;
import net.coreprotect.utility.Util;
public class Queue {
protected static synchronized int modifyForceContainer(String id, ItemStack[] container) {
List<ItemStack[]> forceList = ConfigHandler.forceContainer.get(id);
if (forceList == null) {
return 0;
}
if (container == null) {
forceList.remove(0);
}
else {
forceList.add(container);
}
return forceList.size();
}
protected static synchronized int getChestId(String id) {
int chestId = ConfigHandler.loggingChest.getOrDefault(id, -1) + 1;
ConfigHandler.loggingChest.put(id, chestId);
return chestId;
}
protected static synchronized int getItemId(String id) {
int chestId = ConfigHandler.loggingItem.getOrDefault(id, -1) + 1;
ConfigHandler.loggingItem.put(id, chestId);
return chestId;
}
private static synchronized void addConsumer(int currentConsumer, Object[] data) {
Consumer.consumer.get(currentConsumer).add(data);
}
private static void queueStandardData(int consumerId, int currentConsumer, String[] user, Object object) {
Consumer.consumerUsers.get(currentConsumer).put(consumerId, user);
Consumer.consumerObjects.get(currentConsumer).put(consumerId, object);
Consumer.consumer_id.put(currentConsumer, new Integer[] { Consumer.consumer_id.get(currentConsumer)[0], 0 });
}
protected static void queueAdvancedBreak(String user, BlockState block, Material type, String blockData, int data, Material breakType, int blockNumber) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.BLOCK_BREAK, type, data, breakType, 0, blockNumber, blockData });
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, block);
}
protected static void queueArtInsert(int id, String name) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.ART_INSERT, null, 0, null, 0, id, null });
queueStandardData(consumerId, currentConsumer, new String[] { null, null }, name);
}
protected static void queueBlockBreak(String user, BlockState block, Material type, String blockData, int extraData) {
queueBlockBreak(user, block, type, blockData, null, extraData, 0);
}
protected static void queueBlockBreakValidate(final String user, final Block block, final BlockState blockState, final Material type, final String blockData, final int extraData, int ticks) {
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> {
try {
if (!block.getType().equals(type)) {
queueBlockBreak(user, blockState, type, blockData, null, extraData, 0);
}
}
catch (Exception e) {
e.printStackTrace();
}
}, ticks);
}
protected static void queueBlockBreak(String user, BlockState block, Material type, String blockData, Material breakType, int extraData, int blockNumber) {
if (type == Material.SPAWNER && block instanceof CreatureSpawner) { // Mob spawner
CreatureSpawner mobSpawner = (CreatureSpawner) block;
extraData = Util.getSpawnerType(mobSpawner.getSpawnedType());
}
else if (type.equals(Material.SUNFLOWER) || type.equals(Material.LILAC) || type.equals(Material.TALL_GRASS) || type.equals(Material.LARGE_FERN) || type.equals(Material.ROSE_BUSH) || type.equals(Material.PEONY)) { // Double plant
if (block.getBlockData() instanceof Bisected) {
if (((Bisected) block.getBlockData()).getHalf().equals(Half.TOP) && !user.startsWith("#")) {
if (blockNumber == 5) {
return;
}
if (block.getY() > BukkitAdapter.ADAPTER.getMinHeight(block.getWorld())) {
block = block.getWorld().getBlockAt(block.getX(), block.getY() - 1, block.getZ()).getState();
}
}
}
}
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.BLOCK_BREAK, type, extraData, breakType, 0, blockNumber, blockData });
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, block);
}
protected static void queueBlockPlace(String user, BlockState blockLocation, Material blockType, BlockState blockReplaced, Material forceType, int forceD, int forceData, String blockData) {
// If force_data equals "1", current block data will be used in consumer.
Material type = blockType;
int data = 0;
Material replaceType = null;
int replaceData = 0;
if (type == Material.SPAWNER && blockLocation instanceof CreatureSpawner) { // Mob spawner
CreatureSpawner mobSpawner = (CreatureSpawner) blockLocation;
data = Util.getSpawnerType(mobSpawner.getSpawnedType());
forceData = 1;
}
if (blockReplaced != null) {
replaceType = blockReplaced.getType();
replaceData = 0;
if ((replaceType.equals(Material.SUNFLOWER) || replaceType.equals(Material.LILAC) || replaceType.equals(Material.TALL_GRASS) || replaceType.equals(Material.LARGE_FERN) || replaceType.equals(Material.ROSE_BUSH) || replaceType.equals(Material.PEONY)) && replaceData >= 8) { // Double plant top half
BlockState blockBelow = blockReplaced.getWorld().getBlockAt(blockReplaced.getX(), blockReplaced.getY() - 1, blockReplaced.getZ()).getState();
Material belowType = blockBelow.getType();
Queue.queueBlockBreak(user, blockBelow, belowType, blockBelow.getBlockData().getAsString(), 0);
}
}
if (forceType != null) {
type = forceType;
forceData = 1;
}
if (forceD != -1) {
data = forceD;
forceData = 1;
}
String replacedBlockData = null;
if (blockReplaced != null) {
replacedBlockData = blockReplaced.getBlockData().getAsString();
}
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.BLOCK_PLACE, type, data, replaceType, replaceData, forceData, blockData, replacedBlockData });
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, blockLocation);
}
protected static void queueBlockPlaceDelayed(final String user, final Location placed, final Material type, final String blockData, final BlockState replaced, int ticks) {
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> {
try {
queueBlockPlace(user, placed.getBlock().getState(), type, replaced, null, -1, 0, blockData);
}
catch (Exception e) {
e.printStackTrace();
}
}, ticks);
}
protected static void queueBlockPlaceValidate(final String user, final BlockState blockLocation, final Block block, final BlockState blockReplaced, final Material forceT, final int forceD, final int forceData, final String blockData, int ticks) {
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> {
try {
Material blockType = block.getType();
if (blockType.equals(forceT)) {
BlockState blockStateLocation = blockLocation;
if (Config.getConfig(blockLocation.getWorld()).BLOCK_MOVEMENT) {
blockStateLocation = BlockUtil.gravityScan(blockLocation.getLocation(), blockType, user).getState();
}
queueBlockPlace(user, blockStateLocation, blockType, blockReplaced, forceT, forceD, forceData, blockData);
}
}
catch (Exception e) {
e.printStackTrace();
}
}, ticks);
}
protected static void queueBlockGravityValidate(final String user, final Location location, final Block block, final Material blockType, int ticks) {
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> {
try {
Block placementBlock = BlockUtil.gravityScan(location, blockType, user);
if (!block.equals(placementBlock)) {
queueBlockPlace(user, placementBlock.getState(), blockType, null, blockType, -1, 0, null);
}
}
catch (Exception e) {
e.printStackTrace();
}
}, ticks);
}
protected static void queueContainerBreak(String user, Location location, Material type, ItemStack[] oldInventory) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.CONTAINER_BREAK, type, 0, null, 0, 0, null });
Consumer.consumerContainers.get(currentConsumer).put(consumerId, oldInventory);
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, location);
}
protected static void queueContainerRollbackUpdate(String user, Location location, List<Object[]> list, int action) {
if (location == null) {
location = new Location(Bukkit.getServer().getWorlds().get(0), 0, 0, 0);
}
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.CONTAINER_ROLLBACK_UPDATE, null, 0, null, 0, action, null });
Consumer.consumerObjectArrayList.get(currentConsumer).put(consumerId, list);
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, location);
}
protected static synchronized void queueContainerTransaction(String user, Location location, Material type, Object inventory, int chestId) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.CONTAINER_TRANSACTION, type, 0, null, 0, chestId, null });
Consumer.consumerInventories.get(currentConsumer).put(consumerId, inventory);
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, location);
}
protected static void queueItemTransaction(String user, Location location, int time, int itemId) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.ITEM_TRANSACTION, null, 0, null, time, itemId, null });
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, location);
}
protected static void queueEntityInsert(int id, String name) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.ENTITY_INSERT, null, 0, null, 0, id, null });
queueStandardData(consumerId, currentConsumer, new String[] { null, null }, name);
}
protected static void queueEntityKill(String user, Location location, List<Object> data, EntityType type) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.ENTITY_KILL, null, 0, null, 0, 0 });
Consumer.consumerObjectList.get(currentConsumer).put(consumerId, data);
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, new Object[] { location.getBlock().getState(), type, null });
}
protected static void queueEntitySpawn(String user, BlockState block, EntityType type, int data) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.ENTITY_SPAWN, null, 0, null, 0, data, null });
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, new Object[] { block, type });
}
protected static void queueHangingRemove(String user, BlockState block, int delay) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.HANGING_REMOVE, null, 0, null, 0, delay, null });
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, block);
}
protected static void queueHangingSpawn(String user, BlockState block, Material type, int data, int delay) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.HANGING_SPAWN, type, data, null, 0, delay, null });
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, block);
}
protected static void queueMaterialInsert(int id, String name) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.MATERIAL_INSERT, null, 0, null, 0, id, null });
queueStandardData(consumerId, currentConsumer, new String[] { null, null }, name);
}
protected static void queueBlockDataInsert(int id, String data) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.BLOCKDATA_INSERT, null, 0, null, 0, id, null });
queueStandardData(consumerId, currentConsumer, new String[] { null, null }, data);
}
protected static void queueNaturalBlockBreak(String user, BlockState block, Block relative, Material type, int data) {
List<BlockState> blockStates = new ArrayList<>();
if (relative != null) {
blockStates.add(relative.getState());
}
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.NATURAL_BLOCK_BREAK, type, data, null, 0, 0, null });
Consumer.consumerBlockList.get(currentConsumer).put(consumerId, blockStates);
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, block);
}
protected static void queuePlayerChat(Player player, String message, int time) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.PLAYER_CHAT, null, 0, null, 0, time, null });
Consumer.consumerStrings.get(currentConsumer).put(consumerId, message);
queueStandardData(consumerId, currentConsumer, new String[] { player.getName(), null }, player.getLocation().clone());
}
protected static void queuePlayerCommand(Player player, String message, int time) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.PLAYER_COMMAND, null, 0, null, 0, time, null });
Consumer.consumerStrings.get(currentConsumer).put(consumerId, message);
queueStandardData(consumerId, currentConsumer, new String[] { player.getName(), null }, player.getLocation().clone());
}
protected static void queuePlayerInteraction(String user, BlockState block) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.PLAYER_INTERACTION, null, 0, null, 0, 0, null });
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, block);
}
protected static void queuePlayerKill(String user, Location location, String player) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.PLAYER_KILL, null, 0, null, 0, 0, null });
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, new Object[] { location.getBlock().getState(), player });
}
protected static void queuePlayerLogin(Player player, int time, int configSessions, int configUsernames) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
String uuid = player.getUniqueId().toString();
addConsumer(currentConsumer, new Object[] { consumerId, Process.PLAYER_LOGIN, null, configSessions, null, configUsernames, time, null });
Consumer.consumerStrings.get(currentConsumer).put(consumerId, uuid);
queueStandardData(consumerId, currentConsumer, new String[] { player.getName(), uuid }, player.getLocation().clone());
}
protected static void queuePlayerQuit(Player player, int time) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.PLAYER_LOGOUT, null, 0, null, 0, time, null });
queueStandardData(consumerId, currentConsumer, new String[] { player.getName(), null }, player.getLocation().clone());
}
protected static void queueRollbackUpdate(String user, Location location, List<Object[]> list, int action) {
if (location == null) {
location = new Location(Bukkit.getServer().getWorlds().get(0), 0, 0, 0);
}
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.ROLLBACK_UPDATE, null, 0, null, 0, action, null });
Consumer.consumerObjectArrayList.get(currentConsumer).put(consumerId, list);
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, location);
}
protected static void queueSignText(String user, Location location, int action, int color, boolean glowing, String line1, String line2, String line3, String line4, int offset) {
/*
if (line1.length() == 0 && line2.length() == 0 && line3.length() == 0 && line4.length() == 0) {
return;
}
*/
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.SIGN_TEXT, null, color, null, action, offset, null });
Consumer.consumerSigns.get(currentConsumer).put(consumerId, new Object[] { (glowing == true ? 1 : 0), line1, line2, line3, line4 });
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, location);
}
protected static void queueSignUpdate(String user, BlockState block, int action, int time) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.SIGN_UPDATE, null, action, null, 0, time, null });
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, block);
}
protected static void queueSkullUpdate(String user, BlockState block, int rowId) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.SKULL_UPDATE, null, 0, null, 0, rowId, null });
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, block);
}
protected static void queueStructureGrow(String user, BlockState block, List<BlockState> blockList, int replacedListSize) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.STRUCTURE_GROWTH, null, 0, null, 0, replacedListSize, null });
Consumer.consumerBlockList.get(currentConsumer).put(consumerId, blockList);
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, block);
}
protected static void queueWorldInsert(int id, String world) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.WORLD_INSERT, null, 0, null, 0, id, null });
queueStandardData(consumerId, currentConsumer, new String[] { null, null }, world);
}
}

View File

@ -0,0 +1,35 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.sql.Statement;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.MaterialStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
class ArtInsertProcess {
static void process(PreparedStatement preparedStmt, Statement statement, int batchCount, Object name, int materialId) {
if (name instanceof String) {
String query = "SELECT id FROM " + ConfigHandler.prefix + "art_map WHERE id = '" + materialId + "' LIMIT 0, 1";
boolean hasMaterial = MaterialStatement.hasMaterial(statement, query);
if (!hasMaterial) {
MaterialStatement.insert(preparedStmt, batchCount, materialId, (String) name);
// validate ID maps to ensure mapping wasn't reloaded from database prior to this insertion completing
ConfigHandler.art.put((String) name, materialId);
ConfigHandler.artReversed.put(materialId, (String) name);
if (materialId > ConfigHandler.artId) {
ConfigHandler.artId = materialId;
}
}
else {
Chat.console(Phrase.build(Phrase.CACHE_ERROR, "art"));
Chat.console(Phrase.build(Phrase.CACHE_RELOAD, Selector.FIRST));
ConfigHandler.loadTypes(statement);
}
}
}
}

View File

@ -0,0 +1,42 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.block.Skull;
import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.type.Door;
import net.coreprotect.database.logger.BlockBreakLogger;
import net.coreprotect.database.logger.SkullBreakLogger;
import net.coreprotect.model.BlockGroup;
import net.coreprotect.utility.Util;
class BlockBreakProcess {
static void process(PreparedStatement preparedStmt, PreparedStatement preparedStmtSkulls, int batchCount, int processId, int id, Material blockType, int blockDataId, Material replaceType, int forceData, String user, Object object, String blockData) {
if (object instanceof BlockState) {
BlockState block = (BlockState) object;
List<Object> meta = Util.processMeta(block);
if (block instanceof Skull) {
SkullBreakLogger.log(preparedStmt, preparedStmtSkulls, batchCount, user, block);
}
else {
BlockBreakLogger.log(preparedStmt, batchCount, user, block.getLocation(), Util.getBlockId(blockType), blockDataId, meta, block.getBlockData().getAsString());
if (forceData == 5) { // Fix for doors
if ((blockType == Material.IRON_DOOR || BlockGroup.DOORS.contains(blockType)) && (replaceType != Material.IRON_DOOR && !BlockGroup.DOORS.contains(replaceType))) {
Door door = (Door) block.getBlockData();
door.setHalf(Bisected.Half.TOP);
blockData = door.getAsString();
Location location = block.getLocation();
location.setY(location.getY() + 1);
BlockBreakLogger.log(preparedStmt, batchCount, user, location, Util.getBlockId(blockType), 0, null, blockData);
}
}
}
}
}
}

View File

@ -0,0 +1,35 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.sql.Statement;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.MaterialStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
class BlockDataInsertProcess {
static void process(PreparedStatement preparedStmt, Statement statement, int batchCount, Object name, int materialId) {
if (name instanceof String) {
String query = "SELECT id FROM " + ConfigHandler.prefix + "blockdata_map WHERE id = '" + materialId + "' LIMIT 0, 1";
boolean hasMaterial = MaterialStatement.hasMaterial(statement, query);
if (!hasMaterial) {
MaterialStatement.insert(preparedStmt, batchCount, materialId, (String) name);
// validate ID maps to ensure mapping wasn't reloaded from database prior to this insertion completing
ConfigHandler.blockdata.put((String) name, materialId);
ConfigHandler.blockdataReversed.put(materialId, (String) name);
if (materialId > ConfigHandler.blockdataId) {
ConfigHandler.blockdataId = materialId;
}
}
else {
Chat.console(Phrase.build(Phrase.CACHE_ERROR, "blockdata"));
Chat.console(Phrase.build(Phrase.CACHE_RELOAD, Selector.FIRST));
ConfigHandler.loadTypes(statement);
}
}
}
}

View File

@ -0,0 +1,30 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import net.coreprotect.database.logger.BlockPlaceLogger;
import net.coreprotect.database.logger.SkullPlaceLogger;
import net.coreprotect.utility.Util;
class BlockPlaceProcess {
static void process(PreparedStatement preparedStmt, PreparedStatement preparedStmtSkulls, int batchCount, Material blockType, int blockData, Material replaceType, int replaceData, int forceData, String user, Object object, String newBlockData, String replacedBlockData) {
if (object instanceof BlockState) {
BlockState block = (BlockState) object;
List<Object> meta = Util.processMeta(block);
if (blockType.equals(Material.SKELETON_SKULL) || blockType.equals(Material.SKELETON_WALL_SKULL) || blockType.equals(Material.WITHER_SKELETON_SKULL) || blockType.equals(Material.WITHER_SKELETON_WALL_SKULL) || blockType.equals(Material.ZOMBIE_HEAD) || blockType.equals(Material.ZOMBIE_WALL_HEAD) || blockType.equals(Material.PLAYER_HEAD) || blockType.equals(Material.PLAYER_WALL_HEAD) || blockType.equals(Material.CREEPER_HEAD) || blockType.equals(Material.CREEPER_WALL_HEAD) || blockType.equals(Material.DRAGON_HEAD) || blockType.equals(Material.DRAGON_WALL_HEAD)) {
SkullPlaceLogger.log(preparedStmt, preparedStmtSkulls, batchCount, user, block, Util.getBlockId(replaceType), replaceData);
}
else if (forceData == 1) {
BlockPlaceLogger.log(preparedStmt, batchCount, user, block, Util.getBlockId(replaceType), replaceData, blockType, blockData, true, meta, newBlockData, replacedBlockData);
}
else {
BlockPlaceLogger.log(preparedStmt, batchCount, user, block, Util.getBlockId(replaceType), replaceData, blockType, blockData, false, meta, newBlockData, replacedBlockData);
}
}
}
}

View File

@ -0,0 +1,26 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.util.Map;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.database.logger.ContainerBreakLogger;
class ContainerBreakProcess {
static void process(PreparedStatement preparedStmt, int batchCount, int processId, int id, Material type, String user, Object object) {
if (object instanceof Location) {
Location location = (Location) object;
Map<Integer, ItemStack[]> containers = Consumer.consumerContainers.get(processId);
if (containers.get(id) != null) {
ItemStack[] container = containers.get(id);
ContainerBreakLogger.log(preparedStmt, batchCount, user, location, type, container);
containers.remove(id);
}
}
}
}

View File

@ -0,0 +1,49 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.database.logger.ContainerLogger;
class ContainerTransactionProcess {
static void process(PreparedStatement preparedStmtContainer, PreparedStatement preparedStmtItems, int batchCount, int processId, int id, Material type, int forceData, String user, Object object) {
if (object instanceof Location) {
Location location = (Location) object;
Map<Integer, Object> inventories = Consumer.consumerInventories.get(processId);
if (inventories.get(id) != null) {
Object inventory = inventories.get(id);
String transactingChestId = location.getWorld().getUID().toString() + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
String loggingChestId = user.toLowerCase(Locale.ROOT) + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
if (ConfigHandler.loggingChest.get(loggingChestId) != null) {
int current_chest = ConfigHandler.loggingChest.get(loggingChestId);
if (ConfigHandler.oldContainer.get(loggingChestId) == null) {
return;
}
int force_size = 0;
if (ConfigHandler.forceContainer.get(loggingChestId) != null) {
force_size = ConfigHandler.forceContainer.get(loggingChestId).size();
}
if (current_chest == forceData || force_size > 0) { // This prevents client side chest sorting mods from messing things up.
ContainerLogger.log(preparedStmtContainer, preparedStmtItems, batchCount, user, type, inventory, location);
List<ItemStack[]> old = ConfigHandler.oldContainer.get(loggingChestId);
if (old.size() == 0) {
ConfigHandler.oldContainer.remove(loggingChestId);
ConfigHandler.loggingChest.remove(loggingChestId);
ConfigHandler.transactingChest.remove(transactingChestId);
}
}
}
inventories.remove(id);
}
}
}
}

View File

@ -0,0 +1,35 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.sql.Statement;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.MaterialStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
class EntityInsertProcess {
static void process(PreparedStatement preparedStmt, Statement statement, int batchCount, Object name, int materialId) {
if (name instanceof String) {
String query = "SELECT id FROM " + ConfigHandler.prefix + "entity_map WHERE id = '" + materialId + "' LIMIT 0, 1";
boolean hasMaterial = MaterialStatement.hasMaterial(statement, query);
if (!hasMaterial) {
MaterialStatement.insert(preparedStmt, batchCount, materialId, (String) name);
// validate ID maps to ensure mapping wasn't reloaded from database prior to this insertion completing
ConfigHandler.entities.put((String) name, materialId);
ConfigHandler.entitiesReversed.put(materialId, (String) name);
if (materialId > ConfigHandler.entityId) {
ConfigHandler.entityId = materialId;
}
}
else {
Chat.console(Phrase.build(Phrase.CACHE_ERROR, "entity"));
Chat.console(Phrase.build(Phrase.CACHE_RELOAD, Selector.FIRST));
ConfigHandler.loadTypes(statement);
}
}
}
}

View File

@ -0,0 +1,29 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.util.List;
import java.util.Map;
import org.bukkit.block.BlockState;
import org.bukkit.entity.EntityType;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.database.logger.EntityKillLogger;
import net.coreprotect.utility.Util;
class EntityKillProcess {
static void process(PreparedStatement preparedStmt, PreparedStatement preparedStmtEntities, int batchCount, int processId, int id, Object object, String user) {
if (object instanceof Object[]) {
BlockState block = (BlockState) ((Object[]) object)[0];
EntityType type = (EntityType) ((Object[]) object)[1];
Map<Integer, List<Object>> objectLists = Consumer.consumerObjectList.get(processId);
if (objectLists.get(id) != null) {
List<Object> objectList = objectLists.get(id);
int entityId = Util.getEntityId(type);
EntityKillLogger.log(preparedStmt, preparedStmtEntities, batchCount, user, block, objectList, entityId);
objectLists.remove(id);
}
}
}
}

View File

@ -0,0 +1,24 @@
package net.coreprotect.consumer.process;
import java.sql.Statement;
import java.util.List;
import org.bukkit.block.BlockState;
import org.bukkit.entity.EntityType;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.EntityStatement;
import net.coreprotect.utility.Util;
class EntitySpawnProcess {
static void process(Statement statement, Object object, int rowId) {
if (object instanceof Object[]) {
BlockState block = (BlockState) ((Object[]) object)[0];
EntityType type = (EntityType) ((Object[]) object)[1];
String query = "SELECT data FROM " + ConfigHandler.prefix + "entity WHERE rowid='" + rowId + "' LIMIT 0, 1";
List<Object> data = EntityStatement.getData(statement, block, query);
Util.spawnEntity(block, type, data);
}
}
}

View File

@ -0,0 +1,15 @@
package net.coreprotect.consumer.process;
import org.bukkit.block.BlockState;
import net.coreprotect.utility.Util;
class HangingRemoveProcess {
static void process(Object object, int delay) {
if (object instanceof BlockState) {
BlockState block = (BlockState) object;
Util.removeHanging(block, delay);
}
}
}

View File

@ -0,0 +1,16 @@
package net.coreprotect.consumer.process;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import net.coreprotect.utility.Util;
class HangingSpawnProcess {
static void process(Object object, Material type, int data, int delay) {
if (object instanceof BlockState) {
BlockState block = (BlockState) object;
Util.spawnHanging(block, type, data, delay);
}
}
}

View File

@ -0,0 +1,39 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.util.Locale;
import org.bukkit.Location;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Queue;
import net.coreprotect.database.logger.ItemLogger;
class ItemTransactionProcess extends Queue {
static void process(PreparedStatement preparedStmt, int batchCount, int processId, int id, int forceData, int time, String user, Object object) {
if (object instanceof Location) {
Location location = (Location) object;
String loggingItemId = user.toLowerCase(Locale.ROOT) + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
if (ConfigHandler.loggingItem.get(loggingItemId) != null) {
int current_chest = ConfigHandler.loggingItem.get(loggingItemId);
if (ConfigHandler.itemsDrop.get(loggingItemId) == null && ConfigHandler.itemsPickup.get(loggingItemId) == null) {
return;
}
if (current_chest == forceData) {
int currentTime = (int) (System.currentTimeMillis() / 1000L);
if (currentTime > time) {
ItemLogger.log(preparedStmt, batchCount, location, user);
ConfigHandler.itemsDrop.remove(loggingItemId);
ConfigHandler.itemsPickup.remove(loggingItemId);
ConfigHandler.loggingItem.remove(loggingItemId);
}
else {
Queue.queueItemTransaction(user, location, time, forceData);
}
}
}
}
}
}

View File

@ -0,0 +1,35 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.sql.Statement;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.MaterialStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
class MaterialInsertProcess {
static void process(PreparedStatement preparedStmt, Statement statement, int batchCount, Object name, int materialId) {
if (name instanceof String) {
String query = "SELECT id FROM " + ConfigHandler.prefix + "material_map WHERE id = '" + materialId + "' LIMIT 0, 1";
boolean hasMaterial = MaterialStatement.hasMaterial(statement, query);
if (!hasMaterial) {
MaterialStatement.insert(preparedStmt, batchCount, materialId, (String) name);
// validate ID maps to ensure mapping wasn't reloaded from database prior to this insertion completing
ConfigHandler.materials.put((String) name, materialId);
ConfigHandler.materialsReversed.put(materialId, (String) name);
if (materialId > ConfigHandler.materialId) {
ConfigHandler.materialId = materialId;
}
}
else {
Chat.console(Phrase.build(Phrase.CACHE_ERROR, "material"));
Chat.console(Phrase.build(Phrase.CACHE_RELOAD, Selector.FIRST));
ConfigHandler.loadTypes(statement);
}
}
}
}

View File

@ -0,0 +1,35 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.List;
import java.util.Map;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.database.Lookup;
import net.coreprotect.database.logger.BlockBreakLogger;
import net.coreprotect.utility.Util;
class NaturalBlockBreakProcess {
static void process(Statement statement, PreparedStatement preparedStmt, int batchCount, int processId, int id, String user, Object object, Material blockType, int blockData) {
if (object instanceof BlockState) {
BlockState block = (BlockState) object;
Map<Integer, List<BlockState>> blockLists = Consumer.consumerBlockList.get(processId);
if (blockLists.get(id) != null) {
List<BlockState> blockStateList = blockLists.get(id);
for (BlockState blockState : blockStateList) {
String removed = Lookup.whoRemovedCache(blockState);
if (removed.length() > 0) {
user = removed;
}
}
blockLists.remove(id);
BlockBreakLogger.log(preparedStmt, batchCount, user, block.getLocation(), Util.getBlockId(blockType), blockData, null, block.getBlockData().getAsString());
}
}
}
}

View File

@ -0,0 +1,24 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.util.Map;
import org.bukkit.Location;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.database.logger.ChatLogger;
class PlayerChatProcess {
static void process(PreparedStatement preparedStmt, int batchCount, int processId, int id, Object object, int time, String user) {
if (object instanceof Location) {
Map<Integer, String> strings = Consumer.consumerStrings.get(processId);
if (strings.get(id) != null) {
String message = strings.get(id);
Location location = (Location) object;
ChatLogger.log(preparedStmt, batchCount, time, location, user, message);
strings.remove(id);
}
}
}
}

View File

@ -0,0 +1,24 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.util.Map;
import org.bukkit.Location;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.database.logger.CommandLogger;
class PlayerCommandProcess {
static void process(PreparedStatement preparedStmt, int batchCount, int processId, int id, Object object, int time, String user) {
if (object instanceof Location) {
Map<Integer, String> strings = Consumer.consumerStrings.get(processId);
if (strings.get(id) != null) {
String message = strings.get(id);
Location location = (Location) object;
CommandLogger.log(preparedStmt, batchCount, time, location, user, message);
strings.remove(id);
}
}
}
}

View File

@ -0,0 +1,17 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import org.bukkit.block.BlockState;
import net.coreprotect.database.logger.PlayerInteractLogger;
class PlayerInteractionProcess {
static void process(PreparedStatement preparedStmt, int batchCount, String user, Object object) {
if (object instanceof BlockState) {
BlockState block = (BlockState) object;
PlayerInteractLogger.log(preparedStmt, batchCount, user, block);
}
}
}

View File

@ -0,0 +1,18 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import org.bukkit.block.BlockState;
import net.coreprotect.database.logger.PlayerKillLogger;
class PlayerKillProcess {
static void process(PreparedStatement preparedStmt, int batchCount, int id, Object object, String user) {
if (object instanceof Object[]) {
BlockState block = (BlockState) ((Object[]) object)[0];
String player = (String) ((Object[]) object)[1];
PlayerKillLogger.log(preparedStmt, batchCount, user, block, player);
}
}
}

View File

@ -0,0 +1,29 @@
package net.coreprotect.consumer.process;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Map;
import org.bukkit.Location;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.database.logger.PlayerSessionLogger;
import net.coreprotect.database.logger.UsernameLogger;
class PlayerLoginProcess {
static void process(Connection connection, PreparedStatement preparedStmt, int batchCount, int processId, int id, Object object, int configSessions, int configUsernames, int time, String user) {
if (object instanceof Location) {
Map<Integer, String> strings = Consumer.consumerStrings.get(processId);
if (strings.get(id) != null) {
String uuid = strings.get(id);
Location location = (Location) object;
UsernameLogger.log(connection, user, uuid, configUsernames, time);
if (configSessions == 1) {
PlayerSessionLogger.log(preparedStmt, batchCount, user, location, time, 1);
}
strings.remove(id);
}
}
}
}

View File

@ -0,0 +1,17 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import org.bukkit.Location;
import net.coreprotect.database.logger.PlayerSessionLogger;
class PlayerLogoutProcess {
static void process(PreparedStatement preparedStmt, int batchCount, Object object, int time, String user) {
if (object instanceof Location) {
Location location = (Location) object;
PlayerSessionLogger.log(preparedStmt, batchCount, user, location, time, 0);
}
}
}

View File

@ -0,0 +1,327 @@
package net.coreprotect.consumer.process;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.Material;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.database.Database;
import net.coreprotect.database.statement.UserStatement;
public class Process {
public static final int BLOCK_BREAK = 0;
public static final int BLOCK_PLACE = 1;
public static final int SIGN_TEXT = 2;
public static final int CONTAINER_BREAK = 3;
public static final int PLAYER_INTERACTION = 4;
public static final int CONTAINER_TRANSACTION = 5;
public static final int STRUCTURE_GROWTH = 6;
public static final int ROLLBACK_UPDATE = 7;
public static final int CONTAINER_ROLLBACK_UPDATE = 8;
public static final int WORLD_INSERT = 9;
public static final int SIGN_UPDATE = 10;
public static final int SKULL_UPDATE = 11;
public static final int PLAYER_CHAT = 12;
public static final int PLAYER_COMMAND = 13;
public static final int PLAYER_LOGIN = 14;
public static final int PLAYER_LOGOUT = 15;
public static final int ENTITY_KILL = 16;
public static final int ENTITY_SPAWN = 17;
public static final int HANGING_REMOVE = 18;
public static final int HANGING_SPAWN = 19;
public static final int NATURAL_BLOCK_BREAK = 20;
public static final int MATERIAL_INSERT = 21;
public static final int ART_INSERT = 22;
public static final int ENTITY_INSERT = 23;
public static final int PLAYER_KILL = 24;
public static final int BLOCKDATA_INSERT = 25;
public static final int ITEM_TRANSACTION = 26;
protected static Connection connection = null;
public static int lastLockUpdate = 0;
private static int lastConnection = 0;
private static volatile int currentConsumerSize = 0;
public static int getCurrentConsumerSize() {
return currentConsumerSize;
}
private static void validateConnection(boolean lastRun) {
try {
if (connection != null) {
int timeSinceLastConnection = ((int) (System.currentTimeMillis() / 1000L)) - lastConnection;
if ((!lastRun && timeSinceLastConnection > 900) || !connection.isValid(5) || Consumer.resetConnection) {
connection.close();
connection = null;
Consumer.resetConnection = false;
}
}
if (connection == null && ConfigHandler.serverRunning) {
connection = Database.getConnection(false, 500);
lastConnection = (int) (System.currentTimeMillis() / 1000L);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
protected static void updateLockTable(Statement statement, int locked) {
try {
int unixTimestamp = (int) (System.currentTimeMillis() / 1000L);
int timeSinceLastUpdate = unixTimestamp - lastLockUpdate;
if (timeSinceLastUpdate >= 15 || locked == 0) {
statement.executeUpdate("UPDATE " + ConfigHandler.prefix + "database_lock SET status = '" + locked + "', time = '" + unixTimestamp + "' WHERE rowid = '1'");
lastLockUpdate = unixTimestamp;
}
}
catch (Exception e) {
e.printStackTrace();
}
}
protected static void processConsumer(int processId, boolean lastRun) {
try {
// Connection
validateConnection(lastRun);
if (connection == null) {
return;
}
Consumer.isPaused = true;
Statement statement = connection.createStatement();
ArrayList<Object[]> consumerData = Consumer.consumer.get(processId);
Map<Integer, String[]> users = Consumer.consumerUsers.get(processId);
Map<Integer, Object> consumerObject = Consumer.consumerObjects.get(processId);
int consumerDataSize = consumerData.size();
currentConsumerSize = consumerDataSize;
Database.beginTransaction(statement);
// Scan through usernames, ensure everything is loaded in memory.
for (Entry<Integer, String[]> entry : users.entrySet()) {
String[] data = entry.getValue();
if (data != null) {
String user = data[0];
String uuid = data[1];
if (user != null && ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT)) == null) {
UserStatement.loadId(connection, user, uuid);
}
}
}
updateLockTable(statement, (lastRun ? 0 : 1));
Database.commitTransaction(statement);
// Create prepared statements
PreparedStatement preparedStmtSigns = Database.prepareStatement(connection, Database.SIGN, false);
PreparedStatement preparedStmtBlocks = Database.prepareStatement(connection, Database.BLOCK, false);
PreparedStatement preparedStmtSkulls = Database.prepareStatement(connection, Database.SKULL, true);
PreparedStatement preparedStmtContainers = Database.prepareStatement(connection, Database.CONTAINER, false);
PreparedStatement preparedStmtItems = Database.prepareStatement(connection, Database.ITEM, false);
PreparedStatement preparedStmtWorlds = Database.prepareStatement(connection, Database.WORLD, false);
PreparedStatement preparedStmtChat = Database.prepareStatement(connection, Database.CHAT, false);
PreparedStatement preparedStmtCommand = Database.prepareStatement(connection, Database.COMMAND, false);
PreparedStatement preparedStmtSession = Database.prepareStatement(connection, Database.SESSION, false);
PreparedStatement preparedStmtEntities = Database.prepareStatement(connection, Database.ENTITY, true);
PreparedStatement preparedStmtMaterials = Database.prepareStatement(connection, Database.MATERIAL, false);
PreparedStatement preparedStmtArt = Database.prepareStatement(connection, Database.ART, false);
PreparedStatement preparedStmtEntity = Database.prepareStatement(connection, Database.ENTITY_MAP, false);
PreparedStatement preparedStmtBlockdata = Database.prepareStatement(connection, Database.BLOCKDATA, false);
// Scan through consumer data
Database.beginTransaction(statement);
for (int i = 0; i < consumerDataSize; i++) {
Object[] data = consumerData.get(i);
if (data != null) {
int id = (Integer) data[0];
int action = (Integer) data[1];
Material blockType = (Material) data[2];
int blockData = (Integer) data[3];
Material replace_type = (Material) data[4];
int replaceData = (Integer) data[5];
int forceData = (Integer) data[6];
if (users.get(id) != null && consumerObject.get(id) != null) {
String user = users.get(id)[0];
Object object = consumerObject.get(id);
try {
switch (action) {
case Process.BLOCK_BREAK:
BlockBreakProcess.process(preparedStmtBlocks, preparedStmtSkulls, i, processId, id, blockType, blockData, replace_type, forceData, user, object, (String) data[7]);
break;
case Process.BLOCK_PLACE:
BlockPlaceProcess.process(preparedStmtBlocks, preparedStmtSkulls, i, blockType, blockData, replace_type, replaceData, forceData, user, object, (String) data[7], (String) data[8]);
break;
case Process.SIGN_TEXT:
SignTextProcess.process(preparedStmtSigns, i, processId, id, forceData, user, object, replaceData, blockData);
break;
case Process.CONTAINER_BREAK:
ContainerBreakProcess.process(preparedStmtContainers, i, processId, id, blockType, user, object);
break;
case Process.PLAYER_INTERACTION:
PlayerInteractionProcess.process(preparedStmtBlocks, i, user, object);
break;
case Process.CONTAINER_TRANSACTION:
ContainerTransactionProcess.process(preparedStmtContainers, preparedStmtItems, i, processId, id, blockType, forceData, user, object);
break;
case Process.ITEM_TRANSACTION:
ItemTransactionProcess.process(preparedStmtItems, i, processId, id, forceData, replaceData, user, object);
break;
case Process.STRUCTURE_GROWTH:
StructureGrowthProcess.process(statement, preparedStmtBlocks, i, processId, id, user, object, forceData);
break;
case Process.ROLLBACK_UPDATE:
RollbackUpdateProcess.process(statement, processId, id, forceData, 0);
break;
case Process.CONTAINER_ROLLBACK_UPDATE:
RollbackUpdateProcess.process(statement, processId, id, forceData, 1);
break;
case Process.WORLD_INSERT:
WorldInsertProcess.process(preparedStmtWorlds, i, statement, object, forceData);
break;
case Process.SIGN_UPDATE:
SignUpdateProcess.process(statement, object, user, blockData, forceData);
break;
case Process.SKULL_UPDATE:
SkullUpdateProcess.process(statement, object, forceData);
break;
case Process.PLAYER_CHAT:
PlayerChatProcess.process(preparedStmtChat, i, processId, id, object, forceData, user);
break;
case Process.PLAYER_COMMAND:
PlayerCommandProcess.process(preparedStmtCommand, i, processId, id, object, forceData, user);
break;
case Process.PLAYER_LOGIN:
PlayerLoginProcess.process(connection, preparedStmtSession, i, processId, id, object, blockData, replaceData, forceData, user);
break;
case Process.PLAYER_LOGOUT:
PlayerLogoutProcess.process(preparedStmtSession, i, object, forceData, user);
break;
case Process.ENTITY_KILL:
EntityKillProcess.process(preparedStmtBlocks, preparedStmtEntities, i, processId, id, object, user);
break;
case Process.ENTITY_SPAWN:
EntitySpawnProcess.process(statement, object, forceData);
break;
case Process.HANGING_REMOVE:
HangingRemoveProcess.process(object, forceData);
break;
case Process.HANGING_SPAWN:
HangingSpawnProcess.process(object, blockType, blockData, forceData);
break;
case Process.NATURAL_BLOCK_BREAK:
NaturalBlockBreakProcess.process(statement, preparedStmtBlocks, i, processId, id, user, object, blockType, blockData);
break;
case Process.MATERIAL_INSERT:
MaterialInsertProcess.process(preparedStmtMaterials, statement, i, object, forceData);
break;
case Process.ART_INSERT:
ArtInsertProcess.process(preparedStmtArt, statement, i, object, forceData);
break;
case Process.ENTITY_INSERT:
EntityInsertProcess.process(preparedStmtEntity, statement, i, object, forceData);
break;
case Process.PLAYER_KILL:
PlayerKillProcess.process(preparedStmtBlocks, i, id, object, user);
break;
case Process.BLOCKDATA_INSERT:
BlockDataInsertProcess.process(preparedStmtBlockdata, statement, i, object, forceData);
break;
}
// If database connection goes missing, remove processed data from consumer and abort
if (statement.isClosed()) {
for (int index = (i - 1); index >= 0; index--) {
consumerData.remove(index);
}
connection = null;
currentConsumerSize = 0;
Consumer.isPaused = false;
return;
}
// If interrupt requested, commit data, sleep, and resume processing
if (Consumer.interrupt) {
commit(statement, preparedStmtSigns, preparedStmtBlocks, preparedStmtSkulls, preparedStmtContainers, preparedStmtItems, preparedStmtWorlds, preparedStmtChat, preparedStmtCommand, preparedStmtSession, preparedStmtEntities, preparedStmtMaterials, preparedStmtArt, preparedStmtEntity, preparedStmtBlockdata);
Thread.sleep(500);
Database.beginTransaction(statement);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
currentConsumerSize--;
}
// commit data to database
commit(statement, preparedStmtSigns, preparedStmtBlocks, preparedStmtSkulls, preparedStmtContainers, preparedStmtItems, preparedStmtWorlds, preparedStmtChat, preparedStmtCommand, preparedStmtSession, preparedStmtEntities, preparedStmtMaterials, preparedStmtArt, preparedStmtEntity, preparedStmtBlockdata);
// close connections/statements
preparedStmtSigns.close();
preparedStmtBlocks.close();
preparedStmtSkulls.close();
preparedStmtContainers.close();
preparedStmtItems.close();
preparedStmtWorlds.close();
preparedStmtChat.close();
preparedStmtCommand.close();
preparedStmtSession.close();
preparedStmtEntities.close();
preparedStmtMaterials.close();
preparedStmtArt.close();
preparedStmtEntity.close();
preparedStmtBlockdata.close();
statement.close();
// clear maps
users.clear();
consumerObject.clear();
consumerData.clear();
if (lastRun) {
connection.close();
connection = null;
}
}
catch (Exception e) {
e.printStackTrace();
}
Consumer.consumer_id.put(processId, new Integer[] { 0, 0 });
Consumer.isPaused = false;
}
private static void commit(Statement statement, PreparedStatement preparedStmtSigns, PreparedStatement preparedStmtBlocks, PreparedStatement preparedStmtSkulls, PreparedStatement preparedStmtContainers, PreparedStatement preparedStmtItems, PreparedStatement preparedStmtWorlds, PreparedStatement preparedStmtChat, PreparedStatement preparedStmtCommand, PreparedStatement preparedStmtSession, PreparedStatement preparedStmtEntities, PreparedStatement preparedStmtMaterials, PreparedStatement preparedStmtArt, PreparedStatement preparedStmtEntity, PreparedStatement preparedStmtBlockdata) {
try {
preparedStmtSigns.executeBatch();
preparedStmtBlocks.executeBatch();
preparedStmtSkulls.executeBatch();
preparedStmtContainers.executeBatch();
preparedStmtItems.executeBatch();
preparedStmtWorlds.executeBatch();
preparedStmtChat.executeBatch();
preparedStmtCommand.executeBatch();
preparedStmtSession.executeBatch();
preparedStmtEntities.executeBatch();
preparedStmtMaterials.executeBatch();
preparedStmtArt.executeBatch();
preparedStmtEntity.executeBatch();
preparedStmtBlockdata.executeBatch();
Database.commitTransaction(statement);
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,26 @@
package net.coreprotect.consumer.process;
import java.sql.Statement;
import java.util.List;
import java.util.Map;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.database.Database;
class RollbackUpdateProcess {
static void process(Statement statement, int processId, int id, int action, int table) {
Map<Integer, List<Object[]>> updateLists = Consumer.consumerObjectArrayList.get(processId);
if (updateLists.get(id) != null) {
List<Object[]> list = updateLists.get(id);
for (Object[] listRow : list) {
long rowid = (Long) listRow[0];
int rolledBack = (Integer) listRow[9];
if (rolledBack == action) {
Database.performUpdate(statement, rowid, action, table);
}
}
updateLists.remove(id);
}
}
}

View File

@ -0,0 +1,24 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.util.Map;
import org.bukkit.Location;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.database.logger.SignTextLogger;
class SignTextProcess {
static void process(PreparedStatement preparedStmt, int batchCount, int processId, int id, int forceData, String user, Object object, int action, int color) {
if (object instanceof Location) {
Location location = (Location) object;
Map<Integer, Object[]> signs = Consumer.consumerSigns.get(processId);
if (signs.get(id) != null) {
Object[] SIGN_DATA = signs.get(id);
SignTextLogger.log(preparedStmt, batchCount, user, location, action, color, (Integer) SIGN_DATA[0], (String) SIGN_DATA[1], (String) SIGN_DATA[2], (String) SIGN_DATA[3], (String) SIGN_DATA[4], forceData);
signs.remove(id);
}
}
}
}

View File

@ -0,0 +1,38 @@
package net.coreprotect.consumer.process;
import java.sql.Statement;
import java.util.Locale;
import org.bukkit.block.BlockState;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.SignStatement;
import net.coreprotect.utility.Util;
class SignUpdateProcess {
static void process(Statement statement, Object object, String user, int action, int time) {
/*
* We're switching blocks around quickly.
* This block could already be removed again by the time the server tries to modify it.
* Ignore any errors.
*/
if (object instanceof BlockState) {
BlockState block = (BlockState) object;
int x = block.getX();
int y = block.getY();
int z = block.getZ();
int wid = Util.getWorldId(block.getWorld().getName());
int userid = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
String query = "";
if (action == 0) {
query = "SELECT color, data, line_1, line_2, line_3, line_4 FROM " + ConfigHandler.prefix + "sign WHERE user='" + userid + "' AND wid='" + wid + "' AND x='" + x + "' AND z='" + z + "' AND y='" + y + "' AND time < '" + time + "' ORDER BY rowid DESC LIMIT 0, 1";
}
else {
query = "SELECT color, data, line_1, line_2, line_3, line_4 FROM " + ConfigHandler.prefix + "sign WHERE user='" + userid + "' AND wid='" + wid + "' AND x='" + x + "' AND z='" + z + "' AND y='" + y + "' AND time >= '" + time + "' ORDER BY rowid ASC LIMIT 0, 1";
}
SignStatement.getData(statement, block, query);
Util.updateBlock(block);
}
}
}

View File

@ -0,0 +1,26 @@
package net.coreprotect.consumer.process;
import java.sql.Statement;
import org.bukkit.block.BlockState;
import net.coreprotect.database.statement.SkullStatement;
import net.coreprotect.utility.Util;
import net.coreprotect.config.ConfigHandler;
class SkullUpdateProcess {
static void process(Statement statement, Object object, int rowId) {
/*
* We're switching blocks around quickly.
* This block could already be removed again by the time the server tries to modify it.
* Ignore any errors.
*/
if (object instanceof BlockState) {
BlockState block = (BlockState) object;
String query = "SELECT owner FROM " + ConfigHandler.prefix + "skull WHERE rowid='" + rowId + "' LIMIT 0, 1";
SkullStatement.getData(statement, block, query);
Util.updateBlock(block);
}
}
}

View File

@ -0,0 +1,42 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.List;
import java.util.Map;
import org.bukkit.block.BlockState;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.database.Lookup;
import net.coreprotect.database.logger.BlockBreakLogger;
import net.coreprotect.database.logger.BlockPlaceLogger;
import net.coreprotect.utility.Util;
class StructureGrowthProcess {
static void process(Statement statement, PreparedStatement preparedStmt, int batchCount, int processId, int id, String user, Object object, int replaceBlockCount) {
if (object instanceof BlockState) {
BlockState block = (BlockState) object;
Map<Integer, List<BlockState>> blockLists = Consumer.consumerBlockList.get(processId);
if (blockLists.get(id) != null) {
List<BlockState> blockStates = blockLists.get(id);
String resultData = Lookup.whoPlaced(statement, block);
if (resultData.length() > 0) {
user = resultData;
}
int count = 0;
for (BlockState blockState : blockStates) {
if (count < replaceBlockCount) {
BlockBreakLogger.log(preparedStmt, batchCount, user, blockState.getLocation(), Util.getBlockId(blockState.getType()), 0, null, blockState.getBlockData().getAsString());
}
else {
BlockPlaceLogger.log(preparedStmt, batchCount, user, blockState, 0, 0, null, -1, false, null, null, null);
}
count++;
}
blockLists.remove(id);
}
}
}
}

View File

@ -0,0 +1,36 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.sql.Statement;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.MaterialStatement;
import net.coreprotect.database.statement.WorldStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
class WorldInsertProcess {
static void process(PreparedStatement preparedStmt, int batchCount, Statement statement, Object world, int worldId) {
if (world instanceof String) {
String query = "SELECT id FROM " + ConfigHandler.prefix + "world WHERE id = '" + worldId + "' LIMIT 0, 1";
boolean hasMaterial = MaterialStatement.hasMaterial(statement, query);
if (!hasMaterial) {
WorldStatement.insert(preparedStmt, batchCount, worldId, (String) world);
// validate ID maps to ensure mapping wasn't reloaded from database prior to this insertion completing
ConfigHandler.worlds.put((String) world, worldId);
ConfigHandler.worldsReversed.put(worldId, (String) world);
if (worldId > ConfigHandler.worldId) {
ConfigHandler.worldId = worldId;
}
}
else {
Chat.console(Phrase.build(Phrase.CACHE_ERROR, "world"));
Chat.console(Phrase.build(Phrase.CACHE_RELOAD, Selector.SECOND));
ConfigHandler.loadWorlds(statement);
}
}
}
}

View File

@ -0,0 +1,161 @@
package net.coreprotect.database;
import java.sql.Statement;
import java.util.Collections;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.ItemStack;
import net.coreprotect.CoreProtect;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Queue;
import net.coreprotect.language.Phrase;
import net.coreprotect.model.BlockGroup;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Util;
public class ContainerRollback extends Queue {
public static void performContainerRollbackRestore(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, String timeString, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, final Location location, Integer[] radius, int checkTime, boolean restrictWorld, boolean lookup, boolean verbose, final int rollbackType) {
try {
long startTime = System.currentTimeMillis();
final List<Object[]> lookupList = Lookup.performLookupRaw(statement, user, checkUuids, checkUsers, restrictList, excludeList, excludeUserList, actionList, location, radius, checkTime, -1, -1, restrictWorld, lookup);
if (rollbackType == 1) {
Collections.reverse(lookupList);
}
String userString = "#server";
if (user != null) {
userString = user.getName();
}
Queue.queueContainerRollbackUpdate(userString, location, lookupList, rollbackType); // Perform update transaction in consumer
final String finalUserString = userString;
ConfigHandler.rollbackHash.put(userString, new int[] { 0, 0, 0, 0 });
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(CoreProtect.getInstance(), new Runnable() {
@Override
public void run() {
try {
int[] rollbackHashData = ConfigHandler.rollbackHash.get(finalUserString);
int itemCount = rollbackHashData[0];
// int blockCount = rollbackHashData[1];
int entityCount = rollbackHashData[2];
Block block = location.getBlock();
if (!block.getWorld().isChunkLoaded(block.getChunk())) {
block.getWorld().getChunkAt(block.getLocation());
}
Object container = null;
Material type = block.getType();
if (BlockGroup.CONTAINERS.contains(type)) {
container = Util.getContainerInventory(block.getState(), false);
}
else {
for (Entity entity : block.getChunk().getEntities()) {
if (entity instanceof ArmorStand) {
if (entity.getLocation().getBlockX() == location.getBlockX() && entity.getLocation().getBlockY() == location.getBlockY() && entity.getLocation().getBlockZ() == location.getBlockZ()) {
type = Material.ARMOR_STAND;
container = Util.getEntityEquipment((LivingEntity) entity);
}
}
}
}
int modifyCount = 0;
if (container != null) {
for (Object[] lookupRow : lookupList) {
// int unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
// int rowId = lookupRow[0];
// int rowTime = (Integer)lookupRow[1];
// int rowUserId = (Integer)lookupRow[2];
// int rowX = (Integer)lookupRow[3];
// int rowY = (Integer)lookupRow[4];
// int rowZ = (Integer)lookupRow[5];
int rowTypeRaw = (Integer) lookupRow[6];
int rowData = (Integer) lookupRow[7];
int rowAction = (Integer) lookupRow[8];
int rowRolledBack = (Integer) lookupRow[9];
// int rowWid = (Integer)lookupRow[10];
int rowAmount = (Integer) lookupRow[11];
byte[] rowMetadata = (byte[]) lookupRow[12];
Material rowType = Util.getType(rowTypeRaw);
if ((rollbackType == 0 && rowRolledBack == 0) || (rollbackType == 1 && rowRolledBack == 1)) {
modifyCount = modifyCount + rowAmount;
int action = 0;
if (rollbackType == 0 && rowAction == 0) {
action = 1;
}
if (rollbackType == 1 && rowAction == 1) {
action = 1;
}
ItemStack itemstack = new ItemStack(rowType, rowAmount, (short) rowData);
Object[] populatedStack = Rollback.populateItemStack(itemstack, rowMetadata);
int slot = (Integer) populatedStack[0];
itemstack = (ItemStack) populatedStack[1];
Rollback.modifyContainerItems(type, container, slot, itemstack, action);
}
}
}
ConfigHandler.rollbackHash.put(finalUserString, new int[] { itemCount, modifyCount, entityCount, 1 });
}
catch (Exception e) {
e.printStackTrace();
}
}
}, 0);
int[] rollbackHashData = ConfigHandler.rollbackHash.get(finalUserString);
int next = rollbackHashData[3];
int sleepTime = 0;
while (next == 0) {
sleepTime = sleepTime + 5;
Thread.sleep(5);
rollbackHashData = ConfigHandler.rollbackHash.get(finalUserString);
next = rollbackHashData[3];
if (sleepTime > 300000) {
Chat.console(Phrase.build(Phrase.ROLLBACK_ABORTED));
break;
}
}
rollbackHashData = ConfigHandler.rollbackHash.get(finalUserString);
int blockCount = rollbackHashData[1];
long endTime = System.currentTimeMillis();
double totalSeconds = (endTime - startTime) / 1000.0;
if (user != null) {
int file = -1;
if (blockCount > 0) {
file = 1;
}
int itemCount = 0;
int entityCount = 0;
Rollback.finishRollbackRestore(user, location, checkUsers, restrictList, excludeList, excludeUserList, actionList, timeString, file, totalSeconds, itemCount, blockCount, entityCount, rollbackType, radius, verbose, restrictWorld, 0);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,564 @@
package net.coreprotect.database;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.consumer.Queue;
import net.coreprotect.consumer.process.Process;
import net.coreprotect.language.Phrase;
import net.coreprotect.model.BlockGroup;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class Database extends Queue {
public static final int SIGN = 0;
public static final int BLOCK = 1;
public static final int SKULL = 2;
public static final int CONTAINER = 3;
public static final int WORLD = 4;
public static final int CHAT = 5;
public static final int COMMAND = 6;
public static final int SESSION = 7;
public static final int ENTITY = 8;
public static final int MATERIAL = 9;
public static final int ART = 10;
public static final int ENTITY_MAP = 11;
public static final int BLOCKDATA = 12;
public static final int ITEM = 13;
public static void beginTransaction(Statement statement) {
Consumer.transacting = true;
try {
if (Config.getGlobal().MYSQL) {
statement.executeUpdate("START TRANSACTION");
}
else {
statement.executeUpdate("BEGIN TRANSACTION");
}
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void commitTransaction(Statement statement) throws Exception {
int count = 0;
while (true) {
try {
if (Config.getGlobal().MYSQL) {
statement.executeUpdate("COMMIT");
}
else {
statement.executeUpdate("COMMIT TRANSACTION");
}
}
catch (Exception e) {
if (e.getMessage().startsWith("[SQLITE_BUSY]") && count < 30) {
Thread.sleep(1000);
count++;
continue;
}
else {
e.printStackTrace();
}
}
Consumer.transacting = false;
Consumer.interrupt = false;
return;
}
}
public static void setMultiInt(PreparedStatement statement, int value, int count) {
try {
for (int i = 1; i <= count; i++) {
statement.setInt(i, value);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void containerBreakCheck(String user, Material type, Object container, ItemStack[] contents, Location location) {
if (BlockGroup.CONTAINERS.contains(type) && !BlockGroup.SHULKER_BOXES.contains(type)) {
if (Config.getConfig(location.getWorld()).ITEM_TRANSACTIONS) {
try {
if (contents == null) {
contents = Util.getContainerContents(type, container, location);
}
if (contents != null) {
List<ItemStack[]> forceList = new ArrayList<>();
forceList.add(Util.getContainerState(contents));
ConfigHandler.forceContainer.put(user.toLowerCase(Locale.ROOT) + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ(), forceList);
Queue.queueContainerBreak(user, location, type, contents);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static Connection getConnection(boolean onlyCheckTransacting) {
// Previously 250ms; long consumer commit time may be due to batching
// TODO: Investigate, potentially remove batching for SQLite connections
return getConnection(false, false, onlyCheckTransacting, 1000);
}
public static Connection getConnection(boolean force, int waitTime) {
return getConnection(force, false, false, waitTime);
}
public static Connection getConnection(boolean force, boolean startup, boolean onlyCheckTransacting, int waitTime) {
Connection connection = null;
try {
if (!force && (ConfigHandler.converterRunning || ConfigHandler.purgeRunning)) {
return connection;
}
if (Config.getGlobal().MYSQL) {
try {
/* Using useServerPrepStmts, cachePrepStmts, and rewriteBatchedStatements per https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration */
String database = "jdbc:mysql://" + ConfigHandler.host + ":" + ConfigHandler.port + "/" + ConfigHandler.database + "?useUnicode=true&characterEncoding=utf-8&connectTimeout=10000&useSSL=false&allowPublicKeyRetrieval=true&useCursorFetch=true&useLocalSessionState=true&rewriteBatchedStatements=true&maintainTimeStats=false";
connection = DriverManager.getConnection(database, ConfigHandler.username, ConfigHandler.password);
/* Recommended implementation per https://dev.mysql.com/doc/refman/5.0/en/charset-applications.html & https://dev.mysql.com/doc/refman/5.0/en/charset-syntax.html */
Statement statement = connection.createStatement();
statement.executeUpdate("SET NAMES 'utf8mb4'"); // COLLATE 'utf8mb4mb4_general_ci'
statement.close();
ConfigHandler.databaseReachable = true;
}
catch (Exception e) {
ConfigHandler.databaseReachable = false;
Chat.sendConsoleMessage(Color.RED + "[CoreProtect] " + Phrase.build(Phrase.MYSQL_UNAVAILABLE));
e.printStackTrace();
}
}
else {
if (Consumer.transacting && onlyCheckTransacting) {
Consumer.interrupt = true;
}
long startTime = System.nanoTime();
while (Consumer.isPaused && !force && (Consumer.transacting || !onlyCheckTransacting)) {
Thread.sleep(1);
long pauseTime = (System.nanoTime() - startTime) / 1000000;
if (pauseTime >= waitTime) {
return connection;
}
}
String database = "jdbc:sqlite:" + ConfigHandler.path + ConfigHandler.sqlite + "";
connection = DriverManager.getConnection(database);
ConfigHandler.databaseReachable = true;
}
}
catch (Exception e) {
e.printStackTrace();
}
return connection;
}
public static void performUpdate(Statement statement, long id, int action, int table) {
try {
int rolledBack = 1;
if (action == 1) {
rolledBack = 0;
}
if (table == 1) {
statement.executeUpdate("UPDATE " + ConfigHandler.prefix + "container SET rolled_back='" + rolledBack + "' WHERE rowid='" + id + "'");
}
else {
statement.executeUpdate("UPDATE " + ConfigHandler.prefix + "block SET rolled_back='" + rolledBack + "' WHERE rowid='" + id + "'");
}
}
catch (Exception e) {
e.printStackTrace();
}
}
public static PreparedStatement prepareStatement(Connection connection, int type, boolean keys) {
PreparedStatement preparedStatement = null;
try {
String signInsert = "INSERT INTO " + ConfigHandler.prefix + "sign (time, user, wid, x, y, z, action, color, data, line_1, line_2, line_3, line_4) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
String blockInsert = "INSERT INTO " + ConfigHandler.prefix + "block (time, user, wid, x, y, z, type, data, meta, blockdata, action, rolled_back) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
String skullInsert = "INSERT INTO " + ConfigHandler.prefix + "skull (time, owner) VALUES (?, ?)";
String containerInsert = "INSERT INTO " + ConfigHandler.prefix + "container (time, user, wid, x, y, z, type, data, amount, metadata, action, rolled_back) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
String itemInsert = "INSERT INTO " + ConfigHandler.prefix + "item (time, user, wid, x, y, z, type, data, amount, action) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
String worldInsert = "INSERT INTO " + ConfigHandler.prefix + "world (id, world) VALUES (?, ?)";
String chatInsert = "INSERT INTO " + ConfigHandler.prefix + "chat (time, user, wid, x, y, z, message) VALUES (?, ?, ?, ?, ?, ?, ?)";
String commandInsert = "INSERT INTO " + ConfigHandler.prefix + "command (time, user, wid, x, y, z, message) VALUES (?, ?, ?, ?, ?, ?, ?)";
String sessionInsert = "INSERT INTO " + ConfigHandler.prefix + "session (time, user, wid, x, y, z, action) VALUES (?, ?, ?, ?, ?, ?, ?)";
String entityInsert = "INSERT INTO " + ConfigHandler.prefix + "entity (time, data) VALUES (?, ?)";
String materialInsert = "INSERT INTO " + ConfigHandler.prefix + "material_map (id, material) VALUES (?, ?)";
String artInsert = "INSERT INTO " + ConfigHandler.prefix + "art_map (id, art) VALUES (?, ?)";
String entityMapInsert = "INSERT INTO " + ConfigHandler.prefix + "entity_map (id, entity) VALUES (?, ?)";
String blockdataInsert = "INSERT INTO " + ConfigHandler.prefix + "blockdata_map (id, data) VALUES (?, ?)";
switch (type) {
case SIGN:
preparedStatement = prepareStatement(connection, signInsert, keys);
break;
case BLOCK:
preparedStatement = prepareStatement(connection, blockInsert, keys);
break;
case SKULL:
preparedStatement = prepareStatement(connection, skullInsert, keys);
break;
case CONTAINER:
preparedStatement = prepareStatement(connection, containerInsert, keys);
break;
case ITEM:
preparedStatement = prepareStatement(connection, itemInsert, keys);
break;
case WORLD:
preparedStatement = prepareStatement(connection, worldInsert, keys);
break;
case CHAT:
preparedStatement = prepareStatement(connection, chatInsert, keys);
break;
case COMMAND:
preparedStatement = prepareStatement(connection, commandInsert, keys);
break;
case SESSION:
preparedStatement = prepareStatement(connection, sessionInsert, keys);
break;
case ENTITY:
preparedStatement = prepareStatement(connection, entityInsert, keys);
break;
case MATERIAL:
preparedStatement = prepareStatement(connection, materialInsert, keys);
break;
case ART:
preparedStatement = prepareStatement(connection, artInsert, keys);
break;
case ENTITY_MAP:
preparedStatement = prepareStatement(connection, entityMapInsert, keys);
break;
case BLOCKDATA:
preparedStatement = prepareStatement(connection, blockdataInsert, keys);
break;
}
}
catch (Exception e) {
e.printStackTrace();
}
return preparedStatement;
}
private static PreparedStatement prepareStatement(Connection connection, String query, boolean keys) {
PreparedStatement preparedStatement = null;
try {
if (keys) {
preparedStatement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
}
else {
preparedStatement = connection.prepareStatement(query);
}
}
catch (Exception e) {
e.printStackTrace();
}
return preparedStatement;
}
private static void initializeTables(String prefix, Statement statement) {
try {
boolean lockInitialized = false;
String query = "SELECT rowid as id FROM " + prefix + "database_lock WHERE rowid='1' LIMIT 1";
ResultSet rs = statement.executeQuery(query);
while (rs.next()) {
lockInitialized = true;
}
rs.close();
if (!lockInitialized) {
int unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
statement.executeUpdate("INSERT INTO " + prefix + "database_lock (rowid, status, time) VALUES ('1', '0', '" + unixtimestamp + "')");
Process.lastLockUpdate = 0;
}
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void createDatabaseTables(String prefix, boolean purge) {
ConfigHandler.databaseTables.clear();
ConfigHandler.databaseTables.addAll(Arrays.asList("art_map", "block", "chat", "command", "container", "item", "database_lock", "entity", "entity_map", "material_map", "blockdata_map", "session", "sign", "skull", "user", "username_log", "version", "world"));
if (Config.getGlobal().MYSQL) {
boolean success = false;
try {
Connection connection = Database.getConnection(true, true, true, 0);
if (connection != null) {
String index = "";
Statement statement = connection.createStatement();
index = ", INDEX(id)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "art_map(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),id int(8),art varchar(255)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
index = ", INDEX(wid,x,z,time), INDEX(user,time), INDEX(type,time)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "block(rowid bigint(20) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int(10), user int(8), wid int(4), x int(8), y int(3), z int(8), type int(6), data int(8), meta mediumblob, blockdata blob, action int(2), rolled_back tinyint(1)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
index = ", INDEX(time), INDEX(user,time), INDEX(wid,x,z,time)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "chat(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int(10), user int(8), wid int(4), x int(8), y int (3), z int(8), message varchar(16000)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
index = ", INDEX(time), INDEX(user,time), INDEX(wid,x,z,time)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "command(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int(10), user int(8), wid int(4), x int(8), y int (3), z int(8), message varchar(16000)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
index = ", INDEX(wid,x,z,time), INDEX(user,time), INDEX(type,time)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "container(rowid int(10) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int(10), user int(8), wid int(4), x int(8), y int(3), z int(8), type int(6), data int(6), amount int(4), metadata blob, action int(2), rolled_back tinyint(1)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
index = ", INDEX(wid,x,z,time), INDEX(user,time), INDEX(type,time)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "item(rowid int(10) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int(10), user int(8), wid int(4), x int(8), y int(3), z int(8), type int(6), data blob, amount int(4), action tinyint(1)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "database_lock(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),status tinyint(1),time int(10)) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "entity(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int(10), data blob) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
index = ", INDEX(id)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "entity_map(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),id int(8),entity varchar(255)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
index = ", INDEX(id)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "material_map(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),id int(8),material varchar(255)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
index = ", INDEX(id)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "blockdata_map(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),id int(8),data varchar(255)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
index = ", INDEX(wid,x,z,time), INDEX(action,time), INDEX(user,time), INDEX(time)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "session(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int(10), user int(8), wid int(4), x int(8), y int (3), z int(8), action int(1)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
index = ", INDEX(wid,x,z,time), INDEX(user,time), INDEX(time)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "sign(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int(10), user int(8), wid int(4), x int(8), y int(3), z int(8), action tinyint(1), color int(8), data tinyint(1), line_1 varchar(100), line_2 varchar(100), line_3 varchar(100), line_4 varchar(100)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "skull(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int(10), owner varchar(64)) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
index = ", INDEX(user), INDEX(uuid)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "user(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int(10),user varchar(100),uuid varchar(64)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
index = ", INDEX(uuid,user)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "username_log(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int(10),uuid varchar(64),user varchar(100)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "version(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int(10),version varchar(16)) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
index = ", INDEX(id)";
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "world(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),id int(8),world varchar(255)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
if (!purge) {
initializeTables(prefix, statement);
}
statement.close();
connection.close();
success = true;
}
}
catch (Exception e) {
e.printStackTrace();
}
if (!success) {
Config.getGlobal().MYSQL = false;
}
}
if (!Config.getGlobal().MYSQL) {
try {
Connection connection = Database.getConnection(true, 0);
Statement statement = connection.createStatement();
List<String> tableData = new ArrayList<>();
List<String> indexData = new ArrayList<>();
String attachDatabase = "";
if (purge) {
String query = "ATTACH DATABASE '" + ConfigHandler.path + ConfigHandler.sqlite + ".tmp' AS tmp_db";
PreparedStatement preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
preparedStmt.close();
attachDatabase = "tmp_db.";
}
String query = "SELECT type,name FROM " + attachDatabase + "sqlite_master WHERE type='table' OR type='index';";
ResultSet rs = statement.executeQuery(query);
while (rs.next()) {
String type = rs.getString("type");
if (type.equalsIgnoreCase("table")) {
tableData.add(rs.getString("name"));
}
else if (type.equalsIgnoreCase("index")) {
indexData.add(rs.getString("name"));
}
}
rs.close();
if (!tableData.contains(prefix + "art_map")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "art_map (id INTEGER, art TEXT);");
}
if (!tableData.contains(prefix + "block")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "block (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, type INTEGER, data INTEGER, meta BLOB, blockdata BLOB, action INTEGER, rolled_back INTEGER);");
}
if (!tableData.contains(prefix + "chat")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "chat (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, message TEXT);");
}
if (!tableData.contains(prefix + "command")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "command (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, message TEXT);");
}
if (!tableData.contains(prefix + "container")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "container (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, type INTEGER, data INTEGER, amount INTEGER, metadata BLOB, action INTEGER, rolled_back INTEGER);");
}
if (!tableData.contains(prefix + "item")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "item (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, type INTEGER, data BLOB, amount INTEGER, action INTEGER);");
}
if (!tableData.contains(prefix + "database_lock")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "database_lock (status INTEGER, time INTEGER);");
}
if (!tableData.contains(prefix + "entity")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "entity (id INTEGER PRIMARY KEY ASC, time INTEGER, data BLOB);");
}
if (!tableData.contains(prefix + "entity_map")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "entity_map (id INTEGER, entity TEXT);");
}
if (!tableData.contains(prefix + "material_map")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "material_map (id INTEGER, material TEXT);");
}
if (!tableData.contains(prefix + "blockdata_map")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "blockdata_map (id INTEGER, data TEXT);");
}
if (!tableData.contains(prefix + "session")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "session (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, action INTEGER);");
}
if (!tableData.contains(prefix + "sign")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "sign (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, action INTEGER, color INTEGER, data INTEGER, line_1 TEXT, line_2 TEXT, line_3 TEXT, line_4 TEXT);");
}
if (!tableData.contains(prefix + "skull")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "skull (id INTEGER PRIMARY KEY ASC, time INTEGER, owner TEXT);");
}
if (!tableData.contains(prefix + "user")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "user (id INTEGER PRIMARY KEY ASC, time INTEGER, user TEXT, uuid TEXT);");
}
if (!tableData.contains(prefix + "username_log")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "username_log (id INTEGER PRIMARY KEY ASC, time INTEGER, uuid TEXT, user TEXT);");
}
if (!tableData.contains(prefix + "version")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "version (time INTEGER, version TEXT);");
}
if (!tableData.contains(prefix + "world")) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "world (id INTEGER, world TEXT);");
}
try {
if (!indexData.contains("art_map_id_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "art_map_id_index ON " + ConfigHandler.prefix + "art_map(id);");
}
if (!indexData.contains("block_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "block_index ON " + ConfigHandler.prefix + "block(wid,x,z,time);");
}
if (!indexData.contains("block_user_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "block_user_index ON " + ConfigHandler.prefix + "block(user,time);");
}
if (!indexData.contains("block_type_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "block_type_index ON " + ConfigHandler.prefix + "block(type,time);");
}
if (!indexData.contains("blockdata_map_id_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "blockdata_map_id_index ON " + ConfigHandler.prefix + "blockdata_map(id);");
}
if (!indexData.contains("chat_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "chat_index ON " + ConfigHandler.prefix + "chat(time);");
}
if (!indexData.contains("chat_user_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "chat_user_index ON " + ConfigHandler.prefix + "chat(user,time);");
}
if (!indexData.contains("chat_wid_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "chat_wid_index ON " + ConfigHandler.prefix + "chat(wid,x,z,time);");
}
if (!indexData.contains("command_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "command_index ON " + ConfigHandler.prefix + "command(time);");
}
if (!indexData.contains("command_user_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "command_user_index ON " + ConfigHandler.prefix + "command(user,time);");
}
if (!indexData.contains("command_wid_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "command_wid_index ON " + ConfigHandler.prefix + "command(wid,x,z,time);");
}
if (!indexData.contains("container_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "container_index ON " + ConfigHandler.prefix + "container(wid,x,z,time);");
}
if (!indexData.contains("container_user_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "container_user_index ON " + ConfigHandler.prefix + "container(user,time);");
}
if (!indexData.contains("container_type_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "container_type_index ON " + ConfigHandler.prefix + "container(type,time);");
}
if (!indexData.contains("item_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "item_index ON " + ConfigHandler.prefix + "item(wid,x,z,time);");
}
if (!indexData.contains("item_user_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "item_user_index ON " + ConfigHandler.prefix + "item(user,time);");
}
if (!indexData.contains("item_type_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "item_type_index ON " + ConfigHandler.prefix + "item(type,time);");
}
if (!indexData.contains("entity_map_id_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "entity_map_id_index ON " + ConfigHandler.prefix + "entity_map(id);");
}
if (!indexData.contains("material_map_id_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "material_map_id_index ON " + ConfigHandler.prefix + "material_map(id);");
}
if (!indexData.contains("session_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "session_index ON " + ConfigHandler.prefix + "session(wid,x,z,time);");
}
if (!indexData.contains("session_action_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "session_action_index ON " + ConfigHandler.prefix + "session(action,time);");
}
if (!indexData.contains("session_user_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "session_user_index ON " + ConfigHandler.prefix + "session(user,time);");
}
if (!indexData.contains("session_time_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "session_time_index ON " + ConfigHandler.prefix + "session(time);");
}
if (!indexData.contains("sign_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "sign_index ON " + ConfigHandler.prefix + "sign(wid,x,z,time);");
}
if (!indexData.contains("sign_user_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "sign_user_index ON " + ConfigHandler.prefix + "sign(user,time);");
}
if (!indexData.contains("sign_time_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "sign_time_index ON " + ConfigHandler.prefix + "sign(time);");
}
if (!indexData.contains("user_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "user_index ON " + ConfigHandler.prefix + "user(user);");
}
if (!indexData.contains("uuid_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "uuid_index ON " + ConfigHandler.prefix + "user(uuid);");
}
if (!indexData.contains("username_log_uuid_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "username_log_uuid_index ON " + ConfigHandler.prefix + "username_log(uuid,user);");
}
if (!indexData.contains("world_id_index")) {
statement.executeUpdate("CREATE INDEX IF NOT EXISTS " + attachDatabase + "world_id_index ON " + ConfigHandler.prefix + "world(id);");
}
}
catch (Exception e) {
Chat.console(Phrase.build(Phrase.DATABASE_INDEX_ERROR));
if (purge) {
e.printStackTrace();
}
}
if (!purge) {
initializeTables(prefix, statement);
}
statement.close();
connection.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}

View File

@ -0,0 +1,781 @@
package net.coreprotect.database;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import net.coreprotect.bukkit.BukkitAdapter;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.consumer.Queue;
import net.coreprotect.database.logger.ItemLogger;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.thread.CacheHandler;
import net.coreprotect.utility.Util;
public class Lookup extends Queue {
static List<String[]> convertRawLookup(Statement statement, List<Object[]> list) {
List<String[]> newList = new ArrayList<>();
if (list == null) {
return null;
}
for (Object[] map : list) {
int newLength = map.length - 1;
String[] results = new String[newLength];
for (int i = 0; i < map.length; i++) {
try {
int newId = i - 1;
if (i == 2) {
if (map[i] instanceof Integer) {
int userId = (Integer) map[i];
if (ConfigHandler.playerIdCacheReversed.get(userId) == null) {
UserStatement.loadName(statement.getConnection(), userId);
}
String userResult = ConfigHandler.playerIdCacheReversed.get(userId);
results[newId] = userResult;
}
else {
results[newId] = (String) map[i];
}
}
else if (i == 13 && map[i] instanceof Byte[]) {
results[newId] = Util.byteDataToString((byte[]) map[i], (int) map[6]);
}
else if (i > 0) {
if (map[i] instanceof Integer) {
results[newId] = map[i].toString();
}
else if (map[i] instanceof String) {
results[newId] = (String) map[i];
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
newList.add(results);
}
return newList;
}
public static int countLookupRows(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, int checkTime, boolean restrictWorld, boolean lookup) {
int rows = 0;
try {
while (Consumer.isPaused) {
Thread.sleep(1);
}
Consumer.isPaused = true;
ResultSet results = rawLookupResultSet(statement, user, checkUuids, checkUsers, restrictList, excludeList, excludeUserList, actionList, location, radius, checkTime, -1, -1, restrictWorld, lookup, true);
while (results.next()) {
rows += results.getInt("count");
}
results.close();
}
catch (Exception e) {
e.printStackTrace();
}
Consumer.isPaused = false;
return rows;
}
public static List<String[]> performLookup(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, int checkTime, boolean restrictWorld, boolean lookup) {
List<String[]> newList = new ArrayList<>();
try {
List<Object[]> lookupList = performLookupRaw(statement, user, checkUuids, checkUsers, restrictList, excludeList, excludeUserList, actionList, location, radius, checkTime, -1, -1, restrictWorld, lookup);
newList = convertRawLookup(statement, lookupList);
}
catch (Exception e) {
e.printStackTrace();
}
return newList;
}
static List<Object[]> performLookupRaw(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, int checkTime, int limitOffset, int limitCount, boolean restrictWorld, boolean lookup) {
List<Object[]> list = new ArrayList<>();
List<Integer> invalidRollbackActions = new ArrayList<>();
invalidRollbackActions.add(2);
if (!Config.getGlobal().ROLLBACK_ENTITIES && !actionList.contains(3)) {
invalidRollbackActions.add(3);
}
try {
while (Consumer.isPaused) {
Thread.sleep(1);
}
Consumer.isPaused = true;
ResultSet results = rawLookupResultSet(statement, user, checkUuids, checkUsers, restrictList, excludeList, excludeUserList, actionList, location, radius, checkTime, limitOffset, limitCount, restrictWorld, lookup, false);
while (results.next()) {
if (actionList.contains(6) || actionList.contains(7)) {
long resultId = results.getLong("id");
int resultTime = results.getInt("time");
int resultUserId = results.getInt("user");
String resultMessage = results.getString("message");
Object[] dataArray = new Object[] { resultId, resultTime, resultUserId, resultMessage };
list.add(dataArray);
}
else if (actionList.contains(8)) {
long resultId = results.getLong("id");
int resultTime = results.getInt("time");
int resultUserId = results.getInt("user");
int resultWorldId = results.getInt("wid");
int resultX = results.getInt("x");
int resultY = results.getInt("y");
int resultZ = results.getInt("z");
int resultAction = results.getInt("action");
Object[] dataArray = new Object[] { resultId, resultTime, resultUserId, resultWorldId, resultX, resultY, resultZ, resultAction };
list.add(dataArray);
}
else if (actionList.contains(9)) {
long resultId = results.getLong("id");
int resultTime = results.getInt("time");
String resultUuid = results.getString("uuid");
String resultUser = results.getString("user");
Object[] dataArray = new Object[] { resultId, resultTime, resultUuid, resultUser };
list.add(dataArray);
}
else if (actionList.contains(10)) {
long resultId = results.getLong("id");
int resultTime = results.getInt("time");
int resultUserId = results.getInt("user");
int resultWorldId = results.getInt("wid");
int resultX = results.getInt("x");
int resultY = results.getInt("y");
int resultZ = results.getInt("z");
String line1 = results.getString("line_1");
String line2 = results.getString("line_2");
String line3 = results.getString("line_3");
String line4 = results.getString("line_4");
StringBuilder message = new StringBuilder();
if (line1 != null && line1.length() > 0) {
message.append(line1);
if (!line1.endsWith(" ")) {
message.append(" ");
}
}
if (line2 != null && line2.length() > 0) {
message.append(line2);
if (!line2.endsWith(" ")) {
message.append(" ");
}
}
if (line3 != null && line3.length() > 0) {
message.append(line3);
if (!line3.endsWith(" ")) {
message.append(" ");
}
}
if (line4 != null && line4.length() > 0) {
message.append(line4);
if (!line4.endsWith(" ")) {
message.append(" ");
}
}
Object[] dataArray = new Object[] { resultId, resultTime, resultUserId, resultWorldId, resultX, resultY, resultZ, message.toString() };
list.add(dataArray);
}
else {
int resultData = 0;
int resultAmount = -1;
byte[] resultMeta = null;
byte[] resultBlockData = null;
long resultId = results.getLong("id");
int resultUserId = results.getInt("user");
int resultAction = results.getInt("action");
int resultRolledBack = results.getInt("rolled_back");
int resultType = results.getInt("type");
int resultTime = results.getInt("time");
int resultX = results.getInt("x");
int resultY = results.getInt("y");
int resultZ = results.getInt("z");
int resultWorldId = results.getInt("wid");
if ((lookup && actionList.size() == 0) || actionList.contains(4) || actionList.contains(5) || actionList.contains(11)) {
resultData = results.getInt("data");
resultAmount = results.getInt("amount");
resultMeta = results.getBytes("metadata");
}
else {
resultData = results.getInt("data");
resultMeta = results.getBytes("meta");
resultBlockData = results.getBytes("blockdata");
}
boolean valid = true;
if (!lookup) {
if (invalidRollbackActions.contains(resultAction)) {
valid = false;
}
}
if (valid) {
Object[] dataArray = new Object[] { resultId, resultTime, resultUserId, resultX, resultY, resultZ, resultType, resultData, resultAction, resultRolledBack, resultWorldId, resultAmount, resultMeta, resultBlockData };
list.add(dataArray);
}
}
}
results.close();
}
catch (Exception e) {
e.printStackTrace();
}
Consumer.isPaused = false;
return list;
}
public static List<String[]> performPartialLookup(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, int checkTime, int limitOffset, int limitCount, boolean restrictWorld, boolean lookup) {
List<String[]> newList = new ArrayList<>();
try {
List<Object[]> lookupList = performLookupRaw(statement, user, checkUuids, checkUsers, restrictList, excludeList, excludeUserList, actionList, location, radius, checkTime, limitOffset, limitCount, restrictWorld, lookup);
newList = convertRawLookup(statement, lookupList);
}
catch (Exception e) {
e.printStackTrace();
}
return newList;
}
private static ResultSet rawLookupResultSet(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, int checkTime, int limitOffset, int limitCount, boolean restrictWorld, boolean lookup, boolean count) {
ResultSet results = null;
try {
List<Integer> validActions = Arrays.asList(0, 1, 2, 3);
if (radius != null) {
restrictWorld = true;
}
boolean validAction = false;
String queryBlock = "";
String queryEntity = "";
String queryLimit = "";
String queryTable = "block";
String action = "";
String includeBlock = "";
String includeEntity = "";
String excludeBlock = "";
String excludeEntity = "";
String users = "";
String uuids = "";
String excludeUsers = "";
String index = "";
String query = "";
if (checkUuids.size() > 0) {
String list = "";
for (String value : checkUuids) {
if (list.length() == 0) {
list = "'" + value + "'";
}
else {
list = list + ",'" + value + "'";
}
}
uuids = list;
}
if (!checkUsers.contains("#global")) {
StringBuilder checkUserText = new StringBuilder();
for (String checkUser : checkUsers) {
if (!checkUser.equals("#container")) {
if (ConfigHandler.playerIdCache.get(checkUser.toLowerCase(Locale.ROOT)) == null) {
UserStatement.loadId(statement.getConnection(), checkUser, null);
}
int userId = ConfigHandler.playerIdCache.get(checkUser.toLowerCase(Locale.ROOT));
if (checkUserText.length() == 0) {
checkUserText = checkUserText.append(userId);
}
else {
checkUserText.append(",").append(userId);
}
}
}
users = checkUserText.toString();
}
if (restrictList.size() > 0) {
StringBuilder includeListMaterial = new StringBuilder();
StringBuilder includeListEntity = new StringBuilder();
for (Object restrictTarget : restrictList) {
String targetName = "";
if (restrictTarget instanceof Material) {
targetName = ((Material) restrictTarget).name();
if (includeListMaterial.length() == 0) {
includeListMaterial = includeListMaterial.append(Util.getBlockId(targetName, false));
}
else {
includeListMaterial.append(",").append(Util.getBlockId(targetName, false));
}
/* Include legacy IDs */
int legacyId = BukkitAdapter.ADAPTER.getLegacyBlockId((Material) restrictTarget);
if (legacyId > 0) {
includeListMaterial.append(",").append(legacyId);
}
}
else if (restrictTarget instanceof EntityType) {
targetName = ((EntityType) restrictTarget).name();
if (includeListEntity.length() == 0) {
includeListEntity = includeListEntity.append(Util.getEntityId(targetName, false));
}
else {
includeListEntity.append(",").append(Util.getEntityId(targetName, false));
}
}
}
includeBlock = includeListMaterial.toString();
includeEntity = includeListEntity.toString();
}
if (excludeList.size() > 0) {
StringBuilder excludeListMaterial = new StringBuilder();
StringBuilder excludeListEntity = new StringBuilder();
for (Object restrictTarget : excludeList) {
String targetName = "";
if (restrictTarget instanceof Material) {
targetName = ((Material) restrictTarget).name();
if (excludeListMaterial.length() == 0) {
excludeListMaterial = excludeListMaterial.append(Util.getBlockId(targetName, false));
}
else {
excludeListMaterial.append(",").append(Util.getBlockId(targetName, false));
}
/* Include legacy IDs */
int legacyId = BukkitAdapter.ADAPTER.getLegacyBlockId((Material) restrictTarget);
if (legacyId > 0) {
excludeListMaterial.append(",").append(legacyId);
}
}
else if (restrictTarget instanceof EntityType) {
targetName = ((EntityType) restrictTarget).name();
if (excludeListEntity.length() == 0) {
excludeListEntity = excludeListEntity.append(Util.getEntityId(targetName, false));
}
else {
excludeListEntity.append(",").append(Util.getEntityId(targetName, false));
}
}
}
excludeBlock = excludeListMaterial.toString();
excludeEntity = excludeListEntity.toString();
}
if (excludeUserList.size() > 0) {
StringBuilder excludeUserText = new StringBuilder();
for (String excludeTarget : excludeUserList) {
if (ConfigHandler.playerIdCache.get(excludeTarget.toLowerCase(Locale.ROOT)) == null) {
UserStatement.loadId(statement.getConnection(), excludeTarget, null);
}
int userId = ConfigHandler.playerIdCache.get(excludeTarget.toLowerCase(Locale.ROOT));
if (excludeUserText.length() == 0) {
excludeUserText = excludeUserText.append(userId);
}
else {
excludeUserText.append(",").append(userId);
}
}
excludeUsers = excludeUserText.toString();
}
if (!actionList.isEmpty()) {
StringBuilder actionText = new StringBuilder();
for (Integer actionTarget : actionList) {
if (validActions.contains(actionTarget)) {
// If just looking up drops/pickups, remap the actions to the correct values
if (actionList.contains(11) && !actionList.contains(4)) {
if (actionTarget == ItemLogger.ITEM_REMOVE && !actionList.contains(ItemLogger.ITEM_DROP)) {
actionTarget = ItemLogger.ITEM_DROP;
}
else if (actionTarget == ItemLogger.ITEM_ADD && !actionList.contains(ItemLogger.ITEM_PICKUP)) {
actionTarget = ItemLogger.ITEM_PICKUP;
}
}
if (actionText.length() == 0) {
actionText = actionText.append(actionTarget);
}
else {
actionText.append(",").append(actionTarget);
}
// If selecting from co_item & co_container, add in actions for both transaction types
if (actionList.contains(11) && actionList.contains(4)) {
if (actionTarget == ItemLogger.ITEM_REMOVE) {
actionText.append(",").append(ItemLogger.ITEM_DROP);
actionText.append(",").append(ItemLogger.ITEM_ADD_ENDER);
}
if (actionTarget == ItemLogger.ITEM_ADD) {
actionText.append(",").append(ItemLogger.ITEM_PICKUP);
actionText.append(",").append(ItemLogger.ITEM_REMOVE_ENDER);
}
}
// If just looking up drops/pickups, include ender chest transactions
else if (actionList.contains(11) && !actionList.contains(4)) {
if (actionTarget == ItemLogger.ITEM_DROP) {
actionText.append(",").append(ItemLogger.ITEM_ADD_ENDER);
}
if (actionTarget == ItemLogger.ITEM_PICKUP) {
actionText.append(",").append(ItemLogger.ITEM_REMOVE_ENDER);
}
}
}
}
action = actionText.toString();
}
for (Integer value : actionList) {
if (validActions.contains(value)) {
validAction = true;
}
}
if (restrictWorld) {
int wid = Util.getWorldId(location.getWorld().getName());
queryBlock = queryBlock + " wid=" + wid + " AND";
}
if (radius != null) {
int xmin = radius[1];
int xmax = radius[2];
int ymin = radius[3];
int ymax = radius[4];
int zmin = radius[5];
int zmax = radius[6];
String queryY = "";
if (ymin > -1 && ymax > -1) {
queryY = " y >= '" + ymin + "' AND y <= '" + ymax + "' AND";
}
queryBlock = queryBlock + " x >= '" + xmin + "' AND x <= '" + xmax + "' AND z >= '" + zmin + "' AND z <= '" + zmax + "' AND" + queryY;
}
else if (actionList.contains(5)) {
int worldId = Util.getWorldId(location.getWorld().getName());
int x = (int) Math.floor(location.getX());
int z = (int) Math.floor(location.getZ());
int x2 = (int) Math.ceil(location.getX());
int z2 = (int) Math.ceil(location.getZ());
queryBlock = queryBlock + " wid=" + worldId + " AND (x = '" + x + "' OR x = '" + x2 + "') AND (z = '" + z + "' OR z = '" + z2 + "') AND y = '" + location.getBlockY() + "' AND";
}
if (validAction) {
queryBlock = queryBlock + " action IN(" + action + ") AND";
}
else if (includeBlock.length() > 0 || includeEntity.length() > 0 || excludeBlock.length() > 0 || excludeEntity.length() > 0) {
queryBlock = queryBlock + " action NOT IN(-1) AND";
}
if (includeBlock.length() > 0 || includeEntity.length() > 0) {
queryBlock = queryBlock + " type IN(" + (includeBlock.length() > 0 ? includeBlock : "0") + ") AND";
}
if (excludeBlock.length() > 0 || excludeEntity.length() > 0) {
queryBlock = queryBlock + " type NOT IN(" + (excludeBlock.length() > 0 ? excludeBlock : "0") + ") AND";
}
if (uuids.length() > 0) {
queryBlock = queryBlock + " uuid IN(" + uuids + ") AND";
}
if (users.length() > 0) {
queryBlock = queryBlock + " user IN(" + users + ") AND";
}
if (excludeUsers.length() > 0) {
queryBlock = queryBlock + " user NOT IN(" + excludeUsers + ") AND";
}
if (checkTime > 0) {
queryBlock = queryBlock + " time > '" + checkTime + "' AND";
}
if (actionList.contains(10)) {
queryBlock = queryBlock + " action = '1' AND (LENGTH(line_1) > 0 OR LENGTH(line_2) > 0 OR LENGTH(line_3) > 0 OR LENGTH(line_4) > 0) AND";
}
if (queryBlock.length() > 0) {
queryBlock = queryBlock.substring(0, queryBlock.length() - 4);
}
if (queryBlock.length() == 0) {
queryBlock = " 1";
}
queryEntity = queryBlock;
if (includeBlock.length() > 0 || includeEntity.length() > 0) {
queryEntity = queryEntity.replace("type IN(" + (includeBlock.length() > 0 ? includeBlock : "0") + ")", "type IN(" + (includeEntity.length() > 0 ? includeEntity : "0") + ")");
}
if (excludeBlock.length() > 0 || excludeEntity.length() > 0) {
queryEntity = queryEntity.replace("type NOT IN(" + (excludeBlock.length() > 0 ? excludeBlock : "0") + ")", "type NOT IN(" + (excludeEntity.length() > 0 ? excludeEntity : "0") + ")");
}
String baseQuery = (includeEntity.length() > 0 ? queryEntity : queryBlock);
if (limitOffset > -1 && limitCount > -1) {
queryLimit = " LIMIT " + limitOffset + ", " + limitCount + "";
}
String rows = "rowid as id,time,user,wid,x,y,z,action,type,data,meta,blockdata,rolled_back";
String queryOrder = " ORDER BY rowid DESC";
if (actionList.contains(4) || actionList.contains(5)) {
queryTable = "container";
rows = "rowid as id,time,user,wid,x,y,z,action,type,data,rolled_back,amount,metadata";
}
else if (actionList.contains(6) || actionList.contains(7)) {
queryTable = "chat";
rows = "rowid as id,time,user,message";
if (actionList.contains(7)) {
queryTable = "command";
}
}
else if (actionList.contains(8)) {
queryTable = "session";
rows = "rowid as id,time,user,wid,x,y,z,action";
}
else if (actionList.contains(9)) {
queryTable = "username_log";
rows = "rowid as id,time,uuid,user";
}
else if (actionList.contains(10)) {
queryTable = "sign";
rows = "rowid as id,time,user,wid,x,y,z,line_1,line_2,line_3,line_4";
}
else if (actionList.contains(11)) {
queryTable = "item";
rows = "rowid as id,time,user,wid,x,y,z,type,data as metadata,0 as data,amount,action,0 as rolled_back";
}
if (count) {
rows = "COUNT(*) as count";
queryLimit = " LIMIT 0, 3";
queryOrder = "";
}
if (Config.getGlobal().MYSQL) {
if (radius == null || users.length() > 0 || includeBlock.length() > 0 || includeEntity.length() > 0) {
// index_mysql = "IGNORE INDEX(wid) ";
if (users.length() > 0) {
// index_mysql = "IGNORE INDEX(wid,type,action) ";
}
}
if (queryTable.equals("block")) {
if (includeBlock.length() > 0 || includeEntity.length() > 0) {
index = "USE INDEX(type) ";
}
if (users.length() > 0) {
index = "USE INDEX(user) ";
}
if ((radius != null || actionList.contains(5)) || (index.equals("") && restrictWorld)) {
index = "USE INDEX(wid) ";
}
}
}
else {
if (queryTable.equals("block")) {
if (includeBlock.length() > 0 || includeEntity.length() > 0) {
index = "INDEXED BY block_type_index ";
}
if (users.length() > 0) {
index = "INDEXED BY block_user_index ";
}
if ((radius != null || actionList.contains(5)) || (index.equals("") && restrictWorld)) {
index = "INDEXED BY block_index ";
}
}
}
boolean itemLookup = (actionList.contains(4) && actionList.contains(11));
if (lookup && actionList.size() == 0) {
if (!count) {
rows = "rowid as id,time,user,wid,x,y,z,type,meta as metadata,data,-1 as amount,action,rolled_back";
}
if (includeBlock.length() > 0 || excludeBlock.length() > 0) {
baseQuery = baseQuery.replace("action NOT IN(-1)", "action NOT IN(3)"); // if block specified for include/exclude, filter out entity data
}
query = "SELECT " + rows + " FROM " + ConfigHandler.prefix + queryTable + " " + index + "WHERE" + baseQuery + " UNION ";
itemLookup = true;
}
if (itemLookup) {
if (!count) {
rows = "rowid as id,time,user,wid,x,y,z,type,metadata,data,amount,action,rolled_back";
}
query = query + "SELECT " + rows + " FROM " + ConfigHandler.prefix + "container WHERE" + queryBlock + " UNION ";
if (!count) {
rows = "rowid as id,time,user,wid,x,y,z,type,data as metadata,0 as data,amount,action,0 as rolled_back";
queryOrder = " ORDER BY time DESC, id DESC";
}
query = query + "SELECT " + rows + " FROM " + ConfigHandler.prefix + "item WHERE" + queryBlock;
}
if (query.length() == 0) {
query = "SELECT " + rows + " FROM " + ConfigHandler.prefix + queryTable + " " + index + "WHERE" + baseQuery;
}
query = query + queryOrder + queryLimit + "";
results = statement.executeQuery(query);
}
catch (Exception e) {
e.printStackTrace();
}
return results;
}
public static String whoPlaced(Statement statement, BlockState block) {
String result = "";
try {
if (block == null) {
return result;
}
int x = block.getX();
int y = block.getY();
int z = block.getZ();
int time = (int) (System.currentTimeMillis() / 1000L);
int worldId = Util.getWorldId(block.getWorld().getName());
String query = "SELECT user,type FROM " + ConfigHandler.prefix + "block WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND rolled_back = '0' AND action='1' ORDER BY rowid DESC LIMIT 0, 1";
ResultSet results = statement.executeQuery(query);
while (results.next()) {
int resultUserId = results.getInt("user");
int resultType = results.getInt("type");
if (ConfigHandler.playerIdCacheReversed.get(resultUserId) == null) {
UserStatement.loadName(statement.getConnection(), resultUserId);
}
result = ConfigHandler.playerIdCacheReversed.get(resultUserId);
if (result.length() > 0) {
Material resultMaterial = Util.getType(resultType);
CacheHandler.lookupCache.put("" + x + "." + y + "." + z + "." + worldId + "", new Object[] { time, result, resultMaterial });
}
}
results.close();
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static String whoPlacedCache(Block block) {
if (block == null) {
return "";
}
return whoPlacedCache(block.getState());
}
public static String whoPlacedCache(BlockState block) {
String result = "";
try {
if (block == null) {
return result;
}
int x = block.getX();
int y = block.getY();
int z = block.getZ();
int worldId = Util.getWorldId(block.getWorld().getName());
String cords = "" + x + "." + y + "." + z + "." + worldId + "";
Object[] data = CacheHandler.lookupCache.get(cords);
if (data != null) {
result = (String) data[1];
}
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static String whoRemovedCache(BlockState block) {
/*
* Performs a lookup on who removed a block, from memory. Only searches through the last 30 seconds of block removal data.
*/
String result = "";
try {
if (block != null) {
int x = block.getX();
int y = block.getY();
int z = block.getZ();
int worldId = Util.getWorldId(block.getWorld().getName());
String cords = "" + x + "." + y + "." + z + "." + worldId + "";
Object[] data = CacheHandler.breakCache.get(cords);
if (data != null) {
result = (String) data[1];
}
}
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
package net.coreprotect.database.logger;
import java.sql.PreparedStatement;
import java.util.List;
import java.util.Locale;
import org.bukkit.Location;
import org.bukkit.Material;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.BlockStatement;
import net.coreprotect.thread.CacheHandler;
import net.coreprotect.utility.Util;
public class BlockBreakLogger {
public static void log(PreparedStatement preparedStmt, int batchCount, String user, Location location, int type, int data, List<Object> meta, String blockData) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || location == null) {
return;
}
Material checkType = Util.getType(type);
if (checkType == null) {
return;
}
else if (checkType.equals(Material.AIR) || checkType.equals(Material.CAVE_AIR)) {
return;
}
if (!user.startsWith("#")) {
CacheHandler.spreadCache.remove(location);
}
if (checkType == Material.LECTERN) {
blockData = blockData.replaceFirst("has_book=true", "has_book=false");
}
int wid = Util.getWorldId(location.getWorld().getName());
int time = (int) (System.currentTimeMillis() / 1000L);
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
CacheHandler.breakCache.put("" + x + "." + y + "." + z + "." + wid + "", new Object[] { time, user, type });
int userId = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
BlockStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, type, data, meta, blockData, 0, 0);
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,157 @@
package net.coreprotect.database.logger;
import java.sql.PreparedStatement;
import java.util.List;
import java.util.Locale;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Bed;
import org.bukkit.block.data.type.Door;
import org.bukkit.block.data.type.Door.Hinge;
import net.coreprotect.bukkit.BukkitAdapter;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.BlockStatement;
import net.coreprotect.model.BlockGroup;
import net.coreprotect.thread.CacheHandler;
import net.coreprotect.utility.Util;
public class BlockPlaceLogger {
public static void log(PreparedStatement preparedStmt, int batchCount, String user, BlockState block, int replacedType, int replacedData, Material forceType, int forceData, boolean force, List<Object> meta, String blockData, String replaceBlockData) {
try {
if (user == null || ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
}
Material type = block.getType();
if (blockData == null && (forceType == null || (!forceType.equals(Material.WATER)) && (!forceType.equals(Material.LAVA)))) {
blockData = block.getBlockData().getAsString();
if (blockData.equals("minecraft:air")) {
blockData = null;
}
}
int data = 0;
if (forceType != null && force) {
type = forceType;
if (BukkitAdapter.ADAPTER.isItemFrame(type) || type.equals(Material.SPAWNER) || type.equals(Material.PAINTING) || type.equals(Material.SKELETON_SKULL) || type.equals(Material.SKELETON_WALL_SKULL) || type.equals(Material.WITHER_SKELETON_SKULL) || type.equals(Material.WITHER_SKELETON_WALL_SKULL) || type.equals(Material.ZOMBIE_HEAD) || type.equals(Material.ZOMBIE_WALL_HEAD) || type.equals(Material.PLAYER_HEAD) || type.equals(Material.PLAYER_WALL_HEAD) || type.equals(Material.CREEPER_HEAD) || type.equals(Material.CREEPER_WALL_HEAD) || type.equals(Material.DRAGON_HEAD) || type.equals(Material.DRAGON_WALL_HEAD) || type.equals(Material.ARMOR_STAND) || type.equals(Material.END_CRYSTAL)) {
data = forceData; // mob spawner, skull
}
else if (user.startsWith("#")) {
data = forceData;
}
}
else if (forceType != null && !type.equals(forceType)) {
type = forceType;
data = forceData;
}
if (type.equals(Material.AIR) || type.equals(Material.CAVE_AIR)) {
return;
}
int userId = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
int wid = Util.getWorldId(block.getWorld().getName());
int time = (int) (System.currentTimeMillis() / 1000L);
int x = block.getX();
int y = block.getY();
int z = block.getZ();
int dx = x;
int dy = y;
int dz = z;
Material doubletype = type;
int doubledata = data;
int logdouble = 0;
if (user.length() > 0) {
CacheHandler.lookupCache.put("" + x + "." + y + "." + z + "." + wid + "", new Object[] { time, user, type });
}
String doubleBlockData = null;
if (type.name().endsWith("_BED") || type == Material.IRON_DOOR || BlockGroup.DOORS.contains(type)) { // properly log double blocks (doors/beds)
BlockData blockStateBlockData = block.getBlockData();
if (blockStateBlockData instanceof Bed) {
Bed bed = (Bed) blockStateBlockData;
Bed.Part bedPart = bed.getPart();
BlockFace face = bed.getFacing();
int bedData = 1;
switch (face) {
case WEST:
dx = ((bedPart == Bed.Part.HEAD) ? (x + 1) : (x - 1));
bedData = 2;
break;
case EAST:
dx = ((bedPart == Bed.Part.HEAD) ? (x - 1) : (x + 1));
bedData = 3;
break;
case SOUTH:
dz = ((bedPart == Bed.Part.HEAD) ? (z - 1) : (z + 1));
bedData = 4;
break;
default:
dz = ((bedPart == Bed.Part.HEAD) ? (z + 1) : (z - 1));
break;
}
if (bedPart == Bed.Part.HEAD) {
data = 4 + bedData;
doubledata = bedData;
bed.setPart(Bed.Part.FOOT);
doubleBlockData = bed.getAsString();
}
else {
data = bedData;
doubledata = 4 + bedData;
bed.setPart(Bed.Part.HEAD);
doubleBlockData = bed.getAsString();
}
}
else if (blockStateBlockData instanceof Door) {
Door door = (Door) blockStateBlockData;
BlockFace face = door.getFacing();
Hinge hinge = door.getHinge();
switch (face) {
case EAST:
data = 0;
break;
case SOUTH:
data = 1;
break;
case WEST:
data = 2;
break;
default:
data = 3;
break;
}
if (hinge.equals(Hinge.RIGHT)) {
data = data + 4;
}
if (data < 8) {
dy = y + 1;
doubledata = data + 8;
}
}
logdouble = 1;
}
int internalType = Util.getBlockId(type.name(), true);
int internalDoubleType = Util.getBlockId(doubletype.name(), true);
if (replacedType > 0 && Util.getType(replacedType) != Material.AIR && Util.getType(replacedType) != Material.CAVE_AIR) {
BlockStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, replacedType, replacedData, null, replaceBlockData, 0, 0);
}
BlockStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, internalType, data, meta, blockData, 1, 0);
if (logdouble == 1) {
BlockStatement.insert(preparedStmt, batchCount, time, userId, wid, dx, dy, dz, internalDoubleType, doubledata, null, doubleBlockData, 1, 0);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,31 @@
package net.coreprotect.database.logger;
import java.sql.PreparedStatement;
import java.util.Locale;
import org.bukkit.Location;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.ChatStatement;
import net.coreprotect.utility.Util;
public class ChatLogger {
public static void log(PreparedStatement preparedStmt, int batchCount, int time, Location location, String user, String message) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
}
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
int wid = Util.getWorldId(location.getWorld().getName());
int userId = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
ChatStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, message);
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,34 @@
package net.coreprotect.database.logger;
import java.sql.PreparedStatement;
import java.util.Locale;
import org.bukkit.Location;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.CommandStatement;
import net.coreprotect.utility.Util;
public class CommandLogger {
public static void log(PreparedStatement preparedStmt, int batchCount, int time, Location location, String user, String message) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
}
if (ConfigHandler.blacklist.get(((message + " ").split(" "))[0].toLowerCase(Locale.ROOT)) != null) {
return;
}
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
int wid = Util.getWorldId(location.getWorld().getName());
int userId = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
CommandStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, message);
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,31 @@
package net.coreprotect.database.logger;
import java.sql.PreparedStatement;
import java.util.Locale;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.utility.Util;
public class ContainerBreakLogger {
public static void log(PreparedStatement preparedStmt, int batchCount, String player, Location l, Material type, ItemStack[] oldInventory) {
try {
Util.mergeItems(type, oldInventory);
ContainerLogger.logTransaction(preparedStmt, batchCount, player, type, oldInventory, 0, l);
String loggingContainerId = player.toLowerCase(Locale.ROOT) + "." + l.getBlockX() + "." + l.getBlockY() + "." + l.getBlockZ();
// If there was a pending chest transaction, it would have already been processed.
if (ConfigHandler.forceContainer.get(loggingContainerId) != null) {
ConfigHandler.forceContainer.remove(loggingContainerId);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,176 @@
package net.coreprotect.database.logger;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Queue;
import net.coreprotect.database.statement.ContainerStatement;
import net.coreprotect.utility.Util;
import net.coreprotect.utility.serialize.ItemMetaHandler;
public class ContainerLogger extends Queue {
public static void log(PreparedStatement preparedStmtContainer, PreparedStatement preparedStmtItems, int batchCount, String player, Material type, Object container, Location location) {
try {
ItemStack[] contents = null;
if (type.equals(Material.ARMOR_STAND)) {
EntityEquipment equipment = (EntityEquipment) container;
if (equipment != null) {
contents = Util.getArmorStandContents(equipment);
}
}
else {
Inventory inventory = (Inventory) container;
if (inventory != null) {
contents = inventory.getContents();
}
}
if (contents == null) {
return;
}
String loggingContainerId = player.toLowerCase(Locale.ROOT) + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
List<ItemStack[]> oldList = ConfigHandler.oldContainer.get(loggingContainerId);
ItemStack[] oi1 = oldList.get(0);
ItemStack[] oldInventory = Util.getContainerState(oi1);
ItemStack[] newInventory = Util.getContainerState(contents);
if (ConfigHandler.forceContainer.get(loggingContainerId) != null) {
List<ItemStack[]> forceList = ConfigHandler.forceContainer.get(loggingContainerId);
newInventory = Util.getContainerState(forceList.get(0));
int forceSize = modifyForceContainer(loggingContainerId, null);
if (forceSize == 0) {
ConfigHandler.forceContainer.remove(loggingContainerId);
}
}
else {
String transactingChestId = location.getWorld().getUID().toString() + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
if (ConfigHandler.transactingChest.get(transactingChestId) != null) {
List<Object> list = Collections.synchronizedList(new ArrayList<>(ConfigHandler.transactingChest.get(transactingChestId)));
if (list.size() > 0) {
ItemStack[] newMerge = new ItemStack[newInventory.length + list.size()];
int count = 0;
for (int i = 0; i < newInventory.length; i++) {
newMerge[i] = newInventory[i];
count++;
}
for (Object item : list) {
ItemStack addItem = null;
ItemStack removeItem = null;
if (item instanceof ItemStack) {
addItem = (ItemStack) item;
}
else if (item != null) {
addItem = ((ItemStack[]) item)[0];
removeItem = ((ItemStack[]) item)[1];
}
// item was removed by hopper, add back to state
if (addItem != null) {
newMerge[count] = addItem;
count++;
}
// item was added by hopper, remove from state
if (removeItem != null) {
for (ItemStack check : newMerge) {
if (check != null && check.isSimilar(removeItem)) {
check.setAmount(check.getAmount() - 1);
break;
}
}
}
}
newInventory = newMerge;
}
}
}
for (ItemStack oldi : oldInventory) {
for (ItemStack newi : newInventory) {
if (oldi != null && newi != null) {
if (oldi.isSimilar(newi) && !Util.isAir(oldi.getType())) { // Ignores amount
int oldAmount = oldi.getAmount();
int newAmount = newi.getAmount();
if (newAmount >= oldAmount) {
newAmount = newAmount - oldAmount;
oldi.setAmount(0);
newi.setAmount(newAmount);
}
else {
oldAmount = oldAmount - newAmount;
oldi.setAmount(oldAmount);
newi.setAmount(0);
}
}
}
}
}
Util.mergeItems(type, oldInventory);
Util.mergeItems(type, newInventory);
if (type != Material.ENDER_CHEST) {
logTransaction(preparedStmtContainer, batchCount, player, type, oldInventory, 0, location);
logTransaction(preparedStmtContainer, batchCount, player, type, newInventory, 1, location);
}
else { // pass ender chest transactions to item logger
ItemLogger.logTransaction(preparedStmtItems, batchCount, player, location, oldInventory, ItemLogger.ITEM_REMOVE_ENDER);
ItemLogger.logTransaction(preparedStmtItems, batchCount, player, location, newInventory, ItemLogger.ITEM_ADD_ENDER);
}
oldList.remove(0);
ConfigHandler.oldContainer.put(loggingContainerId, oldList);
}
catch (Exception e) {
e.printStackTrace();
}
}
protected static void logTransaction(PreparedStatement preparedStmt, int batchCount, String user, Material type, ItemStack[] items, int action, Location location) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
}
int slot = 0;
for (ItemStack item : items) {
if (item != null) {
if (item.getAmount() > 0 && !Util.isAir(item.getType())) {
// Object[] metadata = new Object[] { slot, item.getItemMeta() };
List<List<Map<String, Object>>> metadata = ItemMetaHandler.seralize(item, type, slot);
if (metadata.size() == 0) {
metadata = null;
}
int wid = Util.getWorldId(location.getWorld().getName());
int userid = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
int time = (int) (System.currentTimeMillis() / 1000L);
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
int typeId = Util.getBlockId(item.getType().name(), true);
int data = item.getDurability();
int amount = item.getAmount();
ContainerStatement.insert(preparedStmt, batchCount, time, userid, wid, x, y, z, typeId, data, amount, metadata, action, 0);
}
}
slot++;
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,40 @@
package net.coreprotect.database.logger;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;
import java.util.Locale;
import org.bukkit.block.BlockState;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.BlockStatement;
import net.coreprotect.database.statement.EntityStatement;
import net.coreprotect.utility.Util;
public class EntityKillLogger {
public static void log(PreparedStatement preparedStmt, PreparedStatement preparedStmt2, int batchCount, String user, BlockState block, List<Object> data, int type) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
}
int wid = Util.getWorldId(block.getWorld().getName());
int time = (int) (System.currentTimeMillis() / 1000L);
int x = block.getX();
int y = block.getY();
int z = block.getZ();
int userid = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
EntityStatement.insert(preparedStmt2, time, data);
ResultSet keys = preparedStmt2.getGeneratedKeys();
keys.next();
int entity_key = keys.getInt(1);
keys.close();
BlockStatement.insert(preparedStmt, batchCount, time, userid, wid, x, y, z, type, entity_key, null, null, 3, 0);
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,81 @@
package net.coreprotect.database.logger;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.ItemStatement;
import net.coreprotect.utility.Util;
import net.coreprotect.utility.serialize.ItemMetaHandler;
public class ItemLogger {
public static final int ITEM_REMOVE = 0;
public static final int ITEM_ADD = 1;
public static final int ITEM_DROP = 2;
public static final int ITEM_PICKUP = 3;
public static final int ITEM_REMOVE_ENDER = 4;
public static final int ITEM_ADD_ENDER = 5;
public static void log(PreparedStatement preparedStmt, int batchCount, Location location, String user) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
}
String loggingItemId = user.toLowerCase(Locale.ROOT) + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
List<ItemStack> dropList = ConfigHandler.itemsDrop.getOrDefault(loggingItemId, new ArrayList<>());
ItemStack[] itemDrops = new ItemStack[dropList.size()];
itemDrops = dropList.toArray(itemDrops);
dropList.clear();
List<ItemStack> pickupList = ConfigHandler.itemsPickup.getOrDefault(loggingItemId, new ArrayList<>());
ItemStack[] itemPickups = new ItemStack[pickupList.size()];
itemPickups = pickupList.toArray(itemPickups);
pickupList.clear();
Util.mergeItems(null, itemDrops);
Util.mergeItems(null, itemPickups);
logTransaction(preparedStmt, batchCount, user, location, itemDrops, ITEM_DROP);
logTransaction(preparedStmt, batchCount, user, location, itemPickups, ITEM_PICKUP);
}
catch (Exception e) {
e.printStackTrace();
}
}
protected static void logTransaction(PreparedStatement preparedStmt, int batchCount, String user, Location location, ItemStack[] items, int action) {
try {
for (ItemStack item : items) {
if (item != null && item.getAmount() > 0 && !Util.isAir(item.getType())) {
// Object[] metadata = new Object[] { slot, item.getItemMeta() };
List<List<Map<String, Object>>> data = ItemMetaHandler.seralize(item, null, 0);
if (data.size() == 0) {
data = null;
}
int wid = Util.getWorldId(location.getWorld().getName());
int userid = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
int time = (int) (System.currentTimeMillis() / 1000L);
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
int typeId = Util.getBlockId(item.getType().name(), true);
int amount = item.getAmount();
ItemStatement.insert(preparedStmt, batchCount, time, userid, wid, x, y, z, typeId, data, amount, action);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,35 @@
package net.coreprotect.database.logger;
import java.sql.PreparedStatement;
import java.util.Locale;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.BlockStatement;
import net.coreprotect.utility.Util;
public class PlayerInteractLogger {
public static void log(PreparedStatement preparedStmt, int batchCount, String user, BlockState block) {
try {
int type = Util.getBlockId(block.getType().name(), true);
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || Util.getType(type).equals(Material.AIR) || Util.getType(type).equals(Material.CAVE_AIR)) {
return;
}
int wid = Util.getWorldId(block.getWorld().getName());
int userId = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
int time = (int) (System.currentTimeMillis() / 1000L);
int x = block.getX();
int y = block.getY();
int z = block.getZ();
int data = 0;
BlockStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, type, data, null, null, 2, 0);
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,37 @@
package net.coreprotect.database.logger;
import java.sql.PreparedStatement;
import java.util.Locale;
import org.bukkit.block.BlockState;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.BlockStatement;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.utility.Util;
public class PlayerKillLogger {
public static void log(PreparedStatement preparedStmt, int batchCount, String user, BlockState block, String player) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
}
int wid = Util.getWorldId(block.getWorld().getName());
int time = (int) (System.currentTimeMillis() / 1000L);
int x = block.getX();
int y = block.getY();
int z = block.getZ();
int userId = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
if (ConfigHandler.playerIdCache.get(player.toLowerCase(Locale.ROOT)) == null) {
UserStatement.loadId(preparedStmt.getConnection(), player, null);
}
int playerId = ConfigHandler.playerIdCache.get(player.toLowerCase(Locale.ROOT));
BlockStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, 0, playerId, null, null, 3, 0);
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,31 @@
package net.coreprotect.database.logger;
import java.sql.PreparedStatement;
import java.util.Locale;
import org.bukkit.Location;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.SessionStatement;
import net.coreprotect.utility.Util;
public class PlayerSessionLogger {
public static void log(PreparedStatement preparedStmt, int batchCount, String user, Location location, int time, int action) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
}
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
int wid = Util.getWorldId(location.getWorld().getName());
int userId = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
SessionStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, action);
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,32 @@
package net.coreprotect.database.logger;
import java.sql.PreparedStatement;
import java.util.Locale;
import org.bukkit.Location;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.SignStatement;
import net.coreprotect.utility.Util;
public class SignTextLogger {
public static void log(PreparedStatement preparedStmt, int batchCount, String user, Location location, int action, int color, int data, String line1, String line2, String line3, String line4, int timeOffset) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
}
int userId = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
int wid = Util.getWorldId(location.getWorld().getName());
int time = (int) (System.currentTimeMillis() / 1000L) - timeOffset;
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
SignStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, action, color, data, line1, line2, line3, line4);
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,42 @@
package net.coreprotect.database.logger;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Locale;
import org.bukkit.block.BlockState;
import org.bukkit.block.Skull;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.SkullStatement;
import net.coreprotect.utility.Util;
public class SkullBreakLogger {
public static void log(PreparedStatement preparedStmt, PreparedStatement preparedStmt2, int batchCount, String user, BlockState block) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || block == null) {
return;
}
int time = (int) (System.currentTimeMillis() / 1000L);
int type = Util.getBlockId(block.getType().name(), true);
Skull skull = (Skull) block;
String skullOwner = "";
int skullKey = 0;
if (skull.hasOwner()) {
skullOwner = skull.getOwningPlayer().getUniqueId().toString();
SkullStatement.insert(preparedStmt2, time, skullOwner);
ResultSet keys = preparedStmt2.getGeneratedKeys();
keys.next();
skullKey = keys.getInt(1);
keys.close();
}
BlockBreakLogger.log(preparedStmt, batchCount, user, block.getLocation(), type, skullKey, null, block.getBlockData().getAsString());
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,45 @@
package net.coreprotect.database.logger;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Locale;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.block.Skull;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.SkullStatement;
public class SkullPlaceLogger {
public static void log(PreparedStatement preparedStmt, PreparedStatement preparedStmt2, int batchCount, String user, BlockState block, int replaceType, int replaceData) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || block == null) {
return;
}
int time = (int) (System.currentTimeMillis() / 1000L);
Material type = block.getType();
int skullKey = 0;
if (block instanceof Skull) {
Skull skull = (Skull) block;
String skullOwner = "";
if (skull.hasOwner()) {
skullOwner = skull.getOwningPlayer().getUniqueId().toString();
SkullStatement.insert(preparedStmt2, time, skullOwner);
ResultSet keys = preparedStmt2.getGeneratedKeys();
keys.next();
skullKey = keys.getInt(1);
keys.close();
}
}
BlockPlaceLogger.log(preparedStmt, batchCount, user, block, replaceType, replaceData, type, skullKey, true, null, null, null);
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,95 @@
package net.coreprotect.database.logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Locale;
import net.coreprotect.config.ConfigHandler;
public class UsernameLogger {
public static void log(Connection connection, String user, String uuid, int configUsernames, int time) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
}
int idRow = -1;
String userRow = null;
String query = "SELECT rowid as id, user FROM " + ConfigHandler.prefix + "user WHERE uuid = ? LIMIT 0, 1";
PreparedStatement preparedStmt = connection.prepareStatement(query);
preparedStmt.setString(1, uuid);
ResultSet rs = preparedStmt.executeQuery();
while (rs.next()) {
idRow = rs.getInt("id");
userRow = rs.getString("user").toLowerCase(Locale.ROOT);
}
rs.close();
preparedStmt.close();
boolean update = false;
if (userRow == null) {
idRow = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
update = true;
}
else if (!user.equalsIgnoreCase(userRow)) {
update = true;
}
if (update) {
preparedStmt = connection.prepareStatement("UPDATE " + ConfigHandler.prefix + "user SET user = ?, uuid = ? WHERE rowid = ?");
preparedStmt.setString(1, user);
preparedStmt.setString(2, uuid);
preparedStmt.setInt(3, idRow);
preparedStmt.executeUpdate();
preparedStmt.close();
/*
//Commented out to prevent potential issues if player manages to stay logged in with old username
if (ConfigHandler.playerIdCache.get(user_row)!=null){
int cache_id = ConfigHandler.playerIdCache.get(user_row);
if (cache_id==id_row){
ConfigHandler.playerIdCache.remove(user_row);
}
}
*/
}
else {
boolean foundUUID = false;
query = "SELECT rowid as id FROM " + ConfigHandler.prefix + "username_log WHERE uuid = ? AND user = ? LIMIT 0, 1";
PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1, uuid);
preparedStatement.setString(2, user);
rs = preparedStatement.executeQuery();
while (rs.next()) {
foundUUID = true;
}
rs.close();
preparedStatement.close();
if (!foundUUID) {
update = true;
}
}
if (update && configUsernames == 1) {
preparedStmt = connection.prepareStatement("INSERT INTO " + ConfigHandler.prefix + "username_log (time, uuid, user) VALUES (?, ?, ?)");
preparedStmt.setInt(1, time);
preparedStmt.setString(2, uuid);
preparedStmt.setString(3, user);
preparedStmt.executeUpdate();
preparedStmt.close();
}
ConfigHandler.playerIdCache.put(user.toLowerCase(Locale.ROOT), idRow);
ConfigHandler.playerIdCacheReversed.put(idRow, user);
ConfigHandler.uuidCache.put(user.toLowerCase(Locale.ROOT), uuid);
ConfigHandler.uuidCacheReversed.put(uuid, user);
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,166 @@
package net.coreprotect.database.lookup;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Locale;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.command.CommandSender;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class BlockLookup {
public static String performLookup(String command, Statement statement, BlockState block, CommandSender commandSender, int offset, int page, int limit) {
String resultText = "";
try {
if (block == null) {
return resultText;
}
if (command == null) {
if (commandSender.hasPermission("coreprotect.co")) {
command = "co";
}
else if (commandSender.hasPermission("coreprotect.core")) {
command = "core";
}
else if (commandSender.hasPermission("coreprotect.coreprotect")) {
command = "coreprotect";
}
else {
command = "co";
}
}
boolean found = false;
int x = block.getX();
int y = block.getY();
int z = block.getZ();
int time = (int) (System.currentTimeMillis() / 1000L);
int worldId = Util.getWorldId(block.getWorld().getName());
int checkTime = 0;
int count = 0;
int rowMax = page * limit;
int page_start = rowMax - limit;
if (offset > 0) {
checkTime = time - offset;
}
String blockName = block.getType().name().toLowerCase(Locale.ROOT);
String query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "block WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action IN(0,1) AND time >= '" + checkTime + "' LIMIT 0, 1";
ResultSet results = statement.executeQuery(query);
while (results.next()) {
count = results.getInt("count");
}
results.close();
int totalPages = (int) Math.ceil(count / (limit + 0.0));
query = "SELECT time,user,action,type,data,rolled_back FROM " + ConfigHandler.prefix + "block WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action IN(0,1) AND time >= '" + checkTime + "' ORDER BY rowid DESC LIMIT " + page_start + ", " + limit + "";
results = statement.executeQuery(query);
StringBuilder resultTextBuilder = new StringBuilder();
while (results.next()) {
int resultUserId = results.getInt("user");
int resultAction = results.getInt("action");
int resultType = results.getInt("type");
int resultData = results.getInt("data");
int resultTime = results.getInt("time");
int resultRolledBack = results.getInt("rolled_back");
if (ConfigHandler.playerIdCacheReversed.get(resultUserId) == null) {
UserStatement.loadName(statement.getConnection(), resultUserId);
}
String resultUser = ConfigHandler.playerIdCacheReversed.get(resultUserId);
String timeAgo = Util.getTimeSince(resultTime, time, true);
if (!found) {
resultTextBuilder = new StringBuilder(Color.WHITE + "----- " + Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "----- " + Util.getCoordinates(command, worldId, x, y, z, false, false) + "\n");
}
found = true;
Phrase phrase = Phrase.LOOKUP_BLOCK;
String selector = Selector.FIRST;
if (resultAction == 2 || resultAction == 3) {
phrase = Phrase.LOOKUP_INTERACTION; // {clicked|killed}
selector = (resultAction != 3 ? Selector.FIRST : Selector.SECOND);
}
else {
phrase = Phrase.LOOKUP_BLOCK; // {placed|broke}
selector = (resultAction != 0 ? Selector.FIRST : Selector.SECOND);
}
String rbFormat = "";
if (resultRolledBack == 1) {
rbFormat = Color.STRIKETHROUGH;
}
String target;
if (resultAction == 3) {
target = Util.getEntityType(resultType).name();
}
else {
Material resultMaterial = Util.getType(resultType);
if (resultMaterial == null) {
resultMaterial = Material.AIR;
}
target = Util.nameFilter(resultMaterial.name().toLowerCase(Locale.ROOT), resultData);
target = "minecraft:" + target.toLowerCase(Locale.ROOT);
}
if (target.length() > 0) {
target = "" + target + "";
}
// Hide "minecraft:" for now.
if (target.startsWith("minecraft:")) {
target = target.split(":")[1];
}
resultTextBuilder.append(timeAgo + " " + Color.WHITE + "- ").append(Phrase.build(phrase, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, Color.DARK_AQUA + rbFormat + target + Color.WHITE, selector)).append("\n");
}
resultText = resultTextBuilder.toString();
results.close();
if (found) {
if (count > limit) {
String pageInfo = Color.WHITE + "-----\n";
pageInfo = pageInfo + Util.getPageNavigation(command, page, totalPages) + "| " + Phrase.build(Phrase.LOOKUP_VIEW_PAGE, Color.WHITE, "/co l <page>") + "\n";
resultText = resultText + pageInfo;
}
}
else {
if (rowMax > count && count > 0) {
resultText = Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_RESULTS_PAGE, Selector.SECOND);
}
else {
// resultText = Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Color.WHITE + "No block data found at " + Color.ITALIC + "x" + x + "/y" + y + "/z" + z + ".";
resultText = Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_DATA_LOCATION, Selector.FIRST);
if (!blockName.equals("air") && !blockName.equals("cave_air")) {
resultText = Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_DATA, Color.ITALIC + block.getType().name().toLowerCase(Locale.ROOT)) + "\n";
}
}
}
ConfigHandler.lookupPage.put(commandSender.getName(), page);
ConfigHandler.lookupType.put(commandSender.getName(), 2);
ConfigHandler.lookupCommand.put(commandSender.getName(), x + "." + y + "." + z + "." + worldId + ".0." + limit);
}
catch (Exception e) {
e.printStackTrace();
}
return resultText;
}
}

View File

@ -0,0 +1,74 @@
package net.coreprotect.database.lookup;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.block.Block;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.Database;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.utility.Util;
public class BlockLookupAPI {
public static List<String[]> performLookup(Block block, int offset) {
List<String[]> result = new ArrayList<>();
try {
if (block == null) {
return result;
}
int x = block.getX();
int y = block.getY();
int z = block.getZ();
int time = (int) (System.currentTimeMillis() / 1000L);
int worldId = Util.getWorldId(block.getWorld().getName());
int checkTime = 0;
if (offset > 0) {
checkTime = time - offset;
}
Connection connection = Database.getConnection(false, 1000);
if (connection == null) {
return result;
}
Statement statement = connection.createStatement();
String query = "SELECT time,user,action,type,data,blockdata,rolled_back FROM " + ConfigHandler.prefix + "block WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND time > '" + checkTime + "' ORDER BY rowid DESC";
ResultSet results = statement.executeQuery(query);
while (results.next()) {
String resultTime = results.getString("time");
int resultUserId = results.getInt("user");
String resultAction = results.getString("action");
int resultType = results.getInt("type");
String resultData = results.getString("data");
byte[] resultBlockData = results.getBytes("blockdata");
String resultRolledBack = results.getString("rolled_back");
if (ConfigHandler.playerIdCacheReversed.get(resultUserId) == null) {
UserStatement.loadName(connection, resultUserId);
}
String resultUser = ConfigHandler.playerIdCacheReversed.get(resultUserId);
String blockData = Util.byteDataToString(resultBlockData, resultType);
String[] lookupData = new String[] { resultTime, resultUser, String.valueOf(x), String.valueOf(y), String.valueOf(z), String.valueOf(resultType), resultData, resultAction, resultRolledBack, String.valueOf(worldId), blockData };
String[] lineData = Util.toStringArray(lookupData);
result.add(lineData);
}
results.close();
statement.close();
connection.close();
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
}

View File

@ -0,0 +1,151 @@
package net.coreprotect.database.lookup;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Locale;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class ChestTransactionLookup {
public static String performLookup(String command, Statement statement, Location l, CommandSender commandSender, int page, int limit, boolean exact) {
String result = "";
try {
if (l == null) {
return result;
}
if (command == null) {
if (commandSender.hasPermission("coreprotect.co")) {
command = "co";
}
else if (commandSender.hasPermission("coreprotect.core")) {
command = "core";
}
else if (commandSender.hasPermission("coreprotect.coreprotect")) {
command = "coreprotect";
}
else {
command = "co";
}
}
boolean found = false;
int x = (int) Math.floor(l.getX());
int y = (int) Math.floor(l.getY());
int z = (int) Math.floor(l.getZ());
int x2 = (int) Math.ceil(l.getX());
int y2 = (int) Math.ceil(l.getY());
int z2 = (int) Math.ceil(l.getZ());
int time = (int) (System.currentTimeMillis() / 1000L);
int worldId = Util.getWorldId(l.getWorld().getName());
int count = 0;
int rowMax = page * limit;
int pageStart = rowMax - limit;
String query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "container WHERE wid = '" + worldId + "' AND (x = '" + x + "' OR x = '" + x2 + "') AND (z = '" + z + "' OR z = '" + z2 + "') AND y = '" + y + "' LIMIT 0, 1";
if (exact) {
query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "container WHERE wid = '" + worldId + "' AND (x = '" + l.getBlockX() + "') AND (z = '" + l.getBlockZ() + "') AND y = '" + y + "' LIMIT 0, 1";
}
ResultSet results = statement.executeQuery(query);
while (results.next()) {
count = results.getInt("count");
}
results.close();
int totalPages = (int) Math.ceil(count / (limit + 0.0));
query = "SELECT time,user,action,type,data,amount,rolled_back FROM " + ConfigHandler.prefix + "container WHERE wid = '" + worldId + "' AND (x = '" + x + "' OR x = '" + x2 + "') AND (z = '" + z + "' OR z = '" + z2 + "') AND y = '" + y + "' ORDER BY rowid DESC LIMIT " + pageStart + ", " + limit + "";
if (exact) {
query = "SELECT time,user,action,type,data,amount,rolled_back FROM " + ConfigHandler.prefix + "container WHERE wid = '" + worldId + "' AND (x = '" + l.getBlockX() + "') AND (z = '" + l.getBlockZ() + "') AND y = '" + y + "' ORDER BY rowid DESC LIMIT " + pageStart + ", " + limit + "";
}
results = statement.executeQuery(query);
StringBuilder resultBuilder = new StringBuilder();
while (results.next()) {
int resultUserId = results.getInt("user");
int resultAction = results.getInt("action");
int resultType = results.getInt("type");
int resultData = results.getInt("data");
int resultTime = results.getInt("time");
int resultAmount = results.getInt("amount");
int resultRolledBack = results.getInt("rolled_back");
if (ConfigHandler.playerIdCacheReversed.get(resultUserId) == null) {
UserStatement.loadName(statement.getConnection(), resultUserId);
}
String resultUser = ConfigHandler.playerIdCacheReversed.get(resultUserId);
String timeAgo = Util.getTimeSince(resultTime, time, true);
if (!found) {
resultBuilder = new StringBuilder(Color.WHITE + "----- " + Color.DARK_AQUA + Phrase.build(Phrase.CONTAINER_HEADER) + Color.WHITE + " ----- " + Util.getCoordinates(command, worldId, x, y, z, false, false) + "\n");
}
found = true;
String selector = (resultAction != 0 ? Selector.FIRST : Selector.SECOND);
String rbFormat = "";
if (resultRolledBack == 1) {
rbFormat = Color.STRIKETHROUGH;
}
Material resultMaterial = Util.getType(resultType);
if (resultMaterial == null) {
resultMaterial = Material.AIR;
}
String target = resultMaterial.name().toLowerCase(Locale.ROOT);
target = Util.nameFilter(target, resultData);
if (target.length() > 0) {
target = "minecraft:" + target.toLowerCase(Locale.ROOT) + "";
}
// Hide "minecraft:" for now.
if (target.startsWith("minecraft:")) {
target = target.split(":")[1];
}
resultBuilder.append(timeAgo + " " + Color.WHITE + "- ").append(Phrase.build(Phrase.LOOKUP_CONTAINER, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, "x" + resultAmount, Color.DARK_AQUA + rbFormat + target + Color.WHITE, selector)).append("\n");
}
result = resultBuilder.toString();
results.close();
if (found) {
if (count > limit) {
String pageInfo = Color.WHITE + "-----\n";
pageInfo = pageInfo + Util.getPageNavigation(command, page, totalPages) + "| " + Phrase.build(Phrase.LOOKUP_VIEW_PAGE, Color.WHITE, "/co l <page>") + "\n";
result = result + pageInfo;
}
}
else {
if (rowMax > count && count > 0) {
result = Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_RESULTS_PAGE, Selector.SECOND);
}
else {
result = Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_DATA_LOCATION, Selector.SECOND);
}
}
ConfigHandler.lookupType.put(commandSender.getName(), 1);
ConfigHandler.lookupPage.put(commandSender.getName(), page);
ConfigHandler.lookupCommand.put(commandSender.getName(), x + "." + y + "." + z + "." + worldId + "." + x2 + "." + y2 + "." + z2 + "." + limit);
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
}

View File

@ -0,0 +1,143 @@
package net.coreprotect.database.lookup;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Locale;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.command.CommandSender;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class InteractionLookup {
public static String performLookup(String command, Statement statement, Block block, CommandSender commandSender, int offset, int page, int limit) {
String result = "";
try {
if (block == null) {
return result;
}
if (command == null) {
if (commandSender.hasPermission("coreprotect.co")) {
command = "co";
}
else if (commandSender.hasPermission("coreprotect.core")) {
command = "core";
}
else if (commandSender.hasPermission("coreprotect.coreprotect")) {
command = "coreprotect";
}
else {
command = "co";
}
}
boolean found = false;
int x = block.getX();
int y = block.getY();
int z = block.getZ();
int time = (int) (System.currentTimeMillis() / 1000L);
int worldId = Util.getWorldId(block.getWorld().getName());
int checkTime = 0;
int count = 0;
int rowMax = page * limit;
int pageStart = rowMax - limit;
if (offset > 0) {
checkTime = time - offset;
}
String query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "block WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action='2' AND time >= '" + checkTime + "' LIMIT 0, 1";
ResultSet results = statement.executeQuery(query);
while (results.next()) {
count = results.getInt("count");
}
results.close();
int totalPages = (int) Math.ceil(count / (limit + 0.0));
query = "SELECT time,user,action,type,data,rolled_back FROM " + ConfigHandler.prefix + "block WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action='2' AND time >= '" + checkTime + "' ORDER BY rowid DESC LIMIT " + pageStart + ", " + limit + "";
results = statement.executeQuery(query);
StringBuilder resultBuilder = new StringBuilder();
while (results.next()) {
int resultUserId = results.getInt("user");
int resultAction = results.getInt("action");
int resultType = results.getInt("type");
int resultData = results.getInt("data");
int resultTime = results.getInt("time");
int resultRolledBack = results.getInt("rolled_back");
if (ConfigHandler.playerIdCacheReversed.get(resultUserId) == null) {
UserStatement.loadName(statement.getConnection(), resultUserId);
}
String resultUser = ConfigHandler.playerIdCacheReversed.get(resultUserId);
String timeAgo = Util.getTimeSince(resultTime, time, true);
if (!found) {
resultBuilder = new StringBuilder(Color.WHITE + "----- " + Color.DARK_AQUA + Phrase.build(Phrase.INTERACTIONS_HEADER) + Color.WHITE + " ----- " + Util.getCoordinates(command, worldId, x, y, z, false, false) + "\n");
}
found = true;
String rbFormat = "";
if (resultRolledBack == 1) {
rbFormat = Color.STRIKETHROUGH;
}
Material resultMaterial = Util.getType(resultType);
if (resultMaterial == null) {
resultMaterial = Material.AIR;
}
String target = resultMaterial.name().toLowerCase(Locale.ROOT);
target = Util.nameFilter(target, resultData);
if (target.length() > 0) {
target = "minecraft:" + target.toLowerCase(Locale.ROOT) + "";
}
// Hide "minecraft:" for now.
if (target.startsWith("minecraft:")) {
target = target.split(":")[1];
}
resultBuilder.append(timeAgo + " " + Color.WHITE + "- ").append(Phrase.build(Phrase.LOOKUP_INTERACTION, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, Color.DARK_AQUA + rbFormat + target + Color.WHITE, Selector.FIRST)).append("\n");
}
result = resultBuilder.toString();
results.close();
if (found) {
if (count > limit) {
String pageInfo = Color.WHITE + "-----\n";
pageInfo = pageInfo + Util.getPageNavigation(command, page, totalPages) + "| " + Phrase.build(Phrase.LOOKUP_VIEW_PAGE, Color.WHITE, "/co l <page>") + "\n";
result = result + pageInfo;
}
}
else {
if (rowMax > count && count > 0) {
result = Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_RESULTS_PAGE, Selector.SECOND);
}
else {
result = Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_DATA_LOCATION, Selector.THIRD);
}
}
ConfigHandler.lookupPage.put(commandSender.getName(), page);
ConfigHandler.lookupType.put(commandSender.getName(), 7);
ConfigHandler.lookupCommand.put(commandSender.getName(), x + "." + y + "." + z + "." + worldId + ".2." + limit);
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
}

View File

@ -0,0 +1,58 @@
package net.coreprotect.database.lookup;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Locale;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
public class PlayerLookup {
public static boolean playerExists(Connection connection, String user) {
try {
int id = -1;
String uuid = null;
if (ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT)) != null) {
return true;
}
String collate = "";
if (!Config.getGlobal().MYSQL) {
collate = " COLLATE NOCASE";
}
String query = "SELECT rowid as id, uuid FROM " + ConfigHandler.prefix + "user WHERE user = ?" + collate + " LIMIT 0, 1";
PreparedStatement preparedStmt = connection.prepareStatement(query);
preparedStmt.setString(1, user);
ResultSet results = preparedStmt.executeQuery();
while (results.next()) {
id = results.getInt("id");
uuid = results.getString("uuid");
}
results.close();
preparedStmt.close();
if (id > -1) {
if (uuid != null) {
ConfigHandler.uuidCache.put(user.toLowerCase(Locale.ROOT), uuid);
ConfigHandler.uuidCacheReversed.put(uuid, user);
}
ConfigHandler.playerIdCache.put(user.toLowerCase(Locale.ROOT), id);
ConfigHandler.playerIdCacheReversed.put(id, user);
return true;
}
}
catch (Exception e) {
e.printStackTrace();
}
return false;
}
}

View File

@ -0,0 +1,141 @@
package net.coreprotect.database.lookup;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class SignMessageLookup {
public static List<String> performLookup(String command, Statement statement, Location l, CommandSender commandSender, int page, int limit) {
List<String> result = new ArrayList<>();
try {
if (l == null) {
return result;
}
if (command == null) {
if (commandSender.hasPermission("coreprotect.co")) {
command = "co";
}
else if (commandSender.hasPermission("coreprotect.core")) {
command = "core";
}
else if (commandSender.hasPermission("coreprotect.coreprotect")) {
command = "coreprotect";
}
else {
command = "co";
}
}
boolean found = false;
int x = l.getBlockX();
int y = l.getBlockY();
int z = l.getBlockZ();
int time = (int) (System.currentTimeMillis() / 1000L);
int worldId = Util.getWorldId(l.getWorld().getName());
int count = 0;
int rowMax = page * limit;
int pageStart = rowMax - limit;
String query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "sign WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action = '1' AND (LENGTH(line_1) > 0 OR LENGTH(line_2) > 0 OR LENGTH(line_3) > 0 OR LENGTH(line_4) > 0) LIMIT 0, 1";
ResultSet results = statement.executeQuery(query);
while (results.next()) {
count = results.getInt("count");
}
results.close();
int totalPages = (int) Math.ceil(count / (limit + 0.0));
query = "SELECT time,user,line_1,line_2,line_3,line_4 FROM " + ConfigHandler.prefix + "sign WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action = '1' AND (LENGTH(line_1) > 0 OR LENGTH(line_2) > 0 OR LENGTH(line_3) > 0 OR LENGTH(line_4) > 0) ORDER BY rowid DESC LIMIT " + pageStart + ", " + limit + "";
results = statement.executeQuery(query);
while (results.next()) {
int resultTime = results.getInt("time");
int resultUserId = results.getInt("user");
String line1 = results.getString("line_1");
String line2 = results.getString("line_2");
String line3 = results.getString("line_3");
String line4 = results.getString("line_4");
StringBuilder message = new StringBuilder();
if (line1 != null && line1.length() > 0) {
message.append(line1);
if (!line1.endsWith(" ")) {
message.append(" ");
}
}
if (line2 != null && line2.length() > 0) {
message.append(line2);
if (!line2.endsWith(" ")) {
message.append(" ");
}
}
if (line3 != null && line3.length() > 0) {
message.append(line3);
if (!line3.endsWith(" ")) {
message.append(" ");
}
}
if (line4 != null && line4.length() > 0) {
message.append(line4);
if (!line4.endsWith(" ")) {
message.append(" ");
}
}
if (ConfigHandler.playerIdCacheReversed.get(resultUserId) == null) {
UserStatement.loadName(statement.getConnection(), resultUserId);
}
String resultUser = ConfigHandler.playerIdCacheReversed.get(resultUserId);
String timeAgo = Util.getTimeSince(resultTime, time, true);
if (!found) {
result.add(new StringBuilder(Color.WHITE + "----- " + Color.DARK_AQUA + Phrase.build(Phrase.SIGN_HEADER) + Color.WHITE + " ----- " + Util.getCoordinates(command, worldId, x, y, z, false, false) + "").toString());
}
found = true;
result.add(timeAgo + Color.WHITE + " - " + Color.DARK_AQUA + resultUser + ": " + Color.WHITE + "\n" + message.toString() + Color.WHITE);
}
results.close();
if (found) {
if (count > limit) {
result.add(Color.WHITE + "-----");
result.add(Util.getPageNavigation(command, page, totalPages) + "| " + Phrase.build(Phrase.LOOKUP_VIEW_PAGE, Color.WHITE, "/co l <page>"));
}
}
else {
if (rowMax > count && count > 0) {
result.add(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_RESULTS_PAGE, Selector.SECOND));
}
else {
result.add(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_DATA_LOCATION, Selector.FOURTH));
}
}
ConfigHandler.lookupType.put(commandSender.getName(), 8);
ConfigHandler.lookupPage.put(commandSender.getName(), page);
ConfigHandler.lookupCommand.put(commandSender.getName(), x + "." + y + "." + z + "." + worldId + ".8." + limit);
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
}

View File

@ -0,0 +1,41 @@
package net.coreprotect.database.statement;
import java.sql.PreparedStatement;
import java.util.List;
import net.coreprotect.utility.Util;
public class BlockStatement {
public static void insert(PreparedStatement preparedStmt, int batchCount, int time, int id, int wid, int x, int y, int z, int type, int data, List<Object> meta, String blockData, int action, int rolledBack) {
try {
byte[] bBlockData = Util.stringToByteData(blockData, type);
byte[] byteData = null;
if (meta != null) {
byteData = Util.convertByteData(meta);
}
preparedStmt.setInt(1, time);
preparedStmt.setInt(2, id);
preparedStmt.setInt(3, wid);
preparedStmt.setInt(4, x);
preparedStmt.setInt(5, y);
preparedStmt.setInt(6, z);
preparedStmt.setInt(7, type);
preparedStmt.setInt(8, data);
preparedStmt.setObject(9, byteData);
preparedStmt.setObject(10, bBlockData);
preparedStmt.setInt(11, action);
preparedStmt.setInt(12, rolledBack);
preparedStmt.addBatch();
if (batchCount > 0 && batchCount % 1000 == 0) {
preparedStmt.executeBatch();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,26 @@
package net.coreprotect.database.statement;
import java.sql.PreparedStatement;
public class ChatStatement {
public static void insert(PreparedStatement preparedStmt, int batchCount, int time, int user, int wid, int x, int y, int z, String message) {
try {
preparedStmt.setInt(1, time);
preparedStmt.setInt(2, user);
preparedStmt.setInt(3, wid);
preparedStmt.setInt(4, x);
preparedStmt.setInt(5, y);
preparedStmt.setInt(6, z);
preparedStmt.setString(7, message);
preparedStmt.addBatch();
if (batchCount > 0 && batchCount % 1000 == 0) {
preparedStmt.executeBatch();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,26 @@
package net.coreprotect.database.statement;
import java.sql.PreparedStatement;
public class CommandStatement {
public static void insert(PreparedStatement preparedStmt, int batchCount, int time, int user, int wid, int x, int y, int z, String message) {
try {
preparedStmt.setInt(1, time);
preparedStmt.setInt(2, user);
preparedStmt.setInt(3, wid);
preparedStmt.setInt(4, x);
preparedStmt.setInt(5, y);
preparedStmt.setInt(6, z);
preparedStmt.setString(7, message);
preparedStmt.addBatch();
if (batchCount > 0 && batchCount % 1000 == 0) {
preparedStmt.executeBatch();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,34 @@
package net.coreprotect.database.statement;
import java.sql.PreparedStatement;
import net.coreprotect.utility.Util;
public class ContainerStatement {
public static void insert(PreparedStatement preparedStmt, int batchCount, int time, int id, int wid, int x, int y, int z, int type, int data, int amount, Object metadata, int action, int rolledBack) {
try {
byte[] byteData = Util.convertByteData(metadata);
preparedStmt.setInt(1, time);
preparedStmt.setInt(2, id);
preparedStmt.setInt(3, wid);
preparedStmt.setInt(4, x);
preparedStmt.setInt(5, y);
preparedStmt.setInt(6, z);
preparedStmt.setInt(7, type);
preparedStmt.setInt(8, data);
preparedStmt.setInt(9, amount);
preparedStmt.setObject(10, byteData);
preparedStmt.setInt(11, action);
preparedStmt.setInt(12, rolledBack);
preparedStmt.addBatch();
if (batchCount > 0 && batchCount % 1000 == 0) {
preparedStmt.executeBatch();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,60 @@
package net.coreprotect.database.statement;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.block.BlockState;
import org.bukkit.util.io.BukkitObjectInputStream;
import org.bukkit.util.io.BukkitObjectOutputStream;
public class EntityStatement {
public static void insert(PreparedStatement preparedStmt, int time, List<Object> data) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
BukkitObjectOutputStream oos = new BukkitObjectOutputStream(bos);
oos.writeObject(data);
oos.flush();
oos.close();
bos.close();
byte[] byte_data = bos.toByteArray();
preparedStmt.setInt(1, time);
preparedStmt.setObject(2, byte_data);
preparedStmt.executeUpdate();
}
catch (Exception e) {
e.printStackTrace();
}
}
public static List<Object> getData(Statement statement, BlockState block, String query) {
List<Object> result = new ArrayList<>();
try {
ResultSet resultSet = statement.executeQuery(query);
while (resultSet.next()) {
byte[] data = resultSet.getBytes("data");
ByteArrayInputStream bais = new ByteArrayInputStream(data);
BukkitObjectInputStream ins = new BukkitObjectInputStream(bais);
@SuppressWarnings("unchecked")
List<Object> input = (List<Object>) ins.readObject();
ins.close();
bais.close();
result = input;
}
resultSet.close();
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
}

View File

@ -0,0 +1,32 @@
package net.coreprotect.database.statement;
import java.sql.PreparedStatement;
import net.coreprotect.utility.Util;
public class ItemStatement {
public static void insert(PreparedStatement preparedStmt, int batchCount, int time, int id, int wid, int x, int y, int z, int type, Object data, int amount, int action) {
try {
byte[] byteData = Util.convertByteData(data);
preparedStmt.setInt(1, time);
preparedStmt.setInt(2, id);
preparedStmt.setInt(3, wid);
preparedStmt.setInt(4, x);
preparedStmt.setInt(5, y);
preparedStmt.setInt(6, z);
preparedStmt.setInt(7, type);
preparedStmt.setObject(8, byteData);
preparedStmt.setInt(9, amount);
preparedStmt.setInt(10, action);
preparedStmt.addBatch();
if (batchCount > 0 && batchCount % 1000 == 0) {
preparedStmt.executeBatch();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,40 @@
package net.coreprotect.database.statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
public class MaterialStatement {
public static void insert(PreparedStatement preparedStmt, int batchCount, int id, String name) {
try {
preparedStmt.setInt(1, id);
preparedStmt.setString(2, name);
preparedStmt.addBatch();
if (batchCount > 0 && batchCount % 1000 == 0) {
preparedStmt.executeBatch();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
public static boolean hasMaterial(Statement statement, String query) {
boolean result = false;
try {
ResultSet resultSet = statement.executeQuery(query);
if (resultSet.next()) {
result = true;
}
resultSet.close();
}
catch (Exception e) {
e.printStackTrace();
}
return result;
}
}

View File

@ -0,0 +1,26 @@
package net.coreprotect.database.statement;
import java.sql.PreparedStatement;
public class SessionStatement {
public static void insert(PreparedStatement preparedStmt, int batchCount, int time, int user, int wid, int x, int y, int z, int action) {
try {
preparedStmt.setInt(1, time);
preparedStmt.setInt(2, user);
preparedStmt.setInt(3, wid);
preparedStmt.setInt(4, x);
preparedStmt.setInt(5, y);
preparedStmt.setInt(6, z);
preparedStmt.setInt(7, action);
preparedStmt.addBatch();
if (batchCount > 0 && batchCount % 1000 == 0) {
preparedStmt.executeBatch();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,79 @@
package net.coreprotect.database.statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import org.bukkit.Color;
import org.bukkit.DyeColor;
import org.bukkit.block.BlockState;
import org.bukkit.block.Sign;
import net.coreprotect.bukkit.BukkitAdapter;
public class SignStatement {
public static void insert(PreparedStatement preparedStmt, int batchCount, int time, int id, int wid, int x, int y, int z, int action, int color, int data, String line1, String line2, String line3, String line4) {
try {
preparedStmt.setInt(1, time);
preparedStmt.setInt(2, id);
preparedStmt.setInt(3, wid);
preparedStmt.setInt(4, x);
preparedStmt.setInt(5, y);
preparedStmt.setInt(6, z);
preparedStmt.setInt(7, action);
preparedStmt.setInt(8, color);
preparedStmt.setInt(9, data);
preparedStmt.setString(10, line1);
preparedStmt.setString(11, line2);
preparedStmt.setString(12, line3);
preparedStmt.setString(13, line4);
preparedStmt.addBatch();
if (batchCount > 0 && batchCount % 1000 == 0) {
preparedStmt.executeBatch();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void getData(Statement statement, BlockState block, String query) {
try {
if (!(block instanceof Sign)) {
return;
}
Sign sign = (Sign) block;
ResultSet resultSet = statement.executeQuery(query);
while (resultSet.next()) {
int color = resultSet.getInt("color");
int data = resultSet.getInt("data");
String line1 = resultSet.getString("line_1");
String line2 = resultSet.getString("line_2");
String line3 = resultSet.getString("line_3");
String line4 = resultSet.getString("line_4");
if (color > 0) {
sign.setColor(DyeColor.getByColor(Color.fromRGB(color)));
}
if (data > 0) {
BukkitAdapter.ADAPTER.setGlowing(sign, (data == 1 ? true : false));
}
sign.setLine(0, line1);
sign.setLine(1, line2);
sign.setLine(2, line3);
sign.setLine(3, line4);
}
resultSet.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,47 @@
package net.coreprotect.database.statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.block.BlockState;
import org.bukkit.block.Skull;
public class SkullStatement {
public static void insert(PreparedStatement preparedStmt, int time, String owner) {
try {
preparedStmt.setInt(1, time);
preparedStmt.setString(2, owner);
preparedStmt.executeUpdate();
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void getData(Statement statement, BlockState block, String query) {
try {
if (!(block instanceof Skull)) {
return;
}
Skull skull = (Skull) block;
ResultSet resultSet = statement.executeQuery(query);
while (resultSet.next()) {
String owner = resultSet.getString("owner");
if (owner != null && owner.length() >= 32) {
skull.setOwningPlayer(Bukkit.getOfflinePlayer(UUID.fromString(owner)));
}
}
resultSet.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,119 @@
package net.coreprotect.database.statement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Locale;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
public class UserStatement {
public static int insert(Connection connection, String user) {
int id = -1;
try {
int unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
PreparedStatement preparedStmt = connection.prepareStatement("INSERT INTO " + ConfigHandler.prefix + "user (time, user) VALUES (?, ?)", Statement.RETURN_GENERATED_KEYS);
preparedStmt.setInt(1, unixtimestamp);
preparedStmt.setString(2, user);
preparedStmt.executeUpdate();
ResultSet keys = preparedStmt.getGeneratedKeys();
keys.next();
id = keys.getInt(1);
keys.close();
preparedStmt.close();
}
catch (Exception e) {
e.printStackTrace();
}
return id;
}
public static int loadId(Connection connection, String user, String uuid) {
// generate if doesn't exist
int id = -1;
try {
String collate = "";
if (!Config.getGlobal().MYSQL) {
collate = " COLLATE NOCASE";
}
String where = "user = ?" + collate;
if (uuid != null) {
where = where + " OR uuid = ?";
}
String query = "SELECT rowid as id, uuid FROM " + ConfigHandler.prefix + "user WHERE " + where + " ORDER BY rowid ASC LIMIT 0, 1";
PreparedStatement preparedStmt = connection.prepareStatement(query);
preparedStmt.setString(1, user);
if (uuid != null) {
preparedStmt.setString(2, uuid);
}
ResultSet resultSet = preparedStmt.executeQuery();
while (resultSet.next()) {
id = resultSet.getInt("id");
uuid = resultSet.getString("uuid");
}
resultSet.close();
preparedStmt.close();
if (id == -1) {
id = insert(connection, user);
}
ConfigHandler.playerIdCache.put(user.toLowerCase(Locale.ROOT), id);
ConfigHandler.playerIdCacheReversed.put(id, user);
if (uuid != null) {
ConfigHandler.uuidCache.put(user.toLowerCase(Locale.ROOT), uuid);
ConfigHandler.uuidCacheReversed.put(uuid, user);
}
}
catch (Exception e) {
e.printStackTrace();
}
return id;
}
public static String loadName(Connection connection, int id) {
// generate if doesn't exist
String user = "";
String uuid = null;
try {
Statement statement = connection.createStatement();
String query = "SELECT user, uuid FROM " + ConfigHandler.prefix + "user WHERE rowid='" + id + "' LIMIT 0, 1";
ResultSet resultSet = statement.executeQuery(query);
while (resultSet.next()) {
user = resultSet.getString("user");
uuid = resultSet.getString("uuid");
}
if (user.length() == 0) {
return user;
}
ConfigHandler.playerIdCache.put(user.toLowerCase(Locale.ROOT), id);
ConfigHandler.playerIdCacheReversed.put(id, user);
if (uuid != null) {
ConfigHandler.uuidCache.put(user.toLowerCase(Locale.ROOT), uuid);
ConfigHandler.uuidCacheReversed.put(uuid, user);
}
resultSet.close();
statement.close();
}
catch (Exception e) {
e.printStackTrace();
}
return user;
}
}

View File

@ -0,0 +1,21 @@
package net.coreprotect.database.statement;
import java.sql.PreparedStatement;
public class WorldStatement {
public static void insert(PreparedStatement preparedStmt, int batchCount, int id, String world) {
try {
preparedStmt.setInt(1, id);
preparedStmt.setString(2, world);
preparedStmt.addBatch();
if (batchCount > 0 && batchCount % 1000 == 0) {
preparedStmt.executeBatch();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,232 @@
package net.coreprotect.language;
import java.util.concurrent.ConcurrentHashMap;
public class Language {
private static ConcurrentHashMap<Phrase, String> phrases = new ConcurrentHashMap<>();
private static ConcurrentHashMap<Phrase, String> userPhrases = new ConcurrentHashMap<>();
private static ConcurrentHashMap<Phrase, String> translatedPhrases = new ConcurrentHashMap<>();
protected static String getPhrase(Phrase phrase) {
return phrases.get(phrase);
}
protected static String getUserPhrase(Phrase phrase) {
return userPhrases.get(phrase);
}
protected static String getTranslatedPhrase(Phrase phrase) {
return translatedPhrases.get(phrase);
}
protected static void setUserPhrase(Phrase phrase, String value) {
userPhrases.put(phrase, value);
}
protected static void setTranslatedPhrase(Phrase phrase, String value) {
translatedPhrases.put(phrase, value);
}
public static void loadPhrases() {
phrases.put(Phrase.ACTION_NOT_SUPPORTED, "That action is not supported by the command.");
phrases.put(Phrase.AMOUNT_BLOCK, "{0} {block|blocks}");
phrases.put(Phrase.AMOUNT_CHUNK, "{0} {chunk|chunks}");
phrases.put(Phrase.AMOUNT_ENTITY, "{0} {entity|entities}");
phrases.put(Phrase.AMOUNT_ITEM, "{0} {item|items}");
phrases.put(Phrase.API_TEST, "API test successful.");
phrases.put(Phrase.CACHE_ERROR, "WARNING: Error while validating {0} cache.");
phrases.put(Phrase.CACHE_RELOAD, "Forcing reload of {mapping|world} caches from database.");
phrases.put(Phrase.CHECK_CONFIG, "Please check config.yml");
phrases.put(Phrase.COMMAND_NOT_FOUND, "Command \"{0}\" not found.");
phrases.put(Phrase.COMMAND_THROTTLED, "Please wait a moment and try again.");
phrases.put(Phrase.CONTAINER_HEADER, "Container Transactions");
phrases.put(Phrase.DATABASE_BUSY, "Database busy. Please try again later.");
phrases.put(Phrase.DATABASE_INDEX_ERROR, "Unable to validate database indexes.");
phrases.put(Phrase.DATABASE_LOCKED_1, "Database locked. Waiting up to 15 seconds...");
phrases.put(Phrase.DATABASE_LOCKED_2, "Database is already in use. Please try again.");
phrases.put(Phrase.DATABASE_LOCKED_3, "To disable database locking, set \"database-lock: false\".");
phrases.put(Phrase.DATABASE_LOCKED_4, "Disabling database locking can result in data corruption.");
phrases.put(Phrase.DATABASE_UNREACHABLE, "Database is unreachable. Discarding data and shutting down.");
phrases.put(Phrase.DEVELOPMENT_BRANCH, "Development branch detected, skipping patch scripts.");
phrases.put(Phrase.DIRT_BLOCK, "Placed a dirt block under you.");
phrases.put(Phrase.DISABLE_SUCCESS, "Success! Disabled {0}");
phrases.put(Phrase.ENABLE_FAILED, "{0} was unable to start.");
phrases.put(Phrase.ENABLE_SUCCESS, "{0} has been successfully enabled!");
phrases.put(Phrase.ENJOY_COREPROTECT, "Enjoy {0}? Join our Discord!");
phrases.put(Phrase.FINISHING_CONVERSION, "Finishing up data conversion. Please wait...");
phrases.put(Phrase.FINISHING_LOGGING, "Finishing up data logging. Please wait...");
phrases.put(Phrase.FIRST_VERSION, "Initial DB: {0}");
phrases.put(Phrase.GLOBAL_LOOKUP, "Don't specify a radius to do a global lookup.");
phrases.put(Phrase.GLOBAL_ROLLBACK, "Use \"{0}\" to do a global {rollback|restore}");
phrases.put(Phrase.HELP_ACTION_1, "Restrict the lookup to a certain action.");
phrases.put(Phrase.HELP_ACTION_2, "Examples: [a:block], [a:+block], [a:-block] [a:click], [a:container], [a:inventory], [a:item], [a:kill], [a:chat], [a:command], [a:sign], [a:session], [a:username]");
phrases.put(Phrase.HELP_COMMAND, "Display more info for that command.");
phrases.put(Phrase.HELP_EXCLUDE_1, "Exclude blocks/users.");
phrases.put(Phrase.HELP_EXCLUDE_2, "Examples: [e:stone], [e:Notch], [e:stone,Notch]");
phrases.put(Phrase.HELP_HEADER, "{0} Help");
phrases.put(Phrase.HELP_INCLUDE_1, "Include specific blocks/entities.");
phrases.put(Phrase.HELP_INCLUDE_2, "Examples: [i:stone], [i:zombie], [i:stone,wood,bedrock]");
phrases.put(Phrase.HELP_INSPECT_1, "With the inspector enabled, you can do the following:");
phrases.put(Phrase.HELP_INSPECT_2, "Left-click a block to see who placed that block.");
phrases.put(Phrase.HELP_INSPECT_3, "Right-click a block to see what adjacent block was broken.");
phrases.put(Phrase.HELP_INSPECT_4, "Place a block to see what block was broken at that location.");
phrases.put(Phrase.HELP_INSPECT_5, "Place a block in liquid (etc) to see who placed it.");
phrases.put(Phrase.HELP_INSPECT_6, "Right-click on a door, chest, etc, to see who last used it.");
phrases.put(Phrase.HELP_INSPECT_7, "Tip: You can use just \"/co i\" for quicker access.");
phrases.put(Phrase.HELP_INSPECT_COMMAND, "Turns the block inspector on or off.");
phrases.put(Phrase.HELP_LIST, "Displays a list of all commands.");
phrases.put(Phrase.HELP_LOOKUP_1, "Command shortcut.");
phrases.put(Phrase.HELP_LOOKUP_2, "Use after inspecting a block to view logs.");
phrases.put(Phrase.HELP_LOOKUP_COMMAND, "Advanced block data lookup.");
phrases.put(Phrase.HELP_NO_INFO, "Information for command \"{0}\" not found.");
phrases.put(Phrase.HELP_PARAMETER, "Please see \"{0}\" for detailed parameter info.");
phrases.put(Phrase.HELP_PARAMS_1, "Perform the {lookup|rollback|restore}.");
phrases.put(Phrase.HELP_PARAMS_2, "Specify the user(s) to {lookup|rollback|restore}.");
phrases.put(Phrase.HELP_PARAMS_3, "Specify the amount of time to {lookup|rollback|restore}.");
phrases.put(Phrase.HELP_PARAMS_4, "Specify a radius area to limit the {lookup|rollback|restore} to.");
phrases.put(Phrase.HELP_PARAMS_5, "Restrict the {lookup|rollback|restore} to a certain action.");
phrases.put(Phrase.HELP_PARAMS_6, "Include specific blocks/entities in the {lookup|rollback|restore}.");
phrases.put(Phrase.HELP_PARAMS_7, "Exclude blocks/users from the {lookup|rollback|restore}.");
phrases.put(Phrase.HELP_PURGE_1, "Delete data older than specified time.");
phrases.put(Phrase.HELP_PURGE_2, "For example, \"{0}\" will delete all data older than one month, and only keep the last 30 days of data.");
phrases.put(Phrase.HELP_PURGE_COMMAND, "Delete old block data.");
phrases.put(Phrase.HELP_RADIUS_1, "Specify a radius area.");
phrases.put(Phrase.HELP_RADIUS_2, "Examples: [r:10] (Only make changes within 10 blocks of you)");
phrases.put(Phrase.HELP_RELOAD_COMMAND, "Reloads the configuration file.");
phrases.put(Phrase.HELP_RESTORE_COMMAND, "Restore block data.");
phrases.put(Phrase.HELP_ROLLBACK_COMMAND, "Rollback block data.");
phrases.put(Phrase.HELP_STATUS, "View the plugin status and version information.");
phrases.put(Phrase.HELP_STATUS_COMMAND, "Displays the plugin status.");
phrases.put(Phrase.HELP_TELEPORT, "Teleport to a location.");
phrases.put(Phrase.HELP_TIME_1, "Specify the amount of time to lookup.");
phrases.put(Phrase.HELP_TIME_2, "Examples: [t:2w,5d,7h,2m,10s], [t:5d2h], [t:2.50h]");
phrases.put(Phrase.HELP_USER_1, "Specify the user(s) to lookup.");
phrases.put(Phrase.HELP_USER_2, "Examples: [u:Notch], [u:Notch,#enderman]");
phrases.put(Phrase.INCOMPATIBLE_ACTION, "\"{0}\" can't be used with that action.");
phrases.put(Phrase.INSPECTOR_ERROR, "Inspector already {enabled|disabled}.");
phrases.put(Phrase.INSPECTOR_TOGGLED, "Inspector now {enabled|disabled}.");
phrases.put(Phrase.INTEGRATION_ERROR, "Unable to {initialize|disable} {0} logging.");
phrases.put(Phrase.INTEGRATION_SUCCESS, "{0} logging successfully {initialized|disabled}.");
phrases.put(Phrase.INTEGRATION_VERSION, "Invalid {0} version found.");
phrases.put(Phrase.INTERACTIONS_HEADER, "Player Interactions");
phrases.put(Phrase.INVALID_ACTION, "That is not a valid action.");
phrases.put(Phrase.INVALID_BRANCH_1, "Invalid plugin version (branch has not been set).");
phrases.put(Phrase.INVALID_BRANCH_2, "To continue, set project branch to \"development\".");
phrases.put(Phrase.INVALID_BRANCH_3, "Running development code may result in data corruption.");
phrases.put(Phrase.INVALID_CONTAINER, "Please inspect a valid container first.");
phrases.put(Phrase.INVALID_DONATION_KEY, "Invalid donation key.");
phrases.put(Phrase.INVALID_INCLUDE, "\"{0}\" is an invalid block/entity name.");
phrases.put(Phrase.INVALID_INCLUDE_COMBO, "That is an invalid block/entity combination.");
phrases.put(Phrase.INVALID_RADIUS, "Please enter a valid radius.");
phrases.put(Phrase.INVALID_SELECTION, "{0} selection not found.");
phrases.put(Phrase.INVALID_USERNAME, "\"{0}\" is an invalid username.");
phrases.put(Phrase.INVALID_WORLD, "Please specify a valid world.");
phrases.put(Phrase.LATEST_VERSION, "Latest Version: {0}");
phrases.put(Phrase.LINK_DISCORD, "Discord: {0}");
phrases.put(Phrase.LINK_DOWNLOAD, "Download: {0}");
phrases.put(Phrase.LINK_PATREON, "Patreon: {0}");
phrases.put(Phrase.LINK_WIKI_BLOCK, "Block Names: {0}");
phrases.put(Phrase.LINK_WIKI_ENTITY, "Entity Names: {0}");
phrases.put(Phrase.LOGGING_ITEMS, "{0} items left to log. Please wait...");
phrases.put(Phrase.LOGGING_TIME_LIMIT, "Logging time limit reached. Discarding data and shutting down.");
phrases.put(Phrase.LOOKUP_BLOCK, "{0} {placed|broke} {1}.");
phrases.put(Phrase.LOOKUP_CONTAINER, "{0} {added|removed} {1} {2}.");
phrases.put(Phrase.LOOKUP_HEADER, "{0} Lookup Results");
phrases.put(Phrase.LOOKUP_INTERACTION, "{0} {clicked|killed} {1}.");
phrases.put(Phrase.LOOKUP_ITEM, "{0} {picked up|dropped} {1} {2}.");
phrases.put(Phrase.LOOKUP_LOGIN, "{0} logged {in|out}.");
phrases.put(Phrase.LOOKUP_PAGE, "Page {0}");
phrases.put(Phrase.LOOKUP_ROWS_FOUND, "{0} {row|rows} found.");
phrases.put(Phrase.LOOKUP_SEARCHING, "Lookup searching. Please wait...");
phrases.put(Phrase.LOOKUP_STORAGE, "{0} {deposited|withdrew} {1} {2}.");
phrases.put(Phrase.LOOKUP_TIME, "{0} ago");
phrases.put(Phrase.LOOKUP_USERNAME, "{0} logged in as {1}.");
phrases.put(Phrase.LOOKUP_VIEW_PAGE, "To view a page, type \"{0}\".");
phrases.put(Phrase.MAXIMUM_RADIUS, "The maximum {lookup|rollback|restore} radius is {0}.");
phrases.put(Phrase.MISSING_ACTION_USER, "To use that action, please specify a user.");
phrases.put(Phrase.MISSING_LOOKUP_TIME, "Please specify the amount of time to {lookup|rollback|restore}.");
phrases.put(Phrase.MISSING_LOOKUP_USER, "Please specify a user or {block|radius} to lookup.");
phrases.put(Phrase.MISSING_PARAMETERS, "Please use \"{0}\".");
phrases.put(Phrase.MISSING_ROLLBACK_RADIUS, "You did not specify a {rollback|restore} radius.");
phrases.put(Phrase.MISSING_ROLLBACK_USER, "You did not specify a {rollback|restore} user.");
phrases.put(Phrase.MYSQL_UNAVAILABLE, "Unable to connect to MySQL server.");
phrases.put(Phrase.NO_DATA, "No data found at {0}.");
phrases.put(Phrase.NO_DATA_LOCATION, "No {data|transactions|interactions|messages} found at this location.");
phrases.put(Phrase.NO_PERMISSION, "You do not have permission to do that.");
phrases.put(Phrase.NO_RESULTS, "No results found.");
phrases.put(Phrase.NO_RESULTS_PAGE, "No {results|data} found for that page.");
phrases.put(Phrase.NO_ROLLBACK, "No {pending|previous} rollback/restore found.");
phrases.put(Phrase.PATCH_INTERRUPTED, "Upgrade interrupted. Will try again on restart.");
phrases.put(Phrase.PATCH_OUTDATED_1, "Unable to upgrade databases older than {0}.");
phrases.put(Phrase.PATCH_OUTDATED_2, "Please upgrade with a supported version of CoreProtect.");
phrases.put(Phrase.PATCH_PROCESSING, "Processing new data. Please wait...");
phrases.put(Phrase.PATCH_SKIP_UPDATE, "Skipping {table|index} {update|creation|removal} on {0}.");
phrases.put(Phrase.PATCH_STARTED, "Performing {0} upgrade. Please wait...");
phrases.put(Phrase.PATCH_SUCCESS, "Successfully upgraded to {0}.");
phrases.put(Phrase.PATCH_UPGRADING, "Database upgrade in progress. Please wait...");
phrases.put(Phrase.PLEASE_SELECT, "Please select: \"{0}\" or \"{1}\".");
phrases.put(Phrase.PREVIEW_CANCELLED, "Preview cancelled.");
phrases.put(Phrase.PREVIEW_CANCELLING, "Cancelling preview...");
phrases.put(Phrase.PREVIEW_CONTAINER, "You can't preview container transactions.");
phrases.put(Phrase.PREVIEW_IN_GAME, "You can only preview rollbacks in-game.");
phrases.put(Phrase.PURGE_ABORTED, "Purge failed. Database may be corrupt.");
phrases.put(Phrase.PURGE_ERROR, "Unable to process {0} data!");
phrases.put(Phrase.PURGE_FAILED, "Purge failed. Please try again later.");
phrases.put(Phrase.PURGE_IN_PROGRESS, "Purge in progress. Please try again later.");
phrases.put(Phrase.PURGE_MINIMUM_TIME, "You can only purge data older than {0} {days|hours}.");
phrases.put(Phrase.PURGE_NOTICE_1, "Please note that this may take some time.");
phrases.put(Phrase.PURGE_NOTICE_2, "Do not restart your server until completed.");
phrases.put(Phrase.PURGE_OPTIMIZING, "Optimizing database. Please wait...");
phrases.put(Phrase.PURGE_PROCESSING, "Processing {0} data...");
phrases.put(Phrase.PURGE_REPAIRING, "Attempting to repair. This may take some time...");
phrases.put(Phrase.PURGE_ROWS, "{0} {row|rows} of data deleted.");
phrases.put(Phrase.PURGE_STARTED, "Data purge started on \"{0}\".");
phrases.put(Phrase.PURGE_SUCCESS, "Data purge successful.");
phrases.put(Phrase.RELOAD_STARTED, "Reloading configuration - please wait.");
phrases.put(Phrase.RELOAD_SUCCESS, "Configuration successfully reloaded.");
phrases.put(Phrase.ROLLBACK_ABORTED, "Rollback or restore aborted.");
phrases.put(Phrase.ROLLBACK_CHUNKS_FOUND, "Found {0} {chunk|chunks} to modify.");
phrases.put(Phrase.ROLLBACK_CHUNKS_MODIFIED, "Modified {0}/{1} {chunk|chunks}.");
phrases.put(Phrase.ROLLBACK_COMPLETED, "{Rollback|Restore|Preview} completed for \"{0}\".");
phrases.put(Phrase.ROLLBACK_EXCLUDED_USERS, "Excluded {user|users}: \"{0}\".");
phrases.put(Phrase.ROLLBACK_INCLUDE, "{Included|Excluded} {block|entity|target} {type|types}: \"{0}\".");
phrases.put(Phrase.ROLLBACK_IN_PROGRESS, "A rollback/restore is already in progress.");
phrases.put(Phrase.ROLLBACK_LENGTH, "Time taken: {0} {second|seconds}.");
phrases.put(Phrase.ROLLBACK_MODIFIED, "{Modified|Modifying} {0}.");
phrases.put(Phrase.ROLLBACK_RADIUS, "Radius: {0} {block|blocks}.");
phrases.put(Phrase.ROLLBACK_SELECTION, "Radius set to \"{0}\".");
phrases.put(Phrase.ROLLBACK_STARTED, "{Rollback|Restore|Preview} started on \"{0}\".");
phrases.put(Phrase.ROLLBACK_TIME, "Time range: {0}.");
phrases.put(Phrase.ROLLBACK_WORLD_ACTION, "Restricted to {world|action} \"{0}\".");
phrases.put(Phrase.SIGN_HEADER, "Sign Messages");
phrases.put(Phrase.STATUS_CONSUMER, "Consumer: {0} {item|items} in queue.");
phrases.put(Phrase.STATUS_DATABASE, "Database: Using {0}.");
phrases.put(Phrase.STATUS_INTEGRATION, "{0}: Integration {enabled|disabled}.");
phrases.put(Phrase.STATUS_LICENSE, "License: {0}");
phrases.put(Phrase.STATUS_VERSION, "Version: {0}");
phrases.put(Phrase.TELEPORTED, "Teleported to {0}.");
phrases.put(Phrase.TELEPORTED_SAFETY, "Teleported you to safety.");
phrases.put(Phrase.TELEPORT_PLAYERS, "Teleport command can only be used by players.");
phrases.put(Phrase.TIME_DAYS, "{0} {day|days}");
phrases.put(Phrase.TIME_HOURS, "{0} {hour|hours}");
phrases.put(Phrase.TIME_MINUTES, "{0} {minute|minutes}");
phrases.put(Phrase.TIME_SECONDS, "{0} {second|seconds}");
phrases.put(Phrase.TIME_WEEKS, "{0} {week|weeks}");
phrases.put(Phrase.UPDATE_ERROR, "An error occurred while checking for updates.");
phrases.put(Phrase.UPDATE_HEADER, "{0} Update");
phrases.put(Phrase.UPDATE_NOTICE, "Notice: {0} is now available.");
phrases.put(Phrase.UPGRADE_IN_PROGRESS, "Upgrade in progress. Please try again later.");
phrases.put(Phrase.USER_NOT_FOUND, "User \"{0}\" not found.");
phrases.put(Phrase.USING_MYSQL, "Using MySQL for data storage.");
phrases.put(Phrase.USING_SQLITE, "Using SQLite for data storage.");
phrases.put(Phrase.VALID_DONATION_KEY, "Valid donation key.");
phrases.put(Phrase.VERSION_NOTICE, "Version {0} is now available.");
phrases.put(Phrase.VERSION_REQUIRED, "{0} {1} or higher is required.");
phrases.put(Phrase.WORLD_NOT_FOUND, "World \"{0}\" not found.");
userPhrases.putAll(phrases);
translatedPhrases.putAll(phrases);
}
}

View File

@ -0,0 +1,286 @@
package net.coreprotect.language;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import net.coreprotect.utility.ChatMessage;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public enum Phrase {
ACTION_NOT_SUPPORTED,
AMOUNT_BLOCK,
AMOUNT_CHUNK,
AMOUNT_ENTITY,
AMOUNT_ITEM,
API_TEST,
CACHE_ERROR,
CACHE_RELOAD,
CHECK_CONFIG,
COMMAND_NOT_FOUND,
COMMAND_THROTTLED,
CONTAINER_HEADER,
DATABASE_BUSY,
DATABASE_INDEX_ERROR,
DATABASE_LOCKED_1,
DATABASE_LOCKED_2,
DATABASE_LOCKED_3,
DATABASE_LOCKED_4,
DATABASE_UNREACHABLE,
DEVELOPMENT_BRANCH,
DIRT_BLOCK,
DISABLE_SUCCESS,
ENABLE_FAILED,
ENABLE_SUCCESS,
ENJOY_COREPROTECT,
FINISHING_CONVERSION,
FINISHING_LOGGING,
FIRST_VERSION,
GLOBAL_LOOKUP,
GLOBAL_ROLLBACK,
HELP_ACTION_1,
HELP_ACTION_2,
HELP_COMMAND,
HELP_EXCLUDE_1,
HELP_EXCLUDE_2,
HELP_HEADER,
HELP_INCLUDE_1,
HELP_INCLUDE_2,
HELP_INSPECT_1,
HELP_INSPECT_2,
HELP_INSPECT_3,
HELP_INSPECT_4,
HELP_INSPECT_5,
HELP_INSPECT_6,
HELP_INSPECT_7,
HELP_INSPECT_COMMAND,
HELP_LIST,
HELP_LOOKUP_1,
HELP_LOOKUP_2,
HELP_LOOKUP_COMMAND,
HELP_NO_INFO,
HELP_PARAMETER,
HELP_PARAMS_1,
HELP_PARAMS_2,
HELP_PARAMS_3,
HELP_PARAMS_4,
HELP_PARAMS_5,
HELP_PARAMS_6,
HELP_PARAMS_7,
HELP_PURGE_1,
HELP_PURGE_2,
HELP_PURGE_COMMAND,
HELP_RADIUS_1,
HELP_RADIUS_2,
HELP_RELOAD_COMMAND,
HELP_RESTORE_COMMAND,
HELP_ROLLBACK_COMMAND,
HELP_STATUS,
HELP_STATUS_COMMAND,
HELP_TELEPORT,
HELP_TIME_1,
HELP_TIME_2,
HELP_USER_1,
HELP_USER_2,
INCOMPATIBLE_ACTION,
INSPECTOR_ERROR,
INSPECTOR_TOGGLED,
INTEGRATION_ERROR,
INTEGRATION_SUCCESS,
INTEGRATION_VERSION,
INTERACTIONS_HEADER,
INVALID_ACTION,
INVALID_BRANCH_1,
INVALID_BRANCH_2,
INVALID_BRANCH_3,
INVALID_CONTAINER,
INVALID_DONATION_KEY,
INVALID_INCLUDE,
INVALID_INCLUDE_COMBO,
INVALID_RADIUS,
INVALID_SELECTION,
INVALID_USERNAME,
INVALID_WORLD,
LATEST_VERSION,
LINK_DISCORD,
LINK_DOWNLOAD,
LINK_PATREON,
LINK_WIKI_BLOCK,
LINK_WIKI_ENTITY,
LOGGING_ITEMS,
LOGGING_TIME_LIMIT,
LOOKUP_BLOCK,
LOOKUP_CONTAINER,
LOOKUP_HEADER,
LOOKUP_INTERACTION,
LOOKUP_ITEM,
LOOKUP_LOGIN,
LOOKUP_PAGE,
LOOKUP_ROWS_FOUND,
LOOKUP_SEARCHING,
LOOKUP_STORAGE,
LOOKUP_TIME,
LOOKUP_USERNAME,
LOOKUP_VIEW_PAGE,
MAXIMUM_RADIUS,
MISSING_ACTION_USER,
MISSING_LOOKUP_TIME,
MISSING_LOOKUP_USER,
MISSING_PARAMETERS,
MISSING_ROLLBACK_RADIUS,
MISSING_ROLLBACK_USER,
MYSQL_UNAVAILABLE,
NO_DATA,
NO_DATA_LOCATION,
NO_PERMISSION,
NO_RESULTS,
NO_RESULTS_PAGE,
NO_ROLLBACK,
PATCH_INTERRUPTED,
PATCH_OUTDATED_1,
PATCH_OUTDATED_2,
PATCH_PROCESSING,
PATCH_SKIP_UPDATE,
PATCH_STARTED,
PATCH_SUCCESS,
PATCH_UPGRADING,
PLEASE_SELECT,
PREVIEW_CANCELLED,
PREVIEW_CANCELLING,
PREVIEW_CONTAINER,
PREVIEW_IN_GAME,
PURGE_ABORTED,
PURGE_ERROR,
PURGE_FAILED,
PURGE_IN_PROGRESS,
PURGE_MINIMUM_TIME,
PURGE_NOTICE_1,
PURGE_NOTICE_2,
PURGE_OPTIMIZING,
PURGE_PROCESSING,
PURGE_REPAIRING,
PURGE_ROWS,
PURGE_STARTED,
PURGE_SUCCESS,
RELOAD_STARTED,
RELOAD_SUCCESS,
ROLLBACK_ABORTED,
ROLLBACK_CHUNKS_FOUND,
ROLLBACK_CHUNKS_MODIFIED,
ROLLBACK_COMPLETED,
ROLLBACK_EXCLUDED_USERS,
ROLLBACK_INCLUDE,
ROLLBACK_IN_PROGRESS,
ROLLBACK_LENGTH,
ROLLBACK_MODIFIED,
ROLLBACK_RADIUS,
ROLLBACK_SELECTION,
ROLLBACK_STARTED,
ROLLBACK_TIME,
ROLLBACK_WORLD_ACTION,
SIGN_HEADER,
STATUS_CONSUMER,
STATUS_DATABASE,
STATUS_INTEGRATION,
STATUS_LICENSE,
STATUS_VERSION,
TELEPORTED,
TELEPORTED_SAFETY,
TELEPORT_PLAYERS,
TIME_DAYS,
TIME_HOURS,
TIME_MINUTES,
TIME_SECONDS,
TIME_WEEKS,
UPDATE_ERROR,
UPDATE_HEADER,
UPDATE_NOTICE,
UPGRADE_IN_PROGRESS,
USER_NOT_FOUND,
USING_MYSQL,
USING_SQLITE,
VALID_DONATION_KEY,
VERSION_NOTICE,
VERSION_REQUIRED,
WORLD_NOT_FOUND;
final private static Set<Phrase> HEADERS = new HashSet<>(Arrays.asList(Phrase.CONTAINER_HEADER, Phrase.HELP_HEADER, Phrase.INTERACTIONS_HEADER, Phrase.LOOKUP_HEADER, Phrase.SIGN_HEADER, Phrase.UPDATE_HEADER));
final private static Set<String> COLORS = new HashSet<>(Arrays.asList(Color.WHITE, Color.DARK_AQUA));
final private static String split = ":";
public String getPhrase() {
return Language.getPhrase(this);
}
public String getUserPhrase() {
return Language.getUserPhrase(this);
}
public String getTranslatedPhrase() {
return Language.getTranslatedPhrase(this);
}
public static String build(Phrase phrase, String... params) {
String output = phrase.getTranslatedPhrase();
String color = "";
if (HEADERS.contains(phrase)) {
output = Util.capitalize(output, true);
}
int index = 0;
int indexExtra = 0;
for (String param : params) {
if (index == 0 && COLORS.contains(param)) {
color = param;
indexExtra++;
continue;
}
if (Selector.SELECTORS.contains(param)) {
output = Selector.processSelection(output, param, color);
indexExtra++;
continue;
}
if (output.contains("{" + index + "}")) {
output = output.replace("{" + index + "}", param);
index++;
}
}
if ((index + indexExtra) != params.length) { // fallback for issues with user modified phrases
// System.out.println("buildInternal"); // debug
output = buildInternal(phrase, params, color);
}
if (color.length() > 0) {
output = output.replaceFirst(split, split + color);
output = ChatMessage.parseQuotes(output, color);
}
return output;
}
private static String buildInternal(Phrase phrase, String[] params, String color) {
String output = phrase.getPhrase(); // get internal phrase
int index = 0;
for (String param : params) {
if (index == 0 && COLORS.contains(param)) {
continue;
}
if (Selector.SELECTORS.contains(param)) {
output = Selector.processSelection(output, param, color);
continue;
}
output = output.replace("{" + index + "}", param);
index++;
}
return output;
}
}

View File

@ -0,0 +1,60 @@
package net.coreprotect.language;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import net.coreprotect.utility.Color;
public class Selector {
final public static String FIRST = "{1}";
final public static String SECOND = "{2}";
final public static String THIRD = "{3}";
final public static String FOURTH = "{4}";
final protected static Set<String> SELECTORS = new HashSet<>(Arrays.asList(Selector.FIRST, Selector.SECOND, Selector.THIRD, Selector.FOURTH));
protected static String processSelection(String output, String param, String color) {
String substring = output;
try {
substring = substring.substring(substring.indexOf("{") + 1);
substring = substring.substring(0, substring.indexOf("}"));
}
catch (Exception e) {
substring = "";
}
if (substring.contains("|")) {
int selector = Integer.parseInt(param.substring(1, 2)) - 1;
int index = substring(substring, "|", selector);
if (index == -1) {
param = substring.substring(0, substring.indexOf("|"));
}
else {
param = substring.substring(index + 1, (substring.lastIndexOf("|") > index ? substring(substring, "|", selector + 1) : substring.length()));
}
output = output.replace("{" + substring + "}", color + param + (color.length() > 0 ? Color.WHITE : color));
}
return output;
}
private static int substring(String string, String search, int index) {
int result = string.indexOf("|");
if (result == -1 || index == 0) {
return -1;
}
for (int i = 1; i < index; i++) {
result = string.indexOf("|", result + 1);
if (result == -1) {
return -1;
}
}
return result;
}
}

View File

@ -0,0 +1,106 @@
package net.coreprotect.listener;
import org.bukkit.plugin.PluginManager;
import net.coreprotect.CoreProtect;
import net.coreprotect.listener.block.BlockBreakListener;
import net.coreprotect.listener.block.BlockBurnListener;
import net.coreprotect.listener.block.BlockDispenseListener;
import net.coreprotect.listener.block.BlockExplodeListener;
import net.coreprotect.listener.block.BlockFadeListener;
import net.coreprotect.listener.block.BlockFertilizeListener;
import net.coreprotect.listener.block.BlockFormListener;
import net.coreprotect.listener.block.BlockFromToListener;
import net.coreprotect.listener.block.BlockIgniteListener;
import net.coreprotect.listener.block.BlockPistonListener;
import net.coreprotect.listener.block.BlockPlaceListener;
import net.coreprotect.listener.block.BlockSpreadListener;
import net.coreprotect.listener.entity.CreatureSpawnListener;
import net.coreprotect.listener.entity.EntityBlockFormListener;
import net.coreprotect.listener.entity.EntityChangeBlockListener;
import net.coreprotect.listener.entity.EntityDamageByBlockListener;
import net.coreprotect.listener.entity.EntityDamageByEntityListener;
import net.coreprotect.listener.entity.EntityDeathListener;
import net.coreprotect.listener.entity.EntityExplodeListener;
import net.coreprotect.listener.entity.EntityInteractListener;
import net.coreprotect.listener.entity.EntityPickupItemListener;
import net.coreprotect.listener.entity.HangingBreakByEntityListener;
import net.coreprotect.listener.entity.HangingBreakListener;
import net.coreprotect.listener.entity.HangingPlaceListener;
import net.coreprotect.listener.player.ArmorStandManipulateListener;
import net.coreprotect.listener.player.FoodLevelChangeListener;
import net.coreprotect.listener.player.InventoryChangeListener;
import net.coreprotect.listener.player.PlayerBucketEmptyListener;
import net.coreprotect.listener.player.PlayerBucketFillListener;
import net.coreprotect.listener.player.PlayerChatListener;
import net.coreprotect.listener.player.PlayerCommandListener;
import net.coreprotect.listener.player.PlayerDeathListener;
import net.coreprotect.listener.player.PlayerDropItemListener;
import net.coreprotect.listener.player.PlayerInteractEntityListener;
import net.coreprotect.listener.player.PlayerInteractListener;
import net.coreprotect.listener.player.PlayerJoinListener;
import net.coreprotect.listener.player.PlayerQuitListener;
import net.coreprotect.listener.player.PlayerTakeLecternBookListener;
import net.coreprotect.listener.player.SignChangeListener;
import net.coreprotect.listener.world.LeavesDecayListener;
import net.coreprotect.listener.world.PortalCreateListener;
import net.coreprotect.listener.world.StructureGrowListener;
public final class ListenerHandler {
public ListenerHandler(CoreProtect plugin) {
PluginManager pluginManager = plugin.getServer().getPluginManager();
// Block Listeners
pluginManager.registerEvents(new BlockBreakListener(), plugin);
pluginManager.registerEvents(new BlockBurnListener(), plugin);
pluginManager.registerEvents(new BlockDispenseListener(), plugin);
pluginManager.registerEvents(new BlockExplodeListener(), plugin);
pluginManager.registerEvents(new BlockFadeListener(), plugin);
pluginManager.registerEvents(new BlockFertilizeListener(), plugin);
pluginManager.registerEvents(new BlockFormListener(), plugin);
pluginManager.registerEvents(new BlockFromToListener(), plugin);
pluginManager.registerEvents(new BlockIgniteListener(), plugin);
pluginManager.registerEvents(new BlockPistonListener(), plugin);
pluginManager.registerEvents(new BlockPlaceListener(), plugin);
pluginManager.registerEvents(new BlockSpreadListener(), plugin);
// Entity Listeners
pluginManager.registerEvents(new CreatureSpawnListener(), plugin);
pluginManager.registerEvents(new EntityBlockFormListener(), plugin);
pluginManager.registerEvents(new EntityChangeBlockListener(), plugin);
pluginManager.registerEvents(new EntityDamageByBlockListener(), plugin);
pluginManager.registerEvents(new EntityDamageByEntityListener(), plugin);
pluginManager.registerEvents(new EntityDeathListener(), plugin);
pluginManager.registerEvents(new EntityExplodeListener(), plugin);
pluginManager.registerEvents(new EntityInteractListener(), plugin);
pluginManager.registerEvents(new EntityPickupItemListener(), plugin);
pluginManager.registerEvents(new HangingPlaceListener(), plugin);
pluginManager.registerEvents(new HangingBreakListener(), plugin);
pluginManager.registerEvents(new HangingBreakByEntityListener(), plugin);
// Player Listeners
pluginManager.registerEvents(new InventoryChangeListener(), plugin);
pluginManager.registerEvents(new ArmorStandManipulateListener(), plugin);
pluginManager.registerEvents(new PlayerBucketEmptyListener(), plugin);
pluginManager.registerEvents(new PlayerBucketFillListener(), plugin);
pluginManager.registerEvents(new PlayerChatListener(), plugin);
pluginManager.registerEvents(new PlayerCommandListener(), plugin);
pluginManager.registerEvents(new PlayerDeathListener(), plugin);
pluginManager.registerEvents(new PlayerDropItemListener(), plugin);
pluginManager.registerEvents(new FoodLevelChangeListener(), plugin);
pluginManager.registerEvents(new PlayerInteractEntityListener(), plugin);
pluginManager.registerEvents(new PlayerJoinListener(), plugin);
pluginManager.registerEvents(new PlayerQuitListener(), plugin);
pluginManager.registerEvents(new SignChangeListener(), plugin);
pluginManager.registerEvents(new PlayerInteractListener(), plugin);
pluginManager.registerEvents(new PlayerTakeLecternBookListener(), plugin);
// World Listeners
pluginManager.registerEvents(new StructureGrowListener(), plugin);
pluginManager.registerEvents(new LeavesDecayListener(), plugin);
pluginManager.registerEvents(new PortalCreateListener(), plugin);
}
}

View File

@ -0,0 +1,332 @@
package net.coreprotect.listener.block;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.World;
import org.bukkit.block.Banner;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.Sign;
import org.bukkit.block.Skull;
import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Directional;
import org.bukkit.block.data.MultipleFacing;
import org.bukkit.block.data.Rail;
import org.bukkit.block.data.Rail.Shape;
import org.bukkit.block.data.Waterlogged;
import org.bukkit.block.data.type.Bell;
import org.bukkit.block.data.type.Lantern;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import net.coreprotect.bukkit.BukkitAdapter;
import net.coreprotect.config.Config;
import net.coreprotect.consumer.Queue;
import net.coreprotect.database.Database;
import net.coreprotect.model.BlockGroup;
import net.coreprotect.utility.Util;
public final class BlockBreakListener extends Queue implements Listener {
private static boolean isAttached(Block block, Block scanBlock, int scanMin) {
BlockData blockData = scanBlock.getBlockData();
if (blockData instanceof Directional && !(blockData instanceof Bisected) && scanMin != BlockUtil.BOTTOM && scanMin != BlockUtil.TOP) {
Directional directional = (Directional) blockData;
BlockFace blockFace = directional.getFacing();
boolean adjacent = scanBlock.getRelative(blockFace.getOppositeFace()).getLocation().equals(block.getLocation());
return adjacent;
}
else if (blockData instanceof MultipleFacing) {
MultipleFacing multipleFacing = (MultipleFacing) blockData;
for (BlockFace blockFace : multipleFacing.getFaces()) {
boolean adjacent = scanBlock.getRelative(blockFace).getLocation().equals(block.getLocation());
if (adjacent) {
return true;
}
}
return false;
}
else if (blockData instanceof Lantern) {
boolean scan = false;
switch (scanMin) {
case BlockUtil.TOP:
scan = !((Lantern) blockData).isHanging();
break;
case BlockUtil.BOTTOM:
scan = ((Lantern) blockData).isHanging();
break;
default:
break;
}
return scan;
}
else if (!BukkitAdapter.ADAPTER.isAttached(block, scanBlock, blockData, scanMin)) {
return false;
}
return true;
}
protected static void processBlockBreak(Player player, String user, Block block, boolean logBreak, int skipScan) {
List<Block> placementMap = new ArrayList<>();
Material type = block.getType();
World world = block.getWorld();
int x = block.getX();
int y = block.getY();
int z = block.getZ();
int physics = 0;
Location[] locationMap = new Location[6];
locationMap[0] = new Location(world, x + 1, y, z);
locationMap[1] = new Location(world, x - 1, y, z);
locationMap[2] = new Location(world, x, y, z + 1);
locationMap[3] = new Location(world, x, y, z - 1);
locationMap[4] = new Location(world, x, y + 1, z);
locationMap[5] = new Location(world, x, y - 1, z);
int scanMin = 1;
int scanMax = 8;
if (!Config.getConfig(world).NATURAL_BREAK) {
scanMin = 7;
}
if (!logBreak) { // log base block breakage
scanMax = 7;
}
while (scanMin < scanMax) {
Block blockLog = block;
boolean scanDown = false;
boolean log = true;
if (scanMin == skipScan) {
scanMin++;
continue;
}
if (scanMin < 7) {
Location scanLocation = locationMap[scanMin - 1];
if (scanMin == 4 && (type == Material.IRON_DOOR || BlockGroup.DOORS.contains(type))) { // required for doors
scanLocation = locationMap[5];
scanDown = true;
}
Block scanBlock = world.getBlockAt(scanLocation);
Material scanType = scanBlock.getType();
if (scanMin == 5) {
if (scanType.hasGravity()) {
if (Config.getConfig(world).BLOCK_MOVEMENT) {
// log the top-most sand/gravel block as being removed
int scanY = y + 2;
boolean topFound = false;
while (!topFound) {
Block topBlock = world.getBlockAt(x, scanY, z);
Material topMaterial = topBlock.getType();
if (!topMaterial.hasGravity()) {
scanLocation = new Location(world, x, (scanY - 1), z);
topFound = true;
}
scanY++;
}
placementMap.add(scanBlock);
}
}
}
if (!BlockGroup.TRACK_ANY.contains(scanType)) {
if (scanMin != 5 && scanMin != 6 && !scanDown) { // side block
if (!BlockGroup.TRACK_SIDE.contains(scanType)) {
log = false;
/*
if (physics == 0 && scanBlock.getBlockData() instanceof MultipleFacing) {
physics = 1;
}
*/
}
else {
// determine if side block is attached
if (scanType.equals(Material.RAIL) || scanType.equals(Material.POWERED_RAIL) || scanType.equals(Material.DETECTOR_RAIL) || scanType.equals(Material.ACTIVATOR_RAIL)) {
BlockData blockData = scanBlock.getBlockData();
Rail rail = (Rail) blockData;
Shape shape = rail.getShape();
if (scanMin == 1 && shape != Shape.ASCENDING_WEST) {
log = false;
}
else if (scanMin == 2 && shape != Shape.ASCENDING_EAST) {
log = false;
}
else if (scanMin == 3 && shape != Shape.ASCENDING_NORTH) {
log = false;
}
else if (scanMin == 4 && shape != Shape.ASCENDING_SOUTH) {
log = false;
}
}
else if (scanType.name().endsWith("_BED") && !type.name().endsWith("_BED")) {
log = false;
}
else if (!isAttached(block, scanBlock, scanMin)) {
log = false;
}
}
}
else { // top/bottom block
if (BlockUtil.verticalBreakScan(player, user, block, scanBlock, scanType, scanMin)) {
log = false;
}
else if (scanMin == 5 && (!BlockGroup.TRACK_TOP.contains(scanType) && !BlockGroup.TRACK_TOP_BOTTOM.contains(scanType))) {
// top
log = false;
}
else if (scanMin == 6 && (!BlockGroup.TRACK_BOTTOM.contains(scanType) && !BlockGroup.TRACK_TOP_BOTTOM.contains(scanType))) {
// bottom
log = false;
}
else if (scanMin == 4 && !BlockGroup.TRACK_TOP.contains(scanType)) {
// checking block below for door
log = false;
}
else if (!isAttached(block, scanBlock, scanMin)) {
log = false;
}
}
if (!log) {
if (type.equals(Material.MOVING_PISTON)) {// broke a piston extension
if (scanType.equals(Material.STICKY_PISTON) || scanType.equals(Material.PISTON)) { // adjacent piston
log = true;
}
}
else if (scanMin == 5) {
if (scanType.hasGravity()) {
log = true;
}
}
}
}
else {
// determine if side block is attached
if (scanType.equals(Material.MOVING_PISTON)) {
if (!type.equals(Material.STICKY_PISTON) && !type.equals(Material.PISTON)) {
log = false;
}
}
else if (scanType.equals(Material.BELL)) {
boolean scanBell = false;
BlockData blockData = scanBlock.getBlockData();
Bell bell = (Bell) blockData;
switch (bell.getAttachment()) {
case SINGLE_WALL:
scanBell = (scanMin < 5 && scanBlock.getRelative(bell.getFacing()).getLocation().equals(block.getLocation()));
break;
case FLOOR:
scanBell = (scanMin == 5);
break;
case CEILING:
scanBell = (scanMin == 6);
break;
default:
break;
}
if (!scanBell) {
log = false;
}
}
else if (BlockGroup.BUTTONS.contains(scanType) || scanType == Material.LEVER) {
boolean scanButton = BukkitAdapter.ADAPTER.isAttached(block, scanBlock, scanBlock.getBlockData(), scanMin);
if (!scanButton) {
log = false;
}
}
else if (!isAttached(block, scanBlock, scanMin)) {
log = false;
}
}
if (log) {
blockLog = world.getBlockAt(scanLocation);
}
}
int blockNumber = scanMin;
Material blockType = blockLog.getType();
BlockState blockState = blockLog.getState();
if (log && (blockType.name().toUpperCase(Locale.ROOT).endsWith("_BANNER") || blockType.equals(Material.SKELETON_SKULL) || blockType.equals(Material.SKELETON_WALL_SKULL) || blockType.equals(Material.WITHER_SKELETON_SKULL) || blockType.equals(Material.WITHER_SKELETON_WALL_SKULL) || blockType.equals(Material.ZOMBIE_HEAD) || blockType.equals(Material.ZOMBIE_WALL_HEAD) || blockType.equals(Material.PLAYER_HEAD) || blockType.equals(Material.PLAYER_WALL_HEAD) || blockType.equals(Material.CREEPER_HEAD) || blockType.equals(Material.CREEPER_WALL_HEAD) || blockType.equals(Material.DRAGON_HEAD) || blockType.equals(Material.DRAGON_WALL_HEAD))) {
try {
if (blockState instanceof Banner || blockState instanceof Skull) {
Queue.queueAdvancedBreak(user, blockState, blockType, blockState.getBlockData().getAsString(), 0, type, blockNumber);
}
log = false;
}
catch (Exception e) {
e.printStackTrace();
}
}
if (log && Tag.SIGNS.isTagged(blockType)) {
if (Config.getConfig(world).SIGN_TEXT) {
try {
Location location = blockState.getLocation();
Sign sign = (Sign) blockLog.getState();
String line1 = sign.getLine(0);
String line2 = sign.getLine(1);
String line3 = sign.getLine(2);
String line4 = sign.getLine(3);
int color = sign.getColor().getColor().asRGB();
boolean isGlowing = BukkitAdapter.ADAPTER.isGlowing(sign);
Queue.queueSignText(user, location, 0, color, isGlowing, line1, line2, line3, line4, 5);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
if (log) {
Database.containerBreakCheck(user, blockType, blockLog, null, blockLog.getLocation());
Queue.queueBlockBreak(user, blockState, blockType, blockState.getBlockData().getAsString(), type, physics, blockNumber);
if (player != null && Util.iceBreakCheck(blockState, user, blockType)) {
ItemStack handItem = player.getInventory().getItemInMainHand();
if (!(player.getGameMode().equals(GameMode.CREATIVE)) && !(handItem != null && handItem.containsEnchantment(Enchantment.SILK_TOUCH))) {
Queue.queueBlockPlaceValidate(user, blockState, blockLog, null, Material.WATER, -1, 0, null, 0);
}
}
BlockData blockDataB1 = blockState.getBlockData();
if (blockDataB1 instanceof Waterlogged) {
Waterlogged waterlogged = (Waterlogged) blockDataB1;
if (waterlogged.isWaterlogged()) {
Queue.queueBlockPlace(user, blockState, blockLog.getType(), null, Material.WATER, -1, 0, null);
}
}
}
scanMin++;
}
for (Block placementBlock : placementMap) {
queueBlockPlace(user, block.getState(), placementBlock.getType(), null, null, -1, 0, placementBlock.getBlockData().getAsString());
}
}
@EventHandler(priority = EventPriority.MONITOR)
protected void onBlockBreak(BlockBreakEvent event) {
if (!event.isCancelled()) {
String user = event.getPlayer().getName();
Block block = event.getBlock();
processBlockBreak(event.getPlayer(), user, event.getBlock(), Config.getConfig(block.getWorld()).BLOCK_BREAK, BlockUtil.NONE);
}
}
}

View File

@ -0,0 +1,22 @@
package net.coreprotect.listener.block;
import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBurnEvent;
import net.coreprotect.config.Config;
import net.coreprotect.consumer.Queue;
public final class BlockBurnListener extends Queue implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
protected void onBlockBurn(BlockBurnEvent event) {
World world = event.getBlock().getWorld();
if (!event.isCancelled() && Config.getConfig(world).BLOCK_BURN) {
BlockBreakListener.processBlockBreak(null, "#fire", event.getBlock(), true, BlockUtil.NONE);
}
}
}

View File

@ -0,0 +1,118 @@
package net.coreprotect.listener.block;
import java.util.Arrays;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Lightable;
import org.bukkit.block.data.Waterlogged;
import org.bukkit.block.data.type.Dispenser;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockDispenseEvent;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import net.coreprotect.bukkit.BukkitAdapter;
import net.coreprotect.config.Config;
import net.coreprotect.consumer.Queue;
import net.coreprotect.listener.player.InventoryChangeListener;
import net.coreprotect.model.BlockGroup;
import net.coreprotect.thread.CacheHandler;
public final class BlockDispenseListener extends Queue implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
protected void onBlockDispense(BlockDispenseEvent event) {
Block block = event.getBlock();
World world = block.getWorld();
if (!event.isCancelled() && Config.getConfig(world).BLOCK_PLACE) {
BlockData blockData = block.getBlockData();
ItemStack item = event.getItem();
if (item != null && blockData instanceof Dispenser) {
Dispenser dispenser = (Dispenser) blockData;
Material material = item.getType();
Material type = Material.AIR;
String user = "#dispenser";
boolean forceItem = true;
Block newBlock = block.getRelative(dispenser.getFacing());
BlockData newBlockData = newBlock.getBlockData();
Location velocityLocation = event.getVelocity().toLocation(world);
boolean dispenseSuccess = !event.getVelocity().equals(new Vector()); // true if velocity is set
boolean dispenseRelative = newBlock.getLocation().equals(velocityLocation); // true if velocity location matches relative location
if (dispenseRelative || material.equals(Material.FLINT_AND_STEEL) || material.equals(Material.SHEARS)) {
forceItem = false;
}
if (block.getType() == Material.DROPPER) {
forceItem = true; // droppers always drop items
}
ItemStack[] inventory = ((InventoryHolder) block.getState()).getInventory().getStorageContents();
if (forceItem) {
inventory = Arrays.copyOf(inventory, inventory.length + 1);
inventory[inventory.length - 1] = item;
}
InventoryChangeListener.inventoryTransaction(user, block.getLocation(), inventory);
if (material.equals(Material.WATER_BUCKET)) {
type = Material.WATER;
user = "#water";
}
else if (material.equals(Material.LAVA_BUCKET)) {
type = Material.LAVA;
user = "#lava";
}
else if (material.equals(Material.FLINT_AND_STEEL)) {
type = Material.FIRE;
user = "#fire";
}
else {
type = BukkitAdapter.ADAPTER.getBucketContents(material);
}
if (!dispenseSuccess && material == Material.BONE_MEAL) {
CacheHandler.redstoneCache.put(newBlock.getLocation(), new Object[] { System.currentTimeMillis(), user });
}
if (type == Material.FIRE && (!Config.getConfig(world).BLOCK_IGNITE || !(newBlockData instanceof Lightable))) {
return;
}
else if (type != Material.FIRE && (!Config.getConfig(world).BUCKETS || (!Config.getConfig(world).WATER_FLOW && type.equals(Material.WATER)) || (!Config.getConfig(world).LAVA_FLOW && type.equals(Material.LAVA)))) {
return;
}
if (!type.equals(Material.AIR)) {
if (type == Material.FIRE) { // lit a lightable block
type = newBlock.getType();
if (BlockGroup.LIGHTABLES.contains(type)) {
Lightable lightable = (Lightable) newBlockData;
lightable.setLit(true);
queueBlockPlace(user, newBlock.getState(), newBlock.getType(), newBlock.getState(), type, -1, 0, newBlockData.getAsString());
}
}
else if (dispenseRelative) {
BlockState blockState = newBlock.getState();
if (type.equals(Material.WATER)) {
if (newBlockData instanceof Waterlogged) {
blockState = null;
}
}
queueBlockPlace(user, newBlock.getState(), newBlock.getType(), blockState, type, 1, 1, null);
}
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More