Compare commits
60 Commits
Author | SHA1 | Date |
---|---|---|
Intelli | ca59ff25df | |
Intelli | cfb53f766e | |
lukyn76 | e7c5078035 | |
Intelli | 5242973fe8 | |
Intelli | e99a4a86d0 | |
Intelli | 48b1fe22d3 | |
Intelli | 29225a4a59 | |
Intelli | e6557ab5f3 | |
Intelli | 5859958ec2 | |
Intelli | 5bc28b3e05 | |
Intelli | b41e40acc0 | |
Intelli | 5a49ef8447 | |
Telesphoreo | 42af5dc7a1 | |
Intelli | dbb44ab5b9 | |
Intelli | d18a023e73 | |
Intelli | 377a6f55b9 | |
Intelli | e61b8a4d9b | |
Intelli | 3b9d8726d9 | |
Intelli | 48d2030766 | |
Intelli | 86ace6c326 | |
Intelli | 346b4b8b20 | |
Intelli | 704f0aaf9b | |
Intelli | 4daaf6cc02 | |
Intelli | 5426e69fb8 | |
Intelli | 6023c21ba9 | |
Intelli | 3e3496ad12 | |
Intelli | f3c631bbf5 | |
Intelli | d8ad48beb8 | |
Intelli | 053f7d5c7d | |
Nahuel Dolores | a4c37da8ee | |
Intelli | b1598a022a | |
Intelli | 32688c55cf | |
Intelli | a239b51ed1 | |
Intelli | af1d4402eb | |
Intelli | f7fea2b298 | |
Intelli | 15e8cd5b88 | |
Intelli | c91f460e42 | |
Intelli | 7424037795 | |
Intelli | ba6a55fff6 | |
Intelli | 1c57ba52aa | |
Intelli | 4308d4afca | |
Intelli | 7c61a33571 | |
Intelli | 172c6440db | |
Intelli | d8a669ed6c | |
Intelli | 66b77ee75a | |
Intelli | 488392cdbc | |
Intelli | b48dcec589 | |
Intelli | e49913bc09 | |
Intelli | d944c2bd89 | |
Intelli | f76b0d45bd | |
Intelli | 9f3196dc97 | |
Intelli | 69c163468f | |
Intelli | 34421b64f7 | |
Intelli | 0edf160f43 | |
Intelli | 45d4642086 | |
Take-John | af35a98b1d | |
Take-John | 950cf9460b | |
Intelli | 1b6d2ec667 | |
Intelli | d7910262be | |
Intelli | 8459181f77 |
|
@ -41,7 +41,7 @@ Maven
|
|||
<dependency>
|
||||
<groupId>net.coreprotect</groupId>
|
||||
<artifactId>coreprotect</artifactId>
|
||||
<version>22.0</version>
|
||||
<version>22.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
```
|
||||
|
|
18
build.gradle
18
build.gradle
|
@ -2,16 +2,16 @@ import org.apache.tools.ant.filters.ReplaceTokens
|
|||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'com.github.johnrengelman.shadow' version '7.1.2'
|
||||
id 'com.github.johnrengelman.shadow' version '8.1.1'
|
||||
id 'com.palantir.git-version' version '0.13.0'
|
||||
}
|
||||
|
||||
group = 'net.coreprotect'
|
||||
String projectVersion = '22.0'
|
||||
String projectVersion = '22.4'
|
||||
String projectBranch = ''
|
||||
version = projectVersion // `version` might be modified, we don't always want that (e.g. plugin.yml)
|
||||
description = 'Provides block protection for your server.'
|
||||
sourceCompatibility = '17'
|
||||
sourceCompatibility = '21'
|
||||
|
||||
if (System.getenv("BUILD_NUMBER") != null) {
|
||||
// Being built in Jenkins, append Build ID
|
||||
|
@ -23,18 +23,16 @@ if (System.getenv("BUILD_NUMBER") != null) {
|
|||
logger.info("Building version $version")
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
maven { url = 'https://hub.spigotmc.org/nexus/content/groups/public/' }
|
||||
maven { url = 'https://papermc.io/repo/repository/maven-public/' }
|
||||
maven { url = 'https://repo.papermc.io/repository/maven-public/' }
|
||||
maven { url = 'https://repo.codemc.org/repository/maven-public/' }
|
||||
maven { url = 'https://maven.enginehub.org/repo/' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly('com.sk89q.worldedit:worldedit-bukkit:7.0.0-SNAPSHOT') {
|
||||
exclude group: 'org.bukkit'
|
||||
}
|
||||
compileOnly 'dev.folia:folia-api:1.20.1-R0.1-SNAPSHOT'
|
||||
implementation(platform("com.intellectualsites.bom:bom-newest:1.44")) // Ref: https://github.com/IntellectualSites/bom
|
||||
compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Core")
|
||||
compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit")
|
||||
compileOnly 'io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT'
|
||||
implementation 'org.bstats:bstats-bukkit-lite:1.8'
|
||||
implementation 'com.zaxxer:HikariCP:5.0.1'
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ The CoreProtect API enables you to log your own block changes, perform lookups,
|
|||
|
||||
| API Details | |
|
||||
| --- | --- |
|
||||
| **API Version:** | 9 |
|
||||
| **Plugin Version:** | v21.0+ |
|
||||
| **API Version:** | 10 |
|
||||
| **Plugin Version:** | v22.4+ |
|
||||
| **Maven:** | [maven.playpro.com](https://maven.playpro.com) |
|
||||
|
||||
*Documentation for the API version 9 can be found [here](/api/version/v9/).*
|
||||
*Documentation for the API version 10 can be found [here](/api/version/v10/).*
|
|
@ -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:** | v22.4+ |
|
||||
| **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 22.4 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, 22.4).
|
||||
|
||||
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() < 10) {
|
||||
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();
|
||||
```
|
||||
|
||||
---
|
|
@ -93,7 +93,7 @@ Purge old block data. Useful for freeing up space on your HDD if you don't need
|
|||
|
||||
| Command | Parameters |
|
||||
| --- | --- |
|
||||
| /co purge | `t:<time> r:<world>` |
|
||||
| /co purge | `t:<time> r:<world> i:<include>` |
|
||||
|
||||
For example, `/co purge t:30d` will delete all data older than one month, and only keep the last 30 days of data.
|
||||
|
||||
|
@ -101,8 +101,12 @@ For example, `/co purge t:30d` will delete all data older than one month, and on
|
|||
> If used from the console, only data older than 24 hours can be purged.
|
||||
|
||||
**Purging Worlds**
|
||||
You can also optionally specify a world in CoreProtect v19+.
|
||||
For example, `/co purge t:30d r:#world_nether` will delete all data older than one month in the Nether, without deleting data in any other worlds.
|
||||
You can optionally specify a world in CoreProtect v19+.
|
||||
For example, `/co purge t:30d r:#world_nether` will delete all data older than one month in the Nether, without removing data in any other worlds.
|
||||
|
||||
**Purging Blocks**
|
||||
You can optionally specify block types in CoreProtect v23+.
|
||||
For example, `/co purge t:30d i:stone,dirt` will delete all stone and dirt data older than one month, without removing other block data.
|
||||
|
||||
**MySQL Optimization**
|
||||
In CoreProtect v2.15+, adding "#optimize" to the end of the command (e.g. `/co purge t:30d #optimize`) will also optimize your tables and reclaim disk space.
|
||||
|
|
|
@ -18,15 +18,18 @@ Secondary configuration files override the value specified in config.yml. If you
|
|||
|
||||
## Disabling Logging
|
||||
|
||||
To disable logging for specific users or commands, simply do the following:
|
||||
To disable logging for specific users, blocks or commands, simply do the following:
|
||||
|
||||
1. In the CoreProtect plugin directory, create a file named `blacklist.txt`.
|
||||
2. Enter the names of the users (or commands) you'd like to disable logging for (each username on a new line).
|
||||
3. Either restart your server, or type "/co reload" in-game.
|
||||
|
||||
This can be used to disable logging for non-player users, such as "#tnt". For example, if you'd like to disable logging for the user "Notch", TNT explosions, and the "/help" command, the blacklist.txt file would look like this:
|
||||
This can be used to disable logging for non-player users, such as "#creeper". For example, if you'd like to disable logging for the user "Notch", TNT explosions, stone blocks, and the "/help" command, the blacklist.txt file would look like this:
|
||||
```text
|
||||
Notch
|
||||
#tnt
|
||||
/help
|
||||
```
|
||||
minecraft:stone
|
||||
```
|
||||
|
||||
*Please note that to disable logging for blocks, CoreProtect v23+ is required, and you must include the namespace. For example, to disable logging for dirt, you must add it as "minecraft:dirt".*
|
|
@ -22,7 +22,7 @@ Log your own block changes, perform lookups, rollbacks, restores, and more.
|
|||
A list of plugins and tools that are compatible with CoreProtect.
|
||||
|
||||
[**Per-World Configuration Files**](/config/#per-world-configuration)
|
||||
Log your own block changes, perform lookups, rollbacks, restores, and more.
|
||||
Modify the logging settings for a specific world on your server.
|
||||
|
||||
[**Disable Logging for Specific Users or Commands**](/config/#disabling-logging)
|
||||
Log your own block changes, perform lookups, rollbacks, restores, and more.
|
||||
[**Disable Logging With a Blacklist**](/config/#disabling-logging)
|
||||
Disable logging for specific users, blocks or commands.
|
||||
|
|
37
pom.xml
37
pom.xml
|
@ -2,7 +2,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>net.coreprotect</groupId>
|
||||
<artifactId>CoreProtect</artifactId>
|
||||
<version>22.0</version>
|
||||
<version>22.4</version>
|
||||
<properties>
|
||||
<project.branch></project.branch>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
@ -88,11 +88,18 @@
|
|||
<id>codemc-repo</id>
|
||||
<url>https://repo.codemc.org/repository/maven-public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>enginehub-repo</id>
|
||||
<url>https://maven.enginehub.org/repo/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.intellectualsites.bom</groupId>
|
||||
<artifactId>bom-newest</artifactId> <!-- Ref: https://github.com/IntellectualSites/bom -->
|
||||
<version>1.44</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<dependencies>
|
||||
<!--
|
||||
paper-api: io.papermc.paper
|
||||
|
@ -101,9 +108,9 @@
|
|||
bukkit: org.bukkit
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>dev.folia</groupId>
|
||||
<artifactId>folia-api</artifactId>
|
||||
<version>1.20.1-R0.1-SNAPSHOT</version>
|
||||
<groupId>io.papermc.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<version>1.20.4-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -113,14 +120,18 @@
|
|||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sk89q.worldedit</groupId>
|
||||
<artifactId>worldedit-bukkit</artifactId>
|
||||
<version>7.0.0-SNAPSHOT</version>
|
||||
<groupId>com.fastasyncworldedit</groupId>
|
||||
<artifactId>FastAsyncWorldEdit-Core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fastasyncworldedit</groupId>
|
||||
<artifactId>FastAsyncWorldEdit-Bukkit</artifactId>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<artifactId>FastAsyncWorldEdit-Core</artifactId>
|
||||
<groupId>*</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
package net.coreprotect;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.bstats.bukkit.MetricsLite;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
@ -24,6 +28,7 @@ import net.coreprotect.thread.NetworkHandler;
|
|||
import net.coreprotect.thread.Scheduler;
|
||||
import net.coreprotect.utility.Chat;
|
||||
import net.coreprotect.utility.Color;
|
||||
import net.coreprotect.utility.Teleport;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public final class CoreProtect extends JavaPlugin {
|
||||
|
@ -168,6 +173,15 @@ public final class CoreProtect extends JavaPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
if (!ConfigHandler.isFolia) {
|
||||
Iterator<Entry<Location, BlockData>> iterator = Teleport.revertBlocks.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Entry<Location, BlockData> entry = iterator.next();
|
||||
entry.getKey().getBlock().setBlockData(entry.getValue());
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
ConfigHandler.serverRunning = false;
|
||||
long shutdownTime = System.currentTimeMillis();
|
||||
long alertTime = shutdownTime + (10 * 1000);
|
||||
|
|
|
@ -25,7 +25,7 @@ import net.coreprotect.config.Config;
|
|||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.database.Database;
|
||||
import net.coreprotect.database.Lookup;
|
||||
import net.coreprotect.database.Rollback;
|
||||
import net.coreprotect.database.rollback.Rollback;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.listener.player.InventoryChangeListener;
|
||||
import net.coreprotect.utility.Chat;
|
||||
|
@ -168,7 +168,7 @@ public class CoreProtectAPI extends Queue {
|
|||
}
|
||||
|
||||
public int APIVersion() {
|
||||
return 9;
|
||||
return 10;
|
||||
}
|
||||
|
||||
public List<String[]> blockLookup(Block block, int time) {
|
||||
|
@ -191,8 +191,8 @@ public class CoreProtectAPI extends Queue {
|
|||
boolean match = false;
|
||||
|
||||
if (Config.getGlobal().API_ENABLED) {
|
||||
long timestamp = System.currentTimeMillis() / 1000L;
|
||||
long offsetTime = timestamp - offset;
|
||||
long timestamp = System.currentTimeMillis();
|
||||
long offsetTime = timestamp - offset * 1000L;
|
||||
List<String[]> check = blockLookup(block, time);
|
||||
|
||||
for (String[] value : check) {
|
||||
|
@ -212,8 +212,8 @@ public class CoreProtectAPI extends Queue {
|
|||
boolean match = false;
|
||||
|
||||
if (Config.getGlobal().API_ENABLED) {
|
||||
long timestamp = System.currentTimeMillis() / 1000L;
|
||||
long offsetTime = timestamp - offset;
|
||||
long timestamp = System.currentTimeMillis();
|
||||
long offsetTime = timestamp - offset * 1000L;
|
||||
List<String[]> check = blockLookup(block, time);
|
||||
|
||||
for (String[] value : check) {
|
||||
|
@ -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) {
|
||||
|
|
|
@ -3,6 +3,7 @@ package net.coreprotect.api;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Location;
|
||||
|
@ -49,7 +50,9 @@ public class QueueLookup extends Queue {
|
|||
Map<Integer, Object> consumerObject = Consumer.consumerObjects.get(currentConsumer);
|
||||
|
||||
Location oldLocation = block.getLocation();
|
||||
for (Object[] data : consumerData) {
|
||||
ListIterator<Object[]> iterator = consumerData.listIterator();
|
||||
while (iterator.hasNext()) {
|
||||
Object[] data = iterator.next();
|
||||
int id = (int) data[0];
|
||||
int action = (int) data[1];
|
||||
if (action != Process.BLOCK_BREAK && action != Process.BLOCK_PLACE) {
|
||||
|
|
|
@ -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;
|
||||
|
@ -207,6 +212,11 @@ public class BukkitAdapter implements BukkitInterface {
|
|||
return material;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDecoratedPot(Material material) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuspiciousBlock(Material material) {
|
||||
return false;
|
||||
|
@ -258,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;
|
||||
|
@ -66,6 +67,8 @@ public interface BukkitInterface {
|
|||
|
||||
public Material getPlantSeeds(Material material);
|
||||
|
||||
public boolean isDecoratedPot(Material material);
|
||||
|
||||
public boolean isSuspiciousBlock(Material material);
|
||||
|
||||
public boolean isSign(Material material);
|
||||
|
@ -82,4 +85,6 @@ public interface BukkitInterface {
|
|||
|
||||
public boolean isSignFront(SignChangeEvent event);
|
||||
|
||||
public ItemStack getArrowMeta(Arrow arrow, ItemStack itemStack);
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import net.coreprotect.model.BlockGroup;
|
|||
public class Bukkit_v1_16 extends BukkitAdapter implements BukkitInterface {
|
||||
|
||||
public Bukkit_v1_16() {
|
||||
BlockGroup.TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP, Material.SOUL_TORCH, Material.TWISTING_VINES, Material.CRIMSON_FUNGUS, Material.WARPED_FUNGUS, Material.CRIMSON_ROOTS, Material.WARPED_ROOTS, Material.NETHER_SPROUTS, Material.CRIMSON_SIGN, Material.WARPED_SIGN));
|
||||
BlockGroup.TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP, Material.SOUL_TORCH, Material.TWISTING_VINES, Material.CRIMSON_FUNGUS, Material.WARPED_FUNGUS, Material.CRIMSON_ROOTS, Material.WARPED_ROOTS, Material.NETHER_SPROUTS, Material.CRIMSON_SIGN, Material.WARPED_SIGN));
|
||||
BlockGroup.TRACK_BOTTOM = new HashSet<>(Arrays.asList(Material.WEEPING_VINES));
|
||||
BlockGroup.TRACK_SIDE = new HashSet<>(Arrays.asList(Material.WALL_TORCH, Material.REDSTONE_WALL_TORCH, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.ACTIVATOR_RAIL, Material.WHITE_BED, Material.ORANGE_BED, Material.MAGENTA_BED, Material.LIGHT_BLUE_BED, Material.YELLOW_BED, Material.LIME_BED, Material.PINK_BED, Material.GRAY_BED, Material.LIGHT_GRAY_BED, Material.CYAN_BED, Material.PURPLE_BED, Material.BLUE_BED, Material.BROWN_BED, Material.GREEN_BED, Material.RED_BED, Material.BLACK_BED, Material.LADDER, Material.ACACIA_WALL_SIGN, Material.BIRCH_WALL_SIGN, Material.DARK_OAK_WALL_SIGN, Material.JUNGLE_WALL_SIGN, Material.OAK_WALL_SIGN, Material.SPRUCE_WALL_SIGN, Material.VINE, Material.COCOA, Material.TRIPWIRE_HOOK, Material.WHITE_WALL_BANNER, Material.ORANGE_WALL_BANNER, Material.MAGENTA_WALL_BANNER, Material.LIGHT_BLUE_WALL_BANNER, Material.YELLOW_WALL_BANNER, Material.LIME_WALL_BANNER, Material.PINK_WALL_BANNER, Material.GRAY_WALL_BANNER, Material.LIGHT_GRAY_WALL_BANNER, Material.CYAN_WALL_BANNER, Material.PURPLE_WALL_BANNER, Material.BLUE_WALL_BANNER, Material.BROWN_WALL_BANNER, Material.GREEN_WALL_BANNER, Material.RED_WALL_BANNER, Material.BLACK_WALL_BANNER, Material.SOUL_WALL_TORCH, Material.CRIMSON_WALL_SIGN, Material.WARPED_WALL_SIGN));
|
||||
BlockGroup.DOORS = new HashSet<>(Arrays.asList(Material.OAK_DOOR, Material.SPRUCE_DOOR, Material.BIRCH_DOOR, Material.JUNGLE_DOOR, Material.ACACIA_DOOR, Material.DARK_OAK_DOOR, Material.CRIMSON_DOOR, Material.WARPED_DOOR));
|
||||
|
@ -34,7 +34,7 @@ public class Bukkit_v1_16 extends BukkitAdapter implements BukkitInterface {
|
|||
BlockGroup.INTERACT_BLOCKS = new HashSet<>(Arrays.asList(Material.SPRUCE_FENCE_GATE, Material.BIRCH_FENCE_GATE, Material.JUNGLE_FENCE_GATE, Material.DARK_OAK_FENCE_GATE, Material.ACACIA_FENCE_GATE, Material.DISPENSER, Material.NOTE_BLOCK, Material.CHEST, Material.FURNACE, Material.LEVER, Material.REPEATER, Material.ACACIA_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.DARK_OAK_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.OAK_TRAPDOOR, Material.OAK_FENCE_GATE, Material.BREWING_STAND, Material.ANVIL, Material.CHIPPED_ANVIL, Material.DAMAGED_ANVIL, Material.ENDER_CHEST, Material.TRAPPED_CHEST, Material.COMPARATOR, Material.HOPPER, Material.DROPPER, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.GRINDSTONE, Material.LOOM, Material.SMOKER, Material.CRAFTING_TABLE, Material.CARTOGRAPHY_TABLE, Material.ENCHANTING_TABLE, Material.SMITHING_TABLE, Material.STONECUTTER, Material.CRIMSON_FENCE_GATE, Material.WARPED_FENCE_GATE, Material.CRIMSON_TRAPDOOR, Material.WARPED_TRAPDOOR));
|
||||
BlockGroup.SAFE_INTERACT_BLOCKS = new HashSet<>(Arrays.asList(Material.LEVER, Material.ACACIA_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.DARK_OAK_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.OAK_TRAPDOOR, Material.OAK_FENCE_GATE, Material.SPRUCE_FENCE_GATE, Material.BIRCH_FENCE_GATE, Material.JUNGLE_FENCE_GATE, Material.DARK_OAK_FENCE_GATE, Material.ACACIA_FENCE_GATE, Material.CRIMSON_FENCE_GATE, Material.WARPED_FENCE_GATE, Material.CRIMSON_TRAPDOOR, Material.WARPED_TRAPDOOR));
|
||||
BlockGroup.UPDATE_STATE = new HashSet<>(Arrays.asList(Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FURNACE, Material.BLAST_FURNACE, Material.SMOKER, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.GLOWSTONE, Material.JACK_O_LANTERN, Material.REPEATER, Material.REDSTONE_LAMP, Material.BEACON, Material.COMPARATOR, Material.DAYLIGHT_DETECTOR, Material.REDSTONE_BLOCK, Material.HOPPER, Material.CHEST, Material.TRAPPED_CHEST, Material.ACTIVATOR_RAIL, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.SHROOMLIGHT, Material.RESPAWN_ANCHOR, Material.CRYING_OBSIDIAN, Material.TARGET));
|
||||
BlockGroup.NON_ATTACHABLE = new HashSet<>(Arrays.asList(Material.AIR, Material.CAVE_AIR, Material.BARRIER, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.WATER, Material.LAVA, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.LADDER, Material.RAIL, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.SNOW, Material.SUGAR_CANE, Material.NETHER_PORTAL, Material.REPEATER, Material.KELP, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH));
|
||||
BlockGroup.NON_ATTACHABLE = new HashSet<>(Arrays.asList(Material.AIR, Material.CAVE_AIR, Material.BARRIER, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.WATER, Material.LAVA, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.LADDER, Material.RAIL, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.SNOW, Material.SUGAR_CANE, Material.NETHER_PORTAL, Material.REPEATER, Material.KELP, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -31,14 +31,14 @@ public class Bukkit_v1_17 extends Bukkit_v1_16 implements BukkitInterface {
|
|||
|
||||
public Bukkit_v1_17() {
|
||||
BlockGroup.TRACK_ANY = new HashSet<>(Arrays.asList(Material.PISTON_HEAD, Material.LEVER, Material.BELL, Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER, Material.GLOW_LICHEN));
|
||||
BlockGroup.TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP, Material.SOUL_TORCH, Material.TWISTING_VINES, Material.CRIMSON_FUNGUS, Material.WARPED_FUNGUS, Material.CRIMSON_ROOTS, Material.WARPED_ROOTS, Material.NETHER_SPROUTS, Material.CRIMSON_SIGN, Material.WARPED_SIGN, Material.AZALEA, Material.FLOWERING_AZALEA, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF));
|
||||
BlockGroup.TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP, Material.SOUL_TORCH, Material.TWISTING_VINES, Material.CRIMSON_FUNGUS, Material.WARPED_FUNGUS, Material.CRIMSON_ROOTS, Material.WARPED_ROOTS, Material.NETHER_SPROUTS, Material.CRIMSON_SIGN, Material.WARPED_SIGN, Material.AZALEA, Material.FLOWERING_AZALEA, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF));
|
||||
BlockGroup.TRACK_TOP_BOTTOM = new HashSet<>(Arrays.asList(Material.POINTED_DRIPSTONE, Material.BIG_DRIPLEAF_STEM));
|
||||
BlockGroup.TRACK_BOTTOM = new HashSet<>(Arrays.asList(Material.WEEPING_VINES, Material.CAVE_VINES, Material.CAVE_VINES_PLANT, Material.HANGING_ROOTS));
|
||||
BlockGroup.VINES = new HashSet<>(Arrays.asList(Material.VINE, Material.WEEPING_VINES, Material.TWISTING_VINES, Material.CAVE_VINES));
|
||||
BlockGroup.CANDLES = new HashSet<>(Arrays.asList(Material.CANDLE, Material.BLACK_CANDLE, Material.BLUE_CANDLE, Material.BROWN_CANDLE, Material.CYAN_CANDLE, Material.GRAY_CANDLE, Material.GREEN_CANDLE, Material.LIGHT_BLUE_CANDLE, Material.LIGHT_GRAY_CANDLE, Material.LIME_CANDLE, Material.MAGENTA_CANDLE, Material.ORANGE_CANDLE, Material.PINK_CANDLE, Material.PURPLE_CANDLE, Material.RED_CANDLE, Material.WHITE_CANDLE, Material.YELLOW_CANDLE, Material.CANDLE_CAKE, Material.BLACK_CANDLE_CAKE, Material.BLUE_CANDLE_CAKE, Material.BROWN_CANDLE_CAKE, Material.CYAN_CANDLE_CAKE, Material.GRAY_CANDLE_CAKE, Material.GREEN_CANDLE_CAKE, Material.LIGHT_BLUE_CANDLE_CAKE, Material.LIGHT_GRAY_CANDLE_CAKE, Material.LIME_CANDLE_CAKE, Material.MAGENTA_CANDLE_CAKE, Material.ORANGE_CANDLE_CAKE, Material.PINK_CANDLE_CAKE, Material.PURPLE_CANDLE_CAKE, Material.RED_CANDLE_CAKE, Material.WHITE_CANDLE_CAKE, Material.YELLOW_CANDLE_CAKE));
|
||||
BlockGroup.AMETHYST = new HashSet<>(Arrays.asList(Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER));
|
||||
BlockGroup.UPDATE_STATE = new HashSet<>(Arrays.asList(Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FURNACE, Material.BLAST_FURNACE, Material.SMOKER, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.GLOWSTONE, Material.JACK_O_LANTERN, Material.REPEATER, Material.REDSTONE_LAMP, Material.BEACON, Material.COMPARATOR, Material.DAYLIGHT_DETECTOR, Material.REDSTONE_BLOCK, Material.HOPPER, Material.CHEST, Material.TRAPPED_CHEST, Material.ACTIVATOR_RAIL, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.SHROOMLIGHT, Material.RESPAWN_ANCHOR, Material.CRYING_OBSIDIAN, Material.TARGET, Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER, Material.CAVE_VINES, Material.CAVE_VINES_PLANT, Material.GLOW_LICHEN, Material.LIGHT, Material.LAVA_CAULDRON));
|
||||
BlockGroup.NON_ATTACHABLE = new HashSet<>(Arrays.asList(Material.AIR, Material.CAVE_AIR, Material.BARRIER, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.WATER, Material.LAVA, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.LADDER, Material.RAIL, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.SNOW, Material.SUGAR_CANE, Material.NETHER_PORTAL, Material.REPEATER, Material.KELP, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.LIGHT, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF, Material.BIG_DRIPLEAF_STEM, Material.GLOW_LICHEN, Material.HANGING_ROOTS));
|
||||
BlockGroup.NON_ATTACHABLE = new HashSet<>(Arrays.asList(Material.AIR, Material.CAVE_AIR, Material.BARRIER, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.WATER, Material.LAVA, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.LADDER, Material.RAIL, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.SNOW, Material.SUGAR_CANE, Material.NETHER_PORTAL, Material.REPEATER, Material.KELP, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.LIGHT, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF, Material.BIG_DRIPLEAF_STEM, Material.GLOW_LICHEN, Material.HANGING_ROOTS));
|
||||
BlockGroup.VERTICAL_TOP_BOTTOM = new HashSet<>(Arrays.asList(Material.BIG_DRIPLEAF_STEM));
|
||||
}
|
||||
|
||||
|
|
|
@ -16,14 +16,14 @@ import net.coreprotect.model.BlockGroup;
|
|||
public class Bukkit_v1_19 extends Bukkit_v1_18 implements BukkitInterface {
|
||||
|
||||
public Bukkit_v1_19() {
|
||||
BlockGroup.TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.MANGROVE_PROPAGULE, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.MANGROVE_SIGN, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP, Material.SOUL_TORCH, Material.TWISTING_VINES, Material.CRIMSON_FUNGUS, Material.WARPED_FUNGUS, Material.CRIMSON_ROOTS, Material.WARPED_ROOTS, Material.NETHER_SPROUTS, Material.CRIMSON_SIGN, Material.WARPED_SIGN, Material.AZALEA, Material.FLOWERING_AZALEA, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF));
|
||||
BlockGroup.TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.MANGROVE_PROPAGULE, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.MANGROVE_SIGN, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP, Material.SOUL_TORCH, Material.TWISTING_VINES, Material.CRIMSON_FUNGUS, Material.WARPED_FUNGUS, Material.CRIMSON_ROOTS, Material.WARPED_ROOTS, Material.NETHER_SPROUTS, Material.CRIMSON_SIGN, Material.WARPED_SIGN, Material.AZALEA, Material.FLOWERING_AZALEA, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF));
|
||||
BlockGroup.TRACK_SIDE = new HashSet<>(Arrays.asList(Material.WALL_TORCH, Material.REDSTONE_WALL_TORCH, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.ACTIVATOR_RAIL, Material.WHITE_BED, Material.ORANGE_BED, Material.MAGENTA_BED, Material.LIGHT_BLUE_BED, Material.YELLOW_BED, Material.LIME_BED, Material.PINK_BED, Material.GRAY_BED, Material.LIGHT_GRAY_BED, Material.CYAN_BED, Material.PURPLE_BED, Material.BLUE_BED, Material.BROWN_BED, Material.GREEN_BED, Material.RED_BED, Material.BLACK_BED, Material.LADDER, Material.MANGROVE_WALL_SIGN, Material.ACACIA_WALL_SIGN, Material.BIRCH_WALL_SIGN, Material.DARK_OAK_WALL_SIGN, Material.JUNGLE_WALL_SIGN, Material.OAK_WALL_SIGN, Material.SPRUCE_WALL_SIGN, Material.VINE, Material.COCOA, Material.TRIPWIRE_HOOK, Material.WHITE_WALL_BANNER, Material.ORANGE_WALL_BANNER, Material.MAGENTA_WALL_BANNER, Material.LIGHT_BLUE_WALL_BANNER, Material.YELLOW_WALL_BANNER, Material.LIME_WALL_BANNER, Material.PINK_WALL_BANNER, Material.GRAY_WALL_BANNER, Material.LIGHT_GRAY_WALL_BANNER, Material.CYAN_WALL_BANNER, Material.PURPLE_WALL_BANNER, Material.BLUE_WALL_BANNER, Material.BROWN_WALL_BANNER, Material.GREEN_WALL_BANNER, Material.RED_WALL_BANNER, Material.BLACK_WALL_BANNER, Material.SOUL_WALL_TORCH, Material.CRIMSON_WALL_SIGN, Material.WARPED_WALL_SIGN));
|
||||
BlockGroup.DOORS = new HashSet<>(Arrays.asList(Material.OAK_DOOR, Material.SPRUCE_DOOR, Material.BIRCH_DOOR, Material.JUNGLE_DOOR, Material.MANGROVE_DOOR, Material.ACACIA_DOOR, Material.DARK_OAK_DOOR, Material.CRIMSON_DOOR, Material.WARPED_DOOR));
|
||||
BlockGroup.BUTTONS = new HashSet<>(Arrays.asList(Material.STONE_BUTTON, Material.OAK_BUTTON, Material.MANGROVE_BUTTON, Material.ACACIA_BUTTON, Material.BIRCH_BUTTON, Material.DARK_OAK_BUTTON, Material.JUNGLE_BUTTON, Material.SPRUCE_BUTTON, Material.POLISHED_BLACKSTONE_BUTTON, Material.CRIMSON_BUTTON, Material.WARPED_BUTTON));
|
||||
BlockGroup.PRESSURE_PLATES = new HashSet<>(Arrays.asList(Material.STONE_PRESSURE_PLATE, Material.MANGROVE_PRESSURE_PLATE, Material.ACACIA_PRESSURE_PLATE, Material.BIRCH_PRESSURE_PLATE, Material.DARK_OAK_PRESSURE_PLATE, Material.HEAVY_WEIGHTED_PRESSURE_PLATE, Material.JUNGLE_PRESSURE_PLATE, Material.LIGHT_WEIGHTED_PRESSURE_PLATE, Material.OAK_PRESSURE_PLATE, Material.SPRUCE_PRESSURE_PLATE, Material.CRIMSON_PRESSURE_PLATE, Material.WARPED_PRESSURE_PLATE, Material.POLISHED_BLACKSTONE_PRESSURE_PLATE));
|
||||
BlockGroup.INTERACT_BLOCKS = new HashSet<>(Arrays.asList(Material.SPRUCE_FENCE_GATE, Material.BIRCH_FENCE_GATE, Material.JUNGLE_FENCE_GATE, Material.DARK_OAK_FENCE_GATE, Material.MANGROVE_FENCE_GATE, Material.ACACIA_FENCE_GATE, Material.DISPENSER, Material.NOTE_BLOCK, Material.CHEST, Material.FURNACE, Material.LEVER, Material.REPEATER, Material.MANGROVE_TRAPDOOR, Material.ACACIA_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.DARK_OAK_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.OAK_TRAPDOOR, Material.OAK_FENCE_GATE, Material.BREWING_STAND, Material.ANVIL, Material.CHIPPED_ANVIL, Material.DAMAGED_ANVIL, Material.ENDER_CHEST, Material.TRAPPED_CHEST, Material.COMPARATOR, Material.HOPPER, Material.DROPPER, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.GRINDSTONE, Material.LOOM, Material.SMOKER, Material.CRAFTING_TABLE, Material.CARTOGRAPHY_TABLE, Material.ENCHANTING_TABLE, Material.SMITHING_TABLE, Material.STONECUTTER, Material.CRIMSON_FENCE_GATE, Material.WARPED_FENCE_GATE, Material.CRIMSON_TRAPDOOR, Material.WARPED_TRAPDOOR));
|
||||
BlockGroup.SAFE_INTERACT_BLOCKS = new HashSet<>(Arrays.asList(Material.LEVER, Material.MANGROVE_TRAPDOOR, Material.ACACIA_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.DARK_OAK_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.OAK_TRAPDOOR, Material.OAK_FENCE_GATE, Material.SPRUCE_FENCE_GATE, Material.BIRCH_FENCE_GATE, Material.JUNGLE_FENCE_GATE, Material.DARK_OAK_FENCE_GATE, Material.MANGROVE_FENCE_GATE, Material.ACACIA_FENCE_GATE, Material.CRIMSON_FENCE_GATE, Material.WARPED_FENCE_GATE, Material.CRIMSON_TRAPDOOR, Material.WARPED_TRAPDOOR));
|
||||
BlockGroup.NON_ATTACHABLE = new HashSet<>(Arrays.asList(Material.AIR, Material.CAVE_AIR, Material.BARRIER, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.MANGROVE_PROPAGULE, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.WATER, Material.LAVA, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.LADDER, Material.RAIL, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.SNOW, Material.SUGAR_CANE, Material.NETHER_PORTAL, Material.REPEATER, Material.KELP, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.LIGHT, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF, Material.BIG_DRIPLEAF_STEM, Material.GLOW_LICHEN, Material.HANGING_ROOTS));
|
||||
BlockGroup.NON_ATTACHABLE = new HashSet<>(Arrays.asList(Material.AIR, Material.CAVE_AIR, Material.BARRIER, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.MANGROVE_PROPAGULE, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.WATER, Material.LAVA, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.LADDER, Material.RAIL, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.SNOW, Material.SUGAR_CANE, Material.NETHER_PORTAL, Material.REPEATER, Material.KELP, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.LIGHT, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF, Material.BIG_DRIPLEAF_STEM, Material.GLOW_LICHEN, Material.HANGING_ROOTS));
|
||||
BlockGroup.SCULK = new HashSet<>(Arrays.asList(Material.SCULK, Material.SCULK_VEIN, Material.SCULK_SENSOR, Material.SCULK_SHRIEKER));
|
||||
}
|
||||
|
||||
|
|
|
@ -11,18 +11,23 @@ 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;
|
||||
|
||||
public class Bukkit_v1_20 extends Bukkit_v1_19 implements BukkitInterface {
|
||||
|
||||
private Boolean hasClickedPosition = null;
|
||||
private Boolean hasBasePotionType = null;
|
||||
|
||||
public Bukkit_v1_20() {
|
||||
BlockGroup.CONTAINERS = new HashSet<>(Arrays.asList(Material.JUKEBOX, Material.DISPENSER, Material.CHEST, Material.FURNACE, Material.BREWING_STAND, Material.TRAPPED_CHEST, Material.HOPPER, Material.DROPPER, Material.ARMOR_STAND, Material.ITEM_FRAME, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.SMOKER, Material.LECTERN, Material.CHISELED_BOOKSHELF));
|
||||
BlockGroup.CONTAINERS = new HashSet<>(Arrays.asList(Material.JUKEBOX, Material.DISPENSER, Material.CHEST, Material.FURNACE, Material.BREWING_STAND, Material.TRAPPED_CHEST, Material.HOPPER, Material.DROPPER, Material.ARMOR_STAND, Material.ITEM_FRAME, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.SMOKER, Material.LECTERN, Material.CHISELED_BOOKSHELF, Material.DECORATED_POT));
|
||||
BlockGroup.UPDATE_STATE = new HashSet<>(Arrays.asList(Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FURNACE, Material.BLAST_FURNACE, Material.SMOKER, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.GLOWSTONE, Material.JACK_O_LANTERN, Material.REPEATER, Material.REDSTONE_LAMP, Material.BEACON, Material.COMPARATOR, Material.DAYLIGHT_DETECTOR, Material.REDSTONE_BLOCK, Material.HOPPER, Material.CHEST, Material.TRAPPED_CHEST, Material.ACTIVATOR_RAIL, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.SHROOMLIGHT, Material.RESPAWN_ANCHOR, Material.CRYING_OBSIDIAN, Material.TARGET, Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER, Material.CAVE_VINES, Material.CAVE_VINES_PLANT, Material.GLOW_LICHEN, Material.LIGHT, Material.LAVA_CAULDRON, Material.CHISELED_BOOKSHELF));
|
||||
|
||||
BlockGroup.BUTTONS.clear();
|
||||
|
@ -94,6 +99,27 @@ public class Bukkit_v1_20 extends Bukkit_v1_19 implements BukkitInterface {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parseLegacyName(String name) {
|
||||
switch (name) {
|
||||
case "GRASS_PATH":
|
||||
name = "DIRT_PATH";
|
||||
break;
|
||||
case "GRASS":
|
||||
name = "SHORT_GRASS";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// fallback until this method is moved up into v1_21
|
||||
if (name.equals("SHORT_GRASS") && Material.getMaterial(name) == null) {
|
||||
name = "GRASS";
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(Sign sign, boolean isFront, int color) {
|
||||
if (isFront) {
|
||||
|
@ -158,6 +184,11 @@ public class Bukkit_v1_20 extends Bukkit_v1_19 implements BukkitInterface {
|
|||
return material;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDecoratedPot(Material material) {
|
||||
return material == Material.DECORATED_POT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuspiciousBlock(Material material) {
|
||||
return material == Material.SUSPICIOUS_GRAVEL || material == Material.SUSPICIOUS_SAND;
|
||||
|
@ -228,4 +259,36 @@ 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) {
|
||||
try {
|
||||
if (hasBasePotionType == null) {
|
||||
hasBasePotionType = true;
|
||||
Arrow.class.getMethod("getBasePotionType"); // Bukkit 1.20.2+
|
||||
}
|
||||
else if (Boolean.FALSE.equals(hasBasePotionType)) {
|
||||
return super.getArrowMeta(arrow, 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;
|
||||
}
|
||||
catch (Exception e) {
|
||||
hasBasePotionType = false;
|
||||
return super.getArrowMeta(arrow, itemStack);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
@ -34,7 +35,6 @@ import net.coreprotect.utility.Util;
|
|||
public class CommandHandler implements CommandExecutor {
|
||||
private static CommandHandler instance;
|
||||
private static ConcurrentHashMap<String, Boolean> versionAlert = new ConcurrentHashMap<>();
|
||||
protected static Set<Material> naturalBlocks = BlockGroup.NATURAL_BLOCKS;
|
||||
|
||||
public static CommandHandler getInstance() {
|
||||
if (instance == null) {
|
||||
|
@ -277,12 +277,7 @@ public class CommandHandler implements CommandExecutor {
|
|||
if (argument.contains(",")) {
|
||||
String[] i2 = argument.split(",");
|
||||
for (String i3 : i2) {
|
||||
if (i3.equals("#natural")) {
|
||||
for (Material block : naturalBlocks) {
|
||||
excluded.put(block, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!checkTags(i3, excluded)) {
|
||||
Material i3_material = Util.getType(i3);
|
||||
if (i3_material != null && (i3_material.isBlock() || argAction.contains(4))) {
|
||||
excluded.put(i3_material, false);
|
||||
|
@ -306,12 +301,7 @@ public class CommandHandler implements CommandExecutor {
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (argument.equals("#natural")) {
|
||||
for (Material block : naturalBlocks) {
|
||||
excluded.put(block, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!checkTags(argument, excluded)) {
|
||||
Material iMaterial = Util.getType(argument);
|
||||
if (iMaterial != null && (iMaterial.isBlock() || argAction.contains(4))) {
|
||||
excluded.put(iMaterial, false);
|
||||
|
@ -359,7 +349,7 @@ public class CommandHandler implements CommandExecutor {
|
|||
String[] i2 = argument.split(",");
|
||||
for (String i3 : i2) {
|
||||
boolean isBlock = false;
|
||||
if (i3.equals("#natural")) {
|
||||
if (checkTags(i3)) {
|
||||
isBlock = true;
|
||||
}
|
||||
else {
|
||||
|
@ -387,7 +377,7 @@ public class CommandHandler implements CommandExecutor {
|
|||
}
|
||||
else {
|
||||
boolean isBlock = false;
|
||||
if (argument.equals("#natural")) {
|
||||
if (checkTags(argument)) {
|
||||
isBlock = true;
|
||||
}
|
||||
else {
|
||||
|
@ -630,10 +620,7 @@ public class CommandHandler implements CommandExecutor {
|
|||
if (argument.contains(",")) {
|
||||
String[] i2 = argument.split(",");
|
||||
for (String i3 : i2) {
|
||||
if (i3.equals("#natural")) {
|
||||
restricted.addAll(naturalBlocks);
|
||||
}
|
||||
else {
|
||||
if (!checkTags(argument, restricted)) {
|
||||
Material i3_material = Util.getType(i3);
|
||||
if (i3_material != null && (i3_material.isBlock() || argAction.contains(4))) {
|
||||
restricted.add(i3_material);
|
||||
|
@ -662,10 +649,7 @@ public class CommandHandler implements CommandExecutor {
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (argument.equals("#natural")) {
|
||||
restricted.addAll(naturalBlocks);
|
||||
}
|
||||
else {
|
||||
if (!checkTags(argument, restricted)) {
|
||||
Material material = Util.getType(argument);
|
||||
if (material != null && (material.isBlock() || argAction.contains(4))) {
|
||||
restricted.add(material);
|
||||
|
@ -1137,6 +1121,52 @@ public class CommandHandler implements CommandExecutor {
|
|||
return worldName;
|
||||
}
|
||||
|
||||
protected static Map<String, Set<Material>> getTags() {
|
||||
Map<String, Set<Material>> tagMap = new HashMap<>();
|
||||
tagMap.put("#button", BlockGroup.BUTTONS);
|
||||
tagMap.put("#container", BlockGroup.CONTAINERS);
|
||||
tagMap.put("#door", BlockGroup.DOORS);
|
||||
tagMap.put("#natural", BlockGroup.NATURAL_BLOCKS);
|
||||
tagMap.put("#pressure_plate", BlockGroup.PRESSURE_PLATES);
|
||||
tagMap.put("#shulker_box", BlockGroup.SHULKER_BOXES);
|
||||
return tagMap;
|
||||
}
|
||||
|
||||
protected static boolean checkTags(String argument) {
|
||||
return getTags().containsKey(argument);
|
||||
}
|
||||
|
||||
protected static boolean checkTags(String argument, Map<Object, Boolean> list) {
|
||||
for (Entry<String, Set<Material>> entry : getTags().entrySet()) {
|
||||
String tag = entry.getKey();
|
||||
Set<Material> materials = entry.getValue();
|
||||
|
||||
if (argument.equals(tag)) {
|
||||
for (Material block : materials) {
|
||||
list.put(block, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static boolean checkTags(String argument, List<Object> list) {
|
||||
for (Entry<String, Set<Material>> entry : getTags().entrySet()) {
|
||||
String tag = entry.getKey();
|
||||
Set<Material> materials = entry.getValue();
|
||||
|
||||
if (argument.equals(tag)) {
|
||||
list.addAll(materials);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void validUserCheck(List<String> users, String user) {
|
||||
List<String> badUsers = Arrays.asList("n", "noisy", "v", "verbose", "#v", "#verbose", "#silent", "#preview", "#preview_cancel", "#count", "#sum");
|
||||
String check = user.replaceAll("[\\s'\"]", "");
|
||||
|
|
|
@ -8,11 +8,16 @@ import java.sql.ResultSetMetaData;
|
|||
import java.text.NumberFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import net.coreprotect.bukkit.BukkitAdapter;
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.consumer.Consumer;
|
||||
|
@ -31,13 +36,20 @@ public class PurgeCommand extends Consumer {
|
|||
int resultc = args.length;
|
||||
Location location = CommandHandler.parseLocation(player, args);
|
||||
final Integer[] argRadius = CommandHandler.parseRadius(args, player, location);
|
||||
final List<Integer> argAction = CommandHandler.parseAction(args);
|
||||
final List<Object> argBlocks = CommandHandler.parseRestricted(player, args, argAction);
|
||||
final Map<Object, Boolean> argExclude = CommandHandler.parseExcluded(player, args, argAction);
|
||||
final List<String> argExcludeUsers = CommandHandler.parseExcludedUsers(player, args);
|
||||
final long[] argTime = CommandHandler.parseTime(args);
|
||||
final int argWid = CommandHandler.parseWorld(args, false, false);
|
||||
final List<Integer> argAction = CommandHandler.parseAction(args);
|
||||
final List<Integer> supportedActions = Arrays.asList();
|
||||
long startTime = argTime[1] > 0 ? argTime[0] : 0;
|
||||
long endTime = argTime[1] > 0 ? argTime[1] : argTime[0];
|
||||
|
||||
if (argBlocks == null || argExclude == null || argExcludeUsers == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ConfigHandler.converterRunning) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
|
||||
return;
|
||||
|
@ -67,6 +79,14 @@ public class PurgeCommand extends Consumer {
|
|||
Chat.sendMessage(player, new ChatMessage(Phrase.build(Phrase.WORLD_NOT_FOUND, worldName)).build());
|
||||
return;
|
||||
}
|
||||
if (player instanceof Player && endTime < 2592000) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_MINIMUM_TIME, "30", Selector.FIRST)); // 30 days
|
||||
return;
|
||||
}
|
||||
else if (endTime < 86400) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_MINIMUM_TIME, "24", Selector.SECOND)); // 24 hours
|
||||
return;
|
||||
}
|
||||
for (int action : argAction) {
|
||||
if (!supportedActions.contains(action)) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ACTION_NOT_SUPPORTED));
|
||||
|
@ -74,12 +94,70 @@ public class PurgeCommand extends Consumer {
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (player instanceof Player && endTime < 2592000) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_MINIMUM_TIME, "30", Selector.FIRST)); // 30 days
|
||||
return;
|
||||
|
||||
StringBuilder restrict = new StringBuilder();
|
||||
String includeBlock = "";
|
||||
String includeEntity = "";
|
||||
boolean hasBlock = false;
|
||||
boolean item = false;
|
||||
boolean entity = false;
|
||||
int restrictCount = 0;
|
||||
|
||||
if (argBlocks.size() > 0) {
|
||||
StringBuilder includeListMaterial = new StringBuilder();
|
||||
StringBuilder includeListEntity = new StringBuilder();
|
||||
|
||||
for (Object restrictTarget : argBlocks) {
|
||||
String targetName = "";
|
||||
|
||||
if (restrictTarget instanceof Material) {
|
||||
targetName = ((Material) restrictTarget).name();
|
||||
if (includeListMaterial.length() == 0) {
|
||||
includeListMaterial = includeListMaterial.append(Util.getBlockId(targetName, false));
|
||||
}
|
||||
else {
|
||||
includeListMaterial.append(",").append(Util.getBlockId(targetName, false));
|
||||
}
|
||||
|
||||
/* Include legacy IDs */
|
||||
int legacyId = BukkitAdapter.ADAPTER.getLegacyBlockId((Material) restrictTarget);
|
||||
if (legacyId > 0) {
|
||||
includeListMaterial.append(",").append(legacyId);
|
||||
}
|
||||
|
||||
targetName = ((Material) restrictTarget).name().toLowerCase(Locale.ROOT);
|
||||
item = (!item ? !(((Material) restrictTarget).isBlock()) : item);
|
||||
hasBlock = true;
|
||||
}
|
||||
else if (restrictTarget instanceof EntityType) {
|
||||
targetName = ((EntityType) restrictTarget).name();
|
||||
if (includeListEntity.length() == 0) {
|
||||
includeListEntity = includeListEntity.append(Util.getEntityId(targetName, false));
|
||||
}
|
||||
else {
|
||||
includeListEntity.append(",").append(Util.getEntityId(targetName, false));
|
||||
}
|
||||
|
||||
targetName = ((EntityType) restrictTarget).name().toLowerCase(Locale.ROOT);
|
||||
entity = true;
|
||||
}
|
||||
|
||||
if (restrictCount == 0) {
|
||||
restrict = restrict.append("" + targetName + "");
|
||||
}
|
||||
else {
|
||||
restrict.append(", ").append(targetName);
|
||||
}
|
||||
|
||||
restrictCount++;
|
||||
}
|
||||
|
||||
includeBlock = includeListMaterial.toString();
|
||||
includeEntity = includeListEntity.toString();
|
||||
}
|
||||
else if (endTime < 86400) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_MINIMUM_TIME, "24", Selector.SECOND)); // 24 hours
|
||||
|
||||
if (entity) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ACTION_NOT_SUPPORTED));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -90,7 +168,12 @@ public class PurgeCommand extends Consumer {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final StringBuilder restrictTargets = restrict;
|
||||
final String includeBlockFinal = includeBlock;
|
||||
final boolean optimize = optimizeCheck;
|
||||
final boolean hasBlockRestriction = hasBlock;
|
||||
final int restrictCountFinal = restrictCount;
|
||||
|
||||
class BasicThread implements Runnable {
|
||||
|
||||
|
@ -123,6 +206,11 @@ public class PurgeCommand extends Consumer {
|
|||
else {
|
||||
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_STARTED, "#global"));
|
||||
}
|
||||
|
||||
if (hasBlockRestriction) {
|
||||
Chat.sendGlobalMessage(player, Phrase.build(Phrase.ROLLBACK_INCLUDE, restrictTargets.toString(), Selector.FIRST, Selector.FIRST, (restrictCountFinal == 1 ? Selector.FIRST : Selector.SECOND))); // include
|
||||
}
|
||||
|
||||
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_NOTICE_1));
|
||||
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_NOTICE_2));
|
||||
|
||||
|
@ -172,6 +260,7 @@ public class PurgeCommand extends Consumer {
|
|||
|
||||
List<String> purgeTables = Arrays.asList("sign", "container", "item", "skull", "session", "chat", "command", "entity", "block");
|
||||
List<String> worldTables = Arrays.asList("sign", "container", "item", "session", "chat", "command", "block");
|
||||
List<String> restrictTables = Arrays.asList("block");
|
||||
List<String> excludeTables = Arrays.asList("database_lock"); // don't insert data into these tables
|
||||
for (String table : ConfigHandler.databaseTables) {
|
||||
String tableName = table.replaceAll("_", " ");
|
||||
|
@ -198,11 +287,16 @@ public class PurgeCommand extends Consumer {
|
|||
try {
|
||||
String timeLimit = "";
|
||||
if (purgeTables.contains(table)) {
|
||||
String blockRestriction = "";
|
||||
if (hasBlockRestriction && restrictTables.contains(table)) {
|
||||
blockRestriction = "type IN(" + includeBlockFinal + ") AND ";
|
||||
}
|
||||
|
||||
if (argWid > 0 && worldTables.contains(table)) {
|
||||
timeLimit = " WHERE (wid = '" + argWid + "' AND (time >= '" + timeEnd + "' OR time < '" + timeStart + "')) OR wid != '" + argWid + "'";
|
||||
timeLimit = " WHERE (" + blockRestriction + "wid = '" + argWid + "' AND (time >= '" + timeEnd + "' OR time < '" + timeStart + "')) OR (" + blockRestriction + "wid != '" + argWid + "')";
|
||||
}
|
||||
else if (argWid == 0) {
|
||||
timeLimit = " WHERE (time >= '" + timeEnd + "' OR time < '" + timeStart + "')";
|
||||
timeLimit = " WHERE " + blockRestriction + "(time >= '" + timeEnd + "' OR time < '" + timeStart + "')";
|
||||
}
|
||||
}
|
||||
query = "INSERT INTO " + purgePrefix + table + " SELECT " + columns + " FROM " + ConfigHandler.prefix + table + timeLimit;
|
||||
|
@ -256,6 +350,14 @@ public class PurgeCommand extends Consumer {
|
|||
try {
|
||||
boolean purge = purgeTables.contains(table);
|
||||
|
||||
String blockRestriction = "";
|
||||
if (hasBlockRestriction && restrictTables.contains(table)) {
|
||||
blockRestriction = "type IN(" + includeBlockFinal + ") AND ";
|
||||
}
|
||||
else if (hasBlockRestriction) {
|
||||
purge = false;
|
||||
}
|
||||
|
||||
String worldRestriction = "";
|
||||
if (argWid > 0 && worldTables.contains(table)) {
|
||||
worldRestriction = " AND wid = '" + argWid + "'";
|
||||
|
@ -265,7 +367,7 @@ public class PurgeCommand extends Consumer {
|
|||
}
|
||||
|
||||
if (purge) {
|
||||
query = "DELETE FROM " + purgePrefix + table + " WHERE time < '" + timeEnd + "' AND time >= '" + timeStart + "'" + worldRestriction;
|
||||
query = "DELETE FROM " + purgePrefix + table + " WHERE " + blockRestriction + "time < '" + timeEnd + "' AND time >= '" + timeStart + "'" + worldRestriction;
|
||||
preparedStmt = connection.prepareStatement(query);
|
||||
preparedStmt.execute();
|
||||
preparedStmt.close();
|
||||
|
@ -315,6 +417,14 @@ public class PurgeCommand extends Consumer {
|
|||
try {
|
||||
boolean purge = purgeTables.contains(table);
|
||||
|
||||
String blockRestriction = "";
|
||||
if (hasBlockRestriction && restrictTables.contains(table)) {
|
||||
blockRestriction = "type IN(" + includeBlockFinal + ") AND ";
|
||||
}
|
||||
else if (hasBlockRestriction) {
|
||||
purge = false;
|
||||
}
|
||||
|
||||
String worldRestriction = "";
|
||||
if (argWid > 0 && worldTables.contains(table)) {
|
||||
worldRestriction = " AND wid = '" + argWid + "'";
|
||||
|
@ -324,7 +434,7 @@ public class PurgeCommand extends Consumer {
|
|||
}
|
||||
|
||||
if (purge) {
|
||||
query = "DELETE FROM " + ConfigHandler.prefix + table + " WHERE time < '" + timeEnd + "' AND time >= '" + timeStart + "'" + worldRestriction;
|
||||
query = "DELETE FROM " + ConfigHandler.prefix + table + " WHERE " + blockRestriction + "time < '" + timeEnd + "' AND time >= '" + timeStart + "'" + worldRestriction;
|
||||
preparedStmt = connection.prepareStatement(query);
|
||||
preparedStmt.execute();
|
||||
removed = removed + preparedStmt.getUpdateCount();
|
||||
|
|
|
@ -23,8 +23,8 @@ import net.coreprotect.config.Config;
|
|||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.ContainerRollback;
|
||||
import net.coreprotect.database.Database;
|
||||
import net.coreprotect.database.Rollback;
|
||||
import net.coreprotect.database.lookup.PlayerLookup;
|
||||
import net.coreprotect.database.rollback.Rollback;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.language.Selector;
|
||||
import net.coreprotect.utility.Chat;
|
||||
|
|
|
@ -301,7 +301,7 @@ public class TabHandler implements TabCompleter {
|
|||
|
||||
if (materials == null) {
|
||||
List<Material> addList = Arrays.asList(Material.ARMOR_STAND);
|
||||
List<Material> excludeList = Arrays.asList(Material.GRASS);
|
||||
List<Material> excludeList = Arrays.asList();
|
||||
Set<String> materialList = new HashSet<>();
|
||||
|
||||
Material[] materialValues = Material.values();
|
||||
|
@ -317,6 +317,11 @@ public class TabHandler implements TabCompleter {
|
|||
materialList.add(add.name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
// add custom tags
|
||||
for (String tag : CommandHandler.getTags().keySet()) {
|
||||
materialList.add(tag);
|
||||
}
|
||||
|
||||
materials = new ArrayList<>(materialList);
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
@ -42,7 +41,7 @@ public class Config extends Language {
|
|||
public String MYSQL_USERNAME;
|
||||
public String MYSQL_PASSWORD;
|
||||
public String LANGUAGE;
|
||||
public boolean ENABLE_AWE;
|
||||
public boolean ENABLE_SSL;
|
||||
public boolean DISABLE_WAL;
|
||||
public boolean HOVER_EVENTS;
|
||||
public boolean DATABASE_LOCK;
|
||||
|
@ -189,7 +188,7 @@ public class Config extends Language {
|
|||
}
|
||||
|
||||
private void readValues() {
|
||||
this.ENABLE_AWE = this.getBoolean("enable-awe", false);
|
||||
this.ENABLE_SSL = this.getBoolean("enable-ssl", false);
|
||||
this.DISABLE_WAL = this.getBoolean("disable-wal", false);
|
||||
this.HOVER_EVENTS = this.getBoolean("hover-events", true);
|
||||
this.DATABASE_LOCK = this.getBoolean("database-lock", true);
|
||||
|
@ -260,10 +259,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;
|
||||
}
|
||||
|
@ -407,7 +410,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");
|
||||
|
|
|
@ -101,6 +101,7 @@ public class ConfigHandler extends Queue {
|
|||
public static ConcurrentHashMap<String, List<ItemStack>> itemsSell = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsBuy = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, Object[]> hopperAbort = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, Object[]> hopperSuccess = new ConcurrentHashMap<>();
|
||||
public static Map<String, List<ItemStack[]>> forceContainer = syncMap();
|
||||
public static Map<String, Integer> lookupType = syncMap();
|
||||
public static Map<String, Object[]> lookupThrottle = syncMap();
|
||||
|
@ -249,7 +250,7 @@ public class ConfigHandler extends Queue {
|
|||
config.addDataSourceProperty("maintainTimeStats", "false");
|
||||
/* Disable SSL to suppress the unverified server identity warning */
|
||||
config.addDataSourceProperty("allowPublicKeyRetrieval", "true");
|
||||
config.addDataSourceProperty("useSSL", "false");
|
||||
config.addDataSourceProperty("useSSL", Config.getGlobal().ENABLE_SSL);
|
||||
|
||||
ConfigHandler.hikariDataSource = new HikariDataSource(config);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
package net.coreprotect.consumer.process;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
|
@ -41,6 +47,42 @@ class ContainerTransactionProcess {
|
|||
ConfigHandler.transactingChest.remove(transactingChestId);
|
||||
}
|
||||
}
|
||||
else if (loggingChestId.startsWith("#hopper")) {
|
||||
List<Object> transactingChest = ConfigHandler.transactingChest.get(transactingChestId);
|
||||
if (force_size == 0 && ConfigHandler.oldContainer.getOrDefault(loggingChestId, Collections.synchronizedList(new ArrayList<>())).size() == 1 && transactingChest != null && transactingChest.isEmpty()) {
|
||||
int loopCount = ConfigHandler.loggingChest.getOrDefault(loggingChestId, 0);
|
||||
int maxInventorySize = (99 * 54);
|
||||
try {
|
||||
Inventory checkInventory = (Inventory) inventory;
|
||||
maxInventorySize = checkInventory.getSize() * checkInventory.getMaxStackSize();
|
||||
}
|
||||
catch (Exception e) {
|
||||
// use default of 5,346
|
||||
}
|
||||
|
||||
if (loopCount > maxInventorySize) {
|
||||
ItemStack[] destinationContents = null;
|
||||
ItemStack movedItem = null;
|
||||
|
||||
String hopperPush = "#hopper-push." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
|
||||
Object[] hopperPushData = ConfigHandler.hopperSuccess.remove(hopperPush);
|
||||
if (hopperPushData != null) {
|
||||
destinationContents = (ItemStack[]) hopperPushData[0];
|
||||
movedItem = (ItemStack) hopperPushData[1];
|
||||
}
|
||||
|
||||
if (destinationContents != null) {
|
||||
Set<ItemStack> movedItems = new HashSet<>();
|
||||
Object[] lastAbort = ConfigHandler.hopperAbort.get(hopperPush);
|
||||
if (lastAbort != null && Arrays.equals(destinationContents, (ItemStack[]) lastAbort[1])) {
|
||||
((Set<?>) lastAbort[0]).forEach(itemStack -> movedItems.add((ItemStack) itemStack));
|
||||
}
|
||||
movedItems.add(movedItem);
|
||||
ConfigHandler.hopperAbort.put(hopperPush, new Object[] { movedItems, destinationContents });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inventories.remove(id);
|
||||
}
|
||||
|
|
|
@ -83,6 +83,14 @@ public class Process {
|
|||
int consumerDataSize = consumerData.size();
|
||||
currentConsumerSize = consumerDataSize;
|
||||
|
||||
if (currentConsumerSize == 0) { // No data, skip processing
|
||||
updateLockTable(statement, (lastRun ? 0 : 1));
|
||||
statement.close();
|
||||
Consumer.consumer_id.put(processId, new Integer[] { 0, 0 });
|
||||
Consumer.isPaused = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Database.beginTransaction(statement);
|
||||
// Scan through usernames, ensure everything is loaded in memory.
|
||||
for (Entry<Integer, String[]> entry : users.entrySet()) {
|
||||
|
@ -225,6 +233,7 @@ public class Process {
|
|||
consumerData.remove(index);
|
||||
}
|
||||
currentConsumerSize = 0;
|
||||
Consumer.consumer_id.put(processId, new Integer[] { 0, 0 });
|
||||
Consumer.isPaused = false;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -21,13 +21,15 @@ import net.coreprotect.CoreProtect;
|
|||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.consumer.process.Process;
|
||||
import net.coreprotect.database.rollback.Rollback;
|
||||
import net.coreprotect.database.rollback.RollbackComplete;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.model.BlockGroup;
|
||||
import net.coreprotect.thread.Scheduler;
|
||||
import net.coreprotect.utility.Chat;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class ContainerRollback extends Queue {
|
||||
public class ContainerRollback extends Rollback {
|
||||
|
||||
public static void performContainerRollbackRestore(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, String timeString, List<Object> restrictList, Map<Object, Boolean> excludeList, List<String> excludeUserList, List<Integer> actionList, final Location location, Integer[] radius, long startTime, long endTime, boolean restrictWorld, boolean lookup, boolean verbose, final int rollbackType) {
|
||||
try {
|
||||
|
@ -176,7 +178,7 @@ public class ContainerRollback extends Queue {
|
|||
int itemCount = 0;
|
||||
int entityCount = 0;
|
||||
|
||||
Rollback.finishRollbackRestore(user, location, checkUsers, restrictList, excludeList, excludeUserList, actionList, timeString, file, totalSeconds, itemCount, blockCount, entityCount, rollbackType, radius, verbose, restrictWorld, 0);
|
||||
RollbackComplete.output(user, location, checkUsers, restrictList, excludeList, excludeUserList, actionList, timeString, file, totalSeconds, itemCount, blockCount, entityCount, rollbackType, radius, verbose, restrictWorld, 0);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
|
|
@ -106,6 +106,10 @@ public class Database extends Queue {
|
|||
}
|
||||
}
|
||||
|
||||
public static boolean hasReturningKeys() {
|
||||
return (!Config.getGlobal().MYSQL && ConfigHandler.SERVER_VERSION >= 20);
|
||||
}
|
||||
|
||||
public static void containerBreakCheck(String user, Material type, Object container, ItemStack[] contents, Location location) {
|
||||
if (BlockGroup.CONTAINERS.contains(type) && !BlockGroup.SHULKER_BOXES.contains(type)) {
|
||||
if (Config.getConfig(location.getWorld()).ITEM_TRANSACTIONS) {
|
||||
|
@ -286,7 +290,12 @@ public class Database extends Queue {
|
|||
PreparedStatement preparedStatement = null;
|
||||
try {
|
||||
if (keys) {
|
||||
preparedStatement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
|
||||
if (hasReturningKeys()) {
|
||||
preparedStatement = connection.prepareStatement(query + " RETURNING rowid");
|
||||
}
|
||||
else {
|
||||
preparedStatement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
|
||||
}
|
||||
}
|
||||
else {
|
||||
preparedStatement = connection.prepareStatement(query);
|
||||
|
@ -363,7 +372,7 @@ public class Database extends Queue {
|
|||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "session(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int, user int, wid int, x int, y int (3), z int, action tinyint" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
index = ", INDEX(wid,x,z,time), INDEX(user,time), INDEX(time)";
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "sign(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int, user int, wid int, x int, y int, z int, action tinyint, color int, color_secondary int, data tinyint, waxed tinyint, face tinyint, line_1 varchar(100), line_2 varchar(100), line_3 varchar(100), line_4 varchar(100), line_5 varchar(100), line_6 varchar(100), line_7 varchar(100), line_8 varchar(100)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "skull(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int, owner varchar(64)) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "skull(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int, owner varchar(255)) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
index = ", INDEX(user), INDEX(uuid)";
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "user(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int,user varchar(100),uuid varchar(64)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
index = ", INDEX(uuid,user)";
|
||||
|
|
|
@ -29,7 +29,7 @@ import net.coreprotect.utility.Util;
|
|||
|
||||
public class Lookup extends Queue {
|
||||
|
||||
static List<String[]> convertRawLookup(Statement statement, List<Object[]> list) {
|
||||
protected static List<String[]> convertRawLookup(Statement statement, List<Object[]> list) {
|
||||
List<String[]> newList = new ArrayList<>();
|
||||
|
||||
if (list == null) {
|
||||
|
@ -122,7 +122,7 @@ public class Lookup extends Queue {
|
|||
return newList;
|
||||
}
|
||||
|
||||
static List<Object[]> performLookupRaw(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, Map<Object, Boolean> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, Long[] rowData, long startTime, long endTime, int limitOffset, int limitCount, boolean restrictWorld, boolean lookup) {
|
||||
protected static List<Object[]> performLookupRaw(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, Map<Object, Boolean> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, Long[] rowData, long startTime, long endTime, int limitOffset, int limitCount, boolean restrictWorld, boolean lookup) {
|
||||
List<Object[]> list = new ArrayList<>();
|
||||
List<Integer> invalidRollbackActions = new ArrayList<>();
|
||||
invalidRollbackActions.add(2);
|
||||
|
|
|
@ -37,8 +37,13 @@ public class BlockBreakLogger {
|
|||
return;
|
||||
}
|
||||
|
||||
if (ConfigHandler.blacklist.get(checkType.getKey().toString()) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!user.startsWith("#")) {
|
||||
CacheHandler.spreadCache.remove(location);
|
||||
String cacheId = location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ() + "." + Util.getWorldId(location.getWorld().getName());
|
||||
CacheHandler.spreadCache.remove(cacheId);
|
||||
}
|
||||
|
||||
if (checkType == Material.LECTERN) {
|
||||
|
|
|
@ -55,6 +55,10 @@ public class BlockPlaceLogger {
|
|||
return;
|
||||
}
|
||||
|
||||
if (ConfigHandler.blacklist.get(type.getKey().toString()) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int x = block.getX();
|
||||
int y = block.getY();
|
||||
int z = block.getZ();
|
||||
|
|
|
@ -161,12 +161,13 @@ public class ContainerLogger extends Queue {
|
|||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
|
||||
return;
|
||||
}
|
||||
boolean success = false;
|
||||
int slot = 0;
|
||||
for (ItemStack item : items) {
|
||||
if (item != null) {
|
||||
if (item.getAmount() > 0 && !Util.isAir(item.getType())) {
|
||||
// Object[] metadata = new Object[] { slot, item.getItemMeta() };
|
||||
List<List<Map<String, Object>>> metadata = ItemMetaHandler.seralize(item, type, faceData, slot);
|
||||
List<List<Map<String, Object>>> metadata = ItemMetaHandler.serialize(item, type, faceData, slot);
|
||||
if (metadata.size() == 0) {
|
||||
metadata = null;
|
||||
}
|
||||
|
@ -190,10 +191,17 @@ public class ContainerLogger extends Queue {
|
|||
int data = 0;
|
||||
int amount = item.getAmount();
|
||||
ContainerStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, typeId, data, amount, metadata, action, 0);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
slot++;
|
||||
}
|
||||
|
||||
if (success && user.equals("#hopper")) {
|
||||
String hopperPush = "#hopper-push." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
|
||||
ConfigHandler.hopperSuccess.remove(hopperPush);
|
||||
ConfigHandler.hopperAbort.remove(hopperPush);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.bukkit.block.BlockState;
|
|||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.Database;
|
||||
import net.coreprotect.database.statement.BlockStatement;
|
||||
import net.coreprotect.database.statement.EntityStatement;
|
||||
import net.coreprotect.database.statement.UserStatement;
|
||||
|
@ -43,11 +44,21 @@ public class EntityKillLogger {
|
|||
int x = block.getX();
|
||||
int y = block.getY();
|
||||
int z = block.getZ();
|
||||
EntityStatement.insert(preparedStmt2, time, data);
|
||||
ResultSet keys = preparedStmt2.getGeneratedKeys();
|
||||
keys.next();
|
||||
int entity_key = keys.getInt(1);
|
||||
keys.close();
|
||||
int entity_key = 0;
|
||||
|
||||
ResultSet resultSet = EntityStatement.insert(preparedStmt2, time, data);
|
||||
if (Database.hasReturningKeys()) {
|
||||
resultSet.next();
|
||||
entity_key = resultSet.getInt(1);
|
||||
resultSet.close();
|
||||
}
|
||||
else {
|
||||
ResultSet keys = preparedStmt2.getGeneratedKeys();
|
||||
keys.next();
|
||||
entity_key = keys.getInt(1);
|
||||
keys.close();
|
||||
}
|
||||
|
||||
BlockStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, type, entity_key, null, null, 3, 0);
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
|
|
@ -120,7 +120,7 @@ public class ItemLogger {
|
|||
for (ItemStack item : items) {
|
||||
if (item != null && item.getAmount() > 0 && !Util.isAir(item.getType())) {
|
||||
// Object[] metadata = new Object[] { slot, item.getItemMeta() };
|
||||
List<List<Map<String, Object>>> data = ItemMetaHandler.seralize(item, null, null, 0);
|
||||
List<List<Map<String, Object>>> data = ItemMetaHandler.serialize(item, null, null, 0);
|
||||
if (data.size() == 0) {
|
||||
data = null;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,9 @@ import org.bukkit.block.BlockState;
|
|||
import org.bukkit.block.Skull;
|
||||
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.Database;
|
||||
import net.coreprotect.database.statement.SkullStatement;
|
||||
import net.coreprotect.paper.PaperAdapter;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class SkullBreakLogger {
|
||||
|
@ -28,12 +30,19 @@ public class SkullBreakLogger {
|
|||
String skullOwner = "";
|
||||
int skullKey = 0;
|
||||
if (skull.hasOwner()) {
|
||||
skullOwner = skull.getOwningPlayer().getUniqueId().toString();
|
||||
SkullStatement.insert(preparedStmt2, time, skullOwner);
|
||||
ResultSet keys = preparedStmt2.getGeneratedKeys();
|
||||
keys.next();
|
||||
skullKey = keys.getInt(1);
|
||||
keys.close();
|
||||
skullOwner = PaperAdapter.ADAPTER.getSkullOwner(skull);
|
||||
ResultSet resultSet = SkullStatement.insert(preparedStmt2, time, skullOwner);
|
||||
if (Database.hasReturningKeys()) {
|
||||
resultSet.next();
|
||||
skullKey = resultSet.getInt(1);
|
||||
resultSet.close();
|
||||
}
|
||||
else {
|
||||
ResultSet keys = preparedStmt2.getGeneratedKeys();
|
||||
keys.next();
|
||||
skullKey = keys.getInt(1);
|
||||
keys.close();
|
||||
}
|
||||
}
|
||||
|
||||
BlockBreakLogger.log(preparedStmt, batchCount, user, block.getLocation(), type, skullKey, null, block.getBlockData().getAsString(), null);
|
||||
|
|
|
@ -9,7 +9,9 @@ import org.bukkit.block.BlockState;
|
|||
import org.bukkit.block.Skull;
|
||||
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.Database;
|
||||
import net.coreprotect.database.statement.SkullStatement;
|
||||
import net.coreprotect.paper.PaperAdapter;
|
||||
|
||||
public class SkullPlaceLogger {
|
||||
|
||||
|
@ -30,12 +32,19 @@ public class SkullPlaceLogger {
|
|||
Skull skull = (Skull) block;
|
||||
String skullOwner = "";
|
||||
if (skull.hasOwner()) {
|
||||
skullOwner = skull.getOwningPlayer().getUniqueId().toString();
|
||||
SkullStatement.insert(preparedStmt2, time, skullOwner);
|
||||
ResultSet keys = preparedStmt2.getGeneratedKeys();
|
||||
keys.next();
|
||||
skullKey = keys.getInt(1);
|
||||
keys.close();
|
||||
skullOwner = PaperAdapter.ADAPTER.getSkullOwner(skull);
|
||||
ResultSet resultSet = SkullStatement.insert(preparedStmt2, time, skullOwner);
|
||||
if (Database.hasReturningKeys()) {
|
||||
resultSet.next();
|
||||
skullKey = resultSet.getInt(1);
|
||||
resultSet.close();
|
||||
}
|
||||
else {
|
||||
ResultSet keys = preparedStmt2.getGeneratedKeys();
|
||||
keys.next();
|
||||
skullKey = keys.getInt(1);
|
||||
keys.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package net.coreprotect.database;
|
||||
package net.coreprotect.database.rollback;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.sql.Statement;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -20,14 +17,9 @@ import java.util.UUID;
|
|||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.FireworkEffect;
|
||||
import org.bukkit.FireworkEffect.Builder;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.attribute.AttributeModifier;
|
||||
import org.bukkit.block.Banner;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
|
@ -35,7 +27,6 @@ import org.bukkit.block.BlockState;
|
|||
import org.bukkit.block.CommandBlock;
|
||||
import org.bukkit.block.CreatureSpawner;
|
||||
import org.bukkit.block.Jukebox;
|
||||
import org.bukkit.block.ShulkerBox;
|
||||
import org.bukkit.block.banner.Pattern;
|
||||
import org.bukkit.block.data.Bisected;
|
||||
import org.bukkit.block.data.Bisected.Half;
|
||||
|
@ -65,18 +56,6 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.inventory.meta.BannerMeta;
|
||||
import org.bukkit.inventory.meta.BlockStateMeta;
|
||||
import org.bukkit.inventory.meta.CrossbowMeta;
|
||||
import org.bukkit.inventory.meta.FireworkEffectMeta;
|
||||
import org.bukkit.inventory.meta.FireworkMeta;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.LeatherArmorMeta;
|
||||
import org.bukkit.inventory.meta.MapMeta;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.inventory.meta.SuspiciousStewMeta;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.util.io.BukkitObjectInputStream;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
|
@ -85,6 +64,7 @@ import net.coreprotect.config.Config;
|
|||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.consumer.process.Process;
|
||||
import net.coreprotect.database.Lookup;
|
||||
import net.coreprotect.database.logger.ItemLogger;
|
||||
import net.coreprotect.database.statement.UserStatement;
|
||||
import net.coreprotect.language.Phrase;
|
||||
|
@ -100,7 +80,7 @@ import net.coreprotect.utility.Teleport;
|
|||
import net.coreprotect.utility.Util;
|
||||
import net.coreprotect.utility.entity.HangingUtil;
|
||||
|
||||
public class Rollback extends Queue {
|
||||
public class Rollback extends RollbackUtil {
|
||||
|
||||
public static List<String[]> performRollbackRestore(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, String timeString, List<Object> restrictList, Map<Object, Boolean> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, long startTime, long endTime, boolean restrictWorld, boolean lookup, boolean verbose, final int rollbackType, final int preview) {
|
||||
List<String[]> list = new ArrayList<>();
|
||||
|
@ -1258,10 +1238,11 @@ public class Rollback extends Queue {
|
|||
if (preview == 0) {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
Location playerLocation = player.getLocation();
|
||||
String playerWorld = playerLocation.getWorld().getName();
|
||||
int chunkX = playerLocation.getBlockX() >> 4;
|
||||
int chunkZ = playerLocation.getBlockZ() >> 4;
|
||||
|
||||
if (chunkX == finalChunkX && chunkZ == finalChunkZ) {
|
||||
if (bukkitRollbackWorld.getName().equals(playerWorld) && chunkX == finalChunkX && chunkZ == finalChunkZ) {
|
||||
Teleport.performSafeTeleport(player, playerLocation, false);
|
||||
}
|
||||
}
|
||||
|
@ -1336,7 +1317,7 @@ public class Rollback extends Queue {
|
|||
double totalSeconds = (timeFinish - timeStart) / 1000.0;
|
||||
|
||||
if (user != null) {
|
||||
finishRollbackRestore(user, location, checkUsers, restrictList, excludeList, excludeUserList, actionList, timeString, chunkCount, totalSeconds, itemCount, blockCount, entityCount, rollbackType, radius, verbose, restrictWorld, preview);
|
||||
RollbackComplete.output(user, location, checkUsers, restrictList, excludeList, excludeUserList, actionList, timeString, chunkCount, totalSeconds, itemCount, blockCount, entityCount, rollbackType, radius, verbose, restrictWorld, preview);
|
||||
}
|
||||
|
||||
list = Lookup.convertRawLookup(statement, lookupList);
|
||||
|
@ -1349,733 +1330,4 @@ public class Rollback extends Queue {
|
|||
return null;
|
||||
}
|
||||
|
||||
static void finishRollbackRestore(CommandSender user, Location location, List<String> checkUsers, List<Object> restrictList, Map<Object, Boolean> excludeList, List<String> excludeUserList, List<Integer> actionList, String timeString, Integer chunkCount, Double seconds, Integer itemCount, Integer blockCount, Integer entityCount, int rollbackType, Integer[] radius, boolean verbose, boolean restrictWorld, int preview) {
|
||||
try {
|
||||
if (preview == 2) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PREVIEW_CANCELLED));
|
||||
return;
|
||||
}
|
||||
|
||||
Chat.sendMessage(user, "-----");
|
||||
|
||||
StringBuilder usersBuilder = new StringBuilder();
|
||||
for (String value : checkUsers) {
|
||||
if (usersBuilder.length() == 0) {
|
||||
usersBuilder = usersBuilder.append("" + value + "");
|
||||
}
|
||||
else {
|
||||
usersBuilder.append(", ").append(value);
|
||||
}
|
||||
}
|
||||
String users = usersBuilder.toString();
|
||||
|
||||
if (users.equals("#global") && restrictWorld) {
|
||||
users = "#" + location.getWorld().getName();
|
||||
}
|
||||
|
||||
if (preview > 0) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_COMPLETED, users, Selector.THIRD)); // preview
|
||||
}
|
||||
else if (rollbackType == 0) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_COMPLETED, users, Selector.FIRST)); // rollback
|
||||
}
|
||||
else if (rollbackType == 1) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_COMPLETED, users, Selector.SECOND)); // restore
|
||||
}
|
||||
|
||||
if (preview == 1 || rollbackType == 0 || rollbackType == 1) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_TIME, timeString));
|
||||
}
|
||||
|
||||
if (radius != null) {
|
||||
int worldedit = radius[7];
|
||||
if (worldedit == 0) {
|
||||
Integer rollbackRadius = radius[0];
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_RADIUS, rollbackRadius.toString(), (rollbackRadius == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
}
|
||||
else {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_SELECTION, "#worldedit"));
|
||||
}
|
||||
}
|
||||
|
||||
if (restrictWorld && radius == null) {
|
||||
if (location != null) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, location.getWorld().getName(), Selector.FIRST));
|
||||
}
|
||||
}
|
||||
|
||||
if (actionList.contains(4) && actionList.contains(11)) {
|
||||
if (actionList.contains(0)) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "+inventory", Selector.SECOND));
|
||||
}
|
||||
else if (actionList.contains(1)) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "-inventory", Selector.SECOND));
|
||||
}
|
||||
else {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "inventory", Selector.SECOND));
|
||||
}
|
||||
}
|
||||
else if (actionList.contains(4)) {
|
||||
if (actionList.contains(0)) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "-container", Selector.SECOND));
|
||||
}
|
||||
else if (actionList.contains(1)) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "+container", Selector.SECOND));
|
||||
}
|
||||
else {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "container", Selector.SECOND));
|
||||
}
|
||||
}
|
||||
else if (actionList.contains(0) && actionList.contains(1)) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "block", Selector.SECOND));
|
||||
}
|
||||
else if (actionList.contains(0)) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "-block", Selector.SECOND));
|
||||
}
|
||||
else if (actionList.contains(1)) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "+block", Selector.SECOND));
|
||||
}
|
||||
else if (actionList.contains(3)) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "kill", Selector.SECOND));
|
||||
}
|
||||
|
||||
if (restrictList.size() > 0) {
|
||||
StringBuilder restrictTargets = new StringBuilder();
|
||||
boolean material = false;
|
||||
boolean item = false;
|
||||
boolean entity = false;
|
||||
|
||||
int targetCount = 0;
|
||||
for (Object restrictTarget : restrictList) {
|
||||
String targetName = "";
|
||||
|
||||
if (restrictTarget instanceof Material) {
|
||||
targetName = ((Material) restrictTarget).name().toLowerCase(Locale.ROOT);
|
||||
item = (!item ? !(((Material) restrictTarget).isBlock()) : item);
|
||||
material = true;
|
||||
}
|
||||
else if (restrictTarget instanceof EntityType) {
|
||||
targetName = ((EntityType) restrictTarget).name().toLowerCase(Locale.ROOT);
|
||||
entity = true;
|
||||
}
|
||||
|
||||
if (targetCount == 0) {
|
||||
restrictTargets = restrictTargets.append("" + targetName + "");
|
||||
}
|
||||
else {
|
||||
restrictTargets.append(", ").append(targetName);
|
||||
}
|
||||
|
||||
targetCount++;
|
||||
}
|
||||
|
||||
String targetType = Selector.THIRD;
|
||||
if (material && !item && !entity) {
|
||||
targetType = Selector.FIRST;
|
||||
}
|
||||
else if (material && item && !entity) {
|
||||
targetType = Selector.THIRD;
|
||||
}
|
||||
else if (entity && !material) {
|
||||
targetType = Selector.SECOND;
|
||||
}
|
||||
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_INCLUDE, restrictTargets.toString(), Selector.FIRST, targetType, (targetCount == 1 ? Selector.FIRST : Selector.SECOND))); // include
|
||||
}
|
||||
|
||||
if (excludeList.size() > 0) {
|
||||
StringBuilder excludeTargets = new StringBuilder();
|
||||
boolean material = false;
|
||||
boolean item = false;
|
||||
boolean entity = false;
|
||||
|
||||
int excludeCount = 0;
|
||||
for (Map.Entry<Object, Boolean> entry : excludeList.entrySet()) {
|
||||
Object excludeTarget = entry.getKey();
|
||||
Boolean excludeTargetInternal = entry.getValue();
|
||||
|
||||
// don't display default block excludes
|
||||
if (Boolean.TRUE.equals(excludeTargetInternal)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't display that excluded water/fire/farmland in inventory rollbacks
|
||||
if (actionList.contains(4) && actionList.contains(11)) {
|
||||
if (excludeTarget.equals(Material.FIRE) || excludeTarget.equals(Material.WATER) || excludeTarget.equals(Material.FARMLAND)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
String targetName = "";
|
||||
if (excludeTarget instanceof Material) {
|
||||
targetName = ((Material) excludeTarget).name().toLowerCase(Locale.ROOT);
|
||||
item = (!item ? !(((Material) excludeTarget).isBlock()) : item);
|
||||
material = true;
|
||||
}
|
||||
else if (excludeTarget instanceof EntityType) {
|
||||
targetName = ((EntityType) excludeTarget).name().toLowerCase(Locale.ROOT);
|
||||
entity = true;
|
||||
}
|
||||
|
||||
if (excludeCount == 0) {
|
||||
excludeTargets = excludeTargets.append("" + targetName + "");
|
||||
}
|
||||
else {
|
||||
excludeTargets.append(", ").append(targetName);
|
||||
}
|
||||
|
||||
excludeCount++;
|
||||
}
|
||||
|
||||
String targetType = Selector.THIRD;
|
||||
if (material && !item && !entity) {
|
||||
targetType = Selector.FIRST;
|
||||
}
|
||||
else if (material && item && !entity) {
|
||||
targetType = Selector.THIRD;
|
||||
}
|
||||
else if (entity && !material) {
|
||||
targetType = Selector.SECOND;
|
||||
}
|
||||
|
||||
if (excludeCount > 0) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_INCLUDE, excludeTargets.toString(), Selector.SECOND, targetType, (excludeCount == 1 ? Selector.FIRST : Selector.SECOND))); // exclude
|
||||
}
|
||||
}
|
||||
|
||||
if (excludeUserList.size() > 0) {
|
||||
StringBuilder excludeUsers = new StringBuilder();
|
||||
|
||||
int excludeCount = 0;
|
||||
for (String excludeUser : excludeUserList) {
|
||||
// don't display that excluded #hopper in inventory rollbacks
|
||||
if (actionList.contains(4) && actionList.contains(11)) {
|
||||
if (excludeUser.equals("#hopper")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (excludeCount == 0) {
|
||||
excludeUsers = excludeUsers.append("" + excludeUser + "");
|
||||
}
|
||||
else {
|
||||
excludeUsers.append(", ").append(excludeUser);
|
||||
}
|
||||
|
||||
excludeCount++;
|
||||
}
|
||||
|
||||
if (excludeCount > 0) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_EXCLUDED_USERS, excludeUsers.toString(), (excludeCount == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder modifiedData = new StringBuilder();
|
||||
Integer modifyCount = 0;
|
||||
if (actionList.contains(5)) {
|
||||
modifiedData = modifiedData.append(Phrase.build(Phrase.AMOUNT_ITEM, NumberFormat.getInstance().format(blockCount), (blockCount == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
modifyCount++;
|
||||
}
|
||||
else {
|
||||
if (itemCount > 0 || actionList.contains(4)) {
|
||||
modifiedData = modifiedData.append(Phrase.build(Phrase.AMOUNT_ITEM, NumberFormat.getInstance().format(itemCount), (itemCount == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
modifyCount++;
|
||||
}
|
||||
|
||||
if (entityCount > 0) {
|
||||
if (modifyCount > 0) {
|
||||
modifiedData.append(", ");
|
||||
}
|
||||
modifiedData.append(Phrase.build(Phrase.AMOUNT_ENTITY, NumberFormat.getInstance().format(entityCount), (entityCount == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
modifyCount++;
|
||||
}
|
||||
|
||||
if (blockCount > 0 || !actionList.contains(4) || preview > 0) {
|
||||
if (modifyCount > 0) {
|
||||
modifiedData.append(", ");
|
||||
}
|
||||
modifiedData.append(Phrase.build(Phrase.AMOUNT_BLOCK, NumberFormat.getInstance().format(blockCount), (blockCount == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
modifyCount++;
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder modifiedDataVerbose = new StringBuilder();
|
||||
if (verbose && preview == 0 && !actionList.contains(11)) {
|
||||
if (chunkCount > -1 && modifyCount < 3) {
|
||||
if (modifyCount > 0) {
|
||||
modifiedData.append(", ");
|
||||
}
|
||||
modifiedData.append(Phrase.build(Phrase.AMOUNT_CHUNK, NumberFormat.getInstance().format(chunkCount), (chunkCount == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
modifyCount++;
|
||||
}
|
||||
else if (chunkCount > 1) {
|
||||
modifiedDataVerbose.append(Phrase.build(Phrase.AMOUNT_CHUNK, NumberFormat.getInstance().format(chunkCount), (chunkCount == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
}
|
||||
}
|
||||
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_MODIFIED, modifiedData.toString(), (preview == 0 ? Selector.FIRST : Selector.SECOND)));
|
||||
if (modifiedDataVerbose.length() > 0) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_MODIFIED, modifiedDataVerbose.toString(), (preview == 0 ? Selector.FIRST : Selector.SECOND)));
|
||||
}
|
||||
|
||||
if (preview == 0) {
|
||||
BigDecimal decimalSeconds = new BigDecimal(seconds).setScale(1, RoundingMode.HALF_EVEN);
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_LENGTH, decimalSeconds.stripTrailingZeros().toPlainString(), (decimalSeconds.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
}
|
||||
|
||||
Chat.sendMessage(user, "-----");
|
||||
if (preview > 0) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PLEASE_SELECT, "/co apply", "/co cancel"));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
static int modifyContainerItems(Material type, Object container, int slot, ItemStack itemstack, int action) {
|
||||
int modifiedArmor = -1;
|
||||
try {
|
||||
ItemStack[] contents = null;
|
||||
|
||||
if (type != null && type.equals(Material.ARMOR_STAND)) {
|
||||
EntityEquipment equipment = (EntityEquipment) container;
|
||||
if (equipment != null) {
|
||||
if (action == 1) {
|
||||
itemstack.setAmount(1);
|
||||
}
|
||||
else {
|
||||
itemstack.setType(Material.AIR);
|
||||
itemstack.setAmount(0);
|
||||
}
|
||||
|
||||
if (slot < 4) {
|
||||
contents = equipment.getArmorContents();
|
||||
if (slot >= 0) {
|
||||
contents[slot] = itemstack;
|
||||
}
|
||||
equipment.setArmorContents(contents);
|
||||
}
|
||||
else {
|
||||
ArmorStand armorStand = (ArmorStand) equipment.getHolder();
|
||||
armorStand.setArms(true);
|
||||
switch (slot) {
|
||||
case 4:
|
||||
equipment.setItemInMainHand(itemstack);
|
||||
break;
|
||||
case 5:
|
||||
equipment.setItemInOffHand(itemstack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type != null && type.equals(Material.ITEM_FRAME)) {
|
||||
ItemFrame frame = (ItemFrame) container;
|
||||
if (frame != null) {
|
||||
if (action == 1) {
|
||||
itemstack.setAmount(1);
|
||||
}
|
||||
else {
|
||||
itemstack.setType(Material.AIR);
|
||||
itemstack.setAmount(0);
|
||||
}
|
||||
|
||||
frame.setItem(itemstack);
|
||||
}
|
||||
}
|
||||
else if (type != null && type.equals(Material.JUKEBOX)) {
|
||||
Jukebox jukebox = (Jukebox) container;
|
||||
if (jukebox != null) {
|
||||
if (action == 1 && Tag.ITEMS_MUSIC_DISCS.isTagged(itemstack.getType())) {
|
||||
itemstack.setAmount(1);
|
||||
}
|
||||
else {
|
||||
itemstack.setType(Material.AIR);
|
||||
itemstack.setAmount(0);
|
||||
}
|
||||
|
||||
jukebox.setRecord(itemstack);
|
||||
jukebox.update();
|
||||
}
|
||||
}
|
||||
else {
|
||||
Inventory inventory = (Inventory) container;
|
||||
if (inventory != null) {
|
||||
boolean isPlayerInventory = (inventory instanceof PlayerInventory);
|
||||
if (action == 1) {
|
||||
int count = 0;
|
||||
int amount = itemstack.getAmount();
|
||||
itemstack.setAmount(1);
|
||||
|
||||
while (count < amount) {
|
||||
boolean addedItem = false;
|
||||
if (isPlayerInventory) {
|
||||
int setArmor = Util.setPlayerArmor((PlayerInventory) inventory, itemstack);
|
||||
addedItem = (setArmor > -1);
|
||||
modifiedArmor = addedItem ? setArmor : modifiedArmor;
|
||||
}
|
||||
if (!addedItem) {
|
||||
if (BukkitAdapter.ADAPTER.isChiseledBookshelf(type)) {
|
||||
ItemStack[] inventoryContents = inventory.getStorageContents();
|
||||
int i = 0;
|
||||
for (ItemStack stack : inventoryContents) {
|
||||
if (stack == null) {
|
||||
inventoryContents[i] = itemstack;
|
||||
addedItem = true;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (addedItem) {
|
||||
inventory.setStorageContents(inventoryContents);
|
||||
}
|
||||
else {
|
||||
addedItem = (inventory.addItem(itemstack).size() == 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
addedItem = (inventory.addItem(itemstack).size() == 0);
|
||||
}
|
||||
}
|
||||
if (!addedItem && isPlayerInventory) {
|
||||
PlayerInventory playerInventory = (PlayerInventory) inventory;
|
||||
ItemStack offhand = playerInventory.getItemInOffHand();
|
||||
if (offhand == null || offhand.getType() == Material.AIR || (itemstack.isSimilar(offhand) && offhand.getAmount() < offhand.getMaxStackSize())) {
|
||||
ItemStack setOffhand = itemstack.clone();
|
||||
if (itemstack.isSimilar(offhand)) {
|
||||
setOffhand.setAmount(offhand.getAmount() + 1);
|
||||
}
|
||||
|
||||
playerInventory.setItemInOffHand(setOffhand);
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int removeAmount = itemstack.getAmount();
|
||||
ItemStack removeMatch = itemstack.clone();
|
||||
removeMatch.setAmount(1);
|
||||
|
||||
ItemStack[] inventoryContents = (isPlayerInventory ? inventory.getContents() : inventory.getStorageContents()).clone();
|
||||
for (int i = inventoryContents.length - 1; i >= 0; i--) {
|
||||
if (inventoryContents[i] != null) {
|
||||
ItemStack itemStack = inventoryContents[i].clone();
|
||||
int maxAmount = itemStack.getAmount();
|
||||
int currentAmount = maxAmount;
|
||||
itemStack.setAmount(1);
|
||||
|
||||
if (itemStack.toString().equals(removeMatch.toString())) {
|
||||
for (int scan = 0; scan < maxAmount; scan++) {
|
||||
if (removeAmount > 0) {
|
||||
currentAmount--;
|
||||
itemStack.setAmount(currentAmount);
|
||||
removeAmount--;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
itemStack.setAmount(maxAmount);
|
||||
}
|
||||
|
||||
if (itemStack.getAmount() == 0) {
|
||||
inventoryContents[i] = null;
|
||||
}
|
||||
else {
|
||||
inventoryContents[i] = itemStack;
|
||||
}
|
||||
}
|
||||
|
||||
if (removeAmount == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isPlayerInventory) {
|
||||
inventory.setContents(inventoryContents);
|
||||
}
|
||||
else {
|
||||
inventory.setStorageContents(inventoryContents);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
while (count < removeAmount) {
|
||||
inventory.removeItem(removeMatch);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return modifiedArmor;
|
||||
}
|
||||
|
||||
public static void sortContainerItems(PlayerInventory inventory, List<Integer> modifiedArmorSlots) {
|
||||
try {
|
||||
ItemStack[] armorContents = inventory.getArmorContents();
|
||||
ItemStack[] storageContents = inventory.getStorageContents();
|
||||
|
||||
for (int armor = 0; armor < armorContents.length; armor++) {
|
||||
ItemStack armorItem = armorContents[armor];
|
||||
if (armorItem == null || !modifiedArmorSlots.contains(armor)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int storage = 0; storage < storageContents.length; storage++) {
|
||||
ItemStack storageItem = storageContents[storage];
|
||||
if (storageItem == null) {
|
||||
storageContents[storage] = armorItem;
|
||||
armorContents[armor] = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inventory.setArmorContents(armorContents);
|
||||
inventory.setStorageContents(storageContents);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void buildFireworkEffect(Builder effectBuilder, Material rowType, ItemStack itemstack) {
|
||||
try {
|
||||
FireworkEffect effect = effectBuilder.build();
|
||||
if ((rowType == Material.FIREWORK_ROCKET)) {
|
||||
FireworkMeta meta = (FireworkMeta) itemstack.getItemMeta();
|
||||
meta.addEffect(effect);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
else if ((rowType == Material.FIREWORK_STAR)) {
|
||||
FireworkEffectMeta meta = (FireworkEffectMeta) itemstack.getItemMeta();
|
||||
meta.setEffect(effect);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Object[] populateItemStack(ItemStack itemstack, Object list) {
|
||||
int slot = 0;
|
||||
String faceData = "";
|
||||
|
||||
try {
|
||||
/*
|
||||
if (list instanceof Object[]) {
|
||||
slot = (int) ((Object[]) list)[0];
|
||||
ItemMeta itemMeta = (ItemMeta) ((Object[]) list)[1];
|
||||
itemstack.setItemMeta(itemMeta);
|
||||
return new Object[] { slot, itemstack };
|
||||
}
|
||||
*/
|
||||
|
||||
Material rowType = itemstack.getType();
|
||||
List<Object> metaList = (List<Object>) list;
|
||||
if (metaList.size() > 0 && !(metaList.get(0) instanceof List<?>)) {
|
||||
if (rowType.name().endsWith("_BANNER")) {
|
||||
BannerMeta meta = (BannerMeta) itemstack.getItemMeta();
|
||||
for (Object value : metaList) {
|
||||
if (value instanceof Map) {
|
||||
Pattern pattern = new Pattern((Map<String, Object>) value);
|
||||
meta.addPattern(pattern);
|
||||
}
|
||||
}
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
else if (BlockGroup.SHULKER_BOXES.contains(rowType)) {
|
||||
BlockStateMeta meta = (BlockStateMeta) itemstack.getItemMeta();
|
||||
ShulkerBox shulkerBox = (ShulkerBox) meta.getBlockState();
|
||||
for (Object value : metaList) {
|
||||
ItemStack item = Util.unserializeItemStackLegacy(value);
|
||||
if (item != null) {
|
||||
shulkerBox.getInventory().addItem(item);
|
||||
}
|
||||
}
|
||||
meta.setBlockState(shulkerBox);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return new Object[] { slot, faceData, itemstack };
|
||||
}
|
||||
|
||||
int itemCount = 0;
|
||||
Builder effectBuilder = FireworkEffect.builder();
|
||||
for (List<Map<String, Object>> map : (List<List<Map<String, Object>>>) list) {
|
||||
if (map.size() == 0) {
|
||||
if (itemCount == 3 && (rowType == Material.FIREWORK_ROCKET || rowType == Material.FIREWORK_STAR)) {
|
||||
buildFireworkEffect(effectBuilder, rowType, itemstack);
|
||||
itemCount = 0;
|
||||
}
|
||||
|
||||
itemCount++;
|
||||
continue;
|
||||
}
|
||||
Map<String, Object> mapData = map.get(0);
|
||||
|
||||
if (mapData.get("slot") != null) {
|
||||
slot = (Integer) mapData.get("slot");
|
||||
}
|
||||
else if (mapData.get("facing") != null) {
|
||||
faceData = (String) mapData.get("facing");
|
||||
}
|
||||
else if (mapData.get("modifiers") != null) {
|
||||
ItemMeta itemMeta = itemstack.getItemMeta();
|
||||
if (itemMeta.hasAttributeModifiers()) {
|
||||
for (Map.Entry<Attribute, AttributeModifier> entry : itemMeta.getAttributeModifiers().entries()) {
|
||||
itemMeta.removeAttributeModifier(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
List<Object> modifiers = (List<Object>) mapData.get("modifiers");
|
||||
|
||||
for (Object item : modifiers) {
|
||||
Map<Attribute, Map<String, Object>> modifiersMap = (Map<Attribute, Map<String, Object>>) item;
|
||||
for (Map.Entry<Attribute, Map<String, Object>> entry : modifiersMap.entrySet()) {
|
||||
try {
|
||||
Attribute attribute = entry.getKey();
|
||||
AttributeModifier modifier = AttributeModifier.deserialize(entry.getValue());
|
||||
itemMeta.addAttributeModifier(attribute, modifier);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// AttributeModifier already exists
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
itemstack.setItemMeta(itemMeta);
|
||||
}
|
||||
else if (itemCount == 0) {
|
||||
ItemMeta meta = Util.deserializeItemMeta(itemstack.getItemMeta().getClass(), map.get(0));
|
||||
itemstack.setItemMeta(meta);
|
||||
|
||||
if (map.size() > 1 && (rowType == Material.POTION)) {
|
||||
PotionMeta subMeta = (PotionMeta) itemstack.getItemMeta();
|
||||
org.bukkit.Color color = org.bukkit.Color.deserialize(map.get(1));
|
||||
subMeta.setColor(color);
|
||||
itemstack.setItemMeta(subMeta);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((rowType == Material.LEATHER_HORSE_ARMOR) || (rowType == Material.LEATHER_HELMET) || (rowType == Material.LEATHER_CHESTPLATE) || (rowType == Material.LEATHER_LEGGINGS) || (rowType == Material.LEATHER_BOOTS)) { // leather armor
|
||||
for (Map<String, Object> colorData : map) {
|
||||
LeatherArmorMeta meta = (LeatherArmorMeta) itemstack.getItemMeta();
|
||||
org.bukkit.Color color = org.bukkit.Color.deserialize(colorData);
|
||||
meta.setColor(color);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
else if ((rowType == Material.POTION)) { // potion
|
||||
for (Map<String, Object> potionData : map) {
|
||||
PotionMeta meta = (PotionMeta) itemstack.getItemMeta();
|
||||
PotionEffect effect = new PotionEffect(potionData);
|
||||
meta.addCustomEffect(effect, true);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
else if (rowType.name().endsWith("_BANNER")) {
|
||||
for (Map<String, Object> patternData : map) {
|
||||
BannerMeta meta = (BannerMeta) itemstack.getItemMeta();
|
||||
Pattern pattern = new Pattern(patternData);
|
||||
meta.addPattern(pattern);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
else if ((rowType == Material.CROSSBOW)) {
|
||||
CrossbowMeta meta = (CrossbowMeta) itemstack.getItemMeta();
|
||||
for (Map<String, Object> itemData : map) {
|
||||
ItemStack crossbowItem = Util.unserializeItemStack(itemData);
|
||||
if (crossbowItem != null) {
|
||||
meta.addChargedProjectile(crossbowItem);
|
||||
}
|
||||
}
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
else if (rowType == Material.MAP || rowType == Material.FILLED_MAP) {
|
||||
for (Map<String, Object> colorData : map) {
|
||||
MapMeta meta = (MapMeta) itemstack.getItemMeta();
|
||||
org.bukkit.Color color = org.bukkit.Color.deserialize(colorData);
|
||||
meta.setColor(color);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
else if ((rowType == Material.FIREWORK_ROCKET) || (rowType == Material.FIREWORK_STAR)) {
|
||||
if (itemCount == 1) {
|
||||
effectBuilder = FireworkEffect.builder();
|
||||
for (Map<String, Object> fireworkData : map) {
|
||||
org.bukkit.FireworkEffect.Type type = (org.bukkit.FireworkEffect.Type) fireworkData.getOrDefault("type", org.bukkit.FireworkEffect.Type.BALL);
|
||||
boolean hasFlicker = (Boolean) fireworkData.get("flicker");
|
||||
boolean hasTrail = (Boolean) fireworkData.get("trail");
|
||||
effectBuilder.with(type);
|
||||
effectBuilder.flicker(hasFlicker);
|
||||
effectBuilder.trail(hasTrail);
|
||||
}
|
||||
}
|
||||
else if (itemCount == 2) {
|
||||
for (Map<String, Object> colorData : map) {
|
||||
org.bukkit.Color color = org.bukkit.Color.deserialize(colorData);
|
||||
effectBuilder.withColor(color);
|
||||
}
|
||||
}
|
||||
else if (itemCount == 3) {
|
||||
for (Map<String, Object> colorData : map) {
|
||||
org.bukkit.Color color = org.bukkit.Color.deserialize(colorData);
|
||||
effectBuilder.withFade(color);
|
||||
}
|
||||
buildFireworkEffect(effectBuilder, rowType, itemstack);
|
||||
itemCount = 0;
|
||||
}
|
||||
}
|
||||
else if ((rowType == Material.SUSPICIOUS_STEW)) {
|
||||
for (Map<String, Object> suspiciousStewData : map) {
|
||||
SuspiciousStewMeta meta = (SuspiciousStewMeta) itemstack.getItemMeta();
|
||||
PotionEffect effect = new PotionEffect(suspiciousStewData);
|
||||
meta.addCustomEffect(effect, true);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BukkitAdapter.ADAPTER.setItemMeta(rowType, itemstack, map);
|
||||
}
|
||||
}
|
||||
|
||||
itemCount++;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new Object[] { slot, faceData, itemstack };
|
||||
}
|
||||
|
||||
public static Object[] populateItemStack(ItemStack itemstack, byte[] metadata) {
|
||||
if (metadata != null) {
|
||||
try {
|
||||
ByteArrayInputStream metaByteStream = new ByteArrayInputStream(metadata);
|
||||
BukkitObjectInputStream metaObjectStream = new BukkitObjectInputStream(metaByteStream);
|
||||
Object metaList = metaObjectStream.readObject();
|
||||
metaObjectStream.close();
|
||||
metaByteStream.close();
|
||||
|
||||
return populateItemStack(itemstack, metaList);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return new Object[] { 0, "", itemstack };
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,306 @@
|
|||
package net.coreprotect.database.rollback;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.language.Selector;
|
||||
import net.coreprotect.utility.Chat;
|
||||
import net.coreprotect.utility.Color;
|
||||
|
||||
public class RollbackComplete {
|
||||
|
||||
public static void output(CommandSender user, Location location, List<String> checkUsers, List<Object> restrictList, Map<Object, Boolean> excludeList, List<String> excludeUserList, List<Integer> actionList, String timeString, Integer chunkCount, Double seconds, Integer itemCount, Integer blockCount, Integer entityCount, int rollbackType, Integer[] radius, boolean verbose, boolean restrictWorld, int preview) {
|
||||
try {
|
||||
if (preview == 2) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PREVIEW_CANCELLED));
|
||||
return;
|
||||
}
|
||||
|
||||
Chat.sendMessage(user, "-----");
|
||||
|
||||
StringBuilder usersBuilder = new StringBuilder();
|
||||
for (String value : checkUsers) {
|
||||
if (usersBuilder.length() == 0) {
|
||||
usersBuilder = usersBuilder.append("" + value + "");
|
||||
}
|
||||
else {
|
||||
usersBuilder.append(", ").append(value);
|
||||
}
|
||||
}
|
||||
String users = usersBuilder.toString();
|
||||
|
||||
if (users.equals("#global") && restrictWorld) {
|
||||
users = "#" + location.getWorld().getName();
|
||||
}
|
||||
|
||||
if (preview > 0) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_COMPLETED, users, Selector.THIRD)); // preview
|
||||
}
|
||||
else if (rollbackType == 0) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_COMPLETED, users, Selector.FIRST)); // rollback
|
||||
}
|
||||
else if (rollbackType == 1) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_COMPLETED, users, Selector.SECOND)); // restore
|
||||
}
|
||||
|
||||
if (preview == 1 || rollbackType == 0 || rollbackType == 1) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_TIME, timeString));
|
||||
}
|
||||
|
||||
if (radius != null) {
|
||||
int worldedit = radius[7];
|
||||
if (worldedit == 0) {
|
||||
Integer rollbackRadius = radius[0];
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_RADIUS, rollbackRadius.toString(), (rollbackRadius == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
}
|
||||
else {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_SELECTION, "#worldedit"));
|
||||
}
|
||||
}
|
||||
|
||||
if (restrictWorld && radius == null) {
|
||||
if (location != null) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, location.getWorld().getName(), Selector.FIRST));
|
||||
}
|
||||
}
|
||||
|
||||
if (actionList.contains(4) && actionList.contains(11)) {
|
||||
if (actionList.contains(0)) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "+inventory", Selector.SECOND));
|
||||
}
|
||||
else if (actionList.contains(1)) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "-inventory", Selector.SECOND));
|
||||
}
|
||||
else {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "inventory", Selector.SECOND));
|
||||
}
|
||||
}
|
||||
else if (actionList.contains(4)) {
|
||||
if (actionList.contains(0)) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "-container", Selector.SECOND));
|
||||
}
|
||||
else if (actionList.contains(1)) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "+container", Selector.SECOND));
|
||||
}
|
||||
else {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "container", Selector.SECOND));
|
||||
}
|
||||
}
|
||||
else if (actionList.contains(0) && actionList.contains(1)) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "block", Selector.SECOND));
|
||||
}
|
||||
else if (actionList.contains(0)) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "-block", Selector.SECOND));
|
||||
}
|
||||
else if (actionList.contains(1)) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "+block", Selector.SECOND));
|
||||
}
|
||||
else if (actionList.contains(3)) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_WORLD_ACTION, "kill", Selector.SECOND));
|
||||
}
|
||||
|
||||
if (restrictList.size() > 0) {
|
||||
StringBuilder restrictTargets = new StringBuilder();
|
||||
boolean material = false;
|
||||
boolean item = false;
|
||||
boolean entity = false;
|
||||
|
||||
int targetCount = 0;
|
||||
for (Object restrictTarget : restrictList) {
|
||||
String targetName = "";
|
||||
|
||||
if (restrictTarget instanceof Material) {
|
||||
targetName = ((Material) restrictTarget).name().toLowerCase(Locale.ROOT);
|
||||
item = (!item ? !(((Material) restrictTarget).isBlock()) : item);
|
||||
material = true;
|
||||
}
|
||||
else if (restrictTarget instanceof EntityType) {
|
||||
targetName = ((EntityType) restrictTarget).name().toLowerCase(Locale.ROOT);
|
||||
entity = true;
|
||||
}
|
||||
|
||||
if (targetCount == 0) {
|
||||
restrictTargets = restrictTargets.append("" + targetName + "");
|
||||
}
|
||||
else {
|
||||
restrictTargets.append(", ").append(targetName);
|
||||
}
|
||||
|
||||
targetCount++;
|
||||
}
|
||||
|
||||
String targetType = Selector.THIRD;
|
||||
if (material && !item && !entity) {
|
||||
targetType = Selector.FIRST;
|
||||
}
|
||||
else if (material && item && !entity) {
|
||||
targetType = Selector.THIRD;
|
||||
}
|
||||
else if (entity && !material) {
|
||||
targetType = Selector.SECOND;
|
||||
}
|
||||
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_INCLUDE, restrictTargets.toString(), Selector.FIRST, targetType, (targetCount == 1 ? Selector.FIRST : Selector.SECOND))); // include
|
||||
}
|
||||
|
||||
if (excludeList.size() > 0) {
|
||||
StringBuilder excludeTargets = new StringBuilder();
|
||||
boolean material = false;
|
||||
boolean item = false;
|
||||
boolean entity = false;
|
||||
|
||||
int excludeCount = 0;
|
||||
for (Map.Entry<Object, Boolean> entry : excludeList.entrySet()) {
|
||||
Object excludeTarget = entry.getKey();
|
||||
Boolean excludeTargetInternal = entry.getValue();
|
||||
|
||||
// don't display default block excludes
|
||||
if (Boolean.TRUE.equals(excludeTargetInternal)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't display that excluded water/fire/farmland in inventory rollbacks
|
||||
if (actionList.contains(4) && actionList.contains(11)) {
|
||||
if (excludeTarget.equals(Material.FIRE) || excludeTarget.equals(Material.WATER) || excludeTarget.equals(Material.FARMLAND)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
String targetName = "";
|
||||
if (excludeTarget instanceof Material) {
|
||||
targetName = ((Material) excludeTarget).name().toLowerCase(Locale.ROOT);
|
||||
item = (!item ? !(((Material) excludeTarget).isBlock()) : item);
|
||||
material = true;
|
||||
}
|
||||
else if (excludeTarget instanceof EntityType) {
|
||||
targetName = ((EntityType) excludeTarget).name().toLowerCase(Locale.ROOT);
|
||||
entity = true;
|
||||
}
|
||||
|
||||
if (excludeCount == 0) {
|
||||
excludeTargets = excludeTargets.append("" + targetName + "");
|
||||
}
|
||||
else {
|
||||
excludeTargets.append(", ").append(targetName);
|
||||
}
|
||||
|
||||
excludeCount++;
|
||||
}
|
||||
|
||||
String targetType = Selector.THIRD;
|
||||
if (material && !item && !entity) {
|
||||
targetType = Selector.FIRST;
|
||||
}
|
||||
else if (material && item && !entity) {
|
||||
targetType = Selector.THIRD;
|
||||
}
|
||||
else if (entity && !material) {
|
||||
targetType = Selector.SECOND;
|
||||
}
|
||||
|
||||
if (excludeCount > 0) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_INCLUDE, excludeTargets.toString(), Selector.SECOND, targetType, (excludeCount == 1 ? Selector.FIRST : Selector.SECOND))); // exclude
|
||||
}
|
||||
}
|
||||
|
||||
if (excludeUserList.size() > 0) {
|
||||
StringBuilder excludeUsers = new StringBuilder();
|
||||
|
||||
int excludeCount = 0;
|
||||
for (String excludeUser : excludeUserList) {
|
||||
// don't display that excluded #hopper in inventory rollbacks
|
||||
if (actionList.contains(4) && actionList.contains(11)) {
|
||||
if (excludeUser.equals("#hopper")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (excludeCount == 0) {
|
||||
excludeUsers = excludeUsers.append("" + excludeUser + "");
|
||||
}
|
||||
else {
|
||||
excludeUsers.append(", ").append(excludeUser);
|
||||
}
|
||||
|
||||
excludeCount++;
|
||||
}
|
||||
|
||||
if (excludeCount > 0) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_EXCLUDED_USERS, excludeUsers.toString(), (excludeCount == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder modifiedData = new StringBuilder();
|
||||
Integer modifyCount = 0;
|
||||
if (actionList.contains(5)) {
|
||||
modifiedData = modifiedData.append(Phrase.build(Phrase.AMOUNT_ITEM, NumberFormat.getInstance().format(blockCount), (blockCount == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
modifyCount++;
|
||||
}
|
||||
else {
|
||||
if (itemCount > 0 || actionList.contains(4)) {
|
||||
modifiedData = modifiedData.append(Phrase.build(Phrase.AMOUNT_ITEM, NumberFormat.getInstance().format(itemCount), (itemCount == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
modifyCount++;
|
||||
}
|
||||
|
||||
if (entityCount > 0) {
|
||||
if (modifyCount > 0) {
|
||||
modifiedData.append(", ");
|
||||
}
|
||||
modifiedData.append(Phrase.build(Phrase.AMOUNT_ENTITY, NumberFormat.getInstance().format(entityCount), (entityCount == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
modifyCount++;
|
||||
}
|
||||
|
||||
if (blockCount > 0 || !actionList.contains(4) || preview > 0) {
|
||||
if (modifyCount > 0) {
|
||||
modifiedData.append(", ");
|
||||
}
|
||||
modifiedData.append(Phrase.build(Phrase.AMOUNT_BLOCK, NumberFormat.getInstance().format(blockCount), (blockCount == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
modifyCount++;
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder modifiedDataVerbose = new StringBuilder();
|
||||
if (verbose && preview == 0 && !actionList.contains(11)) {
|
||||
if (chunkCount > -1 && modifyCount < 3) {
|
||||
if (modifyCount > 0) {
|
||||
modifiedData.append(", ");
|
||||
}
|
||||
modifiedData.append(Phrase.build(Phrase.AMOUNT_CHUNK, NumberFormat.getInstance().format(chunkCount), (chunkCount == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
modifyCount++;
|
||||
}
|
||||
else if (chunkCount > 1) {
|
||||
modifiedDataVerbose.append(Phrase.build(Phrase.AMOUNT_CHUNK, NumberFormat.getInstance().format(chunkCount), (chunkCount == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
}
|
||||
}
|
||||
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_MODIFIED, modifiedData.toString(), (preview == 0 ? Selector.FIRST : Selector.SECOND)));
|
||||
if (modifiedDataVerbose.length() > 0) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_MODIFIED, modifiedDataVerbose.toString(), (preview == 0 ? Selector.FIRST : Selector.SECOND)));
|
||||
}
|
||||
|
||||
if (preview == 0) {
|
||||
BigDecimal decimalSeconds = new BigDecimal(seconds).setScale(1, RoundingMode.HALF_EVEN);
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ROLLBACK_LENGTH, decimalSeconds.stripTrailingZeros().toPlainString(), (decimalSeconds.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
}
|
||||
|
||||
Chat.sendMessage(user, "-----");
|
||||
if (preview > 0) {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PLEASE_SELECT, "/co apply", "/co cancel"));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,487 @@
|
|||
package net.coreprotect.database.rollback;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.FireworkEffect;
|
||||
import org.bukkit.FireworkEffect.Builder;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.attribute.AttributeModifier;
|
||||
import org.bukkit.block.Jukebox;
|
||||
import org.bukkit.block.ShulkerBox;
|
||||
import org.bukkit.block.banner.Pattern;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.inventory.meta.BannerMeta;
|
||||
import org.bukkit.inventory.meta.BlockStateMeta;
|
||||
import org.bukkit.inventory.meta.CrossbowMeta;
|
||||
import org.bukkit.inventory.meta.FireworkEffectMeta;
|
||||
import org.bukkit.inventory.meta.FireworkMeta;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.LeatherArmorMeta;
|
||||
import org.bukkit.inventory.meta.MapMeta;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.inventory.meta.SuspiciousStewMeta;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.util.io.BukkitObjectInputStream;
|
||||
|
||||
import net.coreprotect.bukkit.BukkitAdapter;
|
||||
import net.coreprotect.database.Lookup;
|
||||
import net.coreprotect.model.BlockGroup;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class RollbackUtil extends Lookup {
|
||||
|
||||
protected static int modifyContainerItems(Material type, Object container, int slot, ItemStack itemstack, int action) {
|
||||
int modifiedArmor = -1;
|
||||
try {
|
||||
ItemStack[] contents = null;
|
||||
|
||||
if (type != null && type.equals(Material.ARMOR_STAND)) {
|
||||
EntityEquipment equipment = (EntityEquipment) container;
|
||||
if (equipment != null) {
|
||||
if (action == 1) {
|
||||
itemstack.setAmount(1);
|
||||
}
|
||||
else {
|
||||
itemstack.setType(Material.AIR);
|
||||
itemstack.setAmount(0);
|
||||
}
|
||||
|
||||
if (slot < 4) {
|
||||
contents = equipment.getArmorContents();
|
||||
if (slot >= 0) {
|
||||
contents[slot] = itemstack;
|
||||
}
|
||||
equipment.setArmorContents(contents);
|
||||
}
|
||||
else {
|
||||
ArmorStand armorStand = (ArmorStand) equipment.getHolder();
|
||||
armorStand.setArms(true);
|
||||
switch (slot) {
|
||||
case 4:
|
||||
equipment.setItemInMainHand(itemstack);
|
||||
break;
|
||||
case 5:
|
||||
equipment.setItemInOffHand(itemstack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type != null && type.equals(Material.ITEM_FRAME)) {
|
||||
ItemFrame frame = (ItemFrame) container;
|
||||
if (frame != null) {
|
||||
if (action == 1) {
|
||||
itemstack.setAmount(1);
|
||||
}
|
||||
else {
|
||||
itemstack.setType(Material.AIR);
|
||||
itemstack.setAmount(0);
|
||||
}
|
||||
|
||||
frame.setItem(itemstack);
|
||||
}
|
||||
}
|
||||
else if (type != null && type.equals(Material.JUKEBOX)) {
|
||||
Jukebox jukebox = (Jukebox) container;
|
||||
if (jukebox != null) {
|
||||
if (action == 1 && Tag.ITEMS_MUSIC_DISCS.isTagged(itemstack.getType())) {
|
||||
itemstack.setAmount(1);
|
||||
}
|
||||
else {
|
||||
itemstack.setType(Material.AIR);
|
||||
itemstack.setAmount(0);
|
||||
}
|
||||
|
||||
jukebox.setRecord(itemstack);
|
||||
jukebox.update();
|
||||
}
|
||||
}
|
||||
else {
|
||||
Inventory inventory = (Inventory) container;
|
||||
if (inventory != null) {
|
||||
boolean isPlayerInventory = (inventory instanceof PlayerInventory);
|
||||
if (action == 1) {
|
||||
int count = 0;
|
||||
int amount = itemstack.getAmount();
|
||||
itemstack.setAmount(1);
|
||||
|
||||
while (count < amount) {
|
||||
boolean addedItem = false;
|
||||
if (isPlayerInventory) {
|
||||
int setArmor = Util.setPlayerArmor((PlayerInventory) inventory, itemstack);
|
||||
addedItem = (setArmor > -1);
|
||||
modifiedArmor = addedItem ? setArmor : modifiedArmor;
|
||||
}
|
||||
if (!addedItem) {
|
||||
if (BukkitAdapter.ADAPTER.isChiseledBookshelf(type)) {
|
||||
ItemStack[] inventoryContents = inventory.getStorageContents();
|
||||
int i = 0;
|
||||
for (ItemStack stack : inventoryContents) {
|
||||
if (stack == null) {
|
||||
inventoryContents[i] = itemstack;
|
||||
addedItem = true;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (addedItem) {
|
||||
inventory.setStorageContents(inventoryContents);
|
||||
}
|
||||
else {
|
||||
addedItem = (inventory.addItem(itemstack).size() == 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
addedItem = (inventory.addItem(itemstack).size() == 0);
|
||||
}
|
||||
}
|
||||
if (!addedItem && isPlayerInventory) {
|
||||
PlayerInventory playerInventory = (PlayerInventory) inventory;
|
||||
ItemStack offhand = playerInventory.getItemInOffHand();
|
||||
if (offhand == null || offhand.getType() == Material.AIR || (itemstack.isSimilar(offhand) && offhand.getAmount() < offhand.getMaxStackSize())) {
|
||||
ItemStack setOffhand = itemstack.clone();
|
||||
if (itemstack.isSimilar(offhand)) {
|
||||
setOffhand.setAmount(offhand.getAmount() + 1);
|
||||
}
|
||||
|
||||
playerInventory.setItemInOffHand(setOffhand);
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int removeAmount = itemstack.getAmount();
|
||||
ItemStack removeMatch = itemstack.clone();
|
||||
removeMatch.setAmount(1);
|
||||
|
||||
ItemStack[] inventoryContents = (isPlayerInventory ? inventory.getContents() : inventory.getStorageContents()).clone();
|
||||
for (int i = inventoryContents.length - 1; i >= 0; i--) {
|
||||
if (inventoryContents[i] != null) {
|
||||
ItemStack itemStack = inventoryContents[i].clone();
|
||||
int maxAmount = itemStack.getAmount();
|
||||
int currentAmount = maxAmount;
|
||||
itemStack.setAmount(1);
|
||||
|
||||
if (itemStack.toString().equals(removeMatch.toString())) {
|
||||
for (int scan = 0; scan < maxAmount; scan++) {
|
||||
if (removeAmount > 0) {
|
||||
currentAmount--;
|
||||
itemStack.setAmount(currentAmount);
|
||||
removeAmount--;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
itemStack.setAmount(maxAmount);
|
||||
}
|
||||
|
||||
if (itemStack.getAmount() == 0) {
|
||||
inventoryContents[i] = null;
|
||||
}
|
||||
else {
|
||||
inventoryContents[i] = itemStack;
|
||||
}
|
||||
}
|
||||
|
||||
if (removeAmount == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isPlayerInventory) {
|
||||
inventory.setContents(inventoryContents);
|
||||
}
|
||||
else {
|
||||
inventory.setStorageContents(inventoryContents);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
while (count < removeAmount) {
|
||||
inventory.removeItem(removeMatch);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return modifiedArmor;
|
||||
}
|
||||
|
||||
public static void sortContainerItems(PlayerInventory inventory, List<Integer> modifiedArmorSlots) {
|
||||
try {
|
||||
ItemStack[] armorContents = inventory.getArmorContents();
|
||||
ItemStack[] storageContents = inventory.getStorageContents();
|
||||
|
||||
for (int armor = 0; armor < armorContents.length; armor++) {
|
||||
ItemStack armorItem = armorContents[armor];
|
||||
if (armorItem == null || !modifiedArmorSlots.contains(armor)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int storage = 0; storage < storageContents.length; storage++) {
|
||||
ItemStack storageItem = storageContents[storage];
|
||||
if (storageItem == null) {
|
||||
storageContents[storage] = armorItem;
|
||||
armorContents[armor] = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inventory.setArmorContents(armorContents);
|
||||
inventory.setStorageContents(storageContents);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void buildFireworkEffect(Builder effectBuilder, Material rowType, ItemStack itemstack) {
|
||||
try {
|
||||
FireworkEffect effect = effectBuilder.build();
|
||||
if ((rowType == Material.FIREWORK_ROCKET)) {
|
||||
FireworkMeta meta = (FireworkMeta) itemstack.getItemMeta();
|
||||
meta.addEffect(effect);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
else if ((rowType == Material.FIREWORK_STAR)) {
|
||||
FireworkEffectMeta meta = (FireworkEffectMeta) itemstack.getItemMeta();
|
||||
meta.setEffect(effect);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Object[] populateItemStack(ItemStack itemstack, Object list) {
|
||||
int slot = 0;
|
||||
String faceData = "";
|
||||
|
||||
try {
|
||||
/*
|
||||
if (list instanceof Object[]) {
|
||||
slot = (int) ((Object[]) list)[0];
|
||||
ItemMeta itemMeta = (ItemMeta) ((Object[]) list)[1];
|
||||
itemstack.setItemMeta(itemMeta);
|
||||
return new Object[] { slot, itemstack };
|
||||
}
|
||||
*/
|
||||
|
||||
Material rowType = itemstack.getType();
|
||||
List<Object> metaList = (List<Object>) list;
|
||||
if (metaList.size() > 0 && !(metaList.get(0) instanceof List<?>)) {
|
||||
if (rowType.name().endsWith("_BANNER")) {
|
||||
BannerMeta meta = (BannerMeta) itemstack.getItemMeta();
|
||||
for (Object value : metaList) {
|
||||
if (value instanceof Map) {
|
||||
Pattern pattern = new Pattern((Map<String, Object>) value);
|
||||
meta.addPattern(pattern);
|
||||
}
|
||||
}
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
else if (BlockGroup.SHULKER_BOXES.contains(rowType)) {
|
||||
BlockStateMeta meta = (BlockStateMeta) itemstack.getItemMeta();
|
||||
ShulkerBox shulkerBox = (ShulkerBox) meta.getBlockState();
|
||||
for (Object value : metaList) {
|
||||
ItemStack item = Util.unserializeItemStackLegacy(value);
|
||||
if (item != null) {
|
||||
shulkerBox.getInventory().addItem(item);
|
||||
}
|
||||
}
|
||||
meta.setBlockState(shulkerBox);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return new Object[] { slot, faceData, itemstack };
|
||||
}
|
||||
|
||||
int itemCount = 0;
|
||||
Builder effectBuilder = FireworkEffect.builder();
|
||||
for (List<Map<String, Object>> map : (List<List<Map<String, Object>>>) list) {
|
||||
if (map.size() == 0) {
|
||||
if (itemCount == 3 && (rowType == Material.FIREWORK_ROCKET || rowType == Material.FIREWORK_STAR)) {
|
||||
buildFireworkEffect(effectBuilder, rowType, itemstack);
|
||||
itemCount = 0;
|
||||
}
|
||||
|
||||
itemCount++;
|
||||
continue;
|
||||
}
|
||||
Map<String, Object> mapData = map.get(0);
|
||||
|
||||
if (mapData.get("slot") != null) {
|
||||
slot = (Integer) mapData.get("slot");
|
||||
}
|
||||
else if (mapData.get("facing") != null) {
|
||||
faceData = (String) mapData.get("facing");
|
||||
}
|
||||
else if (mapData.get("modifiers") != null) {
|
||||
ItemMeta itemMeta = itemstack.getItemMeta();
|
||||
if (itemMeta.hasAttributeModifiers()) {
|
||||
for (Map.Entry<Attribute, AttributeModifier> entry : itemMeta.getAttributeModifiers().entries()) {
|
||||
itemMeta.removeAttributeModifier(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
List<Object> modifiers = (List<Object>) mapData.get("modifiers");
|
||||
|
||||
for (Object item : modifiers) {
|
||||
Map<Attribute, Map<String, Object>> modifiersMap = (Map<Attribute, Map<String, Object>>) item;
|
||||
for (Map.Entry<Attribute, Map<String, Object>> entry : modifiersMap.entrySet()) {
|
||||
try {
|
||||
Attribute attribute = entry.getKey();
|
||||
AttributeModifier modifier = AttributeModifier.deserialize(entry.getValue());
|
||||
itemMeta.addAttributeModifier(attribute, modifier);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// AttributeModifier already exists
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
itemstack.setItemMeta(itemMeta);
|
||||
}
|
||||
else if (itemCount == 0) {
|
||||
ItemMeta meta = Util.deserializeItemMeta(itemstack.getItemMeta().getClass(), map.get(0));
|
||||
itemstack.setItemMeta(meta);
|
||||
|
||||
if (map.size() > 1 && (rowType == Material.POTION)) {
|
||||
PotionMeta subMeta = (PotionMeta) itemstack.getItemMeta();
|
||||
org.bukkit.Color color = org.bukkit.Color.deserialize(map.get(1));
|
||||
subMeta.setColor(color);
|
||||
itemstack.setItemMeta(subMeta);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((rowType == Material.LEATHER_HORSE_ARMOR) || (rowType == Material.LEATHER_HELMET) || (rowType == Material.LEATHER_CHESTPLATE) || (rowType == Material.LEATHER_LEGGINGS) || (rowType == Material.LEATHER_BOOTS)) { // leather armor
|
||||
for (Map<String, Object> colorData : map) {
|
||||
LeatherArmorMeta meta = (LeatherArmorMeta) itemstack.getItemMeta();
|
||||
org.bukkit.Color color = org.bukkit.Color.deserialize(colorData);
|
||||
meta.setColor(color);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
else if ((rowType == Material.POTION)) { // potion
|
||||
for (Map<String, Object> potionData : map) {
|
||||
PotionMeta meta = (PotionMeta) itemstack.getItemMeta();
|
||||
PotionEffect effect = new PotionEffect(potionData);
|
||||
meta.addCustomEffect(effect, true);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
else if (rowType.name().endsWith("_BANNER")) {
|
||||
for (Map<String, Object> patternData : map) {
|
||||
BannerMeta meta = (BannerMeta) itemstack.getItemMeta();
|
||||
Pattern pattern = new Pattern(patternData);
|
||||
meta.addPattern(pattern);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
else if ((rowType == Material.CROSSBOW)) {
|
||||
CrossbowMeta meta = (CrossbowMeta) itemstack.getItemMeta();
|
||||
for (Map<String, Object> itemData : map) {
|
||||
ItemStack crossbowItem = Util.unserializeItemStack(itemData);
|
||||
if (crossbowItem != null) {
|
||||
meta.addChargedProjectile(crossbowItem);
|
||||
}
|
||||
}
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
else if (rowType == Material.MAP || rowType == Material.FILLED_MAP) {
|
||||
for (Map<String, Object> colorData : map) {
|
||||
MapMeta meta = (MapMeta) itemstack.getItemMeta();
|
||||
org.bukkit.Color color = org.bukkit.Color.deserialize(colorData);
|
||||
meta.setColor(color);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
else if ((rowType == Material.FIREWORK_ROCKET) || (rowType == Material.FIREWORK_STAR)) {
|
||||
if (itemCount == 1) {
|
||||
effectBuilder = FireworkEffect.builder();
|
||||
for (Map<String, Object> fireworkData : map) {
|
||||
org.bukkit.FireworkEffect.Type type = (org.bukkit.FireworkEffect.Type) fireworkData.getOrDefault("type", org.bukkit.FireworkEffect.Type.BALL);
|
||||
boolean hasFlicker = (Boolean) fireworkData.get("flicker");
|
||||
boolean hasTrail = (Boolean) fireworkData.get("trail");
|
||||
effectBuilder.with(type);
|
||||
effectBuilder.flicker(hasFlicker);
|
||||
effectBuilder.trail(hasTrail);
|
||||
}
|
||||
}
|
||||
else if (itemCount == 2) {
|
||||
for (Map<String, Object> colorData : map) {
|
||||
org.bukkit.Color color = org.bukkit.Color.deserialize(colorData);
|
||||
effectBuilder.withColor(color);
|
||||
}
|
||||
}
|
||||
else if (itemCount == 3) {
|
||||
for (Map<String, Object> colorData : map) {
|
||||
org.bukkit.Color color = org.bukkit.Color.deserialize(colorData);
|
||||
effectBuilder.withFade(color);
|
||||
}
|
||||
buildFireworkEffect(effectBuilder, rowType, itemstack);
|
||||
itemCount = 0;
|
||||
}
|
||||
}
|
||||
else if ((rowType == Material.SUSPICIOUS_STEW)) {
|
||||
for (Map<String, Object> suspiciousStewData : map) {
|
||||
SuspiciousStewMeta meta = (SuspiciousStewMeta) itemstack.getItemMeta();
|
||||
PotionEffect effect = new PotionEffect(suspiciousStewData);
|
||||
meta.addCustomEffect(effect, true);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BukkitAdapter.ADAPTER.setItemMeta(rowType, itemstack, map);
|
||||
}
|
||||
}
|
||||
|
||||
itemCount++;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new Object[] { slot, faceData, itemstack };
|
||||
}
|
||||
|
||||
public static Object[] populateItemStack(ItemStack itemstack, byte[] metadata) {
|
||||
if (metadata != null) {
|
||||
try {
|
||||
ByteArrayInputStream metaByteStream = new ByteArrayInputStream(metadata);
|
||||
BukkitObjectInputStream metaObjectStream = new BukkitObjectInputStream(metaByteStream);
|
||||
Object metaList = metaObjectStream.readObject();
|
||||
metaObjectStream.close();
|
||||
metaByteStream.close();
|
||||
|
||||
return populateItemStack(itemstack, metaList);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return new Object[] { 0, "", itemstack };
|
||||
}
|
||||
|
||||
}
|
|
@ -12,13 +12,15 @@ import org.bukkit.block.BlockState;
|
|||
import org.bukkit.util.io.BukkitObjectInputStream;
|
||||
import org.bukkit.util.io.BukkitObjectOutputStream;
|
||||
|
||||
import net.coreprotect.database.Database;
|
||||
|
||||
public class EntityStatement {
|
||||
|
||||
private EntityStatement() {
|
||||
throw new IllegalStateException("Database class");
|
||||
}
|
||||
|
||||
public static void insert(PreparedStatement preparedStmt, int time, List<Object> data) {
|
||||
public static ResultSet insert(PreparedStatement preparedStmt, int time, List<Object> data) {
|
||||
try {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
BukkitObjectOutputStream oos = new BukkitObjectOutputStream(bos);
|
||||
|
@ -30,11 +32,18 @@ public class EntityStatement {
|
|||
byte[] byte_data = bos.toByteArray();
|
||||
preparedStmt.setInt(1, time);
|
||||
preparedStmt.setObject(2, byte_data);
|
||||
preparedStmt.executeUpdate();
|
||||
if (Database.hasReturningKeys()) {
|
||||
return preparedStmt.executeQuery();
|
||||
}
|
||||
else {
|
||||
preparedStmt.executeUpdate();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<Object> getData(Statement statement, BlockState block, String query) {
|
||||
|
|
|
@ -9,21 +9,31 @@ import org.bukkit.Bukkit;
|
|||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Skull;
|
||||
|
||||
import net.coreprotect.database.Database;
|
||||
import net.coreprotect.paper.PaperAdapter;
|
||||
|
||||
public class SkullStatement {
|
||||
|
||||
private SkullStatement() {
|
||||
throw new IllegalStateException("Database class");
|
||||
}
|
||||
|
||||
public static void insert(PreparedStatement preparedStmt, int time, String owner) {
|
||||
public static ResultSet insert(PreparedStatement preparedStmt, int time, String owner) {
|
||||
try {
|
||||
preparedStmt.setInt(1, time);
|
||||
preparedStmt.setString(2, owner);
|
||||
preparedStmt.executeUpdate();
|
||||
if (Database.hasReturningKeys()) {
|
||||
return preparedStmt.executeQuery();
|
||||
}
|
||||
else {
|
||||
preparedStmt.executeUpdate();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void getData(Statement statement, BlockState block, String query) {
|
||||
|
@ -37,9 +47,12 @@ public class SkullStatement {
|
|||
|
||||
while (resultSet.next()) {
|
||||
String owner = resultSet.getString("owner");
|
||||
if (owner != null && owner.length() >= 32) {
|
||||
if (owner != null && owner.length() >= 32 && owner.contains("-")) {
|
||||
skull.setOwningPlayer(Bukkit.getOfflinePlayer(UUID.fromString(owner)));
|
||||
}
|
||||
else if (owner != null && owner.length() > 1) {
|
||||
PaperAdapter.ADAPTER.setSkullOwner(skull, owner);
|
||||
}
|
||||
}
|
||||
|
||||
resultSet.close();
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.util.Locale;
|
|||
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.Database;
|
||||
|
||||
public class UserStatement {
|
||||
|
||||
|
@ -21,14 +22,32 @@ public class UserStatement {
|
|||
|
||||
try {
|
||||
int unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
|
||||
PreparedStatement preparedStmt = connection.prepareStatement("INSERT INTO " + ConfigHandler.prefix + "user (time, user) VALUES (?, ?)", Statement.RETURN_GENERATED_KEYS);
|
||||
|
||||
PreparedStatement preparedStmt = null;
|
||||
if (Database.hasReturningKeys()) {
|
||||
preparedStmt = connection.prepareStatement("INSERT INTO " + ConfigHandler.prefix + "user (time, user) VALUES (?, ?) RETURNING rowid");
|
||||
}
|
||||
else {
|
||||
preparedStmt = connection.prepareStatement("INSERT INTO " + ConfigHandler.prefix + "user (time, user) VALUES (?, ?)", Statement.RETURN_GENERATED_KEYS);
|
||||
}
|
||||
|
||||
preparedStmt.setInt(1, unixtimestamp);
|
||||
preparedStmt.setString(2, user);
|
||||
preparedStmt.executeUpdate();
|
||||
ResultSet keys = preparedStmt.getGeneratedKeys();
|
||||
keys.next();
|
||||
id = keys.getInt(1);
|
||||
keys.close();
|
||||
|
||||
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) {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package net.coreprotect.event;
|
||||
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class CoreProtectPreLogEvent extends Event {
|
||||
public class CoreProtectPreLogEvent extends Event implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancelled = false;
|
||||
|
@ -18,10 +19,12 @@ public class CoreProtectPreLogEvent extends Event {
|
|||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancelled = cancel;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ public class Language {
|
|||
phrases.put(Phrase.DATABASE_LOCKED_4, "Disabling database locking can result in data corruption.");
|
||||
phrases.put(Phrase.DATABASE_UNREACHABLE, "Database is unreachable. Discarding data and shutting down.");
|
||||
phrases.put(Phrase.DEVELOPMENT_BRANCH, "Development branch detected, skipping patch scripts.");
|
||||
phrases.put(Phrase.DIRT_BLOCK, "Placed a dirt block under you.");
|
||||
phrases.put(Phrase.DIRT_BLOCK, "Placed a temporary safety block under you.");
|
||||
phrases.put(Phrase.DISABLE_SUCCESS, "Success! Disabled {0}");
|
||||
phrases.put(Phrase.ENABLE_FAILED, "{0} was unable to start.");
|
||||
phrases.put(Phrase.ENABLE_SUCCESS, "{0} has been successfully enabled!");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -49,7 +49,7 @@ public final class BlockDispenseListener extends Queue implements Listener {
|
|||
boolean dispenseSuccess = !event.getVelocity().equals(new Vector()); // true if velocity is set
|
||||
boolean dispenseRelative = newBlock.getLocation().equals(velocityLocation); // true if velocity location matches relative location
|
||||
|
||||
if (!BlockPreDispenseListener.useBlockPreDispenseEvent) {
|
||||
if (!BlockPreDispenseListener.useBlockPreDispenseEvent || (!BlockPreDispenseListener.useForDroppers && block.getType() == Material.DROPPER)) {
|
||||
if (dispenseRelative || material.equals(Material.FLINT_AND_STEEL) || material.equals(Material.SHEARS)) {
|
||||
forceItem = false;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package net.coreprotect.listener.block;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
|
@ -37,9 +37,7 @@ public final class BlockExplodeListener extends Queue implements Listener {
|
|||
}
|
||||
|
||||
if (Config.getConfig(world).NATURAL_BREAK) {
|
||||
Iterator<Map.Entry<Location, Block>> it = new HashMap<>(blockMap).entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<Location, Block> data = it.next();
|
||||
for (Entry<Location, Block> data : new HashMap<>(blockMap).entrySet()) {
|
||||
Block block = data.getValue();
|
||||
int x = block.getX();
|
||||
int y = block.getY();
|
||||
|
@ -158,7 +156,7 @@ public final class BlockExplodeListener extends Queue implements Listener {
|
|||
user = "#tnt";
|
||||
}
|
||||
else if (user.contains("end_crystal")) {
|
||||
user = "#endercrystal";
|
||||
user = "#ender_crystal";
|
||||
}
|
||||
if (!user.startsWith("#")) {
|
||||
user = "#explosion";
|
||||
|
|
|
@ -4,11 +4,13 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockFertilizeEvent;
|
||||
|
||||
|
@ -18,7 +20,7 @@ import net.coreprotect.thread.CacheHandler;
|
|||
|
||||
public final class BlockFertilizeListener extends Queue implements Listener {
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
protected void onBlockFertilize(BlockFertilizeEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
|
@ -31,12 +33,16 @@ public final class BlockFertilizeListener extends Queue implements Listener {
|
|||
|
||||
Location location = block.getLocation();
|
||||
List<BlockState> blocks = event.getBlocks();
|
||||
|
||||
if (Tag.SAPLINGS.isTagged(block.getType()) && (!Config.getConfig(location.getWorld()).TREE_GROWTH || (blocks.size() == 1 && blocks.get(0).getLocation().equals(location)))) {
|
||||
return;
|
||||
}
|
||||
if (block.getType().name().toLowerCase(Locale.ROOT).contains("mushroom") && (!Config.getConfig(location.getWorld()).MUSHROOM_GROWTH || (blocks.size() == 1 && blocks.get(0).getLocation().equals(location)))) {
|
||||
return;
|
||||
}
|
||||
if (block.getType() == Material.AIR && blocks.size() > 1 && Tag.LOGS.isTagged(blocks.get(1).getType()) && !Config.getConfig(location.getWorld()).TREE_GROWTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
String user = "#bonemeal";
|
||||
Player player = event.getPlayer();
|
||||
|
|
|
@ -75,10 +75,10 @@ public final class BlockFromToListener extends Queue implements Listener {
|
|||
}
|
||||
|
||||
if (f.startsWith("#")) {
|
||||
Location location = toBlock.getLocation();
|
||||
String cacheId = toBlock.getX() + "." + toBlock.getY() + "." + toBlock.getZ() + "." + Util.getWorldId(toBlock.getWorld().getName());
|
||||
int timestamp = (int) (System.currentTimeMillis() / 1000L);
|
||||
Object[] cacheData = CacheHandler.spreadCache.get(location);
|
||||
CacheHandler.spreadCache.put(location, new Object[] { timestamp, type });
|
||||
Object[] cacheData = CacheHandler.spreadCache.get(cacheId);
|
||||
CacheHandler.spreadCache.put(cacheId, new Object[] { timestamp, type });
|
||||
if (toBlockState == null && cacheData != null && ((Material) cacheData[1]) == type) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import net.coreprotect.config.Config;
|
|||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.model.BlockGroup;
|
||||
import net.coreprotect.thread.CacheHandler;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public final class BlockSpreadListener extends Queue implements Listener {
|
||||
|
||||
|
@ -81,10 +82,11 @@ public final class BlockSpreadListener extends Queue implements Listener {
|
|||
}
|
||||
|
||||
private boolean checkCacheData(Block block, Material type) {
|
||||
String cacheId = block.getX() + "." + block.getY() + "." + block.getZ() + "." + Util.getWorldId(block.getWorld().getName());
|
||||
Location location = block.getLocation();
|
||||
int timestamp = (int) (System.currentTimeMillis() / 1000L);
|
||||
Object[] cacheData = CacheHandler.spreadCache.get(location);
|
||||
CacheHandler.spreadCache.put(location, new Object[] { timestamp, type });
|
||||
Object[] cacheData = CacheHandler.spreadCache.get(cacheId);
|
||||
CacheHandler.spreadCache.put(cacheId, new Object[] { timestamp, type });
|
||||
if (cacheData != null && ((Material) cacheData[1]) == type) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -40,9 +40,9 @@ public final class CreatureSpawnListener extends Queue implements Listener {
|
|||
Map.Entry<String, Object[]> pair = it.next();
|
||||
String name = pair.getKey();
|
||||
Object[] data = pair.getValue();
|
||||
if ((data[0].equals(key) || data[1].equals(key)) && Util.getEntityMaterial(event.getEntityType()) == ((ItemStack) data[2]).getType()) {
|
||||
if ((data[1].equals(key) || data[2].equals(key)) && Util.getEntityMaterial(event.getEntityType()) == ((ItemStack) data[3]).getType()) {
|
||||
Block gravityLocation = BlockUtil.gravityScan(location, Material.ARMOR_STAND, name);
|
||||
Queue.queueBlockPlace(name, gravityLocation.getState(), location.getBlock().getType(), location.getBlock().getState(), ((ItemStack) data[2]).getType(), (int) event.getEntity().getLocation().getYaw(), 1, null);
|
||||
Queue.queueBlockPlace(name, gravityLocation.getState(), location.getBlock().getType(), location.getBlock().getState(), ((ItemStack) data[3]).getType(), (int) event.getEntity().getLocation().getYaw(), 1, null);
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package net.coreprotect.listener.entity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
@ -121,8 +122,11 @@ public final class EntityDeathListener extends Queue implements Listener {
|
|||
e = isCommand ? "#command" : "";
|
||||
}
|
||||
|
||||
List<DamageCause> validDamageCauses = Arrays.asList(DamageCause.SUICIDE, DamageCause.POISON, DamageCause.THORNS, DamageCause.MAGIC, DamageCause.WITHER);
|
||||
|
||||
boolean skip = true;
|
||||
if (!Config.getConfig(entity.getWorld()).SKIP_GENERIC_DATA || (!(entity instanceof Zombie) && !(entity instanceof Skeleton))) {
|
||||
EntityDamageEvent.DamageCause cause = damage.getCause();
|
||||
if (!Config.getConfig(entity.getWorld()).SKIP_GENERIC_DATA || (!(entity instanceof Zombie) && !(entity instanceof Skeleton)) || (validDamageCauses.contains(cause) || cause.name().equals("KILL"))) {
|
||||
skip = false;
|
||||
}
|
||||
|
||||
|
@ -171,7 +175,6 @@ public final class EntityDeathListener extends Queue implements Listener {
|
|||
}
|
||||
}
|
||||
else {
|
||||
EntityDamageEvent.DamageCause cause = damage.getCause();
|
||||
if (cause.equals(EntityDamageEvent.DamageCause.FIRE)) {
|
||||
e = "#fire";
|
||||
}
|
||||
|
@ -189,6 +192,12 @@ public final class EntityDeathListener extends Queue implements Listener {
|
|||
else if (cause.equals(EntityDamageEvent.DamageCause.MAGIC)) {
|
||||
e = "#magic";
|
||||
}
|
||||
else if (cause.equals(EntityDamageEvent.DamageCause.WITHER)) {
|
||||
e = "#wither_effect";
|
||||
}
|
||||
else if (!cause.name().contains("_")) {
|
||||
e = "#" + cause.name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
if (entity instanceof ArmorStand) {
|
||||
|
@ -224,7 +233,7 @@ public final class EntityDeathListener extends Queue implements Listener {
|
|||
}
|
||||
}
|
||||
|
||||
if (e.startsWith("#wither")) {
|
||||
if (e.startsWith("#wither") && !e.equals("#wither_effect")) {
|
||||
e = "#wither";
|
||||
}
|
||||
|
||||
|
@ -368,7 +377,7 @@ public final class EntityDeathListener extends Queue implements Listener {
|
|||
List<Object> ingredients = new ArrayList<>();
|
||||
List<Object> itemMap = new ArrayList<>();
|
||||
ItemStack item = merchantRecipe.getResult().clone();
|
||||
List<List<Map<String, Object>>> metadata = ItemMetaHandler.seralize(item, item.getType(), null, 0);
|
||||
List<List<Map<String, Object>>> metadata = ItemMetaHandler.serialize(item, item.getType(), null, 0);
|
||||
item.setItemMeta(null);
|
||||
itemMap.add(item.serialize());
|
||||
itemMap.add(metadata);
|
||||
|
@ -380,7 +389,7 @@ public final class EntityDeathListener extends Queue implements Listener {
|
|||
for (ItemStack ingredient : merchantRecipe.getIngredients()) {
|
||||
itemMap = new ArrayList<>();
|
||||
item = ingredient.clone();
|
||||
metadata = ItemMetaHandler.seralize(item, item.getType(), null, 0);
|
||||
metadata = ItemMetaHandler.serialize(item, item.getType(), null, 0);
|
||||
item.setItemMeta(null);
|
||||
itemMap.add(item.serialize());
|
||||
itemMap.add(metadata);
|
||||
|
@ -527,6 +536,16 @@ public final class EntityDeathListener extends Queue implements Listener {
|
|||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onEntityDeath(EntityDeathEvent event) {
|
||||
/*
|
||||
System.out.println("ENTITY DEATH - " + event.getEntity().getName());
|
||||
if (event.getEntity().getKiller() != null) {
|
||||
System.out.println("^ (killer): " + event.getEntity().getKiller().getName());
|
||||
}
|
||||
else if (event.getEntity().getLastDamageCause() != null) {
|
||||
System.out.println("^ (damage cause): " + event.getEntity().getLastDamageCause().getEntity().getName());
|
||||
}
|
||||
*/
|
||||
|
||||
LivingEntity entity = event.getEntity();
|
||||
if (entity == null) {
|
||||
return;
|
||||
|
|
|
@ -46,7 +46,7 @@ public final class EntityExplodeListener extends Queue implements Listener {
|
|||
user = "#wither";
|
||||
}
|
||||
else if (entity instanceof EnderCrystal) {
|
||||
user = "#endercrystal";
|
||||
user = "#ender_crystal";
|
||||
}
|
||||
|
||||
boolean log = false;
|
||||
|
|
|
@ -6,8 +6,6 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.inventory.BrewerInventory;
|
||||
import org.bukkit.inventory.FurnaceInventory;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
@ -30,11 +28,7 @@ public final class HopperPullListener {
|
|||
}
|
||||
}
|
||||
|
||||
ItemStack[] containerState = null;
|
||||
if (!ConfigHandler.isPaper) {
|
||||
containerState = Util.getContainerState(sourceHolder.getInventory().getContents());
|
||||
}
|
||||
ItemStack[] sourceContainer = containerState;
|
||||
ItemStack[] destinationContainer = Util.getContainerState(destinationHolder.getInventory().getContents());
|
||||
ItemStack movedItem = item.clone();
|
||||
|
||||
final long taskStarted = InventoryChangeListener.tasksStarted.incrementAndGet();
|
||||
|
@ -44,48 +38,10 @@ public final class HopperPullListener {
|
|||
return;
|
||||
}
|
||||
|
||||
boolean hopperTransactions = Config.getConfig(location.getWorld()).HOPPER_TRANSACTIONS;
|
||||
int itemHash = Util.getItemStackHashCode(item);
|
||||
boolean abort = false;
|
||||
|
||||
if (ConfigHandler.isPaper) {
|
||||
for (ItemStack itemStack : sourceHolder.getInventory().getContents()) {
|
||||
if (itemStack != null && Util.getItemStackHashCode(itemStack) == itemHash) {
|
||||
if (itemHash != Util.getItemStackHashCode(movedItem) || destinationHolder.getInventory().firstEmpty() == -1 || destinationHolder.getInventory() instanceof BrewerInventory || destinationHolder.getInventory() instanceof FurnaceInventory) {
|
||||
abort = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
for (ItemStack itemStack : sourceHolder.getInventory().getContents()) {
|
||||
if (itemStack != null && Util.getItemStackHashCode(itemStack) == itemHash) {
|
||||
abort = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (abort) {
|
||||
for (ItemStack itemStack : destinationHolder.getInventory().getContents()) {
|
||||
if (itemStack != null && Util.getItemStackHashCode(itemStack) == Util.getItemStackHashCode(movedItem)) {
|
||||
if (itemHash == Util.getItemStackHashCode(itemStack) && destinationHolder.getInventory().firstEmpty() > -1) {
|
||||
abort = false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
else {
|
||||
ItemStack[] sourceContents = sourceHolder.getInventory().getContents();
|
||||
boolean addedInventory = Util.addedContainer(sourceContainer, sourceContents);
|
||||
if (addedInventory) {
|
||||
abort = true;
|
||||
}
|
||||
boolean addedInventory = Util.canAddContainer(destinationContainer, movedItem, destinationHolder.getInventory().getMaxStackSize());
|
||||
if (!addedInventory) {
|
||||
abort = true;
|
||||
}
|
||||
|
||||
if (abort) {
|
||||
|
@ -104,6 +60,7 @@ public final class HopperPullListener {
|
|||
ConfigHandler.hopperAbort.remove(loggingChestId);
|
||||
}
|
||||
|
||||
boolean hopperTransactions = Config.getConfig(location.getWorld()).HOPPER_TRANSACTIONS;
|
||||
if (!hopperTransactions) {
|
||||
List<Object> list = ConfigHandler.transactingChest.get(location.getWorld().getUID().toString() + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ());
|
||||
if (list != null) {
|
||||
|
|
|
@ -6,8 +6,6 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.inventory.BrewerInventory;
|
||||
import org.bukkit.inventory.FurnaceInventory;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
@ -21,7 +19,12 @@ import net.coreprotect.utility.Util;
|
|||
public final class HopperPushListener {
|
||||
|
||||
static void processHopperPush(Location location, InventoryHolder sourceHolder, InventoryHolder destinationHolder, ItemStack item) {
|
||||
String loggingChestId = "#hopper-push." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
|
||||
Location destinationLocation = destinationHolder.getInventory().getLocation();
|
||||
if (destinationLocation == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String loggingChestId = "#hopper-push." + destinationLocation.getBlockX() + "." + destinationLocation.getBlockY() + "." + destinationLocation.getBlockZ();
|
||||
Object[] lastAbort = ConfigHandler.hopperAbort.get(loggingChestId);
|
||||
if (lastAbort != null) {
|
||||
ItemStack[] destinationContents = destinationHolder.getInventory().getContents();
|
||||
|
@ -30,11 +33,7 @@ public final class HopperPushListener {
|
|||
}
|
||||
}
|
||||
|
||||
ItemStack[] containerState = null;
|
||||
if (!ConfigHandler.isPaper) {
|
||||
containerState = Util.getContainerState(destinationHolder.getInventory().getContents());
|
||||
}
|
||||
ItemStack[] destinationContainer = containerState;
|
||||
ItemStack[] destinationContainer = Util.getContainerState(destinationHolder.getInventory().getContents());
|
||||
ItemStack movedItem = item.clone();
|
||||
|
||||
final long taskStarted = InventoryChangeListener.tasksStarted.incrementAndGet();
|
||||
|
@ -44,26 +43,10 @@ public final class HopperPushListener {
|
|||
return;
|
||||
}
|
||||
|
||||
int itemHash = Util.getItemStackHashCode(item);
|
||||
boolean abort = false;
|
||||
|
||||
if (ConfigHandler.isPaper) {
|
||||
for (ItemStack itemStack : sourceHolder.getInventory().getContents()) {
|
||||
if (itemStack != null && Util.getItemStackHashCode(itemStack) == itemHash) {
|
||||
if (itemHash != Util.getItemStackHashCode(movedItem) || destinationHolder.getInventory().firstEmpty() == -1 || destinationHolder.getInventory() instanceof BrewerInventory || destinationHolder.getInventory() instanceof FurnaceInventory) {
|
||||
abort = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ItemStack[] destinationContents = destinationHolder.getInventory().getContents();
|
||||
boolean addedInventory = Util.addedContainer(destinationContainer, destinationContents);
|
||||
if (!addedInventory) {
|
||||
abort = true;
|
||||
}
|
||||
boolean addedInventory = Util.canAddContainer(destinationContainer, movedItem, destinationHolder.getInventory().getMaxStackSize());
|
||||
if (!addedInventory) {
|
||||
abort = true;
|
||||
}
|
||||
|
||||
if (abort) {
|
||||
|
@ -77,6 +60,9 @@ public final class HopperPushListener {
|
|||
ConfigHandler.hopperAbort.put(loggingChestId, new Object[] { movedItems, Util.getContainerState(destinationContents) });
|
||||
return;
|
||||
}
|
||||
else {
|
||||
ConfigHandler.hopperSuccess.put(loggingChestId, new Object[] { destinationContainer, movedItem });
|
||||
}
|
||||
|
||||
List<Object> list = ConfigHandler.transactingChest.get(location.getWorld().getUID().toString() + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ());
|
||||
if (list != null) {
|
||||
|
|
|
@ -203,7 +203,7 @@ public final class InventoryChangeListener extends Queue implements Listener {
|
|||
return false;
|
||||
}
|
||||
|
||||
private static void onInventoryInteractAsync(Player player, Inventory inventory, boolean enderChest) {
|
||||
static void onInventoryInteractAsync(Player player, Inventory inventory, boolean enderChest) {
|
||||
if (inventory == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -317,7 +317,12 @@ public final class InventoryChangeListener extends Queue implements Listener {
|
|||
return;
|
||||
}
|
||||
|
||||
Location location = event.getSource().getLocation();
|
||||
Inventory sourceInventory = event.getSource();
|
||||
if (sourceInventory == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Location location = sourceInventory.getLocation();
|
||||
if (location == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -327,7 +332,7 @@ public final class InventoryChangeListener extends Queue implements Listener {
|
|||
return;
|
||||
}
|
||||
|
||||
InventoryHolder sourceHolder = PaperAdapter.ADAPTER.getHolder(event.getSource(), false);
|
||||
InventoryHolder sourceHolder = PaperAdapter.ADAPTER.getHolder(sourceInventory, false);
|
||||
if (sourceHolder == null) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -75,6 +75,9 @@ public final class PlayerInteractEntityListener extends Queue implements Listene
|
|||
if (frame.getItem().getType().equals(Material.AIR) && !handItem.getType().equals(Material.AIR)) { // add item to item frame
|
||||
ItemStack[] oldState = new ItemStack[] { new ItemStack(Material.AIR) };
|
||||
ItemStack[] newState = new ItemStack[] { handItem.clone() };
|
||||
if (newState[0].getAmount() > 1) {
|
||||
newState[0].setAmount(1); // never add more than 1 item to an item frame at once
|
||||
}
|
||||
queueContainerSpecifiedItems(player.getName(), Material.ITEM_FRAME, new Object[] { oldState, newState, frame.getFacing() }, frame.getLocation(), false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -642,7 +642,7 @@ public final class PlayerInteractListener extends Queue implements Listener {
|
|||
});
|
||||
*/
|
||||
}
|
||||
else if ((type == Material.CAMPFIRE || type == Material.SOUL_CAMPFIRE) && CampfireStartListener.useCampfireStartEvent) {
|
||||
else if (CampfireStartListener.useCampfireStartEvent && (type == Material.CAMPFIRE || type == Material.SOUL_CAMPFIRE)) {
|
||||
ItemStack handItem = null;
|
||||
ItemStack mainHand = player.getInventory().getItemInMainHand();
|
||||
ItemStack offHand = player.getInventory().getItemInOffHand();
|
||||
|
@ -752,6 +752,10 @@ public final class PlayerInteractListener extends Queue implements Listener {
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (BukkitAdapter.ADAPTER.isDecoratedPot(type)) {
|
||||
BlockState blockState = block.getState();
|
||||
InventoryChangeListener.inventoryTransaction(player.getName(), blockState.getLocation(), null);
|
||||
}
|
||||
else if (BukkitAdapter.ADAPTER.isSuspiciousBlock(type)) {
|
||||
ItemStack handItem = null;
|
||||
ItemStack mainHand = player.getInventory().getItemInMainHand();
|
||||
|
@ -904,7 +908,7 @@ public final class PlayerInteractListener extends Queue implements Listener {
|
|||
|
||||
String relativeBlockKey = world.getName() + "-" + relativeBlockLocation.getBlockX() + "-" + relativeBlockLocation.getBlockY() + "-" + relativeBlockLocation.getBlockZ();
|
||||
String blockKey = world.getName() + "-" + blockLocation.getBlockX() + "-" + blockLocation.getBlockY() + "-" + blockLocation.getBlockZ();
|
||||
Object[] keys = new Object[] { relativeBlockKey, blockKey, handItem };
|
||||
Object[] keys = new Object[] { System.currentTimeMillis(), relativeBlockKey, blockKey, handItem };
|
||||
ConfigHandler.entityBlockMapper.put(player.getName(), keys);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
@ -68,10 +67,10 @@ public final class ProjectileLaunchListener extends Queue implements Listener {
|
|||
Map.Entry<String, Object[]> pair = it.next();
|
||||
String name = pair.getKey();
|
||||
Object[] data = pair.getValue();
|
||||
ItemStack itemStack = (ItemStack) data[2];
|
||||
ItemStack itemStack = (ItemStack) data[3];
|
||||
Material entityMaterial = Util.getEntityMaterial(event.getEntityType());
|
||||
boolean isBow = BOWS.contains(itemStack.getType());
|
||||
if ((data[0].equals(key) || data[1].equals(key)) && (entityMaterial == itemStack.getType() || (itemStack.getType() == Material.LINGERING_POTION && entityMaterial == Material.SPLASH_POTION) || isBow)) {
|
||||
if ((data[1].equals(key) || data[2].equals(key)) && (entityMaterial == itemStack.getType() || (itemStack.getType() == Material.LINGERING_POTION && entityMaterial == Material.SPLASH_POTION) || isBow)) {
|
||||
boolean thrownItem = (itemStack.getType() != Material.FIREWORK_ROCKET && !isBow);
|
||||
if (isBow) {
|
||||
if (itemStack.getType() == Material.CROSSBOW) {
|
||||
|
|
|
@ -11,7 +11,7 @@ public final class BlockGroup {
|
|||
|
||||
public static Set<Material> TRACK_ANY = new HashSet<>(Arrays.asList(Material.PISTON_HEAD, Material.LEVER, Material.BELL));
|
||||
public static Set<Material> TRACK_TOP_BOTTOM = new HashSet<>(Arrays.asList());
|
||||
public static Set<Material> TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP));
|
||||
public static Set<Material> TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP));
|
||||
public static Set<Material> TRACK_BOTTOM = new HashSet<>(Arrays.asList());
|
||||
public static Set<Material> TRACK_SIDE = new HashSet<>(Arrays.asList(Material.WALL_TORCH, Material.REDSTONE_WALL_TORCH, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.ACTIVATOR_RAIL, Material.WHITE_BED, Material.ORANGE_BED, Material.MAGENTA_BED, Material.LIGHT_BLUE_BED, Material.YELLOW_BED, Material.LIME_BED, Material.PINK_BED, Material.GRAY_BED, Material.LIGHT_GRAY_BED, Material.CYAN_BED, Material.PURPLE_BED, Material.BLUE_BED, Material.BROWN_BED, Material.GREEN_BED, Material.RED_BED, Material.BLACK_BED, Material.LADDER, Material.ACACIA_WALL_SIGN, Material.BIRCH_WALL_SIGN, Material.DARK_OAK_WALL_SIGN, Material.JUNGLE_WALL_SIGN, Material.OAK_WALL_SIGN, Material.SPRUCE_WALL_SIGN, Material.VINE, Material.COCOA, Material.TRIPWIRE_HOOK, Material.WHITE_WALL_BANNER, Material.ORANGE_WALL_BANNER, Material.MAGENTA_WALL_BANNER, Material.LIGHT_BLUE_WALL_BANNER, Material.YELLOW_WALL_BANNER, Material.LIME_WALL_BANNER, Material.PINK_WALL_BANNER, Material.GRAY_WALL_BANNER, Material.LIGHT_GRAY_WALL_BANNER, Material.CYAN_WALL_BANNER, Material.PURPLE_WALL_BANNER, Material.BLUE_WALL_BANNER, Material.BROWN_WALL_BANNER, Material.GREEN_WALL_BANNER, Material.RED_WALL_BANNER, Material.BLACK_WALL_BANNER));
|
||||
public static Set<Material> SHULKER_BOXES = new HashSet<>(Arrays.asList(Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX));
|
||||
|
@ -41,9 +41,18 @@ public final class BlockGroup {
|
|||
|
||||
// These are blocks that an item frame or painting can't be attached to.
|
||||
// Same as non_solid_entity_blocks? >>Perform testing<<
|
||||
public static Set<Material> NON_ATTACHABLE = new HashSet<>(Arrays.asList(Material.AIR, Material.CAVE_AIR, Material.BARRIER, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.WATER, Material.LAVA, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.LADDER, Material.RAIL, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.SNOW, Material.SUGAR_CANE, Material.NETHER_PORTAL, Material.REPEATER, Material.KELP, Material.CHORUS_FLOWER, Material.CHORUS_PLANT));
|
||||
public static Set<Material> NON_ATTACHABLE = new HashSet<>(Arrays.asList(Material.AIR, Material.CAVE_AIR, Material.BARRIER, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.WATER, Material.LAVA, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.LADDER, Material.RAIL, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.SNOW, Material.SUGAR_CANE, Material.NETHER_PORTAL, Material.REPEATER, Material.KELP, Material.CHORUS_FLOWER, Material.CHORUS_PLANT));
|
||||
|
||||
public static void initialize() {
|
||||
Material shortGrass = Material.getMaterial("SHORT_GRASS");
|
||||
if (shortGrass == null) {
|
||||
shortGrass = Material.getMaterial("GRASS");
|
||||
}
|
||||
if (shortGrass != null) {
|
||||
TRACK_TOP.add(shortGrass);
|
||||
NON_ATTACHABLE.add(shortGrass);
|
||||
}
|
||||
|
||||
TRACK_ANY.addAll(BUTTONS);
|
||||
TRACK_TOP.addAll(DOORS);
|
||||
TRACK_TOP.addAll(PRESSURE_PLATES);
|
||||
|
|
|
@ -3,6 +3,7 @@ package net.coreprotect.paper;
|
|||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.Skull;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
@ -73,4 +74,14 @@ public class PaperAdapter implements PaperInterface {
|
|||
entity.teleport(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSkullOwner(Skull skull) {
|
||||
return skull.getOwningPlayer().getUniqueId().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkullOwner(Skull skull, String owner) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package net.coreprotect.paper;
|
|||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.Skull;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
@ -17,4 +18,8 @@ public interface PaperInterface {
|
|||
|
||||
public void teleportAsync(Entity entity, Location location);
|
||||
|
||||
public String getSkullOwner(Skull skull);
|
||||
|
||||
public void setSkullOwner(Skull skull, String owner);
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,10 @@ public class Paper_v1_17 extends Paper_v1_16 implements PaperInterface {
|
|||
|
||||
@Override
|
||||
public String getLine(Sign sign, int line) {
|
||||
if (line >= 4) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// https://docs.adventure.kyori.net/serializer/
|
||||
return LegacyComponentSerializer.legacySection().serialize(sign.line(line));
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package net.coreprotect.paper;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.Skull;
|
||||
import org.bukkit.block.sign.Side;
|
||||
|
||||
import net.coreprotect.config.Config;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
|
||||
public class Paper_v1_20 extends Paper_v1_17 implements PaperInterface {
|
||||
|
@ -18,4 +21,24 @@ public class Paper_v1_20 extends Paper_v1_17 implements PaperInterface {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSkullOwner(Skull skull) {
|
||||
String owner = skull.getPlayerProfile().getName();
|
||||
if (Config.getGlobal().MYSQL) {
|
||||
if (owner.length() > 255 && skull.getPlayerProfile().getId() != null) {
|
||||
return skull.getPlayerProfile().getId().toString();
|
||||
}
|
||||
else if (owner.length() > 255) {
|
||||
return owner.substring(0, 255);
|
||||
}
|
||||
}
|
||||
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkullOwner(Skull skull, String owner) {
|
||||
skull.setPlayerProfile(Bukkit.createProfile(owner));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.coreprotect.paper.listener;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
@ -18,6 +19,7 @@ import net.coreprotect.listener.player.InventoryChangeListener;
|
|||
public final class BlockPreDispenseListener extends Queue implements Listener {
|
||||
|
||||
public static boolean useBlockPreDispenseEvent = true;
|
||||
public static boolean useForDroppers = false;
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onBlockPreDispense(BlockPreDispenseEvent event) {
|
||||
|
@ -29,6 +31,10 @@ public final class BlockPreDispenseListener extends Queue implements Listener {
|
|||
|
||||
BlockData blockData = block.getBlockData();
|
||||
if (blockData instanceof Dispenser) {
|
||||
if (!useForDroppers && block.getType() == Material.DROPPER) {
|
||||
useForDroppers = true;
|
||||
}
|
||||
|
||||
String user = "#dispenser";
|
||||
ItemStack[] inventory = ((InventoryHolder) block.getState()).getInventory().getStorageContents();
|
||||
InventoryChangeListener.inventoryTransaction(user, block.getLocation(), inventory);
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package net.coreprotect.patch.script;
|
||||
|
||||
import java.sql.Statement;
|
||||
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.language.Selector;
|
||||
import net.coreprotect.utility.Chat;
|
||||
|
||||
public class __2_23_0 {
|
||||
|
||||
protected static boolean patch(Statement statement) {
|
||||
try {
|
||||
if (Config.getGlobal().MYSQL) {
|
||||
try {
|
||||
statement.executeUpdate("ALTER TABLE " + ConfigHandler.prefix + "skull MODIFY owner VARCHAR(255);");
|
||||
}
|
||||
catch (Exception e) {
|
||||
Chat.console(Phrase.build(Phrase.PATCH_SKIP_UPDATE, ConfigHandler.prefix + "skull", Selector.FIRST, Selector.FIRST));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -82,4 +82,8 @@ public class SpigotAdapter implements SpigotInterface {
|
|||
|
||||
Chat.sendMessage(sender, message.toString());
|
||||
}
|
||||
|
||||
public String processComponent(String component) {
|
||||
return component.replace(Chat.COMPONENT_PIPE, "|");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package net.coreprotect.spigot;
|
|||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.utility.Color;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.chat.hover.content.Text;
|
||||
|
@ -18,8 +19,46 @@ public class Spigot_v1_16 extends SpigotHandler implements SpigotInterface {
|
|||
public void addHoverComponent(Object message, String[] data) {
|
||||
try {
|
||||
if (Config.getGlobal().HOVER_EVENTS) {
|
||||
String tooltipText = data[1]; // text displayed inside tooltip
|
||||
TextComponent component = new TextComponent(TextComponent.fromLegacyText(data[2]));
|
||||
component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(TextComponent.fromLegacyText(data[1]))));
|
||||
// BaseComponent[] displayComponent = TextComponent.fromLegacyText(processComponent(tooltipText));
|
||||
|
||||
if (tooltipText.contains(Color.MAGIC)) {
|
||||
tooltipText = tooltipText.replace(Color.MAGIC, "");
|
||||
|
||||
// to-do
|
||||
/*
|
||||
ComponentBuilder formattedComponent = new ComponentBuilder();
|
||||
StringBuilder messageTest = new StringBuilder();
|
||||
String colorChar = String.valueOf(ChatColor.COLOR_CHAR);
|
||||
boolean isObfuscated = false;
|
||||
|
||||
String[] tooltip = tooltipText.split(colorChar);
|
||||
for (String splitText : tooltip) {
|
||||
boolean setObfuscated = splitText.startsWith("k");
|
||||
splitText = setObfuscated ? splitText.substring(1) : (splitText.length() > 0 ? colorChar : "") + splitText;
|
||||
if ((setObfuscated && !isObfuscated) || (!setObfuscated && isObfuscated)) {
|
||||
formattedComponent.append(TextComponent.fromLegacyText(processComponent(messageTest.toString())));
|
||||
formattedComponent.obfuscated(false); // setObfuscated
|
||||
formattedComponent.append(TextComponent.fromLegacyText(processComponent(splitText)));
|
||||
messageTest.setLength(0);
|
||||
isObfuscated = !isObfuscated;
|
||||
}
|
||||
else {
|
||||
messageTest.append(splitText);
|
||||
}
|
||||
}
|
||||
|
||||
if (messageTest.length() > 0) {
|
||||
formattedComponent.append(TextComponent.fromLegacyText(processComponent(messageTest.toString())));
|
||||
}
|
||||
|
||||
displayComponent = formattedComponent.create();
|
||||
*/
|
||||
}
|
||||
|
||||
BaseComponent[] displayComponent = TextComponent.fromLegacyText(processComponent(tooltipText));
|
||||
component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(displayComponent)));
|
||||
((TextComponent) message).addExtra(component);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -18,7 +18,7 @@ public class CacheHandler implements Runnable {
|
|||
public static Map<String, Object[]> interactCache = Collections.synchronizedMap(new HashMap<>());
|
||||
public static Map<String, Object[]> entityCache = Collections.synchronizedMap(new HashMap<>());
|
||||
public static ConcurrentHashMap<String, Object[]> pistonCache = new ConcurrentHashMap<>(16, 0.75f, 2);
|
||||
public static ConcurrentHashMap<Location, Object[]> spreadCache = new ConcurrentHashMap<>(16, 0.75f, 2);
|
||||
public static ConcurrentHashMap<String, Object[]> spreadCache = new ConcurrentHashMap<>(16, 0.75f, 2);
|
||||
public static ConcurrentHashMap<Location, Object[]> redstoneCache = new ConcurrentHashMap<>(16, 0.75f, 2);
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
|
@ -26,7 +26,7 @@ public class CacheHandler implements Runnable {
|
|||
public void run() {
|
||||
while (ConfigHandler.serverRunning) {
|
||||
try {
|
||||
for (int id = 0; id < 7; id++) {
|
||||
for (int id = 0; id < 8; id++) {
|
||||
Thread.sleep(1000);
|
||||
int scanTime = 30;
|
||||
Map cache = CacheHandler.lookupCache;
|
||||
|
@ -41,7 +41,7 @@ public class CacheHandler implements Runnable {
|
|||
break;
|
||||
case 3:
|
||||
cache = CacheHandler.spreadCache;
|
||||
scanTime = 900; // 15 minutes
|
||||
scanTime = 1800; // 30 minutes
|
||||
break;
|
||||
case 4:
|
||||
cache = CacheHandler.interactCache;
|
||||
|
@ -55,6 +55,10 @@ public class CacheHandler implements Runnable {
|
|||
cache = CacheHandler.entityCache;
|
||||
scanTime = 3600; // 60 minutes
|
||||
break;
|
||||
case 7:
|
||||
cache = ConfigHandler.entityBlockMapper;
|
||||
scanTime = 5;
|
||||
break;
|
||||
}
|
||||
|
||||
int timestamp = (int) (System.currentTimeMillis() / 1000L) - scanTime;
|
||||
|
|
|
@ -17,6 +17,7 @@ public final class Chat {
|
|||
public static final String COMPONENT_TAG_CLOSE = "</COMPONENT>";
|
||||
public static final String COMPONENT_COMMAND = "COMMAND";
|
||||
public static final String COMPONENT_POPUP = "POPUP";
|
||||
public static final String COMPONENT_PIPE = "<PIPE/>";
|
||||
|
||||
private Chat() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
|
|
|
@ -3,17 +3,21 @@ package net.coreprotect.utility;
|
|||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.model.BlockGroup;
|
||||
import net.coreprotect.paper.PaperAdapter;
|
||||
import net.coreprotect.thread.Scheduler;
|
||||
|
||||
public class Teleport {
|
||||
|
||||
|
@ -21,6 +25,8 @@ public class Teleport {
|
|||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
|
||||
public static ConcurrentHashMap<Location, BlockData> revertBlocks = new ConcurrentHashMap<>();
|
||||
|
||||
public static void performSafeTeleport(Player player, Location location, boolean enforceTeleport) {
|
||||
try {
|
||||
Set<Material> unsafeBlocks = new HashSet<>(Arrays.asList(Material.LAVA));
|
||||
|
@ -46,20 +52,33 @@ public class Teleport {
|
|||
Material type1 = block1.getType();
|
||||
Material type2 = block2.getType();
|
||||
|
||||
if (!Util.solidBlock(type1) && !Util.solidBlock(type2)) {
|
||||
if (Util.passableBlock(block1) && Util.passableBlock(block2)) {
|
||||
if (unsafeBlocks.contains(type1)) {
|
||||
placeSafe = true;
|
||||
}
|
||||
else {
|
||||
safeBlock = true;
|
||||
if (placeSafe) {
|
||||
if (placeSafe && player.getGameMode() == GameMode.SURVIVAL) {
|
||||
int below = checkY - 1;
|
||||
Block blockBelow = location.getWorld().getBlockAt(playerX, below, playerZ);
|
||||
|
||||
if (checkY < worldHeight && unsafeBlocks.contains(blockBelow.getType())) {
|
||||
alert = true;
|
||||
block1.setType(Material.DIRT);
|
||||
Location revertLocation = block1.getLocation();
|
||||
BlockData revertBlockData = block1.getBlockData();
|
||||
revertBlocks.put(revertLocation, revertBlockData);
|
||||
if (!ConfigHandler.isFolia) {
|
||||
block1.setType(Material.BARRIER);
|
||||
}
|
||||
else {
|
||||
block1.setType(Material.DIRT);
|
||||
}
|
||||
checkY++;
|
||||
|
||||
Scheduler.scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> {
|
||||
block1.setBlockData(revertBlockData);
|
||||
revertBlocks.remove(revertLocation);
|
||||
}, revertLocation, 1200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.sql.Connection;
|
|||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -55,7 +56,7 @@ import net.coreprotect.bukkit.BukkitAdapter;
|
|||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.database.Rollback;
|
||||
import net.coreprotect.database.rollback.Rollback;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.model.BlockGroup;
|
||||
import net.coreprotect.thread.CacheHandler;
|
||||
|
@ -126,7 +127,8 @@ public class Util extends Queue {
|
|||
}
|
||||
|
||||
// command
|
||||
message.append("|/" + command + " teleport wid:" + worldId + " " + (x + 0.50) + " " + y + " " + (z + 0.50) + "|");
|
||||
DecimalFormat decimalFormat = new DecimalFormat("#.##", new DecimalFormatSymbols(Locale.ROOT));
|
||||
message.append("|/" + command + " teleport wid:" + worldId + " " + decimalFormat.format(x + 0.50) + " " + y + " " + decimalFormat.format(z + 0.50) + "|");
|
||||
|
||||
// chat output
|
||||
message.append(Color.GREY + (italic ? Color.ITALIC : "") + "(x" + x + "/y" + y + "/z" + z + worldDisplay.toString() + ")");
|
||||
|
@ -304,7 +306,7 @@ public class Util extends Queue {
|
|||
StringBuilder message = new StringBuilder(Chat.COMPONENT_TAG_OPEN + Chat.COMPONENT_POPUP);
|
||||
|
||||
// tooltip
|
||||
message.append("|" + tooltip + "|");
|
||||
message.append("|" + tooltip.replace("|", Chat.COMPONENT_PIPE) + "|");
|
||||
|
||||
// chat output
|
||||
message.append(phrase);
|
||||
|
@ -680,6 +682,30 @@ public class Util extends Queue {
|
|||
return false;
|
||||
}
|
||||
|
||||
/* return true if item can be added to container */
|
||||
public static boolean canAddContainer(ItemStack[] container, ItemStack item, int forceMaxStack) {
|
||||
for (ItemStack containerItem : container) {
|
||||
if (containerItem == null || containerItem.getType() == Material.AIR) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int maxStackSize = containerItem.getMaxStackSize();
|
||||
if (forceMaxStack > 0 && (forceMaxStack < maxStackSize || maxStackSize == -1)) {
|
||||
maxStackSize = forceMaxStack;
|
||||
}
|
||||
|
||||
if (maxStackSize == -1) {
|
||||
maxStackSize = 1;
|
||||
}
|
||||
|
||||
if (containerItem.isSimilar(item) && containerItem.getAmount() < maxStackSize) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int getArtId(String name, boolean internal) {
|
||||
int id = -1;
|
||||
name = name.toLowerCase(Locale.ROOT).trim();
|
||||
|
@ -993,6 +1019,10 @@ public class Util extends Queue {
|
|||
return type.isSolid();
|
||||
}
|
||||
|
||||
public static boolean passableBlock(Block block) {
|
||||
return block.isPassable();
|
||||
}
|
||||
|
||||
public static Material getType(Block block) {
|
||||
// Temp code
|
||||
return block.getType();
|
||||
|
@ -1009,6 +1039,10 @@ public class Util extends Queue {
|
|||
|
||||
name = BukkitAdapter.ADAPTER.parseLegacyName(name);
|
||||
material = Material.getMaterial(name);
|
||||
|
||||
if (material == null) {
|
||||
material = Material.getMaterial(name, true);
|
||||
}
|
||||
}
|
||||
|
||||
return material;
|
||||
|
@ -1381,7 +1415,7 @@ public class Util extends Queue {
|
|||
Map<String, Object> itemMap = new HashMap<>();
|
||||
if (itemStack != null && !itemStack.getType().equals(Material.AIR)) {
|
||||
ItemStack item = itemStack.clone();
|
||||
List<List<Map<String, Object>>> metadata = ItemMetaHandler.seralize(item, null, faceData, slot);
|
||||
List<List<Map<String, Object>>> metadata = ItemMetaHandler.serialize(item, null, faceData, slot);
|
||||
item.setItemMeta(null);
|
||||
itemMap.put("0", item.serialize());
|
||||
itemMap.put("1", metadata);
|
||||
|
|
|
@ -57,7 +57,7 @@ import org.bukkit.inventory.meta.LeatherArmorMeta;
|
|||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.bukkit.BukkitAdapter;
|
||||
import net.coreprotect.database.Rollback;
|
||||
import net.coreprotect.database.rollback.Rollback;
|
||||
import net.coreprotect.thread.CacheHandler;
|
||||
import net.coreprotect.thread.Scheduler;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
|
|
@ -7,7 +7,6 @@ import java.util.Map;
|
|||
import java.util.Map.Entry;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.FireworkEffect;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
|
@ -28,6 +27,7 @@ import org.bukkit.inventory.meta.SuspiciousStewMeta;
|
|||
import org.bukkit.potion.PotionEffect;
|
||||
|
||||
import net.coreprotect.bukkit.BukkitAdapter;
|
||||
import net.coreprotect.utility.Color;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class ItemMetaHandler {
|
||||
|
@ -96,7 +96,8 @@ public class ItemMetaHandler {
|
|||
|
||||
public static List<String> getEnchantments(ItemStack item, String displayName) {
|
||||
List<String> result = new ArrayList<>();
|
||||
Map<Enchantment, Integer> enchantments = getEnchantments(item.getItemMeta());
|
||||
ItemMeta itemMeta = item.getItemMeta();
|
||||
Map<Enchantment, Integer> enchantments = getEnchantments(itemMeta);
|
||||
|
||||
for (Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
|
||||
Enchantment enchantment = entry.getKey();
|
||||
|
@ -105,15 +106,21 @@ public class ItemMetaHandler {
|
|||
result.add(getEnchantmentName(enchantment, level));
|
||||
}
|
||||
|
||||
if (itemMeta.hasLore()) {
|
||||
for (String lore : itemMeta.getLore()) {
|
||||
result.add(Color.DARK_PURPLE + Color.ITALIC + lore);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<List<Map<String, Object>>> seralize(ItemStack item, Material type, String faceData, int slot) {
|
||||
public static List<List<Map<String, Object>>> serialize(ItemStack item, Material type, String faceData, int slot) {
|
||||
List<List<Map<String, Object>>> metadata = new ArrayList<>();
|
||||
List<Map<String, Object>> list = new ArrayList<>();
|
||||
List<Object> modifiers = new ArrayList<>();
|
||||
|
||||
if (item.hasItemMeta() && item.getItemMeta() != null) {
|
||||
if (item != null && item.hasItemMeta() && item.getItemMeta() != null) {
|
||||
ItemMeta itemMeta = item.getItemMeta().clone();
|
||||
|
||||
if (itemMeta.hasAttributeModifiers()) {
|
||||
|
@ -284,11 +291,11 @@ public class ItemMetaHandler {
|
|||
List<Map<String, Object>> fadeList = new ArrayList<>();
|
||||
List<Map<String, Object>> list = new ArrayList<>();
|
||||
|
||||
for (Color color : effect.getColors()) {
|
||||
for (org.bukkit.Color color : effect.getColors()) {
|
||||
colorList.add(color.serialize());
|
||||
}
|
||||
|
||||
for (Color color : effect.getFadeColors()) {
|
||||
for (org.bukkit.Color color : effect.getFadeColors()) {
|
||||
fadeList.add(color.serialize());
|
||||
}
|
||||
|
||||
|
|
|
@ -5,12 +5,9 @@ import org.bukkit.Bukkit;
|
|||
import com.sk89q.worldedit.EditSession.Stage;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.event.extent.EditSessionEvent;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.util.eventbus.Subscribe;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.language.Selector;
|
||||
|
@ -18,7 +15,6 @@ import net.coreprotect.thread.Scheduler;
|
|||
import net.coreprotect.utility.Chat;
|
||||
|
||||
public class CoreProtectEditSessionEvent {
|
||||
|
||||
private static boolean initialized = false;
|
||||
private static boolean isFAWE = false;
|
||||
private static CoreProtectEditSessionEvent event = new CoreProtectEditSessionEvent();
|
||||
|
@ -37,12 +33,17 @@ public class CoreProtectEditSessionEvent {
|
|||
}
|
||||
|
||||
try {
|
||||
if (Bukkit.getServer().getPluginManager().getPlugin("AsyncWorldEdit") == null || Config.getGlobal().ENABLE_AWE) {
|
||||
WorldEdit.getInstance().getEventBus().register(event);
|
||||
initialized = true;
|
||||
ConfigHandler.worldeditEnabled = true;
|
||||
isFAWE = (Bukkit.getServer().getPluginManager().getPlugin("FastAsyncWorldEdit") != null);
|
||||
}
|
||||
WorldEdit.getInstance().getEventBus().register(new Object() {
|
||||
@Subscribe
|
||||
public void onEditSessionEvent(EditSessionEvent event) {
|
||||
if (event.getActor() != null && event.getStage() == Stage.BEFORE_CHANGE) {
|
||||
event.setExtent(new CoreProtectLogger(event.getActor(), event.getWorld(), event.getExtent()));
|
||||
}
|
||||
}
|
||||
});
|
||||
initialized = true;
|
||||
ConfigHandler.worldeditEnabled = true;
|
||||
isFAWE = (Bukkit.getServer().getPluginManager().getPlugin("FastAsyncWorldEdit") != null);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Failed to initialize WorldEdit logging
|
||||
|
@ -51,10 +52,10 @@ public class CoreProtectEditSessionEvent {
|
|||
Scheduler.runTask(CoreProtect.getInstance(), () -> {
|
||||
try {
|
||||
if (isInitialized()) {
|
||||
Chat.console(Phrase.build(Phrase.INTEGRATION_SUCCESS, "WorldEdit", Selector.FIRST));
|
||||
Chat.console(Phrase.build(Phrase.INTEGRATION_SUCCESS, isFAWE() ? "FastAsyncWorldEdit" : "WorldEdit", Selector.FIRST));
|
||||
}
|
||||
else {
|
||||
Chat.console(Phrase.build(Phrase.INTEGRATION_ERROR, "WorldEdit", Selector.FIRST));
|
||||
Chat.console(Phrase.build(Phrase.INTEGRATION_ERROR, isFAWE() ? "FastAsyncWorldEdit" : "WorldEdit", Selector.FIRST));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
@ -72,19 +73,10 @@ public class CoreProtectEditSessionEvent {
|
|||
WorldEdit.getInstance().getEventBus().unregister(event);
|
||||
initialized = false;
|
||||
ConfigHandler.worldeditEnabled = false;
|
||||
Chat.console(Phrase.build(Phrase.INTEGRATION_SUCCESS, "WorldEdit", Selector.SECOND));
|
||||
Chat.console(Phrase.build(Phrase.INTEGRATION_SUCCESS, isFAWE() ? "FastAsyncWorldEdit" : "WorldEdit", Selector.SECOND));
|
||||
}
|
||||
catch (Exception e) {
|
||||
Chat.console(Phrase.build(Phrase.INTEGRATION_ERROR, "WorldEdit", Selector.SECOND));
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void wrapForLogging(EditSessionEvent event) {
|
||||
Actor actor = event.getActor();
|
||||
World world = event.getWorld();
|
||||
if (actor != null && event.getStage() == (isFAWE ? Stage.BEFORE_HISTORY : Stage.BEFORE_CHANGE)) {
|
||||
event.setExtent(new CoreProtectLogger(actor, world, event.getExtent()));
|
||||
Chat.console(Phrase.build(Phrase.INTEGRATION_ERROR, isFAWE() ? "FastAsyncWorldEdit" : "WorldEdit", Selector.SECOND));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,16 @@ import org.bukkit.Location;
|
|||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
|
@ -19,7 +23,6 @@ import net.coreprotect.config.Config;
|
|||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class CoreProtectLogger extends AbstractDelegateExtent {
|
||||
|
||||
private final Actor eventActor;
|
||||
private final World eventWorld;
|
||||
private final Extent eventExtent;
|
||||
|
@ -35,7 +38,12 @@ public class CoreProtectLogger extends AbstractDelegateExtent {
|
|||
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block) throws WorldEditException {
|
||||
org.bukkit.World world = BukkitAdapter.adapt(eventWorld);
|
||||
if (!Config.getConfig(world).WORLDEDIT) {
|
||||
return eventExtent.setBlock(position, block);
|
||||
if (CoreProtectEditSessionEvent.isFAWE()) {
|
||||
return eventExtent.setBlock(position.getX(), position.getY(), position.getZ(), block);
|
||||
}
|
||||
else {
|
||||
return eventExtent.setBlock(position, block);
|
||||
}
|
||||
}
|
||||
|
||||
BlockState oldBlock = eventExtent.getBlock(position);
|
||||
|
@ -48,16 +56,59 @@ public class CoreProtectLogger extends AbstractDelegateExtent {
|
|||
// e.g. BaseBlock block = eventWorld.getBlock(position);
|
||||
ItemStack[] containerData = CoreProtectEditSessionEvent.isFAWE() ? null : Util.getContainerContents(oldType, null, location);
|
||||
|
||||
if (eventExtent.setBlock(position, block)) {
|
||||
WorldEditLogger.postProcess(eventExtent, eventActor, position, location, block, baseBlock, oldType, oldBlock, containerData);
|
||||
return true;
|
||||
if (CoreProtectEditSessionEvent.isFAWE()) {
|
||||
if (eventExtent.setBlock(position.getX(), position.getY(), position.getZ(), block)) {
|
||||
WorldEditLogger.postProcess(eventExtent, eventActor, position, location, block, baseBlock, oldType, oldBlock, containerData);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (eventExtent.setBlock(position, block)) {
|
||||
WorldEditLogger.postProcess(eventExtent, eventActor, position, location, block, baseBlock, oldType, oldBlock, containerData);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block) throws WorldEditException {
|
||||
return setBlock(BlockVector3.at(x,y,z), block);
|
||||
return this.setBlock(BlockVector3.at(x, y, z), block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int replaceBlocks(final Region region, final Mask mask, final Pattern pattern) throws MaxChangedBlocksException {
|
||||
org.bukkit.World world = BukkitAdapter.adapt(eventWorld);
|
||||
if (!Config.getConfig(world).WORLDEDIT) {
|
||||
return eventExtent.replaceBlocks(region, mask, pattern);
|
||||
}
|
||||
processPatternToBlocks(world, region, pattern);
|
||||
return eventExtent.replaceBlocks(region, mask, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
|
||||
org.bukkit.World world = BukkitAdapter.adapt(eventWorld);
|
||||
if (!Config.getConfig(world).WORLDEDIT) {
|
||||
return eventExtent.setBlocks(region, pattern);
|
||||
}
|
||||
processPatternToBlocks(world, region, pattern);
|
||||
return eventExtent.setBlocks(region, pattern);
|
||||
}
|
||||
|
||||
private void processPatternToBlocks(org.bukkit.World world, Region region, Pattern pattern) {
|
||||
for (BlockVector3 position : region.clone()) {
|
||||
BlockState oldBlock = eventExtent.getBlock(position);
|
||||
Material oldType = BukkitAdapter.adapt(oldBlock.getBlockType());
|
||||
Location location = new Location(world, position.getBlockX(), position.getBlockY(), position.getBlockZ());
|
||||
BaseBlock baseBlock = WorldEditLogger.getBaseBlock(eventExtent, position, location, oldType, oldBlock);
|
||||
|
||||
// No clear way to get container content data from within the WorldEdit API
|
||||
// Data may be available by converting oldBlock.toBaseBlock().getNbtData()
|
||||
// e.g. BaseBlock block = eventWorld.getBlock(position);
|
||||
ItemStack[] containerData = CoreProtectEditSessionEvent.isFAWE() ? null : Util.getContainerContents(oldType, null, location);
|
||||
WorldEditLogger.postProcess(eventExtent, eventActor, position, location, pattern.applyBlock(position), baseBlock, oldType, oldBlock, containerData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -205,4 +205,10 @@ public final class WorldEditBlockState implements BlockState {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState copy() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue