Compare commits

...

18 Commits

Author SHA1 Message Date
Jon Huang 82a7e28759
Merge 33616a61c3 into f3c631bbf5 2024-05-03 20:19:26 -06:00
Intelli f3c631bbf5 Added thread-safe logPlacement and logRemoval API methods 2024-05-03 12:57:27 -06:00
Jon Huang 33616a61c3
Merge pull request #1 from PseudoResonance/postgresql
Fix Postgres lookups/JDBC parameter config option
2024-04-30 10:26:00 +08:00
PseudoResonance 6744c42c42
Fix formatting
Signed-off-by: PseudoResonance <kaio11604@gmail.com>
2024-04-16 07:35:16 -07:00
PseudoResonance c7931d83c1
Fix Postgres lookup
Disables index hinting for Postgres
Adds subquery aliases when creating unions

Signed-off-by: PseudoResonance <kaio11604@gmail.com>
2024-04-16 07:30:23 -07:00
PseudoResonance 5922523326
Add extra JDBC parameter config option
Config option to supply extra parameters to the JDBC string for advanced cases.
Example: Useful for connecting to Postgres behind pgbouncer when set to ?prepareThreshold=0

Signed-off-by: PseudoResonance <kaio11604@gmail.com>
2024-04-16 07:28:57 -07:00
Jon Huang 2b4c101ed7 Fix. 2024-02-11 20:15:33 -08:00
Jon Huang 8e4e2368af Set db type to mysql if mysql is enabled. 2024-01-30 20:37:35 -08:00
Jon Huang 4471ee208d Migrate database options. 2024-01-30 20:10:14 -08:00
Jon Huang 3d317fb0e5 Update. 2024-01-30 19:14:26 -08:00
Jon Huang 0494c31775 Fix. 2024-01-30 14:13:46 -08:00
Jon Huang 19382da778 Fix. 2024-01-30 13:30:57 -08:00
Jon Huang 53176ab0c9 Update. 2024-01-30 13:01:11 -08:00
Jon Huang f07c0a7df8 Refactor. 2024-01-30 09:02:47 -08:00
Jon Huang c77ee07727 Update. 2024-01-30 09:34:49 -07:00
Jon Huang 0695bb751b Update. 2024-01-30 09:23:55 -07:00
Jon Huang 0a235c0f5d Update. 2024-01-29 23:45:53 -08:00
Jon Huang 37b56103e1 Add PostgreSQL support. 2024-01-29 19:53:48 -08:00
47 changed files with 1173 additions and 344 deletions

526
docs/api/version/v10.md Normal file
View File

@ -0,0 +1,526 @@
# API Version 10
The CoreProtect API enables you to log your own block changes, perform lookups, rollbacks, restores, and more.
| API Details | |
| --- | --- |
| **API Version:** | 10 |
| **Plugin Version:** | v23.0+ |
| **Maven:** | [maven.playpro.com](https://maven.playpro.com) |
---
## Upgrading from API v9
The changes from the previous API version are as follows:
- The following methods have been added:
```java
logPlacement(String user, BlockState blockState)
logRemoval(String user, BlockState blockState)
```
---
## Getting Started
Ensure you're using CoreProtect 21.0 or higher. Add it as an external jar to your plugin in your IDE.
Alternatively, if using Maven, you can add it via the repository [https://maven.playpro.com](https://maven.playpro.com) (net.coreprotect, 21.0).
The first thing you need to do is get access to CoreProtect. You can do this by using code similar to the following:
```java
import net.coreprotect.CoreProtect;
import net.coreprotect.CoreProtectAPI;
private CoreProtectAPI getCoreProtect() {
Plugin plugin = getServer().getPluginManager().getPlugin("CoreProtect");
// Check that CoreProtect is loaded
if (plugin == null || !(plugin instanceof CoreProtect)) {
return null;
}
// Check that the API is enabled
CoreProtectAPI CoreProtect = ((CoreProtect) plugin).getAPI();
if (CoreProtect.isEnabled() == false) {
return null;
}
// Check that a compatible version of the API is loaded
if (CoreProtect.APIVersion() < 9) {
return null;
}
return CoreProtect;
}
```
With this code, you can then access the API with a call like the following:
```java
CoreProtectAPI api = getCoreProtect();
if (api != null){ // Ensure we have access to the API
api.testAPI(); // Will print out "[CoreProtect] API test successful." in the console.
}
```
Yay, you're now using the CoreProtect API!
---
## API Overview
### Available Methods
```java
boolean isEnabled()
void testAPI()
List<String[]> performLookup(int time, List<String> restrict_users, List<String> exclude_users, List<Object> restrict_blocks, List<Object> exclude_blocks, List<Integer> action_list, int radius, Location radius_location)
List<String[]> performRollback(int time, List<String> restrict_users, List<String> exclude_users, List<Object> restrict_blocks, List<Object> exclude_blocks, List<Integer> action_list, int radius, Location radius_location)
List<String[]> performRestore(int time, List<String> restrict_users, List<String> exclude_users, List<Object> restrict_blocks, List<Object> exclude_blocks, List<Integer> action_list, int radius, Location radius_location)
List<String[]> blockLookup(Block block, int time)
List<String[]> sessionLookup(String user, int time)
List<String[]> queueLookup(Block block)
ParseResult parseResult(String[] result)
boolean logChat(Player player, String message)
boolean logCommand(Player player, String command)
boolean logPlacement(String user, BlockState blockState)
boolean logPlacement(String user, Location location, Material type, BlockData blockData)
boolean logRemoval(String user, BlockState blockState)
boolean logRemoval(String user, Location location, Material type, BlockData blockData)
boolean logContainerTransaction(String user, Location location)
boolean logInteraction(String user, Location location)
boolean hasPlaced(String user, Block block, int time, int offset)
boolean hasRemoved(String user, Block block, int time, int offset)
void performPurge(int time)
```
---
### Available Events
*The following events are emitted by CoreProtect.*
#### CoreProtectPreLogEvent
Fired when a CoreProtect logger is about to log an action. Cancellable.
| Property | Description | Mutable |
| --- | --- | --- |
| User | The name of the user under which this action will be logged. | Yes |
| Cancelled | If cancelled, the action won't be logged to the database. | Yes |
---
### Method Usage
*Detailed method information is listed below.*
#### `isEnabled()`
Calling this will return true if the server has the CoreProtect API enabled, and false if it does not.
---
#### `testAPI()`
Running this will print out "[CoreProtect] API Test Successful." in the server console.
---
#### `performLookup(int time, List<String> restrict_users, List<String> exclude_users, List<Object> restrict_blocks, List<Object> exclude_blocks, List<Integer> action_list, int radius, Location radius_location)`
This will perform a lookup.
* **time:** Specify the amount of time to search back. "5" would return results from the last 5 seconds.
* **restrict_users:** Specify any usernames to perform the lookup on. Can be set to "null" if both a radius and a location are specified.
* **exclude_users:** Specify any usernames to exclude from the lookup. Can be set to "null".
* **restrict_blocks:** Specify a list of EntityType's or Material's to restrict the search to. Can be set to "null".
* **exclude_blocks:** Specify a list of EntityType's or Material's to exclude from the search. Can be set to "null".
* **action_list:** Specify a list of action types to restrict the search to. Can be set to "null"
* **radius:** Specify a radius to restrict the search to. A location must be specified if using this. Set to "0" to disable.
* **radius_location:** Specify a location to search around. Can be set to "null" if no radius is specified, and a user is specified.
---
#### `performRollback(int time, List<String> restrict_users, List<String> exclude_users, List<Object> restrict_blocks, List<Object> exclude_blocks, List<Integer> action_list, int radius, Location radius_location)`
This will perform a rollback. Method must be called async.
* **time:** Specify the amount of time to rollback. "5" would return results from the last 5 seconds.
* **restrict_users:** Specify any usernames to perform the rollback on. Can be set to "null" if both a radius and a location are specified.
* **exclude_users:** Specify any usernames to exclude from the rollback. Can be set to "null".
* **restrict_blocks:** Specify a list of EntityType's or Material's to restrict the rollback to. Can be set to "null".
* **exclude_blocks:** Specify a list of EntityType's or Material's to exclude from the rollback. Can be set to "null".
* **action_list:** Specify a list of action types to restrict the rollback to. Can be set to "null"
* **radius:** Specify a radius to restrict the rollback to. A location must be specified if using this. Set to "0" to disable.
* **radius_location:** Specify a location to rollback around. Can be set to "null" if no radius is specified, and a user is specified.
---
#### `performRestore(int time, List<String> restrict_users, List<String> exclude_users, List<Object> restrict_blocks, List<Object> exclude_blocks, List<Integer> action_list, int radius, Location radius_location)`
This will perform a restore.
* **time:** Specify the amount of time to restore. "5" would return results from the last 5 seconds.
* **restrict_users:** Specify any usernames to perform the restore on. Can be set to "null" if both a radius and a location are specified.
* **exclude_users:** Specify any usernames to exclude from the restore. Can be set to "null".
* **restrict_blocks:** Specify a list of EntityType's or Material's to restrict the restore to. Can be set to "null".
* **exclude_blocks:** Specify a list of EntityType's or Material's to exclude from the restore. Can be set to "null".
* **action_list:** Specify a list of action types to restrict the restore to. Can be set to "null"
* **radius:** Specify a radius to restrict the restore to. A location must be specified if using this. Set to "0" to disable.
* **radius_location:** Specify a location to restore around. Can be set to "null" if no radius is specified, and a user is specified.
---
#### `blockLookup(Block block, int time)`
This will perform a full lookup on a single block.
* **block:** The block to perform the lookup on.
* **time:** Specify the amount of time to lookup. "5" would return results from the last 5 seconds.
---
#### `queueLookup(Block block)`
This will search the consumer queue for changes on a block not yet saved in the database.
* **block:** The block to perform the lookup on.
---
#### `sessionLookup(String user, int time)`
This will perform a session lookup on a single player.
* **user:** The username to perform the lookup on.
* **time:** Specify the amount of time to lookup. "5" would return results from the last 5 seconds.
---
#### `ParseResult parseResult(String[] result)`
This will parse results from a lookup. You'll then be able to view the following:
* **getX():** Get the X coordinate of the block.
* **getY():** Get the Y coordinate of the block.
* **getZ():** Get the Z coordinate of the block.
* **getType():** Get the Material of the block.
* **getBlockData():** Get the BlockData of the block.
* **getPlayer():** Get the username as a string.
* **getTimestamp():** Get the time of the action.
* **getActionId():** Get the action ID. (0=removed, 1=placed, 2=interaction)
* **getActionString():** Get the action as a string. (Removal, Placement, Interaction)
* **isRolledBack():** If the block is currently rolled back or not.
* **worldName():** The name of the world the block is located in.
---
#### `logPlacement(String user, BlockState blockState)`
This will log a block as being placed. *(Thread safe)*
* **user:** Specify the username to log as having placed the block.
* **blockState:** Specify the BlockState of the block you're logging.
---
#### `logPlacement(String user, Location location, Material type, BlockData blockData)`
This will log a block as being placed.
* **user:** Specify the username to log as having placed the block.
* **location:** Specify the location of the block you're logging.
* **type:** Specify the Material of the block you're logging.
* **blockData:** Specify the BlockData of the block you're logging. Can be set to "null".
---
#### `logRemoval(String user, BlockState blockState)`
This will log a block as being removed/broken. *(Thread safe)*
* **user:** Specify the username to log as having removed the block.
* **blockState:** Specify the BlockState of the block you're logging.
---
#### `logRemoval(String user, Location location, Material type, BlockData blockData)`
This will log a block as being removed/broken, and will log the block's inventory (if applicable).
* **user:** Specify the username to log as having removed the block.
* **location:** Specify the location of the block you're logging.
* **type:** Specify the Material of the block you're logging.
* **blockData:** Specify the BlockData of the block you're logging. Can be set to "null".
---
#### `logContainerTransaction(String user, Location location)`
This will log any transactions made to a block's inventory immediately after calling the method.
* **user:** Specify the username to log as having added/removed the items.
* **location:** Specify the location of the block inventory you're logging.
---
#### `logInteraction(String user, Location location)`
This will log a block as having been interacted with.
* **user:** Specify the username to log as having caused the interaction.
* **location:** Specify the location of the interaction you're logging.
---
#### `hasPlaced(String user, Block block, int time, int offset)`
This will return true if a user has already placed a block at the location within the specified time limit.
* **user:** The username you're checking to see if they've placed a block already.
* **block:** The block you're checking.
* **time:** How far back to check. "5" would only check through the last 5 seconds of logged blocks.
* **offset:** A time offset. "2" would ignore the last 2 seconds of most recently ignored data. (0 = no offset)
---
#### `hasRemoved(String user, Block block, int time, int offset)`
This will return true if a user has already removed a block at the location within the specified time limit.
* **user:** The username you're checking to see if they've removed a block already.
* **block:** The block you're checking.
* **time:** How far back to check. "5" would only check through the last 5 seconds of logged blocks.
* **offset:** A time offset. "2" would ignore the last 2 seconds of most recently ignored data. (0 = no offset)
---
#### `performPurge(int time)`
This will perform a purge on the CoreProtect database.
* **time:** Purge any data earlier than this. "120" would purge any data older than 120 seconds (2 minutes).
---
### Examples
- Get the last 60 seconds of block data for the user "Notch".
```java
CoreProtectAPI CoreProtect = getCoreProtect();
if (CoreProtect != null){ // Ensure we have access to the API
List<String[]> lookup = CoreProtect.performLookup(60, Arrays.asList("Notch"), null, null, null, null, 0, null);
if (lookup != null){
for (String[] result : lookup){
ParseResult parseResult = CoreProtect.parseResult(result);
int x = parseResult.getX();
int y = parseResult.getY();
int z = parseResult.getZ();
// ...
}
}
}
```
---
- Get the last 60 seconds of block data for the user "Notch", excluding dirt and grass blocks.
```java
CoreProtectAPI CoreProtect = getCoreProtect();
if (CoreProtect != null){ // Ensure we have access to the API
List<Object> exclude = Arrays.asList(Material.DIRT, Material.GRASS);
List<String[]> lookup = CoreProtect.performLookup(60, Arrays.asList("Notch"), null, null, exclude, null, 0, null);
if (lookup != null){
for (String[] value : lookup){
ParseResult result = CoreProtect.parseResult(value);
int x = result.getX();
int y = result.getY();
int z = result.getZ();
// ...
}
}
}
```
---
- Get the last 60 seconds of block data within 5 blocks of a location.
```java
CoreProtectAPI CoreProtect = getCoreProtect();
if (CoreProtect != null){ // Ensure we have access to the API
List<String[]> lookup = CoreProtect.performLookup(60, null, null, null, null, null, 5, location);
if (lookup != null){
for (String[] value : lookup){
ParseResult result = CoreProtect.parseResult(value);
int x = result.getX();
int y = result.getY();
int z = result.getZ();
// ...
}
}
}
```
---
- Rollbacks / restores use the same code structure as the above examples. For example:
```java
class BasicThread implements Runnable {
@Override
public void run() {
try {
CoreProtectAPI CoreProtect = getCoreProtect();
if (CoreProtect != null){ // Ensure we have access to the API
List<String[]> lookup = CoreProtect.performRollback(60, Arrays.asList("Notch"), null, null, null, null, 0, null);
if (lookup != null){
for (String[] value : lookup){
ParseResult result = CoreProtect.parseResult(value);
int x = result.getX();
int y = result.getY();
int z = result.getZ();
// ...
}
}
}
}
catch (Exception e){
e.printStackTrace();
}
}
}
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
```
---
- Check if the user "Notch" has already placed a block at a location within the last 60 seconds.
```java
CoreProtectAPI CoreProtect = getCoreProtect();
if (CoreProtect != null){ // Ensure we have access to the API
boolean hasPlaced = CoreProtect.hasPlaced("Notch", block, 60, 0);
// Search queue for pending changes
if (!hasPlaced){
List<String[]> lookup = CoreProtect.queueLookup(block);
for (String[] result : lookup){
ParseResult parseResult = CoreProtect.parseResult(result);
if (parseResult.getActionId()==1 && parseResult.getPlayer().equals("Notch")){
hasPlaced = true;
break;
}
}
}
}
```
---
- Get the last 60 seconds of block data for a specific block.
```java
CoreProtectAPI CoreProtect = getCoreProtect();
if (CoreProtect != null){ // Ensure we have access to the API
List<String[]> lookup = CoreProtect.blockLookup(block, 60);
if (lookup != null){
for (String[] result : lookup){
ParseResult parseResult = CoreProtect.parseResult(result);
int x = parseResult.getX();
int y = parseResult.getY();
int z = parseResult.getZ();
// ...
}
}
}
```
---
- Get the last 1 day of session data for the user "Notch".
```java
CoreProtectAPI CoreProtect = getCoreProtect();
if (CoreProtect != null){ // Ensure we have access to the API
List<String[]> lookup = CoreProtect.sessionLookup("Notch", (24 * 60 * 60));
if (lookup != null){
for (String[] result : lookup){
ParseResult parseResult = CoreProtect.parseResult(result);
int x = parseResult.getX();
int y = parseResult.getY();
int z = parseResult.getZ();
int action = parseResult.getActionId(); // 0 = logout, 1 = login
// ...
}
}
}
```
---
- Log the placement of a block at a location by the user "Notch".
```java
CoreProtectAPI CoreProtect = getCoreProtect();
if (CoreProtect != null){ // Ensure we have access to the API
boolean success = CoreProtect.logPlacement("Notch", block.getLocation(), block.getType(), block.getData());
}
```
---
- Log adding/remove items in a chest (or some other block inventory).
```java
CoreProtectAPI CoreProtect = getCoreProtect();
if (CoreProtect != null){ // Ensure we have access to the API
boolean success = CoreProtect.logContainerTransaction("Notch", inventory.getLocation());
// modify your container contents immediately after (e.g. [i]inventory.addItem(itemStack);[/i])
}
```
---
- Perform a multi-threaded placement check to see if the user "Notch" has already placed a block at a location within the last 60 seconds. This ignores the most recent 1 second of logged data, to account for the fact that that new block data may have already been logged, depending on your code.
```java
final Block block = null; //Should be an actual block
class BasicThread implements Runnable {
@Override
public void run() {
try {
CoreProtectAPI CoreProtect = getCoreProtect();
if (CoreProtect != null){ // Ensure we have access to the API
boolean hasPlaced = CoreProtect.hasPlaced("Notch", block, 60, 1);
}
}
catch (Exception e){
e.printStackTrace();
}
}
}
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
```
---

View File

@ -125,6 +125,7 @@ MISSING_PARAMETERS: "Please use \"{0}\"."
MISSING_ROLLBACK_RADIUS: "You did not specify a {rollback|restore} radius."
MISSING_ROLLBACK_USER: "You did not specify a {rollback|restore} user."
MYSQL_UNAVAILABLE: "Unable to connect to MySQL server."
PGSQL_UNAVAILABLE: "Unable to connect to PostgreSQL server."
NETWORK_CONNECTION: "Connection by {0} {successful|failed}. Using {1} {2}."
NETWORK_TEST: "Network test data has been successful sent."
NO_DATA: "No data found at {0}."
@ -196,6 +197,7 @@ UPGRADE_IN_PROGRESS: "Upgrade in progress. Please try again later."
USER_NOT_FOUND: "User \"{0}\" not found."
USER_OFFLINE: "The user \"{0}\" is not online."
USING_MYSQL: "Using MySQL for data storage."
USING_PGSQL: "Using PostgreSQL for data storage."
USING_SQLITE: "Using SQLite for data storage."
VALID_DONATION_KEY: "Valid donation key."
VERSION_NOTICE: "Version {0} is now available."

View File

@ -129,5 +129,10 @@
<artifactId>HikariCP</artifactId>
<version>5.0.1</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.1</version>
</dependency>
</dependencies>
</project>

View File

@ -88,11 +88,19 @@ public final class CoreProtect extends JavaPlugin {
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));
switch (Config.getGlobal().DB_TYPE) {
case MYSQL: {
Chat.console(Phrase.build(Phrase.USING_MYSQL));
break;
}
case PGSQL: {
Chat.console(Phrase.build(Phrase.USING_PGSQL));
break;
}
case SQLITE: {
Chat.console(Phrase.build(Phrase.USING_SQLITE));
break;
}
}
Chat.console("--------------------");

View File

@ -168,7 +168,7 @@ public class CoreProtectAPI extends Queue {
}
public int APIVersion() {
return 9;
return 10;
}
public List<String[]> blockLookup(Block block, int time) {
@ -282,6 +282,19 @@ public class CoreProtectAPI extends Queue {
return false;
}
public boolean logPlacement(String user, BlockState blockState) {
if (!Config.getGlobal().API_ENABLED) {
return false;
}
if (blockState == null || user == null || user.length() == 0) {
return false;
}
Queue.queueBlockPlace(user, blockState, blockState.getType(), null, blockState.getType(), -1, 0, blockState.getBlockData().getAsString());
return true;
}
public boolean logPlacement(String user, Location location, Material type, BlockData blockData) {
if (Config.getGlobal().API_ENABLED) {
if (user != null && location != null) {
@ -316,6 +329,19 @@ public class CoreProtectAPI extends Queue {
return false;
}
public boolean logRemoval(String user, BlockState blockState) {
if (!Config.getGlobal().API_ENABLED) {
return false;
}
if (blockState == null || user == null || user.length() == 0) {
return false;
}
Queue.queueBlockBreak(user, blockState, blockState.getType(), blockState.getBlockData().getAsString(), 0);
return true;
}
public boolean logRemoval(String user, Location location, Material type, BlockData blockData) {
if (Config.getGlobal().API_ENABLED) {
if (user != null && location != null) {

View File

@ -1,8 +1,8 @@
package net.coreprotect.api;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
@ -10,6 +10,7 @@ import org.bukkit.block.Block;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.Database;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.utility.Util;
@ -37,32 +38,34 @@ public class BlockAPI {
return result;
}
Statement statement = connection.createStatement();
String query = "SELECT time,user,action,type,data,blockdata,rolled_back FROM " + ConfigHandler.prefix + "block " + Util.getWidIndex("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);
try (PreparedStatement ps = connection.prepareStatement("SELECT time, \"user\", action, type, data, blockdata, rolled_back FROM " + StatementUtils.getTableName("block") + " " + Util.getWidIndex("block") + "WHERE wid = ? AND x = ? AND z = ? AND y = ? AND time > ? ORDER BY rowid DESC")) {
ps.setInt(1, worldId);
ps.setInt(2, x);
ps.setInt(3, z);
ps.setInt(4, y);
ps.setInt(5, checkTime);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
String resultTime = rs.getString("time");
int resultUserId = rs.getInt("user");
String resultAction = rs.getString("action");
int resultType = rs.getInt("type");
String resultData = rs.getString("data");
byte[] resultBlockData = rs.getBytes("blockdata");
String resultRolledBack = rs.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);
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[] 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);
}
}
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();
}
catch (Exception e) {
} catch (Exception e) {
e.printStackTrace();
}

View File

@ -1,8 +1,8 @@
package net.coreprotect.api;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@ -10,6 +10,7 @@ import java.util.Locale;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.Database;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.database.statement.UserStatement;
public class SessionLookup {
@ -43,27 +44,28 @@ public class SessionLookup {
}
int userId = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
try (Statement statement = connection.createStatement()) {
String query = "SELECT time,user,wid,x,y,z,action FROM " + ConfigHandler.prefix + "session WHERE user = '" + userId + "' 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 resultWorldId = results.getString("wid");
String resultX = results.getString("x");
String resultY = results.getString("y");
String resultZ = results.getString("z");
String resultAction = results.getString("action");
try (PreparedStatement statement = connection.prepareStatement("SELECT time, \"user\", wid, x, y, z, action FROM " + StatementUtils.getTableName("session") + " WHERE \"user\" = ? AND time > ? ORDER BY rowid DESC")) {
statement.setInt(1, userId);
statement.setInt(2, checkTime);
try (ResultSet results = statement.executeQuery()) {
while (results.next()) {
String resultTime = results.getString("time");
int resultUserId = results.getInt("user");
String resultWorldId = results.getString("wid");
String resultX = results.getString("x");
String resultY = results.getString("y");
String resultZ = results.getString("z");
String resultAction = results.getString("action");
if (ConfigHandler.playerIdCacheReversed.get(resultUserId) == null) {
UserStatement.loadName(connection, resultUserId);
if (ConfigHandler.playerIdCacheReversed.get(resultUserId) == null) {
UserStatement.loadName(connection, resultUserId);
}
String resultUser = ConfigHandler.playerIdCacheReversed.get(resultUserId);
String[] lookupData = new String[] { resultTime, resultUser, resultX, resultY, resultZ, resultWorldId, type, resultAction };
result.add(lookupData);
}
String resultUser = ConfigHandler.playerIdCacheReversed.get(resultUserId);
String[] lookupData = new String[] { resultTime, resultUser, resultX, resultY, resultZ, resultWorldId, type, resultAction };
result.add(lookupData);
}
results.close();
}
}
catch (Exception e) {

View File

@ -15,8 +15,10 @@ import org.bukkit.entity.Player;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.database.Database;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.patch.Patch;
@ -132,16 +134,13 @@ public class PurgeCommand extends Consumer {
}
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();
if (Config.getGlobal().DB_TYPE == DatabaseType.SQLITE) {
try (PreparedStatement ps = connection.prepareStatement("ATTACH DATABASE '" + ConfigHandler.path + ConfigHandler.sqlite + ".tmp' AS tmp_db")) {
ps.execute();
}
purgePrefix = "tmp_db." + ConfigHandler.prefix;
}
@ -154,15 +153,11 @@ public class PurgeCommand extends Consumer {
return;
}
if (!Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE == DatabaseType.SQLITE) {
for (String table : ConfigHandler.databaseTables) {
try {
query = "DROP TABLE IF EXISTS " + purgePrefix + table + "";
preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
preparedStmt.close();
}
catch (Exception e) {
try (PreparedStatement ps = connection.prepareStatement("DROP TABLE IF EXISTS " + purgePrefix + table)) {
ps.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
@ -177,21 +172,22 @@ public class PurgeCommand extends Consumer {
String tableName = table.replaceAll("_", " ");
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_PROCESSING, tableName));
if (!Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE == DatabaseType.SQLITE) {
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;
try (PreparedStatement ps = connection.prepareStatement("SELECT * FROM " + purgePrefix + table);
ResultSet rs = ps.executeQuery();) {
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)) {
@ -205,10 +201,9 @@ public class PurgeCommand extends Consumer {
timeLimit = " WHERE (time >= '" + timeEnd + "' OR time < '" + timeStart + "')";
}
}
query = "INSERT INTO " + purgePrefix + table + " SELECT " + columns + " FROM " + ConfigHandler.prefix + table + timeLimit;
preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
preparedStmt.close();
try (PreparedStatement ps = connection.prepareStatement("INSERT INTO " + purgePrefix + table + " SELECT " + columns + " FROM " + StatementUtils.getTableName(table) + timeLimit)) {
ps.execute();
}
}
catch (Exception e) {
error = true;
@ -220,21 +215,15 @@ public class PurgeCommand extends Consumer {
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();
try (PreparedStatement ps = connection.prepareStatement("DELETE FROM " + purgePrefix + table)) {
ps.execute();
}
catch (Exception e) {
e.printStackTrace();
}
try {
query = "REINDEX " + ConfigHandler.prefix + table;
preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
preparedStmt.close();
try (PreparedStatement ps = connection.prepareStatement("REINDEX " + StatementUtils.getTableName(table))) {
ps.execute();
}
catch (Exception e) {
e.printStackTrace();
@ -242,10 +231,9 @@ public class PurgeCommand extends Consumer {
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();
try (PreparedStatement ps = connection.prepareStatement("INSERT INTO " + purgePrefix + table + " SELECT " + columns + " FROM " + StatementUtils.getTableName(table) + index)) {
ps.execute();
}
}
catch (Exception e) {
e.printStackTrace();
@ -265,10 +253,9 @@ public class PurgeCommand extends Consumer {
}
if (purge) {
query = "DELETE FROM " + purgePrefix + table + " WHERE time < '" + timeEnd + "' AND time >= '" + timeStart + "'" + worldRestriction;
preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
preparedStmt.close();
try (PreparedStatement ps = connection.prepareStatement("DELETE FROM " + purgePrefix + table + " WHERE time < '" + timeEnd + "' AND time >= '" + timeStart + "'" + worldRestriction)) {
ps.execute();
}
}
}
catch (Exception e) {
@ -278,32 +265,22 @@ public class PurgeCommand extends Consumer {
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();
try (PreparedStatement ps = connection.prepareStatement("SELECT COUNT(*) as count FROM " + StatementUtils.getTableName(table) + " LIMIT 1");
ResultSet resultSet = ps.executeQuery();) {
while (resultSet.next()) {
oldCount = resultSet.getInt("count");
}
resultSet.close();
preparedStmt.close();
}
catch (Exception e) {
} 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();
try (PreparedStatement ps = connection.prepareStatement("SELECT COUNT(*) as count FROM " + purgePrefix + table + " LIMIT 1");
ResultSet resultSet = ps.executeQuery();) {
while (resultSet.next()) {
new_count = resultSet.getInt("count");
}
resultSet.close();
preparedStmt.close();
}
catch (Exception e) {
} catch (Exception e) {
e.printStackTrace();
}
@ -311,24 +288,28 @@ public class PurgeCommand extends Consumer {
}
}
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE != DatabaseType.SQLITE) {
try {
boolean purge = purgeTables.contains(table);
String worldRestriction = "";
if (argWid > 0 && worldTables.contains(table)) {
worldRestriction = " AND wid = '" + argWid + "'";
worldRestriction = " AND wid = ?";
}
else if (argWid > 0) {
purge = false;
}
if (purge) {
query = "DELETE FROM " + ConfigHandler.prefix + table + " WHERE time < '" + timeEnd + "' AND time >= '" + timeStart + "'" + worldRestriction;
preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
removed = removed + preparedStmt.getUpdateCount();
preparedStmt.close();
try (PreparedStatement preparedStmt = connection.prepareStatement("DELETE FROM " + StatementUtils.getTableName(table) + " WHERE time < ? AND time >= ?" + worldRestriction)) {
preparedStmt.setLong(1, timeEnd);
preparedStmt.setLong(2, timeStart);
if (!worldRestriction.isEmpty()) {
preparedStmt.setInt(3, argWid);
}
preparedStmt.execute();
removed = removed + preparedStmt.getUpdateCount();
}
}
}
catch (Exception e) {
@ -342,20 +323,37 @@ public class PurgeCommand extends Consumer {
}
}
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();
if (optimize) {
switch (Config.getGlobal().DB_TYPE) {
case MYSQL: {
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_OPTIMIZING));
for (String table : ConfigHandler.databaseTables) {
try (PreparedStatement preparedStmt = connection.prepareStatement("OPTIMIZE LOCAL TABLE " + StatementUtils.getTableName(table))) {
preparedStmt.execute();
}
}
break;
}
case PGSQL: {
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_OPTIMIZING));
for (String table : ConfigHandler.databaseTables) {
try (PreparedStatement preparedStmt = connection.prepareStatement("VACUUM ANALYZE " + StatementUtils.getTableName(table))) {
preparedStmt.execute();
}
}
break;
}
default: {
// no optimization options for SQLite
break;
}
}
}
connection.close();
if (abort) {
if (!Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE == DatabaseType.SQLITE) {
(new File(ConfigHandler.path + ConfigHandler.sqlite + ".tmp")).delete();
}
ConfigHandler.loadDatabase();
@ -365,7 +363,7 @@ public class PurgeCommand extends Consumer {
return;
}
if (!Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE == DatabaseType.SQLITE) {
(new File(ConfigHandler.path + ConfigHandler.sqlite)).delete();
(new File(ConfigHandler.path + ConfigHandler.sqlite + ".tmp")).renameTo(new File(ConfigHandler.path + ConfigHandler.sqlite));
}

View File

@ -65,11 +65,19 @@ public class StatusCommand {
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);
switch (Config.getGlobal().DB_TYPE) {
case MYSQL: {
Chat.sendMessage(player, Color.DARK_AQUA + Phrase.build(Phrase.STATUS_DATABASE, Color.WHITE, "MySQL") + firstVersion);
break;
}
case PGSQL: {
Chat.sendMessage(player, Color.DARK_AQUA + Phrase.build(Phrase.STATUS_DATABASE, Color.WHITE, "PostgreSQL") + firstVersion);
break;
}
case SQLITE: {
Chat.sendMessage(player, Color.DARK_AQUA + Phrase.build(Phrase.STATUS_DATABASE, Color.WHITE, "SQLite") + firstVersion);
break;
}
}
if (ConfigHandler.worldeditEnabled) {

View File

@ -11,6 +11,7 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.CompletableFuture;
@ -35,11 +36,14 @@ public class Config extends Language {
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 DatabaseType DB_TYPE;
public String DB_PREFIX;
public String DB_HOST;
public int DB_PORT;
public String DB_DATABASE;
public String DB_USERNAME;
public String DB_PASSWORD;
public String DB_JDBC_PARAMETERS;
public String LANGUAGE;
public boolean ENABLE_AWE;
public boolean ENABLE_SSL;
@ -50,7 +54,6 @@ public class Config extends Language {
public boolean HOPPER_FILTER_META;
public boolean EXCLUDE_TNT;
public boolean NETWORK_DEBUG;
public boolean MYSQL;
public boolean CHECK_UPDATES;
public boolean API_ENABLED;
public boolean VERBOSE;
@ -90,19 +93,19 @@ public class Config extends Language {
public boolean USERNAME_CHANGES;
public boolean WORLDEDIT;
public int MAXIMUM_POOL_SIZE;
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("db-type", "sqlite");
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("db-host", "127.0.0.1");
DEFAULT_VALUES.put("db-port", "3306");
DEFAULT_VALUES.put("db-database", "database");
DEFAULT_VALUES.put("db-username", "root");
DEFAULT_VALUES.put("db-password", "");
DEFAULT_VALUES.put("db-jdbc-parameters", "");
DEFAULT_VALUES.put("language", "en");
DEFAULT_VALUES.put("check-updates", "true");
DEFAULT_VALUES.put("api-enabled", "true");
@ -145,7 +148,8 @@ public class Config extends Language {
DEFAULT_VALUES.put("worldedit", "true");
HEADERS.put("donation-key", new String[] { "# CoreProtect is donationware. Obtain a donation key from coreprotect.net/donate/" });
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("db-type", new String[] { "# The database type to use. By default this is \"sqlite\"", "# Available options: sqlite, mysql, pgsql" });
HEADERS.put("db-jdbc-parameters", new String[] { "# Extra parameters to append to the JDBC connection string. Only needed for advanced cases." });
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.", });
@ -201,13 +205,34 @@ public class Config extends Language {
this.UNKNOWN_LOGGING = this.getBoolean("unknown-logging", false);
this.MAXIMUM_POOL_SIZE = this.getInt("maximum-pool-size", 10);
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.DB_TYPE = DatabaseType.valueOf(DatabaseType.class, this.getString("db-type", "sqlite").toUpperCase(Locale.ROOT));
if (this.has("use-mysql") && this.getBoolean("use-mysql")) {
// legacy configuration has mysql enabled
this.DB_TYPE = DatabaseType.MYSQL;
DEFAULT_VALUES.put("db-type", DatabaseType.MYSQL.toString().toLowerCase(Locale.ROOT));
}
this.DB_PREFIX = this.getString("table-prefix");
this.DB_HOST = this.getString("db-host");
if (this.DB_HOST == null && this.has("mysql-host")) {
this.DB_HOST = this.getString("mysql-host");
}
this.DB_PORT = this.getInt("db-port");
if (this.DB_PORT == 0 && this.has("mysql-port")) {
this.DB_PORT = this.getInt("mysql-port");
}
this.DB_DATABASE = this.getString("db-database");
if (this.DB_DATABASE == null && this.has("mysql-database")) {
this.DB_DATABASE = this.getString("mysql-database");
}
this.DB_USERNAME = this.getString("db-username");
if (this.DB_USERNAME == null && this.has("mysql-username")) {
this.DB_USERNAME = this.getString("mysql-username");
}
this.DB_PASSWORD = this.getString("db-password");
if (this.DB_PASSWORD == null && this.has("mysql-password")) {
this.DB_PASSWORD = this.getString("mysql-password");
}
this.DB_JDBC_PARAMETERS = this.getString("db-jdbc-parameters");
this.LANGUAGE = this.getString("language");
this.CHECK_UPDATES = this.getBoolean("check-updates");
this.API_ENABLED = this.getBoolean("api-enabled");
@ -281,6 +306,10 @@ public class Config extends Language {
this.defaults = defaults;
}
private boolean has(final String key) {
return this.config.containsKey(key);
}
private String get(final String key, final String dfl) {
String configured = this.config.get(key);
if (configured == null) {
@ -328,6 +357,11 @@ public class Config extends Language {
return configured == null ? "" : configured;
}
private String getString(final String key, final String dfl) {
final String configured = this.get(key, dfl);
return configured == null ? "" : configured;
}
public void clearConfig() {
this.config.clear();
}

View File

@ -26,6 +26,7 @@ import com.zaxxer.hikari.HikariDataSource;
import net.coreprotect.bukkit.BukkitAdapter;
import net.coreprotect.consumer.Queue;
import net.coreprotect.database.Database;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.listener.ListenerHandler;
@ -51,6 +52,7 @@ public class ConfigHandler extends Queue {
public static String database = "database";
public static String username = "root";
public static String password = "";
public static String jdbcParameters = "";
public static String prefix = "co_";
public static int maximumPoolSize = 10;
@ -167,17 +169,18 @@ public class ConfigHandler extends Queue {
ConfigFile.init(ConfigFile.LANGUAGE_CACHE); // load translation cache
// Enforce "co_" table prefix if using SQLite.
if (!Config.getGlobal().MYSQL) {
Config.getGlobal().PREFIX = "co_";
if (Config.getGlobal().DB_TYPE == DatabaseType.SQLITE) {
Config.getGlobal().DB_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.host = Config.getGlobal().DB_HOST;
ConfigHandler.port = Config.getGlobal().DB_PORT;
ConfigHandler.database = Config.getGlobal().DB_DATABASE;
ConfigHandler.username = Config.getGlobal().DB_USERNAME;
ConfigHandler.password = Config.getGlobal().DB_PASSWORD;
ConfigHandler.jdbcParameters = Config.getGlobal().DB_JDBC_PARAMETERS;
ConfigHandler.maximumPoolSize = Config.getGlobal().MAXIMUM_POOL_SIZE;
ConfigHandler.prefix = Config.getGlobal().PREFIX;
ConfigHandler.prefix = Config.getGlobal().DB_PREFIX;
ConfigHandler.loadBlacklist(); // Load the blacklist file if it exists.
}
@ -190,7 +193,7 @@ public class ConfigHandler extends Queue {
// close old pool when we reload the database, e.g. in purge command
Database.closeConnection();
if (!Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE == DatabaseType.SQLITE) {
try {
File tempFile = File.createTempFile("CoreProtect_" + System.currentTimeMillis(), ".tmp");
tempFile.setExecutable(true);
@ -219,8 +222,7 @@ public class ConfigHandler extends Queue {
catch (Exception e) {
e.printStackTrace();
}
}
else {
} else if (Config.getGlobal().DB_TYPE == DatabaseType.MYSQL){
HikariConfig config = new HikariConfig();
try {
Class.forName("com.mysql.cj.jdbc.Driver");
@ -230,7 +232,7 @@ public class ConfigHandler extends Queue {
config.setDriverClassName("com.mysql.jdbc.Driver");
}
config.setJdbcUrl("jdbc:mysql://" + ConfigHandler.host + ":" + ConfigHandler.port + "/" + ConfigHandler.database);
config.setJdbcUrl("jdbc:mysql://" + ConfigHandler.host + ":" + ConfigHandler.port + "/" + ConfigHandler.database + ConfigHandler.jdbcParameters);
config.setUsername(ConfigHandler.username);
config.setPassword(ConfigHandler.password);
config.setMaximumPoolSize(ConfigHandler.maximumPoolSize);
@ -251,6 +253,21 @@ public class ConfigHandler extends Queue {
config.addDataSourceProperty("allowPublicKeyRetrieval", "true");
config.addDataSourceProperty("useSSL", Config.getGlobal().ENABLE_SSL);
ConfigHandler.hikariDataSource = new HikariDataSource(config);
} else if (Config.getGlobal().DB_TYPE == DatabaseType.PGSQL) {
HikariConfig config = new HikariConfig();
try {
Class.forName("org.postgresql.Driver");
config.setDriverClassName("org.postgresql.Driver");
} catch (Exception e) {
throw new RuntimeException(e);
}
config.setJdbcUrl("jdbc:postgresql://" + ConfigHandler.host + ":" + ConfigHandler.port + "/" + ConfigHandler.database + ConfigHandler.jdbcParameters);
config.setUsername(ConfigHandler.username);
config.setPassword(ConfigHandler.password);
config.setMaxLifetime(300000);
config.setKeepaliveTime(60000);
ConfigHandler.hikariDataSource = new HikariDataSource(config);
}
@ -259,7 +276,7 @@ public class ConfigHandler extends Queue {
public static void loadTypes(Statement statement) {
try {
String query = "SELECT id,material FROM " + ConfigHandler.prefix + "material_map";
String query = "SELECT id,material FROM " + StatementUtils.getTableName("material_map");
ResultSet rs = statement.executeQuery(query);
ConfigHandler.materials.clear();
ConfigHandler.materialsReversed.clear();
@ -276,7 +293,7 @@ public class ConfigHandler extends Queue {
}
rs.close();
query = "SELECT id,data FROM " + ConfigHandler.prefix + "blockdata_map";
query = "SELECT id,data FROM " + StatementUtils.getTableName("blockdata_map");
rs = statement.executeQuery(query);
ConfigHandler.blockdata.clear();
ConfigHandler.blockdataReversed.clear();
@ -293,7 +310,7 @@ public class ConfigHandler extends Queue {
}
rs.close();
query = "SELECT id,art FROM " + ConfigHandler.prefix + "art_map";
query = "SELECT id, art FROM " + StatementUtils.getTableName("art_map");
rs = statement.executeQuery(query);
ConfigHandler.art.clear();
ConfigHandler.artReversed.clear();
@ -310,7 +327,7 @@ public class ConfigHandler extends Queue {
}
rs.close();
query = "SELECT id,entity FROM " + ConfigHandler.prefix + "entity_map";
query = "SELECT id,entity FROM " + StatementUtils.getTableName("entity_map");
rs = statement.executeQuery(query);
ConfigHandler.entities.clear();
ConfigHandler.entitiesReversed.clear();
@ -334,7 +351,7 @@ public class ConfigHandler extends Queue {
public static void loadWorlds(Statement statement) {
try {
String query = "SELECT id,world FROM " + ConfigHandler.prefix + "world";
String query = "SELECT id,world FROM " + StatementUtils.getTableName("world");
ResultSet rs = statement.executeQuery(query);
ConfigHandler.worlds.clear();
ConfigHandler.worldsReversed.clear();
@ -379,7 +396,7 @@ public class ConfigHandler extends Queue {
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";
String query = "SELECT * FROM " + StatementUtils.getTableName("database_lock") + " WHERE rowid='1' AND status='1' AND time >= '" + checkTime + "' LIMIT 1";
ResultSet rs = statement.executeQuery(query);
while (rs.next()) {
if (unixtimestamp < waitTime) {

View File

@ -0,0 +1,7 @@
package net.coreprotect.config;
public enum DatabaseType {
SQLITE,
MYSQL,
PGSQL; // PostgreSQL
}

View File

@ -4,6 +4,7 @@ import java.sql.PreparedStatement;
import java.sql.Statement;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.database.statement.MaterialStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
@ -13,7 +14,7 @@ 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";
String query = "SELECT id FROM " + StatementUtils.getTableName("art_map") + " WHERE id = '" + materialId + "' LIMIT 1";
boolean hasMaterial = MaterialStatement.hasMaterial(statement, query);
if (!hasMaterial) {
MaterialStatement.insert(preparedStmt, batchCount, materialId, (String) name);

View File

@ -4,6 +4,7 @@ import java.sql.PreparedStatement;
import java.sql.Statement;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.database.statement.MaterialStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
@ -13,7 +14,7 @@ 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";
String query = "SELECT id FROM " + StatementUtils.getTableName("blockdata_map") + " WHERE id = '" + materialId + "' LIMIT 1";
boolean hasMaterial = MaterialStatement.hasMaterial(statement, query);
if (!hasMaterial) {
MaterialStatement.insert(preparedStmt, batchCount, materialId, (String) name);

View File

@ -4,6 +4,7 @@ import java.sql.PreparedStatement;
import java.sql.Statement;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.database.statement.MaterialStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
@ -13,7 +14,7 @@ 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";
String query = "SELECT id FROM " + StatementUtils.getTableName("entity_map") + " WHERE id = '" + materialId + "' LIMIT 1";
boolean hasMaterial = MaterialStatement.hasMaterial(statement, query);
if (!hasMaterial) {
MaterialStatement.insert(preparedStmt, batchCount, materialId, (String) name);

View File

@ -6,7 +6,7 @@ import java.util.List;
import org.bukkit.block.BlockState;
import org.bukkit.entity.EntityType;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.database.statement.EntityStatement;
import net.coreprotect.utility.entity.EntityUtil;
@ -16,7 +16,7 @@ class EntitySpawnProcess {
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";
String query = "SELECT data FROM " + StatementUtils.getTableName("entity") + " WHERE rowid='" + rowId + "' LIMIT 1";
List<Object> data = EntityStatement.getData(statement, block, query);
EntityUtil.spawnEntity(block, type, data);
}

View File

@ -4,6 +4,7 @@ import java.sql.PreparedStatement;
import java.sql.Statement;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.database.statement.MaterialStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
@ -13,7 +14,7 @@ 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";
String query = "SELECT id FROM " + StatementUtils.getTableName("material_map") + " WHERE id = '" + materialId + "' LIMIT 1";
boolean hasMaterial = MaterialStatement.hasMaterial(statement, query);
if (!hasMaterial) {
MaterialStatement.insert(preparedStmt, batchCount, materialId, (String) name);

View File

@ -13,6 +13,7 @@ import org.bukkit.Material;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.database.Database;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.database.statement.UserStatement;
public class Process {
@ -58,7 +59,7 @@ public class Process {
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'");
statement.executeUpdate("UPDATE " + StatementUtils.getTableName("database_lock") + " SET status = '" + locked + "', time = '" + unixTimestamp + "' WHERE rowid = '1'");
lastLockUpdate = unixTimestamp;
}
}

View File

@ -6,6 +6,7 @@ import java.util.Locale;
import org.bukkit.block.BlockState;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.database.statement.SignStatement;
import net.coreprotect.utility.Util;
@ -24,12 +25,11 @@ class SignUpdateProcess {
int z = block.getZ();
int wid = Util.getWorldId(block.getWorld().getName());
int userid = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
String query = "";
String query;
if (action == 0) {
query = "SELECT color, color_secondary, data, waxed, face, line_1, line_2, line_3, line_4, line_5, line_6, line_7, line_8 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, color_secondary, data, waxed, face, line_1, line_2, line_3, line_4, line_5, line_6, line_7, line_8 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";
query = "SELECT color, color_secondary, data, waxed, face, line_1, line_2, line_3, line_4, line_5, line_6, line_7, line_8 FROM " + StatementUtils.getTableName("sign") + " WHERE \"user\"='" + userid + "' AND wid='" + wid + "' AND x='" + x + "' AND z='" + z + "' AND y='" + y + "' AND time < '" + time + "' ORDER BY rowid DESC LIMIT 1";
} else {
query = "SELECT color, color_secondary, data, waxed, face, line_1, line_2, line_3, line_4, line_5, line_6, line_7, line_8 FROM " + StatementUtils.getTableName("sign") + " WHERE \"user\"='" + userid + "' AND wid='" + wid + "' AND x='" + x + "' AND z='" + z + "' AND y='" + y + "' AND time >= '" + time + "' ORDER BY rowid ASC LIMIT 1";
}
SignStatement.getData(statement, block, query);
Util.updateBlock(block);

View File

@ -4,9 +4,9 @@ import java.sql.Statement;
import org.bukkit.block.BlockState;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.database.statement.SkullStatement;
import net.coreprotect.utility.Util;
import net.coreprotect.config.ConfigHandler;
class SkullUpdateProcess {
@ -18,7 +18,7 @@ class SkullUpdateProcess {
*/
if (object instanceof BlockState) {
BlockState block = (BlockState) object;
String query = "SELECT owner FROM " + ConfigHandler.prefix + "skull WHERE rowid='" + rowId + "' LIMIT 0, 1";
String query = "SELECT owner FROM " + StatementUtils.getTableName("skull") + " WHERE rowid='" + rowId + "' LIMIT 1";
SkullStatement.getData(statement, block, query);
Util.updateBlock(block);
}

View File

@ -4,6 +4,7 @@ import java.sql.PreparedStatement;
import java.sql.Statement;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.database.statement.MaterialStatement;
import net.coreprotect.database.statement.WorldStatement;
import net.coreprotect.language.Phrase;
@ -14,7 +15,7 @@ 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";
String query = "SELECT id FROM " + StatementUtils.getTableName("world") + " WHERE id = '" + worldId + "' LIMIT 1";
boolean hasMaterial = MaterialStatement.hasMaterial(statement, query);
if (!hasMaterial) {
WorldStatement.insert(preparedStmt, batchCount, worldId, (String) world);

View File

@ -17,6 +17,7 @@ import org.bukkit.inventory.ItemStack;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.consumer.Queue;
import net.coreprotect.consumer.process.Process;
@ -47,11 +48,10 @@ public class Database extends Queue {
Consumer.transacting = true;
try {
if (Config.getGlobal().MYSQL) {
statement.executeUpdate("START TRANSACTION");
}
else {
if (Config.getGlobal().DB_TYPE == DatabaseType.SQLITE) {
statement.executeUpdate("BEGIN TRANSACTION");
} else {
statement.executeUpdate("START TRANSACTION");
}
}
catch (Exception e) {
@ -64,11 +64,10 @@ public class Database extends Queue {
while (true) {
try {
if (Config.getGlobal().MYSQL) {
statement.executeUpdate("COMMIT");
}
else {
if (Config.getGlobal().DB_TYPE == DatabaseType.SQLITE) {
statement.executeUpdate("COMMIT TRANSACTION");
} else {
statement.executeUpdate("COMMIT");
}
}
catch (Exception e) {
@ -90,7 +89,7 @@ public class Database extends Queue {
}
public static void performCheckpoint(Statement statement) throws SQLException {
if (!Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE == DatabaseType.SQLITE) {
statement.executeUpdate("PRAGMA wal_checkpoint(TRUNCATE)");
}
}
@ -107,7 +106,7 @@ public class Database extends Queue {
}
public static boolean hasReturningKeys() {
return (!Config.getGlobal().MYSQL && ConfigHandler.SERVER_VERSION >= 20);
return (Config.getGlobal().DB_TYPE == DatabaseType.SQLITE && ConfigHandler.SERVER_VERSION >= 20);
}
public static void containerBreakCheck(String user, Material type, Object container, ItemStack[] contents, Location location) {
@ -147,18 +146,22 @@ public class Database extends Queue {
if (!force && (ConfigHandler.converterRunning || ConfigHandler.purgeRunning)) {
return connection;
}
if (Config.getGlobal().MYSQL) {
DatabaseType dbType = Config.getGlobal().DB_TYPE;
if (dbType != DatabaseType.SQLITE) {
try {
connection = ConfigHandler.hikariDataSource.getConnection();
ConfigHandler.databaseReachable = true;
}
catch (Exception e) {
ConfigHandler.databaseReachable = false;
Chat.sendConsoleMessage(Color.RED + "[CoreProtect] " + Phrase.build(Phrase.MYSQL_UNAVAILABLE));
if (dbType == DatabaseType.MYSQL) {
Chat.sendConsoleMessage(Color.RED + "[CoreProtect] " + Phrase.build(Phrase.MYSQL_UNAVAILABLE));
} else if (dbType == DatabaseType.PGSQL){
Chat.sendConsoleMessage(Color.RED + "[CoreProtect] " + Phrase.build(Phrase.PGSQL_UNAVAILABLE));
}
e.printStackTrace();
}
}
else {
} else {
if (Consumer.transacting && onlyCheckTransacting) {
Consumer.interrupt = true;
}
@ -202,13 +205,13 @@ public class Database extends Queue {
try {
int rolledBack = Util.toggleRolledBack(rb, (table == 2 || table == 3 || table == 4)); // co_item, co_container, co_block
if (table == 1 || table == 3) {
statement.executeUpdate("UPDATE " + ConfigHandler.prefix + "container SET rolled_back='" + rolledBack + "' WHERE rowid='" + id + "'");
statement.executeUpdate("UPDATE " + StatementUtils.getTableName("container") + " SET rolled_back='" + rolledBack + "' WHERE rowid='" + id + "'");
}
else if (table == 2) {
statement.executeUpdate("UPDATE " + ConfigHandler.prefix + "item SET rolled_back='" + rolledBack + "' WHERE rowid='" + id + "'");
statement.executeUpdate("UPDATE " + StatementUtils.getTableName("item") + " SET rolled_back='" + rolledBack + "' WHERE rowid='" + id + "'");
}
else {
statement.executeUpdate("UPDATE " + ConfigHandler.prefix + "block SET rolled_back='" + rolledBack + "' WHERE rowid='" + id + "'");
statement.executeUpdate("UPDATE " + StatementUtils.getTableName("block") + " SET rolled_back='" + rolledBack + "' WHERE rowid='" + id + "'");
}
}
catch (Exception e) {
@ -219,20 +222,20 @@ public class Database extends Queue {
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, color_secondary, data, waxed, face, line_1, line_2, line_3, line_4, line_5, line_6, line_7, line_8) 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, rolled_back) 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 (?, ?)";
String signInsert = "INSERT INTO " + StatementUtils.getTableName("sign") + " (time, \"user\", wid, x, y, z, action, color, color_secondary, data, waxed, face, line_1, line_2, line_3, line_4, line_5, line_6, line_7, line_8) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
String blockInsert = "INSERT INTO " + StatementUtils.getTableName("block") + " (time, \"user\", wid, x, y, z, type, data, meta, blockdata, action, rolled_back) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
String skullInsert = "INSERT INTO " + StatementUtils.getTableName("skull") + " (time, owner) VALUES (?, ?)";
String containerInsert = "INSERT INTO " + StatementUtils.getTableName("container") + " (time, \"user\", wid, x, y, z, type, data, amount, metadata, action, rolled_back) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
String itemInsert = "INSERT INTO " + StatementUtils.getTableName("item") + " (time, \"user\", wid, x, y, z, type, data, amount, action, rolled_back) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
String worldInsert = "INSERT INTO " + StatementUtils.getTableName("world") + " (id, world) VALUES (?, ?)";
String chatInsert = "INSERT INTO " + StatementUtils.getTableName("chat") + " (time, \"user\", wid, x, y, z, message) VALUES (?, ?, ?, ?, ?, ?, ?)";
String commandInsert = "INSERT INTO " + StatementUtils.getTableName("command") + " (time, \"user\", wid, x, y, z, message) VALUES (?, ?, ?, ?, ?, ?, ?)";
String sessionInsert = "INSERT INTO " + StatementUtils.getTableName("session") + " (time, \"user\", wid, x, y, z, action) VALUES (?, ?, ?, ?, ?, ?, ?)";
String entityInsert = "INSERT INTO " + StatementUtils.getTableName("entity") + " (time, data) VALUES (?, ?)";
String materialInsert = "INSERT INTO " + StatementUtils.getTableName("material_map") + " (id, material) VALUES (?, ?)";
String artInsert = "INSERT INTO " + StatementUtils.getTableName("art_map") + " (id, art) VALUES (?, ?)";
String entityMapInsert = "INSERT INTO " + StatementUtils.getTableName("entity_map") + " (id, entity) VALUES (?, ?)";
String blockdataInsert = "INSERT INTO " + StatementUtils.getTableName("blockdata_map") + " (id, data) VALUES (?, ?)";
switch (type) {
case SIGN:
@ -310,7 +313,7 @@ public class Database extends Queue {
private static void initializeTables(String prefix, Statement statement) {
try {
if (!Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE == DatabaseType.SQLITE) {
if (!Config.getGlobal().DISABLE_WAL) {
statement.executeUpdate("PRAGMA journal_mode=WAL;");
}
@ -341,8 +344,90 @@ public class Database extends Queue {
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"));
DatabaseType dbType = Config.getGlobal().DB_TYPE;
if (dbType == DatabaseType.PGSQL) {
boolean success = false;
try (Connection connection = Database.getConnection(true, true, true, 0)) {
if (connection != null) {
Statement statement = connection.createStatement();
statement.executeUpdate("create table if not exists \"" + prefix + "art_map\" (\"rowid\" bigserial primary key not null, \"id\" integer not null, \"art\" varchar(255) not null)");
statement.executeUpdate("create index if not exists \"" + prefix + "art_map_id_index\" on \"" + prefix + "art_map\" (\"id\")");
if (Config.getGlobal().MYSQL) {
statement.executeUpdate("create table if not exists \"" + prefix + "block\" (\"rowid\" bigserial primary key not null, \"time\" integer not null, \"user\" integer not null, \"wid\" integer not null, \"x\" integer not null, \"y\" smallint not null, \"z\" integer not null, \"type\" integer not null, \"data\" integer not null, \"meta\" bytea null, \"blockdata\" bytea null, \"action\" smallint not null, \"rolled_back\" smallint not null)");
statement.executeUpdate("create index if not exists \"" + prefix + "block_wid_x_z_time_index\" on \"" + prefix + "block\" (\"wid\", \"x\", \"z\", \"time\")");
statement.executeUpdate("create index if not exists \"" + prefix + "block_user_time_index\" on \"" + prefix + "block\" (\"user\", \"time\")");
statement.executeUpdate("create index if not exists \"" + prefix + "block_type_time_index\" on \"" + prefix + "block\" (\"type\", \"time\")");
statement.executeUpdate("create table if not exists \"" + prefix + "chat\" (\"rowid\" bigserial primary key not null, \"time\" integer not null, \"user\" integer not null, \"wid\" integer not null, \"x\" integer not null, \"y\" smallint not null, \"z\" integer not null, \"message\" text not null)");
statement.executeUpdate("create index if not exists \"" + prefix + "chat_time_index\" on \"" + prefix + "chat\" (\"time\")");
statement.executeUpdate("create index if not exists \"" + prefix + "chat_user_time_index\" on \"" + prefix + "chat\" (\"user\", \"time\")");
statement.executeUpdate("create index if not exists \"" + prefix + "chat_wid_x_z_time_index\" on \"" + prefix + "chat\" (\"wid\", \"x\", \"z\", \"time\")");
statement.executeUpdate("create table if not exists \"" + prefix + "command\" (\"rowid\" bigserial primary key not null, \"time\" integer not null, \"user\" integer not null, \"wid\" integer not null, \"x\" integer not null, \"y\" smallint not null, \"z\" integer not null, \"message\" text not null)");
statement.executeUpdate("create index if not exists \"" + prefix + "command_time_index\" on \"" + prefix + "command\" (\"time\")");
statement.executeUpdate("create index if not exists \"" + prefix + "command_user_time_index\" on \"" + prefix + "command\" (\"user\", \"time\")");
statement.executeUpdate("create index if not exists \"" + prefix + "command_wid_x_z_time_index\" on \"" + prefix + "command\" (\"wid\", \"x\", \"z\", \"time\")");
statement.executeUpdate("create table if not exists \"" + prefix + "container\" (\"rowid\" bigserial primary key not null, \"time\" integer not null, \"user\" integer not null, \"wid\" integer not null, \"x\" integer not null, \"y\" smallint not null, \"z\" integer not null, \"type\" integer not null, \"data\" integer not null, \"amount\" integer not null, \"metadata\" bytea null, \"action\" smallint not null, \"rolled_back\" smallint not null)");
statement.executeUpdate("create index if not exists \"" + prefix + "container_wid_x_z_time_index\" on \"" + prefix + "container\" (\"wid\", \"x\", \"z\", \"time\")");
statement.executeUpdate("create index if not exists \"" + prefix + "container_user_time_index\" on \"" + prefix + "container\" (\"user\", \"time\")");
statement.executeUpdate("create index if not exists \"" + prefix + "container_type_time_index\" on \"" + prefix + "container\" (\"type\", \"time\")");
statement.executeUpdate("create table if not exists \"" + prefix + "item\" (\"rowid\" bigserial primary key not null, \"time\" integer not null, \"user\" integer not null, \"wid\" integer not null, \"x\" integer not null, \"y\" smallint not null, \"z\" integer not null, \"type\" integer not null, \"data\" bytea null, \"amount\" integer not null, \"action\" smallint not null, \"rolled_back\" smallint not null)");
statement.executeUpdate("create index if not exists \"" + prefix + "item_wid_x_z_time_index\" on \"" + prefix + "item\" (\"wid\", \"x\", \"z\", \"time\")");
statement.executeUpdate("create index if not exists \"" + prefix + "item_user_time_index\" on \"" + prefix + "item\" (\"user\", \"time\")");
statement.executeUpdate("create index if not exists \"" + prefix + "item_type_time_index\" on \"" + prefix + "item\" (\"type\", \"time\")");
statement.executeUpdate("create table if not exists \"" + prefix + "database_lock\" (\"rowid\" bigserial primary key not null, \"status\" smallint not null, \"time\" integer not null)");
statement.executeUpdate("create table if not exists \"" + prefix + "entity\" (\"rowid\" bigserial primary key not null, \"time\" integer not null, \"data\" bytea not null)");
statement.executeUpdate("create table if not exists \"" + prefix + "entity_map\" (\"rowid\" bigserial primary key not null, \"id\" integer not null, \"entity\" varchar(255) not null)");
statement.executeUpdate("create index if not exists \"" + prefix + "entity_map_id_index\" on \"" + prefix + "entity_map\" (\"id\")");
statement.executeUpdate("create table if not exists \"" + prefix + "material_map\" (\"rowid\" bigserial primary key not null, \"id\" integer not null, \"material\" varchar(255) not null)");
statement.executeUpdate("create index if not exists \"" + prefix + "material_map_id_index\" on \"" + prefix + "material_map\" (\"id\")");
statement.executeUpdate("create table if not exists \"" + prefix + "blockdata_map\" (\"rowid\" bigserial primary key not null, \"id\" integer not null, \"data\" varchar(255) not null)");
statement.executeUpdate("create index if not exists \"" + prefix + "blockdata_map_id_index\" on \"" + prefix + "blockdata_map\" (\"id\")");
statement.executeUpdate("create table if not exists \"" + prefix + "session\" (\"rowid\" bigserial primary key not null, \"time\" integer not null, \"user\" integer not null, \"wid\" integer not null, \"x\" integer not null, \"y\" smallint not null, \"z\" integer not null, \"action\" smallint not null)");
statement.executeUpdate("create index if not exists \"" + prefix + "session_wid_x_y_time_index\" on \"" + prefix + "session\" (\"wid\", \"x\", \"y\", \"time\")");
statement.executeUpdate("create index if not exists \"" + prefix + "session_action_time_index\" on \"" + prefix + "session\" (\"action\", \"time\")");
statement.executeUpdate("create index if not exists \"" + prefix + "session_user_time_index\" on \"" + prefix + "session\" (\"user\", \"time\")");
statement.executeUpdate("create index if not exists \"" + prefix + "session_time_index\" on \"" + prefix + "session\" (\"time\")");
statement.executeUpdate("create table if not exists \"" + prefix + "sign\" (\"rowid\" bigserial primary key not null, \"time\" integer not null, \"user\" integer not null, \"wid\" integer not null, \"x\" integer not null, \"y\" smallint not null, \"z\" integer not null, \"action\" smallint not null, \"color\" integer not null, \"color_secondary\" integer not null, \"data\" smallint not null, \"waxed\" smallint not null, \"face\" smallint not null, \"line_1\" varchar(100) null, \"line_2\" varchar(100) null, \"line_3\" varchar(100) null, \"line_4\" varchar(100) null, \"line_5\" varchar(100) null, \"line_6\" varchar(100) null, \"line_7\" varchar(100) null, \"line_8\" varchar(100) null)");
statement.executeUpdate("create index if not exists \"" + prefix + "sign_wid_x_z_time_index\" on \"" + prefix + "sign\" (\"wid\", \"x\", \"z\", \"time\")");
statement.executeUpdate("create index if not exists \"" + prefix + "sign_user_time_index\" on \"" + prefix + "sign\" (\"user\", \"time\")");
statement.executeUpdate("create index if not exists \"" + prefix + "sign_time_index\" on \"" + prefix + "sign\" (\"time\")");
statement.executeUpdate("create table if not exists \"" + prefix + "skull\" (\"rowid\" bigserial primary key not null, \"time\" integer not null, \"owner\" varchar(64) not null)");
statement.executeUpdate("create table if not exists \"" + prefix + "user\" (\"rowid\" bigserial primary key not null, \"time\" integer not null, \"user\" varchar(255) not null, \"uuid\" uuid null)");
statement.executeUpdate("create index if not exists \"" + prefix + "user_user_index\" on \"" + prefix + "user\" (\"user\")");
statement.executeUpdate("create index if not exists \"" + prefix + "user_uuid_index\" on \"" + prefix + "user\" (\"uuid\")");
statement.executeUpdate("create table if not exists \"" + prefix + "username_log\" (\"rowid\" bigserial primary key not null, \"time\" integer not null, \"uuid\" uuid not null, \"user\" varchar(100) not null)");
statement.executeUpdate("create index if not exists \"" + prefix + "username_log_uuid_user_index\" on \"" + prefix + "username_log\" (\"uuid\", \"user\")");
statement.executeUpdate("create table if not exists \"" + prefix + "version\" (\"rowid\" bigserial primary key not null, \"time\" integer not null, \"version\" varchar(16) not null)");
statement.executeUpdate("create table if not exists \"" + prefix + "world\" (\"rowid\" bigserial primary key not null, \"id\" integer not null, \"world\" varchar(255) not null)");
statement.executeUpdate("create index if not exists \"" + prefix + "world_id_index\" on \"" + prefix + "world\" (\"id\")");
if (!purge) {
initializeTables(prefix, statement);
}
statement.close();
success = true;
}
} catch (Exception e) {
e.printStackTrace();
}
if (!success) {
Config.getGlobal().DB_TYPE = DatabaseType.SQLITE;
}
} else if (dbType == DatabaseType.MYSQL) {
boolean success = false;
try (Connection connection = Database.getConnection(true, true, true, 0)) {
if (connection != null) {
@ -391,10 +476,9 @@ public class Database extends Queue {
e.printStackTrace();
}
if (!success) {
Config.getGlobal().MYSQL = false;
Config.getGlobal().DB_TYPE = DatabaseType.SQLITE;
}
}
if (!Config.getGlobal().MYSQL) {
} else {
try (Connection connection = Database.getConnection(true, 0)) {
Statement statement = connection.createStatement();
List<String> tableData = new ArrayList<>();

View File

@ -19,6 +19,7 @@ import org.bukkit.entity.EntityType;
import net.coreprotect.bukkit.BukkitAdapter;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.consumer.Queue;
import net.coreprotect.database.logger.ItemLogger;
@ -355,6 +356,7 @@ public class Lookup extends Queue {
String unionLimit = "";
String index = "";
String query = "";
String alias = "";
if (checkUuids.size() > 0) {
String list = "";
@ -646,20 +648,20 @@ public class Lookup extends Queue {
String baseQuery = ((!includeEntity.isEmpty() || !excludeEntity.isEmpty()) ? queryEntity : queryBlock);
if (limitOffset > -1 && limitCount > -1) {
queryLimit = " LIMIT " + limitOffset + ", " + limitCount + "";
queryLimit = " LIMIT " + limitCount + " OFFSET " + limitOffset;
unionLimit = " ORDER BY time DESC, id DESC LIMIT " + (limitOffset + limitCount) + "";
}
String rows = "rowid as id,time,user,wid,x,y,z,action,type,data,meta,blockdata,rolled_back";
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";
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";
rows = "rowid as id,time,\"user\",message";
if (PluginChannelHandshakeListener.getInstance().isPluginChannelPlayer(user)) {
rows += ",wid,x,y,z";
}
@ -670,30 +672,30 @@ public class Lookup extends Queue {
}
else if (actionList.contains(8)) {
queryTable = "session";
rows = "rowid as id,time,user,wid,x,y,z,action";
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";
rows = "rowid as id,time,uuid,\"user\"";
}
else if (actionList.contains(10)) {
queryTable = "sign";
rows = "rowid as id,time,user,wid,x,y,z,face,line_1,line_2,line_3,line_4,line_5,line_6,line_7,line_8";
rows = "rowid as id,time,\"user\",wid,x,y,z,face,line_1,line_2,line_3,line_4,line_5,line_6,line_7,line_8";
}
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";
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";
queryLimit = " LIMIT 3";
queryOrder = "";
unionLimit = "";
}
String unionSelect = "SELECT * FROM (";
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE == DatabaseType.MYSQL) {
if (queryTable.equals("block")) {
if (includeBlock.length() > 0 || includeEntity.length() > 0) {
index = "USE INDEX(type) IGNORE INDEX(user,wid) ";
@ -711,7 +713,7 @@ public class Lookup extends Queue {
unionSelect = "(";
}
else {
else if (Config.getGlobal().DB_TYPE == DatabaseType.SQLITE) {
if (queryTable.equals("block")) {
if (includeBlock.length() > 0 || includeEntity.length() > 0) {
index = "INDEXED BY block_type_index ";
@ -731,7 +733,7 @@ public class Lookup extends Queue {
boolean itemLookup = inventoryQuery;
if ((lookup && actionList.size() == 0) || (itemLookup && !actionList.contains(0))) {
if (!count) {
rows = "rowid as id,time,user,wid,x,y,z,type,meta as metadata,data,-1 as amount,action,rolled_back";
rows = "rowid as id,time,\"user\",wid,x,y,z,type,meta as metadata,data,-1 as amount,action,rolled_back";
}
if (inventoryQuery) {
@ -743,7 +745,7 @@ public class Lookup extends Queue {
}
if (!count) {
rows = "rowid as id,time,user,wid,x,y,z,type,meta as metadata,data,1 as amount,action,rolled_back";
rows = "rowid as id,time,\"user\",wid,x,y,z,type,meta as metadata,data,1 as amount,action,rolled_back";
}
}
@ -751,18 +753,26 @@ public class Lookup extends Queue {
baseQuery = baseQuery.replace("action NOT IN(-1)", "action NOT IN(3)"); // if block specified for include/exclude, filter out entity data
}
query = unionSelect + "SELECT " + "'0' as tbl," + rows + " FROM " + ConfigHandler.prefix + "block " + index + "WHERE" + baseQuery + unionLimit + ") UNION ALL ";
if (Config.getGlobal().DB_TYPE == DatabaseType.PGSQL) {
alias = " AS union1";
}
query = unionSelect + "SELECT " + "'0' as tbl," + rows + " FROM " + StatementUtils.getTableName("block") + " " + index + "WHERE" + baseQuery + unionLimit + ")" + alias + " UNION ALL ";
itemLookup = true;
}
if (itemLookup) {
if (!count) {
rows = "rowid as id,time,user,wid,x,y,z,type,metadata,data,amount,action,rolled_back";
rows = "rowid as id,time,\"user\",wid,x,y,z,type,metadata,data,amount,action,rolled_back";
}
query = query + unionSelect + "SELECT " + "'1' as tbl," + rows + " FROM " + ConfigHandler.prefix + "container WHERE" + queryBlock + unionLimit + ") UNION ALL ";
if (Config.getGlobal().DB_TYPE == DatabaseType.PGSQL) {
alias = " AS union2";
}
query = query + unionSelect + "SELECT " + "'1' as tbl," + rows + " FROM " + StatementUtils.getTableName("container") + " WHERE" + queryBlock + unionLimit + ")" + alias + " UNION ALL ";
if (!count) {
rows = "rowid as id,time,user,wid,x,y,z,type,data as metadata,0 as data,amount,action,rolled_back";
rows = "rowid as id,time,\"user\",wid,x,y,z,type,data as metadata,0 as data,amount,action,rolled_back";
queryOrder = " ORDER BY time DESC, tbl DESC, id DESC";
}
@ -770,7 +780,10 @@ public class Lookup extends Queue {
queryBlock = queryBlock.replace("action NOT IN(-1)", "action NOT IN(" + actionExclude + ")");
}
query = query + unionSelect + "SELECT " + "'2' as tbl," + rows + " FROM " + ConfigHandler.prefix + "item WHERE" + queryBlock + unionLimit + ")";
if (Config.getGlobal().DB_TYPE == DatabaseType.PGSQL) {
alias = " AS union3";
}
query = query + unionSelect + "SELECT " + "'2' as tbl," + rows + " FROM " + StatementUtils.getTableName("item") + " WHERE" + queryBlock + unionLimit + ")" + alias;
}
if (query.length() == 0) {
@ -778,7 +791,7 @@ public class Lookup extends Queue {
baseQuery = baseQuery.replace("action NOT IN(-1)", "action NOT IN(" + actionExclude + ")");
}
query = "SELECT " + "'0' as tbl," + rows + " FROM " + ConfigHandler.prefix + queryTable + " " + index + "WHERE" + baseQuery;
query = "SELECT " + "'0' as tbl," + rows + " FROM " + StatementUtils.getTableName(queryTable) + " " + index + "WHERE" + baseQuery;
}
query = query + queryOrder + queryLimit + "";
@ -819,7 +832,7 @@ public class Lookup extends Queue {
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 " + Util.getWidIndex("block") + "WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND rolled_back IN(0,2) AND action='1' ORDER BY rowid DESC LIMIT 0, 1";
String query = "SELECT \"user\", type FROM " + StatementUtils.getTableName("block") + " " + Util.getWidIndex("block") + "WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND rolled_back IN(0,2) AND action='1' ORDER BY rowid DESC LIMIT 1";
ResultSet results = statement.executeQuery(query);
while (results.next()) {

View File

@ -0,0 +1,39 @@
package net.coreprotect.database;
import java.util.Objects;
import net.coreprotect.config.ConfigHandler;
public final class StatementUtils {
private StatementUtils() {
}
/**
* Creates a table name with the configured prefix and provided table name.
*
* @param table The SQL table name.
* @return The prepended table name with the table prefix.
*/
public static String getTableName(String table) {
Objects.requireNonNull(table, "table cannot be null");
return "\"" + ConfigHandler.prefix + table + "\"";
}
/**
* Creates a SQL "LIMIT ... OFFSET ..." query fragment compatible with multiple
* databases.
*
* @param limit The number of results to limit.
* @param offset The offset for the results.
* @return The SQL limit statement as a {@link String}.
*/
public static String getLimit(int limit, int offset) {
if (limit <= 0) {
throw new IllegalArgumentException("limit must be greater than 0");
}
if (offset < 0) {
throw new IllegalArgumentException("offset cannot be negative");
}
return "LIMIT " + limit + " OFFSET " + offset;
}
}

View File

@ -3,9 +3,14 @@ package net.coreprotect.database.logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Types;
import java.util.Locale;
import java.util.UUID;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
import net.coreprotect.database.StatementUtils;
public class UsernameLogger {
@ -18,19 +23,23 @@ public class UsernameLogger {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
}
DatabaseType dbType = Config.getGlobal().DB_TYPE;
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);
String query = "SELECT rowid as id, \"user\" FROM " + StatementUtils.getTableName("user") + " WHERE uuid = ? LIMIT 1";
try (PreparedStatement preparedStmt = connection.prepareStatement(query)) {
if (dbType == DatabaseType.PGSQL) {
preparedStmt.setObject(1, UUID.fromString(uuid), Types.OTHER);
} else {
preparedStmt.setString(1, uuid);
}
try (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) {
@ -42,12 +51,16 @@ public class UsernameLogger {
}
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();
try (PreparedStatement preparedStmt = connection.prepareStatement("UPDATE " + StatementUtils.getTableName("user") + " SET \"user\" = ?, uuid = ? WHERE rowid = ?")) {
preparedStmt.setString(1, user);
if (dbType == DatabaseType.PGSQL) {
preparedStmt.setObject(2, UUID.fromString(uuid), Types.OTHER);
} else {
preparedStmt.setString(2, uuid);
}
preparedStmt.setInt(3, idRow);
preparedStmt.executeUpdate();
}
/*
//Commented out to prevent potential issues if player manages to stay logged in with old username
@ -61,16 +74,20 @@ public class UsernameLogger {
}
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;
query = "SELECT rowid as id FROM " + StatementUtils.getTableName("username_log") + " WHERE uuid = ? AND \"user\" = ? LIMIT 1";
try (PreparedStatement preparedStmt = connection.prepareStatement(query)) {
if (dbType == DatabaseType.PGSQL) {
preparedStmt.setObject(1, UUID.fromString(uuid), Types.OTHER);
} else {
preparedStmt.setString(1, uuid);
}
preparedStmt.setString(2, user);
try (ResultSet rs = preparedStmt.executeQuery()) {
while (rs.next()) {
foundUUID = true;
}
}
}
rs.close();
preparedStatement.close();
if (!foundUUID) {
update = true;
@ -78,12 +95,16 @@ public class UsernameLogger {
}
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();
try (PreparedStatement preparedStmt = connection.prepareStatement("INSERT INTO " + StatementUtils.getTableName("username_log") + " (time, uuid, \"user\") VALUES (?, ?, ?)")) {
preparedStmt.setInt(1, time);
if (dbType == DatabaseType.PGSQL) {
preparedStmt.setObject(2, UUID.fromString(uuid), Types.OTHER);
} else {
preparedStmt.setString(2, uuid);
}
preparedStmt.setString(3, user);
preparedStmt.executeUpdate();
}
}
ConfigHandler.playerIdCache.put(user.toLowerCase(Locale.ROOT), idRow);

View File

@ -9,6 +9,7 @@ import org.bukkit.block.BlockState;
import org.bukkit.command.CommandSender;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
@ -57,7 +58,7 @@ public class BlockLookup {
String blockName = block.getType().name().toLowerCase(Locale.ROOT);
String query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "block " + Util.getWidIndex("block") + "WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action IN(0,1) AND time >= '" + checkTime + "' LIMIT 0, 1";
String query = "SELECT COUNT(*) as count from " + StatementUtils.getTableName("block") + " " + Util.getWidIndex("block") + "WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action IN(0,1) AND time >= '" + checkTime + "' LIMIT 1";
ResultSet results = statement.executeQuery(query);
while (results.next()) {
count = results.getInt("count");
@ -65,7 +66,7 @@ public class BlockLookup {
results.close();
int totalPages = (int) Math.ceil(count / (limit + 0.0));
query = "SELECT time,user,action,type,data,rolled_back FROM " + ConfigHandler.prefix + "block " + Util.getWidIndex("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 + "";
query = "SELECT time, \"user\", action, type, data, rolled_back FROM " + StatementUtils.getTableName("block") + " " + Util.getWidIndex("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 " + limit + " OFFSET " + page_start;
results = statement.executeQuery(query);
StringBuilder resultTextBuilder = new StringBuilder();

View File

@ -11,6 +11,7 @@ import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
@ -56,9 +57,9 @@ public class ChestTransactionLookup {
int rowMax = page * limit;
int pageStart = rowMax - limit;
String query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "container " + Util.getWidIndex("container") + "WHERE wid = '" + worldId + "' AND (x = '" + x + "' OR x = '" + x2 + "') AND (z = '" + z + "' OR z = '" + z2 + "') AND y = '" + y + "' LIMIT 0, 1";
String query = "SELECT COUNT(*) as count from " + StatementUtils.getTableName("container") + " " + Util.getWidIndex("container") + "WHERE wid = '" + worldId + "' AND (x = '" + x + "' OR x = '" + x2 + "') AND (z = '" + z + "' OR z = '" + z2 + "') AND y = '" + y + "' LIMIT 1";
if (exact) {
query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "container " + Util.getWidIndex("container") + "WHERE wid = '" + worldId + "' AND (x = '" + l.getBlockX() + "') AND (z = '" + l.getBlockZ() + "') AND y = '" + y + "' LIMIT 0, 1";
query = "SELECT COUNT(*) as count from " + StatementUtils.getTableName("container") + " " + Util.getWidIndex("container") + "WHERE wid = '" + worldId + "' AND (x = '" + l.getBlockX() + "') AND (z = '" + l.getBlockZ() + "') AND y = '" + y + "' LIMIT 1";
}
ResultSet results = statement.executeQuery(query);
@ -69,9 +70,9 @@ public class ChestTransactionLookup {
int totalPages = (int) Math.ceil(count / (limit + 0.0));
query = "SELECT time,user,action,type,data,amount,metadata,rolled_back FROM " + ConfigHandler.prefix + "container " + Util.getWidIndex("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 + "";
query = "SELECT time, \"user\", action, type, data, amount, metadata, rolled_back FROM " + StatementUtils.getTableName("container") + " " + Util.getWidIndex("container") + "WHERE wid = '" + worldId + "' AND (x = '" + x + "' OR x = '" + x2 + "') AND (z = '" + z + "' OR z = '" + z2 + "') AND y = '" + y + "' ORDER BY rowid DESC LIMIT " + limit + " OFFSET " + pageStart;
if (exact) {
query = "SELECT time,user,action,type,data,amount,metadata,rolled_back FROM " + ConfigHandler.prefix + "container " + Util.getWidIndex("container") + "WHERE wid = '" + worldId + "' AND (x = '" + l.getBlockX() + "') AND (z = '" + l.getBlockZ() + "') AND y = '" + y + "' ORDER BY rowid DESC LIMIT " + pageStart + ", " + limit + "";
query = "SELECT time, \"user\", action, type, data, amount, metadata, rolled_back FROM " + StatementUtils.getTableName("container") + " " + Util.getWidIndex("container") + "WHERE wid = '" + worldId + "' AND (x = '" + l.getBlockX() + "') AND (z = '" + l.getBlockZ() + "') AND y = '" + y + "' ORDER BY rowid DESC LIMIT " + limit + " OFFSET " + pageStart;
}
results = statement.executeQuery(query);
while (results.next()) {

View File

@ -9,6 +9,7 @@ import org.bukkit.block.Block;
import org.bukkit.command.CommandSender;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
@ -55,7 +56,7 @@ public class InteractionLookup {
checkTime = time - offset;
}
String query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "block " + Util.getWidIndex("block") + "WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action='2' AND time >= '" + checkTime + "' LIMIT 0, 1";
String query = "SELECT COUNT(*) as count from " + StatementUtils.getTableName("block") + " " + Util.getWidIndex("block") + "WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action='2' AND time >= '" + checkTime + "' LIMIT 1";
ResultSet results = statement.executeQuery(query);
while (results.next()) {
@ -64,7 +65,7 @@ public class InteractionLookup {
results.close();
int totalPages = (int) Math.ceil(count / (limit + 0.0));
query = "SELECT time,user,action,type,data,rolled_back FROM " + ConfigHandler.prefix + "block " + Util.getWidIndex("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 + "";
query = "SELECT time, \"user\", action, type, data, rolled_back FROM " + StatementUtils.getTableName("block") + " " + Util.getWidIndex("block") + "WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action='2' AND time >= '" + checkTime + "' ORDER BY rowid DESC LIMIT " + limit + " OFFSET " + pageStart;
results = statement.executeQuery(query);
StringBuilder resultBuilder = new StringBuilder();

View File

@ -7,6 +7,8 @@ import java.util.Locale;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
import net.coreprotect.database.StatementUtils;
public class PlayerLookup {
@ -20,11 +22,11 @@ public class PlayerLookup {
}
String collate = "";
if (!Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE == DatabaseType.SQLITE) {
collate = " COLLATE NOCASE";
}
String query = "SELECT rowid as id, uuid FROM " + ConfigHandler.prefix + "user WHERE user = ?" + collate + " LIMIT 0, 1";
String query = "SELECT rowid as id, uuid FROM " + StatementUtils.getTableName("user") + " WHERE \"user\" = ?" + collate + " LIMIT 1";
PreparedStatement preparedStmt = connection.prepareStatement(query);
preparedStmt.setString(1, user);

View File

@ -11,6 +11,7 @@ import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
@ -55,7 +56,7 @@ public class SignMessageLookup {
int rowMax = page * limit;
int pageStart = rowMax - limit;
String query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "sign " + Util.getWidIndex("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 OR LENGTH(line_5) > 0 OR LENGTH(line_6) > 0 OR LENGTH(line_7) > 0 OR LENGTH(line_8) > 0) LIMIT 0, 1";
String query = "SELECT COUNT(*) as count from " + StatementUtils.getTableName("sign") + " " + Util.getWidIndex("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 OR LENGTH(line_5) > 0 OR LENGTH(line_6) > 0 OR LENGTH(line_7) > 0 OR LENGTH(line_8) > 0) LIMIT 1";
ResultSet results = statement.executeQuery(query);
while (results.next()) {
@ -65,7 +66,7 @@ public class SignMessageLookup {
int totalPages = (int) Math.ceil(count / (limit + 0.0));
query = "SELECT time,user,face,line_1,line_2,line_3,line_4,line_5,line_6,line_7,line_8 FROM " + ConfigHandler.prefix + "sign " + Util.getWidIndex("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 OR LENGTH(line_5) > 0 OR LENGTH(line_6) > 0 OR LENGTH(line_7) > 0 OR LENGTH(line_8) > 0) ORDER BY rowid DESC LIMIT " + pageStart + ", " + limit + "";
query = "SELECT time, \"user\", face, line_1, line_2, line_3, line_4, line_5, line_6, line_7, line_8 FROM " + StatementUtils.getTableName("sign") + " " + Util.getWidIndex("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 OR LENGTH(line_5) > 0 OR LENGTH(line_6) > 0 OR LENGTH(line_7) > 0 OR LENGTH(line_8) > 0) ORDER BY rowid DESC LIMIT " + limit + " OFFSET " + pageStart;
results = statement.executeQuery(query);
while (results.next()) {

View File

@ -5,11 +5,15 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.Locale;
import java.util.UUID;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
import net.coreprotect.database.Database;
import net.coreprotect.database.StatementUtils;
public class UserStatement {
@ -23,32 +27,26 @@ public class UserStatement {
try {
int unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
PreparedStatement preparedStmt = null;
if (Database.hasReturningKeys()) {
preparedStmt = connection.prepareStatement("INSERT INTO " + ConfigHandler.prefix + "user (time, user) VALUES (?, ?) RETURNING rowid");
try (PreparedStatement preparedStmt = connection.prepareStatement("INSERT INTO " + StatementUtils.getTableName("user") + " (time, \"user\") VALUES (?, ?) RETURNING rowid")) {
preparedStmt.setInt(1, unixtimestamp);
preparedStmt.setString(2, user);
try (ResultSet resultSet = preparedStmt.executeQuery()) {
resultSet.next();
id = resultSet.getInt(1);
}
}
} else {
try (PreparedStatement preparedStmt = connection.prepareStatement("INSERT INTO " + StatementUtils.getTableName("user") + " (time, \"user\") VALUES (?, ?)", Statement.RETURN_GENERATED_KEYS)) {
preparedStmt.setInt(1, unixtimestamp);
preparedStmt.setString(2, user);
preparedStmt.executeUpdate();
try (ResultSet keys = preparedStmt.getGeneratedKeys()) {
keys.next();
id = keys.getInt(1);
}
}
}
else {
preparedStmt = connection.prepareStatement("INSERT INTO " + ConfigHandler.prefix + "user (time, user) VALUES (?, ?)", Statement.RETURN_GENERATED_KEYS);
}
preparedStmt.setInt(1, unixtimestamp);
preparedStmt.setString(2, user);
if (Database.hasReturningKeys()) {
ResultSet resultSet = preparedStmt.executeQuery();
resultSet.next();
id = resultSet.getInt(1);
resultSet.close();
}
else {
preparedStmt.executeUpdate();
ResultSet keys = preparedStmt.getGeneratedKeys();
keys.next();
id = keys.getInt(1);
keys.close();
}
preparedStmt.close();
}
catch (Exception e) {
e.printStackTrace();
@ -67,24 +65,29 @@ public class UserStatement {
public static int loadId(Connection connection, String user, String uuid) {
// generate if doesn't exist
int id = -1;
DatabaseType dbType = Config.getGlobal().DB_TYPE;
try {
String collate = "";
if (!Config.getGlobal().MYSQL) {
if (dbType == DatabaseType.SQLITE) {
collate = " COLLATE NOCASE";
}
String where = "user = ?" + collate;
String where = "\"user\" = ?" + collate;
if (uuid != null) {
where = where + " OR uuid = ?";
where += " OR uuid = ?";
}
String query = "SELECT rowid as id, uuid FROM " + ConfigHandler.prefix + "user WHERE " + where + " ORDER BY rowid ASC LIMIT 0, 1";
String query = "SELECT rowid as id, uuid FROM " + StatementUtils.getTableName("user") + " WHERE " + where + " ORDER BY rowid ASC LIMIT 1";
PreparedStatement preparedStmt = connection.prepareStatement(query);
preparedStmt.setString(1, user);
if (uuid != null) {
preparedStmt.setString(2, uuid);
if (dbType == DatabaseType.PGSQL) {
preparedStmt.setObject(2, UUID.fromString(uuid), Types.OTHER);
} else {
preparedStmt.setString(2, uuid);
}
}
ResultSet resultSet = preparedStmt.executeQuery();
@ -120,7 +123,7 @@ public class UserStatement {
try {
Statement statement = connection.createStatement();
String query = "SELECT user, uuid FROM " + ConfigHandler.prefix + "user WHERE rowid='" + id + "' LIMIT 0, 1";
String query = "SELECT \"user\", uuid FROM " + StatementUtils.getTableName("user") + " WHERE rowid='" + id + "' LIMIT 1";
ResultSet resultSet = statement.executeQuery(query);
while (resultSet.next()) {

View File

@ -154,6 +154,7 @@ public class Language {
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.PGSQL_UNAVAILABLE, "Unable to connect to PostgreSQL server.");
phrases.put(Phrase.NETWORK_CONNECTION, "Connection by {0} {successful|failed}. Using {1} {2}.");
phrases.put(Phrase.NETWORK_TEST, "Network test data has been successful sent.");
phrases.put(Phrase.NO_DATA, "No data found at {0}.");
@ -225,6 +226,7 @@ public class Language {
phrases.put(Phrase.USER_NOT_FOUND, "User \"{0}\" not found.");
phrases.put(Phrase.USER_OFFLINE, "The user \"{0}\" is not online.");
phrases.put(Phrase.USING_MYSQL, "Using MySQL for data storage.");
phrases.put(Phrase.USING_PGSQL, "Using PostgreSQL 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.");

View File

@ -137,6 +137,7 @@ public enum Phrase {
MISSING_ROLLBACK_RADIUS,
MISSING_ROLLBACK_USER,
MYSQL_UNAVAILABLE,
PGSQL_UNAVAILABLE,
NETWORK_CONNECTION,
NETWORK_TEST,
NO_DATA,
@ -208,6 +209,7 @@ public enum Phrase {
USER_NOT_FOUND,
USER_OFFLINE,
USING_MYSQL,
USING_PGSQL,
USING_SQLITE,
VALID_DONATION_KEY,
VERSION_NOTICE,

View File

@ -17,6 +17,7 @@ import net.coreprotect.CoreProtect;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.database.Database;
import net.coreprotect.database.StatementUtils;
import net.coreprotect.language.Phrase;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
@ -52,7 +53,7 @@ public class Patch {
public static Integer[] getDatabaseVersion(Connection connection, boolean lastVersion) {
Integer[] last_version = new Integer[] { 0, 0, 0 };
try {
String query = "SELECT version FROM " + ConfigHandler.prefix + "version ORDER BY rowid " + (lastVersion ? "DESC" : "ASC") + " LIMIT 0, 1";
String query = "SELECT version FROM " + StatementUtils.getTableName("version") + " ORDER BY rowid " + (lastVersion ? "DESC" : "ASC") + " LIMIT 1";
Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery(query);
while (rs.next()) {
@ -213,10 +214,10 @@ public class Patch {
// mark as being up to date
int unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
if (result >= 0) {
statement.executeUpdate("INSERT INTO " + ConfigHandler.prefix + "version (time,version) VALUES ('" + unixtimestamp + "', '" + version[0] + "." + version[1] + "." + version[2] + "')");
statement.executeUpdate("INSERT INTO " + StatementUtils.getTableName("version") + " (time,version) VALUES ('" + unixtimestamp + "', '" + version[0] + "." + version[1] + "." + version[2] + "')");
}
else if (patched) {
statement.executeUpdate("INSERT INTO " + ConfigHandler.prefix + "version (time,version) VALUES ('" + unixtimestamp + "', '" + newVersion[0] + "." + newVersion[1] + "." + newVersion[2] + "')");
statement.executeUpdate("INSERT INTO " + StatementUtils.getTableName("version") + " (time,version) VALUES ('" + unixtimestamp + "', '" + newVersion[0] + "." + newVersion[1] + "." + newVersion[2] + "')");
}
statement.close();
@ -307,7 +308,7 @@ public class Patch {
}
else if (lastVersion[0] == 0) {
int unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
statement.executeUpdate("INSERT INTO " + ConfigHandler.prefix + "version (time,version) VALUES ('" + unixtimestamp + "', '" + currentVersion[0] + "." + (ConfigHandler.EDITION_BRANCH.contains("-dev") ? (currentVersion[1] - 1) : currentVersion[1]) + "." + currentVersion[2] + "')");
statement.executeUpdate("INSERT INTO " + StatementUtils.getTableName("version") + " (time,version) VALUES ('" + unixtimestamp + "', '" + currentVersion[0] + "." + (ConfigHandler.EDITION_BRANCH.contains("-dev") ? (currentVersion[1] - 1) : currentVersion[1]) + "." + currentVersion[2] + "')");
}
else {
currentVersion[2] = 0;

View File

@ -4,12 +4,13 @@ import java.sql.Statement;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
public class __2_10_0 {
protected static boolean patch(Statement statement) {
try {
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE != DatabaseType.SQLITE) {
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "user ADD COLUMN uuid varchar(64), ADD INDEX(uuid)");
}
else {

View File

@ -9,12 +9,13 @@ import org.bukkit.entity.EntityType;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
public class __2_11_0 {
protected static boolean patch(Statement statement) {
try {
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE != DatabaseType.SQLITE) {
statement.executeUpdate("START TRANSACTION");
}
else {
@ -54,7 +55,7 @@ public class __2_11_0 {
}
}
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE != DatabaseType.SQLITE) {
statement.executeUpdate("COMMIT");
}
else {

View File

@ -6,13 +6,14 @@ import java.sql.Statement;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
import net.coreprotect.database.Database;
public class __2_15_0 {
protected static boolean patch(Statement statement) {
try {
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE != DatabaseType.SQLITE) {
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "chat MODIFY message VARCHAR(1000)");
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "command MODIFY message VARCHAR(1000)");
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "user MODIFY user VARCHAR(100)");
@ -39,7 +40,7 @@ public class __2_15_0 {
Database.commitTransaction(statement);
try {
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE != DatabaseType.SQLITE) {
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "block MODIFY COLUMN rowid bigint NOT NULL AUTO_INCREMENT, ADD COLUMN blockdata BLOB");
}
else {

View File

@ -6,6 +6,7 @@ import java.sql.Statement;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
import net.coreprotect.database.Database;
import net.coreprotect.patch.Patch;
@ -13,7 +14,7 @@ public class __2_16_0 {
protected static boolean patch(Statement statement) {
try {
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE != DatabaseType.SQLITE) {
try {
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "skull MODIFY owner VARCHAR(64), DROP COLUMN type, DROP COLUMN data, DROP COLUMN rotation");
}

View File

@ -4,12 +4,13 @@ import java.sql.Statement;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
public class __2_17_0 {
protected static boolean patch(Statement statement) {
try {
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE != DatabaseType.SQLITE) {
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "sign ADD COLUMN color int");
}
else {

View File

@ -13,6 +13,7 @@ import org.bukkit.block.data.Rotatable;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
import net.coreprotect.database.Database;
import net.coreprotect.patch.Patch;
import net.coreprotect.utility.Util;
@ -25,7 +26,7 @@ public class __2_18_0 {
try {
try {
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE != DatabaseType.SQLITE) {
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "block ADD COLUMN blockdata BLOB");
}
}
@ -41,7 +42,7 @@ public class __2_18_0 {
return false;
}
String query = "SELECT rowid, id, material FROM " + ConfigHandler.prefix + "material_map WHERE material LIKE 'minecraft:legacy_%' LIMIT 0, 1";
String query = "SELECT rowid, id, material FROM " + ConfigHandler.prefix + "material_map WHERE material LIKE 'minecraft:legacy_%' LIMIT 1";
String preparedBlockQuery = "SELECT rowid as id, data, blockdata FROM " + ConfigHandler.prefix + "block WHERE type = ? AND action < '3'";
String preparedContainerQuery = "SELECT rowid as id FROM " + ConfigHandler.prefix + "container WHERE type = ?";
String preparedBlockUpdateQuery = "UPDATE " + ConfigHandler.prefix + "block SET type = ?, blockdata = ? WHERE rowid = ?";
@ -178,7 +179,7 @@ public class __2_18_0 {
if (createIndexes) {
try {
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE != DatabaseType.SQLITE) {
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "art_map ADD INDEX(id)");
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "entity_map ADD INDEX(id)");
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "material_map ADD INDEX(id)");

View File

@ -11,6 +11,7 @@ import org.bukkit.Tag;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
import net.coreprotect.database.Database;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
@ -22,7 +23,7 @@ public class __2_19_0 {
protected static boolean patch(Statement statement) {
try {
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE != DatabaseType.SQLITE) {
try {
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "sign ADD COLUMN action int");
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "sign DROP INDEX wid");
@ -139,7 +140,7 @@ public class __2_19_0 {
}
String blockQuery = "SELECT time, user, wid, x, y, z FROM " + ConfigHandler.prefix + "block WHERE type IN(" + signData.toString() + ") AND action='1' ORDER BY rowid ASC";
String preparedSignQuery = "SELECT rowid as id FROM " + ConfigHandler.prefix + "sign WHERE user = ? AND wid = ? AND x = ? AND y = ? AND z = ? AND time >= ? ORDER BY rowid ASC LIMIT 0, 1";
String preparedSignQuery = "SELECT rowid as id FROM " + ConfigHandler.prefix + "sign WHERE user = ? AND wid = ? AND x = ? AND y = ? AND z = ? AND time >= ? ORDER BY rowid ASC LIMIT 1";
String preparedQueryUpdate = "UPDATE " + ConfigHandler.prefix + "sign SET action = 1 WHERE rowid = ?";
PreparedStatement preparedSignStatement = statement.getConnection().prepareStatement(preparedSignQuery);
PreparedStatement preparedStatementUpdate = statement.getConnection().prepareStatement(preparedQueryUpdate);

View File

@ -8,6 +8,7 @@ import org.bukkit.entity.EntityType;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
import net.coreprotect.database.Database;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
@ -19,7 +20,7 @@ public class __2_20_0 {
protected static boolean patch(Statement statement) {
try {
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE != DatabaseType.SQLITE) {
try {
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "command MODIFY message VARCHAR(16000), CONVERT TO CHARACTER SET utf8mb4");
}

View File

@ -5,6 +5,7 @@ import java.sql.Statement;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigFile;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.patch.Patch;
@ -14,7 +15,7 @@ public class __2_21_0 {
protected static boolean patch(Statement statement) {
try {
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE != DatabaseType.SQLITE) {
try {
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "item ADD COLUMN rolled_back TINYINT DEFAULT 0;");
}

View File

@ -4,6 +4,7 @@ import java.sql.Statement;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.patch.Patch;
@ -13,7 +14,7 @@ public class __2_22_0 {
protected static boolean patch(Statement statement) {
try {
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE != DatabaseType.SQLITE) {
try {
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "sign ADD COLUMN line_5 VARCHAR(100);");
}

View File

@ -4,13 +4,14 @@ import java.sql.Statement;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
import net.coreprotect.patch.Patch;
public class __2_5_0 {
protected static boolean patch(Statement statement) {
try {
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE != DatabaseType.SQLITE) {
try {
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "sign MODIFY line_1 VARCHAR(100)");
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "sign MODIFY line_2 VARCHAR(100)");

View File

@ -4,12 +4,13 @@ import java.sql.Statement;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
public class __2_6_0 {
protected static boolean patch(Statement statement) {
try {
if (Config.getGlobal().MYSQL) {
if (Config.getGlobal().DB_TYPE != DatabaseType.SQLITE) {
statement.executeUpdate("START TRANSACTION");
statement.executeUpdate("CREATE TEMPORARY TABLE " + ConfigHandler.prefix + "version_tmp(rowid int, time int, version varchar(16)) ENGINE=InnoDB");
statement.executeUpdate("INSERT INTO " + ConfigHandler.prefix + "version_tmp SELECT rowid,time,version FROM " + ConfigHandler.prefix + "version;");

View File

@ -55,6 +55,7 @@ import net.coreprotect.CoreProtect;
import net.coreprotect.bukkit.BukkitAdapter;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.config.DatabaseType;
import net.coreprotect.consumer.Queue;
import net.coreprotect.database.Rollback;
import net.coreprotect.language.Phrase;
@ -1590,12 +1591,12 @@ public class Util extends Queue {
}
public static String getWidIndex(String queryTable) {
String index = "";
boolean isMySQL = Config.getGlobal().MYSQL;
if (isMySQL) {
DatabaseType dbType = Config.getGlobal().DB_TYPE;
String index;
if (dbType == DatabaseType.MYSQL) {
// mysql has the use index hint
index = "USE INDEX(wid) ";
}
else {
} else if (dbType == DatabaseType.SQLITE) {
switch (queryTable) {
case "block":
index = "INDEXED BY block_index ";
@ -1619,8 +1620,11 @@ public class Util extends Queue {
index = "INDEXED BY session_index ";
break;
default:
index = "";
break;
}
} else {
index = "";
}
return index;