Compare commits
13 Commits
747aa67030
...
217bb7004b
Author | SHA1 | Date |
---|---|---|
Take-John | 217bb7004b | |
Intelli | f3c631bbf5 | |
Intelli | d8ad48beb8 | |
Intelli | 053f7d5c7d | |
Nahuel Dolores | a4c37da8ee | |
takejohn | 8c85baf55c | |
takejohn | b905832138 | |
takejohn | 1540fecf93 | |
takejohn | a58d764075 | |
takejohn | 7c00d4c42f | |
takejohn | ddce775f78 | |
takejohn | 59166ad45b | |
takejohn | 8b1c20a441 |
|
@ -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();
|
||||
```
|
||||
|
||||
---
|
|
@ -1,5 +1,6 @@
|
|||
package net.coreprotect;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
|
@ -17,8 +18,12 @@ import org.bukkit.block.BlockState;
|
|||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.BlockStateMeta;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import net.coreprotect.api.BlockAPI;
|
||||
import net.coreprotect.api.ContainerTransactionsAPI;
|
||||
import net.coreprotect.api.QueueLookup;
|
||||
import net.coreprotect.api.SessionLookup;
|
||||
import net.coreprotect.config.Config;
|
||||
|
@ -117,9 +122,21 @@ public class CoreProtectAPI extends Queue {
|
|||
return null;
|
||||
}
|
||||
|
||||
final ItemMeta itemMeta = getItemMeta();
|
||||
if (itemMeta instanceof BlockStateMeta) {
|
||||
return ((BlockStateMeta) itemMeta).getBlockState().getBlockData();
|
||||
}
|
||||
|
||||
String blockData = parse[12];
|
||||
if (blockData == null || blockData.length() == 0) {
|
||||
return getType().createBlockData();
|
||||
final Material type = getType();
|
||||
if (type.isBlock()) {
|
||||
return type.createBlockData();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
return Bukkit.getServer().createBlockData(blockData);
|
||||
}
|
||||
|
@ -147,6 +164,27 @@ public class CoreProtectAPI extends Queue {
|
|||
public String worldName() {
|
||||
return Util.getWorldName(Integer.parseInt(parse.length < 13 ? parse[5] : parse[9]));
|
||||
}
|
||||
|
||||
public int getAmount() {
|
||||
if (parse.length < 13) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Integer.parseInt(parse[10]);
|
||||
}
|
||||
|
||||
public ItemMeta getItemMeta() {
|
||||
if (parse.length < 13) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (parse[11] == null || parse[11].isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final byte[] metadata = parse[11].getBytes(StandardCharsets.ISO_8859_1);
|
||||
final ItemStack item = (ItemStack) Rollback.populateItemStack(new ItemStack(getType(), getAmount()), metadata)[2];
|
||||
return item.getItemMeta();
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<Object, Boolean> parseList(List<Object> list) {
|
||||
|
@ -168,7 +206,7 @@ public class CoreProtectAPI extends Queue {
|
|||
}
|
||||
|
||||
public int APIVersion() {
|
||||
return 9;
|
||||
return 10;
|
||||
}
|
||||
|
||||
public List<String[]> blockLookup(Block block, int time) {
|
||||
|
@ -178,6 +216,13 @@ public class CoreProtectAPI extends Queue {
|
|||
return null;
|
||||
}
|
||||
|
||||
public List<String[]> containerTransactionsLookup(Location location, int time) {
|
||||
if (Config.getGlobal().API_ENABLED) {
|
||||
return ContainerTransactionsAPI.performLookup(location, time);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String[]> queueLookup(Block block) {
|
||||
return QueueLookup.performLookup(block);
|
||||
}
|
||||
|
@ -282,6 +327,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 +374,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) {
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
package net.coreprotect.api;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.Location;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.Database;
|
||||
import net.coreprotect.database.statement.UserStatement;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public final class ContainerTransactionsAPI {
|
||||
|
||||
private static final int CONNECTION_WAIT_TIME = 1000;
|
||||
|
||||
private ContainerTransactionsAPI() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public static List<String[]> performLookup(Location location, int offset) {
|
||||
List<String[]> result = new ArrayList<>();
|
||||
|
||||
if (location == null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
try (Connection connection = Database.getConnection(false, CONNECTION_WAIT_TIME)) {
|
||||
final int x = (int) location.getX();
|
||||
final int y = (int) location.getY();
|
||||
final int z = (int) location.getZ();
|
||||
final int now = (int) (System.currentTimeMillis() / 1000L);
|
||||
final int worldId = Util.getWorldId(location.getWorld().getName());
|
||||
final int timeFrom = offset > 0 ? now - offset : 0;
|
||||
|
||||
if (connection == null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
String query = "SELECT time,user,action,type,data,rolled_back,amount,metadata FROM " +
|
||||
ConfigHandler.prefix + "container " + Util.getWidIndex("container") +
|
||||
"WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "'" +
|
||||
" AND time > '" + timeFrom + "' ORDER BY rowid DESC";
|
||||
try (ResultSet resultSet = statement.executeQuery(query)) {
|
||||
|
||||
while (resultSet.next()) {
|
||||
final String resultTime = resultSet.getString("time");
|
||||
final int resultUserId = resultSet.getInt("user");
|
||||
final String resultAction = resultSet.getString("action");
|
||||
final int resultType = resultSet.getInt("type");
|
||||
final String resultData = resultSet.getString("data");
|
||||
final String resultRolledBack = resultSet.getString("rolled_back");
|
||||
final int resultAmount = resultSet.getInt("amount");
|
||||
final byte[] resultMetadata = resultSet.getBytes("metadata");
|
||||
if (ConfigHandler.playerIdCacheReversed.get(resultUserId) == null) {
|
||||
UserStatement.loadName(connection, resultUserId);
|
||||
}
|
||||
String resultUser = ConfigHandler.playerIdCacheReversed.get(resultUserId);
|
||||
final String metadata = resultMetadata != null ? new String(resultMetadata, StandardCharsets.ISO_8859_1) : "";
|
||||
|
||||
String[] resultElement = new String[]{ resultTime, resultUser,
|
||||
String.valueOf(x), String.valueOf(y), String.valueOf(z), String.valueOf(resultType),
|
||||
resultData, resultAction, resultRolledBack, String.valueOf(worldId),
|
||||
String.valueOf(resultAmount), metadata, "" };
|
||||
result.add(resultElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
CoreProtect.getInstance().getLogger().log(Level.WARNING, e.toString(), e);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -13,6 +13,7 @@ import org.bukkit.block.BlockState;
|
|||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.Directional;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
|
@ -22,6 +23,10 @@ import org.bukkit.event.player.PlayerInteractEvent;
|
|||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.PotionData;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionType;
|
||||
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
@ -263,4 +268,20 @@ public class BukkitAdapter implements BukkitInterface {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getArrowMeta(Arrow arrow, ItemStack itemStack) {
|
||||
PotionData data = arrow.getBasePotionData();
|
||||
if (data.getType() != PotionType.UNCRAFTABLE) {
|
||||
itemStack = new ItemStack(Material.TIPPED_ARROW);
|
||||
PotionMeta meta = (PotionMeta) itemStack.getItemMeta();
|
||||
meta.setBasePotionData(data);
|
||||
for (PotionEffect effect : arrow.getCustomEffects()) {
|
||||
meta.addCustomEffect(effect, false);
|
||||
}
|
||||
itemStack.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.bukkit.block.Block;
|
|||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
@ -84,4 +85,6 @@ public interface BukkitInterface {
|
|||
|
||||
public boolean isSignFront(SignChangeEvent event);
|
||||
|
||||
public ItemStack getArrowMeta(Arrow arrow, ItemStack itemStack);
|
||||
|
||||
}
|
||||
|
|
|
@ -11,9 +11,13 @@ import org.bukkit.block.BlockState;
|
|||
import org.bukkit.block.ChiseledBookshelf;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.sign.Side;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionType;
|
||||
|
||||
import net.coreprotect.model.BlockGroup;
|
||||
|
||||
|
@ -254,4 +258,22 @@ public class Bukkit_v1_20 extends Bukkit_v1_19 implements BukkitInterface {
|
|||
return event.getSide().equals(Side.FRONT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getArrowMeta(Arrow arrow, ItemStack itemStack) {
|
||||
PotionType potionType = arrow.getBasePotionType();
|
||||
Color color = arrow.getColor();
|
||||
if (potionType != null || color != null) {
|
||||
itemStack = new ItemStack(Material.TIPPED_ARROW);
|
||||
PotionMeta meta = (PotionMeta) itemStack.getItemMeta();
|
||||
meta.setBasePotionType(potionType);
|
||||
meta.setColor(color);
|
||||
for (PotionEffect effect : arrow.getCustomEffects()) {
|
||||
meta.addCustomEffect(effect, false);
|
||||
}
|
||||
itemStack.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ public class Config extends Language {
|
|||
private static final Map<String, String[]> HEADERS = new HashMap<>();
|
||||
private static final Map<String, String> DEFAULT_VALUES = new LinkedHashMap<>();
|
||||
private static final Map<String, Config> CONFIG_BY_WORLD_NAME = new HashMap<>();
|
||||
private static final WeakHashMap<World, Config> CONFIG_BY_WORLD = new WeakHashMap<>();
|
||||
private static final String DEFAULT_FILE_HEADER = "# CoreProtect Config";
|
||||
public static final String LINE_SEPARATOR = "\n";
|
||||
|
||||
|
@ -262,10 +261,14 @@ public class Config extends Language {
|
|||
|
||||
// returns a world specific config if it exists, otherwise the global config
|
||||
public static Config getConfig(final World world) {
|
||||
Config ret = CONFIG_BY_WORLD.get(world);
|
||||
return getConfig(world.getName());
|
||||
}
|
||||
|
||||
public static Config getConfig(final String worldName) {
|
||||
Config ret = CONFIG_BY_WORLD_NAME.get(worldName);
|
||||
if (ret == null) {
|
||||
ret = CONFIG_BY_WORLD_NAME.getOrDefault(world.getName(), GLOBAL);
|
||||
CONFIG_BY_WORLD.put(world, ret);
|
||||
ret = CONFIG_BY_WORLD_NAME.getOrDefault(worldName, GLOBAL);
|
||||
CONFIG_BY_WORLD_NAME.put(worldName, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -409,7 +412,6 @@ public class Config extends Language {
|
|||
}
|
||||
|
||||
CONFIG_BY_WORLD_NAME.clear();
|
||||
CONFIG_BY_WORLD.clear();
|
||||
|
||||
// we need to load global first since it is used for config defaults
|
||||
final byte[] defaultData = data.get("config");
|
||||
|
|
|
@ -45,6 +45,7 @@ import net.coreprotect.listener.player.PlayerInteractEntityListener;
|
|||
import net.coreprotect.listener.player.PlayerInteractListener;
|
||||
import net.coreprotect.listener.player.PlayerItemBreakListener;
|
||||
import net.coreprotect.listener.player.PlayerJoinListener;
|
||||
import net.coreprotect.listener.player.PlayerPickupArrowListener;
|
||||
import net.coreprotect.listener.player.PlayerQuitListener;
|
||||
import net.coreprotect.listener.player.PlayerTakeLecternBookListener;
|
||||
import net.coreprotect.listener.player.ProjectileLaunchListener;
|
||||
|
|
|
@ -122,11 +122,11 @@ public final class EntityDeathListener extends Queue implements Listener {
|
|||
e = isCommand ? "#command" : "";
|
||||
}
|
||||
|
||||
List<DamageCause> validDamageCauses = Arrays.asList(DamageCause.KILL, DamageCause.POISON, DamageCause.THORNS, DamageCause.MAGIC, DamageCause.WITHER);
|
||||
List<DamageCause> validDamageCauses = Arrays.asList(DamageCause.SUICIDE, DamageCause.POISON, DamageCause.THORNS, DamageCause.MAGIC, DamageCause.WITHER);
|
||||
|
||||
boolean skip = true;
|
||||
EntityDamageEvent.DamageCause cause = damage.getCause();
|
||||
if (!Config.getConfig(entity.getWorld()).SKIP_GENERIC_DATA || (!(entity instanceof Zombie) && !(entity instanceof Skeleton)) || validDamageCauses.contains(cause)) {
|
||||
if (!Config.getConfig(entity.getWorld()).SKIP_GENERIC_DATA || (!(entity instanceof Zombie) && !(entity instanceof Skeleton)) || (validDamageCauses.contains(cause) || cause.name().equals("KILL"))) {
|
||||
skip = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package net.coreprotect.listener;
|
||||
package net.coreprotect.listener.player;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.AbstractArrow;
|
||||
|
@ -8,11 +8,8 @@ import org.bukkit.event.EventPriority;
|
|||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerPickupArrowEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.PotionData;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionType;
|
||||
|
||||
import net.coreprotect.bukkit.BukkitAdapter;
|
||||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.listener.entity.EntityPickupItemListener;
|
||||
|
||||
|
@ -31,16 +28,7 @@ public final class PlayerPickupArrowListener extends Queue implements Listener {
|
|||
|
||||
if (arrow instanceof Arrow) {
|
||||
Arrow arrowEntity = (Arrow) arrow;
|
||||
PotionData data = arrowEntity.getBasePotionData();
|
||||
if (data.getType() != PotionType.UNCRAFTABLE) {
|
||||
itemStack = new ItemStack(Material.TIPPED_ARROW);
|
||||
PotionMeta meta = (PotionMeta) itemStack.getItemMeta();
|
||||
meta.setBasePotionData(data);
|
||||
for (PotionEffect effect : arrowEntity.getCustomEffects()) {
|
||||
meta.addCustomEffect(effect, false);
|
||||
}
|
||||
itemStack.setItemMeta(meta);
|
||||
}
|
||||
itemStack = BukkitAdapter.ADAPTER.getArrowMeta(arrowEntity, itemStack);
|
||||
}
|
||||
|
||||
return itemStack;
|
|
@ -24,7 +24,6 @@ import net.coreprotect.config.Config;
|
|||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.database.logger.ItemLogger;
|
||||
import net.coreprotect.listener.PlayerPickupArrowListener;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public final class ProjectileLaunchListener extends Queue implements Listener {
|
||||
|
|
Loading…
Reference in New Issue