Compare commits
271 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 | |
Intelli | 58f4a76d75 | |
Intelli | a46deeb6ba | |
Jeff P | 7fd50a0507 | |
Intelli | 9e1d5af97d | |
ianiiaannn | 4cce566e37 | |
Intelli | 703c36f356 | |
Intelli | 1dd293c5a4 | |
Radiant | 1331b8d0c5 | |
violetc | 2476aa2ea8 | |
Keno Medenbach | 6045799fea | |
Intelli | 342fadd0f6 | |
Intelli | e81c84671c | |
Intelli | e501046073 | |
Intelli | c6a0f20fff | |
Intelli | 05aebe7544 | |
Intelli | 36ad62007f | |
Intelli | bdde2d36be | |
Intelli | f32a3e7c5e | |
Intelli | c7cf035564 | |
Intelli | d4997cca60 | |
Intelli | 355eea1cf9 | |
Intelli | d7b76135c8 | |
Intelli | 1a06e6a6bf | |
Intelli | e7a6f21d88 | |
Intelli | 5973206bb3 | |
Intelli | 1e007c98a4 | |
Intelli | df9b478be7 | |
Intelli | 054beb700b | |
Intelli | 47a000a57f | |
Intelli | cde18dc529 | |
asdanjer | d200616fe1 | |
Intelli | e0d65453b6 | |
Intelli | d414db1c0b | |
Intelli | b0469924a7 | |
Intelli | 4e43a42662 | |
Intelli | 7e97e12969 | |
Intelli | d7d53bf9e2 | |
Intelli | b9309482cf | |
Intelli | 410eba5559 | |
ByteExceptionM | 814ae4d9d5 | |
Intelli | d64ec8d911 | |
Intelli | 5d90f25211 | |
Intelli | 7825f61e45 | |
Intelli | 7e49c95832 | |
Intelli | 4b9e69c40f | |
Sofiane H. Djerbi | f2934fd876 | |
Intelli | f706bcf38e | |
Intelli | fe6023450c | |
Intelli | ace870b930 | |
Intelli | 7170e29452 | |
Intelli | 29345e2fb1 | |
Amir | a22db638fa | |
Intelli | de3c326203 | |
Intelli | acb71a83a2 | |
Intelli | 3ffed30b1e | |
Intelli | 5d6fd60d40 | |
Intelli | 20710a00de | |
Intelli | 5eabee6504 | |
Intelli | 97eb0d777b | |
Intelli | 61847f2f8d | |
Intelli | 12f2000085 | |
Intelli | 66e32c02bf | |
Intelli | 9da1343f7f | |
Intelli | 272ecae858 | |
Intelli | 3db2159292 | |
Intelli | 78ef45d049 | |
Intelli | 2f28183261 | |
Intelli | d82f92e06b | |
Intelli | ce5c1c50bf | |
Intelli | 026b9ce322 | |
Intelli | 3cedc69205 | |
Intelli | f4fe410141 | |
Intelli | e3b82858b4 | |
Intelli | 990f90bab9 | |
Ryan Huston | 3b349c9d07 | |
Intelli | 319d104622 | |
Intelli | 9f8c2e8a2f | |
Intelli | fcd789ef5b | |
dkim19375 | b450f4d05a | |
Intelli | 606c043bf0 | |
Intelli | 4b056d9474 | |
Intelli | 1cca7bc573 | |
Intelli | 204456d6c5 | |
Intelli | d34b60dc8f | |
Intelli | 070c5139e1 | |
流光溢彩Last | 1974838f74 | |
Intelli | acdfb3515b | |
vacla | 8cdf99429d | |
Intelli | e848d65b93 | |
Intelli | 85ebd53e5f | |
KrazyxWolf | 209c63b009 | |
Intelli | 8fd41ac231 | |
Intelli | 703d52bcc7 | |
Intelli | aea0c82fd7 | |
Intelli | 01ed2e9f97 | |
Intelli | 5861570f8a | |
Intelli | 840eb3b4ee | |
Intelli | 92e030f3e8 | |
Intelli | d97f5482ee | |
Intelli | 2763952dc6 | |
Intelli | 3011aece46 | |
Intelli | dedba3c57f | |
Intelli | 75f66bf212 | |
Intelli | 64106e2d64 | |
Intelli | 975a030ebe | |
Intelli | 829f4e95d5 | |
Intelli | 96292c82c3 | |
Intelli | dad51fc900 | |
Intelli | 40ee11f644 | |
Intelli | 02dcc873d6 | |
Intelli | 2b96daa422 | |
Intelli | d472879dec | |
EEstar | dbcf79cd46 | |
Intelli | c69ea79329 | |
Intelli | 83fc221bf2 | |
Intelli | 7bc95931d2 | |
Intelli | 2fa5af64ca | |
Intelli | 1be82111ed | |
Intelli | a6869176be | |
Intelli | 7c7fd200d2 | |
Intelli | 6714ded600 | |
Intelli | 6a22903240 | |
Intelli | 0bbeee65e8 | |
Intelli | a596dd66a9 | |
Intelli | 1aaff4e2b0 | |
Intelli | 1c476408e9 | |
Intelli | 5530a89189 | |
Intelli | c69a5a58c0 | |
Intelli | f0702339f2 | |
Intelli | 3774e6748d | |
Intelli | 596a39c965 | |
Intelli | 42c6deff8a | |
Intelli | f5d13f8818 | |
Intelli | 659fe649ed | |
Intelli | 9bdac6db4d | |
Intelli | 42233f1f72 | |
Intelli | 900cad643f | |
Intelli | ddb804ce99 | |
Intelli | 45f9f4316e | |
Intelli | 5494bce0fc | |
Intelli | 30c1921968 | |
Intelli | 262f27da3e | |
Intelli | f9083053b2 | |
Intelli | 3b93046731 | |
Intelli | 4445c3c4a7 | |
Intelli | c95bf3cc30 | |
Intelli | 2a8e4f9797 | |
Intelli | f80c6ab5cd | |
Intelli | b96f47cbac | |
Intelli | 0d7fa2dd59 | |
Intelli | a238045287 | |
Intelli | 167b8dfabd | |
Intelli | d365eb498b | |
Intelli | 585d8b275a | |
Intelli | 527be90249 | |
Intelli | c652ce852f | |
Intelli | fb79071ee7 | |
Intelli | e462e68806 | |
Intelli | 7398f7dfe6 | |
Intelli | eb5b3b5bcc | |
Intelli | abfecda8d0 | |
Intelli | c5d5308753 | |
Intelli | 50689604dd | |
Intelli | 25b03511c2 | |
Intelli | d69d762bf4 | |
Intelli | d9eea32b19 | |
Intelli | a2353afd0a | |
Intelli | 29d55e6ba9 | |
Intelli | 21eefff53f | |
Intelli | b1c2795289 | |
Intelli | fdb98bd329 | |
Intelli | dc359a1be3 | |
Intelli | d5c2b908d3 | |
Intelli | 54da739c1d | |
Intelli | 01e6351194 | |
Intelli | 855a2e5ae2 | |
Intelli | 971de8c078 | |
Intelli | cd8ef0d273 | |
Intelli | 02afc6c530 | |
Intelli | 748490b8f0 | |
Intelli | 40561e41c0 | |
Intelli | 6a978128af | |
Intelli | 635a2b0d95 | |
Intelli | ea69bf0dc5 | |
Intelli | 19efdeff89 | |
Intelli | 673529df54 | |
Intelli | 3a0c86a614 | |
Intelli | 70f74ced0f | |
Intelli | 2c8e289c43 | |
Intelli | b0d14f4d2b | |
Intelli | 29d01a158a | |
Intelli | 67d9f2f832 | |
Intelli | 591110cbb2 | |
Intelli | 286cf2afb9 | |
Intelli | d9f5411e87 | |
Intelli | 19ed0162e5 | |
Intelli | 03bd19480e | |
Intelli | 947c59882e | |
Intelli | 8ed4216c64 | |
Intelli | 64188f5a75 | |
Intelli | 55fec1d092 | |
Intelli | c1eecefa6f | |
Intelli | 204d6c8d5f | |
Intelli | fffe75f1f4 | |
Intelli | 3201a18b16 | |
Intelli | 085e410ab1 | |
Intelli | 4f977d394c | |
Intelli | a4c21ec8f3 | |
Intelli | d7ee5257dd | |
Intelli | 08aeb5d5aa | |
Intelli | c1a4323ce4 |
|
@ -13,11 +13,11 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
- name: Set up JDK 16
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: '16'
|
||||
distribution: 'adopt-hotspot'
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
- name: Cache Maven packages
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
|
|
|
@ -10,7 +10,7 @@ Please note we have a code of conduct, please follow it in all your interactions
|
|||
- For consistency, please only use spaces for indentation.
|
||||
- Use descriptiveCamelCase for variable/method names. Names containing underscore or abbreviations should be changed.
|
||||
- Restrict changes in a commit to a single event or section of code (e.g. refactor BlockBreakEvent and BlockPlaceEvent in separate commits)
|
||||
- Attempt to keep the amount of code modified in a single commit small and readable.
|
||||
- Attempt to keep the amount of code modified in a single pull request small and readable.
|
||||
- Please utilize [SonarLint](https://www.sonarlint.org) in your IDE. Contributions are automatically analyzed.
|
||||
- When adding new functionality, please also be sure to update the documentation as well.
|
||||
- Use common sense. If you have a suggestion for a contribution guideline, post it on Discord.
|
||||
|
@ -148,4 +148,4 @@ at [https://www.contributor-covenant.org/translations][translations].
|
|||
[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
|
||||
[Mozilla CoC]: https://github.com/mozilla/diversity
|
||||
[FAQ]: https://www.contributor-covenant.org/faq
|
||||
[translations]: https://www.contributor-covenant.org/translations
|
||||
[translations]: https://www.contributor-covenant.org/translations
|
||||
|
|
|
@ -11,14 +11,14 @@ CoreProtect
|
|||
|
||||
CoreProtect is a blazing fast data logging and anti-griefing tool for Minecraft servers.
|
||||
|
||||
For a detailed description of the plugin, please visit [spigotmc.org/resources/coreprotect.8631](https://www.spigotmc.org/resources/coreprotect.8631/).
|
||||
For a detailed description of the plugin, please visit [coreprotect.net](https://coreprotect.net).
|
||||
|
||||
| Quick Links | |
|
||||
| --- | --- |
|
||||
| CoreProtect Discord: | [discord.gg/b4DZ4jy](https://discord.gg/b4DZ4jy) |
|
||||
| CoreProtect Patreon: | [patreon.com/coreprotect](https://www.patreon.com/coreprotect) |
|
||||
| CoreProtect Documentation: | [docs.coreprotect.net](https://docs.coreprotect.net) |
|
||||
| Downloads for MC 1.14 - 1.17: | [spigotmc.org/resources/coreprotect.8631](https://www.spigotmc.org/resources/coreprotect.8631/) |
|
||||
| Downloads for MC 1.14 - 1.20: | [coreprotect.net/latest](https://coreprotect.net/latest/) |
|
||||
| Downloads for MC 1.8 - 1.12: | [coreprotect.net/legacy](https://coreprotect.net/legacy/) |
|
||||
|
||||
bStats
|
||||
|
@ -41,7 +41,7 @@ Maven
|
|||
<dependency>
|
||||
<groupId>net.coreprotect</groupId>
|
||||
<artifactId>coreprotect</artifactId>
|
||||
<version>20.0</version>
|
||||
<version>22.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
```
|
||||
|
|
28
build.gradle
28
build.gradle
|
@ -2,16 +2,16 @@ import org.apache.tools.ant.filters.ReplaceTokens
|
|||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'com.github.johnrengelman.shadow' version '6.0.0'
|
||||
id 'com.palantir.git-version' version '0.12.3'
|
||||
id 'com.github.johnrengelman.shadow' version '8.1.1'
|
||||
id 'com.palantir.git-version' version '0.13.0'
|
||||
}
|
||||
|
||||
group = 'net.coreprotect'
|
||||
String projectVersion = '20.2'
|
||||
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 = '1.8'
|
||||
sourceCompatibility = '21'
|
||||
|
||||
if (System.getenv("BUILD_NUMBER") != null) {
|
||||
// Being built in Jenkins, append Build ID
|
||||
|
@ -23,21 +23,18 @@ 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://oss.sonatype.org/content/repositories/snapshots/' }
|
||||
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.sk89q.com/repo/' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly('com.sk89q.worldedit:worldedit-bukkit:7.0.0-SNAPSHOT') {
|
||||
exclude group: 'org.bukkit'
|
||||
}
|
||||
compileOnly 'org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT'
|
||||
implementation(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:4.0.3'
|
||||
implementation 'com.zaxxer:HikariCP:5.0.1'
|
||||
}
|
||||
|
||||
jar {
|
||||
|
@ -53,6 +50,10 @@ shadowJar {
|
|||
// #toString because #getGroup technically returns an Object
|
||||
relocate('org.bstats', project.group.toString())
|
||||
relocate('com.zaxxer', project.group.toString())
|
||||
exclude(dependency('com.google.code.gson:.*'))
|
||||
exclude(dependency('org.intellij:.*'))
|
||||
exclude(dependency('org.jetbrains:.*'))
|
||||
exclude(dependency('org.slf4j:.*'))
|
||||
}
|
||||
archiveClassifier.set(null)
|
||||
}
|
||||
|
@ -86,4 +87,3 @@ processResources {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -4,461 +4,8 @@ The CoreProtect API enables you to log your own block changes, perform lookups,
|
|||
|
||||
| API Details | |
|
||||
| --- | --- |
|
||||
| **API Version:** | 8 |
|
||||
| **Plugin Version:** | v20.2+ |
|
||||
| **API Version:** | 10 |
|
||||
| **Plugin Version:** | v22.4+ |
|
||||
| **Maven:** | [maven.playpro.com](https://maven.playpro.com) |
|
||||
|
||||
*Documentation for the previous API version can be found [here](https://www.minerealm.com/community/viewtopic.php?f=32&t=16687).*
|
||||
|
||||
---
|
||||
|
||||
## Upgrading from API v6
|
||||
|
||||
The changes from the previous API version are as follows:
|
||||
|
||||
- The following methods have been added:
|
||||
```java
|
||||
parseResult(String[] result).getTimestamp()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
- The following methods have been deprecated:
|
||||
```java
|
||||
parseResult(String[] result).getTime()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
- The following methods have been removed:
|
||||
```java
|
||||
parseResult(String[] result).getTypeId()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Started
|
||||
|
||||
Ensure you're using CoreProtect 20.2 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, 20.2).
|
||||
|
||||
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() < 7) {
|
||||
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)
|
||||
|
||||
ParseResult parseResult(String[] result)
|
||||
|
||||
boolean logChat(Player player, String message)
|
||||
|
||||
boolean logCommand(Player player, String command)
|
||||
|
||||
boolean logPlacement(String user, Location location, Material type, BlockData blockData)
|
||||
|
||||
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. Not cancellable.
|
||||
|
||||
| Property | Description | Mutable |
|
||||
| --- | --- | --- |
|
||||
| User | The name of the user under which this action will be logged. | 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.
|
||||
|
||||
---
|
||||
|
||||
#### `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, 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, 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);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
- 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(value);
|
||||
int x = parseResult.getX();
|
||||
int y = parseResult.getY();
|
||||
int z = parseResult.getZ();
|
||||
//...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
- 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();
|
||||
```
|
||||
|
||||
---
|
||||
*Documentation for the API version 10 can be found [here](/api/version/v10/).*
|
|
@ -0,0 +1,99 @@
|
|||
# Networking API
|
||||
|
||||
The CoreProtect Networking API allows clients to receive data using packets.
|
||||
|
||||
| Networking Details | |
|
||||
|-------------------------|--------|
|
||||
| **Networking Version:** | 1 |
|
||||
| **Plugin Version:** | v21.3+ |
|
||||
|
||||
---
|
||||
|
||||
## Packets
|
||||
|
||||
The server will not respond unless the player has the correct permission, which is `coreprotect.networking`.
|
||||
|
||||
---
|
||||
|
||||
## Server to Client
|
||||
|
||||
### Data Packet
|
||||
Sends data from the database.
|
||||
|
||||
* Channel: `coreprotect:data`
|
||||
|
||||
| Type: `Int` | 1 | 2 | 3 | 4 |
|
||||
|-------------|------------------------|------------------------|--------------------|--------------------|
|
||||
| | Time: `long` | Time: `long` | Time: `long` | Time: `long` |
|
||||
| | Phrase selector: `UTF` | Phrase selector: `UTF` | Result User: `UTF` | Result User: `UTF` |
|
||||
| | Result User: `UTF` | Result User: `UTF` | Message: `UTF` | Target: `UTF` |
|
||||
| | Target: `UTF` | Amount: `Int` | Sign: `Boolean` | |
|
||||
| | Amount: `Int` | X: `Int` | X: `Int` | |
|
||||
| | X: `Int` | Y: `Int` | Y: `Int` | |
|
||||
| | Y: `Int` | Z: `Int` | Z: `Int` | |
|
||||
| | Z: `Int` | World name: `UTF` | World name: `UTF` | |
|
||||
| | World name: `UTF` | | | |
|
||||
| | Rolledback: `Boolean` | | | |
|
||||
| | isContainer: `Boolean` | | | |
|
||||
| | Added: `Boolean` | | | |
|
||||
|
||||
Example (Fabric):
|
||||
```
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(buf.getWrittenBytes());
|
||||
DataInputStream dis = new DataInputStream(in);
|
||||
int type = dis.readInt();
|
||||
long time = dis.readLong();
|
||||
String selector = dis.readUTF();
|
||||
String resultUser = dis.readUTF();
|
||||
String target = dis.readUTF();
|
||||
int amount = dis.readInt();
|
||||
int x = dis.readInt();
|
||||
int y = dis.readInt();
|
||||
int z = dis.readInt();
|
||||
String worldName = dis.readUTF();
|
||||
boolean rolledback = dis.readBoolean();
|
||||
boolean isContainer = dis.readBoolean();
|
||||
boolean added = dis.readBoolean();
|
||||
```
|
||||
|
||||
### Handshake Packet
|
||||
Sends handshake if player is registered.
|
||||
|
||||
* Channel: `coreprotect:handshake`
|
||||
* Registered: `Boolean`
|
||||
|
||||
---
|
||||
|
||||
## Client to Server
|
||||
|
||||
### Handshake Packet
|
||||
Sends handshake to register
|
||||
|
||||
* Channel: `coreprotect:handshake`
|
||||
* Mod Version: `UTF`
|
||||
* Mod Id: `UTF`
|
||||
* CoreProtect Protocol: `Int`
|
||||
|
||||
Example (Fabric):
|
||||
```
|
||||
PacketByteBuf packetByteBuf = new PacketByteBuf(Unpooled.buffer());
|
||||
ByteArrayOutputStream msgBytes = new ByteArrayOutputStream();
|
||||
DataOutputStream msgOut = new DataOutputStream(msgBytes);
|
||||
msgOut.writeUTF(modVersion);
|
||||
msgOut.writeUTF(modId);
|
||||
msgOut.writeInt(coreprotectProtocol);
|
||||
packetByteBuf.writeBytes(msgBytes.toByteArray());
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Debugging
|
||||
|
||||
### /co network-debug
|
||||
Allows you to debug the networking API if you are registered and have correct permissions.
|
||||
To utilize the command, `network-debug: true` must be set in the CoreProtect `config.yml`.
|
||||
|
||||
**Example**
|
||||
`/co network-debug <type>`
|
||||
|
||||
___
|
|
@ -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();
|
||||
```
|
||||
|
||||
---
|
|
@ -0,0 +1,450 @@
|
|||
# API Version 7
|
||||
|
||||
The CoreProtect API enables you to log your own block changes, perform lookups, rollbacks, restores, and more.
|
||||
|
||||
| API Details | |
|
||||
| --- | --- |
|
||||
| **API Version:** | 7 |
|
||||
| **Plugin Version:** | v20.0+ |
|
||||
| **Maven:** | [maven.playpro.com](https://maven.playpro.com) |
|
||||
|
||||
<span style="color:red;">*Documentation for the latest API version can be found [here](/api/).*</span>
|
||||
|
||||
---
|
||||
|
||||
## Upgrading from API v6
|
||||
|
||||
The changes from the previous API version are as follows:
|
||||
|
||||
- The following methods have been added:
|
||||
```java
|
||||
parseResult(String[] result).getTimestamp()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
- The following methods have been deprecated:
|
||||
```java
|
||||
parseResult(String[] result).getTime()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
- The following methods have been removed:
|
||||
```java
|
||||
parseResult(String[] result).getTypeId()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Started
|
||||
|
||||
Ensure you're using CoreProtect 20.0 or higher. Add it as an external jar to your plugin in your IDE.
|
||||
Alternatively, if using Maven, you can add it via the repository [https://maven.playpro.com](https://maven.playpro.com) (net.coreprotect, 20.0).
|
||||
|
||||
The first thing you need to do is get access to CoreProtect. You can do this by using code similar to the following:
|
||||
|
||||
```java
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.CoreProtectAPI;
|
||||
|
||||
private CoreProtectAPI getCoreProtect() {
|
||||
Plugin plugin = getServer().getPluginManager().getPlugin("CoreProtect");
|
||||
|
||||
// Check that CoreProtect is loaded
|
||||
if (plugin == null || !(plugin instanceof CoreProtect)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check that the API is enabled
|
||||
CoreProtectAPI CoreProtect = ((CoreProtect) plugin).getAPI();
|
||||
if (CoreProtect.isEnabled() == false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check that a compatible version of the API is loaded
|
||||
if (CoreProtect.APIVersion() < 7) {
|
||||
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)
|
||||
|
||||
ParseResult parseResult(String[] result)
|
||||
|
||||
boolean logChat(Player player, String message)
|
||||
|
||||
boolean logCommand(Player player, String command)
|
||||
|
||||
boolean logPlacement(String user, Location location, Material type, BlockData blockData)
|
||||
|
||||
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)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 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.
|
||||
|
||||
---
|
||||
|
||||
#### `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, 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, 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);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
- 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();
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
- 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();
|
||||
```
|
||||
|
||||
---
|
|
@ -0,0 +1,450 @@
|
|||
# API Version 8
|
||||
|
||||
The CoreProtect API enables you to log your own block changes, perform lookups, rollbacks, restores, and more.
|
||||
|
||||
| API Details | |
|
||||
| --- | --- |
|
||||
| **API Version:** | 8 |
|
||||
| **Plugin Version:** | v20.2+ |
|
||||
| **Maven:** | [maven.playpro.com](https://maven.playpro.com) |
|
||||
|
||||
<span style="color:red;">*Documentation for the latest API version can be found [here](/api/).*</span>
|
||||
|
||||
---
|
||||
|
||||
## Upgrading from API v7
|
||||
|
||||
The changes from the previous API version are as follows:
|
||||
|
||||
- The following events have been added:
|
||||
```java
|
||||
CoreProtectPreLogEvent
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Started
|
||||
|
||||
Ensure you're using CoreProtect 20.2 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, 20.2).
|
||||
|
||||
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() < 8) {
|
||||
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)
|
||||
|
||||
ParseResult parseResult(String[] result)
|
||||
|
||||
boolean logChat(Player player, String message)
|
||||
|
||||
boolean logCommand(Player player, String command)
|
||||
|
||||
boolean logPlacement(String user, Location location, Material type, BlockData blockData)
|
||||
|
||||
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. Not cancellable.
|
||||
|
||||
| Property | Description | Mutable |
|
||||
| --- | --- | --- |
|
||||
| User | The name of the user under which this action will be logged. | 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.
|
||||
|
||||
---
|
||||
|
||||
#### `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, 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, 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);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
- 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();
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
- 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();
|
||||
```
|
||||
|
||||
---
|
|
@ -0,0 +1,504 @@
|
|||
# API Version 9
|
||||
|
||||
The CoreProtect API enables you to log your own block changes, perform lookups, rollbacks, restores, and more.
|
||||
|
||||
| API Details | |
|
||||
| --- | --- |
|
||||
| **API Version:** | 9 |
|
||||
| **Plugin Version:** | v21.0+ |
|
||||
| **Maven:** | [maven.playpro.com](https://maven.playpro.com) |
|
||||
|
||||
---
|
||||
|
||||
## Upgrading from API v8
|
||||
|
||||
The changes from the previous API version are as follows:
|
||||
|
||||
- The following methods have been added:
|
||||
```java
|
||||
sessionLookup(String user, int time)
|
||||
|
||||
queueLookup(Block block)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Started
|
||||
|
||||
Ensure you're using CoreProtect 21.0 or higher. Add it as an external jar to your plugin in your IDE.
|
||||
Alternatively, if using Maven, you can add it via the repository [https://maven.playpro.com](https://maven.playpro.com) (net.coreprotect, 21.0).
|
||||
|
||||
The first thing you need to do is get access to CoreProtect. You can do this by using code similar to the following:
|
||||
|
||||
```java
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.CoreProtectAPI;
|
||||
|
||||
private CoreProtectAPI getCoreProtect() {
|
||||
Plugin plugin = getServer().getPluginManager().getPlugin("CoreProtect");
|
||||
|
||||
// Check that CoreProtect is loaded
|
||||
if (plugin == null || !(plugin instanceof CoreProtect)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check that the API is enabled
|
||||
CoreProtectAPI CoreProtect = ((CoreProtect) plugin).getAPI();
|
||||
if (CoreProtect.isEnabled() == false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check that a compatible version of the API is loaded
|
||||
if (CoreProtect.APIVersion() < 9) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return CoreProtect;
|
||||
}
|
||||
```
|
||||
|
||||
With this code, you can then access the API with a call like the following:
|
||||
|
||||
```java
|
||||
CoreProtectAPI api = getCoreProtect();
|
||||
if (api != null){ // Ensure we have access to the API
|
||||
api.testAPI(); // Will print out "[CoreProtect] API test successful." in the console.
|
||||
}
|
||||
```
|
||||
|
||||
Yay, you're now using the CoreProtect API!
|
||||
|
||||
---
|
||||
|
||||
## API Overview
|
||||
|
||||
### Available Methods
|
||||
|
||||
```java
|
||||
boolean isEnabled()
|
||||
|
||||
void testAPI()
|
||||
|
||||
List<String[]> performLookup(int time, List<String> restrict_users, List<String> exclude_users, List<Object> restrict_blocks, List<Object> exclude_blocks, List<Integer> action_list, int radius, Location radius_location)
|
||||
|
||||
List<String[]> performRollback(int time, List<String> restrict_users, List<String> exclude_users, List<Object> restrict_blocks, List<Object> exclude_blocks, List<Integer> action_list, int radius, Location radius_location)
|
||||
|
||||
List<String[]> performRestore(int time, List<String> restrict_users, List<String> exclude_users, List<Object> restrict_blocks, List<Object> exclude_blocks, List<Integer> action_list, int radius, Location radius_location)
|
||||
|
||||
List<String[]> blockLookup(Block block, int time)
|
||||
|
||||
List<String[]> sessionLookup(String user, int time)
|
||||
|
||||
List<String[]> queueLookup(Block block)
|
||||
|
||||
ParseResult parseResult(String[] result)
|
||||
|
||||
boolean logChat(Player player, String message)
|
||||
|
||||
boolean logCommand(Player player, String command)
|
||||
|
||||
boolean logPlacement(String user, Location location, Material type, BlockData blockData)
|
||||
|
||||
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, 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, 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();
|
||||
```
|
||||
|
||||
---
|
|
@ -15,6 +15,7 @@ ___
|
|||
| [/co purge](#co-purge) | Delete old block data |
|
||||
| [/co reload](#co-reload) | Reload the configuration file |
|
||||
| [/co status](#co-status) | View the plugin status |
|
||||
| [/co consumer](#co-consumer) | Toggle consumer processing |
|
||||
|
||||
### Alias Commands
|
||||
|
||||
|
@ -92,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.
|
||||
|
||||
|
@ -100,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.
|
||||
|
@ -119,6 +124,10 @@ ___
|
|||
Displays the plugin status and version information.
|
||||
___
|
||||
|
||||
### /co consumer
|
||||
Console command to pause or resume consumer queue processing.
|
||||
___
|
||||
|
||||
|
||||
## Parameter Details
|
||||
|
||||
|
@ -128,6 +137,7 @@ ___
|
|||
|
||||
* Example: `u:Notch`
|
||||
* Example: `u:Notch,Intelli`
|
||||
* Example: `u:#fire,#tnt,#creeper,#explosion`
|
||||
|
||||
---
|
||||
|
||||
|
@ -138,7 +148,8 @@ ___
|
|||
|
||||
* Example: `t:2w,5d,7h,2m,10s`
|
||||
* Example: `t:5d2h`
|
||||
* Example: `t:2.50h` *(2 and a half hours)*
|
||||
* Example: `t:1h-2h` *(between one to two hours)*
|
||||
* Example: `t:2.50h` *(two and a half hours)*
|
||||
|
||||
---
|
||||
|
||||
|
@ -171,12 +182,12 @@ ___
|
|||
| `a:container` | items taken from or put in chests |
|
||||
| `a:+container` | items put in chests |
|
||||
| `a:-container` | items taken from chests |
|
||||
| `a:inventory` | items dropped, picked up, deposited, or withdrawn by players |
|
||||
| `a:+inventory` | items picked up or withdrawn by players |
|
||||
| `a:-inventory` | items dropped or deposited by players |
|
||||
| `a:item` | merges `a:container` and `a:inventory` |
|
||||
| `a:+item` | merges `a:+container` and `a:+inventory` |
|
||||
| `a:-item` | merges `a:-container` and `a:-inventory` |
|
||||
| `a:inventory` | items added or removed from player inventories |
|
||||
| `a:+inventory` | items added to player inventories |
|
||||
| `a:-inventory` | items removed from player inventories |
|
||||
| `a:item` | items dropped, thrown, picked up, deposited, or withdrawn by players |
|
||||
| `a:+item` | items picked up or withdrawn by players |
|
||||
| `a:-item` | items dropped, thrown, or deposited by players |
|
||||
| `a:kill` | mobs/animals killed |
|
||||
| `a:session` | player logins/logouts |
|
||||
| `a:+session` | player logins |
|
||||
|
@ -244,6 +255,8 @@ By default, if no radius is specified, a radius of 10 will be applied, restricti
|
|||
*(rollback griefing Notch did in the last hour that is within 20 blocks of you)*
|
||||
* `/co rollback u:Notch t:1h r:#nether`
|
||||
*(rollback griefing Notch did in the last hour ONLY in the Nether)*
|
||||
* `/co rollback u:Notch t:5m a:inventory`
|
||||
*(rollback inventory transactions by Notch in the last 5 minutes)*
|
||||
* `/co rollback t:15m r:30`
|
||||
*(rollback everything done in the last 15 minutes by anyone within 30 blocks of you)*
|
||||
* `/co rollback t:15m r:#worldedit`
|
||||
|
@ -259,6 +272,8 @@ Lookup commands are generally the same as rollback commands. The primary differe
|
|||
*(lookup all diamond ore mined in the last hour)*
|
||||
* `/co lookup u:Notch t:30m a:chat`
|
||||
*(lookup chat messages sent by Notch in the last 30 minutes)*
|
||||
* `/co lookup u:Notch t:3d a:inventory`
|
||||
*(lookup inventory transactions by Notch in the last 3 days)*
|
||||
* `/co lookup u:Notch a:login`
|
||||
*(lookup all logins ever done by Notch)*
|
||||
* `/co lookup u:Notch a:login`
|
||||
|
@ -266,4 +281,4 @@ Lookup commands are generally the same as rollback commands. The primary differe
|
|||
* `/co lookup u:Notch a:username`
|
||||
*(lookup previous usernames used by Notch)*
|
||||
|
||||
___
|
||||
___
|
||||
|
|
|
@ -18,14 +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" and for TNT explosions, 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".*
|
|
@ -4,8 +4,7 @@ For more information about CoreProtect, visit [coreprotect.net](http://coreprote
|
|||
|
||||
## Getting Started
|
||||
|
||||
These documents are still a work in progress.
|
||||
Please be sure to visit the following links for more information.
|
||||
Please visit one of the following links for more information.
|
||||
|
||||
[**CoreProtect Commands**](/commands/)
|
||||
A list of all commands that can be used within CoreProtect.
|
||||
|
@ -13,6 +12,9 @@ A list of all commands that can be used within CoreProtect.
|
|||
[**CoreProtect Permissions**](/permissions/)
|
||||
A list of all permissions that can be used with CoreProtect.
|
||||
|
||||
[**CoreProtect Language Codes**](/languages/)
|
||||
A list of all language codes that can be used with CoreProtect.
|
||||
|
||||
[**CoreProtect API Documentation**](/api/)
|
||||
Log your own block changes, perform lookups, rollbacks, restores, and more.
|
||||
|
||||
|
@ -20,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.
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
# Languages
|
||||
|
||||
Language codes can be entered in `config.yml` for automatic online translation.
|
||||
|
||||
---
|
||||
|
||||
## CoreProtect Language Codes
|
||||
|
||||
| Language | Code |
|
||||
| --- | --- |
|
||||
| Afrikaans | `af` |
|
||||
| Albanian | `sq` |
|
||||
| Amharic | `am` |
|
||||
| Arabic | `ar` |
|
||||
| Armenian | `hy` |
|
||||
| Azerbaijani | `az` |
|
||||
| Basque | `eu` |
|
||||
| Belarusian | `be` |
|
||||
| Bengali | `bn` |
|
||||
| Bosnian | `bs` |
|
||||
| Bulgarian | `bg` |
|
||||
| Catalan | `ca` |
|
||||
| Cebuano | `ceb` |
|
||||
| Chinese (Simplified) | `zh-CN` or `zh` |
|
||||
| Chinese (Traditional) | `zh-TW` |
|
||||
| Corsican | `co` |
|
||||
| Croatian | `hr` |
|
||||
| Czech | `cs` |
|
||||
| Danish | `da` |
|
||||
| Dutch | `nl` |
|
||||
| English | `en` |
|
||||
| Esperanto | `eo` |
|
||||
| Estonian | `et` |
|
||||
| Finnish | `fi` |
|
||||
| French | `fr` |
|
||||
| Frisian | `fy` |
|
||||
| Galician | `gl` |
|
||||
| Georgian | `ka` |
|
||||
| German | `de` |
|
||||
| Greek | `el` |
|
||||
| Gujarati | `gu` |
|
||||
| Haitian Creole | `ht` |
|
||||
| Hausa | `ha` |
|
||||
| Hawaiian | `haw` |
|
||||
| Hebrew | `he` or `iw` |
|
||||
| Hindi | `hi` |
|
||||
| Hmong | `hmn` |
|
||||
| Hungarian | `hu` |
|
||||
| Icelandic | `is` |
|
||||
| Igbo | `ig` |
|
||||
| Indonesian | `id` |
|
||||
| Irish | `ga` |
|
||||
| Italian | `it` |
|
||||
| Japanese | `ja` |
|
||||
| Javanese | `jv` |
|
||||
| Kannada | `kn` |
|
||||
| Kazakh | `kk` |
|
||||
| Khmer | `km` |
|
||||
| Kinyarwanda | `rw` |
|
||||
| Korean | `ko` |
|
||||
| Kurdish | `ku` |
|
||||
| Kyrgyz | `ky` |
|
||||
| Lao | `lo` |
|
||||
| Latin | `la` |
|
||||
| Latvian | `lv` |
|
||||
| Lithuanian | `lt` |
|
||||
| Luxembourgish | `lb` |
|
||||
| Macedonian | `mk` |
|
||||
| Malagasy | `mg` |
|
||||
| Malay | `ms` |
|
||||
| Malayalam | `ml` |
|
||||
| Maltese | `mt` |
|
||||
| Maori | `mi` |
|
||||
| Marathi | `mr` |
|
||||
| Mongolian | `mn` |
|
||||
| Myanmar (Burmese) | `my` |
|
||||
| Nepali | `ne` |
|
||||
| Norwegian | `no` |
|
||||
| Nyanja (Chichewa) | `ny` |
|
||||
| Odia (Oriya) | `or` |
|
||||
| Pashto | `ps` |
|
||||
| Persian | `fa` |
|
||||
| Polish | `pl` |
|
||||
| Portuguese (Portugal, Brazil) | `pt` |
|
||||
| Punjabi | `pa` |
|
||||
| Romanian | `ro` |
|
||||
| Russian | `ru` |
|
||||
| Samoan | `sm` |
|
||||
| Scots Gaelic | `gd` |
|
||||
| Serbian | `sr` |
|
||||
| Sesotho | `st` |
|
||||
| Shona | `sn` |
|
||||
| Sindhi | `sd` |
|
||||
| Sinhala (Sinhalese) | `si` |
|
||||
| Slovak | `sk` |
|
||||
| Slovenian | `sl` |
|
||||
| Somali | `so` |
|
||||
| Spanish | `es` |
|
||||
| Sundanese | `su` |
|
||||
| Swahili | `sw` |
|
||||
| Swedish | `sv` |
|
||||
| Tagalog (Filipino) | `tl` |
|
||||
| Tajik | `tg` |
|
||||
| Tamil | `ta` |
|
||||
| Tatar | `tt` |
|
||||
| Telugu | `te` |
|
||||
| Thai | `th` |
|
||||
| Turkish | `tr` |
|
||||
| Turkmen | `tk` |
|
||||
| Ukrainian | `uk` |
|
||||
| Urdu | `ur` |
|
||||
| Uyghur | `ug` |
|
||||
| Uzbek | `uz` |
|
||||
| Vietnamese | `vi` |
|
||||
| Welsh | `cy` |
|
||||
| Xhosa | `xh` |
|
||||
| Yiddish | `yi` |
|
||||
| Yoruba | `yo` |
|
||||
| Zulu | `zu` |
|
||||
|
||||
*Source: [cloud.google.com/translate](https://cloud.google.com/translate/docs/languages)*
|
||||
|
||||
---
|
|
@ -35,6 +35,12 @@ The following permissions can be used to restrict functionality within the plugi
|
|||
|
||||
* **coreprotect.status** *(default: op)*
|
||||
Allows access to the CoreProtect status command.
|
||||
|
||||
* **coreprotect.consumer** *(default: op)*
|
||||
Allows access to the CoreProtect consumer command.
|
||||
|
||||
* **coreprotect.networking** *(default: op)*
|
||||
Allows access to the CoreProtect networking API.
|
||||
|
||||
---
|
||||
|
||||
|
@ -58,6 +64,9 @@ The following permissions can be used to restrict functionality within the plugi
|
|||
* **coreprotect.lookup.inventory** *(default: op)*
|
||||
Can be optionally used as a negative permission to prevent inventory lookups.
|
||||
|
||||
* **coreprotect.lookup.item** *(default: op)*
|
||||
Can be optionally used as a negative permission to prevent item lookups.
|
||||
|
||||
* **coreprotect.lookup.kill** *(default: op)*
|
||||
Can be optionally used as a negative permission to prevent entity kill lookups.
|
||||
|
||||
|
|
|
@ -14,10 +14,15 @@ Use WorldEdit selections as a radius, and log your WorldEdit changes.
|
|||
|
||||
|
||||
* **CoreProtect-Anti-Xray**
|
||||
Displays how many ores a player has destroyed in a specific time span.
|
||||
Displays how many ores a player has destroyed in a specific time span.
|
||||
[https://dev.bukkit.org/bukkit-plugins/coreprotect-anti-xray/](https://dev.bukkit.org/bukkit-plugins/coreprotect-anti-xray/)
|
||||
|
||||
|
||||
* **CoreProtect TNT**
|
||||
The CoreProtect TNT extension adds logging for TNT and creeper explosion sources.
|
||||
[https://www.spigotmc.org/resources/coreprotect-tnt-log-tnt-creeper-explode-source.69609/](https://www.spigotmc.org/resources/coreprotect-tnt-log-tnt-creeper-explode-source.69609/)
|
||||
|
||||
|
||||
## Tools
|
||||
|
||||
* **CoreProtect Lookup Web Interface**
|
||||
|
@ -36,4 +41,4 @@ Watson is a client side Minecraft mod that displays CoreProtect logs in 3D.
|
|||
Have you created a plugin that's compatible with CoreProtect?
|
||||
Let us know to have it added to this list!
|
||||
|
||||
---
|
||||
---
|
||||
|
|
12
lang/de.yml
12
lang/de.yml
|
@ -9,8 +9,11 @@ API_TEST: "API-Test erfolgreich."
|
|||
CACHE_ERROR: "WARNUNG: Fehler beim Validieren {0} Zwischenspeicher."
|
||||
CACHE_RELOAD: "Erzwingen des Nachladens von {kartierung|welt} Caches aus der Datenbank."
|
||||
CHECK_CONFIG: "Bitte überprüfen Sie config.yml"
|
||||
COMMAND_CONSOLE: "Bitte führen Sie den Befehl von der Konsole aus."
|
||||
COMMAND_NOT_FOUND: "Befehl \"{0}\" nicht gefunden."
|
||||
COMMAND_THROTTLED: "Bitte warten Sie einen Moment und versuchen Sie es erneut."
|
||||
CONSUMER_ERROR: "Verbraucherwarteschlange wird bereits verarbeitet {angehalten|fortgesetzt}."
|
||||
CONSUMER_TOGGLED: "Die Verarbeitung der Verbraucherwarteschlange wurde durchgeführt {angehalten|fortgesetzt}."
|
||||
CONTAINER_HEADER: "Containertransaktionen"
|
||||
DATABASE_BUSY: "Datenbank beschäftigt. Bitte versuchen Sie es später erneut."
|
||||
DATABASE_INDEX_ERROR: "Datenbankindizes können nicht validiert werden."
|
||||
|
@ -101,19 +104,19 @@ LINK_WIKI_BLOCK: "Blocknamen: {0}"
|
|||
LINK_WIKI_ENTITY: "Entitätsnamen: {0}"
|
||||
LOGGING_ITEMS: "{0} Elemente, die noch zu loggen sind. Warten Sie mal..."
|
||||
LOGGING_TIME_LIMIT: "Zeitlimit für die Protokollierung erreicht. Daten verwerfen und herunterfahren."
|
||||
LOOKUP_BLOCK: "{0} {platziert|kaputt} {1}."
|
||||
LOOKUP_BLOCK: "{0} {platziert|entfernt} {1}."
|
||||
LOOKUP_CONTAINER: "{0} {hinzugefügt|entfernt} {1} {2}."
|
||||
LOOKUP_HEADER: "{0} Ergebnisse"
|
||||
LOOKUP_INTERACTION: "{0} {angeklickt|getötet} {1}."
|
||||
LOOKUP_ITEM: "{0} {abgeholt|abgeworfen} {1} {2}."
|
||||
LOOKUP_LOGIN: "{0} eingeloggt {rein|raus}."
|
||||
LOOKUP_PAGE: "Seite {0}"
|
||||
LOOKUP_PROJECTILE: "{0} {geworfen|geschossen} {1} {2}."
|
||||
LOOKUP_ROWS_FOUND: "{0} {Reihe|Reihen} gefunden."
|
||||
LOOKUP_SEARCHING: "Suche nachschlagen. Warten Sie mal..."
|
||||
LOOKUP_STORAGE: "{0} {hinterlegt|abgehoben} {1} {2}."
|
||||
LOOKUP_TIME: "{0} vor"
|
||||
LOOKUP_USERNAME: "{0} Eingeloggt als {1}."
|
||||
LOOKUP_VIEW_PAGE: "Um eine Seite anzuzeigen, geben Sie \"{0}\"."
|
||||
MAXIMUM_RADIUS: "Das Maximum {Nachschlagen|Rollback|Wiederherstellen} Radius ist {0}."
|
||||
MISSING_ACTION_USER: "Um diese Aktion zu verwenden, geben Sie bitte einen Benutzer an."
|
||||
MISSING_LOOKUP_TIME: "Bitte geben Sie die Zeit an, um {Nachschlagen|Rollback|Wiederherstellen}."
|
||||
|
@ -139,8 +142,8 @@ PATCH_UPGRADING: "Datenbank-Upgrade im Gange. Warten Sie mal..."
|
|||
PLEASE_SELECT: "Bitte auswählen: \"{0}\" oder \"{1}\"."
|
||||
PREVIEW_CANCELLED: "Vorschau abgebrochen."
|
||||
PREVIEW_CANCELLING: "Vorschau abbrechen..."
|
||||
PREVIEW_CONTAINER: "Sie können keine Containertransaktionen in der Vorschau anzeigen."
|
||||
PREVIEW_IN_GAME: "Sie können Rollbacks nur im Spiel in der Vorschau anzeigen."
|
||||
PREVIEW_TRANSACTION: "Sie können keine Vorschau anzeigen {Behälter|Inventar} Transaktionen."
|
||||
PURGE_ABORTED: "Bereinigung fehlgeschlagen. Die Datenbank ist möglicherweise beschädigt."
|
||||
PURGE_ERROR: "Kann nicht verarbeitet werden {0} Daten!"
|
||||
PURGE_FAILED: "Bereinigung fehlgeschlagen. Bitte versuchen Sie es später erneut."
|
||||
|
@ -189,9 +192,10 @@ UPDATE_HEADER: "{0} Aktualisieren"
|
|||
UPDATE_NOTICE: "Beachten: {0} ist nun verfügbar."
|
||||
UPGRADE_IN_PROGRESS: "Upgrade läuft. Bitte versuchen Sie es später erneut."
|
||||
USER_NOT_FOUND: "Benutzer \"{0}\" nicht gefunden."
|
||||
USER_OFFLINE: "Der Benutzer \"{0}\" ist nicht online."
|
||||
USING_MYSQL: "Verwenden von MySQL zur Datenspeicherung."
|
||||
USING_SQLITE: "Verwenden von SQLite zur Datenspeicherung."
|
||||
VALID_DONATION_KEY: "Gültiger Spendenschlüssel."
|
||||
VERSION_NOTICE: "Ausführung {0} ist nun verfügbar."
|
||||
VERSION_REQUIRED: "{0} {1} oder höher erforderlich."
|
||||
WORLD_NOT_FOUND: "Welt \"{0}\" nicht gefunden."
|
||||
WORLD_NOT_FOUND: "Welt \"{0}\" nicht gefunden."
|
||||
|
|
10
lang/en.yml
10
lang/en.yml
|
@ -9,8 +9,11 @@ API_TEST: "API test successful."
|
|||
CACHE_ERROR: "WARNING: Error while validating {0} cache."
|
||||
CACHE_RELOAD: "Forcing reload of {mapping|world} caches from database."
|
||||
CHECK_CONFIG: "Please check config.yml"
|
||||
COMMAND_CONSOLE: "Please run the command from the console."
|
||||
COMMAND_NOT_FOUND: "Command \"{0}\" not found."
|
||||
COMMAND_THROTTLED: "Please wait a moment and try again."
|
||||
CONSUMER_ERROR: "Consumer queue processing already {paused|resumed}."
|
||||
CONSUMER_TOGGLED: "Consumer queue processing has been {paused|resumed}."
|
||||
CONTAINER_HEADER: "Container Transactions"
|
||||
DATABASE_BUSY: "Database busy. Please try again later."
|
||||
DATABASE_INDEX_ERROR: "Unable to validate database indexes."
|
||||
|
@ -108,12 +111,12 @@ LOOKUP_INTERACTION: "{0} {clicked|killed} {1}."
|
|||
LOOKUP_ITEM: "{0} {picked up|dropped} {1} {2}."
|
||||
LOOKUP_LOGIN: "{0} logged {in|out}."
|
||||
LOOKUP_PAGE: "Page {0}"
|
||||
LOOKUP_PROJECTILE: "{0} {threw|shot} {1} {2}."
|
||||
LOOKUP_ROWS_FOUND: "{0} {row|rows} found."
|
||||
LOOKUP_SEARCHING: "Lookup searching. Please wait..."
|
||||
LOOKUP_STORAGE: "{0} {deposited|withdrew} {1} {2}."
|
||||
LOOKUP_TIME: "{0} ago"
|
||||
LOOKUP_USERNAME: "{0} logged in as {1}."
|
||||
LOOKUP_VIEW_PAGE: "To view a page, type \"{0}\"."
|
||||
MAXIMUM_RADIUS: "The maximum {lookup|rollback|restore} radius is {0}."
|
||||
MISSING_ACTION_USER: "To use that action, please specify a user."
|
||||
MISSING_LOOKUP_TIME: "Please specify the amount of time to {lookup|rollback|restore}."
|
||||
|
@ -122,6 +125,8 @@ MISSING_PARAMETERS: "Please use \"{0}\"."
|
|||
MISSING_ROLLBACK_RADIUS: "You did not specify a {rollback|restore} radius."
|
||||
MISSING_ROLLBACK_USER: "You did not specify a {rollback|restore} user."
|
||||
MYSQL_UNAVAILABLE: "Unable to connect to MySQL server."
|
||||
NETWORK_CONNECTION: "Connection by {0} {successful|failed}. Using {1} {2}."
|
||||
NETWORK_TEST: "Network test data has been successful sent."
|
||||
NO_DATA: "No data found at {0}."
|
||||
NO_DATA_LOCATION: "No {data|transactions|interactions|messages} found at this location."
|
||||
NO_PERMISSION: "You do not have permission to do that."
|
||||
|
@ -139,8 +144,8 @@ PATCH_UPGRADING: "Database upgrade in progress. Please wait..."
|
|||
PLEASE_SELECT: "Please select: \"{0}\" or \"{1}\"."
|
||||
PREVIEW_CANCELLED: "Preview cancelled."
|
||||
PREVIEW_CANCELLING: "Cancelling preview..."
|
||||
PREVIEW_CONTAINER: "You can't preview container transactions."
|
||||
PREVIEW_IN_GAME: "You can only preview rollbacks in-game."
|
||||
PREVIEW_TRANSACTION: "You can't preview {container|inventory} transactions."
|
||||
PURGE_ABORTED: "Purge failed. Database may be corrupt."
|
||||
PURGE_ERROR: "Unable to process {0} data!"
|
||||
PURGE_FAILED: "Purge failed. Please try again later."
|
||||
|
@ -189,6 +194,7 @@ UPDATE_HEADER: "{0} Update"
|
|||
UPDATE_NOTICE: "Notice: {0} is now available."
|
||||
UPGRADE_IN_PROGRESS: "Upgrade in progress. Please try again later."
|
||||
USER_NOT_FOUND: "User \"{0}\" not found."
|
||||
USER_OFFLINE: "The user \"{0}\" is not online."
|
||||
USING_MYSQL: "Using MySQL for data storage."
|
||||
USING_SQLITE: "Using SQLite for data storage."
|
||||
VALID_DONATION_KEY: "Valid donation key."
|
||||
|
|
330
lang/es.yml
330
lang/es.yml
|
@ -1,197 +1,201 @@
|
|||
# CoreProtect Language File (es)
|
||||
|
||||
ACTION_NOT_SUPPORTED: "Esa acción no es compatible."
|
||||
ACTION_NOT_SUPPORTED: "Está acción no es compatible con el comando."
|
||||
AMOUNT_BLOCK: "{0} {bloque|bloques}"
|
||||
AMOUNT_CHUNK: "{0} {trozo|trozos}"
|
||||
AMOUNT_CHUNK: "{0} {chunk|chunks}"
|
||||
AMOUNT_ENTITY: "{0} {entidad|entidades}"
|
||||
AMOUNT_ITEM: "{0} {artículo|artículos}"
|
||||
API_TEST: "Prueba de API exitosa."
|
||||
CACHE_ERROR: "ADVERTENCIA: Error al validar {0} cache."
|
||||
CACHE_RELOAD: "Forzando la recarga de {mapeo|mundo} cachés de la base de datos."
|
||||
CHECK_CONFIG: "Por favor revise config.yml"
|
||||
COMMAND_NOT_FOUND: "Comando \"{0}\" extraviado."
|
||||
COMMAND_THROTTLED: "Espere un momento y vuelva a intentarlo."
|
||||
CONTAINER_HEADER: "Transacciones de contenedores"
|
||||
DATABASE_BUSY: "Base de datos ocupado. Por favor, inténtelo de nuevo más tarde."
|
||||
DATABASE_INDEX_ERROR: "No se pueden validar los índices de la base de datos."
|
||||
DATABASE_LOCKED_1: "Base de datos bloqueada. Esperando hasta 15 segundos..."
|
||||
DATABASE_LOCKED_2: "La base de datos ya está en uso. Inténtalo de nuevo."
|
||||
DATABASE_LOCKED_3: "Para deshabilitar el bloqueo de la base de datos, establezca \"database-lock: false\"."
|
||||
DATABASE_LOCKED_4: "La desactivación del bloqueo de la base de datos puede provocar daños en los datos."
|
||||
DATABASE_UNREACHABLE: "La base de datos es inalcanzable. Descartando datos y cerrando."
|
||||
DEVELOPMENT_BRANCH: "Se detectó una rama de desarrollo, omitiendo los scripts de parches."
|
||||
DIRT_BLOCK: "Colocó un bloque de tierra debajo de usted."
|
||||
DISABLE_SUCCESS: "¡Éxito! Discapacitado {0}"
|
||||
ENABLE_FAILED: "{0} fue incapaz de comenzar."
|
||||
ENABLE_SUCCESS: "{0} ahora está habilitado!"
|
||||
ENJOY_COREPROTECT: "Disfrutar {0}? Únete a nuestro Discord!"
|
||||
FINISHING_CONVERSION: "Terminando la conversión de datos. Espere por favor..."
|
||||
FINISHING_LOGGING: "Terminando el registro de datos. Espere por favor..."
|
||||
FIRST_VERSION: "DB inicial: {0}"
|
||||
GLOBAL_LOOKUP: "No especifique un radio para realizar una búsqueda global."
|
||||
GLOBAL_ROLLBACK: "Usar \"{0}\" para hacer un global {deshacer|restaurar}"
|
||||
HELP_ACTION_1: "Restrinja la búsqueda a una acción."
|
||||
AMOUNT_ITEM: "{0} {objeto|objetos}"
|
||||
API_TEST: "Testeo de la API exitosa."
|
||||
CACHE_ERROR: "ADVERTENCIA: Error mientras se validaba el caché {0}."
|
||||
CACHE_RELOAD: "Forzando recarga de cachés desde la base de datos de {mapeado|mundo}."
|
||||
CHECK_CONFIG: "Por favor revise su config.yml"
|
||||
COMMAND_CONSOLE: "Intente ejecutar el comando desde la consola."
|
||||
COMMAND_NOT_FOUND: "Comando \"{0}\" no encontrado."
|
||||
COMMAND_THROTTLED: "Espere un momento e intente nuevamente."
|
||||
CONSUMER_ERROR: "La espera en el procesamiento del consumidor ha sido {pausada|continuada}."
|
||||
CONSUMER_TOGGLED: "Consumer queue processing has been {pausado|continuado}."
|
||||
CONTAINER_HEADER: "Transacciones del contenedor"
|
||||
DATABASE_BUSY: "Base de datos ocupada. Intente más tarde."
|
||||
DATABASE_INDEX_ERROR: "Imposible validar los indices de la base de datos."
|
||||
DATABASE_LOCKED_1: "Base de datos bloqueada. Espere en los siguientes 15 segundos..."
|
||||
DATABASE_LOCKED_2: "Base de datos ya en uso. Intente nuevamente."
|
||||
DATABASE_LOCKED_3: "Para desactivar el bloqueo de la base de datos, coloque \"database-lock: false\"."
|
||||
DATABASE_LOCKED_4: "Desactivando el bloqueo en la base de datos resultaría en una posible corrupción de datos."
|
||||
DATABASE_UNREACHABLE: "No se pudo alcanzar la base de datos. Descartando datos y apagando."
|
||||
DEVELOPMENT_BRANCH: "Rama de desarrollo detectada, saltando scripts de parche."
|
||||
DIRT_BLOCK: "Se ha colocado un bloque de tierra debajo de tí."
|
||||
DISABLE_SUCCESS: "¡Se ha desactivado exitosamente {0}!"
|
||||
ENABLE_FAILED: "Imposible de iniciar {0}."
|
||||
ENABLE_SUCCESS: "¡{0} ha sido exitosamente activado!"
|
||||
ENJOY_COREPROTECT: "¿Disfrutando {0}? ¡Ingrese a nuestro Discord!"
|
||||
FINISHING_CONVERSION: "Terminando la conversión de datos. Espere..."
|
||||
FINISHING_LOGGING: "Terminando el registro de datos. Espere..."
|
||||
FIRST_VERSION: "Base de datos inicial: {0}"
|
||||
GLOBAL_LOOKUP: "No especificaste el radio para una busqueda global."
|
||||
GLOBAL_ROLLBACK: "Usa \"{0}\" para hacer un {respaldo|restauración} global"
|
||||
HELP_ACTION_1: "Restringir la busqueda a una acción."
|
||||
HELP_ACTION_2: "Ejemplos: [a:block], [a:+block], [a:-block] [a:click], [a:container], [a:inventory], [a:item], [a:kill], [a:chat], [a:command], [a:sign], [a:session], [a:username]"
|
||||
HELP_COMMAND: "Muestra información adicional."
|
||||
HELP_EXCLUDE_1: "Excluir bloques / usuarios."
|
||||
HELP_COMMAND: "Mostrar información sobre un comando."
|
||||
HELP_EXCLUDE_1: "Excluir bloques/usuarios."
|
||||
HELP_EXCLUDE_2: "Ejemplos: [e:stone], [e:Notch], [e:stone,Notch]"
|
||||
HELP_HEADER: "{0} Ayudar"
|
||||
HELP_INCLUDE_1: "Incluya bloques / entidades."
|
||||
HELP_HEADER: "Ayuda {0}"
|
||||
HELP_INCLUDE_1: "Incluir bloques/entidades exactos."
|
||||
HELP_INCLUDE_2: "Ejemplos: [i:stone], [i:zombie], [i:stone,wood,bedrock]"
|
||||
HELP_INSPECT_1: "Con el inspector habilitado, puede:"
|
||||
HELP_INSPECT_2: "Haga clic con el botón izquierdo para ver la ubicación."
|
||||
HELP_INSPECT_3: "Haga clic derecho para ver las eliminaciones adyacentes."
|
||||
HELP_INSPECT_4: "Coloque un bloque para ver la eliminación."
|
||||
HELP_INSPECT_5: "Coloque un bloque en líquido para ver la ubicación."
|
||||
HELP_INSPECT_6: "Haga clic derecho para ver las transacciones del cofre."
|
||||
HELP_INSPECT_7: "Sugerencia: puede usar solo \"/co i\"."
|
||||
HELP_INSPECT_COMMAND: "Alterna el inspector de bloques."
|
||||
HELP_INSPECT_1: "Con el inspeccionador activo, puedes hacer lo siguiente:"
|
||||
HELP_INSPECT_2: "Clic izquierdo para ver quien colocó ese bloque."
|
||||
HELP_INSPECT_3: "Clic derecho para ver quien rompió el bloque de encima."
|
||||
HELP_INSPECT_4: "Coloca un bloque para ver si se ha roto alguno en la zona."
|
||||
HELP_INSPECT_5: "Coloca el bloque en un liquido (etc) para ver quien lo colocó."
|
||||
HELP_INSPECT_6: "Clic derecho sobre un cofres y ver sus transacciones."
|
||||
HELP_INSPECT_7: "Consejo: Puedes usar \"/co i\" para un acceso rápido."
|
||||
HELP_INSPECT_COMMAND: "Alterna el revisor de bloques."
|
||||
HELP_LIST: "Muestra una lista de todos los comandos."
|
||||
HELP_LOOKUP_1: "Atajo de comando."
|
||||
HELP_LOOKUP_2: "Ver páginas adicionales."
|
||||
HELP_LOOKUP_COMMAND: "Búsqueda de datos de bloques."
|
||||
HELP_NO_INFO: "Información para el mando \"{0}\" extraviado."
|
||||
HELP_PARAMETER: "Por favor mira \"{0}\" para obtener información detallada sobre los parámetros."
|
||||
HELP_PARAMS_1: "Realizar el {buscar|deshacer|restaurar}."
|
||||
HELP_PARAMS_2: "Especifique los usuarios para {buscar|deshacer|restaurar}."
|
||||
HELP_PARAMS_3: "Especifique el tiempo para {buscar|deshacer|restaurar}."
|
||||
HELP_PARAMS_4: "Restringir el {buscar|deshacer|restaurar} a un radio."
|
||||
HELP_PARAMS_5: "Restringir el {buscar|deshacer|restaurar} a una acción."
|
||||
HELP_PARAMS_6: "Incluir bloques / entidades en el {buscar|deshacer|restaurar}."
|
||||
HELP_PARAMS_7: "Excluir bloques / usuarios del {buscar|deshacer|restaurar}."
|
||||
HELP_PURGE_1: "Eliminar datos antiguos."
|
||||
HELP_PURGE_2: "Por ejemplo, \"{0}\" eliminará todos los datos anteriores a un mes y solo conservará los datos de los últimos 30 días."
|
||||
HELP_PURGE_COMMAND: "Elimina los datos del bloque antiguo."
|
||||
HELP_RADIUS_1: "Especifique un área de radio."
|
||||
HELP_RADIUS_2: "Ejemplos: [r:10] (Solo haga cambios dentro de las 10 cuadras de usted)"
|
||||
HELP_RELOAD_COMMAND: "Vuelve a cargar el archivo de configuración."
|
||||
HELP_RESTORE_COMMAND: "Restaurar los datos del bloque."
|
||||
HELP_ROLLBACK_COMMAND: "Revertir los datos del bloque."
|
||||
HELP_STATUS: "Ver el estado del complemento."
|
||||
HELP_STATUS_COMMAND: "Muestra el estado del complemento."
|
||||
HELP_TELEPORT: "Teletransportarse."
|
||||
HELP_TIME_1: "Especifique la hora."
|
||||
HELP_LOOKUP_1: "Atajo de comandos."
|
||||
HELP_LOOKUP_2: "Mostrar páginas adicionales."
|
||||
HELP_LOOKUP_COMMAND: "Busqueda de bloques avanzada."
|
||||
HELP_NO_INFO: "Información para el comando \"{0}\" no encontrada."
|
||||
HELP_PARAMETER: "Revisa \"{0}\" para una información más detallada."
|
||||
HELP_PARAMS_1: "Ingrese la {búsqueda|respaldo|restauración}."
|
||||
HELP_PARAMS_2: "Especifique al usuario a {buscar|respaldar|restaurar}."
|
||||
HELP_PARAMS_3: "Especifique la cantidad de tiempo a {buscar|respaldar|restaurar}."
|
||||
HELP_PARAMS_4: "Especifique el radio de area a {buscar|respaldar|restaurar}."
|
||||
HELP_PARAMS_5: "Restringir la {búsqueda|respaldo|restauración} a una acción dada."
|
||||
HELP_PARAMS_6: "Incluir bloques/entidades exactas a {buscar|respaldar|restaurar}."
|
||||
HELP_PARAMS_7: "Excluir bloques/usuarios a {buscar|respaldar|resturar}."
|
||||
HELP_PURGE_1: "Eliminar los datos en un tiempo dado."
|
||||
HELP_PURGE_2: "Por ejemplo, \"{0}\" eliminará los datos que sean más viejos, y solo mantendrá lo que está en los 30d."
|
||||
HELP_PURGE_COMMAND: "Elimina los datos de bloques viejos."
|
||||
HELP_RADIUS_1: "Especifica un radio del area."
|
||||
HELP_RADIUS_2: "Ejemplos: [r:10] (Solo cambiará 10 bloques delante de ti)"
|
||||
HELP_RELOAD_COMMAND: "Recarga los archivos de configuración."
|
||||
HELP_RESTORE_COMMAND: "Restaurar los datos de bloques."
|
||||
HELP_ROLLBACK_COMMAND: "Restaurar bloques."
|
||||
HELP_STATUS: "Muestra el estado del plugin y su información."
|
||||
HELP_STATUS_COMMAND: "Muestra el estado del plugin."
|
||||
HELP_TELEPORT: "Teletransportar a una coordenada."
|
||||
HELP_TIME_1: "Especifique una cantidad de tiempo."
|
||||
HELP_TIME_2: "Ejemplos: [t:2w,5d,7h,2m,10s], [t:5d2h], [t:2.50h]"
|
||||
HELP_USER_1: "Especifique los usuarios."
|
||||
HELP_USER_1: "Especifica al usuario para buscar."
|
||||
HELP_USER_2: "Ejemplos: [u:Notch], [u:Notch,#enderman]"
|
||||
INCOMPATIBLE_ACTION: "\"{0}\" no se puede utilizar con esa acción."
|
||||
INSPECTOR_ERROR: "Inspector ya {habilitado|deshabilitado}."
|
||||
INSPECTOR_TOGGLED: "Inspector ahora {habilitado|deshabilitado}."
|
||||
INTEGRATION_ERROR: "Incapaz de {inicializar|deshabilitar} {0} Inicio sesión."
|
||||
INTEGRATION_SUCCESS: "{0} registrando exitosamente {inicializado|deshabilitado}."
|
||||
INTEGRATION_VERSION: "Inválido {0} versión encontrada."
|
||||
INCOMPATIBLE_ACTION: "\"{0}\" no puede ser usado para esta acción."
|
||||
INSPECTOR_ERROR: "Inspeccionador ya {activado|desactivado}."
|
||||
INSPECTOR_TOGGLED: "Inspeccionador {activado|desactivado}."
|
||||
INTEGRATION_ERROR: "Imposible {inicializar|desactivar} los registros {0}."
|
||||
INTEGRATION_SUCCESS: "Registros en {0} han sido correctamente {inicializados|desactivados}."
|
||||
INTEGRATION_VERSION: "Versión inválida {0} encontrada."
|
||||
INTERACTIONS_HEADER: "Interacciones del jugador"
|
||||
INVALID_ACTION: "Esa no es una acción válida."
|
||||
INVALID_BRANCH_1: "Versión de complemento no válida (la rama no se ha configurado)."
|
||||
INVALID_BRANCH_2: "Para continuar, establezca la rama del proyecto en \"desarrollo\"."
|
||||
INVALID_BRANCH_3: "La ejecución de código de desarrollo puede provocar daños en los datos."
|
||||
INVALID_CONTAINER: "Primero inspeccione un contenedor válido."
|
||||
INVALID_DONATION_KEY: "Clave de donación no válida."
|
||||
INVALID_INCLUDE: "\"{0}\" es un valor no válido."
|
||||
INVALID_INCLUDE_COMBO: "Esa es una combinación de tipos no válida."
|
||||
INVALID_RADIUS: "Ingrese un radio válido."
|
||||
INVALID_SELECTION: "{0} selección no encontrada."
|
||||
INVALID_USERNAME: "\"{0}\" es un nombre de usuario no válido."
|
||||
INVALID_ACTION: "No es una acción válida."
|
||||
INVALID_BRANCH_1: "Versión del plugin inválida (la rama no ha sido definida)."
|
||||
INVALID_BRANCH_2: "Para continuar, coloque la rama del proyecto a \"development\"."
|
||||
INVALID_BRANCH_3: "Ejecutar códigos en desarrollo puede resultar en una corrupción de datos."
|
||||
INVALID_CONTAINER: "Intente inspeccionar un contenedor válido primero."
|
||||
INVALID_DONATION_KEY: "Clave de donación inválida."
|
||||
INVALID_INCLUDE: "\"{0}\" es un bloque inválido/ o nombre de entidad."
|
||||
INVALID_INCLUDE_COMBO: "Es una combinación inválida de bloque/entidad."
|
||||
INVALID_RADIUS: "Coloque un radio válido."
|
||||
INVALID_SELECTION: "{0} sección no encontrada."
|
||||
INVALID_USERNAME: "\"{0}\" no es usuario existente."
|
||||
INVALID_WORLD: "Especifique un mundo válido."
|
||||
LATEST_VERSION: "Última versión: {0}"
|
||||
LINK_DISCORD: "Discord: {0}"
|
||||
LINK_DOWNLOAD: "Descargar: {0}"
|
||||
LINK_DOWNLOAD: "Descarga: {0}"
|
||||
LINK_PATREON: "Patreon: {0}"
|
||||
LINK_WIKI_BLOCK: "Nombres de bloque: {0}"
|
||||
LINK_WIKI_BLOCK: "Nombres de bloques: {0}"
|
||||
LINK_WIKI_ENTITY: "Nombres de entidades: {0}"
|
||||
LOGGING_ITEMS: "{0} elementos que quedan por registrar. Espere por favor..."
|
||||
LOGGING_TIME_LIMIT: "Se alcanzó el límite de tiempo de registro. Descartando datos y cerrando."
|
||||
LOOKUP_BLOCK: "{0} {colocado|roto} {1}."
|
||||
LOOKUP_CONTAINER: "{0} {añadido|eliminado} {1} {2}."
|
||||
LOGGING_ITEMS: "{0} objetos restantes por registrar. Espere un momento..."
|
||||
LOGGING_TIME_LIMIT: "Limite de tiempo de registros. Descartamdo pérdida de información."
|
||||
LOOKUP_BLOCK: "{0} {colocó|rompió} {1}."
|
||||
LOOKUP_CONTAINER: "{0} {agregó|removió} {1} {2}."
|
||||
LOOKUP_HEADER: "{0} Resultados"
|
||||
LOOKUP_INTERACTION: "{0} {clickeado|muerto} {1}."
|
||||
LOOKUP_ITEM: "{0} {recogido|caído} {1} {2}."
|
||||
LOOKUP_LOGIN: "{0} registrado {adentro|afuera}."
|
||||
LOOKUP_INTERACTION: "{0} {clickeó|mató} {1}."
|
||||
LOOKUP_ITEM: "{0} {recogió|soltó} {1} {2}."
|
||||
LOOKUP_LOGIN: "{0} ha {entrado|salido}."
|
||||
LOOKUP_PAGE: "Página {0}"
|
||||
LOOKUP_ROWS_FOUND: "{0} {fila|filas} encontró."
|
||||
LOOKUP_SEARCHING: "Búsqueda de búsqueda. Espere por favor..."
|
||||
LOOKUP_STORAGE: "{0} {depositado|retirado} {1} {2}."
|
||||
LOOKUP_TIME: "{0} atrás"
|
||||
LOOKUP_USERNAME: "{0} Conectado como {1}."
|
||||
LOOKUP_VIEW_PAGE: "Para ver una página, escriba \"{0}\"."
|
||||
MAXIMUM_RADIUS: "El maximo {buscar|deshacer|restaurar} el radio es {0}."
|
||||
MISSING_ACTION_USER: "Para utilizar esa acción, especifique un usuario."
|
||||
MISSING_LOOKUP_TIME: "Por favor, especifique el tiempo para {buscar|deshacer|restaurar}."
|
||||
MISSING_LOOKUP_USER: "Especifique un usuario o {bloque|radio}."
|
||||
MISSING_PARAMETERS: "Por favor use \"{0}\"."
|
||||
MISSING_ROLLBACK_RADIUS: "No especificó un {deshacer|restaurar} radio."
|
||||
MISSING_ROLLBACK_USER: "No especificó un {deshacer|restaurar} usuario."
|
||||
MYSQL_UNAVAILABLE: "Incapaz de conectarse a MySQL servidor."
|
||||
NO_DATA: "No se encontraron datos en {0}."
|
||||
NO_DATA_LOCATION: "No {datos|transacciones|interacciones|mensajes} encontró."
|
||||
NO_PERMISSION: "No tienes permiso para hacer eso."
|
||||
NO_RESULTS: "No se han encontrado resultados."
|
||||
NO_RESULTS_PAGE: "No {resultados|datos} encontrado para esa página."
|
||||
NO_ROLLBACK: "No {pendiente|anterior} deshacer / restaurar encontrado."
|
||||
PATCH_INTERRUPTED: "Actualización interrumpida. Intentará de nuevo al reiniciar."
|
||||
PATCH_OUTDATED_1: "No se pueden actualizar las bases de datos anteriores a {0}."
|
||||
PATCH_OUTDATED_2: "Actualice con una versión compatible de CoreProtect."
|
||||
PATCH_PROCESSING: "Procesando nuevos datos. Espere por favor..."
|
||||
PATCH_SKIP_UPDATE: "Salto a la comba {tabla|índice} {actualización|creación|eliminación} en {0}."
|
||||
PATCH_STARTED: "Ejecutando {0} potenciar. Espere por favor..."
|
||||
PATCH_SUCCESS: "Actualizado con éxito a {0}."
|
||||
PATCH_UPGRADING: "Actualización de la base de datos en curso. Espere por favor..."
|
||||
LOOKUP_PROJECTILE: "{0} {tiró|disparó} {1} {2}."
|
||||
LOOKUP_ROWS_FOUND: "{0} {fila|filas} encontradas."
|
||||
LOOKUP_SEARCHING: "Busqueda iniciada. Espere..."
|
||||
LOOKUP_STORAGE: "{0} {depositó|retiró} {1} {2}."
|
||||
LOOKUP_TIME: "Hace {0}"
|
||||
LOOKUP_USERNAME: "{0} entró como {1}."
|
||||
MAXIMUM_RADIUS: "El radio máximo de {búsqueda|retorno|restauración} es {0}."
|
||||
MISSING_ACTION_USER: "Para usar esta acción, especifique a un usuario."
|
||||
MISSING_LOOKUP_TIME: "Especifique la cantidad de tiempo para {buscar|retornar|restaurar}."
|
||||
MISSING_LOOKUP_USER: "Especifique un usuario o {bloque|radio} para buscar."
|
||||
MISSING_PARAMETERS: "Usa \"{0}\"."
|
||||
MISSING_ROLLBACK_RADIUS: "No especificaste un radio para {retornar|resturar}."
|
||||
MISSING_ROLLBACK_USER: "No especificaste a un usuario para {retornar|restaurar}."
|
||||
MYSQL_UNAVAILABLE: "No se pudo conectar con el servidor de MySQL."
|
||||
NO_DATA: "Sin datos para {0}."
|
||||
NO_DATA_LOCATION: "Sin {datos|transacciones|interacciones|mensajes} encontrados acá."
|
||||
NO_PERMISSION: "No tienes permisos para hacer esto."
|
||||
NO_RESULTS: "No se hallaron resultados."
|
||||
NO_RESULTS_PAGE: "Sin {resultados|datos} encontados para esta página."
|
||||
NO_ROLLBACK: "No hay rollbacks {pendientes|previos} encontrados."
|
||||
PATCH_INTERRUPTED: "Mejora interrumpida. Se intentará nuevamente en el reinicio."
|
||||
PATCH_OUTDATED_1: "No se puede mejorar base de datos más antiguas de {0}."
|
||||
PATCH_OUTDATED_2: "Actualice con una versión soportada de CoreProtect."
|
||||
PATCH_PROCESSING: "Procesando nueva información. Espere un momento..."
|
||||
PATCH_SKIP_UPDATE: "Saltando {tabla|índice} {actualización|creación|remoción} en {0}."
|
||||
PATCH_STARTED: "Intentando actualizar {0}. Espere..."
|
||||
PATCH_SUCCESS: "Exitosamente actualizada a {0}."
|
||||
PATCH_UPGRADING: "Mejora de base de datos en progreso. Espere un momento..."
|
||||
PLEASE_SELECT: "Seleccione: \"{0}\" o \"{1}\"."
|
||||
PREVIEW_CANCELLED: "Vista previa cancelada."
|
||||
PREVIEW_CANCELLING: "Cancelando vista previa..."
|
||||
PREVIEW_CONTAINER: "No puede obtener una vista previa de las transacciones de contenedor."
|
||||
PREVIEW_IN_GAME: "Solo puedes obtener una vista previa de las reversiones en el juego."
|
||||
PURGE_ABORTED: "La purga falló. La base de datos puede estar dañada."
|
||||
PURGE_ERROR: "No se puede procesar {0} ¡datos!"
|
||||
PURGE_FAILED: "La purga falló. Por favor, inténtelo de nuevo más tarde."
|
||||
PURGE_IN_PROGRESS: "Purga en curso. Por favor, inténtelo de nuevo más tarde."
|
||||
PURGE_MINIMUM_TIME: "Solo puede depurar datos anteriores a {0} {días|horas}."
|
||||
PURGE_NOTICE_1: "Tenga en cuenta que esto puede llevar algún tiempo."
|
||||
PURGE_NOTICE_2: "No reinicie su servidor hasta que haya terminado."
|
||||
PURGE_OPTIMIZING: "Optimización de la base de datos. Espere por favor..."
|
||||
PREVIEW_CANCELLED: "Muestra cancelada."
|
||||
PREVIEW_CANCELLING: "Cancelando muestra..."
|
||||
PREVIEW_IN_GAME: "Solo puedes mostrar respaldos en el juego."
|
||||
PREVIEW_TRANSACTION: "No puedes mostrar transacciones de {contenedor|inventario}."
|
||||
PURGE_ABORTED: "Purga fallida. La base de datos debe estar corrupta."
|
||||
PURGE_ERROR: "¡No se pudo procesar {0} datos!"
|
||||
PURGE_FAILED: "Purga fallida. Intente nuevamente."
|
||||
PURGE_IN_PROGRESS: "Purga en progreso. Intentelo nuevamente."
|
||||
PURGE_MINIMUM_TIME: "Solo puedes limpiar datos viejos desde {0} {días|horas}."
|
||||
PURGE_NOTICE_1: "Ten en cuenta que va a demorar un poco."
|
||||
PURGE_NOTICE_2: "No reinicies el servidor hasta que se complete."
|
||||
PURGE_OPTIMIZING: "Optimizando base de datos. Espere..."
|
||||
PURGE_PROCESSING: "Procesando {0} datos..."
|
||||
PURGE_REPAIRING: "Intentando reparar. Esto puede tomar algo de tiempo..."
|
||||
PURGE_ROWS: "{0} {fila|filas} de datos eliminados."
|
||||
PURGE_STARTED: "La depuración de datos comenzó el \"{0}\"."
|
||||
PURGE_REPAIRING: "Intentando reparar. Esto tomará algo de tiempo..."
|
||||
PURGE_ROWS: "{0} {fila|filas} de datos limpiados."
|
||||
PURGE_STARTED: "Purga de datos iniciada en \"{0}\"."
|
||||
PURGE_SUCCESS: "Purga de datos exitosa."
|
||||
RELOAD_STARTED: "Recargando la configuración - espere."
|
||||
RELOAD_SUCCESS: "Configuración recargada correctamente."
|
||||
ROLLBACK_ABORTED: "Reversión o restauración abortada."
|
||||
ROLLBACK_CHUNKS_FOUND: "Encontró {0} {trozo|trozos} Modificar."
|
||||
ROLLBACK_CHUNKS_MODIFIED: "Modificado {0}/{1} {trozo|trozos}."
|
||||
ROLLBACK_COMPLETED: "{Retroceder|Restaurar|Vista previa} completado para \"{0}\"."
|
||||
ROLLBACK_EXCLUDED_USERS: "Excluido {usuario|usuarios}: \"{0}\"."
|
||||
RELOAD_STARTED: "Recargando configuración - espere."
|
||||
RELOAD_SUCCESS: "Configuración exitosamente recargada."
|
||||
ROLLBACK_ABORTED: "Retorno o restauración abortado."
|
||||
ROLLBACK_CHUNKS_FOUND: "Encontrado {0} {chunk|chunks} para modificar."
|
||||
ROLLBACK_CHUNKS_MODIFIED: "Se han modificado {0}/{1} {chunk|chunks}."
|
||||
ROLLBACK_COMPLETED: "{Respaldo|Restauración|Muestra} completado por \"{0}\"."
|
||||
ROLLBACK_EXCLUDED_USERS: "Excluir al {usuario|usuarios}: \"{0}\"."
|
||||
ROLLBACK_INCLUDE: "{Incluido|Excluido} {bloque|entidad|objetivo} {tipo|tipos}: \"{0}\"."
|
||||
ROLLBACK_IN_PROGRESS: "Ya se está realizando una reversión / restauración."
|
||||
ROLLBACK_LENGTH: "Tiempo tomado: {0} {segundo|segundos}."
|
||||
ROLLBACK_IN_PROGRESS: "Un retorno/resturación ya está en progreso."
|
||||
ROLLBACK_LENGTH: "Tiempo gastado: {0} {segundo|segundos}."
|
||||
ROLLBACK_MODIFIED: "{Modificado|Modificando} {0}."
|
||||
ROLLBACK_RADIUS: "Radio: {0} {bloque|bloques}."
|
||||
ROLLBACK_SELECTION: "Radio establecido en \"{0}\"."
|
||||
ROLLBACK_STARTED: "{Retroceder|Restaurar|Vista previa} comenzó en \"{0}\"."
|
||||
ROLLBACK_TIME: "Intervalo de tiempo: {0}."
|
||||
ROLLBACK_WORLD_ACTION: "Prohibido para {mundo|acción} \"{0}\"."
|
||||
SIGN_HEADER: "Firmar mensajes"
|
||||
STATUS_CONSUMER: "Consumidor: {0} {artículo|artículos} en fila."
|
||||
ROLLBACK_SELECTION: "Radio definido a \"{0}\"."
|
||||
ROLLBACK_STARTED: "{Retorno|Restauración|Muestra} iniciado en \"{0}\"."
|
||||
ROLLBACK_TIME: "Tiempo hecho: {0}."
|
||||
ROLLBACK_WORLD_ACTION: "Restringido para {mundo|acción} \"{0}\"."
|
||||
SIGN_HEADER: "Mensajes de cartel"
|
||||
STATUS_CONSUMER: "Consumidor: {0} {objeto|objetos} en espera."
|
||||
STATUS_DATABASE: "Base de datos: Usando {0}."
|
||||
STATUS_INTEGRATION: "{0}: Integración {habilitado|deshabilitado}."
|
||||
STATUS_INTEGRATION: "{0}: Integración {activada|desactivada}."
|
||||
STATUS_LICENSE: "Licencia: {0}"
|
||||
STATUS_VERSION: "Versión: {0}"
|
||||
TELEPORTED: "Teletransportado a {0}."
|
||||
TELEPORTED_SAFETY: "Te teletransportó a un lugar seguro."
|
||||
TELEPORT_PLAYERS: "El comando de teletransporte solo puede ser utilizado por jugadores."
|
||||
TELEPORTED_SAFETY: "Te he teletransportado a un lugar seguro."
|
||||
TELEPORT_PLAYERS: "El comando de teletransporte solo puede ser usado por jugadores."
|
||||
TIME_DAYS: "{0} {día|días}"
|
||||
TIME_HOURS: "{0} {hora|horas}"
|
||||
TIME_MINUTES: "{0} {minuto|minutos}"
|
||||
TIME_SECONDS: "{0} {segundo|segundos}"
|
||||
TIME_WEEKS: "{0} {semana|semanas}"
|
||||
UPDATE_ERROR: "Se produjo un error al buscar actualizaciones."
|
||||
UPDATE_HEADER: "{0} Actualizar"
|
||||
UPDATE_NOTICE: "Darse cuenta: {0} Ya está disponible."
|
||||
UPGRADE_IN_PROGRESS: "Actualización en curso. Por favor, inténtelo de nuevo más tarde."
|
||||
USER_NOT_FOUND: "Usuario \"{0}\" extraviado."
|
||||
USING_MYSQL: "Utilizando MySQL para el almacenamiento de datos."
|
||||
USING_SQLITE: "Utilizando SQLite para el almacenamiento de datos."
|
||||
UPDATE_ERROR: "Un error ocurrió mientras se revisaban las actualizaciones."
|
||||
UPDATE_HEADER: "Actualización {0}"
|
||||
UPDATE_NOTICE: "Noticia: {0} está disponible."
|
||||
UPGRADE_IN_PROGRESS: "Actualización en progreso. Intente nuevamente."
|
||||
USER_NOT_FOUND: "Usuario \"{0}\" no encontrado."
|
||||
USER_OFFLINE: "El usuario \"{0}\" no está conectado."
|
||||
USING_MYSQL: "Usando MySQL para el guardado de información."
|
||||
USING_SQLITE: "Usando SQLite para el guardado de información."
|
||||
VALID_DONATION_KEY: "Clave de donación válida."
|
||||
VERSION_NOTICE: "Versión {0} Ya está disponible."
|
||||
VERSION_REQUIRED: "{0} {1} se requiere o superior."
|
||||
WORLD_NOT_FOUND: "Mundo \"{0}\" extraviado."
|
||||
VERSION_NOTICE: "Versión {0} está disponible."
|
||||
VERSION_REQUIRED: "{0} {1} o súperior es requerida."
|
||||
WORLD_NOT_FOUND: "Mundo \"{0}\" inexistente."
|
||||
|
|
|
@ -9,8 +9,11 @@ API_TEST: "Test API réussi."
|
|||
CACHE_ERROR: "ATTENTION: Erreur lors de la validation {0} cache."
|
||||
CACHE_RELOAD: "Forcer le rechargement de {cartographie|monde} cache de la base de données."
|
||||
CHECK_CONFIG: "Veuillez vérifier config.yml"
|
||||
COMMAND_CONSOLE: "Veuillez exécuter la commande depuis la console."
|
||||
COMMAND_NOT_FOUND: "Commande \"{0}\" pas trouvé."
|
||||
COMMAND_THROTTLED: "Veuillez patienter un instant et réessayer."
|
||||
CONSUMER_ERROR: "Traitement de la file d'attente des consommateurs déjà {mis en pause|repris}."
|
||||
CONSUMER_TOGGLED: "Le traitement de la file d'attente des consommateurs a été {mis en pause|repris}."
|
||||
CONTAINER_HEADER: "Transactions de conteneurs"
|
||||
DATABASE_BUSY: "Base de données occupée. Veuillez réessayer plus tard."
|
||||
DATABASE_INDEX_ERROR: "Impossible de valider les index de la base de données."
|
||||
|
@ -108,12 +111,12 @@ LOOKUP_INTERACTION: "{0} {cliqué|tué} {1}."
|
|||
LOOKUP_ITEM: "{0} {ramassé|lâché} {1} {2}."
|
||||
LOOKUP_LOGIN: "{0} connecté {entrée|sortie}."
|
||||
LOOKUP_PAGE: "Page {0}"
|
||||
LOOKUP_PROJECTILE: "{0} {jeté|tiré} {1} {2}."
|
||||
LOOKUP_ROWS_FOUND: "{0} {ligne|lignes} trouvé."
|
||||
LOOKUP_SEARCHING: "Recherche de recherche. S'il vous plaît, attendez..."
|
||||
LOOKUP_STORAGE: "{0} {déposé|retiré} {1} {2}."
|
||||
LOOKUP_TIME: "{0} depuis"
|
||||
LOOKUP_USERNAME: "{0} connecté en tant que {1}."
|
||||
LOOKUP_VIEW_PAGE: "Pour afficher une page, tapez \"{0}\"."
|
||||
MAXIMUM_RADIUS: "Le maximum {recherche|restauration|restauration} le rayon est {0}."
|
||||
MISSING_ACTION_USER: "Pour utiliser cette action, veuillez spécifier un utilisateur."
|
||||
MISSING_LOOKUP_TIME: "Veuillez préciser l'heure à laquelle {recherche|restauration|restauration}."
|
||||
|
@ -139,8 +142,8 @@ PATCH_UPGRADING: "Mise à niveau de la base de données en cours. S'il vous pla
|
|||
PLEASE_SELECT: "Veuillez sélectionner: \"{0}\" ou alors \"{1}\"."
|
||||
PREVIEW_CANCELLED: "Aperçu annulé."
|
||||
PREVIEW_CANCELLING: "Annulation de l'aperçu..."
|
||||
PREVIEW_CONTAINER: "Vous ne pouvez pas prévisualiser les transactions de conteneur."
|
||||
PREVIEW_IN_GAME: "Vous ne pouvez prévisualiser les rollbacks que dans le jeu."
|
||||
PREVIEW_TRANSACTION: "Vous ne pouvez pas prévisualiser {conteneur|inventaire} transactions."
|
||||
PURGE_ABORTED: "Échec de la purge. La base de données est peut-être corrompue."
|
||||
PURGE_ERROR: "Impossible de traiter {0} Les données!"
|
||||
PURGE_FAILED: "Échec de la purge. Veuillez réessayer plus tard."
|
||||
|
@ -189,6 +192,7 @@ UPDATE_HEADER: "{0} Mettre à jour"
|
|||
UPDATE_NOTICE: "Remarquer: {0} est maintenant disponible."
|
||||
UPGRADE_IN_PROGRESS: "Mise à niveau en cours. Veuillez réessayer plus tard."
|
||||
USER_NOT_FOUND: "Utilisateur \"{0}\" pas trouvé."
|
||||
USER_OFFLINE: "L'utilisateur \"{0}\" n'est pas en ligne."
|
||||
USING_MYSQL: "Utilisant MySQL pour le stockage des données."
|
||||
USING_SQLITE: "Utilisant SQLite pour le stockage des données."
|
||||
VALID_DONATION_KEY: "Clé de don valide."
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
# CoreProtect Language File (ja)
|
||||
|
||||
ACTION_NOT_SUPPORTED: "そのアクションはサポートされていません。"
|
||||
AMOUNT_BLOCK: "{0} {ブロック|ブロック}"
|
||||
AMOUNT_CHUNK: "{0} {チャンク|チャンク}"
|
||||
AMOUNT_ENTITY: "{0} {エンティティ|エンティティ}"
|
||||
AMOUNT_ITEM: "{0} {item|items}"
|
||||
API_TEST: "APIテストが成功しました。"
|
||||
CACHE_ERROR: "警告:検証中にエラーが発生しました {0} キャッシュ。"
|
||||
CACHE_RELOAD: "のリロードを強制する {マッピング|世界} データベースからのキャッシュ。"
|
||||
CHECK_CONFIG: "config.ymlを確認してください"
|
||||
COMMAND_CONSOLE: "コンソールからコマンドを実行してください。"
|
||||
COMMAND_NOT_FOUND: "指示 \"{0}\" 見つかりません。"
|
||||
COMMAND_THROTTLED: "しばらく待ってから、もう一度お試しください。"
|
||||
CONSUMER_ERROR: "すでにコンシューマキュー処理 {一時停止|再開}。"
|
||||
CONSUMER_TOGGLED: "消費者キューの処理は {一時停止|再開}。"
|
||||
CONTAINER_HEADER: "コンテナトランザクション"
|
||||
DATABASE_BUSY: "データベースがビジーです。後でもう一度やり直してください。"
|
||||
DATABASE_INDEX_ERROR: "データベースインデックスを検証できません。"
|
||||
DATABASE_LOCKED_1: "データベースがロックされています。最大15秒待機しています..."
|
||||
DATABASE_LOCKED_2: "データベースはすでに使用されています。もう一度やり直してください。"
|
||||
DATABASE_LOCKED_3: "データベースロックを無効にするには、「database-lock:false」を設定します。"
|
||||
DATABASE_LOCKED_4: "データベースロックを無効にすると、データが破損する可能性があります。"
|
||||
DATABASE_UNREACHABLE: "データベースにアクセスできません。データを破棄してシャットダウンします。"
|
||||
DEVELOPMENT_BRANCH: "開発ブランチが検出され、パッチスクリプトをスキップしました。"
|
||||
DIRT_BLOCK: "あなたの下にダートブロックを置きました。"
|
||||
DISABLE_SUCCESS: "成功!無効 {0}"
|
||||
ENABLE_FAILED: "{0} 開始できませんでした。"
|
||||
ENABLE_SUCCESS: "{0} これで有効になります!"
|
||||
ENJOY_COREPROTECT: "楽しみ {0}?私たちに参加する Discord!"
|
||||
FINISHING_CONVERSION: "データ変換を終了します。お待ちください..."
|
||||
FINISHING_LOGGING: "データロギングの終了。お待ちください..."
|
||||
FIRST_VERSION: "初期DB:{0}"
|
||||
GLOBAL_LOOKUP: "グローバルルックアップを実行するために半径を指定しないでください。"
|
||||
GLOBAL_ROLLBACK: "つかいます \"{0}「グローバルに {ロールバック|復元}"
|
||||
HELP_ACTION_1: "ルックアップをアクションに制限します。"
|
||||
HELP_ACTION_2: "例:[a:block]、 [a:+block]、 [a:-block] [a:click]、 [a:container]、 [a:inventory]、 [a:item]、 [a:kill]、 [a:chat]、 [a:command]、 [a:sign]、 [a:session]、 [a:username]"
|
||||
HELP_COMMAND: "追加情報を表示します。"
|
||||
HELP_EXCLUDE_1: "ブロック/ユーザーを除外します。"
|
||||
HELP_EXCLUDE_2: "例:[e:stone]、 [e:Notch]、 [e:stone,Notch]"
|
||||
HELP_HEADER: "{0} ヘルプ"
|
||||
HELP_INCLUDE_1: "ブロック/エンティティを含めます。"
|
||||
HELP_INCLUDE_2: "例:[i:stone]、 [i:zombie]、 [i:stone,wood,bedrock]"
|
||||
HELP_INSPECT_1: "インスペクターを有効にすると、次のことができます。"
|
||||
HELP_INSPECT_2: "左クリックして配置を確認します。"
|
||||
HELP_INSPECT_3: "右クリックして、隣接する削除を表示します。"
|
||||
HELP_INSPECT_4: "ブロックを配置して、削除を確認します。"
|
||||
HELP_INSPECT_5: "ブロックを液体に入れて配置を確認します。"
|
||||
HELP_INSPECT_6: "右クリックしてチェストトランザクションを表示します。"
|
||||
HELP_INSPECT_7: "ヒント:「/coi」だけを使用できます。"
|
||||
HELP_INSPECT_COMMAND: "ブロックインスペクターを切り替えます。"
|
||||
HELP_LIST: "すべてのコマンドのリストを表示します。"
|
||||
HELP_LOOKUP_1: "コマンドショートカット。"
|
||||
HELP_LOOKUP_2: "追加のページを表示します。"
|
||||
HELP_LOOKUP_COMMAND: "ルックアップブロックデータ。"
|
||||
HELP_NO_INFO: "コマンドの情報 \"{0}\" 見つかりません。"
|
||||
HELP_PARAMETER: "見てください \"{0}詳細なパラメータ情報については、「」を参照してください。"
|
||||
HELP_PARAMS_1: "を実行します {ルックアップ|ロールバック|復元}。"
|
||||
HELP_PARAMS_2: "ユーザーを指定して {ルックアップ|ロールバック|復元}。"
|
||||
HELP_PARAMS_3: "時間を指定します {ルックアップ|ロールバック|復元}。"
|
||||
HELP_PARAMS_4: "制限する {ルックアップ|ロールバック|復元} 半径に。"
|
||||
HELP_PARAMS_5: "制限する {ルックアップ|ロールバック|復元} アクションに。"
|
||||
HELP_PARAMS_6: "ブロック/エンティティをに含める {ルックアップ|ロールバック|復元}。"
|
||||
HELP_PARAMS_7: "ブロック/ユーザーをから除外する {ルックアップ|ロールバック|復元}。"
|
||||
HELP_PURGE_1: "古いデータを削除します。"
|
||||
HELP_PURGE_2: "例えば、 \"{0}\" は、1か月より古いすべてのデータを削除し、過去30日間のデータのみを保持します。"
|
||||
HELP_PURGE_COMMAND: "古いブロックデータを削除します。"
|
||||
HELP_RADIUS_1: "半径領域を指定します。"
|
||||
HELP_RADIUS_2: "例:[r:10] (変更は10ブロック以内でのみ行ってください)"
|
||||
HELP_RELOAD_COMMAND: "構成ファイルを再ロードします。"
|
||||
HELP_RESTORE_COMMAND: "ブロックデータを復元します。"
|
||||
HELP_ROLLBACK_COMMAND: "ブロックデータをロールバックします。"
|
||||
HELP_STATUS: "プラグインのステータスを表示します。"
|
||||
HELP_STATUS_COMMAND: "プラグインのステータスを表示します。"
|
||||
HELP_TELEPORT: "テレポート。"
|
||||
HELP_TIME_1: "時間を指定します。"
|
||||
HELP_TIME_2: "例:[t:2w,5d,7h,2m,10s]、 [t:5d2h]、 [t:2.50h]"
|
||||
HELP_USER_1: "ユーザーを指定します。"
|
||||
HELP_USER_2: "例:[u:Notch]、 [u:Notch,#enderman]"
|
||||
INCOMPATIBLE_ACTION: "「」{0}「そのアクションでは使用できません。"
|
||||
INSPECTOR_ERROR: "すでに検査官 {有効|無効}。"
|
||||
INSPECTOR_TOGGLED: "今インスペクター {有効|無効}。"
|
||||
INTEGRATION_ERROR: "できません {初期化|無効化} {0} ロギング。"
|
||||
INTEGRATION_SUCCESS: "{0} 正常にロギング {初期化|無効}。"
|
||||
INTEGRATION_VERSION: "無効 {0} バージョンが見つかりました。"
|
||||
INTERACTIONS_HEADER: "プレイヤーの相互作用"
|
||||
INVALID_ACTION: "それは有効なアクションではありません。"
|
||||
INVALID_BRANCH_1: "プラグインのバージョンが無効です(ブランチが設定されていません)。"
|
||||
INVALID_BRANCH_2: "続行するには、プロジェクトブランチを「開発」に設定します。"
|
||||
INVALID_BRANCH_3: "開発コードを実行すると、データが破損する可能性があります。"
|
||||
INVALID_CONTAINER: "最初に有効なコンテナを調べてください。"
|
||||
INVALID_DONATION_KEY: "寄付キーが無効です。"
|
||||
INVALID_INCLUDE: "「」{0}\" は無効な値です。"
|
||||
INVALID_INCLUDE_COMBO: "これは無効な型の組み合わせです。"
|
||||
INVALID_RADIUS: "有効な半径を入力してください。"
|
||||
INVALID_SELECTION: "{0} 選択が見つかりません。"
|
||||
INVALID_USERNAME: "「」{0}\" は無効なユーザー名です。"
|
||||
INVALID_WORLD: "有効なワールドを指定してください。"
|
||||
LATEST_VERSION: "最新バージョン: {0}"
|
||||
LINK_DISCORD: "Discord: {0}"
|
||||
LINK_DOWNLOAD: "ダウンロード:{0}"
|
||||
LINK_PATREON: "Patreon: {0}"
|
||||
LINK_WIKI_BLOCK: "ブロック名:{0}"
|
||||
LINK_WIKI_ENTITY: "エンティティ名:{0}"
|
||||
LOGGING_ITEMS: "{0} ログに残されたアイテム。お待ちください..."
|
||||
LOGGING_TIME_LIMIT: "ロギングの制限時間に達しました。データを破棄してシャットダウンします。"
|
||||
LOOKUP_BLOCK: "{0} {配置|壊れた} {1}。"
|
||||
LOOKUP_CONTAINER: "{0} {追加|削除} {1} {2}。"
|
||||
LOOKUP_HEADER: "{0} 結果"
|
||||
LOOKUP_INTERACTION: "{0} {クリック|殺された} {1}。"
|
||||
LOOKUP_ITEM: "{0} {拾った|落とした} {1} {2}。"
|
||||
LOOKUP_LOGIN: "{0} ログに記録されます {in|out}。"
|
||||
LOOKUP_PAGE: "ページ {0}"
|
||||
LOOKUP_PROJECTILE: "{0} {投げた|ショット} {1} {2}。"
|
||||
LOOKUP_ROWS_FOUND: "{0} {行|行} 見つかった。"
|
||||
LOOKUP_SEARCHING: "ルックアップ検索。お待ちください..."
|
||||
LOOKUP_STORAGE: "{0} {預け入れ|撤回} {1} {2}。"
|
||||
LOOKUP_TIME: "{0} 前に"
|
||||
LOOKUP_USERNAME: "{0} としてログイン {1}。"
|
||||
MAXIMUM_RADIUS: "最大 {ルックアップ|ロールバック|復元} 半径は {0}。"
|
||||
MISSING_ACTION_USER: "そのアクションを使用するには、ユーザーを指定してください。"
|
||||
MISSING_LOOKUP_TIME: "時間を指定してください {ルックアップ|ロールバック|復元}。"
|
||||
MISSING_LOOKUP_USER: "ユーザーを指定するか、 {ブロック|半径}。"
|
||||
MISSING_PARAMETERS: "使ってください \"{0}\" 。"
|
||||
MISSING_ROLLBACK_RADIUS: "指定しませんでした {ロールバック|復元} 半径。"
|
||||
MISSING_ROLLBACK_USER: "指定しませんでした {ロールバック|復元} ユーザー。"
|
||||
MYSQL_UNAVAILABLE: "接続できません MySQL サーバ。"
|
||||
NO_DATA: "でデータが見つかりません {0}。"
|
||||
NO_DATA_LOCATION: "番号 {データ|トランザクション|相互作用|メッセージ} 見つかった。"
|
||||
NO_PERMISSION: "あなたにはそれをする許可がありません。"
|
||||
NO_RESULTS: "結果が見つかりません。"
|
||||
NO_RESULTS_PAGE: "番号 {結果|データ} そのページで見つかりました。"
|
||||
NO_ROLLBACK: "番号 {保留中|前へ} ロールバック/復元が見つかりました。"
|
||||
PATCH_INTERRUPTED: "アップグレードが中断されました。再起動時に再試行します。"
|
||||
PATCH_OUTDATED_1: "古いデータベースをアップグレードできません {0}。"
|
||||
PATCH_OUTDATED_2: "サポートされているバージョンでアップグレードしてください CoreProtect。"
|
||||
PATCH_PROCESSING: "新しいデータを処理しています。お待ちください..."
|
||||
PATCH_SKIP_UPDATE: "スキップ {テーブル|インデックス} {更新|作成|削除} の上 {0}。"
|
||||
PATCH_STARTED: "実行する {0} アップグレード。お待ちください..."
|
||||
PATCH_SUCCESS: "正常にアップグレードされました {0}。"
|
||||
PATCH_UPGRADING: "データベースのアップグレードが進行中です。お待ちください..."
|
||||
PLEASE_SELECT: "選んでください: \"{0}\" また \"{1}\" 。"
|
||||
PREVIEW_CANCELLED: "プレビューがキャンセルされました。"
|
||||
PREVIEW_CANCELLING: "プレビューをキャンセルしています..."
|
||||
PREVIEW_IN_GAME: "ゲーム内でのみロールバックをプレビューできます。"
|
||||
PREVIEW_TRANSACTION: "プレビューできません {コンテナ|在庫} トランザクション。"
|
||||
PURGE_ABORTED: "パージに失敗しました。データベースが破損している可能性があります。"
|
||||
PURGE_ERROR: "処理できません {0} データ!"
|
||||
PURGE_FAILED: "パージに失敗しました。後でもう一度やり直してください。"
|
||||
PURGE_IN_PROGRESS: "進行中のパージ。後でもう一度やり直してください。"
|
||||
PURGE_MINIMUM_TIME: "パージできるのは、より古いデータのみです。 {0} {日|時間}。"
|
||||
PURGE_NOTICE_1: "これには時間がかかる場合がありますのでご注意ください。"
|
||||
PURGE_NOTICE_2: "完了するまでサーバーを再起動しないでください。"
|
||||
PURGE_OPTIMIZING: "データベースの最適化。お待ちください..."
|
||||
PURGE_PROCESSING: "処理 {0} データ..."
|
||||
PURGE_REPAIRING: "修復しようとしています。これには時間がかかる場合があります..."
|
||||
PURGE_ROWS: "{0} {行|行} 削除されたデータの。"
|
||||
PURGE_STARTED: "データの削除は \"で開始されました{0}\" 。"
|
||||
PURGE_SUCCESS: "データのパージに成功しました。"
|
||||
RELOAD_STARTED: "構成の再読み込み-しばらくお待ちください。"
|
||||
RELOAD_SUCCESS: "構成が正常に再ロードされました。"
|
||||
ROLLBACK_ABORTED: "ロールバックまたは復元が中止されました。"
|
||||
ROLLBACK_CHUNKS_FOUND: "見つかった {0} {チャンク|チャンク} 変更します。"
|
||||
ROLLBACK_CHUNKS_MODIFIED: "変更 {0}/{1} {チャンク|チャンク}。"
|
||||
ROLLBACK_COMPLETED: "{ロールバック|復元|プレビュー} 「のために完成{0}\" 。"
|
||||
ROLLBACK_EXCLUDED_USERS: "除外 {ユーザー|ユーザー}: \"{0}\" 。"
|
||||
ROLLBACK_INCLUDE: "{含まれる|除外される} {ブロック|エンティティ|ターゲット} {タイプ|タイプ}: \"{0}\" 。"
|
||||
ROLLBACK_IN_PROGRESS: "ロールバック/復元はすでに進行中です。"
|
||||
ROLLBACK_LENGTH: "所要時間:{0} {秒|秒}。"
|
||||
ROLLBACK_MODIFIED: "{変更|変更} {0}。"
|
||||
ROLLBACK_RADIUS: "半径:{0} {ブロック|ブロック}。"
|
||||
ROLLBACK_SELECTION: "半径を「{0}\" 。"
|
||||
ROLLBACK_STARTED: "{ロールバック|復元|プレビュー} 「で始まった{0}\" 。"
|
||||
ROLLBACK_TIME: "時間範囲:{0}。"
|
||||
ROLLBACK_WORLD_ACTION: "に制限 {世界|アクション} 「」{0}\" 。"
|
||||
SIGN_HEADER: "メッセージに署名する"
|
||||
STATUS_CONSUMER: "消費者: {0} {item|items} 順番待ち。"
|
||||
STATUS_DATABASE: "データベース: 使用する {0}。"
|
||||
STATUS_INTEGRATION: "{0}: 統合 {有効|無効}。"
|
||||
STATUS_LICENSE: "ライセンス: {0}"
|
||||
STATUS_VERSION: "バージョン: {0}"
|
||||
TELEPORTED: "にテレポート {0}。"
|
||||
TELEPORTED_SAFETY: "安全にテレポートしました。"
|
||||
TELEPORT_PLAYERS: "テレポートコマンドはプレイヤーだけが使用できます。"
|
||||
TIME_DAYS: "{0} {日|日}"
|
||||
TIME_HOURS: "{0} {時間|時間}"
|
||||
TIME_MINUTES: "{0} {分|分}"
|
||||
TIME_SECONDS: "{0} {秒|秒}"
|
||||
TIME_WEEKS: "{0} {週|週}"
|
||||
UPDATE_ERROR: "更新の確認中にエラーが発生しました。"
|
||||
UPDATE_HEADER: "{0} アップデート"
|
||||
UPDATE_NOTICE: "知らせ:{0} 現在利用できます。"
|
||||
UPGRADE_IN_PROGRESS: "アップグレードが進行中です。後でもう一度やり直してください。"
|
||||
USER_NOT_FOUND: "ユーザー \"{0}\" 見つかりません。"
|
||||
USER_OFFLINE: "ユーザー \"{0}\" はオンラインではありません。"
|
||||
USING_MYSQL: "使用する MySQL データストレージ用。"
|
||||
USING_SQLITE: "使用する SQLite データストレージ用。"
|
||||
VALID_DONATION_KEY: "有効な寄付キー。"
|
||||
VERSION_NOTICE: "バージョン {0} 現在利用できます。"
|
||||
VERSION_REQUIRED: "{0} {1} 以上が必要です。"
|
||||
WORLD_NOT_FOUND: "世界 \"{0}\" 見つかりません。"
|
|
@ -9,8 +9,11 @@ API_TEST: "Test interfejsu API pomyślny."
|
|||
CACHE_ERROR: "OSTRZEŻENIE: Błąd podczas walidacji {0} Pamięć podręczna."
|
||||
CACHE_RELOAD: "Wymuszanie przeładowania {mapowanie|świat} pamięci podręczne z bazy danych."
|
||||
CHECK_CONFIG: "Sprawdź plik config.yml"
|
||||
COMMAND_CONSOLE: "Uruchom polecenie z konsoli."
|
||||
COMMAND_NOT_FOUND: "Komenda \"{0}\" nie znaleziono."
|
||||
COMMAND_THROTTLED: "Poczekaj chwilę i spróbuj ponownie."
|
||||
CONSUMER_ERROR: "Przetwarzanie kolejki klientów już {wstrzymane|wznowione}."
|
||||
CONSUMER_TOGGLED: "Przetwarzanie kolejki klientów zostało {wstrzymane|wznowione}."
|
||||
CONTAINER_HEADER: "Transakcje kontenerowe"
|
||||
DATABASE_BUSY: "Baza danych zajęta. Spróbuj ponownie później."
|
||||
DATABASE_INDEX_ERROR: "Nie można zweryfikować indeksów bazy danych."
|
||||
|
@ -108,12 +111,12 @@ LOOKUP_INTERACTION: "{0} {kliknięty|zabity} {1}."
|
|||
LOOKUP_ITEM: "{0} {odebrany|upuszczony} {1} {2}."
|
||||
LOOKUP_LOGIN: "{0} zalogowany {w|na zewnątrz}."
|
||||
LOOKUP_PAGE: "Strona {0}"
|
||||
LOOKUP_PROJECTILE: "{0} {rzucił|strzał} {1} {2}."
|
||||
LOOKUP_ROWS_FOUND: "{0} {wiersz|wiersze} znaleziony."
|
||||
LOOKUP_SEARCHING: "Wyszukiwanie wyszukiwania. Proszę czekać..."
|
||||
LOOKUP_STORAGE: "{0} {zdeponowane|wycofane} {1} {2}."
|
||||
LOOKUP_TIME: "{0} temu"
|
||||
LOOKUP_USERNAME: "{0} zalogowany jako {1}."
|
||||
LOOKUP_VIEW_PAGE: "Aby wyświetlić stronę, wpisz „{0}”."
|
||||
MAXIMUM_RADIUS: "Maksymalny {wyszukiwanie|wycofywanie|przywracanie} promień to {0}."
|
||||
MISSING_ACTION_USER: "Aby skorzystać z tej akcji, określ użytkownika."
|
||||
MISSING_LOOKUP_TIME: "Proszę określić czas na {wyszukiwanie|przywracanie|przywracanie}."
|
||||
|
@ -139,8 +142,8 @@ PATCH_UPGRADING: "Trwa aktualizacja bazy danych. Proszę czekać..."
|
|||
PLEASE_SELECT: "Proszę wybrać: \"{0}\" lub \"{1}”."
|
||||
PREVIEW_CANCELLED: "Podgląd anulowany."
|
||||
PREVIEW_CANCELLING: "Anulowanie podglądu..."
|
||||
PREVIEW_CONTAINER: "Nie możesz wyświetlić podglądu transakcji kontenerowych."
|
||||
PREVIEW_IN_GAME: "Możesz tylko podglądać wycofania w grze."
|
||||
PREVIEW_TRANSACTION: "Nie możesz wyświetlić podglądu {kontener|inwentarz} transakcje."
|
||||
PURGE_ABORTED: "Czyszczenie nie powiodło się. Baza danych może być uszkodzona."
|
||||
PURGE_ERROR: "Nie można przetworzyć {0} dane!"
|
||||
PURGE_FAILED: "Czyszczenie nie powiodło się. Spróbuj ponownie później."
|
||||
|
@ -189,6 +192,7 @@ UPDATE_HEADER: "{0} Aktualizacja"
|
|||
UPDATE_NOTICE: "Ogłoszenie: {0} jest teraz dostępne."
|
||||
UPGRADE_IN_PROGRESS: "Trwa aktualizacja. Spróbuj ponownie później."
|
||||
USER_NOT_FOUND: "Użytkownik \"{0}\" nie znaleziono."
|
||||
USER_OFFLINE: "Użytkownik \"{0}\" nie jest online."
|
||||
USING_MYSQL: "Za pomocą MySQL do przechowywania danych."
|
||||
USING_SQLITE: "Za pomocą SQLite do przechowywania danych."
|
||||
VALID_DONATION_KEY: "Ważny klucz darowizny."
|
||||
|
|
10
lang/ru.yml
10
lang/ru.yml
|
@ -9,8 +9,11 @@ API_TEST: "Тест API прошёл успешно!"
|
|||
CACHE_ERROR: "ВНИМАНИЕ: Ошибка при проверке кеша {0}."
|
||||
CACHE_RELOAD: "Принудительная перезагрузка кеша {отображения|мира} из базы данных."
|
||||
CHECK_CONFIG: "Пожалуйста, проверьте config.yml"
|
||||
COMMAND_CONSOLE: "Пожалуйста, запустите команду из консоли."
|
||||
COMMAND_NOT_FOUND: "Команда «{0}» не найдена."
|
||||
COMMAND_THROTTLED: "Подождите немного и попробуйте еще раз."
|
||||
CONSUMER_ERROR: "Обработка потребительской очереди уже {приостановлено|возобновлено}."
|
||||
CONSUMER_TOGGLED: "Обработка очереди потребителей была {приостановлено|возобновлено}."
|
||||
CONTAINER_HEADER: "Контейнерные транзакции"
|
||||
DATABASE_BUSY: "База данных занята. Пожалуйста, повторите попытку позже."
|
||||
DATABASE_INDEX_ERROR: "Невозможно проверить индексы базы данных."
|
||||
|
@ -108,12 +111,12 @@ LOOKUP_INTERACTION: "{0} {нажал|убил} {1}."
|
|||
LOOKUP_ITEM: "{0} {подобрал|выкинул} {1} {2}."
|
||||
LOOKUP_LOGIN: "{0} {вошёл|вышел}."
|
||||
LOOKUP_PAGE: "Страница {0}"
|
||||
LOOKUP_PROJECTILE: "{0} {бросил|выстрелил} {1} {2}."
|
||||
LOOKUP_ROWS_FOUND: "{0} {строка|строк} найдено."
|
||||
LOOKUP_SEARCHING: "Ведётся поиск. Пожалуйста подождите..."
|
||||
LOOKUP_STORAGE: "{0} {положил|забрал} {1} {2}."
|
||||
LOOKUP_TIME: "{0} назад"
|
||||
LOOKUP_USERNAME: "{0} зарегистрирован как {1}."
|
||||
LOOKUP_VIEW_PAGE: "Чтобы просмотреть страницу, введите «{0}»."
|
||||
MAXIMUM_RADIUS: "Максимальный радиус для {поиска|отката|восстановления} - {0}."
|
||||
MISSING_ACTION_USER: "Чтобы использовать это действие, укажите пользователя."
|
||||
MISSING_LOOKUP_TIME: "Пожалуйста, укажите количество времени, чтобы использовать {поиск|откат|восстановление}."
|
||||
|
@ -139,8 +142,8 @@ PATCH_UPGRADING: "Выполняется обновление базы данн
|
|||
PLEASE_SELECT: "Пожалуйта выберете: «{0}» или «{1}»."
|
||||
PREVIEW_CANCELLED: "Предварительный просмотр отменен."
|
||||
PREVIEW_CANCELLING: "Отмена предварительного просмотра..."
|
||||
PREVIEW_CONTAINER: "Вы не можете предварительно просмотреть контейнерные транзакции."
|
||||
PREVIEW_IN_GAME: "Предварительный просмотр откатов доступен только в игре."
|
||||
PREVIEW_TRANSACTION: "Вы не можете просмотреть {контейнер|инвентарь} транзакции."
|
||||
PURGE_ABORTED: "Очистка не удалась. База данных может быть повреждена."
|
||||
PURGE_ERROR: "Невозможно обработать данные {0}!"
|
||||
PURGE_FAILED: "Очистка не удалась. Пожалуйста, повторите попытку позже."
|
||||
|
@ -189,9 +192,10 @@ UPDATE_HEADER: "{0} Обновление"
|
|||
UPDATE_NOTICE: "Примечание: теперь доступен {0}."
|
||||
UPGRADE_IN_PROGRESS: "Выполняется обновление. Пожалуйста, повторите попытку позже."
|
||||
USER_NOT_FOUND: "Пользователь «{0}» не найден."
|
||||
USER_OFFLINE: "Пользователь \"{0}\" нет в сети."
|
||||
USING_MYSQL: "Для хранения данных используется MySQL."
|
||||
USING_SQLITE: "Для хранения данных используется SQLite."
|
||||
VALID_DONATION_KEY: "Действующий ключ пожертвования."
|
||||
VERSION_NOTICE: "Версия {0} уже доступна!"
|
||||
VERSION_REQUIRED: "{0} {1} или выше требуется."
|
||||
WORLD_NOT_FOUND: "Мир «{0}» не найден."
|
||||
WORLD_NOT_FOUND: "Мир «{0}» не найден."
|
|
@ -0,0 +1,201 @@
|
|||
# CoreProtect Language File (tr)
|
||||
|
||||
ACTION_NOT_SUPPORTED: "Bu işlem desteklenmiyor."
|
||||
AMOUNT_BLOCK: "{0} {blok|bloklar}"
|
||||
AMOUNT_CHUNK: "{0} {yığın|parçalar}"
|
||||
AMOUNT_ENTITY: "{0} {varlık|kuruluşlar}"
|
||||
AMOUNT_ITEM: "{0} {öğe|öğeler}"
|
||||
API_TEST: "API testi başarılı."
|
||||
CACHE_ERROR: "UYARI: Doğrulama sırasında hata {0} önbellek."
|
||||
CACHE_RELOAD: "Yeniden yüklemeye zorlama {haritalama|dünya} veritabanından önbellekler."
|
||||
CHECK_CONFIG: "Lütfen config.yml'yi kontrol edin"
|
||||
COMMAND_CONSOLE: "Lütfen komutu konsoldan çalıştırın."
|
||||
COMMAND_NOT_FOUND: "Emretmek \"{0}\" bulunamadı."
|
||||
COMMAND_THROTTLED: "Lütfen biraz bekleyin ve tekrar deneyin."
|
||||
CONSUMER_ERROR: "Tüketici kuyruğu işleme zaten {duraklatıldı|devam ettirildi}."
|
||||
CONSUMER_TOGGLED: "Tüketici kuyruğu işleme {duraklatıldı|devam ettirildi}."
|
||||
CONTAINER_HEADER: "Konteyner İşlemleri"
|
||||
DATABASE_BUSY: "Veritabanı meşgul. Lütfen daha sonra tekrar deneyiniz."
|
||||
DATABASE_INDEX_ERROR: "Veritabanı dizinleri doğrulanamıyor."
|
||||
DATABASE_LOCKED_1: "Veritabanı kilitlendi. 15 saniyeye kadar bekleniyor..."
|
||||
DATABASE_LOCKED_2: "Veritabanı zaten kullanılıyor. Lütfen tekrar deneyin."
|
||||
DATABASE_LOCKED_3: "Veritabanı kilitlemeyi devre dışı bırakmak için \"veritabanı kilidi: yanlış\" olarak ayarlayın."
|
||||
DATABASE_LOCKED_4: "Veritabanı kilitlemeyi devre dışı bırakmak, verilerin bozulmasına neden olabilir."
|
||||
DATABASE_UNREACHABLE: "Veritabanına erişilemiyor. Verileri atma ve kapatma."
|
||||
DEVELOPMENT_BRANCH: "Geliştirme dalı algılandı, yama komut dosyaları atlandı."
|
||||
DIRT_BLOCK: "Altına bir toprak bloğu yerleştirdi."
|
||||
DISABLE_SUCCESS: "Başarı! Engelli {0}"
|
||||
ENABLE_FAILED: "{0} başlayamadı."
|
||||
ENABLE_SUCCESS: "{0} şimdi etkinleştirildi!"
|
||||
ENJOY_COREPROTECT: "Eğlence {0}? Bize katılın Discord!"
|
||||
FINISHING_CONVERSION: "Veri dönüştürme işlemi tamamlanıyor. Lütfen bekle..."
|
||||
FINISHING_LOGGING: "Veri kaydının tamamlanması. Lütfen bekle..."
|
||||
FIRST_VERSION: "İlk Veri Tabanı: {0}"
|
||||
GLOBAL_LOOKUP: "Genel arama yapmak için bir yarıçap belirlemeyin."
|
||||
GLOBAL_ROLLBACK: "Kullanmak \"{0}\" küresel yapmak {geri alma|geri yükleme}"
|
||||
HELP_ACTION_1: "Aramayı bir eylemle sınırlayın."
|
||||
HELP_ACTION_2: "Örnekler: [a:block], [a:+block], [a:-block] [a:click], [a:container], [a:inventory], [a:item], [a:kill], [a:chat], [a:command], [a:sign], [a:session], [a:username]"
|
||||
HELP_COMMAND: "Ek bilgileri görüntüleyin."
|
||||
HELP_EXCLUDE_1: "Blokları/kullanıcıları hariç tutun."
|
||||
HELP_EXCLUDE_2: "Örnekler: [e:stone], [e:Notch], [e:stone,Notch]"
|
||||
HELP_HEADER: "{0} Yardım"
|
||||
HELP_INCLUDE_1: "Blokları/varlıkları dahil et."
|
||||
HELP_INCLUDE_2: "Örnekler: [i:stone], [i:zombie], [i:stone,wood,bedrock]"
|
||||
HELP_INSPECT_1: "Müfettiş etkinken şunları yapabilirsiniz:"
|
||||
HELP_INSPECT_2: "Yerleşimi görmek için sol tıklayın."
|
||||
HELP_INSPECT_3: "Bitişik kaldırmaları görmek için sağ tıklayın."
|
||||
HELP_INSPECT_4: "Kaldırma işlemini görmek için bir blok yerleştirin."
|
||||
HELP_INSPECT_5: "Yerleşimi görmek için sıvıya bir blok yerleştirin."
|
||||
HELP_INSPECT_6: "Sandık işlemlerini görmek için sağ tıklayın."
|
||||
HELP_INSPECT_7: "İpucu: Yalnızca \"/co i\" kullanabilirsiniz."
|
||||
HELP_INSPECT_COMMAND: "Blok denetçisini değiştirir."
|
||||
HELP_LIST: "Tüm komutların bir listesini görüntüler."
|
||||
HELP_LOOKUP_1: "Komut kısayolu."
|
||||
HELP_LOOKUP_2: "Ek sayfaları görüntüleyin."
|
||||
HELP_LOOKUP_COMMAND: "Blok verilerini arayın."
|
||||
HELP_NO_INFO: "Komut için bilgi \"{0}\" bulunamadı."
|
||||
HELP_PARAMETER: "Bakınız \"{0}\" detaylı parametre bilgisi için."
|
||||
HELP_PARAMS_1: "Gerçekleştir {arama|geri alma|geri yükleme}."
|
||||
HELP_PARAMS_2: "Kullanıcıları belirtin {arama|geri alma|geri yükleme}."
|
||||
HELP_PARAMS_3: "Zamanı belirtin {arama|geri alma|geri yükleme}."
|
||||
HELP_PARAMS_4: "kısıtlamak {arama|geri alma|geri yükleme} bir yarıçapa."
|
||||
HELP_PARAMS_5: "kısıtlamak {arama|geri alma|geri yükleme} bir eyleme."
|
||||
HELP_PARAMS_6: "Blokları/varlıkları dahil et {arama|geri alma|geri yükleme}."
|
||||
HELP_PARAMS_7: "Blokları/kullanıcıları {arama|geri alma|geri yükleme}."
|
||||
HELP_PURGE_1: "Eski verileri kaldırın."
|
||||
HELP_PURGE_2: "Örneğin, \"{0}\" bir aydan eski tüm verileri silecek ve yalnızca son 30 güne ait verileri tutacaktır."
|
||||
HELP_PURGE_COMMAND: "Eski blok verilerini silin."
|
||||
HELP_RADIUS_1: "Bir yarıçap alanı belirtin."
|
||||
HELP_RADIUS_2: "Örnekler: [r:10] (Sadece 10 blok içinde değişiklik yapın)"
|
||||
HELP_RELOAD_COMMAND: "Yapılandırma dosyasını yeniden yükler."
|
||||
HELP_RESTORE_COMMAND: "Blok verilerini geri yükleyin."
|
||||
HELP_ROLLBACK_COMMAND: "Geri alma blok verileri."
|
||||
HELP_STATUS: "Eklenti durumunu görüntüleyin."
|
||||
HELP_STATUS_COMMAND: "Eklenti durumunu görüntüler."
|
||||
HELP_TELEPORT: "Işınlanma."
|
||||
HELP_TIME_1: "Zamanı belirtin."
|
||||
HELP_TIME_2: "Örnekler: [t:2w,5d,7h,2m,10s], [t:5d2h], [t:2.50h]"
|
||||
HELP_USER_1: "Kullanıcıları belirtin."
|
||||
HELP_USER_2: "Örnekler: [u:Notch], [u:Notch,#enderman]"
|
||||
INCOMPATIBLE_ACTION: "\"{0}\" bu eylemle kullanılamaz."
|
||||
INSPECTOR_ERROR: "Müfettiş zaten {etkin|devre dışı}."
|
||||
INSPECTOR_TOGGLED: "Müfettiş şimdi {etkin|devre dışı}."
|
||||
INTEGRATION_ERROR: "Olanaksız {başlat|devre dışı bırak} {0} Kerestecilik."
|
||||
INTEGRATION_SUCCESS: "{0} başarıyla giriş yapmak {başlatıldı|devre dışı}."
|
||||
INTEGRATION_VERSION: "Geçersiz {0} sürüm bulundu."
|
||||
INTERACTIONS_HEADER: "Oyuncu Etkileşimleri"
|
||||
INVALID_ACTION: "Bu geçerli bir eylem değil."
|
||||
INVALID_BRANCH_1: "Geçersiz eklenti sürümü (dal ayarlanmadı)."
|
||||
INVALID_BRANCH_2: "Devam etmek için proje dalını \"geliştirme\" olarak ayarlayın."
|
||||
INVALID_BRANCH_3: "Geliştirme kodunu çalıştırmak, verilerin bozulmasına neden olabilir."
|
||||
INVALID_CONTAINER: "Lütfen önce geçerli bir kapsayıcıyı inceleyin."
|
||||
INVALID_DONATION_KEY: "Geçersiz bağış anahtarı."
|
||||
INVALID_INCLUDE: "\"{0}\" geçersiz bir değerdir."
|
||||
INVALID_INCLUDE_COMBO: "Bu geçersiz bir tür birleşimidir."
|
||||
INVALID_RADIUS: "Lütfen geçerli bir yarıçap girin."
|
||||
INVALID_SELECTION: "{0} seçim bulunamadı."
|
||||
INVALID_USERNAME: "\"{0}\" geçersiz bir kullanıcı adıdır."
|
||||
INVALID_WORLD: "Lütfen geçerli bir dünya belirtin."
|
||||
LATEST_VERSION: "En son sürüm: {0}"
|
||||
LINK_DISCORD: "Discord: {0}"
|
||||
LINK_DOWNLOAD: "İndirmek: {0}"
|
||||
LINK_PATREON: "Patreon: {0}"
|
||||
LINK_WIKI_BLOCK: "Blok İsimleri: {0}"
|
||||
LINK_WIKI_ENTITY: "Varlık Adları: {0}"
|
||||
LOGGING_ITEMS: "{0} günlüğe bırakılan öğeler. Lütfen bekle..."
|
||||
LOGGING_TIME_LIMIT: "Günlüğe kaydetme zaman sınırına ulaşıldı. Verileri atma ve kapatma."
|
||||
LOOKUP_BLOCK: "{0} {yerleştirilmiş|kırıldı} {1}."
|
||||
LOOKUP_CONTAINER: "{0} {eklendi|kaldırıldı} {1} {2}."
|
||||
LOOKUP_HEADER: "{0} Sonuçlar"
|
||||
LOOKUP_INTERACTION: "{0} {tıklandı|öldürüldü} {1}."
|
||||
LOOKUP_ITEM: "{0} {aldı|bıraktı} {1} {2}."
|
||||
LOOKUP_LOGIN: "{0} günlüğe kaydedildi {içeri|dışarı}."
|
||||
LOOKUP_PAGE: "Sayfa {0}"
|
||||
LOOKUP_PROJECTILE: "{0} {fırlattı|vuruş} {1} {2}."
|
||||
LOOKUP_ROWS_FOUND: "{0} {satır|satır} kurmak."
|
||||
LOOKUP_SEARCHING: "Arama arama. Lütfen bekle..."
|
||||
LOOKUP_STORAGE: "{0} {yatırıldı|geri çekildi} {1} {2}."
|
||||
LOOKUP_TIME: "{0} evvel"
|
||||
LOOKUP_USERNAME: "{0} olarak giriş yaptı {1}."
|
||||
MAXIMUM_RADIUS: "Maksimum {arama|geri alma|geri yükleme} yarıçap {0}."
|
||||
MISSING_ACTION_USER: "Bu eylemi kullanmak için lütfen bir kullanıcı belirtin."
|
||||
MISSING_LOOKUP_TIME: "Lütfen zamanı belirtin {arama|geri alma|geri yükleme}."
|
||||
MISSING_LOOKUP_USER: "Lütfen bir kullanıcı belirtin veya {blok|yarıçap}."
|
||||
MISSING_PARAMETERS: "Lütfen kullan \"{0}\"."
|
||||
MISSING_ROLLBACK_RADIUS: "bir belirtmemişsin {geri alma|geri yükleme} yarıçap."
|
||||
MISSING_ROLLBACK_USER: "bir belirtmemişsin {geri alma|geri yükleme} kullanıcı."
|
||||
MYSQL_UNAVAILABLE: "Bağlantı kurulamıyor MySQL sunucu."
|
||||
NO_DATA: "şurada veri bulunamadı {0}."
|
||||
NO_DATA_LOCATION: "Numara {veri|işlemler|etkileşimler|mesajlar} kurmak."
|
||||
NO_PERMISSION: "Bunu yapmaya iznin yok."
|
||||
NO_RESULTS: "Sonuç bulunamadı."
|
||||
NO_RESULTS_PAGE: "Numara {sonuçlar|veri} o sayfa için bulundu."
|
||||
NO_ROLLBACK: "Numara {beklemede|önceki} geri alma/geri yükleme bulundu."
|
||||
PATCH_INTERRUPTED: "Yükseltme kesintiye uğradı. Yeniden başlatıldığında tekrar deneyecek."
|
||||
PATCH_OUTDATED_1: "Daha eski veritabanları yükseltilemiyor {0}."
|
||||
PATCH_OUTDATED_2: "Lütfen desteklenen bir sürümle yükseltin CoreProtect."
|
||||
PATCH_PROCESSING: "Yeni veriler işleniyor. Lütfen bekle..."
|
||||
PATCH_SKIP_UPDATE: "Atlama {tablo|dizin} {güncelleme|oluşturma|kaldırma} üzerinde {0}."
|
||||
PATCH_STARTED: "performans {0} Yükselt. Lütfen bekle..."
|
||||
PATCH_SUCCESS: "Başarıyla yükseltildi {0}."
|
||||
PATCH_UPGRADING: "Veritabanı yükseltmesi devam ediyor. Lütfen bekle..."
|
||||
PLEASE_SELECT: "Lütfen seçin: \"{0}\" veya \"{1}\"."
|
||||
PREVIEW_CANCELLED: "Önizleme iptal edildi."
|
||||
PREVIEW_CANCELLING: "Önizleme iptal ediliyor..."
|
||||
PREVIEW_IN_GAME: "Geri almaları yalnızca oyun içinde önizleyebilirsiniz."
|
||||
PREVIEW_TRANSACTION: "önizleme yapamazsınız {konteyner|envanter} işlemler."
|
||||
PURGE_ABORTED: "Temizleme başarısız oldu. Veritabanı bozuk olabilir."
|
||||
PURGE_ERROR: "işlenemiyor {0} veri!"
|
||||
PURGE_FAILED: "Temizleme başarısız oldu. Lütfen daha sonra tekrar deneyiniz."
|
||||
PURGE_IN_PROGRESS: "Temizleme işlemi devam ediyor. Lütfen daha sonra tekrar deneyiniz."
|
||||
PURGE_MINIMUM_TIME: "Yalnızca şu tarihten daha eski verileri temizleyebilirsiniz: {0} {gün|saat}."
|
||||
PURGE_NOTICE_1: "Lütfen bunun biraz zaman alabileceğini unutmayın."
|
||||
PURGE_NOTICE_2: "Tamamlanana kadar sunucunuzu yeniden başlatmayın."
|
||||
PURGE_OPTIMIZING: "Veritabanını optimize etme. Lütfen bekle..."
|
||||
PURGE_PROCESSING: "İşleme {0} veri..."
|
||||
PURGE_REPAIRING: "Tamir etmeye çalışmak. Bu biraz zaman alabilir..."
|
||||
PURGE_ROWS: "{0} {satır|satır} silinen veriler."
|
||||
PURGE_STARTED: "Veri temizleme başladı \"{0}\"."
|
||||
PURGE_SUCCESS: "Veri temizleme başarılı."
|
||||
RELOAD_STARTED: "Yapılandırma yeniden yükleniyor - lütfen bekleyin."
|
||||
RELOAD_SUCCESS: "Yapılandırma başarıyla yeniden yüklendi."
|
||||
ROLLBACK_ABORTED: "Geri alma veya geri yükleme iptal edildi."
|
||||
ROLLBACK_CHUNKS_FOUND: "Kurmak {0} {yığın|parçalar} düzenlemek."
|
||||
ROLLBACK_CHUNKS_MODIFIED: "Değiştirilmiş {0}/{1} {yığın|parçalar}."
|
||||
ROLLBACK_COMPLETED: "{Geri Alma|Geri Yükleme|Önizleme} için tamamlandı \"{0}\"."
|
||||
ROLLBACK_EXCLUDED_USERS: "Hariç tutulan {kullanıcı|kullanıcılar}: \"{0}\"."
|
||||
ROLLBACK_INCLUDE: "{Dahil|Hariç} {blok|varlık|hedef} {tip|tür}: \"{0}\"."
|
||||
ROLLBACK_IN_PROGRESS: "Halihazırda bir geri alma/geri yükleme işlemi devam ediyor."
|
||||
ROLLBACK_LENGTH: "Geçen süre: {0} {saniye|saniye}."
|
||||
ROLLBACK_MODIFIED: "{Değiştirildi|Değiştiriliyor} {0}."
|
||||
ROLLBACK_RADIUS: "yarıçap: {0} {blok|bloklar}."
|
||||
ROLLBACK_SELECTION: "Yarıçap \" olarak ayarlandı{0}\"."
|
||||
ROLLBACK_STARTED: "{Geri Alma|Geri Yükleme|Önizleme} başladı \"{0}\"."
|
||||
ROLLBACK_TIME: "Zaman aralığı: {0}."
|
||||
ROLLBACK_WORLD_ACTION: "Sınırlı {dünya|eylem} \"{0}\"."
|
||||
SIGN_HEADER: "Mesajları İmzala"
|
||||
STATUS_CONSUMER: "Tüketici: {0} {öğe|öğeler} sırada."
|
||||
STATUS_DATABASE: "Veri tabanı: kullanma {0}."
|
||||
STATUS_INTEGRATION: "{0}: Entegrasyon {etkin|devre dışı}."
|
||||
STATUS_LICENSE: "Lisans: {0}"
|
||||
STATUS_VERSION: "Sürüm: {0}"
|
||||
TELEPORTED: "Işınlandı {0}."
|
||||
TELEPORTED_SAFETY: "Sizi emniyete ışınladım."
|
||||
TELEPORT_PLAYERS: "Teleport komutu sadece oyuncular tarafından kullanılabilir."
|
||||
TIME_DAYS: "{0} {gün|gün}"
|
||||
TIME_HOURS: "{0} {saat|saat}"
|
||||
TIME_MINUTES: "{0} {dakika|dakika}"
|
||||
TIME_SECONDS: "{0} {saniye|saniye}"
|
||||
TIME_WEEKS: "{0} {hafta|hafta}"
|
||||
UPDATE_ERROR: "Güncellemeler kontrol edilirken bir hata oluştu."
|
||||
UPDATE_HEADER: "{0} Güncelleme"
|
||||
UPDATE_NOTICE: "Fark etme: {0} şimdi kullanılabilir."
|
||||
UPGRADE_IN_PROGRESS: "Yükseltme devam ediyor. Lütfen daha sonra tekrar deneyiniz."
|
||||
USER_NOT_FOUND: "kullanıcı \"{0}\" bulunamadı."
|
||||
USER_OFFLINE: "Kullanıcı \"{0}\" çevrimiçi değil."
|
||||
USING_MYSQL: "kullanma MySQL veri depolama için."
|
||||
USING_SQLITE: "kullanma SQLite veri depolama için."
|
||||
VALID_DONATION_KEY: "Geçerli bağış anahtarı."
|
||||
VERSION_NOTICE: "sürüm {0} şimdi kullanılabilir."
|
||||
VERSION_REQUIRED: "{0} {1} veya daha yüksek gereklidir."
|
||||
WORLD_NOT_FOUND: "Dünya \"{0}\" bulunamadı."
|
|
@ -0,0 +1,201 @@
|
|||
# CoreProtect Language File (uk)
|
||||
|
||||
ACTION_NOT_SUPPORTED: "Ця дія не підтримується."
|
||||
AMOUNT_BLOCK: "{0} {блок|блоки}"
|
||||
AMOUNT_CHUNK: "{0} {шматок|шматки}"
|
||||
AMOUNT_ENTITY: "{0} {сутність|сутності}"
|
||||
AMOUNT_ITEM: "{0} {пункт|предмети}"
|
||||
API_TEST: "Тест API успішний."
|
||||
CACHE_ERROR: "УВАГА: Помилка під час перевірки {0} кеш."
|
||||
CACHE_RELOAD: "Примусове перезавантаження {картографування|світу} кеші з бази даних."
|
||||
CHECK_CONFIG: "Перевірте config.yml"
|
||||
COMMAND_CONSOLE: "Будь ласка, запустіть команду з консолі."
|
||||
COMMAND_NOT_FOUND: "Команда \"{0}\" не знайдено."
|
||||
COMMAND_THROTTLED: "Зачекайте хвилину і повторіть спробу."
|
||||
CONSUMER_ERROR: "Вже обробка черги споживачів {призупинено|відновлено}."
|
||||
CONSUMER_TOGGLED: "Обробка черги споживачів була {призупинено|відновлено}."
|
||||
CONTAINER_HEADER: "Контейнерні операції"
|
||||
DATABASE_BUSY: "База даних зайнята. Будь-ласка спробуйте пізніше."
|
||||
DATABASE_INDEX_ERROR: "Неможливо перевірити індекси бази даних."
|
||||
DATABASE_LOCKED_1: "База даних заблокована. Очікування до 15 секунд..."
|
||||
DATABASE_LOCKED_2: "База даних вже використовується. Будь ласка спробуйте ще раз."
|
||||
DATABASE_LOCKED_3: "Щоб вимкнути блокування бази даних, встановіть \"database-lock: false\"."
|
||||
DATABASE_LOCKED_4: "Вимкнення блокування бази даних може призвести до пошкодження даних."
|
||||
DATABASE_UNREACHABLE: "База даних недоступна. Видалення даних та завершення роботи."
|
||||
DEVELOPMENT_BRANCH: "Виявлено гілку розробки, пропущено сценарії виправлення."
|
||||
DIRT_BLOCK: "Поклали під себе брудний блок."
|
||||
DISABLE_SUCCESS: "Успіху! Інвалід {0}"
|
||||
ENABLE_FAILED: "{0} не вдалося почати."
|
||||
ENABLE_SUCCESS: "{0} тепер увімкнено!"
|
||||
ENJOY_COREPROTECT: "Насолоджуйтесь {0}? Приєднуйтесь до наших Discord!"
|
||||
FINISHING_CONVERSION: "Завершення перетворення даних. Будь ласка, зачекайте..."
|
||||
FINISHING_LOGGING: "Завершення реєстрації даних. Будь ласка, зачекайте..."
|
||||
FIRST_VERSION: "Початкова БД: {0}"
|
||||
GLOBAL_LOOKUP: "Не вказуйте радіус для глобального пошуку."
|
||||
GLOBAL_ROLLBACK: "Використовувати \"{0}\" зробити глобальний {відкат|відновлення}"
|
||||
HELP_ACTION_1: "Обмежити пошук до дії."
|
||||
HELP_ACTION_2: "Приклади: [a:block], [a:+block], [a:-block] [a:click], [a:container], [a:inventory], [a:item], [a:kill], [a:chat], [a:command], [a:sign], [a:session], [a:username]"
|
||||
HELP_COMMAND: "Відображення додаткової інформації."
|
||||
HELP_EXCLUDE_1: "Виключити блоки/користувачів."
|
||||
HELP_EXCLUDE_2: "Приклади: [e:stone], [e:Notch], [e:stone,Notch]"
|
||||
HELP_HEADER: "{0} Довідка"
|
||||
HELP_INCLUDE_1: "Включити блоки/сутності."
|
||||
HELP_INCLUDE_2: "Приклади: [i:stone], [i:zombie], [i:stone,wood,bedrock]"
|
||||
HELP_INSPECT_1: "Якщо інспектор увімкнено, ви можете:"
|
||||
HELP_INSPECT_2: "Клацніть лівою кнопкою миші, щоб побачити місце розташування."
|
||||
HELP_INSPECT_3: "Клацніть правою кнопкою миші, щоб побачити суміжні видалення."
|
||||
HELP_INSPECT_4: "Поставте блок, щоб побачити видалення."
|
||||
HELP_INSPECT_5: "Помістіть блок у рідину, щоб побачити розташування."
|
||||
HELP_INSPECT_6: "Клацніть правою кнопкою миші, щоб побачити операції з суднами."
|
||||
HELP_INSPECT_7: "Порада: Ви можете використовувати лише \"/co i\"."
|
||||
HELP_INSPECT_COMMAND: "Перемикає інспектор блоків."
|
||||
HELP_LIST: "Відображає список усіх команд."
|
||||
HELP_LOOKUP_1: "Ярлик команди."
|
||||
HELP_LOOKUP_2: "Переглянути додаткові сторінки."
|
||||
HELP_LOOKUP_COMMAND: "Перегляд даних блоку."
|
||||
HELP_NO_INFO: "Інформація для команди \"{0}\" не знайдено."
|
||||
HELP_PARAMETER: "Будь ласка, подивіться \"{0}\" для отримання детальної інформації про параметри."
|
||||
HELP_PARAMS_1: "Виконайте {пошук|відкат|відновлення}."
|
||||
HELP_PARAMS_2: "Вкажіть користувачів для {пошук|відкат|відновлення}."
|
||||
HELP_PARAMS_3: "Вкажіть час до {пошук|відкат|відновлення}."
|
||||
HELP_PARAMS_4: "Обмежте {пошук|відкат|відновлення} до радіусу."
|
||||
HELP_PARAMS_5: "Обмежте {пошук|відкат|відновлення} до дії."
|
||||
HELP_PARAMS_6: "Включити блоки/сутності до {пошук|відкат|відновлення}."
|
||||
HELP_PARAMS_7: "Виключити блокування/користувачів із {пошук|відкат|відновлення}."
|
||||
HELP_PURGE_1: "Видаліть старі дані."
|
||||
HELP_PURGE_2: "Наприклад, \"{0}\" видалить усі дані старше одного місяця та збереже дані лише за останні 30 днів."
|
||||
HELP_PURGE_COMMAND: "Видалити дані старого блоку."
|
||||
HELP_RADIUS_1: "Вкажіть зону радіуса."
|
||||
HELP_RADIUS_2: "Приклади: [r:10] (Вносити зміни лише в межах 10 блоків від вас)"
|
||||
HELP_RELOAD_COMMAND: "Перезавантажує файл конфігурації."
|
||||
HELP_RESTORE_COMMAND: "Відновлення даних блоку."
|
||||
HELP_ROLLBACK_COMMAND: "Дані блоку відкату."
|
||||
HELP_STATUS: "Переглянути стан плагіна."
|
||||
HELP_STATUS_COMMAND: "Відображає стан плагіна."
|
||||
HELP_TELEPORT: "Телепорт."
|
||||
HELP_TIME_1: "Вкажіть час."
|
||||
HELP_TIME_2: "Приклади: [t:2w,5d,7h,2m,10s], [t:5d2h], [t:2.50h]"
|
||||
HELP_USER_1: "Вкажіть користувачів."
|
||||
HELP_USER_2: "Приклади: [u:Notch], [u:Notch,#enderman]"
|
||||
INCOMPATIBLE_ACTION: "\"{0}\" не можна використовувати з цією дією."
|
||||
INSPECTOR_ERROR: "Вже інспектор {включено|вимкнено}."
|
||||
INSPECTOR_TOGGLED: "Зараз інспектор {включено|вимкнено}."
|
||||
INTEGRATION_ERROR: "Вдалося {ініціалізувати|вимкнути} {0} лісозаготівлі."
|
||||
INTEGRATION_SUCCESS: "{0} реєстрація успішно {ініціалізовано|відключено}."
|
||||
INTEGRATION_VERSION: "Недійсний {0} версія знайдена."
|
||||
INTERACTIONS_HEADER: "Взаємодії гравців"
|
||||
INVALID_ACTION: "Це не дійсна дія."
|
||||
INVALID_BRANCH_1: "Недійсна версія плагіна (гілка не встановлена)."
|
||||
INVALID_BRANCH_2: "Щоб продовжити, встановіть гілку проекту на \"розвиток\"."
|
||||
INVALID_BRANCH_3: "Запуск коду розробки може призвести до пошкодження даних."
|
||||
INVALID_CONTAINER: "Спочатку перевірте дійсний контейнер."
|
||||
INVALID_DONATION_KEY: "Недійсний ключ пожертви."
|
||||
INVALID_INCLUDE: "\"{0}\" є недійсним значенням."
|
||||
INVALID_INCLUDE_COMBO: "Це недійсна комбінація типів."
|
||||
INVALID_RADIUS: "Введіть дійсний радіус."
|
||||
INVALID_SELECTION: "{0} виділення не знайдено."
|
||||
INVALID_USERNAME: "\"{0}\" є недійсним ім'ям користувача."
|
||||
INVALID_WORLD: "Укажіть дійсний світ."
|
||||
LATEST_VERSION: "Остання версія: {0}"
|
||||
LINK_DISCORD: "Discord: {0}"
|
||||
LINK_DOWNLOAD: "Завантажити: {0}"
|
||||
LINK_PATREON: "Patreon: {0}"
|
||||
LINK_WIKI_BLOCK: "Імена блоків: {0}"
|
||||
LINK_WIKI_ENTITY: "Назви сутностей: {0}"
|
||||
LOGGING_ITEMS: "{0} елементи, залишені для реєстрації. Будь ласка, зачекайте..."
|
||||
LOGGING_TIME_LIMIT: "Досягнуто обмеження часу реєстрації. Видалення даних та завершення роботи."
|
||||
LOOKUP_BLOCK: "{0} {розміщено|зламано} {1}."
|
||||
LOOKUP_CONTAINER: "{0} {додано|видалено} {1} {2}."
|
||||
LOOKUP_HEADER: "{0} Результати"
|
||||
LOOKUP_INTERACTION: "{0} {натиснув|убитий} {1}."
|
||||
LOOKUP_ITEM: "{0} {взяв|скинув} {1} {2}."
|
||||
LOOKUP_LOGIN: "{0} зареєстрований {в|з ~ ~}."
|
||||
LOOKUP_PAGE: "Сторінка {0}"
|
||||
LOOKUP_PROJECTILE: "{0} {кинув|постріл} {1} {2}."
|
||||
LOOKUP_ROWS_FOUND: "{0} {рядок|рядки} знайдено."
|
||||
LOOKUP_SEARCHING: "Пошук під час пошуку. Будь ласка, зачекайте..."
|
||||
LOOKUP_STORAGE: "{0} {здано на зберігання|вилучено} {1} {2}."
|
||||
LOOKUP_TIME: "{0} тому"
|
||||
LOOKUP_USERNAME: "{0} Ви увійшли як {1}."
|
||||
MAXIMUM_RADIUS: "Максимум {пошук|відкат|відновлення} радіус дорівнює {0}."
|
||||
MISSING_ACTION_USER: "Щоб використати цю дію, вкажіть користувача."
|
||||
MISSING_LOOKUP_TIME: "Будь ласка, вкажіть час до {пошук|відкат|відновлення}."
|
||||
MISSING_LOOKUP_USER: "Будь ласка, вкажіть користувача або {блок|радіус}."
|
||||
MISSING_PARAMETERS: "Будь ласка, використовуйте \"{0}\"."
|
||||
MISSING_ROLLBACK_RADIUS: "Ви не вказали a {відкат|відновлення} радіус."
|
||||
MISSING_ROLLBACK_USER: "Ви не вказали a {відкат|відновлення} користувача."
|
||||
MYSQL_UNAVAILABLE: "Не вдається підключитися до MySQL сервер."
|
||||
NO_DATA: "Дані не знайдені за адресою {0}."
|
||||
NO_DATA_LOCATION: "Ні {дані|транзакції|взаємодії|повідомлення} знайдено."
|
||||
NO_PERMISSION: "У вас немає дозволу на це."
|
||||
NO_RESULTS: "Нічого не знайдено."
|
||||
NO_RESULTS_PAGE: "Ні {результати|дані} знайдено для цієї сторінки."
|
||||
NO_ROLLBACK: "Ні {в очікуванні|попередній} відкат/відновлення знайдено."
|
||||
PATCH_INTERRUPTED: "Оновлення перервано. Спробую ще раз при перезавантаженні."
|
||||
PATCH_OUTDATED_1: "Не вдається оновити бази даних старші {0}."
|
||||
PATCH_OUTDATED_2: "Оновіть підтримувану версію CoreProtect."
|
||||
PATCH_PROCESSING: "Обробка нових даних. Будь ласка, зачекайте..."
|
||||
PATCH_SKIP_UPDATE: "Пропуск {таблиця|індекс} {оновлення|створення|видалення} на {0}."
|
||||
PATCH_STARTED: "Виконання {0} оновлення. Будь ласка, зачекайте..."
|
||||
PATCH_SUCCESS: "Успішно оновлено до {0}."
|
||||
PATCH_UPGRADING: "Триває оновлення бази даних. Будь ласка, зачекайте..."
|
||||
PLEASE_SELECT: "Виберіть будь ласка: \"{0}\" або \"{1}\"."
|
||||
PREVIEW_CANCELLED: "Попередній перегляд скасовано."
|
||||
PREVIEW_CANCELLING: "Скасування попереднього перегляду..."
|
||||
PREVIEW_IN_GAME: "Попередній перегляд можна лише в грі."
|
||||
PREVIEW_TRANSACTION: "Ви не можете попередньо переглянути {тару|інвентар} трансакцій."
|
||||
PURGE_ABORTED: "Помилка очищення. Можливо, база даних пошкоджена."
|
||||
PURGE_ERROR: "Не вдається обробити {0} дані!"
|
||||
PURGE_FAILED: "Помилка очищення. Будь-ласка спробуйте пізніше."
|
||||
PURGE_IN_PROGRESS: "Триває чистка. Будь-ласка спробуйте пізніше."
|
||||
PURGE_MINIMUM_TIME: "Очистити дані можна лише старше {0} {днів|годин}."
|
||||
PURGE_NOTICE_1: "Зверніть увагу, що це може зайняти деякий час."
|
||||
PURGE_NOTICE_2: "Не перезавантажуйте сервер до завершення."
|
||||
PURGE_OPTIMIZING: "Оптимізація бази даних. Будь ласка, зачекайте..."
|
||||
PURGE_PROCESSING: "Обробка {0} дані..."
|
||||
PURGE_REPAIRING: "Спроба ремонту. Це може зайняти деякий час..."
|
||||
PURGE_ROWS: "{0} {рядок|рядки} даних видалено."
|
||||
PURGE_STARTED: "Очищення даних розпочато \"{0}\"."
|
||||
PURGE_SUCCESS: "Очищення даних успішно."
|
||||
RELOAD_STARTED: "Перезавантаження конфігурації - зачекайте."
|
||||
RELOAD_SUCCESS: "Конфігурацію успішно перезавантажено."
|
||||
ROLLBACK_ABORTED: "Відкат або відновлення припинено."
|
||||
ROLLBACK_CHUNKS_FOUND: "Знайдено {0} {шматок|шматки} змінити."
|
||||
ROLLBACK_CHUNKS_MODIFIED: "Змінено {0}/{1} {шматок|шматки}."
|
||||
ROLLBACK_COMPLETED: "{Відкат|Відновлення|Попередній перегляд} завершено за \"{0}\"."
|
||||
ROLLBACK_EXCLUDED_USERS: "Виключено {користувач|користувачі}: \"{0}\"."
|
||||
ROLLBACK_INCLUDE: "{Включено|Виключено} {блок|сутність|ціль} {тип|типи}: \"{0}\"."
|
||||
ROLLBACK_IN_PROGRESS: "Відкат/відновлення вже триває."
|
||||
ROLLBACK_LENGTH: "Витрачений час: {0} {секунда|секунди}."
|
||||
ROLLBACK_MODIFIED: "{Змінено|Змінюється} {0}."
|
||||
ROLLBACK_RADIUS: "Радіус: {0} {блок|блоки}."
|
||||
ROLLBACK_SELECTION: "Радіус встановлено на \"{0}\"."
|
||||
ROLLBACK_STARTED: "{Відкат|Відновлення|Попередній перегляд} почав \"{0}\"."
|
||||
ROLLBACK_TIME: "Часовий діапазон: {0}."
|
||||
ROLLBACK_WORLD_ACTION: "Обмежено до {світ|дія} \"{0}\"."
|
||||
SIGN_HEADER: "Підписуйте повідомлення"
|
||||
STATUS_CONSUMER: "Споживач: {0} {пункт|предмети} в черзі."
|
||||
STATUS_DATABASE: "База даних: Використання {0}."
|
||||
STATUS_INTEGRATION: "{0}: Інтеграція {включено|вимкнено}."
|
||||
STATUS_LICENSE: "Ліцензія: {0}"
|
||||
STATUS_VERSION: "Версія: {0}"
|
||||
TELEPORTED: "Телепортувався до {0}."
|
||||
TELEPORTED_SAFETY: "Телепортував вас у безпечне місце."
|
||||
TELEPORT_PLAYERS: "Команду телепорту можуть використовувати лише гравці."
|
||||
TIME_DAYS: "{0} {день|дні}"
|
||||
TIME_HOURS: "{0} {година|години}"
|
||||
TIME_MINUTES: "{0} {хвилина|хвилини}"
|
||||
TIME_SECONDS: "{0} {секунда|секунди}"
|
||||
TIME_WEEKS: "{0} {тиждень|тиждень}"
|
||||
UPDATE_ERROR: "Під час перевірки оновлень сталася помилка."
|
||||
UPDATE_HEADER: "{0} Оновлення"
|
||||
UPDATE_NOTICE: "Примітка: {0} тепер доступний."
|
||||
UPGRADE_IN_PROGRESS: "Оновлення триває. Будь-ласка спробуйте пізніше."
|
||||
USER_NOT_FOUND: "Користувач \"{0}\" не знайдено."
|
||||
USER_OFFLINE: "Користувач \"{0}\" не в мережі."
|
||||
USING_MYSQL: "Використання MySQL для зберігання даних."
|
||||
USING_SQLITE: "Використання SQLite для зберігання даних."
|
||||
VALID_DONATION_KEY: "Дійсний ключ пожертви."
|
||||
VERSION_NOTICE: "Версія {0} тепер доступний."
|
||||
VERSION_REQUIRED: "{0} {1} або вище."
|
||||
WORLD_NOT_FOUND: "Світ \"{0}\" не знайдено."
|
|
@ -9,8 +9,11 @@ API_TEST: "Kiểm tra API thành công."
|
|||
CACHE_ERROR: "CẢNH BÁO: Lỗi khi xác thực {0} bộ nhớ đệm."
|
||||
CACHE_RELOAD: "Buộc tải lại {lập bản đồ|thế giới} bộ nhớ đệm từ cơ sở dữ liệu."
|
||||
CHECK_CONFIG: "Vui lòng kiểm tra config.yml"
|
||||
COMMAND_CONSOLE: "Vui lòng chạy lệnh từ bảng điều khiển."
|
||||
COMMAND_NOT_FOUND: "Yêu cầu \"{0}\" không tìm thấy."
|
||||
COMMAND_THROTTLED: "Vui lòng đợi trong giây lát và thử lại."
|
||||
CONSUMER_ERROR: "Đã xử lý hàng đợi của người tiêu dùng {bị tạm dừng|tiếp tục}."
|
||||
CONSUMER_TOGGLED: "Xử lý hàng đợi của người tiêu dùng đã được {bị tạm dừng|tiếp tục}."
|
||||
CONTAINER_HEADER: "Giao dịch vùng chứa"
|
||||
DATABASE_BUSY: "Cơ sở dữ liệu bận rộn. Vui lòng thử lại sau."
|
||||
DATABASE_INDEX_ERROR: "Không thể xác thực các chỉ mục cơ sở dữ liệu."
|
||||
|
@ -108,12 +111,12 @@ LOOKUP_INTERACTION: "{0} {đã nhấp vào|giết} {1}."
|
|||
LOOKUP_ITEM: "{0} {nhặt lên|đánh rơi} {1} {2}."
|
||||
LOOKUP_LOGIN: "{0} ghi nhật ký {vào|ra}."
|
||||
LOOKUP_PAGE: "Trang {0}"
|
||||
LOOKUP_PROJECTILE: "{0} {ném|bắn} {1} {2}."
|
||||
LOOKUP_ROWS_FOUND: "{0} {hàng|hàng} tìm."
|
||||
LOOKUP_SEARCHING: "Tra cứu tìm kiếm. Vui lòng chờ..."
|
||||
LOOKUP_STORAGE: "{0} {ký gửi|rút tiền} {1} {2}."
|
||||
LOOKUP_TIME: "{0} trước kia"
|
||||
LOOKUP_USERNAME: "{0} đăng nhập với tư cách {1}."
|
||||
LOOKUP_VIEW_PAGE: "Để xem một trang, hãy nhập \"{0}\"."
|
||||
MAXIMUM_RADIUS: "Giá trị lớn nhất {tra cứu|khôi phục|khôi phục} bán kính là {0}."
|
||||
MISSING_ACTION_USER: "Để sử dụng hành động đó, vui lòng chỉ định người dùng."
|
||||
MISSING_LOOKUP_TIME: "Vui lòng xác định thời gian để {tra cứu|khôi phục|khôi phục}."
|
||||
|
@ -139,8 +142,8 @@ PATCH_UPGRADING: "Đang nâng cấp cơ sở dữ liệu. Vui lòng chờ..."
|
|||
PLEASE_SELECT: "Xin hãy lựa chọn: \"{0}\" hoặc \"{1}\"."
|
||||
PREVIEW_CANCELLED: "Đã hủy bản xem trước."
|
||||
PREVIEW_CANCELLING: "Đang hủy bản xem trước..."
|
||||
PREVIEW_CONTAINER: "Bạn không thể xem trước các giao dịch vùng chứa."
|
||||
PREVIEW_IN_GAME: "Bạn chỉ có thể xem trước các lần quay lại trong trò chơi."
|
||||
PREVIEW_TRANSACTION: "Bạn không thể xem trước {container|hàng tồn kho} các giao dịch."
|
||||
PURGE_ABORTED: "Thanh trừng không thành công. Cơ sở dữ liệu có thể bị hỏng."
|
||||
PURGE_ERROR: "Không thể xử lý {0} dữ liệu!"
|
||||
PURGE_FAILED: "Thanh trừng không thành công. Vui lòng thử lại sau."
|
||||
|
@ -189,6 +192,7 @@ UPDATE_HEADER: "{0} Cập nhật"
|
|||
UPDATE_NOTICE: "Lưu ý: {0} hiện đã có sẵn."
|
||||
UPGRADE_IN_PROGRESS: "Đang nâng cấp. Vui lòng thử lại sau."
|
||||
USER_NOT_FOUND: "Người sử dụng \"{0}\" không tìm thấy."
|
||||
USER_OFFLINE: "Người dùng \"{0}\" không trực tuyến."
|
||||
USING_MYSQL: "Sử dụng MySQL để lưu trữ dữ liệu."
|
||||
USING_SQLITE: "Sử dụng SQLite để lưu trữ dữ liệu."
|
||||
VALID_DONATION_KEY: "Chìa khóa quyên góp hợp lệ."
|
||||
|
|
|
@ -10,8 +10,11 @@ API_TEST: "API 测试成功。"
|
|||
CACHE_ERROR: "警告: 验证缓存 {0} 时出错。"
|
||||
CACHE_RELOAD: "正在强制从数据库中重新加载{映射|世界}的缓存。"
|
||||
CHECK_CONFIG: "请检查 config.yml 文件"
|
||||
COMMAND_CONSOLE: "请在控制台中运行此命令。"
|
||||
COMMAND_NOT_FOUND: "找不到命令 \"{0}\""
|
||||
COMMAND_THROTTLED: "请稍等片刻,然后重试。"
|
||||
CONSUMER_ERROR: "数据处理队列已经{暂停|恢复}。"
|
||||
CONSUMER_TOGGLED: "数据处理队列现已{暂停|恢复}。"
|
||||
CONTAINER_HEADER: "容器物品变更记录"
|
||||
DATABASE_BUSY: "数据库繁忙,请稍后重试。"
|
||||
DATABASE_INDEX_ERROR: "无法验证数据库索引。"
|
||||
|
@ -39,7 +42,7 @@ HELP_EXCLUDE_2: "例子: [e:stone], [e:Notch], [e:stone,Notch]"
|
|||
HELP_HEADER: "{0} 帮助"
|
||||
HELP_INCLUDE_1: "包括方块/实体。"
|
||||
HELP_INCLUDE_2: "例子: [i:stone], [i:zombie], [i:stone,wood,bedrock]"
|
||||
HELP_INSPECT_1: "启用检查器后,你可以: "
|
||||
HELP_INSPECT_1: "启用检查器后,你可以:"
|
||||
HELP_INSPECT_2: "左键单击以查看方块放置记录。"
|
||||
HELP_INSPECT_3: "右键单击以查看相邻方块破坏记录。"
|
||||
HELP_INSPECT_4: "放置一个方块以查看放置位置的破坏记录。"
|
||||
|
@ -109,12 +112,12 @@ LOOKUP_INTERACTION: "{0} {点击|击杀} {1}."
|
|||
LOOKUP_ITEM: "{0} {拾起|丢弃} {1} {2}."
|
||||
LOOKUP_LOGIN: "{0} {登入|离开}."
|
||||
LOOKUP_PAGE: "第 {0} 页"
|
||||
LOOKUP_PROJECTILE: "{0} {扔出|发射} {1} {2}."
|
||||
LOOKUP_ROWS_FOUND: "已找到 {0}{行|行}。"
|
||||
LOOKUP_SEARCHING: "正在搜索,请稍等..."
|
||||
LOOKUP_STORAGE: "{0} {放入|取出} {1} {2}."
|
||||
LOOKUP_TIME: "{0} 前"
|
||||
LOOKUP_USERNAME: "{0} 已登入为 {1}."
|
||||
LOOKUP_VIEW_PAGE: "查看指定操作记录,请输入\"{0}\"。"
|
||||
MAXIMUM_RADIUS: "最大{查找|回滚|恢复}半径是 {0}."
|
||||
MISSING_ACTION_USER: "要使用该标识符,请指定玩家名。"
|
||||
MISSING_LOOKUP_TIME: "请指定{查找|回滚|恢复}时间."
|
||||
|
@ -140,8 +143,8 @@ PATCH_UPGRADING: "正在进行数据库升级,请稍等..."
|
|||
PLEASE_SELECT: "请选择: \"{0}\"或\"{1}\"。"
|
||||
PREVIEW_CANCELLED: "预览已取消。"
|
||||
PREVIEW_CANCELLING: "正在取消预览..."
|
||||
PREVIEW_CONTAINER: "你无法预览容器的存入取出操作。"
|
||||
PREVIEW_IN_GAME: "你只能在游戏中预览回滚操作。"
|
||||
PREVIEW_TRANSACTION: "你不能预览{容器|背包}物品交换。"
|
||||
PURGE_ABORTED: "清除失败,数据库可能已损坏。"
|
||||
PURGE_ERROR: "无法处理 {0} 数据!"
|
||||
PURGE_FAILED: "数据清除失败,请稍后再试。"
|
||||
|
@ -190,6 +193,7 @@ UPDATE_HEADER: "{0} 更新"
|
|||
UPDATE_NOTICE: "注意: {0} 现在可用。"
|
||||
UPGRADE_IN_PROGRESS: "正在进行升级,请稍后再试。"
|
||||
USER_NOT_FOUND: "玩家\"{0}\"未找到。"
|
||||
USER_OFFLINE: "玩家\"{0}\"不在线。"
|
||||
USING_MYSQL: "使用 MySQL 用于数据存储。"
|
||||
USING_SQLITE: "使用 SQLite 用于数据存储。"
|
||||
VALID_DONATION_KEY: "有效的捐赠密钥。"
|
||||
|
|
188
lang/zh-tw.yml
188
lang/zh-tw.yml
|
@ -1,8 +1,8 @@
|
|||
# CoreProtect Language File (zh-TW)
|
||||
# Translators: whitebear13579, Flandre_tw
|
||||
# Translators: whitebear13579, flandretw, ianiiaannn
|
||||
|
||||
ACTION_NOT_SUPPORTED: "此指令不支援該操作。"
|
||||
AMOUNT_BLOCK: "{0} 個{方塊|方塊}"
|
||||
ACTION_NOT_SUPPORTED: "此指令不支援該行為。"
|
||||
AMOUNT_BLOCK: "{0} 格{方塊|方塊}"
|
||||
AMOUNT_CHUNK: "{0} 個{區塊|區塊}"
|
||||
AMOUNT_ENTITY: "{0} 個{實體|實體}"
|
||||
AMOUNT_ITEM: "{0} 個{物品|物品}"
|
||||
|
@ -10,49 +10,52 @@ API_TEST: "API 測試成功。"
|
|||
CACHE_ERROR: "警告: 驗證快取 {0} 時出現錯誤。"
|
||||
CACHE_RELOAD: "正在強制從資料庫中重新載入{鏡像|世界}快取。"
|
||||
CHECK_CONFIG: "請檢查 config.yml 檔案。"
|
||||
COMMAND_NOT_FOUND: "未知的指令 \"{0}\"。"
|
||||
COMMAND_CONSOLE: "請從控制台執行此指令。"
|
||||
COMMAND_NOT_FOUND: "未知的指令「{0}」。"
|
||||
COMMAND_THROTTLED: "請稍後再試。"
|
||||
CONTAINER_HEADER: "儲存容器變更記錄。"
|
||||
CONSUMER_ERROR: "消費者隊列處理已經{暫停|繼續}."
|
||||
CONSUMER_TOGGLED: "消費者隊列處理已{暫停|繼續}."
|
||||
CONTAINER_HEADER: "儲存容器變更紀錄。"
|
||||
DATABASE_BUSY: "資料庫繁忙,請稍後再試。"
|
||||
DATABASE_INDEX_ERROR: "無法驗證資料庫索引。"
|
||||
DATABASE_LOCKED_1: "資料庫已被鎖定,請等待 15 秒後再試……"
|
||||
DATABASE_LOCKED_1: "資料庫已被鎖定,請稍後 15 秒後再試……"
|
||||
DATABASE_LOCKED_2: "資料庫正在使用,請稍後再試一次。"
|
||||
DATABASE_LOCKED_3: "若要關閉資料庫鎖定功能,請設定 \"database-lock: false\"。"
|
||||
DATABASE_LOCKED_4: "關閉資料庫鎖定功能,可能導致資料損壞。"
|
||||
DATABASE_UNREACHABLE: "資料庫無法存取,正在拋棄資料並關閉。"
|
||||
DEVELOPMENT_BRANCH: "檢測到正在使用開發分支的版本,已跳過使用補丁腳本。"
|
||||
DATABASE_LOCKED_3: "若要停用資料庫鎖定功能,請設定「database-lock: false」。"
|
||||
DATABASE_LOCKED_4: "停用資料庫鎖定功能可能導致資料毀損。"
|
||||
DATABASE_UNREACHABLE: "資料庫無法存取,正在拋棄資料並停用。"
|
||||
DEVELOPMENT_BRANCH: "檢測到正在使用開發分支的版本,已跳過資料庫版本更新。"
|
||||
DIRT_BLOCK: "已在你的下方放置了泥土。"
|
||||
DISABLE_SUCCESS: "執行成功 ! 關閉 {0} !"
|
||||
DISABLE_SUCCESS: "執行成功!已停用 {0}!"
|
||||
ENABLE_FAILED: "無法啟用 {0}。"
|
||||
ENABLE_SUCCESS: "已經成功啟用 {0} !"
|
||||
ENJOY_COREPROTECT: "喜歡 {0} 嗎 ? 加入我們的 Discord !"
|
||||
ENABLE_SUCCESS: "已經成功啟用 {0}!"
|
||||
ENJOY_COREPROTECT: "喜歡 {0} 嗎?加入我們的 Discord!"
|
||||
FINISHING_CONVERSION: "正在完成資料轉換,請稍候……"
|
||||
FINISHING_LOGGING: "正在完成資料記錄,請稍候……"
|
||||
FIRST_VERSION: "初始化資料庫: {0}"
|
||||
FINISHING_LOGGING: "正在完成紀錄檔處理,請稍候……"
|
||||
FIRST_VERSION: "資料庫初始化版本: {0}"
|
||||
GLOBAL_LOOKUP: "請勿指定範圍來進行全面的搜尋。"
|
||||
GLOBAL_ROLLBACK: "使用 \"{0}\" 來進行全面的{回滾|恢復}。"
|
||||
HELP_ACTION_1: "將搜尋限制為某個行為。"
|
||||
GLOBAL_ROLLBACK: "使用「{0}」來進行全面的{回滾|恢復}。"
|
||||
HELP_ACTION_1: "僅過濾某個行為。"
|
||||
HELP_ACTION_2: "範例: [a:block], [a:+block], [a:-block] [a:click], [a:container], [a:inventory], [a:item], [a:kill], [a:chat], [a:command], [a:sign], [a:session], [a:username]"
|
||||
HELP_COMMAND: "顯示該指令的更多資訊。"
|
||||
HELP_EXCLUDE_1: "排除方塊/玩家"
|
||||
HELP_EXCLUDE_2: "範例: [e:stone], [e:Notch], [e:stone,Notch]"
|
||||
HELP_HEADER: "{0} 說明"
|
||||
HELP_INCLUDE_1: "包括指定的方塊/實體"
|
||||
HELP_INCLUDE_1: "僅過濾指定的方塊/實體"
|
||||
HELP_INCLUDE_2: "範例: [i:stone], [i:zombie], [i:stone,wood,bedrock]"
|
||||
HELP_INSPECT_1: "當檢查器啟用後,你可以執行以下操作: "
|
||||
HELP_INSPECT_2: "對你欲查詢的方塊點擊左鍵,可以查看方塊放置記錄。"
|
||||
HELP_INSPECT_3: "對你欲查詢的方塊點擊右鍵,可以查看相鄰方塊破壞記錄。"
|
||||
HELP_INSPECT_4: "對你欲查詢的位置放置方塊,可以查看放置位置破壞記錄。"
|
||||
HELP_INSPECT_5: "對你欲查詢的液體中放置方塊,可以查看液體變更記錄。"
|
||||
HELP_INSPECT_6: "對你欲查詢的門、儲物箱等方塊點擊右鍵,可以查看使用記錄。"
|
||||
HELP_INSPECT_7: "小提醒: 你可以使用 \"/co i\" 來加快搜尋的速度。"
|
||||
HELP_INSPECT_COMMAND: "開啟或關閉檢查器。"
|
||||
HELP_INSPECT_1: "當檢查器啟用後,你可以執行以下操作:"
|
||||
HELP_INSPECT_2: "對你欲查詢的方塊點擊左鍵,可以查看方塊放置紀錄。"
|
||||
HELP_INSPECT_3: "對你欲查詢的方塊點擊右鍵,可以查看相鄰方塊破壞紀錄。"
|
||||
HELP_INSPECT_4: "對你欲查詢的位置放置方塊,可以查看放置位置破壞紀錄。"
|
||||
HELP_INSPECT_5: "對你欲查詢的液體中放置方塊,可以查看液體變更紀錄。"
|
||||
HELP_INSPECT_6: "對你欲查詢的門、儲物箱等方塊點擊右鍵,可以查看使用紀錄。"
|
||||
HELP_INSPECT_7: "小提醒: 你可以使用「/co i」來快速啟用或停用檢查器。"
|
||||
HELP_INSPECT_COMMAND: "啟用或停用檢查器。"
|
||||
HELP_LIST: "顯示所有指令列表。"
|
||||
HELP_LOOKUP_1: "指令捷徑"
|
||||
HELP_LOOKUP_2: "在使用檢查器檢查後以便查看日誌。"
|
||||
HELP_LOOKUP_COMMAND: "進階查詢方塊的資料。"
|
||||
HELP_NO_INFO: "未找到 \"{0}\" 的相關指令資訊。"
|
||||
HELP_PARAMETER: "若需查看相關詳細參數資訊,請查閱 \"{0}\"。"
|
||||
HELP_LOOKUP_COMMAND: "進階查詢方塊資料。"
|
||||
HELP_NO_INFO: "未找到「{0}」的相關指令資訊。"
|
||||
HELP_PARAMETER: "若需查看相關詳細參數資訊,請查閱「{0}」。"
|
||||
HELP_PARAMS_1: "執行{查詢|回滾|恢復}。"
|
||||
HELP_PARAMS_2: "指定需要{查詢|回滾|恢復}的玩家。"
|
||||
HELP_PARAMS_3: "指定需要{查詢|回滾|恢復}的時間範圍。"
|
||||
|
@ -60,12 +63,12 @@ HELP_PARAMS_4: "指定限制{查詢|回滾|恢復}的範圍。"
|
|||
HELP_PARAMS_5: "將{查詢|回滾|恢復}限制在某個行為。"
|
||||
HELP_PARAMS_6: "在{查詢|回滾|恢復}中指定特定的實體/方塊。"
|
||||
HELP_PARAMS_7: "從{查詢|回滾|恢復}中排除特定的方塊/玩家。"
|
||||
HELP_PURGE_1: "刪除了指定時間範圍的資料。"
|
||||
HELP_PURGE_2: "舉例來說,\"{0}\" 將會刪除超過一個月的所有方塊資料,只保留最近 30 天的資料。"
|
||||
HELP_PURGE_COMMAND: "刪除舊的方塊資料。"
|
||||
HELP_PURGE_1: "清除指定時間範圍內的資料。"
|
||||
HELP_PURGE_2: "舉例來說,「{0}」將會清除超過一個月的所有資料,只保留最近 30 天的資料。"
|
||||
HELP_PURGE_COMMAND: "清除舊資料。"
|
||||
HELP_RADIUS_1: "指定半徑範圍。"
|
||||
HELP_RADIUS_2: "範例: [r:10] (僅會更改你周圍的 10 格方塊)"
|
||||
HELP_RELOAD_COMMAND: "重新載入配置檔案。"
|
||||
HELP_RADIUS_2: "範例: [r:10](僅會更改你周圍的 10 格方塊)"
|
||||
HELP_RELOAD_COMMAND: "重新載入設定檔。"
|
||||
HELP_RESTORE_COMMAND: "恢復方塊資料。"
|
||||
HELP_ROLLBACK_COMMAND: "回滾方塊資料。"
|
||||
HELP_STATUS: "查看插件狀態與版本資訊。"
|
||||
|
@ -75,106 +78,106 @@ HELP_TIME_1: "指定搜尋的時間範圍。"
|
|||
HELP_TIME_2: "範例: [t:2w,5d,7h,2m,10s], [t:5d2h], [t:2.50h]"
|
||||
HELP_USER_1: "指定要搜尋的玩家。"
|
||||
HELP_USER_2: "範例: [u:Notch], [u:Notch,#enderman]"
|
||||
INCOMPATIBLE_ACTION: "\"{0}\" 不能用於此操作。"
|
||||
INSPECTOR_ERROR: "已{開啟|關閉}檢查器了。"
|
||||
INSPECTOR_TOGGLED: "已{開啟|關閉}檢查器。"
|
||||
INTEGRATION_ERROR: "無法{初始化|關閉} {0} 日誌記錄。"
|
||||
INTEGRATION_SUCCESS: "{0} 成功記錄{初始化|關閉}。"
|
||||
INTEGRATION_VERSION: "發現 {0} 版本無效。"
|
||||
INCOMPATIBLE_ACTION: "「{0}」不能用於此行為。"
|
||||
INSPECTOR_ERROR: "檢查器已經{啟用|停用}了。"
|
||||
INSPECTOR_TOGGLED: "已{啟用|停用}檢查器。"
|
||||
INTEGRATION_ERROR: "無法{初始化|停用}{0}紀錄檔。"
|
||||
INTEGRATION_SUCCESS: "{0} 紀錄檔已成功{初始化|停用}。"
|
||||
INTEGRATION_VERSION: "{0} 的版本無效。"
|
||||
INTERACTIONS_HEADER: "玩家互動"
|
||||
INVALID_ACTION: "這不是有效的行為。"
|
||||
INVALID_BRANCH_1: "插件版本無效 (未設定分支)。"
|
||||
INVALID_BRANCH_2: "若要繼續行為,請將你的項目分之設定為 \"development\"。"
|
||||
INVALID_BRANCH_3: "執行開發中的插件可能會導致資料損毀。"
|
||||
INVALID_CONTAINER: "請先檢查有效的容器。"
|
||||
INVALID_DONATION_KEY: "無效的捐贈金鑰。"
|
||||
INVALID_INCLUDE: "\"{0}\" 是無效的方塊/實體名稱。"
|
||||
INVALID_INCLUDE_COMBO: "這是無效的方塊/實體組合。"
|
||||
INVALID_RADIUS: "請輸入有效的範圍。"
|
||||
INVALID_SELECTION: "未找到選擇 {0} 的內容。"
|
||||
INVALID_USERNAME: "\"{0}\" 是無效的玩家名稱。"
|
||||
INVALID_WORLD: "請指定有效的世界。"
|
||||
INVALID_ACTION: "此並非有效的行為。"
|
||||
INVALID_BRANCH_1: "插件版本無效(未設定分支)。"
|
||||
INVALID_BRANCH_2: "若要繼續,請將分支設定為「development」。"
|
||||
INVALID_BRANCH_3: "執行開發中的插件版本可能會導致資料損毀。"
|
||||
INVALID_CONTAINER: "此並非有效的容器。"
|
||||
INVALID_DONATION_KEY: "無效的贊助金鑰。"
|
||||
INVALID_INCLUDE: "「{0}」為無效的方塊/實體名稱。"
|
||||
INVALID_INCLUDE_COMBO: "此為無效的方塊/實體組合。"
|
||||
INVALID_RADIUS: "此並非有效的範圍。"
|
||||
INVALID_SELECTION: "「{0}」為無效的選擇範圍。"
|
||||
INVALID_USERNAME: "「{0}」為無效的使用者名稱。"
|
||||
INVALID_WORLD: "此並非有效的世界。"
|
||||
LATEST_VERSION: "最新版本: {0}"
|
||||
LINK_DISCORD: "Discord: {0}"
|
||||
LINK_DOWNLOAD: "下載: {0}"
|
||||
LINK_PATREON: "Patreon: {0}"
|
||||
LINK_WIKI_BLOCK: "方塊名稱: {0}"
|
||||
LINK_WIKI_ENTITY: "實體名稱: {0}"
|
||||
LOGGING_ITEMS: "還剩 {0} 項要進行記錄,請稍候……"
|
||||
LOGGING_TIME_LIMIT: "已達到記錄的時間上限,正在刪除資料並關閉……"
|
||||
LOGGING_ITEMS: "還剩 {0} 項要進行紀錄,請稍候……"
|
||||
LOGGING_TIME_LIMIT: "已達到紀錄的時間上限,正在捨棄資料並停用……"
|
||||
LOOKUP_BLOCK: "{0} {放置|破壞} {1}。"
|
||||
LOOKUP_CONTAINER: "{0} {新增|刪除} {1} {2}。"
|
||||
LOOKUP_HEADER: "{0} 搜尋結果。"
|
||||
LOOKUP_CONTAINER: "{0} {存入|取出} {1} {2}。"
|
||||
LOOKUP_HEADER: "{0} 條搜尋結果。"
|
||||
LOOKUP_INTERACTION: "{0} {點擊|殺死} {1}。"
|
||||
LOOKUP_ITEM: "{0} {撿起|拋棄} {1} {2}。"
|
||||
LOOKUP_LOGIN: "{0} 已登{入|出}。"
|
||||
LOOKUP_PAGE: "第 {0} 頁"
|
||||
LOOKUP_ROWS_FOUND: "已找到 {0} {行|行}。"
|
||||
LOOKUP_PROJECTILE: "{0} {扔|射} {1} {2}."
|
||||
LOOKUP_ROWS_FOUND: "已找到 {0} {條|條}。"
|
||||
LOOKUP_SEARCHING: "正在搜尋,請稍候……"
|
||||
LOOKUP_STORAGE: "{0} {存|取} {1} {2}。"
|
||||
LOOKUP_STORAGE: "{0} {存入|取出} {1} {2}。"
|
||||
LOOKUP_TIME: "{0} 前"
|
||||
LOOKUP_USERNAME: "{0} 以 {1} 的身分登入。"
|
||||
LOOKUP_VIEW_PAGE: "若要查看指定頁面,請輸入 \"{0}\"。"
|
||||
MAXIMUM_RADIUS: "最大 {查詢|回滾|恢復} 的範圍為 {0}。"
|
||||
MISSING_ACTION_USER: "若要使用此操作,請指定玩家。"
|
||||
LOOKUP_USERNAME: "{0} 已改變使用者名稱為 {1}。"
|
||||
MAXIMUM_RADIUS: "最大{查詢|回滾|恢復}的範圍為 {0}。"
|
||||
MISSING_ACTION_USER: "若要使用此行為,請指定玩家。"
|
||||
MISSING_LOOKUP_TIME: "請指定{查詢|回滾|恢復}的時間範圍。"
|
||||
MISSING_LOOKUP_USER: "請指定搜尋的玩家或是{方塊|範圍}。"
|
||||
MISSING_PARAMETERS: "請使用 \"{0}\"。"
|
||||
MISSING_PARAMETERS: "請使用「{0}」。"
|
||||
MISSING_ROLLBACK_RADIUS: "你沒有指定{回滾|恢復}的範圍。"
|
||||
MISSING_ROLLBACK_USER: "你沒有指定{回滾|恢復}的玩家。"
|
||||
MYSQL_UNAVAILABLE: "無法連線到 MySQL 伺服器。"
|
||||
NO_DATA: "找不到 {0} §f的資料。"
|
||||
NO_DATA_LOCATION: "找不到這個位置的{資料|交易|互動|訊息}。"
|
||||
NO_DATA: "未找到 {0} §f的資料。"
|
||||
NO_DATA_LOCATION: "未找到此位置的{資料|交易|互動|訊息}。"
|
||||
NO_PERMISSION: "你沒有使用該操作的權限。"
|
||||
NO_RESULTS: "未找到相關結果。"
|
||||
NO_RESULTS_PAGE: "未找到該頁面相關的{結果|資料}。"
|
||||
NO_ROLLBACK: "未找到{待處理|上一個}回滾/恢復。"
|
||||
PATCH_INTERRUPTED: "更新已中斷 ! 將會在下次重新啟動時再次嘗試。"
|
||||
PATCH_INTERRUPTED: "更新已中斷!將會在下次啟動時再次嘗試。"
|
||||
PATCH_OUTDATED_1: "無法更新早於 {0} 的資料庫。"
|
||||
PATCH_OUTDATED_2: "請使用受到支援的 CoreProtect 版本。"
|
||||
PATCH_PROCESSING: "正在處理新資訊,請稍候……"
|
||||
PATCH_SKIP_UPDATE: "已在 {0} 上跳過{列表|索引}的{更新|建立|刪除}。"
|
||||
PATCH_SKIP_UPDATE: "已在 {0} 上跳過{資料表|索引}的{更新|建立|清除}。"
|
||||
PATCH_STARTED: "正在執行 {0} 更新,請稍候……"
|
||||
PATCH_SUCCESS: "已成功升級到 {0}。"
|
||||
PATCH_UPGRADING: "正在進行資料庫升級,請稍候……"
|
||||
PLEASE_SELECT: "請選擇: \"{0}\" 或是 \"{1}\"。"
|
||||
PATCH_SUCCESS: "資料庫已成功更新到 {0}。"
|
||||
PATCH_UPGRADING: "正在進行資料庫更新,請稍候……"
|
||||
PLEASE_SELECT: "請選擇:「{0}」或是「{1}」。"
|
||||
PREVIEW_CANCELLED: "預覽已取消。"
|
||||
PREVIEW_CANCELLING: "正在取消預覽……"
|
||||
PREVIEW_CONTAINER: "你無法預覽容器內的物品資料。"
|
||||
PREVIEW_IN_GAME: "你只能在遊戲中預覽回滾。"
|
||||
PREVIEW_TRANSACTION: "您無法預覽{集裝箱|庫存}交易。"
|
||||
PURGE_ABORTED: "清除失敗,你的資料可能已損毀。"
|
||||
PURGE_ERROR: "無法處理 {0} 條資料 !"
|
||||
PURGE_ERROR: "無法處理 {0} 筆資料!"
|
||||
PURGE_FAILED: "清除失敗,請稍後再試。"
|
||||
PURGE_IN_PROGRESS: "正在執行清除作業,請稍後再試。"
|
||||
PURGE_MINIMUM_TIME: "你只能清除早於 {0} {天|小時}的資料。"
|
||||
PURGE_NOTICE_1: "請注意,此操作可能需要一些時間。"
|
||||
PURGE_NOTICE_2: "在完成此程序前請不要重新啟動伺服器。"
|
||||
PURGE_OPTIMIZING: "正在最佳化資料庫,請稍候……"
|
||||
PURGE_PROCESSING: "正在處理 {0} 資料……"
|
||||
PURGE_REPAIRING: "正在嘗試修復此問題,這可能需要一些時間。"
|
||||
PURGE_ROWS: "已刪除 {0} {行|行}資料。"
|
||||
PURGE_STARTED: "資料刪除開始於 \"{0}\"。"
|
||||
PURGE_PROCESSING: "正在清除 {0} 筆資料……"
|
||||
PURGE_REPAIRING: "正在嘗試修復問題,這可能需要一些時間。"
|
||||
PURGE_ROWS: "已清除 {0} {筆|筆}資料。"
|
||||
PURGE_STARTED: "資料清除開始於「{0}」。"
|
||||
PURGE_SUCCESS: "成功清除資料。"
|
||||
RELOAD_STARTED: "正在重新載入配置檔案 - 請稍候……"
|
||||
RELOAD_SUCCESS: "成功重新載入配置檔案。"
|
||||
ROLLBACK_ABORTED: "已中止回滾/恢復。"
|
||||
RELOAD_STARTED: "正在重新載入設定檔——請稍候……"
|
||||
RELOAD_SUCCESS: "成功重新載入設定檔。"
|
||||
ROLLBACK_ABORTED: "已中斷回滾/恢復。"
|
||||
ROLLBACK_CHUNKS_FOUND: "找到 {0} 個{區塊|區塊}需要修改。"
|
||||
ROLLBACK_CHUNKS_MODIFIED: "已修改 {0}/{1}個{區塊|區塊}。"
|
||||
ROLLBACK_COMPLETED: "已完成 \"{0}\" 的{回滾|恢復|預覽}。"
|
||||
ROLLBACK_EXCLUDED_USERS: "已排除{玩家|玩家}: \"{0}\"。"
|
||||
ROLLBACK_INCLUDE: "{包括|不包括}{方塊|實體|目標}{類型|類型}: \"{0}\"。"
|
||||
ROLLBACK_COMPLETED: "已完成「{0}」的{回滾|恢復|預覽}。"
|
||||
ROLLBACK_EXCLUDED_USERS: "已排除{玩家|玩家}「{0}」。"
|
||||
ROLLBACK_INCLUDE: "{包括|不包括}{方塊|實體|目標}{類型|類型}「{0}」。"
|
||||
ROLLBACK_IN_PROGRESS: "已在進行回滾/恢復。"
|
||||
ROLLBACK_LENGTH: "花費時間: {0} {秒|秒}。"
|
||||
ROLLBACK_MODIFIED: "{已修改|正在修改} {0}。"
|
||||
ROLLBACK_RADIUS: "範圍: {0} {方塊|方塊}。"
|
||||
ROLLBACK_SELECTION: "範圍設定為 \"{0}\"。"
|
||||
ROLLBACK_STARTED: "{回滾|恢復|預覽}開始於 \"{0}\"。"
|
||||
ROLLBACK_RADIUS: "範圍: {0} 格{方塊|方塊}。"
|
||||
ROLLBACK_SELECTION: "選擇範圍為「{0}」。"
|
||||
ROLLBACK_STARTED: "{回滾|恢復|預覽}開始於「{0}」。"
|
||||
ROLLBACK_TIME: "時間範圍: {0}。"
|
||||
ROLLBACK_WORLD_ACTION: "限制{世界|互動} \"{0}\"。"
|
||||
ROLLBACK_WORLD_ACTION: "限制{世界|行為}「{0}」。"
|
||||
SIGN_HEADER: "簽名訊息"
|
||||
STATUS_CONSUMER: "玩家: {0} 個{物品|物品}已在隊列中。"
|
||||
STATUS_CONSUMER: "消費者隊列: {0} 筆{資料|資料}在隊列中。"
|
||||
STATUS_DATABASE: "資料庫: 使用 {0}。"
|
||||
STATUS_INTEGRATION: "{0}: 整合{開啟|關閉}。"
|
||||
STATUS_INTEGRATION: "{0}: 整合{啟用|停用}。"
|
||||
STATUS_LICENSE: "憑證: {0}"
|
||||
STATUS_VERSION: "版本: {0}"
|
||||
TELEPORTED: "傳送到 {0}。"
|
||||
|
@ -189,10 +192,11 @@ UPDATE_ERROR: "檢查更新時發生錯誤。"
|
|||
UPDATE_HEADER: "{0} 更新"
|
||||
UPDATE_NOTICE: "通知: {0} 現已推出。"
|
||||
UPGRADE_IN_PROGRESS: "正在進行更新,請稍後再試。"
|
||||
USER_NOT_FOUND: "找不到玩家 \"{0}\"。"
|
||||
USER_NOT_FOUND: "未找到玩家「{0}」。"
|
||||
USER_OFFLINE: "用戶「{0}」不在線上。"
|
||||
USING_MYSQL: "使用 MySQL 進行資料儲存。"
|
||||
USING_SQLITE: "使用 SQLite 進行資料儲存。"
|
||||
VALID_DONATION_KEY: "有效的贈品金鑰"
|
||||
VALID_DONATION_KEY: "有效的贊助金鑰"
|
||||
VERSION_NOTICE: "版本 {0} 現已推出。"
|
||||
VERSION_REQUIRED: "{0} 需要使用 {1} 或更高版本。 "
|
||||
WORLD_NOT_FOUND: "世界: \"{0}\" 不存在。"
|
||||
VERSION_REQUIRED: "{0} 需要使用 {1} 或更高版本。"
|
||||
WORLD_NOT_FOUND: "世界「{0}」不存在。"
|
|
@ -4,4 +4,4 @@ theme: readthedocs
|
|||
repo_url: https://github.com/PlayPro/CoreProtect
|
||||
docs_dir: 'docs'
|
||||
extra_css:
|
||||
- css/extra.css
|
||||
- css/extra.css
|
50
pom.xml
50
pom.xml
|
@ -2,7 +2,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>net.coreprotect</groupId>
|
||||
<artifactId>CoreProtect</artifactId>
|
||||
<version>20.2</version>
|
||||
<version>22.4</version>
|
||||
<properties>
|
||||
<project.branch></project.branch>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
@ -25,8 +25,8 @@
|
|||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
@ -51,6 +51,14 @@
|
|||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
<artifactSet>
|
||||
<excludes>
|
||||
<exclude>com.google.code.gson:*</exclude>
|
||||
<exclude>org.intellij:*</exclude>
|
||||
<exclude>org.jetbrains:*</exclude>
|
||||
<exclude>org.slf4j:*</exclude>
|
||||
</excludes>
|
||||
</artifactSet>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.bstats</pattern>
|
||||
|
@ -74,19 +82,27 @@
|
|||
</repository>
|
||||
<repository>
|
||||
<id>paper-repo</id>
|
||||
<url>https://papermc.io/repo/repository/maven-public/</url>
|
||||
<url>https://repo.papermc.io/repository/maven-public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<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
|
||||
paper-api (<= 1.16): com.destroystokyo.paper
|
||||
spigot-api: org.spigotmc
|
||||
bukkit: org.bukkit
|
||||
|
@ -94,7 +110,7 @@
|
|||
<dependency>
|
||||
<groupId>io.papermc.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<version>1.17-R0.1-SNAPSHOT</version>
|
||||
<version>1.20.4-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -104,21 +120,25 @@
|
|||
<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>
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>4.0.3</version>
|
||||
<version>5.0.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -1 +1 @@
|
|||
mkdocs==1.2.3
|
||||
mkdocs==1.3.1
|
|
@ -1,9 +1,14 @@
|
|||
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;
|
||||
|
||||
|
@ -16,10 +21,14 @@ import net.coreprotect.consumer.process.Process;
|
|||
import net.coreprotect.language.Language;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.listener.ListenerHandler;
|
||||
import net.coreprotect.listener.player.PlayerQuitListener;
|
||||
import net.coreprotect.paper.PaperAdapter;
|
||||
import net.coreprotect.thread.CacheHandler;
|
||||
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 {
|
||||
|
@ -91,7 +100,7 @@ public final class CoreProtect extends JavaPlugin {
|
|||
Chat.console(Phrase.build(Phrase.LINK_DISCORD, "www.coreprotect.net/discord/"));
|
||||
Chat.console("--------------------");
|
||||
|
||||
getServer().getScheduler().scheduleSyncDelayedTask(this, () -> {
|
||||
Scheduler.scheduleSyncDelayedTask(this, () -> {
|
||||
try {
|
||||
Thread networkHandler = new Thread(new NetworkHandler(true, true));
|
||||
networkHandler.start();
|
||||
|
@ -157,6 +166,22 @@ public final class CoreProtect extends JavaPlugin {
|
|||
|
||||
private static void safeShutdown(CoreProtect plugin) {
|
||||
try {
|
||||
/* if server is stopping, log disconnections of online players */
|
||||
if (ConfigHandler.serverRunning && PaperAdapter.ADAPTER.isStopping(plugin.getServer())) {
|
||||
for (Player player : plugin.getServer().getOnlinePlayers()) {
|
||||
PlayerQuitListener.queuePlayerQuit(player);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -189,6 +214,7 @@ public final class CoreProtect extends JavaPlugin {
|
|||
Thread.sleep(100);
|
||||
}
|
||||
|
||||
ConfigHandler.performDisable();
|
||||
Chat.console(Phrase.build(Phrase.DISABLE_SUCCESS, "CoreProtect v" + plugin.getDescription().getVersion()));
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
|
|
@ -3,8 +3,10 @@ package net.coreprotect;
|
|||
import java.sql.Connection;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
|
@ -16,12 +18,14 @@ import org.bukkit.block.data.BlockData;
|
|||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import net.coreprotect.api.BlockAPI;
|
||||
import net.coreprotect.api.QueueLookup;
|
||||
import net.coreprotect.api.SessionLookup;
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.database.Database;
|
||||
import net.coreprotect.database.Lookup;
|
||||
import net.coreprotect.database.Rollback;
|
||||
import net.coreprotect.database.lookup.BlockLookupAPI;
|
||||
import net.coreprotect.database.rollback.Rollback;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.listener.player.InventoryChangeListener;
|
||||
import net.coreprotect.utility.Chat;
|
||||
|
@ -42,8 +46,18 @@ public class CoreProtectAPI extends Queue {
|
|||
|
||||
public String getActionString() {
|
||||
int actionID = Integer.parseInt(parse[7]);
|
||||
String result = "unknown";
|
||||
if (parse.length < 13 && Integer.parseInt(parse[6]) == SessionLookup.ID) {
|
||||
switch (actionID) {
|
||||
case 0:
|
||||
return "logout";
|
||||
case 1:
|
||||
return "login";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
String result = "unknown";
|
||||
if (actionID == 0) {
|
||||
result = "break";
|
||||
}
|
||||
|
@ -79,6 +93,10 @@ public class CoreProtectAPI extends Queue {
|
|||
}
|
||||
|
||||
public Material getType() {
|
||||
if (parse.length < 13) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int actionID = this.getActionId();
|
||||
int type = Integer.parseInt(parse[5]);
|
||||
String typeName;
|
||||
|
@ -95,8 +113,12 @@ public class CoreProtectAPI extends Queue {
|
|||
}
|
||||
|
||||
public BlockData getBlockData() {
|
||||
if (parse.length < 13) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String blockData = parse[12];
|
||||
if (blockData.length() == 0) {
|
||||
if (blockData == null || blockData.length() == 0) {
|
||||
return getType().createBlockData();
|
||||
}
|
||||
return Bukkit.getServer().createBlockData(blockData);
|
||||
|
@ -115,25 +137,29 @@ public class CoreProtectAPI extends Queue {
|
|||
}
|
||||
|
||||
public boolean isRolledBack() {
|
||||
return Integer.parseInt(parse[8]) == 1;
|
||||
if (parse.length < 13) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Integer.parseInt(parse[8]) == 1 || Integer.parseInt(parse[8]) == 3);
|
||||
}
|
||||
|
||||
public String worldName() {
|
||||
return Util.getWorldName(Integer.parseInt(parse[9]));
|
||||
return Util.getWorldName(Integer.parseInt(parse.length < 13 ? parse[5] : parse[9]));
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Object> parseList(List<Object> list) {
|
||||
List<Object> result = new ArrayList<>();
|
||||
private static Map<Object, Boolean> parseList(List<Object> list) {
|
||||
Map<Object, Boolean> result = new HashMap<>();
|
||||
|
||||
if (list != null) {
|
||||
for (Object value : list) {
|
||||
if (value instanceof Material || value instanceof EntityType) {
|
||||
result.add(value);
|
||||
result.put(value, false);
|
||||
}
|
||||
else if (value instanceof Integer) {
|
||||
Material material = Util.getType((Integer) value);
|
||||
result.add(material);
|
||||
result.put(material, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,23 +168,31 @@ public class CoreProtectAPI extends Queue {
|
|||
}
|
||||
|
||||
public int APIVersion() {
|
||||
return 8;
|
||||
return 10;
|
||||
}
|
||||
|
||||
public List<String[]> blockLookup(Block block, int time) {
|
||||
if (Config.getGlobal().API_ENABLED) {
|
||||
return BlockLookupAPI.performLookup(block, time);
|
||||
return BlockAPI.performLookup(block, time);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String[]> queueLookup(Block block) {
|
||||
return QueueLookup.performLookup(block);
|
||||
}
|
||||
|
||||
public List<String[]> sessionLookup(String user, int time) {
|
||||
return SessionLookup.performLookup(user, time);
|
||||
}
|
||||
|
||||
public boolean hasPlaced(String user, Block block, int time, int offset) {
|
||||
// Determine if a user has placed a block at this location in the last # of seconds.
|
||||
boolean match = false;
|
||||
|
||||
if (Config.getGlobal().API_ENABLED) {
|
||||
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) {
|
||||
|
@ -178,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) {
|
||||
|
@ -232,7 +266,7 @@ public class CoreProtectAPI extends Queue {
|
|||
if (Config.getGlobal().API_ENABLED) {
|
||||
if (user != null && location != null) {
|
||||
if (user.length() > 0) {
|
||||
Queue.queuePlayerInteraction(user, location.getBlock().getState());
|
||||
Queue.queuePlayerInteraction(user, location.getBlock().getState(), location.getBlock().getType());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -248,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) {
|
||||
|
@ -282,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) {
|
||||
|
@ -385,7 +445,7 @@ public class CoreProtectAPI extends Queue {
|
|||
return null;
|
||||
}
|
||||
|
||||
private List<String[]> processData(int time, int radius, Location location, List<Object> restrictBlocks, List<Object> excludeBlocks, List<String> restrictUsers, List<String> excludeUsers, List<Integer> actionList, int action, int lookup, int offset, int rowCount, boolean useLimit) {
|
||||
private List<String[]> processData(int time, int radius, Location location, Map<Object, Boolean> restrictBlocksMap, Map<Object, Boolean> excludeBlocks, List<String> restrictUsers, List<String> excludeUsers, List<Integer> actionList, int action, int lookup, int offset, int rowCount, boolean useLimit) {
|
||||
// You need to either specify time/radius or time/user
|
||||
List<String[]> result = new ArrayList<>();
|
||||
List<String> uuids = new ArrayList<>();
|
||||
|
@ -402,6 +462,7 @@ public class CoreProtectAPI extends Queue {
|
|||
actionList = new ArrayList<>();
|
||||
}
|
||||
|
||||
List<Object> restrictBlocks = new ArrayList<>(restrictBlocksMap.keySet());
|
||||
if (actionList.size() == 0 && restrictBlocks.size() > 0) {
|
||||
boolean addedMaterial = false;
|
||||
boolean addedEntity = false;
|
||||
|
@ -431,7 +492,8 @@ public class CoreProtectAPI extends Queue {
|
|||
}
|
||||
|
||||
long timestamp = System.currentTimeMillis() / 1000L;
|
||||
long timePeriod = timestamp - time;
|
||||
long startTime = timestamp - time;
|
||||
long endTime = 0;
|
||||
|
||||
if (radius < 1) {
|
||||
radius = -1;
|
||||
|
@ -464,7 +526,7 @@ public class CoreProtectAPI extends Queue {
|
|||
int xMax = location.getBlockX() + radius;
|
||||
int zMin = location.getBlockZ() - radius;
|
||||
int zMax = location.getBlockZ() + radius;
|
||||
argRadius = new Integer[] { radius, xMin, xMax, -1, -1, zMin, zMax, 0 };
|
||||
argRadius = new Integer[] { radius, xMin, xMax, null, null, zMin, zMax, 0 };
|
||||
}
|
||||
|
||||
if (lookup == 1) {
|
||||
|
@ -473,16 +535,16 @@ public class CoreProtectAPI extends Queue {
|
|||
}
|
||||
|
||||
if (useLimit) {
|
||||
result = Lookup.performPartialLookup(statement, null, uuids, restrictUsers, restrictBlocks, excludeBlocks, excludeUsers, actionList, location, argRadius, timePeriod, offset, rowCount, restrictWorld, true);
|
||||
result = Lookup.performPartialLookup(statement, null, uuids, restrictUsers, restrictBlocks, excludeBlocks, excludeUsers, actionList, location, argRadius, null, startTime, endTime, offset, rowCount, restrictWorld, true);
|
||||
}
|
||||
else {
|
||||
result = Lookup.performLookup(statement, null, uuids, restrictUsers, restrictBlocks, excludeBlocks, excludeUsers, actionList, location, argRadius, timePeriod, restrictWorld, true);
|
||||
result = Lookup.performLookup(statement, null, uuids, restrictUsers, restrictBlocks, excludeBlocks, excludeUsers, actionList, location, argRadius, startTime, endTime, restrictWorld, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!Bukkit.isPrimaryThread()) {
|
||||
boolean verbose = false;
|
||||
result = Rollback.performRollbackRestore(statement, null, uuids, restrictUsers, null, restrictBlocks, excludeBlocks, excludeUsers, actionList, location, argRadius, timePeriod, restrictWorld, false, verbose, action, 0);
|
||||
result = Rollback.performRollbackRestore(statement, null, uuids, restrictUsers, null, restrictBlocks, excludeBlocks, excludeUsers, actionList, location, argRadius, startTime, endTime, restrictWorld, false, verbose, action, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -497,7 +559,7 @@ public class CoreProtectAPI extends Queue {
|
|||
}
|
||||
|
||||
@Deprecated
|
||||
private List<String[]> processData(String user, int time, int radius, Location location, List<Object> restrictBlocks, List<Object> excludeBlocks, int action, int lookup, int offset, int rowCount, boolean useLimit) {
|
||||
private List<String[]> processData(String user, int time, int radius, Location location, Map<Object, Boolean> restrictBlocks, Map<Object, Boolean> excludeBlocks, int action, int lookup, int offset, int rowCount, boolean useLimit) {
|
||||
ArrayList<String> restrictUsers = new ArrayList<>();
|
||||
if (user != null) {
|
||||
restrictUsers.add(user);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package net.coreprotect.database.lookup;
|
||||
package net.coreprotect.api;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -13,7 +13,7 @@ import net.coreprotect.database.Database;
|
|||
import net.coreprotect.database.statement.UserStatement;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class BlockLookupAPI {
|
||||
public class BlockAPI {
|
||||
|
||||
public static List<String[]> performLookup(Block block, int offset) {
|
||||
List<String[]> result = new ArrayList<>();
|
||||
|
@ -38,7 +38,7 @@ public class BlockLookupAPI {
|
|||
}
|
||||
|
||||
Statement statement = connection.createStatement();
|
||||
String query = "SELECT time,user,action,type,data,blockdata,rolled_back FROM " + ConfigHandler.prefix + "block WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND time > '" + checkTime + "' ORDER BY rowid DESC";
|
||||
String query = "SELECT time,user,action,type,data,blockdata,rolled_back FROM " + ConfigHandler.prefix + "block " + Util.getWidIndex("block") + "WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND time > '" + checkTime + "' ORDER BY rowid DESC";
|
||||
ResultSet results = statement.executeQuery(query);
|
||||
|
||||
while (results.next()) {
|
|
@ -0,0 +1,90 @@
|
|||
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;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.consumer.Consumer;
|
||||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.consumer.process.Process;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class QueueLookup extends Queue {
|
||||
|
||||
private QueueLookup() {
|
||||
throw new IllegalStateException("API class");
|
||||
}
|
||||
|
||||
public static List<String[]> performLookup(Block block) {
|
||||
List<String[]> result = new ArrayList<>();
|
||||
if (!Config.getGlobal().API_ENABLED) {
|
||||
return result;
|
||||
}
|
||||
|
||||
try {
|
||||
int consumerCount = 0;
|
||||
int currentConsumerSize = Process.getCurrentConsumerSize();
|
||||
if (currentConsumerSize == 0) {
|
||||
consumerCount = Consumer.getConsumerSize(0) + Consumer.getConsumerSize(1);
|
||||
}
|
||||
else {
|
||||
int consumerId = (Consumer.currentConsumer == 1) ? 1 : 0;
|
||||
consumerCount = Consumer.getConsumerSize(consumerId) + currentConsumerSize;
|
||||
}
|
||||
|
||||
if (consumerCount == 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int currentConsumer = Consumer.currentConsumer;
|
||||
ArrayList<Object[]> consumerData = Consumer.consumer.get(currentConsumer);
|
||||
Map<Integer, String[]> users = Consumer.consumerUsers.get(currentConsumer);
|
||||
Map<Integer, Object> consumerObject = Consumer.consumerObjects.get(currentConsumer);
|
||||
|
||||
Location oldLocation = block.getLocation();
|
||||
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) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] userData = users.get(id);
|
||||
Object objectData = consumerObject.get(id);
|
||||
if (userData != null && objectData != null && (objectData instanceof BlockState) && ((BlockState) objectData).getLocation().equals(oldLocation)) {
|
||||
Material blockType = (Material) data[2];
|
||||
int legacyData = (int) data[3];
|
||||
String blockData = (String) data[7];
|
||||
String user = userData[0];
|
||||
BlockState blockState = (BlockState) objectData;
|
||||
Location location = blockState.getLocation();
|
||||
int wid = Util.getWorldId(location.getWorld().getName());
|
||||
int resultType = Util.getBlockId(blockType);
|
||||
int time = (int) (System.currentTimeMillis() / 1000L);
|
||||
|
||||
String[] lookupData = new String[] { String.valueOf(time), user, String.valueOf(location.getBlockX()), String.valueOf(location.getBlockY()), String.valueOf(location.getBlockZ()), String.valueOf(resultType), String.valueOf(legacyData), String.valueOf(action), "0", String.valueOf(wid), blockData };
|
||||
String[] lineData = Util.toStringArray(lookupData);
|
||||
result.add(lineData);
|
||||
}
|
||||
}
|
||||
|
||||
Collections.reverse(result);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package net.coreprotect.api;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.Database;
|
||||
import net.coreprotect.database.statement.UserStatement;
|
||||
|
||||
public class SessionLookup {
|
||||
|
||||
public static final int ID = 0;
|
||||
|
||||
private SessionLookup() {
|
||||
throw new IllegalStateException("API class");
|
||||
}
|
||||
|
||||
public static List<String[]> performLookup(String user, int offset) {
|
||||
List<String[]> result = new ArrayList<>();
|
||||
if (!Config.getGlobal().API_ENABLED) {
|
||||
return result;
|
||||
}
|
||||
|
||||
try (Connection connection = Database.getConnection(false, 1000)) {
|
||||
if (connection == null || user == null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
String type = String.valueOf(ID);
|
||||
int time = (int) (System.currentTimeMillis() / 1000L);
|
||||
int checkTime = 0;
|
||||
if (offset > 0) {
|
||||
checkTime = time - offset;
|
||||
}
|
||||
|
||||
if (ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT)) == null) {
|
||||
UserStatement.loadId(connection, user, null);
|
||||
}
|
||||
int userId = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
|
||||
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
String query = "SELECT time,user,wid,x,y,z,action FROM " + ConfigHandler.prefix + "session WHERE user = '" + userId + "' AND time > '" + checkTime + "' ORDER BY rowid DESC";
|
||||
ResultSet results = statement.executeQuery(query);
|
||||
while (results.next()) {
|
||||
String resultTime = results.getString("time");
|
||||
int resultUserId = results.getInt("user");
|
||||
String resultWorldId = results.getString("wid");
|
||||
String resultX = results.getString("x");
|
||||
String resultY = results.getString("y");
|
||||
String resultZ = results.getString("z");
|
||||
String resultAction = results.getString("action");
|
||||
|
||||
if (ConfigHandler.playerIdCacheReversed.get(resultUserId) == null) {
|
||||
UserStatement.loadName(connection, resultUserId);
|
||||
}
|
||||
String resultUser = ConfigHandler.playerIdCacheReversed.get(resultUserId);
|
||||
|
||||
String[] lookupData = new String[] { resultTime, resultUser, resultX, resultY, resultZ, resultWorldId, type, resultAction };
|
||||
result.add(lookupData);
|
||||
}
|
||||
results.close();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -3,18 +3,30 @@ package net.coreprotect.bukkit;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
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;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
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;
|
||||
|
@ -27,23 +39,33 @@ public class BukkitAdapter implements BukkitInterface {
|
|||
public static final int BUKKIT_V1_15 = 15;
|
||||
public static final int BUKKIT_V1_16 = 16;
|
||||
public static final int BUKKIT_V1_17 = 17;
|
||||
public static final int BUKKIT_V1_18 = 18;
|
||||
public static final int BUKKIT_V1_19 = 19;
|
||||
public static final int BUKKIT_V1_20 = 20;
|
||||
|
||||
public static void loadAdapter() {
|
||||
switch (ConfigHandler.SERVER_VERSION) {
|
||||
case BUKKIT_V1_13:
|
||||
case BUKKIT_V1_14:
|
||||
BukkitAdapter.ADAPTER = new BukkitAdapter();
|
||||
break;
|
||||
case BUKKIT_V1_15:
|
||||
BukkitAdapter.ADAPTER = new Bukkit_v1_15();
|
||||
BukkitAdapter.ADAPTER = new BukkitAdapter();
|
||||
break;
|
||||
case BUKKIT_V1_16:
|
||||
BukkitAdapter.ADAPTER = new Bukkit_v1_16();
|
||||
break;
|
||||
case BUKKIT_V1_17:
|
||||
default:
|
||||
BukkitAdapter.ADAPTER = new Bukkit_v1_17();
|
||||
break;
|
||||
case BUKKIT_V1_18:
|
||||
BukkitAdapter.ADAPTER = new Bukkit_v1_18();
|
||||
break;
|
||||
case BUKKIT_V1_19:
|
||||
BukkitAdapter.ADAPTER = new Bukkit_v1_19();
|
||||
break;
|
||||
case BUKKIT_V1_20:
|
||||
default:
|
||||
BukkitAdapter.ADAPTER = new Bukkit_v1_20();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,11 +113,6 @@ public class BukkitAdapter implements BukkitInterface {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSignChange(Player player, Sign sign) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinHeight(World world) {
|
||||
return 0;
|
||||
|
@ -116,19 +133,24 @@ public class BukkitAdapter implements BukkitInterface {
|
|||
return Material.ITEM_FRAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getFrameType(EntityType type) {
|
||||
return type == EntityType.ITEM_FRAME ? Material.ITEM_FRAME : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getFrameClass(Material material) {
|
||||
return ItemFrame.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGlowing(Sign sign) {
|
||||
public boolean isGlowing(Sign sign, boolean isFront) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGlowing(Sign sign, boolean set) {
|
||||
return;
|
||||
public boolean isWaxed(Sign sign) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -136,4 +158,130 @@ public class BukkitAdapter implements BukkitInterface {
|
|||
return Util.isAir(material);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack adjustIngredient(MerchantRecipe recipe, ItemStack itemStack) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGlowing(Sign sign, boolean isFront, boolean isGlowing) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(Sign sign, boolean isFront, int color) {
|
||||
if (!isFront) {
|
||||
return;
|
||||
}
|
||||
|
||||
sign.setColor(DyeColor.getByColor(Color.fromRGB(color)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWaxed(Sign sign, boolean isWaxed) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor(Sign sign, boolean isFront) {
|
||||
if (isFront) {
|
||||
return sign.getColor().getColor().asRGB();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getPlantSeeds(Material material) {
|
||||
switch (material) {
|
||||
case WHEAT:
|
||||
material = Material.WHEAT_SEEDS;
|
||||
break;
|
||||
case PUMPKIN_STEM:
|
||||
material = Material.PUMPKIN_SEEDS;
|
||||
break;
|
||||
case MELON_STEM:
|
||||
material = Material.MELON_SEEDS;
|
||||
break;
|
||||
case BEETROOTS:
|
||||
material = Material.BEETROOT_SEEDS;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDecoratedPot(Material material) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuspiciousBlock(Material material) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSign(Material material) {
|
||||
return Tag.SIGNS.isTagged(material);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChiseledBookshelf(Material material) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBookshelfBook(Material material) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getChiseledBookshelfBook(BlockState blockState, PlayerInteractEvent event) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLine(Sign sign, int line) {
|
||||
if (line < 4) {
|
||||
return sign.getLine(line);
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLine(Sign sign, int line, String string) {
|
||||
if (string == null) {
|
||||
string = "";
|
||||
}
|
||||
|
||||
if (line < 4) {
|
||||
sign.setLine(line, string);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSignFront(SignChangeEvent event) {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,20 +6,29 @@ import java.util.Map;
|
|||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
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;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
public interface BukkitInterface {
|
||||
|
||||
public ItemStack adjustIngredient(MerchantRecipe recipe, ItemStack itemStack);
|
||||
|
||||
public Material getBucketContents(Material material);
|
||||
|
||||
public Material getFrameType(Entity entity);
|
||||
|
||||
public Material getFrameType(EntityType type);
|
||||
|
||||
public Class<?> getFrameClass(Material material);
|
||||
|
||||
public String parseLegacyName(String name);
|
||||
|
@ -38,16 +47,44 @@ public interface BukkitInterface {
|
|||
|
||||
public boolean isItemFrame(Material material);
|
||||
|
||||
public boolean isGlowing(Sign sign);
|
||||
public boolean isGlowing(Sign sign, boolean isFront);
|
||||
|
||||
public boolean isInvisible(Material material);
|
||||
|
||||
public boolean isWaxed(Sign sign);
|
||||
|
||||
public int getMinHeight(World world);
|
||||
|
||||
public int getLegacyBlockId(Material material);
|
||||
|
||||
public void sendSignChange(Player player, Sign sign);
|
||||
public void setGlowing(Sign sign, boolean isFront, boolean isGlowing);
|
||||
|
||||
public void setGlowing(Sign sign, boolean b);
|
||||
public void setColor(Sign sign, boolean isFront, int color);
|
||||
|
||||
public void setWaxed(Sign sign, boolean isWaxed);
|
||||
|
||||
public int getColor(Sign sign, boolean isFront);
|
||||
|
||||
public Material getPlantSeeds(Material material);
|
||||
|
||||
public boolean isDecoratedPot(Material material);
|
||||
|
||||
public boolean isSuspiciousBlock(Material material);
|
||||
|
||||
public boolean isSign(Material material);
|
||||
|
||||
public boolean isChiseledBookshelf(Material material);
|
||||
|
||||
public boolean isBookshelfBook(Material material);
|
||||
|
||||
public ItemStack getChiseledBookshelfBook(BlockState blockState, PlayerInteractEvent event);
|
||||
|
||||
public String getLine(Sign sign, int line);
|
||||
|
||||
public void setLine(Sign sign, int line, String string);
|
||||
|
||||
public boolean isSignFront(SignChangeEvent event);
|
||||
|
||||
public ItemStack getArrowMeta(Arrow arrow, ItemStack itemStack);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
package net.coreprotect.bukkit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.entity.Bee;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SuspiciousStewMeta;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
||||
public class Bukkit_v1_15 extends BukkitAdapter implements BukkitInterface {
|
||||
|
||||
@Override
|
||||
public boolean getEntityMeta(LivingEntity entity, List<Object> info) {
|
||||
if (entity instanceof Bee) {
|
||||
Bee bee = (Bee) entity;
|
||||
info.add(bee.getAnger());
|
||||
info.add(bee.hasNectar());
|
||||
info.add(bee.hasStung());
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setEntityMeta(Entity entity, Object value, int count) {
|
||||
if (entity instanceof Bee) {
|
||||
Bee bee = (Bee) entity;
|
||||
if (count == 0) {
|
||||
int set = (int) value;
|
||||
bee.setAnger(set);
|
||||
}
|
||||
else if (count == 1) {
|
||||
boolean set = (Boolean) value;
|
||||
bee.setHasNectar(set);
|
||||
}
|
||||
else if (count == 2) {
|
||||
boolean set = (Boolean) value;
|
||||
bee.setHasStung(set);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getItemMeta(ItemMeta itemMeta, List<Map<String, Object>> list, List<List<Map<String, Object>>> metadata, int slot) {
|
||||
if (itemMeta instanceof SuspiciousStewMeta) {
|
||||
SuspiciousStewMeta meta = (SuspiciousStewMeta) itemMeta;
|
||||
SuspiciousStewMeta subMeta = meta.clone();
|
||||
meta.clearCustomEffects();
|
||||
list.add(meta.serialize());
|
||||
metadata.add(list);
|
||||
|
||||
if (subMeta.hasCustomEffects()) {
|
||||
for (PotionEffect effect : subMeta.getCustomEffects()) {
|
||||
list = new ArrayList<>();
|
||||
list.add(effect.serialize());
|
||||
metadata.add(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setItemMeta(Material rowType, ItemStack itemstack, List<Map<String, Object>> map) {
|
||||
if ((rowType == Material.SUSPICIOUS_STEW)) {
|
||||
for (Map<String, Object> suspiciousStewData : map) {
|
||||
SuspiciousStewMeta meta = (SuspiciousStewMeta) itemstack.getItemMeta();
|
||||
PotionEffect effect = new PotionEffect(suspiciousStewData);
|
||||
meta.addCustomEffect(effect, true);
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSignChange(Player player, Sign sign) {
|
||||
player.sendSignChange(sign.getLocation(), sign.getLines(), sign.getColor());
|
||||
}
|
||||
|
||||
}
|
|
@ -17,10 +17,10 @@ import org.bukkit.entity.Zoglin;
|
|||
|
||||
import net.coreprotect.model.BlockGroup;
|
||||
|
||||
public class Bukkit_v1_16 extends Bukkit_v1_15 implements BukkitInterface {
|
||||
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));
|
||||
|
@ -31,10 +31,10 @@ public class Bukkit_v1_16 extends Bukkit_v1_15 implements BukkitInterface {
|
|||
BlockGroup.FIRE = new HashSet<>(Arrays.asList(Material.FIRE, Material.SOUL_FIRE));
|
||||
BlockGroup.LANTERNS = new HashSet<>(Arrays.asList(Material.LANTERN, Material.SOUL_LANTERN));
|
||||
BlockGroup.SOUL_BLOCKS = new HashSet<>(Arrays.asList(Material.SOUL_SAND, Material.SOUL_SOIL));
|
||||
BlockGroup.INTERACT_BLOCKS = new HashSet<>(Arrays.asList(Material.SPRUCE_FENCE_GATE, Material.BIRCH_FENCE_GATE, Material.JUNGLE_FENCE_GATE, Material.DARK_OAK_FENCE_GATE, Material.ACACIA_FENCE_GATE, Material.DISPENSER, Material.NOTE_BLOCK, Material.CHEST, Material.FURNACE, Material.LEVER, Material.REPEATER, Material.ACACIA_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.DARK_OAK_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.OAK_TRAPDOOR, Material.OAK_FENCE_GATE, Material.BREWING_STAND, Material.ANVIL, Material.CHIPPED_ANVIL, Material.DAMAGED_ANVIL, Material.ENDER_CHEST, Material.TRAPPED_CHEST, Material.COMPARATOR, Material.HOPPER, Material.DROPPER, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.GRINDSTONE, Material.LOOM, Material.SMOKER, Material.CARTOGRAPHY_TABLE, Material.CRIMSON_FENCE_GATE, Material.WARPED_FENCE_GATE, Material.CRIMSON_TRAPDOOR, Material.WARPED_TRAPDOOR));
|
||||
BlockGroup.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
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.bukkit.block.data.BlockData;
|
|||
import org.bukkit.block.data.type.PointedDripstone;
|
||||
import org.bukkit.entity.Axolotl;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.GlowItemFrame;
|
||||
import org.bukkit.entity.Goat;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
|
@ -30,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));
|
||||
}
|
||||
|
||||
|
@ -122,7 +123,7 @@ public class Bukkit_v1_17 extends Bukkit_v1_16 implements BukkitInterface {
|
|||
if (subMeta.hasItems()) {
|
||||
list = new ArrayList<>();
|
||||
for (ItemStack itemStack : subMeta.getItems()) {
|
||||
Map<String, Object> itemMap = Util.serializeItemStack(itemStack, slot);
|
||||
Map<String, Object> itemMap = Util.serializeItemStack(itemStack, null, slot);
|
||||
if (itemMap.size() > 0) {
|
||||
list.add(itemMap);
|
||||
}
|
||||
|
@ -199,19 +200,39 @@ public class Bukkit_v1_17 extends Bukkit_v1_16 implements BukkitInterface {
|
|||
return (entity instanceof GlowItemFrame) ? Material.GLOW_ITEM_FRAME : Material.ITEM_FRAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getFrameType(EntityType type) {
|
||||
switch (type) {
|
||||
case ITEM_FRAME:
|
||||
return Material.ITEM_FRAME;
|
||||
case GLOW_ITEM_FRAME:
|
||||
return Material.GLOW_ITEM_FRAME;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getFrameClass(Material material) {
|
||||
return (material == Material.GLOW_ITEM_FRAME) ? GlowItemFrame.class : ItemFrame.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGlowing(Sign sign) {
|
||||
public boolean isGlowing(Sign sign, boolean isFront) {
|
||||
if (!isFront) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return sign.isGlowingText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGlowing(Sign sign, boolean set) {
|
||||
sign.setGlowingText(set);
|
||||
public void setGlowing(Sign sign, boolean isFront, boolean isGlowing) {
|
||||
if (!isFront) {
|
||||
return;
|
||||
}
|
||||
|
||||
sign.setGlowingText(isGlowing);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package net.coreprotect.bukkit;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
|
||||
public class Bukkit_v1_18 extends Bukkit_v1_17 implements BukkitInterface {
|
||||
|
||||
private Boolean hasAdjust = null;
|
||||
|
||||
@Override
|
||||
public ItemStack adjustIngredient(MerchantRecipe recipe, ItemStack itemStack) {
|
||||
try {
|
||||
if (hasAdjust == null) {
|
||||
hasAdjust = true;
|
||||
MerchantRecipe.class.getMethod("adjust", ItemStack.class); // Bukkit 1.18.1+
|
||||
}
|
||||
else if (Boolean.FALSE.equals(hasAdjust)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ItemStack adjustedStack = itemStack.clone();
|
||||
recipe.adjust(adjustedStack);
|
||||
return adjustedStack;
|
||||
}
|
||||
catch (Exception e) {
|
||||
hasAdjust = false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package net.coreprotect.bukkit;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Frog;
|
||||
import org.bukkit.entity.Goat;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Tadpole;
|
||||
|
||||
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.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.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));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getEntityMeta(LivingEntity entity, List<Object> info) {
|
||||
if (entity instanceof Frog) {
|
||||
Frog frog = (Frog) entity;
|
||||
info.add(frog.getVariant());
|
||||
}
|
||||
else if (entity instanceof Tadpole) {
|
||||
Tadpole tadpole = (Tadpole) entity;
|
||||
info.add(tadpole.getAge());
|
||||
}
|
||||
else if (entity instanceof Goat) {
|
||||
Goat goat = (Goat) entity;
|
||||
info.add(goat.isScreaming());
|
||||
info.add(goat.hasLeftHorn());
|
||||
info.add(goat.hasRightHorn());
|
||||
}
|
||||
else if (super.getEntityMeta(entity, info)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setEntityMeta(Entity entity, Object value, int count) {
|
||||
if (entity instanceof Frog) {
|
||||
Frog frog = (Frog) entity;
|
||||
if (count == 0) {
|
||||
Frog.Variant set = (Frog.Variant) value;
|
||||
frog.setVariant(set);
|
||||
}
|
||||
}
|
||||
else if (entity instanceof Tadpole) {
|
||||
Tadpole tadpole = (Tadpole) entity;
|
||||
if (count == 0) {
|
||||
int set = (int) value;
|
||||
tadpole.setAge(set);
|
||||
}
|
||||
}
|
||||
else if (entity instanceof Goat) {
|
||||
Goat goat = (Goat) entity;
|
||||
boolean set = (Boolean) value;
|
||||
if (count == 0) {
|
||||
goat.setScreaming(set);
|
||||
}
|
||||
else if (count == 1) {
|
||||
goat.setLeftHorn(set);
|
||||
}
|
||||
else if (count == 2) {
|
||||
goat.setRightHorn(set);
|
||||
}
|
||||
}
|
||||
else if (super.setEntityMeta(entity, value, count)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,294 @@
|
|||
package net.coreprotect.bukkit;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Tag;
|
||||
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, 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();
|
||||
BlockGroup.BUTTONS.addAll(Tag.BUTTONS.getValues());
|
||||
BlockGroup.PRESSURE_PLATES.clear();
|
||||
BlockGroup.PRESSURE_PLATES.addAll(Tag.PRESSURE_PLATES.getValues());
|
||||
|
||||
for (Material value : Tag.DOORS.getValues()) {
|
||||
if (!BlockGroup.DOORS.contains(value)) {
|
||||
BlockGroup.DOORS.add(value);
|
||||
}
|
||||
}
|
||||
for (Material value : Tag.FENCE_GATES.getValues()) {
|
||||
if (!BlockGroup.INTERACT_BLOCKS.contains(value)) {
|
||||
BlockGroup.INTERACT_BLOCKS.add(value);
|
||||
}
|
||||
if (!BlockGroup.SAFE_INTERACT_BLOCKS.contains(value)) {
|
||||
BlockGroup.SAFE_INTERACT_BLOCKS.add(value);
|
||||
}
|
||||
}
|
||||
for (Material value : Tag.WOODEN_TRAPDOORS.getValues()) {
|
||||
if (!BlockGroup.INTERACT_BLOCKS.contains(value)) {
|
||||
BlockGroup.INTERACT_BLOCKS.add(value);
|
||||
}
|
||||
if (!BlockGroup.SAFE_INTERACT_BLOCKS.contains(value)) {
|
||||
BlockGroup.SAFE_INTERACT_BLOCKS.add(value);
|
||||
}
|
||||
}
|
||||
for (Material value : Tag.CEILING_HANGING_SIGNS.getValues()) {
|
||||
if (!BlockGroup.TRACK_BOTTOM.contains(value)) {
|
||||
BlockGroup.TRACK_BOTTOM.add(value);
|
||||
}
|
||||
}
|
||||
for (Material value : Tag.WALL_SIGNS.getValues()) {
|
||||
if (!BlockGroup.TRACK_SIDE.contains(value)) {
|
||||
BlockGroup.TRACK_SIDE.add(value);
|
||||
}
|
||||
}
|
||||
for (Material value : Tag.SAPLINGS.getValues()) {
|
||||
if (!BlockGroup.TRACK_TOP.contains(value)) {
|
||||
BlockGroup.TRACK_TOP.add(value);
|
||||
}
|
||||
if (!BlockGroup.NON_ATTACHABLE.contains(value)) {
|
||||
BlockGroup.NON_ATTACHABLE.add(value);
|
||||
}
|
||||
}
|
||||
for (Material value : Tag.FLOWERS.getValues()) {
|
||||
if (!BlockGroup.TRACK_TOP.contains(value)) {
|
||||
BlockGroup.TRACK_TOP.add(value);
|
||||
}
|
||||
if (!BlockGroup.NON_ATTACHABLE.contains(value)) {
|
||||
BlockGroup.NON_ATTACHABLE.add(value);
|
||||
}
|
||||
}
|
||||
for (Material value : Tag.SIGNS.getValues()) {
|
||||
if (!Tag.WALL_SIGNS.isTagged(value) && !BlockGroup.TRACK_TOP.contains(value)) {
|
||||
BlockGroup.TRACK_TOP.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGlowing(Sign sign, boolean isFront, boolean isGlowing) {
|
||||
if (isFront) {
|
||||
sign.getSide(Side.FRONT).setGlowingText(isGlowing);
|
||||
}
|
||||
else {
|
||||
sign.getSide(Side.BACK).setGlowingText(isGlowing);
|
||||
}
|
||||
}
|
||||
|
||||
@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) {
|
||||
sign.getSide(Side.FRONT).setColor(DyeColor.getByColor(Color.fromRGB(color)));
|
||||
}
|
||||
else {
|
||||
sign.getSide(Side.BACK).setColor(DyeColor.getByColor(Color.fromRGB(color)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWaxed(Sign sign, boolean isWaxed) {
|
||||
sign.setWaxed(isWaxed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor(Sign sign, boolean isFront) {
|
||||
if (isFront) {
|
||||
return sign.getSide(Side.FRONT).getColor().getColor().asRGB();
|
||||
}
|
||||
else {
|
||||
return sign.getSide(Side.BACK).getColor().getColor().asRGB();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGlowing(Sign sign, boolean isFront) {
|
||||
if (isFront) {
|
||||
return sign.getSide(Side.FRONT).isGlowingText();
|
||||
}
|
||||
else {
|
||||
return sign.getSide(Side.BACK).isGlowingText();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWaxed(Sign sign) {
|
||||
return sign.isWaxed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getPlantSeeds(Material material) {
|
||||
switch (material) {
|
||||
case WHEAT:
|
||||
material = Material.WHEAT_SEEDS;
|
||||
break;
|
||||
case PUMPKIN_STEM:
|
||||
material = Material.PUMPKIN_SEEDS;
|
||||
break;
|
||||
case MELON_STEM:
|
||||
material = Material.MELON_SEEDS;
|
||||
break;
|
||||
case BEETROOTS:
|
||||
material = Material.BEETROOT_SEEDS;
|
||||
break;
|
||||
case TORCHFLOWER_CROP:
|
||||
material = Material.TORCHFLOWER_SEEDS;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSign(Material material) {
|
||||
return Tag.ALL_SIGNS.isTagged(material);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChiseledBookshelf(Material material) {
|
||||
return material == Material.CHISELED_BOOKSHELF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBookshelfBook(Material material) {
|
||||
return Tag.ITEMS_BOOKSHELF_BOOKS.isTagged(material);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getChiseledBookshelfBook(BlockState blockState, PlayerInteractEvent event) {
|
||||
try {
|
||||
if (hasClickedPosition == null) {
|
||||
hasClickedPosition = true;
|
||||
PlayerInteractEvent.class.getMethod("getClickedPosition"); // Bukkit 1.20.1+
|
||||
}
|
||||
else if (Boolean.FALSE.equals(hasClickedPosition)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ChiseledBookshelf chiseledBookshelf = (ChiseledBookshelf) blockState;
|
||||
ItemStack book = chiseledBookshelf.getInventory().getItem(chiseledBookshelf.getSlot(event.getClickedPosition()));
|
||||
return book == null ? new ItemStack(Material.AIR) : book;
|
||||
}
|
||||
catch (Exception e) {
|
||||
hasClickedPosition = false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLine(Sign sign, int line) {
|
||||
if (line < 4) {
|
||||
return sign.getSide(Side.FRONT).getLine(line);
|
||||
}
|
||||
else {
|
||||
return sign.getSide(Side.BACK).getLine(line - 4);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLine(Sign sign, int line, String string) {
|
||||
if (string == null) {
|
||||
string = "";
|
||||
}
|
||||
|
||||
if (line < 4) {
|
||||
sign.getSide(Side.FRONT).setLine(line, string);
|
||||
}
|
||||
else {
|
||||
sign.getSide(Side.BACK).setLine(line - 4, string);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSignFront(SignChangeEvent event) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -11,16 +11,16 @@ import net.coreprotect.language.Phrase;
|
|||
import net.coreprotect.language.Selector;
|
||||
import net.coreprotect.utility.Chat;
|
||||
import net.coreprotect.utility.Color;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class ApplyCommand {
|
||||
protected static void runCommand(CommandSender user, Command command, boolean permission, String[] args) {
|
||||
try {
|
||||
if (ConfigHandler.lastRollback.get(user.getName()) != null) {
|
||||
List<Object> list = ConfigHandler.lastRollback.get(user.getName());
|
||||
int time = (Integer) list.get(0);
|
||||
args = (String[]) list.get(1);
|
||||
Location location = (Location) list.get(2);
|
||||
long startTime = (Long) list.get(0);
|
||||
long endTime = (Long) list.get(1);
|
||||
args = (String[]) list.get(2);
|
||||
Location location = (Location) list.get(3);
|
||||
boolean valid = false;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i].equals("#preview")) {
|
||||
|
@ -33,7 +33,7 @@ public class ApplyCommand {
|
|||
}
|
||||
else {
|
||||
ConfigHandler.lastRollback.remove(user.getName());
|
||||
RollbackRestoreCommand.runCommand(user, command, permission, args, location, time);
|
||||
RollbackRestoreCommand.runCommand(user, command, permission, args, location, startTime, endTime);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -11,16 +11,16 @@ import net.coreprotect.language.Phrase;
|
|||
import net.coreprotect.language.Selector;
|
||||
import net.coreprotect.utility.Chat;
|
||||
import net.coreprotect.utility.Color;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class CancelCommand {
|
||||
protected static void runCommand(CommandSender user, Command command, boolean permission, String[] args) {
|
||||
try {
|
||||
if (ConfigHandler.lastRollback.get(user.getName()) != null) {
|
||||
List<Object> list = ConfigHandler.lastRollback.get(user.getName());
|
||||
int time = (Integer) list.get(0);
|
||||
args = (String[]) list.get(1);
|
||||
Location location = (Location) list.get(2);
|
||||
long startTime = (Long) list.get(0);
|
||||
long endTime = (Long) list.get(1);
|
||||
args = (String[]) list.get(2);
|
||||
Location location = (Location) list.get(3);
|
||||
boolean valid = false;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i].equals("#preview")) {
|
||||
|
@ -33,7 +33,7 @@ public class CancelCommand {
|
|||
}
|
||||
else {
|
||||
ConfigHandler.lastRollback.remove(user.getName());
|
||||
RollbackRestoreCommand.runCommand(user, command, permission, args, location, time);
|
||||
RollbackRestoreCommand.runCommand(user, command, permission, args, location, startTime, endTime);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -3,8 +3,11 @@ package net.coreprotect.command;
|
|||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
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;
|
||||
|
||||
|
@ -32,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) {
|
||||
|
@ -70,13 +72,13 @@ public class CommandHandler implements CommandExecutor {
|
|||
if (argument.startsWith("#")) {
|
||||
argument = argument.replaceFirst("#", "");
|
||||
}
|
||||
if (argument.equals("broke") || argument.equals("break") || argument.equals("remove") || argument.equals("destroy") || argument.equals("block-break") || argument.equals("block-remove") || argument.equals("-block") || argument.equals("block-")) {
|
||||
if (argument.equals("broke") || argument.equals("break") || argument.equals("remove") || argument.equals("destroy") || argument.equals("block-break") || argument.equals("block-remove") || argument.equals("-block") || argument.equals("-blocks") || argument.equals("block-")) {
|
||||
result.add(0);
|
||||
}
|
||||
else if (argument.equals("placed") || argument.equals("place") || argument.equals("block-place") || argument.equals("+block") || argument.equals("block+")) {
|
||||
else if (argument.equals("placed") || argument.equals("place") || argument.equals("block-place") || argument.equals("+block") || argument.equals("+blocks") || argument.equals("block+")) {
|
||||
result.add(1);
|
||||
}
|
||||
else if (argument.equals("block") || argument.equals("block-change") || argument.equals("change")) {
|
||||
else if (argument.equals("block") || argument.equals("blocks") || argument.equals("block-change") || argument.equals("change") || argument.equals("changes")) {
|
||||
result.add(0);
|
||||
result.add(1);
|
||||
}
|
||||
|
@ -97,17 +99,17 @@ public class CommandHandler implements CommandExecutor {
|
|||
result.add(4);
|
||||
result.add(1);
|
||||
}
|
||||
else if (argument.equals("chat")) {
|
||||
else if (argument.equals("chat") || argument.equals("chats")) {
|
||||
result.add(6);
|
||||
}
|
||||
else if (argument.equals("command") || argument.equals("commands")) {
|
||||
result.add(7);
|
||||
}
|
||||
else if (argument.equals("login") || argument.equals("+session") || argument.equals("session+") || argument.equals("+connection") || argument.equals("connection+")) {
|
||||
else if (argument.equals("logins") || argument.equals("login") || argument.equals("+session") || argument.equals("+sessions") || argument.equals("session+") || argument.equals("+connection") || argument.equals("connection+")) {
|
||||
result.add(8);
|
||||
result.add(1);
|
||||
}
|
||||
else if (argument.equals("logout") || argument.equals("-session") || argument.equals("session-") || argument.equals("-connection") || argument.equals("connection-")) {
|
||||
else if (argument.equals("logout") || argument.equals("logouts") || argument.equals("-session") || argument.equals("-sessions") || argument.equals("session-") || argument.equals("-connection") || argument.equals("connection-")) {
|
||||
result.add(8);
|
||||
result.add(0);
|
||||
}
|
||||
|
@ -117,31 +119,31 @@ public class CommandHandler implements CommandExecutor {
|
|||
else if (argument.equals("username") || argument.equals("usernames") || argument.equals("user") || argument.equals("users") || argument.equals("name") || argument.equals("names") || argument.equals("uuid") || argument.equals("uuids") || argument.equals("username-change") || argument.equals("username-changes") || argument.equals("name-change") || argument.equals("name-changes")) {
|
||||
result.add(9);
|
||||
}
|
||||
else if (argument.equals("sign")) {
|
||||
else if (argument.equals("sign") || argument.equals("signs")) {
|
||||
result.add(10);
|
||||
}
|
||||
else if (argument.equals("item") || argument.equals("items")) {
|
||||
result.add(4);
|
||||
result.add(11);
|
||||
else if (argument.equals("inv") || argument.equals("inventory") || argument.equals("inventories")) {
|
||||
result.add(4); // container
|
||||
result.add(11); // item
|
||||
}
|
||||
else if (argument.equals("-item") || argument.equals("item-") || argument.equals("-items") || argument.equals("items-")) {
|
||||
result.add(4);
|
||||
result.add(11);
|
||||
result.add(0);
|
||||
}
|
||||
else if (argument.equals("+item") || argument.equals("item+") || argument.equals("+items") || argument.equals("items+")) {
|
||||
else if (argument.equals("-inv") || argument.equals("inv-") || argument.equals("-inventory") || argument.equals("inventory-") || argument.equals("-inventories")) {
|
||||
result.add(4);
|
||||
result.add(11);
|
||||
result.add(1);
|
||||
}
|
||||
else if (argument.equals("inv") || argument.equals("inventory") || argument.equals("inventories")) {
|
||||
result.add(11);
|
||||
}
|
||||
else if (argument.equals("-inv") || argument.equals("inv-") || argument.equals("-inventory") || argument.equals("inventory-") || argument.equals("-inventories") || argument.equals("drop") || argument.equals("drops") || argument.equals("deposit") || argument.equals("deposits") || argument.equals("deposited")) {
|
||||
else if (argument.equals("+inv") || argument.equals("inv+") || argument.equals("+inventory") || argument.equals("inventory+") || argument.equals("+inventories")) {
|
||||
result.add(4);
|
||||
result.add(11);
|
||||
result.add(0);
|
||||
}
|
||||
else if (argument.equals("+inv") || argument.equals("inv+") || argument.equals("+inventory") || argument.equals("inventory+") || argument.equals("+inventories") || argument.equals("pickup") || argument.equals("pickups") || argument.equals("withdraw") || argument.equals("withdraws") || argument.equals("withdrew")) {
|
||||
else if (argument.equals("item") || argument.equals("items")) {
|
||||
result.add(11);
|
||||
}
|
||||
else if (argument.equals("-item") || argument.equals("item-") || argument.equals("-items") || argument.equals("items-") || argument.equals("drop") || argument.equals("drops") || argument.equals("deposit") || argument.equals("deposits") || argument.equals("deposited")) {
|
||||
result.add(11);
|
||||
result.add(0);
|
||||
}
|
||||
else if (argument.equals("+item") || argument.equals("item+") || argument.equals("+items") || argument.equals("items+") || argument.equals("pickup") || argument.equals("pickups") || argument.equals("withdraw") || argument.equals("withdraws") || argument.equals("withdrew")) {
|
||||
result.add(11);
|
||||
result.add(1);
|
||||
}
|
||||
|
@ -255,9 +257,9 @@ public class CommandHandler implements CommandExecutor {
|
|||
return result;
|
||||
}
|
||||
|
||||
protected static List<Object> parseExcluded(CommandSender player, String[] inputArguments, List<Integer> argAction) {
|
||||
protected static Map<Object, Boolean> parseExcluded(CommandSender player, String[] inputArguments, List<Integer> argAction) {
|
||||
String[] argumentArray = inputArguments.clone();
|
||||
List<Object> excluded = new ArrayList<>();
|
||||
Map<Object, Boolean> excluded = new HashMap<>();
|
||||
int count = 0;
|
||||
int next = 0;
|
||||
for (String argument : argumentArray) {
|
||||
|
@ -275,21 +277,18 @@ public class CommandHandler implements CommandExecutor {
|
|||
if (argument.contains(",")) {
|
||||
String[] i2 = argument.split(",");
|
||||
for (String i3 : i2) {
|
||||
if (i3.equals("#natural")) {
|
||||
excluded.addAll(naturalBlocks);
|
||||
}
|
||||
else {
|
||||
if (!checkTags(i3, excluded)) {
|
||||
Material i3_material = Util.getType(i3);
|
||||
if (i3_material != null && (i3_material.isBlock() || argAction.contains(4))) {
|
||||
excluded.add(i3_material);
|
||||
excluded.put(i3_material, false);
|
||||
}
|
||||
else {
|
||||
EntityType i3_entity = Util.getEntityType(i3);
|
||||
if (i3_entity != null) {
|
||||
excluded.add(i3_entity);
|
||||
excluded.put(i3_entity, false);
|
||||
}
|
||||
else if (i3_material != null) {
|
||||
excluded.add(i3_material);
|
||||
excluded.put(i3_material, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -302,21 +301,18 @@ public class CommandHandler implements CommandExecutor {
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (argument.equals("#natural")) {
|
||||
excluded.addAll(naturalBlocks);
|
||||
}
|
||||
else {
|
||||
if (!checkTags(argument, excluded)) {
|
||||
Material iMaterial = Util.getType(argument);
|
||||
if (iMaterial != null && (iMaterial.isBlock() || argAction.contains(4))) {
|
||||
excluded.add(iMaterial);
|
||||
excluded.put(iMaterial, false);
|
||||
}
|
||||
else {
|
||||
EntityType iEntity = Util.getEntityType(argument);
|
||||
if (iEntity != null) {
|
||||
excluded.add(iEntity);
|
||||
excluded.put(iEntity, false);
|
||||
}
|
||||
else if (iMaterial != null) {
|
||||
excluded.add(iMaterial);
|
||||
excluded.put(iMaterial, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -353,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 {
|
||||
|
@ -381,7 +377,7 @@ public class CommandHandler implements CommandExecutor {
|
|||
}
|
||||
else {
|
||||
boolean isBlock = false;
|
||||
if (argument.equals("#natural")) {
|
||||
if (checkTags(argument)) {
|
||||
isBlock = true;
|
||||
}
|
||||
else {
|
||||
|
@ -563,12 +559,12 @@ public class CommandHandler implements CommandExecutor {
|
|||
rcount++;
|
||||
}
|
||||
if (location != null) {
|
||||
int xmin = location.getBlockX() - r_x;
|
||||
int xmax = location.getBlockX() + r_x;
|
||||
int ymin = -1;
|
||||
int ymax = -1;
|
||||
int zmin = location.getBlockZ() - r_z;
|
||||
int zmax = location.getBlockZ() + r_z;
|
||||
Integer xmin = location.getBlockX() - r_x;
|
||||
Integer xmax = location.getBlockX() + r_x;
|
||||
Integer ymin = null;
|
||||
Integer ymax = null;
|
||||
Integer zmin = location.getBlockZ() - r_z;
|
||||
Integer zmax = location.getBlockZ() + r_z;
|
||||
if (r_y > -1) {
|
||||
ymin = location.getBlockY() - r_y;
|
||||
ymax = location.getBlockY() + r_y;
|
||||
|
@ -624,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);
|
||||
|
@ -656,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);
|
||||
|
@ -691,11 +681,13 @@ public class CommandHandler implements CommandExecutor {
|
|||
return restricted;
|
||||
}
|
||||
|
||||
protected static int parseTime(String[] inputArguments) {
|
||||
protected static long[] parseTime(String[] inputArguments) {
|
||||
String[] argumentArray = inputArguments.clone();
|
||||
int time = 0;
|
||||
long timeStart = 0;
|
||||
long timeEnd = 0;
|
||||
int count = 0;
|
||||
int next = 0;
|
||||
boolean range = false;
|
||||
double w = 0;
|
||||
double d = 0;
|
||||
double h = 0;
|
||||
|
@ -720,41 +712,59 @@ public class CommandHandler implements CommandExecutor {
|
|||
argument = argument.replaceAll("d", "d:");
|
||||
argument = argument.replaceAll("h", "h:");
|
||||
argument = argument.replaceAll("s", "s:");
|
||||
range = argument.contains("-");
|
||||
|
||||
int argCount = 0;
|
||||
String[] i2 = argument.split(":");
|
||||
for (String i3 : i2) {
|
||||
if (i3.endsWith("w")) {
|
||||
if (range && argCount > 0 && timeStart == 0 && i3.startsWith("-")) {
|
||||
timeStart = (long) (((w * 7 * 24 * 60 * 60) + (d * 24 * 60 * 60) + (h * 60 * 60) + (m * 60) + s));
|
||||
w = 0;
|
||||
d = 0;
|
||||
h = 0;
|
||||
m = 0;
|
||||
s = 0;
|
||||
}
|
||||
|
||||
if (i3.endsWith("w") && w == 0) {
|
||||
String i4 = i3.replaceAll("[^0-9.]", "");
|
||||
if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) {
|
||||
w = Double.parseDouble(i4);
|
||||
}
|
||||
}
|
||||
else if (i3.endsWith("d")) {
|
||||
else if (i3.endsWith("d") && d == 0) {
|
||||
String i4 = i3.replaceAll("[^0-9.]", "");
|
||||
if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) {
|
||||
d = Double.parseDouble(i4);
|
||||
}
|
||||
}
|
||||
else if (i3.endsWith("h")) {
|
||||
else if (i3.endsWith("h") && h == 0) {
|
||||
String i4 = i3.replaceAll("[^0-9.]", "");
|
||||
if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) {
|
||||
h = Double.parseDouble(i4);
|
||||
}
|
||||
}
|
||||
else if (i3.endsWith("m")) {
|
||||
else if (i3.endsWith("m") && m == 0) {
|
||||
String i4 = i3.replaceAll("[^0-9.]", "");
|
||||
if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) {
|
||||
m = Double.parseDouble(i4);
|
||||
}
|
||||
}
|
||||
else if (i3.endsWith("s")) {
|
||||
else if (i3.endsWith("s") && s == 0) {
|
||||
String i4 = i3.replaceAll("[^0-9.]", "");
|
||||
if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) {
|
||||
s = Double.parseDouble(i4);
|
||||
}
|
||||
}
|
||||
|
||||
argCount++;
|
||||
}
|
||||
if (timeStart > 0) {
|
||||
timeEnd = (long) (((w * 7 * 24 * 60 * 60) + (d * 24 * 60 * 60) + (h * 60 * 60) + (m * 60) + s));
|
||||
}
|
||||
else {
|
||||
timeStart = (long) (((w * 7 * 24 * 60 * 60) + (d * 24 * 60 * 60) + (h * 60 * 60) + (m * 60) + s));
|
||||
}
|
||||
double rs = ((w * 7 * 24 * 60 * 60) + (d * 24 * 60 * 60) + (h * 60 * 60) + (m * 60) + s);
|
||||
time = (int) rs;
|
||||
next = 0;
|
||||
}
|
||||
else {
|
||||
|
@ -763,7 +773,13 @@ public class CommandHandler implements CommandExecutor {
|
|||
}
|
||||
count++;
|
||||
}
|
||||
return time;
|
||||
|
||||
if (timeEnd >= timeStart) {
|
||||
return new long[] { timeEnd, timeStart };
|
||||
}
|
||||
else {
|
||||
return new long[] { timeStart, timeEnd };
|
||||
}
|
||||
}
|
||||
|
||||
private static String timeString(BigDecimal input) {
|
||||
|
@ -775,6 +791,7 @@ public class CommandHandler implements CommandExecutor {
|
|||
String time = "";
|
||||
int count = 0;
|
||||
int next = 0;
|
||||
boolean range = false;
|
||||
BigDecimal w = new BigDecimal(0);
|
||||
BigDecimal d = new BigDecimal(0);
|
||||
BigDecimal h = new BigDecimal(0);
|
||||
|
@ -799,43 +816,82 @@ public class CommandHandler implements CommandExecutor {
|
|||
argument = argument.replaceAll("d", "d:");
|
||||
argument = argument.replaceAll("h", "h:");
|
||||
argument = argument.replaceAll("s", "s:");
|
||||
range = argument.contains("-");
|
||||
|
||||
int argCount = 0;
|
||||
String[] i2 = argument.split(":");
|
||||
for (String i3 : i2) {
|
||||
if (i3.endsWith("w")) {
|
||||
if (range && argCount > 0 && !time.contains("-") && i3.startsWith("-")) {
|
||||
w = new BigDecimal(0);
|
||||
d = new BigDecimal(0);
|
||||
h = new BigDecimal(0);
|
||||
m = new BigDecimal(0);
|
||||
s = new BigDecimal(0);
|
||||
time = time + " -";
|
||||
}
|
||||
|
||||
if (i3.endsWith("w") && w.intValue() == 0) {
|
||||
String i4 = i3.replaceAll("[^0-9.]", "");
|
||||
if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) {
|
||||
w = new BigDecimal(i4);
|
||||
time = time + " " + Phrase.build(Phrase.TIME_WEEKS, timeString(w), (w.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND));
|
||||
if (range) {
|
||||
time = time + " " + timeString(w) + "w";
|
||||
}
|
||||
else {
|
||||
time = time + " " + Phrase.build(Phrase.TIME_WEEKS, timeString(w), (w.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (i3.endsWith("d")) {
|
||||
else if (i3.endsWith("d") && d.intValue() == 0) {
|
||||
String i4 = i3.replaceAll("[^0-9.]", "");
|
||||
if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) {
|
||||
d = new BigDecimal(i4);
|
||||
time = time + " " + Phrase.build(Phrase.TIME_DAYS, timeString(d), (d.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND));
|
||||
if (range) {
|
||||
time = time + " " + timeString(d) + "d";
|
||||
}
|
||||
else {
|
||||
time = time + " " + Phrase.build(Phrase.TIME_DAYS, timeString(d), (d.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (i3.endsWith("h")) {
|
||||
else if (i3.endsWith("h") && h.intValue() == 0) {
|
||||
String i4 = i3.replaceAll("[^0-9.]", "");
|
||||
if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) {
|
||||
h = new BigDecimal(i4);
|
||||
time = time + " " + Phrase.build(Phrase.TIME_HOURS, timeString(h), (h.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND));
|
||||
if (range) {
|
||||
time = time + " " + timeString(h) + "h";
|
||||
}
|
||||
else {
|
||||
time = time + " " + Phrase.build(Phrase.TIME_HOURS, timeString(h), (h.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (i3.endsWith("m")) {
|
||||
else if (i3.endsWith("m") && m.intValue() == 0) {
|
||||
String i4 = i3.replaceAll("[^0-9.]", "");
|
||||
if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) {
|
||||
m = new BigDecimal(i4);
|
||||
time = time + " " + Phrase.build(Phrase.TIME_MINUTES, timeString(m), (m.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND));
|
||||
if (range) {
|
||||
time = time + " " + timeString(m) + "m";
|
||||
}
|
||||
else {
|
||||
time = time + " " + Phrase.build(Phrase.TIME_MINUTES, timeString(m), (m.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (i3.endsWith("s")) {
|
||||
else if (i3.endsWith("s") && s.intValue() == 0) {
|
||||
String i4 = i3.replaceAll("[^0-9.]", "");
|
||||
if (i4.length() > 0 && i4.replaceAll("[^0-9]", "").length() > 0 && i4.indexOf('.') == i4.lastIndexOf('.')) {
|
||||
s = new BigDecimal(i4);
|
||||
time = time + " " + Phrase.build(Phrase.TIME_SECONDS, timeString(s), (s.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND));
|
||||
if (range) {
|
||||
time = time + " " + timeString(s) + "s";
|
||||
}
|
||||
else {
|
||||
time = time + " " + Phrase.build(Phrase.TIME_SECONDS, timeString(s), (s.doubleValue() == 1 ? Selector.FIRST : Selector.SECOND));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
argCount++;
|
||||
}
|
||||
next = 0;
|
||||
}
|
||||
|
@ -1065,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'\"]", "");
|
||||
|
@ -1097,7 +1199,7 @@ public class CommandHandler implements CommandExecutor {
|
|||
else if (user.hasPermission("coreprotect.restore") && (corecommand.equals("restore") || corecommand.equals("rs") || corecommand.equals("re") || corecommand.equals("undo") || corecommand.equals("apply") || corecommand.equals("cancel"))) {
|
||||
permission = true;
|
||||
}
|
||||
else if (user.hasPermission("coreprotect.inspect") && (corecommand.equals("i") || corecommand.equals("inspect"))) {
|
||||
else if (user.hasPermission("coreprotect.inspect") && (corecommand.equals("i") || corecommand.equals("inspect") || corecommand.equals("inspector"))) {
|
||||
permission = true;
|
||||
}
|
||||
else if (user.hasPermission("coreprotect.help") && corecommand.equals("help")) {
|
||||
|
@ -1106,7 +1208,7 @@ public class CommandHandler implements CommandExecutor {
|
|||
else if (user.hasPermission("coreprotect.purge") && corecommand.equals("purge")) {
|
||||
permission = true;
|
||||
}
|
||||
else if (user.hasPermission("coreprotect.lookup") && (corecommand.equals("l") || corecommand.equals("lookup") || corecommand.equals("near"))) {
|
||||
else if (user.hasPermission("coreprotect.lookup") && (corecommand.equals("l") || corecommand.equals("lookup") || corecommand.equals("page") || corecommand.equals("near"))) {
|
||||
permission = true;
|
||||
}
|
||||
else if (user.hasPermission("coreprotect.lookup.near") && corecommand.equals("near")) {
|
||||
|
@ -1121,10 +1223,16 @@ public class CommandHandler implements CommandExecutor {
|
|||
else if (user.hasPermission("coreprotect.status") && (corecommand.equals("status") || corecommand.equals("stats") || corecommand.equals("version"))) {
|
||||
permission = true;
|
||||
}
|
||||
else if (user.hasPermission("coreprotect.consumer") && corecommand.equals("consumer")) {
|
||||
permission = true;
|
||||
}
|
||||
else if (user.hasPermission("coreprotect.networking") && corecommand.equals("network-debug")) {
|
||||
permission = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (corecommand.equals("rollback") || corecommand.equals("restore") || corecommand.equals("rb") || corecommand.equals("rs") || corecommand.equals("ro") || corecommand.equals("re")) {
|
||||
RollbackRestoreCommand.runCommand(user, command, permission, argumentArray, null, 0);
|
||||
RollbackRestoreCommand.runCommand(user, command, permission, argumentArray, null, 0, 0);
|
||||
}
|
||||
else if (corecommand.equals("apply")) {
|
||||
ApplyCommand.runCommand(user, command, permission, argumentArray);
|
||||
|
@ -1144,7 +1252,7 @@ public class CommandHandler implements CommandExecutor {
|
|||
else if (corecommand.equals("inspect") || corecommand.equals("i")) {
|
||||
InspectCommand.runCommand(user, permission, argumentArray);
|
||||
}
|
||||
else if (corecommand.equals("lookup") || corecommand.equals("l")) {
|
||||
else if (corecommand.equals("lookup") || corecommand.equals("l") || corecommand.equals("page")) {
|
||||
LookupCommand.runCommand(user, command, permission, argumentArray);
|
||||
}
|
||||
else if (corecommand.equals("near")) {
|
||||
|
@ -1159,6 +1267,12 @@ public class CommandHandler implements CommandExecutor {
|
|||
else if (corecommand.equals("reload")) {
|
||||
ReloadCommand.runCommand(user, permission, argumentArray);
|
||||
}
|
||||
else if (corecommand.equals("consumer")) {
|
||||
ConsumerCommand.runCommand(user, permission, argumentArray);
|
||||
}
|
||||
else if (corecommand.equals("network-debug")) {
|
||||
NetworkDebugCommand.runCommand(user, permission, argumentArray);
|
||||
}
|
||||
else {
|
||||
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.COMMAND_NOT_FOUND, Color.WHITE, "/co " + corecommand));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package net.coreprotect.command;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.language.Selector;
|
||||
import net.coreprotect.utility.Chat;
|
||||
import net.coreprotect.utility.Color;
|
||||
|
||||
public class ConsumerCommand {
|
||||
|
||||
private ConsumerCommand() {
|
||||
throw new IllegalStateException("Command class");
|
||||
}
|
||||
|
||||
protected static void runCommand(final CommandSender player, boolean permission, String[] args) {
|
||||
if (!permission) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
|
||||
return;
|
||||
}
|
||||
if (!(player instanceof ConsoleCommandSender)) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.COMMAND_CONSOLE));
|
||||
return;
|
||||
}
|
||||
if (ConfigHandler.converterRunning) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
|
||||
return;
|
||||
}
|
||||
if (ConfigHandler.purgeRunning) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length == 2) {
|
||||
String action = args[1].toLowerCase(Locale.ROOT);
|
||||
boolean pauseCommand = (action.equals("pause") || action.equals("disable") || action.equals("stop"));
|
||||
boolean resumeCommand = (action.equals("resume") || action.equals("enable") || action.equals("start"));
|
||||
|
||||
if (pauseCommand || resumeCommand) {
|
||||
if (ConfigHandler.pauseConsumer) {
|
||||
if (pauseCommand) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.CONSUMER_ERROR, Selector.FIRST)); // already paused
|
||||
}
|
||||
else {
|
||||
ConfigHandler.pauseConsumer = false;
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.CONSUMER_TOGGLED, Selector.SECOND)); // now started
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (resumeCommand) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.CONSUMER_ERROR, Selector.SECOND)); // already running
|
||||
}
|
||||
else {
|
||||
ConfigHandler.pauseConsumer = true;
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.CONSUMER_TOGGLED, Selector.FIRST)); // now paused
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_PARAMETERS, Color.WHITE, "/co consumer <pause|resume>"));
|
||||
}
|
||||
|
||||
}
|
|
@ -7,7 +7,6 @@ import net.coreprotect.language.Phrase;
|
|||
import net.coreprotect.language.Selector;
|
||||
import net.coreprotect.utility.Chat;
|
||||
import net.coreprotect.utility.Color;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class InspectCommand {
|
||||
protected static void runCommand(CommandSender player, boolean permission, String[] args) {
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package net.coreprotect.command;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Statement;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
|
@ -24,6 +26,7 @@ import net.coreprotect.config.Config;
|
|||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.Database;
|
||||
import net.coreprotect.database.Lookup;
|
||||
import net.coreprotect.database.logger.ItemLogger;
|
||||
import net.coreprotect.database.lookup.BlockLookup;
|
||||
import net.coreprotect.database.lookup.ChestTransactionLookup;
|
||||
import net.coreprotect.database.lookup.InteractionLookup;
|
||||
|
@ -32,6 +35,8 @@ import net.coreprotect.database.lookup.SignMessageLookup;
|
|||
import net.coreprotect.database.statement.UserStatement;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.language.Selector;
|
||||
import net.coreprotect.listener.channel.PluginChannelHandshakeListener;
|
||||
import net.coreprotect.listener.channel.PluginChannelListener;
|
||||
import net.coreprotect.utility.Chat;
|
||||
import net.coreprotect.utility.ChatMessage;
|
||||
import net.coreprotect.utility.Color;
|
||||
|
@ -48,10 +53,12 @@ public class LookupCommand {
|
|||
int argNoisy = CommandHandler.parseNoisy(args);
|
||||
List<Integer> argAction = CommandHandler.parseAction(args);
|
||||
List<Object> argBlocks = CommandHandler.parseRestricted(player, args, argAction);
|
||||
List<Object> argExclude = CommandHandler.parseExcluded(player, args, argAction);
|
||||
Map<Object, Boolean> argExclude = CommandHandler.parseExcluded(player, args, argAction);
|
||||
List<String> argExcludeUsers = CommandHandler.parseExcludedUsers(player, args);
|
||||
String ts = CommandHandler.parseTimeString(args);
|
||||
int rbseconds = CommandHandler.parseTime(args);
|
||||
long[] argTime = CommandHandler.parseTime(args);
|
||||
long startTime = argTime[0];
|
||||
long endTime = argTime[1];
|
||||
int argWid = CommandHandler.parseWorld(args, true, true);
|
||||
int parseRows = CommandHandler.parseRows(args);
|
||||
boolean count = CommandHandler.parseCount(args);
|
||||
|
@ -63,6 +70,11 @@ public class LookupCommand {
|
|||
return;
|
||||
}
|
||||
|
||||
if (args[0].toLowerCase(Locale.ROOT).equals("page") && (args.length != 2 || !args[1].equals(args[1].replaceAll("[^0-9]", "")))) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_PARAMETERS, Color.WHITE, "/co page <page>"));
|
||||
return;
|
||||
}
|
||||
|
||||
int argExcluded = argExclude.size();
|
||||
int argRestricted = argBlocks.size();
|
||||
|
||||
|
@ -86,7 +98,7 @@ public class LookupCommand {
|
|||
}
|
||||
|
||||
/* check for invalid block/entity combinations (exclude) */
|
||||
for (Object arg : argExclude) {
|
||||
for (Object arg : argExclude.keySet()) {
|
||||
if (arg instanceof Material) {
|
||||
hasBlock = true;
|
||||
}
|
||||
|
@ -204,7 +216,7 @@ public class LookupCommand {
|
|||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
|
||||
return;
|
||||
}
|
||||
if (argAction.contains(4) && !player.hasPermission("coreprotect.lookup.container")) {
|
||||
if (argAction.contains(4) && !argAction.contains(11) && !player.hasPermission("coreprotect.lookup.container")) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
|
||||
return;
|
||||
}
|
||||
|
@ -228,7 +240,11 @@ public class LookupCommand {
|
|||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
|
||||
return;
|
||||
}
|
||||
if (argAction.contains(11) && (!player.hasPermission("coreprotect.lookup.inventory") || !player.hasPermission("coreprotect.lookup.item"))) {
|
||||
if (argAction.contains(11) && !argAction.contains(4) && !player.hasPermission("coreprotect.lookup.item")) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
|
||||
return;
|
||||
}
|
||||
if (argAction.contains(4) && argAction.contains(11) && !player.hasPermission("coreprotect.lookup.inventory")) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
|
||||
return;
|
||||
}
|
||||
|
@ -248,11 +264,23 @@ public class LookupCommand {
|
|||
}
|
||||
}
|
||||
|
||||
if (rbseconds <= 0 && !pageLookup && type == 4 && (argBlocks.size() > 0 || argUsers.size() > 0)) {
|
||||
if (startTime <= 0 && !pageLookup && type == 4 && (argBlocks.size() > 0 || argUsers.size() > 0)) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_LOOKUP_TIME, Selector.FIRST));
|
||||
return;
|
||||
}
|
||||
|
||||
if (argAction.contains(4) && argAction.contains(11)) { // a:inventory
|
||||
if (argUsers.size() == 0) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_ACTION_USER));
|
||||
return;
|
||||
}
|
||||
|
||||
argExclude.put(Material.FIRE, false);
|
||||
argExclude.put(Material.WATER, false);
|
||||
argExclude.put(Material.FARMLAND, false);
|
||||
argExcludeUsers.add("#hopper");
|
||||
}
|
||||
|
||||
if (type == 1) {
|
||||
boolean defaultRe = true;
|
||||
int p = 0;
|
||||
|
@ -329,14 +357,9 @@ public class LookupCommand {
|
|||
ConfigHandler.lookupThrottle.put(player2.getName(), new Object[] { true, System.currentTimeMillis() });
|
||||
if (connection != null) {
|
||||
Statement statement = connection.createStatement();
|
||||
String blockdata = ChestTransactionLookup.performLookup(command.getName(), statement, location, player2, p2, finalLimit, false);
|
||||
if (blockdata.contains("\n")) {
|
||||
for (String b : blockdata.split("\n")) {
|
||||
Chat.sendComponent(player2, b);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Chat.sendComponent(player2, blockdata);
|
||||
List<String> blockData = ChestTransactionLookup.performLookup(command.getName(), statement, location, player2, p2, finalLimit, false);
|
||||
for (String data : blockData) {
|
||||
Chat.sendComponent(player2, data);
|
||||
}
|
||||
statement.close();
|
||||
}
|
||||
|
@ -479,7 +502,7 @@ public class LookupCommand {
|
|||
boolean defaultRe = true;
|
||||
int pa = 1;
|
||||
int re = 4;
|
||||
if (argAction.contains(6) || argAction.contains(7) || argAction.contains(9)) {
|
||||
if (argAction.contains(6) || argAction.contains(7) || argAction.contains(9) || (argAction.contains(4) && argAction.contains(11))) {
|
||||
re = 7;
|
||||
}
|
||||
if (parseRows > 0) {
|
||||
|
@ -552,9 +575,17 @@ public class LookupCommand {
|
|||
}
|
||||
}
|
||||
c++;
|
||||
|
||||
if (argAction.contains(4) && argAction.contains(11)) {
|
||||
if (ruser.startsWith("#")) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_USERNAME, ruser));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int cs = -1;
|
||||
long timeStart = -1;
|
||||
long timeEnd = 0;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int z = 0;
|
||||
|
@ -567,14 +598,14 @@ public class LookupCommand {
|
|||
y = Integer.parseInt(data[1]);
|
||||
z = Integer.parseInt(data[2]);
|
||||
wid = Integer.parseInt(data[3]);
|
||||
cs = Integer.parseInt(data[4]);
|
||||
// arg_radius = Integer.parseInt(data[5]);
|
||||
argNoisy = Integer.parseInt(data[5]);
|
||||
argExcluded = Integer.parseInt(data[6]);
|
||||
argRestricted = Integer.parseInt(data[7]);
|
||||
argWid = Integer.parseInt(data[8]);
|
||||
timeStart = Long.parseLong(data[4]);
|
||||
timeEnd = Long.parseLong(data[5]);
|
||||
argNoisy = Integer.parseInt(data[6]);
|
||||
argExcluded = Integer.parseInt(data[7]);
|
||||
argRestricted = Integer.parseInt(data[8]);
|
||||
argWid = Integer.parseInt(data[9]);
|
||||
if (defaultRe) {
|
||||
re = Integer.parseInt(data[9]);
|
||||
re = Integer.parseInt(data[10]);
|
||||
}
|
||||
|
||||
rollbackusers = ConfigHandler.lookupUlist.get(player.getName());
|
||||
|
@ -584,7 +615,8 @@ public class LookupCommand {
|
|||
argAction = ConfigHandler.lookupAlist.get(player.getName());
|
||||
argRadius = ConfigHandler.lookupRadius.get(player.getName());
|
||||
ts = ConfigHandler.lookupTime.get(player.getName());
|
||||
rbseconds = 1;
|
||||
startTime = 1;
|
||||
endTime = 0;
|
||||
}
|
||||
else {
|
||||
if (lo != null) {
|
||||
|
@ -599,7 +631,7 @@ public class LookupCommand {
|
|||
}
|
||||
|
||||
if (rollbackusers.contains("#container")) {
|
||||
if (argAction.contains(6) || argAction.contains(7) || argAction.contains(8) || argAction.contains(9) || argAction.contains(10)) {
|
||||
if (argAction.contains(6) || argAction.contains(7) || argAction.contains(8) || argAction.contains(9) || argAction.contains(10) || argAction.contains(11)) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_USERNAME, "#container"));
|
||||
return;
|
||||
}
|
||||
|
@ -640,20 +672,28 @@ public class LookupCommand {
|
|||
}
|
||||
|
||||
final List<String> rollbackusers2 = rollbackusers;
|
||||
int unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
|
||||
if (cs == -1) {
|
||||
if (rbseconds <= 0) {
|
||||
cs = 0;
|
||||
long unixtimestamp = (System.currentTimeMillis() / 1000L);
|
||||
if (timeStart == -1) {
|
||||
if (startTime <= 0) {
|
||||
timeStart = 0;
|
||||
}
|
||||
else {
|
||||
cs = unixtimestamp - rbseconds;
|
||||
timeStart = unixtimestamp - startTime;
|
||||
}
|
||||
if (endTime <= 0) {
|
||||
timeEnd = 0;
|
||||
}
|
||||
else {
|
||||
timeEnd = unixtimestamp - endTime;
|
||||
}
|
||||
}
|
||||
final int stime = cs;
|
||||
|
||||
final long finalTimeStart = timeStart;
|
||||
final long finalTimeEnd = timeEnd;
|
||||
final Integer[] radius = argRadius;
|
||||
|
||||
try {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.LOOKUP_SEARCHING));
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Color.ITALIC + Phrase.build(Phrase.LOOKUP_SEARCHING));
|
||||
final CommandSender player2 = player;
|
||||
final int finalX = x;
|
||||
final int finalY = y;
|
||||
|
@ -666,7 +706,7 @@ public class LookupCommand {
|
|||
final int restricted = argRestricted;
|
||||
// final List<String> uuid_list = arg_uuids;
|
||||
final List<Object> blist = argBlocks;
|
||||
final List<Object> elist = argExclude;
|
||||
final Map<Object, Boolean> elist = argExclude;
|
||||
final List<String> euserlist = argExcludeUsers;
|
||||
final int page = pa;
|
||||
final int displayResults = re;
|
||||
|
@ -684,7 +724,7 @@ public class LookupCommand {
|
|||
List<String> uuidList = new ArrayList<>();
|
||||
Location location = finalLocation;
|
||||
boolean exists = false;
|
||||
String bc = finalX + "." + finalY + "." + finalZ + "." + finalWid + "." + stime + "." + noisy + "." + excluded + "." + restricted + "." + finalArgWid + "." + displayResults;
|
||||
String bc = finalX + "." + finalY + "." + finalZ + "." + finalWid + "." + finalTimeStart + "." + finalTimeEnd + "." + noisy + "." + excluded + "." + restricted + "." + finalArgWid + "." + displayResults;
|
||||
ConfigHandler.lookupCommand.put(player2.getName(), bc);
|
||||
ConfigHandler.lookupPage.put(player2.getName(), page);
|
||||
ConfigHandler.lookupTime.put(player2.getName(), rtime);
|
||||
|
@ -719,14 +759,14 @@ public class LookupCommand {
|
|||
}
|
||||
if (exists) {
|
||||
for (String check : euserlist) {
|
||||
if (!check.equals("#global")) {
|
||||
if (!check.equals("#global") && !check.equals("#hopper")) {
|
||||
exists = PlayerLookup.playerExists(connection, check);
|
||||
if (!exists) {
|
||||
baduser = check;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (check.equals("#global")) {
|
||||
baduser = "#global";
|
||||
exists = false;
|
||||
}
|
||||
|
@ -755,28 +795,34 @@ public class LookupCommand {
|
|||
location = new Location(Bukkit.getServer().getWorld(Util.getWorldName(finalWid)), finalX, finalY, finalZ);
|
||||
}
|
||||
|
||||
Long[] rowData = new Long[] { 0L, 0L, 0L, 0L };
|
||||
long rowMax = (long) page * displayResults;
|
||||
long pageStart = rowMax - displayResults;
|
||||
int rows = 0;
|
||||
long rows = 0L;
|
||||
boolean checkRows = true;
|
||||
|
||||
if (typeLookup == 5 && page > 1) {
|
||||
rows = ConfigHandler.lookupRows.get(player2.getName());
|
||||
rowData = ConfigHandler.lookupRows.get(player2.getName());
|
||||
rows = rowData[3];
|
||||
|
||||
if (pageStart < rows) {
|
||||
checkRows = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkRows) {
|
||||
rows = Lookup.countLookupRows(statement, player2, uuidList, userList, blist, elist, euserlist, finalArgAction, location, radius, stime, restrict_world, true);
|
||||
ConfigHandler.lookupRows.put(player2.getName(), rows);
|
||||
rows = Lookup.countLookupRows(statement, player2, uuidList, userList, blist, elist, euserlist, finalArgAction, location, radius, rowData, finalTimeStart, finalTimeEnd, restrict_world, true);
|
||||
rowData[3] = rows;
|
||||
ConfigHandler.lookupRows.put(player2.getName(), rowData);
|
||||
}
|
||||
if (finalCount) {
|
||||
String row_format = NumberFormat.getInstance().format(rows);
|
||||
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.LOOKUP_ROWS_FOUND, row_format, (rows == 1 ? Selector.FIRST : Selector.SECOND)));
|
||||
}
|
||||
else if (pageStart < rows) {
|
||||
List<String[]> lookupList = Lookup.performPartialLookup(statement, player2, uuidList, userList, blist, elist, euserlist, finalArgAction, location, radius, stime, (int) pageStart, displayResults, restrict_world, true);
|
||||
Chat.sendMessage(player2, Color.WHITE + "----- " + Color.DARK_AQUA + Phrase.build(Phrase.LOOKUP_HEADER, "CoreProtect") + Color.WHITE + " -----");
|
||||
List<String[]> lookupList = Lookup.performPartialLookup(statement, player2, uuidList, userList, blist, elist, euserlist, finalArgAction, location, radius, rowData, finalTimeStart, finalTimeEnd, (int) pageStart, displayResults, restrict_world, true);
|
||||
|
||||
Chat.sendMessage(player2, Color.WHITE + "----- " + Color.DARK_AQUA + Phrase.build(Phrase.LOOKUP_HEADER, "CoreProtect" + Color.WHITE + " | " + Color.DARK_AQUA) + Color.WHITE + " -----");
|
||||
if (finalArgAction.contains(6) || finalArgAction.contains(7)) { // Chat/command
|
||||
for (String[] data : lookupList) {
|
||||
String time = data[0];
|
||||
|
@ -784,6 +830,13 @@ public class LookupCommand {
|
|||
String message = data[2];
|
||||
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
|
||||
Chat.sendComponent(player2, timeago + " " + Color.WHITE + "- " + Color.DARK_AQUA + dplayer + ": " + Color.WHITE, message);
|
||||
if (PluginChannelHandshakeListener.getInstance().isPluginChannelPlayer(player2)) {
|
||||
int wid = Integer.parseInt(data[3]);
|
||||
int x = Integer.parseInt(data[4]);
|
||||
int y = Integer.parseInt(data[5]);
|
||||
int z = Integer.parseInt(data[6]);
|
||||
PluginChannelListener.getInstance().sendMessageData(player2, Integer.parseInt(time), dplayer, message, false, x, y, z, wid);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (finalArgAction.contains(8)) { // login/logouts
|
||||
|
@ -796,11 +849,19 @@ public class LookupCommand {
|
|||
int z = Integer.parseInt(data[5]);
|
||||
int action = Integer.parseInt(data[6]);
|
||||
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
|
||||
double time_length = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, false).replaceAll("[^0-9]", "").length() * 1.50;
|
||||
int padding = (int) (time_length + 12.50);
|
||||
String leftPadding = Strings.padStart("", padding, ' ');
|
||||
Chat.sendComponent(player2, timeago + " " + Color.WHITE + "- " + Color.DARK_AQUA + Phrase.build(Phrase.LOOKUP_LOGIN, Color.DARK_AQUA + dplayer + Color.WHITE, (action != 0 ? Selector.FIRST : Selector.SECOND)));
|
||||
int timeLength = 50 + (Util.getTimeSince(Integer.parseInt(time), unixtimestamp, false).replaceAll("[^0-9]", "").length() * 6);
|
||||
String leftPadding = Color.BOLD + Strings.padStart("", 10, ' ');
|
||||
if (timeLength % 4 == 0) {
|
||||
leftPadding = Strings.padStart("", timeLength / 4, ' ');
|
||||
}
|
||||
else {
|
||||
leftPadding = leftPadding + Color.WHITE + Strings.padStart("", (timeLength - 50) / 4, ' ');
|
||||
}
|
||||
|
||||
String tag = (action != 0 ? Color.GREEN + "+" : Color.RED + "-");
|
||||
Chat.sendComponent(player2, timeago + " " + tag + " " + Color.DARK_AQUA + Phrase.build(Phrase.LOOKUP_LOGIN, Color.DARK_AQUA + dplayer + Color.WHITE, (action != 0 ? Selector.FIRST : Selector.SECOND)));
|
||||
Chat.sendComponent(player2, Color.WHITE + leftPadding + Color.GREY + "^ " + Util.getCoordinates(command.getName(), wid, x, y, z, true, true) + "");
|
||||
PluginChannelListener.getInstance().sendInfoData(player2, Integer.parseInt(time), Phrase.LOOKUP_LOGIN, (action != 0 ? Selector.FIRST : Selector.SECOND), dplayer, -1, x, y, z, wid);
|
||||
}
|
||||
}
|
||||
else if (finalArgAction.contains(9)) { // username-changes
|
||||
|
@ -810,6 +871,7 @@ public class LookupCommand {
|
|||
String username = data[2];
|
||||
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
|
||||
Chat.sendComponent(player2, timeago + " " + Color.WHITE + "- " + Phrase.build(Phrase.LOOKUP_USERNAME, Color.DARK_AQUA + user + Color.WHITE, Color.DARK_AQUA + username + Color.WHITE));
|
||||
PluginChannelListener.getInstance().sendUsernameData(player2, Integer.parseInt(time), user, username);
|
||||
}
|
||||
}
|
||||
else if (finalArgAction.contains(10)) { // sign messages
|
||||
|
@ -822,18 +884,75 @@ public class LookupCommand {
|
|||
int z = Integer.parseInt(data[5]);
|
||||
String message = data[6];
|
||||
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
|
||||
double time_length = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, false).replaceAll("[^0-9]", "").length() * 1.50;
|
||||
int padding = (int) (time_length + 12.50);
|
||||
String leftPadding = Strings.padStart("", padding, ' ');
|
||||
int timeLength = 50 + (Util.getTimeSince(Integer.parseInt(time), unixtimestamp, false).replaceAll("[^0-9]", "").length() * 6);
|
||||
String leftPadding = Color.BOLD + Strings.padStart("", 10, ' ');
|
||||
if (timeLength % 4 == 0) {
|
||||
leftPadding = Strings.padStart("", timeLength / 4, ' ');
|
||||
}
|
||||
else {
|
||||
leftPadding = leftPadding + Color.WHITE + Strings.padStart("", (timeLength - 50) / 4, ' ');
|
||||
}
|
||||
|
||||
Chat.sendComponent(player2, timeago + " " + Color.WHITE + "- " + Color.DARK_AQUA + dplayer + ": " + Color.WHITE, message);
|
||||
Chat.sendComponent(player2, Color.WHITE + leftPadding + Color.GREY + "^ " + Util.getCoordinates(command.getName(), wid, x, y, z, true, true) + "");
|
||||
PluginChannelListener.getInstance().sendMessageData(player2, Integer.parseInt(time), dplayer, message, true, x, y, z, wid);
|
||||
}
|
||||
}
|
||||
else if (finalArgAction.contains(4) && finalArgAction.contains(11)) { // inventory transactions
|
||||
for (String[] data : lookupList) {
|
||||
String time = data[0];
|
||||
String dplayer = data[1];
|
||||
int dtype = Integer.parseInt(data[5]);
|
||||
int ddata = Integer.parseInt(data[6]);
|
||||
int daction = Integer.parseInt(data[7]);
|
||||
int amount = Integer.parseInt(data[10]);
|
||||
int wid = Integer.parseInt(data[9]);
|
||||
int x = Integer.parseInt(data[2]);
|
||||
int y = Integer.parseInt(data[3]);
|
||||
int z = Integer.parseInt(data[4]);
|
||||
String rbd = ((Integer.parseInt(data[8]) == 2 || Integer.parseInt(data[8]) == 3) ? Color.STRIKETHROUGH : "");
|
||||
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
|
||||
Material blockType = Util.itemFilter(Util.getType(dtype), (Integer.parseInt(data[13]) == 0));
|
||||
String dname = Util.nameFilter(blockType.name().toLowerCase(Locale.ROOT), ddata);
|
||||
byte[] metadata = data[11] == null ? null : data[11].getBytes(StandardCharsets.ISO_8859_1);
|
||||
String tooltip = Util.getEnchantments(metadata, dtype, amount);
|
||||
|
||||
String selector = Selector.FIRST;
|
||||
String tag = Color.WHITE + "-";
|
||||
if (daction == 2 || daction == 3) { // LOOKUP_ITEM
|
||||
selector = (daction != 2 ? Selector.FIRST : Selector.SECOND);
|
||||
tag = (daction != 2 ? Color.GREEN + "+" : Color.RED + "-");
|
||||
}
|
||||
else if (daction == 4 || daction == 5) { // LOOKUP_STORAGE
|
||||
selector = (daction == 4 ? Selector.FIRST : Selector.SECOND);
|
||||
tag = (daction == 4 ? Color.GREEN + "+" : Color.RED + "-");
|
||||
}
|
||||
else if (daction == 6 || daction == 7) { // LOOKUP_PROJECTILE
|
||||
selector = Selector.SECOND;
|
||||
tag = Color.RED + "-";
|
||||
}
|
||||
else if (daction == ItemLogger.ITEM_BREAK || daction == ItemLogger.ITEM_DESTROY || daction == ItemLogger.ITEM_CREATE) {
|
||||
selector = (daction == ItemLogger.ITEM_CREATE ? Selector.FIRST : Selector.SECOND);
|
||||
tag = (daction == ItemLogger.ITEM_CREATE ? Color.GREEN + "+" : Color.RED + "-");
|
||||
}
|
||||
else if (daction == ItemLogger.ITEM_SELL || daction == ItemLogger.ITEM_BUY) { // LOOKUP_TRADE
|
||||
selector = (daction == ItemLogger.ITEM_BUY ? Selector.FIRST : Selector.SECOND);
|
||||
tag = (daction == ItemLogger.ITEM_BUY ? Color.GREEN + "+" : Color.RED + "-");
|
||||
}
|
||||
else { // LOOKUP_CONTAINER
|
||||
selector = (daction == 0 ? Selector.FIRST : Selector.SECOND);
|
||||
tag = (daction == 0 ? Color.GREEN + "+" : Color.RED + "-");
|
||||
}
|
||||
|
||||
Chat.sendComponent(player2, timeago + " " + tag + " " + Phrase.build(Phrase.LOOKUP_CONTAINER, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, "x" + amount, Util.createTooltip(Color.DARK_AQUA + rbd + dname, tooltip) + Color.WHITE, selector));
|
||||
PluginChannelListener.getInstance().sendData(player2, Integer.parseInt(time), Phrase.LOOKUP_CONTAINER, selector, dplayer, dname, amount, x, y, z, wid, rbd, true, tag.contains("+"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (String[] data : lookupList) {
|
||||
int drb = Integer.parseInt(data[8]);
|
||||
String rbd = "";
|
||||
if (drb == 1) {
|
||||
if (drb == 1 || drb == 3) {
|
||||
rbd = Color.STRIKETHROUGH;
|
||||
}
|
||||
|
||||
|
@ -842,7 +961,7 @@ public class LookupCommand {
|
|||
int x = Integer.parseInt(data[2]);
|
||||
int y = Integer.parseInt(data[3]);
|
||||
int z = Integer.parseInt(data[4]);
|
||||
String dtype = data[5];
|
||||
int dtype = Integer.parseInt(data[5]);
|
||||
int ddata = Integer.parseInt(data[6]);
|
||||
int daction = Integer.parseInt(data[7]);
|
||||
int wid = Integer.parseInt(data[9]);
|
||||
|
@ -850,15 +969,19 @@ public class LookupCommand {
|
|||
String tag = Color.WHITE + "-";
|
||||
|
||||
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
|
||||
double timeLength = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, false).replaceAll("[^0-9]", "").length() * 1.50;
|
||||
int padding = (int) (timeLength + 12.50);
|
||||
String leftPadding = Strings.padStart("", padding, ' ');
|
||||
int timeLength = 50 + (Util.getTimeSince(Integer.parseInt(time), unixtimestamp, false).replaceAll("[^0-9]", "").length() * 6);
|
||||
String leftPadding = Color.BOLD + Strings.padStart("", 10, ' ');
|
||||
if (timeLength % 4 == 0) {
|
||||
leftPadding = Strings.padStart("", timeLength / 4, ' ');
|
||||
}
|
||||
else {
|
||||
leftPadding = leftPadding + Color.WHITE + Strings.padStart("", (timeLength - 50) / 4, ' ');
|
||||
}
|
||||
|
||||
String dname = "";
|
||||
boolean isPlayer = false;
|
||||
if (daction == 3 && !finalArgAction.contains(11) && amount == -1) {
|
||||
int dTypeInt = Integer.parseInt(dtype);
|
||||
if (dTypeInt == 0) {
|
||||
if (dtype == 0) {
|
||||
if (ConfigHandler.playerIdCacheReversed.get(ddata) == null) {
|
||||
UserStatement.loadName(connection, ddata);
|
||||
}
|
||||
|
@ -866,11 +989,11 @@ public class LookupCommand {
|
|||
isPlayer = true;
|
||||
}
|
||||
else {
|
||||
dname = Util.getEntityType(dTypeInt).name();
|
||||
dname = Util.getEntityType(dtype).name();
|
||||
}
|
||||
}
|
||||
else {
|
||||
dname = Util.getType(Integer.parseInt(dtype)).name().toLowerCase(Locale.ROOT);
|
||||
dname = Util.getType(dtype).name().toLowerCase(Locale.ROOT);
|
||||
dname = Util.nameFilter(dname, ddata);
|
||||
}
|
||||
if (dname.length() > 0 && !isPlayer) {
|
||||
|
@ -889,50 +1012,64 @@ public class LookupCommand {
|
|||
String selector = Selector.FIRST;
|
||||
String action = "a:block";
|
||||
if (finalArgAction.contains(4) || finalArgAction.contains(5) || finalArgAction.contains(11) || amount > -1) {
|
||||
byte[] metadata = data[11] == null ? null : data[11].getBytes(StandardCharsets.ISO_8859_1);
|
||||
String tooltip = Util.getEnchantments(metadata, dtype, amount);
|
||||
|
||||
if (daction == 2 || daction == 3) {
|
||||
phrase = Phrase.LOOKUP_ITEM; // {picked up|dropped}
|
||||
selector = (daction != 2 ? Selector.FIRST : Selector.SECOND);
|
||||
action = "a:inventory";
|
||||
tag = (daction != 2 ? Color.GREEN + "+" : Color.RED + "-");
|
||||
action = "a:item";
|
||||
}
|
||||
else if (daction == 4 || daction == 5) {
|
||||
phrase = Phrase.LOOKUP_STORAGE; // {deposited|withdrew}
|
||||
selector = (daction != 4 ? Selector.FIRST : Selector.SECOND);
|
||||
action = "a:inventory";
|
||||
tag = (daction != 4 ? Color.RED + "-" : Color.GREEN + "+");
|
||||
action = "a:item";
|
||||
}
|
||||
else if (daction == 6 || daction == 7) {
|
||||
phrase = Phrase.LOOKUP_PROJECTILE; // {threw|shot}
|
||||
selector = (daction != 7 ? Selector.FIRST : Selector.SECOND);
|
||||
tag = Color.RED + "-";
|
||||
action = "a:item";
|
||||
}
|
||||
else {
|
||||
phrase = Phrase.LOOKUP_CONTAINER; // {added|removed}
|
||||
selector = (daction != 0 ? Selector.FIRST : Selector.SECOND);
|
||||
tag = (daction != 0 ? Color.GREEN + "+" : Color.RED + "-");
|
||||
action = "a:container";
|
||||
}
|
||||
|
||||
Chat.sendComponent(player2, timeago + " " + tag + " " + Phrase.build(phrase, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, "x" + amount, Color.DARK_AQUA + rbd + dname + Color.WHITE, selector));
|
||||
Chat.sendComponent(player2, timeago + " " + tag + " " + Phrase.build(phrase, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, "x" + amount, Util.createTooltip(Color.DARK_AQUA + rbd + dname, tooltip) + Color.WHITE, selector));
|
||||
PluginChannelListener.getInstance().sendData(player2, Integer.parseInt(time), phrase, selector, dplayer, dname, (tag.contains("+") ? 1 : -1), x, y, z, wid, rbd, action.contains("container"), tag.contains("+"));
|
||||
}
|
||||
else {
|
||||
if (daction == 2 || daction == 3) {
|
||||
phrase = Phrase.LOOKUP_INTERACTION; // {clicked|killed}
|
||||
selector = (daction != 3 ? Selector.FIRST : Selector.SECOND);
|
||||
tag = (daction != 3 ? Color.WHITE + "-" : Color.RED + "-");
|
||||
action = (daction == 2 ? "a:click" : "a:kill");
|
||||
}
|
||||
else {
|
||||
phrase = Phrase.LOOKUP_BLOCK; // {placed|broke}
|
||||
selector = (daction != 0 ? Selector.FIRST : Selector.SECOND);
|
||||
tag = (daction != 0 ? Color.GREEN + "+" : Color.RED + "-");
|
||||
}
|
||||
|
||||
// tag = ChatColors.RED + "-";
|
||||
Chat.sendComponent(player2, timeago + " " + tag + " " + Phrase.build(phrase, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, Color.DARK_AQUA + rbd + dname + Color.WHITE, selector));
|
||||
PluginChannelListener.getInstance().sendData(player2, Integer.parseInt(time), phrase, selector, dplayer, dname, (tag.contains("+") ? 1 : -1), x, y, z, wid, rbd, false, tag.contains("+"));
|
||||
}
|
||||
|
||||
boolean itemLookup = finalArgAction.contains(4) && finalArgAction.contains(11);
|
||||
action = (finalArgAction.size() == 0 || itemLookup ? " (" + action + ")" : "");
|
||||
action = (finalArgAction.size() == 0 ? " (" + action + ")" : "");
|
||||
Chat.sendComponent(player2, Color.WHITE + leftPadding + Color.GREY + "^ " + Util.getCoordinates(command.getName(), wid, x, y, z, true, true) + Color.GREY + Color.ITALIC + action);
|
||||
}
|
||||
}
|
||||
if (rows > displayResults) {
|
||||
int total_pages = (int) Math.ceil(rows / (displayResults + 0.0));
|
||||
if (finalArgAction.contains(6) || finalArgAction.contains(7) || finalArgAction.contains(9)) {
|
||||
if (finalArgAction.contains(6) || finalArgAction.contains(7) || finalArgAction.contains(9) || (finalArgAction.contains(4) && finalArgAction.contains(11))) {
|
||||
Chat.sendMessage(player2, "-----");
|
||||
}
|
||||
Chat.sendComponent(player2, Util.getPageNavigation(command.getName(), page, total_pages) + "| " + Phrase.build(Phrase.LOOKUP_VIEW_PAGE, Color.WHITE, "/co l <page>"));
|
||||
Chat.sendComponent(player2, Util.getPageNavigation(command.getName(), page, total_pages));
|
||||
}
|
||||
}
|
||||
else if (rows > 0) {
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package net.coreprotect.command;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.listener.channel.PluginChannelListener;
|
||||
import net.coreprotect.utility.Chat;
|
||||
import net.coreprotect.utility.Color;
|
||||
|
||||
public class NetworkDebugCommand {
|
||||
protected static void runCommand(CommandSender player, boolean permission, String[] args) {
|
||||
if (!permission || !Config.getGlobal().NETWORK_DEBUG) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
PluginChannelListener.getInstance().sendTest(player, args.length == 2 ? args[1] : "");
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +1,23 @@
|
|||
package net.coreprotect.command;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.*;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import 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;
|
||||
|
@ -28,10 +36,19 @@ public class PurgeCommand extends Consumer {
|
|||
int resultc = args.length;
|
||||
Location location = CommandHandler.parseLocation(player, args);
|
||||
final Integer[] argRadius = CommandHandler.parseRadius(args, player, location);
|
||||
final int seconds = CommandHandler.parseTime(args);
|
||||
final int argWid = CommandHandler.parseWorld(args, false, false);
|
||||
final List<Integer> argAction = CommandHandler.parseAction(args);
|
||||
final List<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> 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));
|
||||
|
@ -49,7 +66,7 @@ public class PurgeCommand extends Consumer {
|
|||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_PARAMETERS, "/co purge t:<time>"));
|
||||
return;
|
||||
}
|
||||
if (seconds <= 0) {
|
||||
if (endTime <= 0) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_PARAMETERS, "/co purge t:<time>"));
|
||||
return;
|
||||
}
|
||||
|
@ -62,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));
|
||||
|
@ -69,12 +94,70 @@ public class PurgeCommand extends Consumer {
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (player instanceof Player && seconds < 2592000) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_MINIMUM_TIME, "30", Selector.FIRST)); // 30 days
|
||||
return;
|
||||
|
||||
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 (seconds < 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;
|
||||
}
|
||||
|
||||
|
@ -85,18 +168,26 @@ 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 {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try (Connection connection = Database.getConnection(false, 500)) {
|
||||
int timestamp = (int) (System.currentTimeMillis() / 1000L);
|
||||
int ptime = timestamp - seconds;
|
||||
try {
|
||||
long timestamp = (System.currentTimeMillis() / 1000L);
|
||||
long timeStart = startTime > 0 ? (timestamp - startTime) : 0;
|
||||
long timeEnd = timestamp - endTime;
|
||||
long removed = 0;
|
||||
|
||||
Connection connection = null;
|
||||
for (int i = 0; i <= 5; i++) {
|
||||
connection = Database.getConnection(false, 500);
|
||||
if (connection != null) {
|
||||
break;
|
||||
}
|
||||
|
@ -115,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));
|
||||
|
||||
|
@ -164,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("_", " ");
|
||||
|
@ -190,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 >= '" + ptime + "') 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 >= '" + ptime + "'";
|
||||
timeLimit = " WHERE " + blockRestriction + "(time >= '" + timeEnd + "' OR time < '" + timeStart + "')";
|
||||
}
|
||||
}
|
||||
query = "INSERT INTO " + purgePrefix + table + " SELECT " + columns + " FROM " + ConfigHandler.prefix + table + timeLimit;
|
||||
|
@ -248,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 + "'";
|
||||
|
@ -257,7 +367,7 @@ public class PurgeCommand extends Consumer {
|
|||
}
|
||||
|
||||
if (purge) {
|
||||
query = "DELETE FROM " + purgePrefix + table + " WHERE time < '" + ptime + "'" + worldRestriction;
|
||||
query = "DELETE FROM " + purgePrefix + table + " WHERE " + blockRestriction + "time < '" + timeEnd + "' AND time >= '" + timeStart + "'" + worldRestriction;
|
||||
preparedStmt = connection.prepareStatement(query);
|
||||
preparedStmt.execute();
|
||||
preparedStmt.close();
|
||||
|
@ -307,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 + "'";
|
||||
|
@ -316,7 +434,7 @@ public class PurgeCommand extends Consumer {
|
|||
}
|
||||
|
||||
if (purge) {
|
||||
query = "DELETE FROM " + ConfigHandler.prefix + table + " WHERE time < '" + ptime + "'" + 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();
|
||||
|
@ -324,6 +442,11 @@ public class PurgeCommand extends Consumer {
|
|||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (!ConfigHandler.serverRunning) {
|
||||
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_FAILED));
|
||||
return;
|
||||
}
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -339,6 +462,8 @@ public class PurgeCommand extends Consumer {
|
|||
}
|
||||
}
|
||||
|
||||
connection.close();
|
||||
|
||||
if (abort) {
|
||||
if (!Config.getGlobal().MYSQL) {
|
||||
(new File(ConfigHandler.path + ConfigHandler.sqlite + ".tmp")).delete();
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.sql.Statement;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
|
@ -22,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;
|
||||
|
@ -31,7 +32,7 @@ import net.coreprotect.utility.Color;
|
|||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class RollbackRestoreCommand {
|
||||
protected static void runCommand(CommandSender player, Command command, boolean permission, String[] args, Location argLocation, int forceSeconds) {
|
||||
protected static void runCommand(CommandSender player, Command command, boolean permission, String[] args, Location argLocation, long forceStart, long forceEnd) {
|
||||
Location lo = (argLocation != null ? argLocation : CommandHandler.parseLocation(player, args));
|
||||
List<String> argUuids = new ArrayList<>();
|
||||
List<String> argUsers = CommandHandler.parseUsers(args);
|
||||
|
@ -39,10 +40,12 @@ public class RollbackRestoreCommand {
|
|||
int argNoisy = CommandHandler.parseNoisy(args);
|
||||
List<Integer> argAction = CommandHandler.parseAction(args);
|
||||
List<Object> argBlocks = CommandHandler.parseRestricted(player, args, argAction);
|
||||
List<Object> argExclude = CommandHandler.parseExcluded(player, args, argAction);
|
||||
Map<Object, Boolean> argExclude = CommandHandler.parseExcluded(player, args, argAction);
|
||||
List<String> argExcludeUsers = CommandHandler.parseExcludedUsers(player, args);
|
||||
String ts = CommandHandler.parseTimeString(args);
|
||||
int rbSeconds = CommandHandler.parseTime(args);
|
||||
long[] argTime = CommandHandler.parseTime(args);
|
||||
long startTime = argTime[0];
|
||||
long endTime = argTime[1];
|
||||
int argWid = CommandHandler.parseWorld(args, true, true);
|
||||
boolean count = CommandHandler.parseCount(args);
|
||||
boolean worldedit = CommandHandler.parseWorldEdit(args);
|
||||
|
@ -74,7 +77,7 @@ public class RollbackRestoreCommand {
|
|||
}
|
||||
|
||||
/* check for invalid block/entity combinations (exclude) */
|
||||
for (Object arg : argExclude) {
|
||||
for (Object arg : argExclude.keySet()) {
|
||||
if (arg instanceof Material) {
|
||||
hasBlock = true;
|
||||
}
|
||||
|
@ -139,7 +142,7 @@ public class RollbackRestoreCommand {
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (preview > 1 && forceSeconds <= 0) {
|
||||
if (preview > 1 && forceStart <= 0) {
|
||||
preview = 1;
|
||||
}
|
||||
|
||||
|
@ -151,13 +154,13 @@ public class RollbackRestoreCommand {
|
|||
final int finalAction = a;
|
||||
|
||||
int DEFAULT_RADIUS = Config.getGlobal().DEFAULT_RADIUS;
|
||||
if ((player instanceof Player || player instanceof BlockCommandSender) && argRadius == null && DEFAULT_RADIUS > 0 && !forceglobal) {
|
||||
if ((player instanceof Player || player instanceof BlockCommandSender) && argRadius == null && DEFAULT_RADIUS > 0 && !forceglobal && !argAction.contains(11)) {
|
||||
Location location = lo;
|
||||
int xmin = location.getBlockX() - DEFAULT_RADIUS;
|
||||
int xmax = location.getBlockX() + DEFAULT_RADIUS;
|
||||
int zmin = location.getBlockZ() - DEFAULT_RADIUS;
|
||||
int zmax = location.getBlockZ() + DEFAULT_RADIUS;
|
||||
argRadius = new Integer[] { DEFAULT_RADIUS, xmin, xmax, -1, -1, zmin, zmax, 0 };
|
||||
argRadius = new Integer[] { DEFAULT_RADIUS, xmin, xmax, null, null, zmin, zmax, 0 };
|
||||
}
|
||||
// if (arg_radius==-2)arg_radius = -1;
|
||||
|
||||
|
@ -178,6 +181,21 @@ public class RollbackRestoreCommand {
|
|||
return;
|
||||
}
|
||||
|
||||
if (argAction.contains(4) && argAction.contains(11)) { // a:inventory
|
||||
if (argUsers.size() == 0) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.MISSING_ACTION_USER));
|
||||
return;
|
||||
}
|
||||
|
||||
argExclude.put(Material.FIRE, false);
|
||||
argExclude.put(Material.WATER, false);
|
||||
argExclude.put(Material.FARMLAND, false);
|
||||
argExcludeUsers.add("#hopper");
|
||||
}
|
||||
else if (!argAction.contains(4) && Config.getGlobal().EXCLUDE_TNT && !argExclude.containsKey(Material.TNT) && !argBlocks.contains(Material.TNT)) {
|
||||
argExclude.put(Material.TNT, true);
|
||||
}
|
||||
|
||||
if (g == 1 && (argUsers.size() > 0 || (argUsers.size() == 0 && argRadius != null))) {
|
||||
Integer MAX_RADIUS = Config.getGlobal().MAX_RADIUS;
|
||||
if (argRadius != null) {
|
||||
|
@ -195,11 +213,11 @@ public class RollbackRestoreCommand {
|
|||
return;
|
||||
}
|
||||
else if (preview > 0) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PREVIEW_CONTAINER));
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PREVIEW_TRANSACTION, !argAction.contains(11) ? Selector.FIRST : Selector.SECOND));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (argAction.contains(8) || argAction.contains(11) || (!argAction.contains(0) && !argAction.contains(1) && !argAction.contains(3) && !argAction.contains(4))) {
|
||||
if (argAction.contains(8) || (argAction.contains(11) && !argAction.contains(4)) || (!argAction.contains(0) && !argAction.contains(1) && !argAction.contains(3) && !argAction.contains(4))) {
|
||||
if (finalAction == 0) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ACTION_NOT_SUPPORTED));
|
||||
}
|
||||
|
@ -213,16 +231,26 @@ public class RollbackRestoreCommand {
|
|||
if (argUsers.size() == 0) {
|
||||
argUsers.add("#global");
|
||||
}
|
||||
|
||||
List<String> rollbackusers = argUsers;
|
||||
int c = 0;
|
||||
for (String ruser : rollbackusers) {
|
||||
List<Player> players = Bukkit.getServer().matchPlayer(ruser);
|
||||
List<Player> players = Bukkit.getServer().matchPlayer(ruser); // here
|
||||
for (Player p : players) {
|
||||
if (p.getName().equalsIgnoreCase(ruser)) {
|
||||
rollbackusers.set(c, p.getName());
|
||||
ruser = p.getName();
|
||||
rollbackusers.set(c, ruser);
|
||||
}
|
||||
}
|
||||
c++;
|
||||
|
||||
if (argAction.contains(4) && argAction.contains(11)) {
|
||||
Player onlineUser = Bukkit.getServer().getPlayer(ruser);
|
||||
if (onlineUser == null || !onlineUser.isOnline()) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.USER_OFFLINE, ruser));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int wid = 0;
|
||||
|
@ -230,6 +258,11 @@ public class RollbackRestoreCommand {
|
|||
int y = 0;
|
||||
int z = 0;
|
||||
if (rollbackusers.contains("#container")) {
|
||||
if (argAction.contains(11)) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.INVALID_USERNAME, "#container"));
|
||||
return;
|
||||
}
|
||||
|
||||
boolean valid = false;
|
||||
if (ConfigHandler.lookupType.get(player.getName()) != null) {
|
||||
int lookupType = ConfigHandler.lookupType.get(player.getName());
|
||||
|
@ -244,7 +277,7 @@ public class RollbackRestoreCommand {
|
|||
}
|
||||
if (valid) {
|
||||
if (preview > 0) {
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PREVIEW_CONTAINER));
|
||||
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PREVIEW_TRANSACTION, Selector.FIRST));
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
@ -283,13 +316,16 @@ public class RollbackRestoreCommand {
|
|||
}
|
||||
|
||||
final List<String> rollbackusers2 = rollbackusers;
|
||||
if (rbSeconds > 0) {
|
||||
int unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
|
||||
int seconds = unixtimestamp - rbSeconds;
|
||||
if (forceSeconds > 0) {
|
||||
seconds = forceSeconds;
|
||||
if (startTime > 0) {
|
||||
long unixtimestamp = (System.currentTimeMillis() / 1000L);
|
||||
long timeStart = unixtimestamp - startTime;
|
||||
long timeEnd = endTime > 0 ? (unixtimestamp - endTime) : 0;
|
||||
if (forceStart > 0) {
|
||||
timeStart = forceStart;
|
||||
timeEnd = forceEnd;
|
||||
}
|
||||
final int stime = seconds;
|
||||
final long finalTimeStart = timeStart;
|
||||
final long finalTimeEnd = timeEnd;
|
||||
final Integer[] radius = argRadius;
|
||||
try {
|
||||
final CommandSender player2 = player;
|
||||
|
@ -297,7 +333,7 @@ public class RollbackRestoreCommand {
|
|||
final String rtime = ts;
|
||||
final List<String> uuidList = argUuids;
|
||||
final List<Object> blist = argBlocks;
|
||||
final List<Object> elist = argExclude;
|
||||
final Map<Object, Boolean> elist = argExclude;
|
||||
final List<String> euserlist = argExcludeUsers;
|
||||
final Location locationFinal = lo;
|
||||
final int finalArgWid = argWid;
|
||||
|
@ -332,14 +368,14 @@ public class RollbackRestoreCommand {
|
|||
}
|
||||
if (exists) {
|
||||
for (String check : euserlist) {
|
||||
if (!check.equals("#global")) {
|
||||
if (!check.equals("#global") && !check.equals("#hopper")) {
|
||||
exists = PlayerLookup.playerExists(connection, check);
|
||||
if (!exists) {
|
||||
baduser = check;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (check.equals("#global")) {
|
||||
baduser = "#global";
|
||||
exists = false;
|
||||
}
|
||||
|
@ -389,17 +425,18 @@ public class RollbackRestoreCommand {
|
|||
}
|
||||
|
||||
if (finalArgAction.contains(5)) {
|
||||
ContainerRollback.performContainerRollbackRestore(statement, player2, uuidList, rollbackusers2, rtime, blist, elist, euserlist, finalArgAction, location, radius, stime, restrictWorld, false, verbose, action);
|
||||
ContainerRollback.performContainerRollbackRestore(statement, player2, uuidList, rollbackusers2, rtime, blist, elist, euserlist, finalArgAction, location, radius, finalTimeStart, finalTimeEnd, restrictWorld, false, verbose, action);
|
||||
}
|
||||
else {
|
||||
Rollback.performRollbackRestore(statement, player2, uuidList, rollbackusers2, rtime, blist, elist, euserlist, finalArgAction, location, radius, stime, restrictWorld, false, verbose, action, finalPreview);
|
||||
if (finalPreview < 2) {
|
||||
List<Object> list = new ArrayList<>();
|
||||
list.add(stime);
|
||||
list.add(finalArgs);
|
||||
list.add(locationFinal);
|
||||
ConfigHandler.lastRollback.put(player2.getName(), list);
|
||||
}
|
||||
Rollback.performRollbackRestore(statement, player2, uuidList, rollbackusers2, rtime, blist, elist, euserlist, finalArgAction, location, radius, finalTimeStart, finalTimeEnd, restrictWorld, false, verbose, action, finalPreview);
|
||||
}
|
||||
if (finalPreview < 2) {
|
||||
List<Object> list = new ArrayList<>();
|
||||
list.add(finalTimeStart);
|
||||
list.add(finalTimeEnd);
|
||||
list.add(finalArgs);
|
||||
list.add(locationFinal);
|
||||
ConfigHandler.lastRollback.put(player2.getName(), list);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -24,7 +24,7 @@ public class TabHandler implements TabCompleter {
|
|||
// private static String[] COMMANDS = new String[] { "help", "inspect", "rollback", "restore", "lookup", "purge", "reload", "status", "near", "undo" }; // max 10!
|
||||
private static String[] HELP = new String[] { "inspect", "rollback", "restore", "lookup", "purge", "teleport", "status", "params", "users", "time", "radius", "action", "include", "exclude" };
|
||||
private static String[] PARAMS = new String[] { "user:", "time:", "radius:", "action:", "include:", "exclude:", "#container" };
|
||||
private static String[] ACTIONS = new String[] { "block", "+block", "-block", "click", "kill", "container", "chat", "command", "+inventory", "-inventory", "inventory", "item", "+item", "-item", "sign", "session", "+session", "-session", "username" };
|
||||
private static String[] ACTIONS = new String[] { "block", "+block", "-block", "click", "kill", "+container", "-container", "container", "chat", "command", "+inventory", "-inventory", "inventory", "item", "+item", "-item", "sign", "session", "+session", "-session", "username" };
|
||||
private static String[] NUMBERS = new String[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
||||
private static String[] TIMES = new String[] { "w", "d", "h", "m", "s" };
|
||||
private static ArrayList<String> materials = null;
|
||||
|
@ -141,11 +141,11 @@ public class TabHandler implements TabCompleter {
|
|||
}
|
||||
}
|
||||
|
||||
if (lastArg.equals("a:") || lastArg.equals("action:")) {
|
||||
if ((lastArg.equals("a:") || lastArg.equals("action:")) && (sender.hasPermission("coreprotect.lookup") || sender.hasPermission("coreprotect.rollback") || sender.hasPermission("coreprotect.restore"))) {
|
||||
List<String> completions = new ArrayList<>(Arrays.asList(ACTIONS));
|
||||
return StringUtil.copyPartialMatches(currentArg, completions, new ArrayList<>(completions.size()));
|
||||
}
|
||||
else if (currentArg.startsWith("a:") || currentArg.startsWith("action:")) {
|
||||
else if ((currentArg.startsWith("a:") || currentArg.startsWith("action:")) && (sender.hasPermission("coreprotect.lookup") || sender.hasPermission("coreprotect.rollback") || sender.hasPermission("coreprotect.restore"))) {
|
||||
String arg = "";
|
||||
String[] split = currentArg.split(":", 2);
|
||||
String filter = split[0] + ":";
|
||||
|
@ -159,10 +159,10 @@ public class TabHandler implements TabCompleter {
|
|||
}
|
||||
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
|
||||
}
|
||||
else if (lastArg.equals("u:") || lastArg.equals("user:") || lastArg.equals("users:") || lastArg.equals("p:")) {
|
||||
else if ((lastArg.equals("u:") || lastArg.equals("user:") || lastArg.equals("users:") || lastArg.equals("p:")) && (sender.hasPermission("coreprotect.lookup") || sender.hasPermission("coreprotect.rollback") || sender.hasPermission("coreprotect.restore"))) {
|
||||
return null;
|
||||
}
|
||||
else if (currentArg.startsWith("u:") || currentArg.startsWith("user:") || currentArg.startsWith("users:") || currentArg.startsWith("p:")) {
|
||||
else if ((currentArg.startsWith("u:") || currentArg.startsWith("user:") || currentArg.startsWith("users:") || currentArg.startsWith("p:")) && (sender.hasPermission("coreprotect.lookup") || sender.hasPermission("coreprotect.rollback") || sender.hasPermission("coreprotect.restore"))) {
|
||||
String arg = "";
|
||||
String[] split = currentArg.split(":", 2);
|
||||
String filter = split[0] + ":";
|
||||
|
@ -177,7 +177,7 @@ public class TabHandler implements TabCompleter {
|
|||
|
||||
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
|
||||
}
|
||||
else if (lastArg.equals("t:") || lastArg.equals("time:") || currentArg.startsWith("t:") || currentArg.startsWith("time:")) {
|
||||
else if ((lastArg.equals("t:") || lastArg.equals("time:") || currentArg.startsWith("t:") || currentArg.startsWith("time:")) && (sender.hasPermission("coreprotect.lookup") || sender.hasPermission("coreprotect.rollback") || sender.hasPermission("coreprotect.restore") || sender.hasPermission("coreprotect.purge"))) {
|
||||
String filter = lastArg;
|
||||
String arg = "";
|
||||
if (currentArg.contains(":")) {
|
||||
|
@ -215,7 +215,7 @@ public class TabHandler implements TabCompleter {
|
|||
|
||||
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
|
||||
}
|
||||
else if (lastArg.equals("page:") || currentArg.startsWith("page:")) {
|
||||
else if ((lastArg.equals("page:") || currentArg.startsWith("page:")) && (sender.hasPermission("coreprotect.lookup") || sender.hasPermission("coreprotect.lookup.near") || sender.hasPermission("coreprotect.inspect"))) {
|
||||
String filter = lastArg;
|
||||
String arg = "";
|
||||
if (currentArg.contains(":")) {
|
||||
|
@ -243,7 +243,7 @@ public class TabHandler implements TabCompleter {
|
|||
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
|
||||
}
|
||||
}
|
||||
else if (lastArg.equals("r:") || lastArg.equals("radius:") || currentArg.startsWith("r:") || currentArg.startsWith("radius:")) {
|
||||
else if ((lastArg.equals("r:") || lastArg.equals("radius:") || currentArg.startsWith("r:") || currentArg.startsWith("radius:")) && (sender.hasPermission("coreprotect.lookup") || sender.hasPermission("coreprotect.rollback") || sender.hasPermission("coreprotect.restore") || sender.hasPermission("coreprotect.purge"))) {
|
||||
String filter = lastArg;
|
||||
String arg = "";
|
||||
if (currentArg.contains(":")) {
|
||||
|
@ -284,7 +284,7 @@ public class TabHandler implements TabCompleter {
|
|||
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
|
||||
}
|
||||
}
|
||||
else if (lastArg.equals("i:") || lastArg.equals("include:") || lastArg.equals("item:") || lastArg.equals("items:") || lastArg.equals("b:") || lastArg.equals("block:") || lastArg.equals("blocks:") || currentArg.startsWith("i:") || currentArg.startsWith("include:") || currentArg.startsWith("item:") || currentArg.startsWith("items:") || currentArg.startsWith("b:") || currentArg.startsWith("block:") || currentArg.startsWith("blocks:") || lastArg.equals("e:") || lastArg.equals("exclude:") || currentArg.startsWith("e:") || currentArg.startsWith("exclude:")) {
|
||||
else if ((sender.hasPermission("coreprotect.lookup") || sender.hasPermission("coreprotect.rollback") || sender.hasPermission("coreprotect.restore")) && (lastArg.equals("i:") || lastArg.equals("include:") || lastArg.equals("item:") || lastArg.equals("items:") || lastArg.equals("b:") || lastArg.equals("block:") || lastArg.equals("blocks:") || currentArg.startsWith("i:") || currentArg.startsWith("include:") || currentArg.startsWith("item:") || currentArg.startsWith("items:") || currentArg.startsWith("b:") || currentArg.startsWith("block:") || currentArg.startsWith("blocks:") || lastArg.equals("e:") || lastArg.equals("exclude:") || currentArg.startsWith("e:") || currentArg.startsWith("exclude:"))) {
|
||||
String filter = lastArg;
|
||||
String arg = "";
|
||||
if (currentArg.contains(":")) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -328,21 +333,21 @@ public class TabHandler implements TabCompleter {
|
|||
|
||||
}
|
||||
else if (args.length == 2) {
|
||||
if (argument0.equals("help")) {
|
||||
if (argument0.equals("help") && sender.hasPermission("coreprotect.help")) {
|
||||
List<String> completions = new ArrayList<>(Arrays.asList(HELP));
|
||||
return StringUtil.copyPartialMatches(argument1, completions, new ArrayList<>(completions.size()));
|
||||
}
|
||||
else if (argument0.equals("purge")) {
|
||||
else if (argument0.equals("purge") && sender.hasPermission("coreprotect.purge")) {
|
||||
List<String> completions = new ArrayList<>(Arrays.asList("t:", "r:"));
|
||||
return StringUtil.copyPartialMatches(argument1, completions, new ArrayList<>(completions.size()));
|
||||
}
|
||||
else if (argument0.equals("l") || argument0.equals("lookup") || argument0.equals("rollback") || argument0.equals("rb") || argument0.equals("ro") || argument0.equals("restore") || argument0.equals("rs") || argument0.equals("re")) {
|
||||
else if ((sender.hasPermission("coreprotect.lookup") && (argument0.equals("l") || argument0.equals("lookup"))) || (sender.hasPermission("coreprotect.rollback") && (argument0.equals("rollback") || argument0.equals("rb") || argument0.equals("ro"))) || (sender.hasPermission("coreprotect.restore") && (argument0.equals("restore") || argument0.equals("rs") || argument0.equals("re")))) {
|
||||
List<String> completions = new ArrayList<>(filterParams(true, argument0, argument1, hasUser, hasAction, hasInclude, hasExclude, hasRadius, hasTime, hasContainer, hasCount, hasPreview, pageLookup, validContainer));
|
||||
completions.addAll(Bukkit.getOnlinePlayers().stream().filter(player -> player.getName().toLowerCase(Locale.ROOT).startsWith(argument1)).map(Player::getName).collect(Collectors.toList()));
|
||||
return StringUtil.copyPartialMatches(argument1, completions, new ArrayList<>(completions.size()));
|
||||
}
|
||||
}
|
||||
else if (args.length == 3 && argument0.equals("purge")) {
|
||||
else if (args.length == 3 && argument0.equals("purge") && sender.hasPermission("coreprotect.purge")) {
|
||||
if (argument1.startsWith("t:")) {
|
||||
List<String> completions = new ArrayList<>(Arrays.asList("r:"));
|
||||
return StringUtil.copyPartialMatches(args[2].toLowerCase(Locale.ROOT), completions, new ArrayList<>(completions.size()));
|
||||
|
@ -353,7 +358,7 @@ public class TabHandler implements TabCompleter {
|
|||
}
|
||||
return Arrays.asList("");
|
||||
}
|
||||
else if (argument0.equals("l") || argument0.equals("lookup") || argument0.equals("rollback") || argument0.equals("rb") || argument0.equals("ro") || argument0.equals("restore") || argument0.equals("rs") || argument0.equals("re")) {
|
||||
else if ((sender.hasPermission("coreprotect.lookup") && (argument0.equals("l") || argument0.equals("lookup"))) || (sender.hasPermission("coreprotect.rollback") && (argument0.equals("rollback") || argument0.equals("rb") || argument0.equals("ro"))) || (sender.hasPermission("coreprotect.restore") && (argument0.equals("restore") || argument0.equals("rs") || argument0.equals("re")))) {
|
||||
if ((!argument0.equals("l") && !argument0.equals("lookup")) || !hasPage) {
|
||||
ArrayList<String> params = filterParams(false, argument0, currentArg, hasUser, hasAction, hasInclude, hasExclude, hasRadius, hasTime, hasContainer, hasCount, hasPreview, pageLookup, validContainer);
|
||||
List<String> completions = new ArrayList<>(params);
|
||||
|
|
|
@ -6,11 +6,14 @@ import org.bukkit.World;
|
|||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.thread.Scheduler;
|
||||
import net.coreprotect.utility.Chat;
|
||||
import net.coreprotect.utility.ChatMessage;
|
||||
import net.coreprotect.utility.Color;
|
||||
import net.coreprotect.utility.Teleport;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class TeleportCommand {
|
||||
|
@ -98,12 +101,14 @@ public class TeleportCommand {
|
|||
|
||||
int chunkX = location.getBlockX() >> 4;
|
||||
int chunkZ = location.getBlockZ() >> 4;
|
||||
if (location.getWorld().isChunkLoaded(chunkX, chunkZ) == false) {
|
||||
location.getWorld().getChunkAt(location);
|
||||
}
|
||||
Scheduler.runTask(CoreProtect.getInstance(), () -> {
|
||||
if (!location.getWorld().isChunkLoaded(chunkX, chunkZ)) {
|
||||
location.getWorld().getChunkAt(location);
|
||||
}
|
||||
|
||||
// Teleport the player to a safe location
|
||||
Util.performSafeTeleport(((Player) player), location, true);
|
||||
// Teleport the player to a safe location
|
||||
Teleport.performSafeTeleport(((Player) player), location, true);
|
||||
}, location);
|
||||
|
||||
ConfigHandler.teleportThrottle.put(player.getName(), new Object[] { false, System.currentTimeMillis() });
|
||||
}
|
||||
|
|
|
@ -11,16 +11,16 @@ import net.coreprotect.language.Phrase;
|
|||
import net.coreprotect.language.Selector;
|
||||
import net.coreprotect.utility.Chat;
|
||||
import net.coreprotect.utility.Color;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class UndoCommand {
|
||||
protected static void runCommand(CommandSender user, Command command, boolean permission, String[] args) {
|
||||
try {
|
||||
if (ConfigHandler.lastRollback.get(user.getName()) != null) {
|
||||
List<Object> list = ConfigHandler.lastRollback.get(user.getName());
|
||||
int time = (Integer) list.get(0);
|
||||
args = (String[]) list.get(1);
|
||||
Location location = (Location) list.get(2);
|
||||
long startTime = (Long) list.get(0);
|
||||
long endTime = (Long) list.get(1);
|
||||
args = (String[]) list.get(2);
|
||||
Location location = (Location) list.get(3);
|
||||
for (String arg : args) {
|
||||
if (arg.equals("#preview")) {
|
||||
CancelCommand.runCommand(user, command, permission, args);
|
||||
|
@ -39,7 +39,7 @@ public class UndoCommand {
|
|||
}
|
||||
if (valid) {
|
||||
ConfigHandler.lastRollback.remove(user.getName());
|
||||
RollbackRestoreCommand.runCommand(user, command, permission, args, location, time);
|
||||
RollbackRestoreCommand.runCommand(user, command, permission, args, location, startTime, endTime);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -20,13 +20,13 @@ import org.bukkit.World;
|
|||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.language.Language;
|
||||
import net.coreprotect.thread.Scheduler;
|
||||
|
||||
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";
|
||||
|
||||
|
@ -41,9 +41,14 @@ public class Config extends Language {
|
|||
public String MYSQL_USERNAME;
|
||||
public String MYSQL_PASSWORD;
|
||||
public String LANGUAGE;
|
||||
public boolean ENABLE_SSL;
|
||||
public boolean DISABLE_WAL;
|
||||
public boolean HOVER_EVENTS;
|
||||
public boolean DATABASE_LOCK;
|
||||
public boolean LOG_CANCELLED_CHAT;
|
||||
public boolean HOPPER_FILTER_META;
|
||||
public boolean EXCLUDE_TNT;
|
||||
public boolean NETWORK_DEBUG;
|
||||
public boolean MYSQL;
|
||||
public boolean CHECK_UPDATES;
|
||||
public boolean API_ENABLED;
|
||||
|
@ -67,6 +72,7 @@ public class Config extends Language {
|
|||
public boolean TREE_GROWTH;
|
||||
public boolean MUSHROOM_GROWTH;
|
||||
public boolean VINE_GROWTH;
|
||||
public boolean SCULK_SPREAD;
|
||||
public boolean PORTALS;
|
||||
public boolean WATER_FLOW;
|
||||
public boolean LAVA_FLOW;
|
||||
|
@ -79,8 +85,10 @@ public class Config extends Language {
|
|||
public boolean PLAYER_MESSAGES;
|
||||
public boolean PLAYER_COMMANDS;
|
||||
public boolean PLAYER_SESSIONS;
|
||||
public boolean UNKNOWN_LOGGING;
|
||||
public boolean USERNAME_CHANGES;
|
||||
public boolean WORLDEDIT;
|
||||
public int MAXIMUM_POOL_SIZE;
|
||||
public int MYSQL_PORT;
|
||||
public int DEFAULT_RADIUS;
|
||||
public int MAX_RADIUS;
|
||||
|
@ -119,6 +127,7 @@ public class Config extends Language {
|
|||
DEFAULT_VALUES.put("tree-growth", "true");
|
||||
DEFAULT_VALUES.put("mushroom-growth", "true");
|
||||
DEFAULT_VALUES.put("vine-growth", "true");
|
||||
DEFAULT_VALUES.put("sculk-spread", "true");
|
||||
DEFAULT_VALUES.put("portals", "true");
|
||||
DEFAULT_VALUES.put("water-flow", "true");
|
||||
DEFAULT_VALUES.put("lava-flow", "true");
|
||||
|
@ -134,7 +143,7 @@ public class Config extends Language {
|
|||
DEFAULT_VALUES.put("username-changes", "true");
|
||||
DEFAULT_VALUES.put("worldedit", "true");
|
||||
|
||||
HEADERS.put("donation-key", new String[] { "# CoreProtect is donationware. For more information, visit our project page." });
|
||||
HEADERS.put("donation-key", new String[] { "# CoreProtect is donationware. Obtain a donation key from coreprotect.net/donate/" });
|
||||
HEADERS.put("use-mysql", new String[] { "# MySQL is optional and not required.", "# If you prefer to use MySQL, enable the following and fill out the fields." });
|
||||
HEADERS.put("language", new String[] { "# If modified, will automatically attempt to translate languages phrases.", "# List of language codes: https://coreprotect.net/languages/" });
|
||||
HEADERS.put("check-updates", new String[] { "# If enabled, CoreProtect will check for updates when your server starts up.", "# If an update is available, you'll be notified via your server console.", });
|
||||
|
@ -158,9 +167,10 @@ public class Config extends Language {
|
|||
HEADERS.put("sign-text", new String[] { "# Logs text on signs. If disabled, signs will be blank when rolled back." });
|
||||
HEADERS.put("buckets", new String[] { "# Logs lava and water sources placed/removed by players who are using buckets." });
|
||||
HEADERS.put("leaf-decay", new String[] { "# Logs natural tree leaf decay." });
|
||||
HEADERS.put("tree-growth", new String[] { "# Logs tree growth. Trees are linked to the player who planted the sappling." });
|
||||
HEADERS.put("tree-growth", new String[] { "# Logs tree growth. Trees are linked to the player who planted the sapling." });
|
||||
HEADERS.put("mushroom-growth", new String[] { "# Logs mushroom growth." });
|
||||
HEADERS.put("vine-growth", new String[] { "# Logs natural vine growth." });
|
||||
HEADERS.put("sculk-spread", new String[] { "# Logs the spread of sculk blocks from sculk catalysts." });
|
||||
HEADERS.put("portals", new String[] { "# Logs when portals such as Nether portals generate naturally." });
|
||||
HEADERS.put("water-flow", new String[] { "# Logs water flow. If water destroys other blocks, such as torches,", "# this allows it to be properly rolled back." });
|
||||
HEADERS.put("lava-flow", new String[] { "# Logs lava flow. If lava destroys other blocks, such as torches,", "# this allows it to be properly rolled back." });
|
||||
|
@ -178,9 +188,16 @@ public class Config extends Language {
|
|||
}
|
||||
|
||||
private void readValues() {
|
||||
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);
|
||||
this.LOG_CANCELLED_CHAT = this.getBoolean("log-cancelled-chat", true);
|
||||
this.HOPPER_FILTER_META = this.getBoolean("hopper-filter-meta", false);
|
||||
this.EXCLUDE_TNT = this.getBoolean("exclude-tnt", false);
|
||||
this.NETWORK_DEBUG = this.getBoolean("network-debug", false);
|
||||
this.UNKNOWN_LOGGING = this.getBoolean("unknown-logging", false);
|
||||
this.MAXIMUM_POOL_SIZE = this.getInt("maximum-pool-size", 10);
|
||||
this.DONATION_KEY = this.getString("donation-key");
|
||||
this.MYSQL = this.getBoolean("use-mysql");
|
||||
this.PREFIX = this.getString("table-prefix");
|
||||
|
@ -214,6 +231,7 @@ public class Config extends Language {
|
|||
this.TREE_GROWTH = this.getBoolean("tree-growth");
|
||||
this.MUSHROOM_GROWTH = this.getBoolean("mushroom-growth");
|
||||
this.VINE_GROWTH = this.getBoolean("vine-growth");
|
||||
this.SCULK_SPREAD = this.getBoolean("sculk-spread");
|
||||
this.PORTALS = this.getBoolean("portals");
|
||||
this.WATER_FLOW = this.getBoolean("water-flow");
|
||||
this.LAVA_FLOW = this.getBoolean("lava-flow");
|
||||
|
@ -241,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;
|
||||
}
|
||||
|
@ -296,7 +318,7 @@ public class Config extends Language {
|
|||
|
||||
configured = configured.replaceAll("[^0-9]", "");
|
||||
|
||||
return configured.isEmpty() ? 0 : Integer.parseInt(configured);
|
||||
return configured.isEmpty() ? dfl : Integer.parseInt(configured);
|
||||
}
|
||||
|
||||
private String getString(final String key) {
|
||||
|
@ -369,7 +391,7 @@ public class Config extends Language {
|
|||
// for now this solution is good enough to ensure we only modify on the main thread
|
||||
final CompletableFuture<Void> complete = new CompletableFuture<>();
|
||||
|
||||
Bukkit.getScheduler().runTask(CoreProtect.getInstance(), () -> {
|
||||
Scheduler.runTask(CoreProtect.getInstance(), () -> {
|
||||
try {
|
||||
parseConfig(data);
|
||||
}
|
||||
|
@ -388,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");
|
||||
|
|
|
@ -14,6 +14,7 @@ import java.nio.file.Files;
|
|||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
@ -181,7 +182,7 @@ public class ConfigFile extends Config {
|
|||
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
if (lines.get(i).equalsIgnoreCase(oldLine)) {
|
||||
if (newLine.length() > 0) {
|
||||
if (newLine != null && newLine.length() > 0) {
|
||||
lines.set(i, newLine);
|
||||
}
|
||||
else {
|
||||
|
@ -204,6 +205,27 @@ public class ConfigFile extends Config {
|
|||
}
|
||||
}
|
||||
|
||||
public static void sortFile(String fileName) {
|
||||
try {
|
||||
Path path = Paths.get(ConfigHandler.path + fileName);
|
||||
List<String> lines = Files.readAllLines(path);
|
||||
List<String> sort = lines.subList(2, lines.size());
|
||||
Collections.sort(sort);
|
||||
lines = lines.subList(0, 2);
|
||||
lines.addAll(sort);
|
||||
|
||||
if (lines.size() > 0) {
|
||||
String lastLine = lines.get(lines.size() - 1); // append the final line to prevent a line separator from being added
|
||||
Files.write(path, (lines.remove(lines.size() - 1).isEmpty() ? lines : lines), StandardCharsets.UTF_8);
|
||||
Files.write(path, lastLine.getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
|
||||
lines.clear();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void resetCache(String cacheName, String fileName) throws IOException {
|
||||
File file = new File(CoreProtect.getInstance().getDataFolder(), cacheName);
|
||||
if (file.length() > 0) {
|
||||
|
|
|
@ -11,11 +11,8 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -23,12 +20,15 @@ import org.bukkit.inventory.ItemStack;
|
|||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
|
||||
import net.coreprotect.bukkit.BukkitAdapter;
|
||||
import net.coreprotect.consumer.Consumer;
|
||||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.database.Database;
|
||||
import net.coreprotect.database.statement.UserStatement;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.listener.ListenerHandler;
|
||||
import net.coreprotect.model.BlockGroup;
|
||||
import net.coreprotect.paper.PaperAdapter;
|
||||
import net.coreprotect.patch.Patch;
|
||||
|
@ -42,8 +42,8 @@ public class ConfigHandler extends Queue {
|
|||
public static final int EDITION_VERSION = 2;
|
||||
public static final String EDITION_BRANCH = Util.getBranch();
|
||||
public static final String EDITION_NAME = Util.getPluginName();
|
||||
public static final String JAVA_VERSION = "1.8";
|
||||
public static final String SPIGOT_VERSION = "1.14";
|
||||
public static final String JAVA_VERSION = "11.0";
|
||||
public static final String SPIGOT_VERSION = "1.15";
|
||||
public static String path = "plugins/CoreProtect/";
|
||||
public static String sqlite = "database.db";
|
||||
public static String host = "127.0.0.1";
|
||||
|
@ -52,12 +52,16 @@ public class ConfigHandler extends Queue {
|
|||
public static String username = "root";
|
||||
public static String password = "";
|
||||
public static String prefix = "co_";
|
||||
public static int maximumPoolSize = 10;
|
||||
|
||||
public static HikariDataSource hikariDataSource = null;
|
||||
public static final boolean isSpigot = Util.isSpigot();
|
||||
public static final boolean isPaper = Util.isPaper();
|
||||
public static final boolean isFolia = Util.isFolia();
|
||||
public static volatile boolean serverRunning = false;
|
||||
public static volatile boolean converterRunning = false;
|
||||
public static volatile boolean purgeRunning = false;
|
||||
public static volatile boolean pauseConsumer = false;
|
||||
public static volatile boolean worldeditEnabled = false;
|
||||
public static volatile boolean databaseReachable = true;
|
||||
public static volatile int worldId = 0;
|
||||
|
@ -87,9 +91,17 @@ public class ConfigHandler extends Queue {
|
|||
public static Map<String, Integer> loggingItem = syncMap();
|
||||
public static ConcurrentHashMap<String, List<Object>> transactingChest = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack[]>> oldContainer = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsDrop = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsPickup = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsDrop = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsThrown = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsShot = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsBreak = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsDestroy = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsCreate = new ConcurrentHashMap<>();
|
||||
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();
|
||||
|
@ -97,20 +109,21 @@ public class ConfigHandler extends Queue {
|
|||
public static Map<String, Integer> lookupPage = syncMap();
|
||||
public static Map<String, String> lookupCommand = syncMap();
|
||||
public static Map<String, List<Object>> lookupBlist = syncMap();
|
||||
public static Map<String, List<Object>> lookupElist = syncMap();
|
||||
public static Map<String, Map<Object, Boolean>> lookupElist = syncMap();
|
||||
public static Map<String, List<String>> lookupEUserlist = syncMap();
|
||||
public static Map<String, List<String>> lookupUlist = syncMap();
|
||||
public static Map<String, List<Integer>> lookupAlist = syncMap();
|
||||
public static Map<String, Integer[]> lookupRadius = syncMap();
|
||||
public static Map<String, String> lookupTime = syncMap();
|
||||
public static Map<String, Integer> lookupRows = syncMap();
|
||||
public static Map<String, Long[]> lookupRows = syncMap();
|
||||
public static Map<String, String> uuidCache = syncMap();
|
||||
public static Map<String, String> uuidCacheReversed = syncMap();
|
||||
public static Map<String, Integer> playerIdCache = syncMap();
|
||||
public static Map<Integer, String> playerIdCacheReversed = syncMap();
|
||||
public static Map<String, List<Object>> lastRollback = syncMap();
|
||||
public static Map<String, Boolean> activeRollbacks = syncMap();
|
||||
public static Map<UUID, Object[]> entityBlockMapper = syncMap();
|
||||
public static Map<String, Object[]> entityBlockMapper = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<Long, Long> populatedChunks = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, String> language = new ConcurrentHashMap<>();
|
||||
public static List<String> databaseTables = new ArrayList<>();
|
||||
|
||||
|
@ -164,6 +177,7 @@ public class ConfigHandler extends Queue {
|
|||
ConfigHandler.database = Config.getGlobal().MYSQL_DATABASE;
|
||||
ConfigHandler.username = Config.getGlobal().MYSQL_USERNAME;
|
||||
ConfigHandler.password = Config.getGlobal().MYSQL_PASSWORD;
|
||||
ConfigHandler.maximumPoolSize = Config.getGlobal().MAXIMUM_POOL_SIZE;
|
||||
ConfigHandler.prefix = Config.getGlobal().PREFIX;
|
||||
|
||||
ConfigHandler.loadBlacklist(); // Load the blacklist file if it exists.
|
||||
|
@ -175,10 +189,7 @@ public class ConfigHandler extends Queue {
|
|||
|
||||
public static void loadDatabase() {
|
||||
// close old pool when we reload the database, e.g. in purge command
|
||||
if (ConfigHandler.hikariDataSource != null) {
|
||||
ConfigHandler.hikariDataSource.close();
|
||||
ConfigHandler.hikariDataSource = null;
|
||||
}
|
||||
Database.closeConnection();
|
||||
|
||||
if (!Config.getGlobal().MYSQL) {
|
||||
try {
|
||||
|
@ -203,15 +214,28 @@ public class ConfigHandler extends Queue {
|
|||
}
|
||||
|
||||
tempFile.delete();
|
||||
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
HikariConfig config = new HikariConfig();
|
||||
try {
|
||||
Class.forName("com.mysql.cj.jdbc.Driver");
|
||||
config.setDriverClassName("com.mysql.cj.jdbc.Driver");
|
||||
}
|
||||
catch (Exception e) {
|
||||
config.setDriverClassName("com.mysql.jdbc.Driver");
|
||||
}
|
||||
|
||||
config.setJdbcUrl("jdbc:mysql://" + ConfigHandler.host + ":" + ConfigHandler.port + "/" + ConfigHandler.database);
|
||||
config.setUsername(ConfigHandler.username);
|
||||
config.setPassword(ConfigHandler.password);
|
||||
config.setMaximumPoolSize(ConfigHandler.maximumPoolSize);
|
||||
config.setMaxLifetime(60000);
|
||||
config.addDataSourceProperty("characterEncoding", "UTF-8");
|
||||
config.addDataSourceProperty("connectionTimeout", "10000");
|
||||
/* https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration */
|
||||
|
@ -225,7 +249,8 @@ public class ConfigHandler extends Queue {
|
|||
config.addDataSourceProperty("cacheServerConfiguration", "true");
|
||||
config.addDataSourceProperty("maintainTimeStats", "false");
|
||||
/* Disable SSL to suppress the unverified server identity warning */
|
||||
config.addDataSourceProperty("useSSL", "false");
|
||||
config.addDataSourceProperty("allowPublicKeyRetrieval", "true");
|
||||
config.addDataSourceProperty("useSSL", Config.getGlobal().ENABLE_SSL);
|
||||
|
||||
ConfigHandler.hikariDataSource = new HikariDataSource(config);
|
||||
}
|
||||
|
@ -395,7 +420,11 @@ public class ConfigHandler extends Queue {
|
|||
ConfigHandler.loadConfig(); // Load (or create) the configuration file.
|
||||
ConfigHandler.loadDatabase(); // Initialize MySQL and create tables if necessary.
|
||||
|
||||
} catch (Exception e) {
|
||||
if (startup) {
|
||||
ListenerHandler.registerNetworking(); // Register channels for networking API
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
@ -437,4 +466,14 @@ public class ConfigHandler extends Queue {
|
|||
return false;
|
||||
}
|
||||
|
||||
public static void performDisable() {
|
||||
try {
|
||||
Database.closeConnection();
|
||||
ListenerHandler.unregisterNetworking(); // Unregister channels for networking API
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ public class Consumer extends Process implements Runnable, Thread.UncaughtExcept
|
|||
|
||||
private static void pauseConsumer(int process_id) {
|
||||
try {
|
||||
while ((ConfigHandler.serverRunning || ConfigHandler.converterRunning) && (Consumer.isPaused || ConfigHandler.purgeRunning || Consumer.consumer_id.get(process_id)[1] == 1)) {
|
||||
while ((ConfigHandler.serverRunning || ConfigHandler.converterRunning) && (Consumer.isPaused || ConfigHandler.pauseConsumer || ConfigHandler.purgeRunning || Consumer.consumer_id.get(process_id)[1] == 1)) {
|
||||
pausedSuccess = true;
|
||||
Thread.sleep(100);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ import org.bukkit.block.BlockState;
|
|||
import org.bukkit.block.CreatureSpawner;
|
||||
import org.bukkit.block.data.Bisected;
|
||||
import org.bukkit.block.data.Bisected.Half;
|
||||
import org.bukkit.block.data.type.Bed;
|
||||
import org.bukkit.block.data.type.Bed.Part;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
@ -21,6 +23,8 @@ import net.coreprotect.config.Config;
|
|||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.consumer.process.Process;
|
||||
import net.coreprotect.listener.block.BlockUtil;
|
||||
import net.coreprotect.model.BlockGroup;
|
||||
import net.coreprotect.thread.Scheduler;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class Queue {
|
||||
|
@ -57,7 +61,7 @@ public class Queue {
|
|||
Consumer.consumer.get(currentConsumer).add(data);
|
||||
}
|
||||
|
||||
private static void queueStandardData(int consumerId, int currentConsumer, String[] user, Object object) {
|
||||
private static synchronized void queueStandardData(int consumerId, int currentConsumer, String[] user, Object object) {
|
||||
Consumer.consumerUsers.get(currentConsumer).put(consumerId, user);
|
||||
Consumer.consumerObjects.get(currentConsumer).put(consumerId, object);
|
||||
Consumer.consumer_id.put(currentConsumer, new Integer[] { Consumer.consumer_id.get(currentConsumer)[0], 0 });
|
||||
|
@ -82,7 +86,7 @@ public class Queue {
|
|||
}
|
||||
|
||||
protected static void queueBlockBreakValidate(final String user, final Block block, final BlockState blockState, final Material type, final String blockData, final int extraData, int ticks) {
|
||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> {
|
||||
Scheduler.scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> {
|
||||
try {
|
||||
if (!block.getType().equals(type)) {
|
||||
queueBlockBreak(user, blockState, type, blockData, null, extraData, 0);
|
||||
|
@ -91,7 +95,7 @@ public class Queue {
|
|||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, ticks);
|
||||
}, block.getLocation(), ticks);
|
||||
}
|
||||
|
||||
protected static void queueBlockBreak(String user, BlockState block, Material type, String blockData, Material breakType, int extraData, int blockNumber) {
|
||||
|
@ -99,19 +103,29 @@ public class Queue {
|
|||
CreatureSpawner mobSpawner = (CreatureSpawner) block;
|
||||
extraData = Util.getSpawnerType(mobSpawner.getSpawnedType());
|
||||
}
|
||||
else if (type.equals(Material.SUNFLOWER) || type.equals(Material.LILAC) || type.equals(Material.TALL_GRASS) || type.equals(Material.LARGE_FERN) || type.equals(Material.ROSE_BUSH) || type.equals(Material.PEONY)) { // Double plant
|
||||
else if (type == Material.IRON_DOOR || BlockGroup.DOORS.contains(type) || type.equals(Material.SUNFLOWER) || type.equals(Material.LILAC) || type.equals(Material.TALL_GRASS) || type.equals(Material.LARGE_FERN) || type.equals(Material.ROSE_BUSH) || type.equals(Material.PEONY)) { // Double plant
|
||||
if (block.getBlockData() instanceof Bisected) {
|
||||
if (((Bisected) block.getBlockData()).getHalf().equals(Half.TOP) && !user.startsWith("#")) {
|
||||
if (((Bisected) block.getBlockData()).getHalf().equals(Half.TOP)) {
|
||||
if (blockNumber == 5) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (block.getY() > BukkitAdapter.ADAPTER.getMinHeight(block.getWorld())) {
|
||||
block = block.getWorld().getBlockAt(block.getX(), block.getY() - 1, block.getZ()).getState();
|
||||
if (type != block.getType()) {
|
||||
return;
|
||||
}
|
||||
|
||||
blockData = block.getBlockData().getAsString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type.name().endsWith("_BED") && block.getBlockData() instanceof Bed) {
|
||||
if (((Bed) block.getBlockData()).getPart().equals(Part.HEAD)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int currentConsumer = Consumer.currentConsumer;
|
||||
int consumerId = Consumer.newConsumerId(currentConsumer);
|
||||
|
@ -136,7 +150,7 @@ public class Queue {
|
|||
replaceType = blockReplaced.getType();
|
||||
replaceData = 0;
|
||||
|
||||
if ((replaceType.equals(Material.SUNFLOWER) || replaceType.equals(Material.LILAC) || replaceType.equals(Material.TALL_GRASS) || replaceType.equals(Material.LARGE_FERN) || replaceType.equals(Material.ROSE_BUSH) || replaceType.equals(Material.PEONY)) && replaceData >= 8) { // Double plant top half
|
||||
if ((replaceType == Material.IRON_DOOR || BlockGroup.DOORS.contains(replaceType) || replaceType.equals(Material.SUNFLOWER) || replaceType.equals(Material.LILAC) || replaceType.equals(Material.TALL_GRASS) || replaceType.equals(Material.LARGE_FERN) || replaceType.equals(Material.ROSE_BUSH) || replaceType.equals(Material.PEONY)) && replaceData >= 8) { // Double plant top half
|
||||
BlockState blockBelow = blockReplaced.getWorld().getBlockAt(blockReplaced.getX(), blockReplaced.getY() - 1, blockReplaced.getZ()).getState();
|
||||
Material belowType = blockBelow.getType();
|
||||
Queue.queueBlockBreak(user, blockBelow, belowType, blockBelow.getBlockData().getAsString(), 0);
|
||||
|
@ -165,18 +179,18 @@ public class Queue {
|
|||
}
|
||||
|
||||
protected static void queueBlockPlaceDelayed(final String user, final Location placed, final Material type, final String blockData, final BlockState replaced, int ticks) {
|
||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> {
|
||||
Scheduler.scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> {
|
||||
try {
|
||||
queueBlockPlace(user, placed.getBlock().getState(), type, replaced, null, -1, 0, blockData);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, ticks);
|
||||
}, placed, ticks);
|
||||
}
|
||||
|
||||
protected static void queueBlockPlaceValidate(final String user, final BlockState blockLocation, final Block block, final BlockState blockReplaced, final Material forceT, final int forceD, final int forceData, final String blockData, int ticks) {
|
||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> {
|
||||
Scheduler.scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> {
|
||||
try {
|
||||
Material blockType = block.getType();
|
||||
if (blockType.equals(forceT)) {
|
||||
|
@ -191,11 +205,11 @@ public class Queue {
|
|||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, ticks);
|
||||
}, blockLocation.getLocation(), ticks);
|
||||
}
|
||||
|
||||
protected static void queueBlockGravityValidate(final String user, final Location location, final Block block, final Material blockType, int ticks) {
|
||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> {
|
||||
Scheduler.scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> {
|
||||
try {
|
||||
Block placementBlock = BlockUtil.gravityScan(location, blockType, user);
|
||||
if (!block.equals(placementBlock)) {
|
||||
|
@ -205,7 +219,7 @@ public class Queue {
|
|||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, ticks);
|
||||
}, location, ticks);
|
||||
}
|
||||
|
||||
protected static void queueContainerBreak(String user, Location location, Material type, ItemStack[] oldInventory) {
|
||||
|
@ -216,18 +230,6 @@ public class Queue {
|
|||
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, location);
|
||||
}
|
||||
|
||||
protected static void queueContainerRollbackUpdate(String user, Location location, List<Object[]> list, int action) {
|
||||
if (location == null) {
|
||||
location = new Location(Bukkit.getServer().getWorlds().get(0), 0, 0, 0);
|
||||
}
|
||||
|
||||
int currentConsumer = Consumer.currentConsumer;
|
||||
int consumerId = Consumer.newConsumerId(currentConsumer);
|
||||
addConsumer(currentConsumer, new Object[] { consumerId, Process.CONTAINER_ROLLBACK_UPDATE, null, 0, null, 0, action, null });
|
||||
Consumer.consumerObjectArrayList.get(currentConsumer).put(consumerId, list);
|
||||
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, location);
|
||||
}
|
||||
|
||||
protected static synchronized void queueContainerTransaction(String user, Location location, Material type, Object inventory, int chestId) {
|
||||
int currentConsumer = Consumer.currentConsumer;
|
||||
int consumerId = Consumer.newConsumerId(currentConsumer);
|
||||
|
@ -236,10 +238,10 @@ public class Queue {
|
|||
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, location);
|
||||
}
|
||||
|
||||
protected static void queueItemTransaction(String user, Location location, int time, int itemId) {
|
||||
protected static void queueItemTransaction(String user, Location location, int time, int offset, int itemId) {
|
||||
int currentConsumer = Consumer.currentConsumer;
|
||||
int consumerId = Consumer.newConsumerId(currentConsumer);
|
||||
addConsumer(currentConsumer, new Object[] { consumerId, Process.ITEM_TRANSACTION, null, 0, null, time, itemId, null });
|
||||
addConsumer(currentConsumer, new Object[] { consumerId, Process.ITEM_TRANSACTION, null, offset, null, time, itemId, null });
|
||||
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, location);
|
||||
}
|
||||
|
||||
|
@ -265,20 +267,6 @@ public class Queue {
|
|||
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, new Object[] { block, type });
|
||||
}
|
||||
|
||||
protected static void queueHangingRemove(String user, BlockState block, int delay) {
|
||||
int currentConsumer = Consumer.currentConsumer;
|
||||
int consumerId = Consumer.newConsumerId(currentConsumer);
|
||||
addConsumer(currentConsumer, new Object[] { consumerId, Process.HANGING_REMOVE, null, 0, null, 0, delay, null });
|
||||
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, block);
|
||||
}
|
||||
|
||||
protected static void queueHangingSpawn(String user, BlockState block, Material type, int data, int delay) {
|
||||
int currentConsumer = Consumer.currentConsumer;
|
||||
int consumerId = Consumer.newConsumerId(currentConsumer);
|
||||
addConsumer(currentConsumer, new Object[] { consumerId, Process.HANGING_SPAWN, type, data, null, 0, delay, null });
|
||||
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, block);
|
||||
}
|
||||
|
||||
protected static void queueMaterialInsert(int id, String name) {
|
||||
int currentConsumer = Consumer.currentConsumer;
|
||||
int consumerId = Consumer.newConsumerId(currentConsumer);
|
||||
|
@ -293,7 +281,7 @@ public class Queue {
|
|||
queueStandardData(consumerId, currentConsumer, new String[] { null, null }, data);
|
||||
}
|
||||
|
||||
protected static void queueNaturalBlockBreak(String user, BlockState block, Block relative, Material type, int data) {
|
||||
protected static void queueNaturalBlockBreak(String user, BlockState block, Block relative, Material type, String blockData, int data) {
|
||||
List<BlockState> blockStates = new ArrayList<>();
|
||||
if (relative != null) {
|
||||
blockStates.add(relative.getState());
|
||||
|
@ -301,7 +289,7 @@ public class Queue {
|
|||
|
||||
int currentConsumer = Consumer.currentConsumer;
|
||||
int consumerId = Consumer.newConsumerId(currentConsumer);
|
||||
addConsumer(currentConsumer, new Object[] { consumerId, Process.NATURAL_BLOCK_BREAK, type, data, null, 0, 0, null });
|
||||
addConsumer(currentConsumer, new Object[] { consumerId, Process.NATURAL_BLOCK_BREAK, type, data, null, 0, 0, blockData });
|
||||
Consumer.consumerBlockList.get(currentConsumer).put(consumerId, blockStates);
|
||||
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, block);
|
||||
}
|
||||
|
@ -322,10 +310,10 @@ public class Queue {
|
|||
queueStandardData(consumerId, currentConsumer, new String[] { player.getName(), null }, new Object[] { timestamp, player.getLocation().clone() });
|
||||
}
|
||||
|
||||
protected static void queuePlayerInteraction(String user, BlockState block) {
|
||||
protected static void queuePlayerInteraction(String user, BlockState block, Material type) {
|
||||
int currentConsumer = Consumer.currentConsumer;
|
||||
int consumerId = Consumer.newConsumerId(currentConsumer);
|
||||
addConsumer(currentConsumer, new Object[] { consumerId, Process.PLAYER_INTERACTION, null, 0, null, 0, 0, null });
|
||||
addConsumer(currentConsumer, new Object[] { consumerId, Process.PLAYER_INTERACTION, type, 0, null, 0, 0, null });
|
||||
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, block);
|
||||
}
|
||||
|
||||
|
@ -352,18 +340,19 @@ public class Queue {
|
|||
queueStandardData(consumerId, currentConsumer, new String[] { player.getName(), null }, player.getLocation().clone());
|
||||
}
|
||||
|
||||
protected static void queueRollbackUpdate(String user, Location location, List<Object[]> list, int action) {
|
||||
protected static void queueRollbackUpdate(String user, Location location, List<Object[]> list, int table, int action) {
|
||||
if (location == null) {
|
||||
location = new Location(Bukkit.getServer().getWorlds().get(0), 0, 0, 0);
|
||||
}
|
||||
|
||||
int currentConsumer = Consumer.currentConsumer;
|
||||
int consumerId = Consumer.newConsumerId(currentConsumer);
|
||||
addConsumer(currentConsumer, new Object[] { consumerId, Process.ROLLBACK_UPDATE, null, 0, null, 0, action, null });
|
||||
addConsumer(currentConsumer, new Object[] { consumerId, table, null, 0, null, 0, action, null });
|
||||
Consumer.consumerObjectArrayList.get(currentConsumer).put(consumerId, list);
|
||||
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, location);
|
||||
}
|
||||
|
||||
protected static void queueSignText(String user, Location location, int action, int color, boolean glowing, String line1, String line2, String line3, String line4, int offset) {
|
||||
protected static void queueSignText(String user, Location location, int action, int color, int colorSecondary, boolean frontGlowing, boolean backGlowing, boolean isWaxed, boolean isFront, String line1, String line2, String line3, String line4, String line5, String line6, String line7, String line8, int offset) {
|
||||
/*
|
||||
if (line1.length() == 0 && line2.length() == 0 && line3.length() == 0 && line4.length() == 0) {
|
||||
return;
|
||||
|
@ -372,7 +361,7 @@ public class Queue {
|
|||
int currentConsumer = Consumer.currentConsumer;
|
||||
int consumerId = Consumer.newConsumerId(currentConsumer);
|
||||
addConsumer(currentConsumer, new Object[] { consumerId, Process.SIGN_TEXT, null, color, null, action, offset, null });
|
||||
Consumer.consumerSigns.get(currentConsumer).put(consumerId, new Object[] { (glowing == true ? 1 : 0), line1, line2, line3, line4 });
|
||||
Consumer.consumerSigns.get(currentConsumer).put(consumerId, new Object[] { colorSecondary, Util.getSignData(frontGlowing, backGlowing), isWaxed, isFront, line1, line2, line3, line4, line5, line6, line7, line8 });
|
||||
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, location);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,16 +3,12 @@ package net.coreprotect.consumer.process;
|
|||
import java.sql.PreparedStatement;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Skull;
|
||||
import org.bukkit.block.data.Bisected;
|
||||
import org.bukkit.block.data.type.Door;
|
||||
|
||||
import net.coreprotect.database.logger.BlockBreakLogger;
|
||||
import net.coreprotect.database.logger.SkullBreakLogger;
|
||||
import net.coreprotect.model.BlockGroup;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
class BlockBreakProcess {
|
||||
|
@ -25,17 +21,7 @@ class BlockBreakProcess {
|
|||
SkullBreakLogger.log(preparedStmt, preparedStmtSkulls, batchCount, user, block);
|
||||
}
|
||||
else {
|
||||
BlockBreakLogger.log(preparedStmt, batchCount, user, block.getLocation(), Util.getBlockId(blockType), blockDataId, meta, block.getBlockData().getAsString());
|
||||
if (forceData == 5) { // Fix for doors
|
||||
if ((blockType == Material.IRON_DOOR || BlockGroup.DOORS.contains(blockType)) && (replaceType != Material.IRON_DOOR && !BlockGroup.DOORS.contains(replaceType))) {
|
||||
Door door = (Door) block.getBlockData();
|
||||
door.setHalf(Bisected.Half.TOP);
|
||||
blockData = door.getAsString();
|
||||
Location location = block.getLocation();
|
||||
location.setY(location.getY() + 1);
|
||||
BlockBreakLogger.log(preparedStmt, batchCount, user, location, Util.getBlockId(blockType), 0, null, blockData);
|
||||
}
|
||||
}
|
||||
BlockBreakLogger.log(preparedStmt, batchCount, user, block.getLocation(), Util.getBlockId(blockType), blockDataId, meta, block.getBlockData().getAsString(), blockData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import org.bukkit.entity.EntityType;
|
|||
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.statement.EntityStatement;
|
||||
import net.coreprotect.utility.Util;
|
||||
import net.coreprotect.utility.entity.EntityUtil;
|
||||
|
||||
class EntitySpawnProcess {
|
||||
|
||||
|
@ -18,7 +18,7 @@ class EntitySpawnProcess {
|
|||
EntityType type = (EntityType) ((Object[]) object)[1];
|
||||
String query = "SELECT data FROM " + ConfigHandler.prefix + "entity WHERE rowid='" + rowId + "' LIMIT 0, 1";
|
||||
List<Object> data = EntityStatement.getData(statement, block, query);
|
||||
Util.spawnEntity(block, type, data);
|
||||
EntityUtil.spawnEntity(block, type, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
package net.coreprotect.consumer.process;
|
||||
|
||||
import org.bukkit.block.BlockState;
|
||||
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
class HangingRemoveProcess {
|
||||
|
||||
static void process(Object object, int delay) {
|
||||
if (object instanceof BlockState) {
|
||||
BlockState block = (BlockState) object;
|
||||
Util.removeHanging(block, delay);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package net.coreprotect.consumer.process;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
class HangingSpawnProcess {
|
||||
|
||||
static void process(Object object, Material type, int data, int delay) {
|
||||
if (object instanceof BlockState) {
|
||||
BlockState block = (BlockState) object;
|
||||
Util.spawnHanging(block, type, data, delay);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,26 +11,33 @@ import net.coreprotect.database.logger.ItemLogger;
|
|||
|
||||
class ItemTransactionProcess extends Queue {
|
||||
|
||||
static void process(PreparedStatement preparedStmt, int batchCount, int processId, int id, int forceData, int time, String user, Object object) {
|
||||
static void process(PreparedStatement preparedStmt, int batchCount, int processId, int id, int forceData, int time, int offset, String user, Object object) {
|
||||
if (object instanceof Location) {
|
||||
Location location = (Location) object;
|
||||
String loggingItemId = user.toLowerCase(Locale.ROOT) + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
|
||||
|
||||
if (ConfigHandler.loggingItem.get(loggingItemId) != null) {
|
||||
int current_chest = ConfigHandler.loggingItem.get(loggingItemId);
|
||||
if (ConfigHandler.itemsDrop.get(loggingItemId) == null && ConfigHandler.itemsPickup.get(loggingItemId) == null) {
|
||||
if (ConfigHandler.itemsPickup.get(loggingItemId) == null && ConfigHandler.itemsDrop.get(loggingItemId) == null && ConfigHandler.itemsThrown.get(loggingItemId) == null && ConfigHandler.itemsShot.get(loggingItemId) == null && ConfigHandler.itemsBreak.get(loggingItemId) == null && ConfigHandler.itemsDestroy.get(loggingItemId) == null && ConfigHandler.itemsCreate.get(loggingItemId) == null && ConfigHandler.itemsSell.get(loggingItemId) == null && ConfigHandler.itemsBuy.get(loggingItemId) == null) {
|
||||
return;
|
||||
}
|
||||
if (current_chest == forceData) {
|
||||
int currentTime = (int) (System.currentTimeMillis() / 1000L);
|
||||
if (currentTime > time) {
|
||||
ItemLogger.log(preparedStmt, batchCount, location, user);
|
||||
ConfigHandler.itemsDrop.remove(loggingItemId);
|
||||
ItemLogger.log(preparedStmt, batchCount, location, offset, user);
|
||||
ConfigHandler.itemsPickup.remove(loggingItemId);
|
||||
ConfigHandler.itemsDrop.remove(loggingItemId);
|
||||
ConfigHandler.itemsThrown.remove(loggingItemId);
|
||||
ConfigHandler.itemsShot.remove(loggingItemId);
|
||||
ConfigHandler.itemsBreak.remove(loggingItemId);
|
||||
ConfigHandler.itemsDestroy.remove(loggingItemId);
|
||||
ConfigHandler.itemsCreate.remove(loggingItemId);
|
||||
ConfigHandler.itemsSell.remove(loggingItemId);
|
||||
ConfigHandler.itemsBuy.remove(loggingItemId);
|
||||
ConfigHandler.loggingItem.remove(loggingItemId);
|
||||
}
|
||||
else {
|
||||
Queue.queueItemTransaction(user, location, time, forceData);
|
||||
Queue.queueItemTransaction(user, location, time, offset, forceData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import net.coreprotect.utility.Util;
|
|||
|
||||
class NaturalBlockBreakProcess {
|
||||
|
||||
static void process(Statement statement, PreparedStatement preparedStmt, int batchCount, int processId, int id, String user, Object object, Material blockType, int blockData) {
|
||||
static void process(Statement statement, PreparedStatement preparedStmt, int batchCount, int processId, int id, String user, Object object, Material blockType, int blockData, String overrideData) {
|
||||
if (object instanceof BlockState) {
|
||||
BlockState block = (BlockState) object;
|
||||
Map<Integer, List<BlockState>> blockLists = Consumer.consumerBlockList.get(processId);
|
||||
|
@ -28,7 +28,7 @@ class NaturalBlockBreakProcess {
|
|||
}
|
||||
}
|
||||
blockLists.remove(id);
|
||||
BlockBreakLogger.log(preparedStmt, batchCount, user, block.getLocation(), Util.getBlockId(blockType), blockData, null, block.getBlockData().getAsString());
|
||||
BlockBreakLogger.log(preparedStmt, batchCount, user, block.getLocation(), Util.getBlockId(blockType), blockData, null, block.getBlockData().getAsString(), overrideData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,16 +2,17 @@ package net.coreprotect.consumer.process;
|
|||
|
||||
import java.sql.PreparedStatement;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
|
||||
import net.coreprotect.database.logger.PlayerInteractLogger;
|
||||
|
||||
class PlayerInteractionProcess {
|
||||
|
||||
static void process(PreparedStatement preparedStmt, int batchCount, String user, Object object) {
|
||||
static void process(PreparedStatement preparedStmt, int batchCount, String user, Object object, Material type) {
|
||||
if (object instanceof BlockState) {
|
||||
BlockState block = (BlockState) object;
|
||||
PlayerInteractLogger.log(preparedStmt, batchCount, user, block);
|
||||
PlayerInteractLogger.log(preparedStmt, batchCount, user, block, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package net.coreprotect.consumer.process;
|
|||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
@ -36,8 +35,6 @@ public class Process {
|
|||
public static final int PLAYER_LOGOUT = 15;
|
||||
public static final int ENTITY_KILL = 16;
|
||||
public static final int ENTITY_SPAWN = 17;
|
||||
public static final int HANGING_REMOVE = 18;
|
||||
public static final int HANGING_SPAWN = 19;
|
||||
public static final int NATURAL_BLOCK_BREAK = 20;
|
||||
public static final int MATERIAL_INSERT = 21;
|
||||
public static final int ART_INSERT = 22;
|
||||
|
@ -45,6 +42,9 @@ public class Process {
|
|||
public static final int PLAYER_KILL = 24;
|
||||
public static final int BLOCKDATA_INSERT = 25;
|
||||
public static final int ITEM_TRANSACTION = 26;
|
||||
public static final int INVENTORY_ROLLBACK_UPDATE = 27;
|
||||
public static final int INVENTORY_CONTAINER_ROLLBACK_UPDATE = 28;
|
||||
public static final int BLOCK_INVENTORY_ROLLBACK_UPDATE = 29;
|
||||
|
||||
public static int lastLockUpdate = 0;
|
||||
private static volatile int currentConsumerSize = 0;
|
||||
|
@ -73,14 +73,24 @@ public class Process {
|
|||
return;
|
||||
}
|
||||
|
||||
Consumer.isPaused = true;
|
||||
Statement statement = connection.createStatement();
|
||||
Database.performCheckpoint(statement);
|
||||
|
||||
Consumer.isPaused = true;
|
||||
ArrayList<Object[]> consumerData = Consumer.consumer.get(processId);
|
||||
Map<Integer, String[]> users = Consumer.consumerUsers.get(processId);
|
||||
Map<Integer, Object> consumerObject = Consumer.consumerObjects.get(processId);
|
||||
int consumerDataSize = consumerData.size();
|
||||
currentConsumerSize = consumerDataSize;
|
||||
|
||||
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()) {
|
||||
|
@ -144,13 +154,13 @@ public class Process {
|
|||
ContainerBreakProcess.process(preparedStmtContainers, i, processId, id, blockType, user, object);
|
||||
break;
|
||||
case Process.PLAYER_INTERACTION:
|
||||
PlayerInteractionProcess.process(preparedStmtBlocks, i, user, object);
|
||||
PlayerInteractionProcess.process(preparedStmtBlocks, i, user, object, blockType);
|
||||
break;
|
||||
case Process.CONTAINER_TRANSACTION:
|
||||
ContainerTransactionProcess.process(preparedStmtContainers, preparedStmtItems, i, processId, id, blockType, forceData, user, object);
|
||||
break;
|
||||
case Process.ITEM_TRANSACTION:
|
||||
ItemTransactionProcess.process(preparedStmtItems, i, processId, id, forceData, replaceData, user, object);
|
||||
ItemTransactionProcess.process(preparedStmtItems, i, processId, id, forceData, replaceData, blockData, user, object);
|
||||
break;
|
||||
case Process.STRUCTURE_GROWTH:
|
||||
StructureGrowthProcess.process(statement, preparedStmtBlocks, i, processId, id, user, object, forceData);
|
||||
|
@ -161,6 +171,15 @@ public class Process {
|
|||
case Process.CONTAINER_ROLLBACK_UPDATE:
|
||||
RollbackUpdateProcess.process(statement, processId, id, forceData, 1);
|
||||
break;
|
||||
case Process.INVENTORY_ROLLBACK_UPDATE:
|
||||
RollbackUpdateProcess.process(statement, processId, id, forceData, 2);
|
||||
break;
|
||||
case Process.INVENTORY_CONTAINER_ROLLBACK_UPDATE:
|
||||
RollbackUpdateProcess.process(statement, processId, id, forceData, 3);
|
||||
break;
|
||||
case Process.BLOCK_INVENTORY_ROLLBACK_UPDATE:
|
||||
RollbackUpdateProcess.process(statement, processId, id, forceData, 4);
|
||||
break;
|
||||
case Process.WORLD_INSERT:
|
||||
WorldInsertProcess.process(preparedStmtWorlds, i, statement, object, forceData);
|
||||
break;
|
||||
|
@ -188,14 +207,8 @@ public class Process {
|
|||
case Process.ENTITY_SPAWN:
|
||||
EntitySpawnProcess.process(statement, object, forceData);
|
||||
break;
|
||||
case Process.HANGING_REMOVE:
|
||||
HangingRemoveProcess.process(object, forceData);
|
||||
break;
|
||||
case Process.HANGING_SPAWN:
|
||||
HangingSpawnProcess.process(object, blockType, blockData, forceData);
|
||||
break;
|
||||
case Process.NATURAL_BLOCK_BREAK:
|
||||
NaturalBlockBreakProcess.process(statement, preparedStmtBlocks, i, processId, id, user, object, blockType, blockData);
|
||||
NaturalBlockBreakProcess.process(statement, preparedStmtBlocks, i, processId, id, user, object, blockType, blockData, (String) data[7]);
|
||||
break;
|
||||
case Process.MATERIAL_INSERT:
|
||||
MaterialInsertProcess.process(preparedStmtMaterials, statement, i, object, forceData);
|
||||
|
@ -220,6 +233,7 @@ public class Process {
|
|||
consumerData.remove(index);
|
||||
}
|
||||
currentConsumerSize = 0;
|
||||
Consumer.consumer_id.put(processId, new Integer[] { 0, 0 });
|
||||
Consumer.isPaused = false;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.util.Map;
|
|||
|
||||
import net.coreprotect.consumer.Consumer;
|
||||
import net.coreprotect.database.Database;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
class RollbackUpdateProcess {
|
||||
|
||||
|
@ -16,8 +17,8 @@ class RollbackUpdateProcess {
|
|||
for (Object[] listRow : list) {
|
||||
long rowid = (Long) listRow[0];
|
||||
int rolledBack = (Integer) listRow[9];
|
||||
if (rolledBack == action) {
|
||||
Database.performUpdate(statement, rowid, action, table);
|
||||
if (Util.rolledBack(rolledBack, (table == 2 || table == 3 || table == 4)) == action) { // 1 = restore, 0 = rollback
|
||||
Database.performUpdate(statement, rowid, rolledBack, table);
|
||||
}
|
||||
}
|
||||
updateLists.remove(id);
|
||||
|
|
|
@ -16,7 +16,7 @@ class SignTextProcess {
|
|||
Map<Integer, Object[]> signs = Consumer.consumerSigns.get(processId);
|
||||
if (signs.get(id) != null) {
|
||||
Object[] SIGN_DATA = signs.get(id);
|
||||
SignTextLogger.log(preparedStmt, batchCount, user, location, action, color, (Integer) SIGN_DATA[0], (String) SIGN_DATA[1], (String) SIGN_DATA[2], (String) SIGN_DATA[3], (String) SIGN_DATA[4], forceData);
|
||||
SignTextLogger.log(preparedStmt, batchCount, user, location, action, color, (Integer) SIGN_DATA[0], (Integer) SIGN_DATA[1], (Boolean) SIGN_DATA[2], (Boolean) SIGN_DATA[3], (String) SIGN_DATA[4], (String) SIGN_DATA[5], (String) SIGN_DATA[6], (String) SIGN_DATA[7], (String) SIGN_DATA[8], (String) SIGN_DATA[9], (String) SIGN_DATA[10], (String) SIGN_DATA[11], forceData);
|
||||
signs.remove(id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,10 +26,10 @@ class SignUpdateProcess {
|
|||
int userid = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
|
||||
String query = "";
|
||||
if (action == 0) {
|
||||
query = "SELECT color, data, line_1, line_2, line_3, line_4 FROM " + ConfigHandler.prefix + "sign WHERE user='" + userid + "' AND wid='" + wid + "' AND x='" + x + "' AND z='" + z + "' AND y='" + y + "' AND time < '" + time + "' ORDER BY rowid DESC LIMIT 0, 1";
|
||||
query = "SELECT color, color_secondary, data, waxed, face, line_1, line_2, line_3, line_4, line_5, line_6, line_7, line_8 FROM " + ConfigHandler.prefix + "sign WHERE user='" + userid + "' AND wid='" + wid + "' AND x='" + x + "' AND z='" + z + "' AND y='" + y + "' AND time < '" + time + "' ORDER BY rowid DESC LIMIT 0, 1";
|
||||
}
|
||||
else {
|
||||
query = "SELECT color, data, line_1, line_2, line_3, line_4 FROM " + ConfigHandler.prefix + "sign WHERE user='" + userid + "' AND wid='" + wid + "' AND x='" + x + "' AND z='" + z + "' AND y='" + y + "' AND time >= '" + time + "' ORDER BY rowid ASC LIMIT 0, 1";
|
||||
query = "SELECT color, color_secondary, data, waxed, face, line_1, line_2, line_3, line_4, line_5, line_6, line_7, line_8 FROM " + ConfigHandler.prefix + "sign WHERE user='" + userid + "' AND wid='" + wid + "' AND x='" + x + "' AND z='" + z + "' AND y='" + y + "' AND time >= '" + time + "' ORDER BY rowid ASC LIMIT 0, 1";
|
||||
}
|
||||
SignStatement.getData(statement, block, query);
|
||||
Util.updateBlock(block);
|
||||
|
|
|
@ -21,14 +21,17 @@ class StructureGrowthProcess {
|
|||
Map<Integer, List<BlockState>> blockLists = Consumer.consumerBlockList.get(processId);
|
||||
if (blockLists.get(id) != null) {
|
||||
List<BlockState> blockStates = blockLists.get(id);
|
||||
String resultData = Lookup.whoPlaced(statement, block);
|
||||
String resultData = Lookup.whoPlacedCache(block);
|
||||
if (resultData.isEmpty()) {
|
||||
resultData = Lookup.whoPlaced(statement, block);
|
||||
}
|
||||
if (resultData.length() > 0) {
|
||||
user = resultData;
|
||||
}
|
||||
int count = 0;
|
||||
for (BlockState blockState : blockStates) {
|
||||
if (count < replaceBlockCount) {
|
||||
BlockBreakLogger.log(preparedStmt, batchCount, user, blockState.getLocation(), Util.getBlockId(blockState.getType()), 0, null, blockState.getBlockData().getAsString());
|
||||
BlockBreakLogger.log(preparedStmt, batchCount, user, blockState.getLocation(), Util.getBlockId(blockState.getType()), 0, null, blockState.getBlockData().getAsString(), null);
|
||||
}
|
||||
else {
|
||||
BlockPlaceLogger.log(preparedStmt, batchCount, user, blockState, 0, 0, null, -1, false, null, null, null);
|
||||
|
|
|
@ -1,34 +1,41 @@
|
|||
package net.coreprotect.database;
|
||||
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.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, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, final Location location, Integer[] radius, int checkTime, boolean restrictWorld, boolean lookup, boolean verbose, final int rollbackType) {
|
||||
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 {
|
||||
long startTime = System.currentTimeMillis();
|
||||
long timeStart = System.currentTimeMillis();
|
||||
|
||||
final List<Object[]> lookupList = Lookup.performLookupRaw(statement, user, checkUuids, checkUsers, restrictList, excludeList, excludeUserList, actionList, location, radius, checkTime, -1, -1, restrictWorld, lookup);
|
||||
final List<Object[]> lookupList = Lookup.performLookupRaw(statement, user, checkUuids, checkUsers, restrictList, excludeList, excludeUserList, actionList, location, radius, null, startTime, endTime, -1, -1, restrictWorld, lookup);
|
||||
if (rollbackType == 1) {
|
||||
Collections.reverse(lookupList);
|
||||
}
|
||||
|
@ -38,12 +45,12 @@ public class ContainerRollback extends Queue {
|
|||
userString = user.getName();
|
||||
}
|
||||
|
||||
Queue.queueContainerRollbackUpdate(userString, location, lookupList, rollbackType); // Perform update transaction in consumer
|
||||
Queue.queueRollbackUpdate(userString, location, lookupList, Process.CONTAINER_ROLLBACK_UPDATE, rollbackType); // Perform update transaction in consumer
|
||||
|
||||
final String finalUserString = userString;
|
||||
ConfigHandler.rollbackHash.put(userString, new int[] { 0, 0, 0, 0 });
|
||||
ConfigHandler.rollbackHash.put(userString, new int[] { 0, 0, 0, 0, 0 });
|
||||
|
||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(CoreProtect.getInstance(), new Runnable() {
|
||||
Scheduler.scheduleSyncDelayedTask(CoreProtect.getInstance(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
|
@ -58,17 +65,23 @@ public class ContainerRollback extends Queue {
|
|||
}
|
||||
Object container = null;
|
||||
Material type = block.getType();
|
||||
List<ItemFrame> matchingFrames = new ArrayList<>();
|
||||
|
||||
if (BlockGroup.CONTAINERS.contains(type)) {
|
||||
container = Util.getContainerInventory(block.getState(), false);
|
||||
}
|
||||
else {
|
||||
for (Entity entity : block.getChunk().getEntities()) {
|
||||
if (entity instanceof ArmorStand) {
|
||||
if (entity.getLocation().getBlockX() == location.getBlockX() && entity.getLocation().getBlockY() == location.getBlockY() && entity.getLocation().getBlockZ() == location.getBlockZ()) {
|
||||
if (entity.getLocation().getBlockX() == location.getBlockX() && entity.getLocation().getBlockY() == location.getBlockY() && entity.getLocation().getBlockZ() == location.getBlockZ()) {
|
||||
if (entity instanceof ArmorStand) {
|
||||
type = Material.ARMOR_STAND;
|
||||
container = Util.getEntityEquipment((LivingEntity) entity);
|
||||
}
|
||||
else if (entity instanceof ItemFrame) {
|
||||
type = Material.ITEM_FRAME;
|
||||
container = entity;
|
||||
matchingFrames.add((ItemFrame) entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +99,7 @@ public class ContainerRollback extends Queue {
|
|||
int rowTypeRaw = (Integer) lookupRow[6];
|
||||
int rowData = (Integer) lookupRow[7];
|
||||
int rowAction = (Integer) lookupRow[8];
|
||||
int rowRolledBack = (Integer) lookupRow[9];
|
||||
int rowRolledBack = Util.rolledBack((Integer) lookupRow[9], false);
|
||||
// int rowWid = (Integer)lookupRow[10];
|
||||
int rowAmount = (Integer) lookupRow[11];
|
||||
byte[] rowMetadata = (byte[]) lookupRow[12];
|
||||
|
@ -104,23 +117,38 @@ public class ContainerRollback extends Queue {
|
|||
action = 1;
|
||||
}
|
||||
|
||||
ItemStack itemstack = new ItemStack(rowType, rowAmount, (short) rowData);
|
||||
ItemStack itemstack = new ItemStack(rowType, rowAmount);
|
||||
Object[] populatedStack = Rollback.populateItemStack(itemstack, rowMetadata);
|
||||
int slot = (Integer) populatedStack[0];
|
||||
itemstack = (ItemStack) populatedStack[1];
|
||||
String faceData = (String) populatedStack[1];
|
||||
itemstack = (ItemStack) populatedStack[2];
|
||||
|
||||
if (type == Material.ITEM_FRAME && faceData.length() > 0) {
|
||||
BlockFace blockFace = BlockFace.valueOf(faceData);
|
||||
ItemFrame itemFrame = (ItemFrame) container;
|
||||
if (blockFace != itemFrame.getFacing()) {
|
||||
for (ItemFrame frame : matchingFrames) {
|
||||
if (blockFace == frame.getFacing()) {
|
||||
container = frame;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rollback.modifyContainerItems(type, container, slot, itemstack, action);
|
||||
}
|
||||
}
|
||||
}
|
||||
matchingFrames.clear();
|
||||
|
||||
ConfigHandler.rollbackHash.put(finalUserString, new int[] { itemCount, modifyCount, entityCount, 1 });
|
||||
ConfigHandler.rollbackHash.put(finalUserString, new int[] { itemCount, modifyCount, entityCount, 1, 1 });
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
}, location, 0);
|
||||
|
||||
int[] rollbackHashData = ConfigHandler.rollbackHash.get(finalUserString);
|
||||
int next = rollbackHashData[3];
|
||||
|
@ -139,8 +167,8 @@ public class ContainerRollback extends Queue {
|
|||
|
||||
rollbackHashData = ConfigHandler.rollbackHash.get(finalUserString);
|
||||
int blockCount = rollbackHashData[1];
|
||||
long endTime = System.currentTimeMillis();
|
||||
double totalSeconds = (endTime - startTime) / 1000.0;
|
||||
long timeFinish = System.currentTimeMillis();
|
||||
double totalSeconds = (timeFinish - timeStart) / 1000.0;
|
||||
|
||||
if (user != null) {
|
||||
int file = -1;
|
||||
|
@ -150,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) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.sql.Connection;
|
|||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -88,6 +89,12 @@ public class Database extends Queue {
|
|||
}
|
||||
}
|
||||
|
||||
public static void performCheckpoint(Statement statement) throws SQLException {
|
||||
if (!Config.getGlobal().MYSQL) {
|
||||
statement.executeUpdate("PRAGMA wal_checkpoint(TRUNCATE)");
|
||||
}
|
||||
}
|
||||
|
||||
public static void setMultiInt(PreparedStatement statement, int value, int count) {
|
||||
try {
|
||||
for (int i = 1; i <= count; i++) {
|
||||
|
@ -99,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) {
|
||||
|
@ -175,16 +186,27 @@ public class Database extends Queue {
|
|||
return connection;
|
||||
}
|
||||
|
||||
public static void performUpdate(Statement statement, long id, int action, int table) {
|
||||
public static void closeConnection() {
|
||||
try {
|
||||
int rolledBack = 1;
|
||||
if (action == 1) {
|
||||
rolledBack = 0;
|
||||
if (ConfigHandler.hikariDataSource != null) {
|
||||
ConfigHandler.hikariDataSource.close();
|
||||
ConfigHandler.hikariDataSource = null;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (table == 1) {
|
||||
public static void performUpdate(Statement statement, long id, int rb, int table) {
|
||||
try {
|
||||
int rolledBack = Util.toggleRolledBack(rb, (table == 2 || table == 3 || table == 4)); // co_item, co_container, co_block
|
||||
if (table == 1 || table == 3) {
|
||||
statement.executeUpdate("UPDATE " + ConfigHandler.prefix + "container SET rolled_back='" + rolledBack + "' WHERE rowid='" + id + "'");
|
||||
}
|
||||
else if (table == 2) {
|
||||
statement.executeUpdate("UPDATE " + ConfigHandler.prefix + "item SET rolled_back='" + rolledBack + "' WHERE rowid='" + id + "'");
|
||||
}
|
||||
else {
|
||||
statement.executeUpdate("UPDATE " + ConfigHandler.prefix + "block SET rolled_back='" + rolledBack + "' WHERE rowid='" + id + "'");
|
||||
}
|
||||
|
@ -197,11 +219,11 @@ public class Database extends Queue {
|
|||
public static PreparedStatement prepareStatement(Connection connection, int type, boolean keys) {
|
||||
PreparedStatement preparedStatement = null;
|
||||
try {
|
||||
String signInsert = "INSERT INTO " + ConfigHandler.prefix + "sign (time, user, wid, x, y, z, action, color, data, line_1, line_2, line_3, line_4) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
String signInsert = "INSERT INTO " + ConfigHandler.prefix + "sign (time, user, wid, x, y, z, action, color, color_secondary, data, waxed, face, line_1, line_2, line_3, line_4, line_5, line_6, line_7, line_8) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
String blockInsert = "INSERT INTO " + ConfigHandler.prefix + "block (time, user, wid, x, y, z, type, data, meta, blockdata, action, rolled_back) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
String skullInsert = "INSERT INTO " + ConfigHandler.prefix + "skull (time, owner) VALUES (?, ?)";
|
||||
String containerInsert = "INSERT INTO " + ConfigHandler.prefix + "container (time, user, wid, x, y, z, type, data, amount, metadata, action, rolled_back) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
String itemInsert = "INSERT INTO " + ConfigHandler.prefix + "item (time, user, wid, x, y, z, type, data, amount, action) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
String itemInsert = "INSERT INTO " + ConfigHandler.prefix + "item (time, user, wid, x, y, z, type, data, amount, action, rolled_back) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
String worldInsert = "INSERT INTO " + ConfigHandler.prefix + "world (id, world) VALUES (?, ?)";
|
||||
String chatInsert = "INSERT INTO " + ConfigHandler.prefix + "chat (time, user, wid, x, y, z, message) VALUES (?, ?, ?, ?, ?, ?, ?)";
|
||||
String commandInsert = "INSERT INTO " + ConfigHandler.prefix + "command (time, user, wid, x, y, z, message) VALUES (?, ?, ?, ?, ?, ?, ?)";
|
||||
|
@ -268,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);
|
||||
|
@ -283,6 +310,15 @@ public class Database extends Queue {
|
|||
|
||||
private static void initializeTables(String prefix, Statement statement) {
|
||||
try {
|
||||
if (!Config.getGlobal().MYSQL) {
|
||||
if (!Config.getGlobal().DISABLE_WAL) {
|
||||
statement.executeUpdate("PRAGMA journal_mode=WAL;");
|
||||
}
|
||||
else {
|
||||
statement.executeUpdate("PRAGMA journal_mode=DELETE;");
|
||||
}
|
||||
}
|
||||
|
||||
boolean lockInitialized = false;
|
||||
String query = "SELECT rowid as id FROM " + prefix + "database_lock WHERE rowid='1' LIMIT 1";
|
||||
ResultSet rs = statement.executeQuery(query);
|
||||
|
@ -313,37 +349,37 @@ public class Database extends Queue {
|
|||
String index = "";
|
||||
Statement statement = connection.createStatement();
|
||||
index = ", INDEX(id)";
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "art_map(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),id int(8),art varchar(255)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "art_map(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),id int,art varchar(255)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
index = ", INDEX(wid,x,z,time), INDEX(user,time), INDEX(type,time)";
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "block(rowid bigint(20) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int(10), user int(8), wid int(4), x int(8), y int(3), z int(8), type int(6), data int(8), meta mediumblob, blockdata blob, action int(2), rolled_back tinyint(1)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "block(rowid bigint NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int, user int, wid int, x int, y int, z int, type int, data int, meta mediumblob, blockdata blob, action tinyint, rolled_back tinyint" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
index = ", INDEX(time), INDEX(user,time), INDEX(wid,x,z,time)";
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "chat(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int(10), user int(8), wid int(4), x int(8), y int (3), z int(8), message varchar(16000)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "chat(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int, user int, wid int, x int, y int (3), z int, message varchar(16000)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
index = ", INDEX(time), INDEX(user,time), INDEX(wid,x,z,time)";
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "command(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int(10), user int(8), wid int(4), x int(8), y int (3), z int(8), message varchar(16000)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "command(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int, user int, wid int, x int, y int (3), z int, message varchar(16000)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
index = ", INDEX(wid,x,z,time), INDEX(user,time), INDEX(type,time)";
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "container(rowid int(10) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int(10), user int(8), wid int(4), x int(8), y int(3), z int(8), type int(6), data int(6), amount int(4), metadata blob, action int(2), rolled_back tinyint(1)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "container(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int, user int, wid int, x int, y int, z int, type int, data int, amount int, metadata blob, action tinyint, rolled_back tinyint" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
index = ", INDEX(wid,x,z,time), INDEX(user,time), INDEX(type,time)";
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "item(rowid int(10) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int(10), user int(8), wid int(4), x int(8), y int(3), z int(8), type int(6), data blob, amount int(4), action tinyint(1)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "database_lock(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),status tinyint(1),time int(10)) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "entity(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int(10), data blob) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "item(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int, user int, wid int, x int, y int, z int, type int, data blob, amount int, action tinyint, rolled_back tinyint" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "database_lock(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),status tinyint,time int) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "entity(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int, data blob) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
index = ", INDEX(id)";
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "entity_map(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),id int(8),entity varchar(255)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "entity_map(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),id int,entity varchar(255)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
index = ", INDEX(id)";
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "material_map(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),id int(8),material varchar(255)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "material_map(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),id int,material varchar(255)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
index = ", INDEX(id)";
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "blockdata_map(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),id int(8),data varchar(255)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "blockdata_map(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),id int,data varchar(255)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
index = ", INDEX(wid,x,z,time), INDEX(action,time), INDEX(user,time), INDEX(time)";
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "session(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int(10), user int(8), wid int(4), x int(8), y int (3), z int(8), action int(1)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
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(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int(10), user int(8), wid int(4), x int(8), y int(3), z int(8), action tinyint(1), color int(8), data tinyint(1), line_1 varchar(100), line_2 varchar(100), line_3 varchar(100), line_4 varchar(100)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "skull(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid), time int(10), owner varchar(64)) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
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(255)) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
index = ", INDEX(user), INDEX(uuid)";
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "user(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int(10),user varchar(100),uuid varchar(64)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
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)";
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "username_log(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int(10),uuid varchar(64),user varchar(100)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "version(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int(10),version varchar(16)) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "username_log(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int,uuid varchar(64),user varchar(100)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "version(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),time int,version varchar(16)) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
index = ", INDEX(id)";
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "world(rowid int(8) NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),id int(8),world varchar(255)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "world(rowid int NOT NULL AUTO_INCREMENT,PRIMARY KEY(rowid),id int,world varchar(255)" + index + ") ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4");
|
||||
if (!purge) {
|
||||
initializeTables(prefix, statement);
|
||||
}
|
||||
|
@ -402,7 +438,7 @@ public class Database extends Queue {
|
|||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "container (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, type INTEGER, data INTEGER, amount INTEGER, metadata BLOB, action INTEGER, rolled_back INTEGER);");
|
||||
}
|
||||
if (!tableData.contains(prefix + "item")) {
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "item (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, type INTEGER, data BLOB, amount INTEGER, action INTEGER);");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "item (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, type INTEGER, data BLOB, amount INTEGER, action INTEGER, rolled_back INTEGER);");
|
||||
}
|
||||
if (!tableData.contains(prefix + "database_lock")) {
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "database_lock (status INTEGER, time INTEGER);");
|
||||
|
@ -423,7 +459,7 @@ public class Database extends Queue {
|
|||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "session (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, action INTEGER);");
|
||||
}
|
||||
if (!tableData.contains(prefix + "sign")) {
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "sign (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, action INTEGER, color INTEGER, data INTEGER, line_1 TEXT, line_2 TEXT, line_3 TEXT, line_4 TEXT);");
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "sign (time INTEGER, user INTEGER, wid INTEGER, x INTEGER, y INTEGER, z INTEGER, action INTEGER, color INTEGER, color_secondary INTEGER, data INTEGER, waxed INTEGER, face INTEGER, line_1 TEXT, line_2 TEXT, line_3 TEXT, line_4 TEXT, line_5 TEXT, line_6 TEXT, line_7 TEXT, line_8 TEXT);");
|
||||
}
|
||||
if (!tableData.contains(prefix + "skull")) {
|
||||
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + prefix + "skull (id INTEGER PRIMARY KEY ASC, time INTEGER, owner TEXT);");
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package net.coreprotect.database;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
|
@ -21,12 +23,13 @@ import net.coreprotect.consumer.Consumer;
|
|||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.database.logger.ItemLogger;
|
||||
import net.coreprotect.database.statement.UserStatement;
|
||||
import net.coreprotect.listener.channel.PluginChannelHandshakeListener;
|
||||
import net.coreprotect.thread.CacheHandler;
|
||||
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) {
|
||||
|
@ -53,16 +56,19 @@ public class Lookup extends Queue {
|
|||
results[newId] = (String) map[i];
|
||||
}
|
||||
}
|
||||
else if (i == 13 && map[i] instanceof Byte[]) {
|
||||
else if (i == 13 && map[i] instanceof byte[]) {
|
||||
results[newId] = Util.byteDataToString((byte[]) map[i], (int) map[6]);
|
||||
}
|
||||
else if (i > 0) {
|
||||
else if (i > 0) { // skip rowid
|
||||
if (map[i] instanceof Integer) {
|
||||
results[newId] = map[i].toString();
|
||||
}
|
||||
else if (map[i] instanceof String) {
|
||||
results[newId] = (String) map[i];
|
||||
}
|
||||
else if (map[i] instanceof byte[]) {
|
||||
results[newId] = new String((byte[]) map[i], StandardCharsets.ISO_8859_1);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
@ -75,8 +81,8 @@ public class Lookup extends Queue {
|
|||
return newList;
|
||||
}
|
||||
|
||||
public static int countLookupRows(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, int checkTime, boolean restrictWorld, boolean lookup) {
|
||||
int rows = 0;
|
||||
public static long countLookupRows(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, boolean restrictWorld, boolean lookup) {
|
||||
Long rows = 0L;
|
||||
|
||||
try {
|
||||
while (Consumer.isPaused) {
|
||||
|
@ -84,9 +90,12 @@ public class Lookup extends Queue {
|
|||
}
|
||||
Consumer.isPaused = true;
|
||||
|
||||
ResultSet results = rawLookupResultSet(statement, user, checkUuids, checkUsers, restrictList, excludeList, excludeUserList, actionList, location, radius, checkTime, -1, -1, restrictWorld, lookup, true);
|
||||
ResultSet results = rawLookupResultSet(statement, user, checkUuids, checkUsers, restrictList, excludeList, excludeUserList, actionList, location, radius, null, startTime, endTime, -1, -1, restrictWorld, lookup, true);
|
||||
while (results.next()) {
|
||||
rows += results.getInt("count");
|
||||
int resultTable = results.getInt("tbl");
|
||||
long count = results.getLong("count");
|
||||
rowData[resultTable] = count;
|
||||
rows += count;
|
||||
}
|
||||
results.close();
|
||||
}
|
||||
|
@ -99,11 +108,11 @@ public class Lookup extends Queue {
|
|||
return rows;
|
||||
}
|
||||
|
||||
public static List<String[]> performLookup(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, long checkTime, boolean restrictWorld, boolean lookup) {
|
||||
public static List<String[]> performLookup(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 startTime, long endTime, boolean restrictWorld, boolean lookup) {
|
||||
List<String[]> newList = new ArrayList<>();
|
||||
|
||||
try {
|
||||
List<Object[]> lookupList = performLookupRaw(statement, user, checkUuids, checkUsers, restrictList, excludeList, excludeUserList, actionList, location, radius, checkTime, -1, -1, restrictWorld, lookup);
|
||||
List<Object[]> lookupList = performLookupRaw(statement, user, checkUuids, checkUsers, restrictList, excludeList, excludeUserList, actionList, location, radius, null, startTime, endTime, -1, -1, restrictWorld, lookup);
|
||||
newList = convertRawLookup(statement, lookupList);
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
@ -113,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, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, long checkTime, 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);
|
||||
|
@ -122,6 +131,10 @@ public class Lookup extends Queue {
|
|||
invalidRollbackActions.add(3);
|
||||
}
|
||||
|
||||
if (actionList.contains(4) && actionList.contains(11)) {
|
||||
invalidRollbackActions.clear();
|
||||
}
|
||||
|
||||
try {
|
||||
while (Consumer.isPaused) {
|
||||
Thread.sleep(1);
|
||||
|
@ -129,7 +142,7 @@ public class Lookup extends Queue {
|
|||
|
||||
Consumer.isPaused = true;
|
||||
|
||||
ResultSet results = rawLookupResultSet(statement, user, checkUuids, checkUsers, restrictList, excludeList, excludeUserList, actionList, location, radius, checkTime, limitOffset, limitCount, restrictWorld, lookup, false);
|
||||
ResultSet results = rawLookupResultSet(statement, user, checkUuids, checkUsers, restrictList, excludeList, excludeUserList, actionList, location, radius, rowData, startTime, endTime, limitOffset, limitCount, restrictWorld, lookup, false);
|
||||
|
||||
while (results.next()) {
|
||||
if (actionList.contains(6) || actionList.contains(7)) {
|
||||
|
@ -139,6 +152,13 @@ public class Lookup extends Queue {
|
|||
String resultMessage = results.getString("message");
|
||||
|
||||
Object[] dataArray = new Object[] { resultId, resultTime, resultUserId, resultMessage };
|
||||
if (PluginChannelHandshakeListener.getInstance().isPluginChannelPlayer(user)) {
|
||||
int resultWorldId = results.getInt("wid");
|
||||
int resultX = results.getInt("x");
|
||||
int resultY = results.getInt("y");
|
||||
int resultZ = results.getInt("z");
|
||||
dataArray = new Object[] { resultId, resultTime, resultUserId, resultMessage, resultWorldId, resultX, resultY, resultZ };
|
||||
}
|
||||
list.add(dataArray);
|
||||
}
|
||||
else if (actionList.contains(8)) {
|
||||
|
@ -171,36 +191,65 @@ public class Lookup extends Queue {
|
|||
int resultX = results.getInt("x");
|
||||
int resultY = results.getInt("y");
|
||||
int resultZ = results.getInt("z");
|
||||
boolean isFront = results.getInt("face") == 0;
|
||||
String line1 = results.getString("line_1");
|
||||
String line2 = results.getString("line_2");
|
||||
String line3 = results.getString("line_3");
|
||||
String line4 = results.getString("line_4");
|
||||
String line5 = results.getString("line_5");
|
||||
String line6 = results.getString("line_6");
|
||||
String line7 = results.getString("line_7");
|
||||
String line8 = results.getString("line_8");
|
||||
|
||||
StringBuilder message = new StringBuilder();
|
||||
if (line1 != null && line1.length() > 0) {
|
||||
if (isFront && line1 != null && line1.length() > 0) {
|
||||
message.append(line1);
|
||||
if (!line1.endsWith(" ")) {
|
||||
message.append(" ");
|
||||
}
|
||||
}
|
||||
if (line2 != null && line2.length() > 0) {
|
||||
if (isFront && line2 != null && line2.length() > 0) {
|
||||
message.append(line2);
|
||||
if (!line2.endsWith(" ")) {
|
||||
message.append(" ");
|
||||
}
|
||||
}
|
||||
if (line3 != null && line3.length() > 0) {
|
||||
if (isFront && line3 != null && line3.length() > 0) {
|
||||
message.append(line3);
|
||||
if (!line3.endsWith(" ")) {
|
||||
message.append(" ");
|
||||
}
|
||||
}
|
||||
if (line4 != null && line4.length() > 0) {
|
||||
if (isFront && line4 != null && line4.length() > 0) {
|
||||
message.append(line4);
|
||||
if (!line4.endsWith(" ")) {
|
||||
message.append(" ");
|
||||
}
|
||||
}
|
||||
if (!isFront && line5 != null && line5.length() > 0) {
|
||||
message.append(line5);
|
||||
if (!line5.endsWith(" ")) {
|
||||
message.append(" ");
|
||||
}
|
||||
}
|
||||
if (!isFront && line6 != null && line6.length() > 0) {
|
||||
message.append(line6);
|
||||
if (!line6.endsWith(" ")) {
|
||||
message.append(" ");
|
||||
}
|
||||
}
|
||||
if (!isFront && line7 != null && line7.length() > 0) {
|
||||
message.append(line7);
|
||||
if (!line7.endsWith(" ")) {
|
||||
message.append(" ");
|
||||
}
|
||||
}
|
||||
if (!isFront && line8 != null && line8.length() > 0) {
|
||||
message.append(line8);
|
||||
if (!line8.endsWith(" ")) {
|
||||
message.append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
Object[] dataArray = new Object[] { resultId, resultTime, resultUserId, resultWorldId, resultX, resultY, resultZ, message.toString() };
|
||||
list.add(dataArray);
|
||||
|
@ -208,6 +257,7 @@ public class Lookup extends Queue {
|
|||
else {
|
||||
int resultData = 0;
|
||||
int resultAmount = -1;
|
||||
int resultTable = 0;
|
||||
byte[] resultMeta = null;
|
||||
byte[] resultBlockData = null;
|
||||
long resultId = results.getLong("id");
|
||||
|
@ -221,10 +271,13 @@ public class Lookup extends Queue {
|
|||
int resultZ = results.getInt("z");
|
||||
int resultWorldId = results.getInt("wid");
|
||||
|
||||
boolean hasTbl = false;
|
||||
if ((lookup && actionList.size() == 0) || actionList.contains(4) || actionList.contains(5) || actionList.contains(11)) {
|
||||
resultData = results.getInt("data");
|
||||
resultAmount = results.getInt("amount");
|
||||
resultMeta = results.getBytes("metadata");
|
||||
resultTable = results.getInt("tbl");
|
||||
hasTbl = true;
|
||||
}
|
||||
else {
|
||||
resultData = results.getInt("data");
|
||||
|
@ -233,7 +286,6 @@ public class Lookup extends Queue {
|
|||
}
|
||||
|
||||
boolean valid = true;
|
||||
|
||||
if (!lookup) {
|
||||
if (invalidRollbackActions.contains(resultAction)) {
|
||||
valid = false;
|
||||
|
@ -241,8 +293,14 @@ public class Lookup extends Queue {
|
|||
}
|
||||
|
||||
if (valid) {
|
||||
Object[] dataArray = new Object[] { resultId, resultTime, resultUserId, resultX, resultY, resultZ, resultType, resultData, resultAction, resultRolledBack, resultWorldId, resultAmount, resultMeta, resultBlockData };
|
||||
list.add(dataArray);
|
||||
if (hasTbl) {
|
||||
Object[] dataArray = new Object[] { resultId, resultTime, resultUserId, resultX, resultY, resultZ, resultType, resultData, resultAction, resultRolledBack, resultWorldId, resultAmount, resultMeta, resultBlockData, resultTable };
|
||||
list.add(dataArray);
|
||||
}
|
||||
else {
|
||||
Object[] dataArray = new Object[] { resultId, resultTime, resultUserId, resultX, resultY, resultZ, resultType, resultData, resultAction, resultRolledBack, resultWorldId, resultAmount, resultMeta, resultBlockData };
|
||||
list.add(dataArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -256,11 +314,11 @@ public class Lookup extends Queue {
|
|||
return list;
|
||||
}
|
||||
|
||||
public static List<String[]> performPartialLookup(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, long checkTime, int limitOffset, int limitCount, boolean restrictWorld, boolean lookup) {
|
||||
public static List<String[]> performPartialLookup(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<String[]> newList = new ArrayList<>();
|
||||
|
||||
try {
|
||||
List<Object[]> lookupList = performLookupRaw(statement, user, checkUuids, checkUsers, restrictList, excludeList, excludeUserList, actionList, location, radius, checkTime, limitOffset, limitCount, restrictWorld, lookup);
|
||||
List<Object[]> lookupList = performLookupRaw(statement, user, checkUuids, checkUsers, restrictList, excludeList, excludeUserList, actionList, location, radius, rowData, startTime, endTime, limitOffset, limitCount, restrictWorld, lookup);
|
||||
newList = convertRawLookup(statement, lookupList);
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
@ -270,7 +328,7 @@ public class Lookup extends Queue {
|
|||
return newList;
|
||||
}
|
||||
|
||||
private static ResultSet rawLookupResultSet(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, long checkTime, int limitOffset, int limitCount, boolean restrictWorld, boolean lookup, boolean count) {
|
||||
private static ResultSet rawLookupResultSet(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, boolean count) {
|
||||
ResultSet results = null;
|
||||
|
||||
try {
|
||||
|
@ -279,12 +337,14 @@ public class Lookup extends Queue {
|
|||
restrictWorld = true;
|
||||
}
|
||||
|
||||
boolean inventoryQuery = (actionList.contains(4) && actionList.contains(11));
|
||||
boolean validAction = false;
|
||||
String queryBlock = "";
|
||||
String queryEntity = "";
|
||||
String queryLimit = "";
|
||||
String queryTable = "block";
|
||||
String action = "";
|
||||
String actionExclude = "";
|
||||
String includeBlock = "";
|
||||
String includeEntity = "";
|
||||
String excludeBlock = "";
|
||||
|
@ -292,6 +352,7 @@ public class Lookup extends Queue {
|
|||
String users = "";
|
||||
String uuids = "";
|
||||
String excludeUsers = "";
|
||||
String unionLimit = "";
|
||||
String index = "";
|
||||
String query = "";
|
||||
|
||||
|
@ -372,7 +433,7 @@ public class Lookup extends Queue {
|
|||
StringBuilder excludeListMaterial = new StringBuilder();
|
||||
StringBuilder excludeListEntity = new StringBuilder();
|
||||
|
||||
for (Object restrictTarget : excludeList) {
|
||||
for (Object restrictTarget : excludeList.keySet()) {
|
||||
String targetName = "";
|
||||
|
||||
if (restrictTarget instanceof Material) {
|
||||
|
@ -425,6 +486,17 @@ public class Lookup extends Queue {
|
|||
excludeUsers = excludeUserText.toString();
|
||||
}
|
||||
|
||||
// Specify actions to exclude from a:item
|
||||
if ((lookup && actionList.size() == 0) || (actionList.contains(11) && actionList.size() == 1)) {
|
||||
StringBuilder actionText = new StringBuilder();
|
||||
actionText = actionText.append(ItemLogger.ITEM_BREAK);
|
||||
actionText.append(",").append(ItemLogger.ITEM_DESTROY);
|
||||
actionText.append(",").append(ItemLogger.ITEM_CREATE);
|
||||
actionText.append(",").append(ItemLogger.ITEM_SELL);
|
||||
actionText.append(",").append(ItemLogger.ITEM_BUY);
|
||||
actionExclude = actionText.toString();
|
||||
}
|
||||
|
||||
if (!actionList.isEmpty()) {
|
||||
StringBuilder actionText = new StringBuilder();
|
||||
for (Integer actionTarget : actionList) {
|
||||
|
@ -449,18 +521,27 @@ public class Lookup extends Queue {
|
|||
// If selecting from co_item & co_container, add in actions for both transaction types
|
||||
if (actionList.contains(11) && actionList.contains(4)) {
|
||||
if (actionTarget == ItemLogger.ITEM_REMOVE) {
|
||||
actionText.append(",").append(ItemLogger.ITEM_DROP);
|
||||
actionText.append(",").append(ItemLogger.ITEM_ADD_ENDER);
|
||||
}
|
||||
if (actionTarget == ItemLogger.ITEM_ADD) {
|
||||
actionText.append(",").append(ItemLogger.ITEM_PICKUP);
|
||||
actionText.append(",").append(ItemLogger.ITEM_REMOVE_ENDER);
|
||||
actionText.append(",").append(ItemLogger.ITEM_CREATE);
|
||||
actionText.append(",").append(ItemLogger.ITEM_BUY);
|
||||
}
|
||||
if (actionTarget == ItemLogger.ITEM_ADD) {
|
||||
actionText.append(",").append(ItemLogger.ITEM_DROP);
|
||||
actionText.append(",").append(ItemLogger.ITEM_ADD_ENDER);
|
||||
actionText.append(",").append(ItemLogger.ITEM_THROW);
|
||||
actionText.append(",").append(ItemLogger.ITEM_SHOOT);
|
||||
actionText.append(",").append(ItemLogger.ITEM_BREAK);
|
||||
actionText.append(",").append(ItemLogger.ITEM_DESTROY);
|
||||
actionText.append(",").append(ItemLogger.ITEM_SELL);
|
||||
}
|
||||
}
|
||||
// If just looking up drops/pickups, include ender chest transactions
|
||||
else if (actionList.contains(11) && !actionList.contains(4)) {
|
||||
if (actionTarget == ItemLogger.ITEM_DROP) {
|
||||
actionText.append(",").append(ItemLogger.ITEM_ADD_ENDER);
|
||||
actionText.append(",").append(ItemLogger.ITEM_THROW);
|
||||
actionText.append(",").append(ItemLogger.ITEM_SHOOT);
|
||||
}
|
||||
if (actionTarget == ItemLogger.ITEM_PICKUP) {
|
||||
actionText.append(",").append(ItemLogger.ITEM_REMOVE_ENDER);
|
||||
|
@ -484,15 +565,15 @@ public class Lookup extends Queue {
|
|||
}
|
||||
|
||||
if (radius != null) {
|
||||
int xmin = radius[1];
|
||||
int xmax = radius[2];
|
||||
int ymin = radius[3];
|
||||
int ymax = radius[4];
|
||||
int zmin = radius[5];
|
||||
int zmax = radius[6];
|
||||
Integer xmin = radius[1];
|
||||
Integer xmax = radius[2];
|
||||
Integer ymin = radius[3];
|
||||
Integer ymax = radius[4];
|
||||
Integer zmin = radius[5];
|
||||
Integer zmax = radius[6];
|
||||
String queryY = "";
|
||||
|
||||
if (ymin > -1 && ymax > -1) {
|
||||
if (ymin != null && ymax != null) {
|
||||
queryY = " y >= '" + ymin + "' AND y <= '" + ymax + "' AND";
|
||||
}
|
||||
|
||||
|
@ -511,7 +592,7 @@ public class Lookup extends Queue {
|
|||
if (validAction) {
|
||||
queryBlock = queryBlock + " action IN(" + action + ") AND";
|
||||
}
|
||||
else if (includeBlock.length() > 0 || includeEntity.length() > 0 || excludeBlock.length() > 0 || excludeEntity.length() > 0) {
|
||||
else if (inventoryQuery || actionExclude.length() > 0 || includeBlock.length() > 0 || includeEntity.length() > 0 || excludeBlock.length() > 0 || excludeEntity.length() > 0) {
|
||||
queryBlock = queryBlock + " action NOT IN(-1) AND";
|
||||
}
|
||||
|
||||
|
@ -535,12 +616,16 @@ public class Lookup extends Queue {
|
|||
queryBlock = queryBlock + " user NOT IN(" + excludeUsers + ") AND";
|
||||
}
|
||||
|
||||
if (checkTime > 0) {
|
||||
queryBlock = queryBlock + " time > '" + checkTime + "' AND";
|
||||
if (startTime > 0) {
|
||||
queryBlock = queryBlock + " time > '" + startTime + "' AND";
|
||||
}
|
||||
|
||||
if (endTime > 0) {
|
||||
queryBlock = queryBlock + " time <= '" + endTime + "' AND";
|
||||
}
|
||||
|
||||
if (actionList.contains(10)) {
|
||||
queryBlock = queryBlock + " action = '1' AND (LENGTH(line_1) > 0 OR LENGTH(line_2) > 0 OR LENGTH(line_3) > 0 OR LENGTH(line_4) > 0) AND";
|
||||
queryBlock = queryBlock + " action = '1' AND (LENGTH(line_1) > 0 OR LENGTH(line_2) > 0 OR LENGTH(line_3) > 0 OR LENGTH(line_4) > 0 OR LENGTH(line_5) > 0 OR LENGTH(line_6) > 0 OR LENGTH(line_7) > 0 OR LENGTH(line_8) > 0) AND";
|
||||
}
|
||||
|
||||
if (queryBlock.length() > 0) {
|
||||
|
@ -562,6 +647,7 @@ public class Lookup extends Queue {
|
|||
String baseQuery = ((!includeEntity.isEmpty() || !excludeEntity.isEmpty()) ? queryEntity : queryBlock);
|
||||
if (limitOffset > -1 && limitCount > -1) {
|
||||
queryLimit = " LIMIT " + limitOffset + ", " + limitCount + "";
|
||||
unionLimit = " ORDER BY time DESC, id DESC LIMIT " + (limitOffset + limitCount) + "";
|
||||
}
|
||||
|
||||
String rows = "rowid as id,time,user,wid,x,y,z,action,type,data,meta,blockdata,rolled_back";
|
||||
|
@ -574,6 +660,9 @@ public class Lookup extends Queue {
|
|||
else if (actionList.contains(6) || actionList.contains(7)) {
|
||||
queryTable = "chat";
|
||||
rows = "rowid as id,time,user,message";
|
||||
if (PluginChannelHandshakeListener.getInstance().isPluginChannelPlayer(user)) {
|
||||
rows += ",wid,x,y,z";
|
||||
}
|
||||
|
||||
if (actionList.contains(7)) {
|
||||
queryTable = "command";
|
||||
|
@ -589,7 +678,7 @@ public class Lookup extends Queue {
|
|||
}
|
||||
else if (actionList.contains(10)) {
|
||||
queryTable = "sign";
|
||||
rows = "rowid as id,time,user,wid,x,y,z,line_1,line_2,line_3,line_4";
|
||||
rows = "rowid as id,time,user,wid,x,y,z,face,line_1,line_2,line_3,line_4,line_5,line_6,line_7,line_8";
|
||||
}
|
||||
else if (actionList.contains(11)) {
|
||||
queryTable = "item";
|
||||
|
@ -600,27 +689,27 @@ public class Lookup extends Queue {
|
|||
rows = "COUNT(*) as count";
|
||||
queryLimit = " LIMIT 0, 3";
|
||||
queryOrder = "";
|
||||
unionLimit = "";
|
||||
}
|
||||
|
||||
String unionSelect = "SELECT * FROM (";
|
||||
if (Config.getGlobal().MYSQL) {
|
||||
if (radius == null || users.length() > 0 || includeBlock.length() > 0 || includeEntity.length() > 0) {
|
||||
// index_mysql = "IGNORE INDEX(wid) ";
|
||||
if (queryTable.equals("block")) {
|
||||
if (includeBlock.length() > 0 || includeEntity.length() > 0) {
|
||||
index = "USE INDEX(type) IGNORE INDEX(user,wid) ";
|
||||
}
|
||||
if (users.length() > 0) {
|
||||
// index_mysql = "IGNORE INDEX(wid,type,action) ";
|
||||
index = "USE INDEX(user) IGNORE INDEX(type,wid) ";
|
||||
}
|
||||
if (radius != null && (radius[2] - radius[1]) <= 50 && (radius[6] - radius[5]) <= 50) {
|
||||
index = "USE INDEX(wid) IGNORE INDEX(type,user) ";
|
||||
}
|
||||
if ((restrictWorld && (users.length() > 0 || includeBlock.length() > 0 || includeEntity.length() > 0))) {
|
||||
index = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (queryTable.equals("block")) {
|
||||
if (includeBlock.length() > 0 || includeEntity.length() > 0) {
|
||||
index = "USE INDEX(type) ";
|
||||
}
|
||||
if (users.length() > 0) {
|
||||
index = "USE INDEX(user) ";
|
||||
}
|
||||
if ((radius != null || actionList.contains(5)) || (index.equals("") && restrictWorld)) {
|
||||
index = "USE INDEX(wid) ";
|
||||
}
|
||||
}
|
||||
unionSelect = "(";
|
||||
}
|
||||
else {
|
||||
if (queryTable.equals("block")) {
|
||||
|
@ -630,23 +719,39 @@ public class Lookup extends Queue {
|
|||
if (users.length() > 0) {
|
||||
index = "INDEXED BY block_user_index ";
|
||||
}
|
||||
if ((radius != null || actionList.contains(5)) || (index.equals("") && restrictWorld)) {
|
||||
if (radius != null && (radius[2] - radius[1]) <= 50 && (radius[6] - radius[5]) <= 50) {
|
||||
index = "INDEXED BY block_index ";
|
||||
}
|
||||
if ((restrictWorld && (users.length() > 0 || includeBlock.length() > 0 || includeEntity.length() > 0))) {
|
||||
index = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean itemLookup = (actionList.contains(4) && actionList.contains(11));
|
||||
if (lookup && actionList.size() == 0) {
|
||||
boolean itemLookup = inventoryQuery;
|
||||
if ((lookup && actionList.size() == 0) || (itemLookup && !actionList.contains(0))) {
|
||||
if (!count) {
|
||||
rows = "rowid as id,time,user,wid,x,y,z,type,meta as metadata,data,-1 as amount,action,rolled_back";
|
||||
}
|
||||
|
||||
if (inventoryQuery) {
|
||||
if (validAction) {
|
||||
baseQuery = baseQuery.replace("action IN(" + action + ")", "action IN(1)");
|
||||
}
|
||||
else {
|
||||
baseQuery = baseQuery.replace("action NOT IN(-1)", "action IN(1)");
|
||||
}
|
||||
|
||||
if (!count) {
|
||||
rows = "rowid as id,time,user,wid,x,y,z,type,meta as metadata,data,1 as amount,action,rolled_back";
|
||||
}
|
||||
}
|
||||
|
||||
if (includeBlock.length() > 0 || excludeBlock.length() > 0) {
|
||||
baseQuery = baseQuery.replace("action NOT IN(-1)", "action NOT IN(3)"); // if block specified for include/exclude, filter out entity data
|
||||
}
|
||||
|
||||
query = "SELECT " + rows + " FROM " + ConfigHandler.prefix + queryTable + " " + index + "WHERE" + baseQuery + " UNION ";
|
||||
query = unionSelect + "SELECT " + "'0' as tbl," + rows + " FROM " + ConfigHandler.prefix + "block " + index + "WHERE" + baseQuery + unionLimit + ") UNION ALL ";
|
||||
itemLookup = true;
|
||||
}
|
||||
|
||||
|
@ -654,17 +759,26 @@ public class Lookup extends Queue {
|
|||
if (!count) {
|
||||
rows = "rowid as id,time,user,wid,x,y,z,type,metadata,data,amount,action,rolled_back";
|
||||
}
|
||||
query = query + "SELECT " + rows + " FROM " + ConfigHandler.prefix + "container WHERE" + queryBlock + " UNION ";
|
||||
query = query + unionSelect + "SELECT " + "'1' as tbl," + rows + " FROM " + ConfigHandler.prefix + "container WHERE" + queryBlock + unionLimit + ") UNION ALL ";
|
||||
|
||||
if (!count) {
|
||||
rows = "rowid as id,time,user,wid,x,y,z,type,data as metadata,0 as data,amount,action,0 as rolled_back";
|
||||
queryOrder = " ORDER BY time DESC, id DESC";
|
||||
rows = "rowid as id,time,user,wid,x,y,z,type,data as metadata,0 as data,amount,action,rolled_back";
|
||||
queryOrder = " ORDER BY time DESC, tbl DESC, id DESC";
|
||||
}
|
||||
query = query + "SELECT " + rows + " FROM " + ConfigHandler.prefix + "item WHERE" + queryBlock;
|
||||
|
||||
if (actionExclude.length() > 0) {
|
||||
queryBlock = queryBlock.replace("action NOT IN(-1)", "action NOT IN(" + actionExclude + ")");
|
||||
}
|
||||
|
||||
query = query + unionSelect + "SELECT " + "'2' as tbl," + rows + " FROM " + ConfigHandler.prefix + "item WHERE" + queryBlock + unionLimit + ")";
|
||||
}
|
||||
|
||||
if (query.length() == 0) {
|
||||
query = "SELECT " + rows + " FROM " + ConfigHandler.prefix + queryTable + " " + index + "WHERE" + baseQuery;
|
||||
if (actionExclude.length() > 0) {
|
||||
baseQuery = baseQuery.replace("action NOT IN(-1)", "action NOT IN(" + actionExclude + ")");
|
||||
}
|
||||
|
||||
query = "SELECT " + "'0' as tbl," + rows + " FROM " + ConfigHandler.prefix + queryTable + " " + index + "WHERE" + baseQuery;
|
||||
}
|
||||
|
||||
query = query + queryOrder + queryLimit + "";
|
||||
|
@ -677,6 +791,21 @@ public class Lookup extends Queue {
|
|||
return results;
|
||||
}
|
||||
|
||||
/*
|
||||
private static long calculateTableOffset(long col2, long col3, long limitOffset, int limitCount) {
|
||||
return (limitOffset - (col2 + col3)) < 0L ? 0L : (limitOffset - (col2 + col3));
|
||||
}
|
||||
|
||||
private static long calculateTableLimit(long col1, long col2, long col3, long limitOffset, int limitCount) {
|
||||
long offset = calculateTableOffset(col2, col3, limitOffset, limitCount);
|
||||
long limit = (col2 + col3) + limitCount;
|
||||
limit = (limit > (limitOffset + limitCount)) ? (limitOffset + limitCount) : limit;
|
||||
limit = (limit > (col1 - offset)) ? (col1 - offset) : limit;
|
||||
|
||||
return limit;
|
||||
}
|
||||
*/
|
||||
|
||||
public static String whoPlaced(Statement statement, BlockState block) {
|
||||
String result = "";
|
||||
|
||||
|
@ -690,7 +819,7 @@ public class Lookup extends Queue {
|
|||
int z = block.getZ();
|
||||
int time = (int) (System.currentTimeMillis() / 1000L);
|
||||
int worldId = Util.getWorldId(block.getWorld().getName());
|
||||
String query = "SELECT user,type FROM " + ConfigHandler.prefix + "block WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND rolled_back = '0' AND action='1' ORDER BY rowid DESC LIMIT 0, 1";
|
||||
String query = "SELECT user,type FROM " + ConfigHandler.prefix + "block " + Util.getWidIndex("block") + "WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND rolled_back IN(0,2) AND action='1' ORDER BY rowid DESC LIMIT 0, 1";
|
||||
|
||||
ResultSet results = statement.executeQuery(query);
|
||||
while (results.next()) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,6 +8,8 @@ import org.bukkit.Location;
|
|||
import org.bukkit.Material;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.bukkit.BukkitAdapter;
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.statement.BlockStatement;
|
||||
import net.coreprotect.database.statement.UserStatement;
|
||||
|
@ -21,7 +23,7 @@ public class BlockBreakLogger {
|
|||
throw new IllegalStateException("Database class");
|
||||
}
|
||||
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, String user, Location location, int type, int data, List<Object> meta, String blockData) {
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, String user, Location location, int type, int data, List<Object> meta, String blockData, String overrideData) {
|
||||
try {
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || location == null) {
|
||||
return;
|
||||
|
@ -35,16 +37,26 @@ 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) {
|
||||
blockData = blockData.replaceFirst("has_book=true", "has_book=false");
|
||||
}
|
||||
else if (checkType == Material.PAINTING || BukkitAdapter.ADAPTER.isItemFrame(checkType)) {
|
||||
blockData = overrideData;
|
||||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
if (Config.getGlobal().API_ENABLED) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int wid = Util.getWorldId(location.getWorld().getName());
|
||||
|
@ -53,6 +65,11 @@ public class BlockBreakLogger {
|
|||
int y = location.getBlockY();
|
||||
int z = location.getBlockZ();
|
||||
CacheHandler.breakCache.put("" + x + "." + y + "." + z + "." + wid + "", new Object[] { time, event.getUser(), type });
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
BlockStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, type, data, meta, blockData, 0, 0);
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
|
|
@ -5,20 +5,15 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.Bed;
|
||||
import org.bukkit.block.data.type.Door;
|
||||
import org.bukkit.block.data.type.Door.Hinge;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.bukkit.BukkitAdapter;
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.statement.BlockStatement;
|
||||
import net.coreprotect.database.statement.UserStatement;
|
||||
import net.coreprotect.event.CoreProtectPreLogEvent;
|
||||
import net.coreprotect.model.BlockGroup;
|
||||
import net.coreprotect.thread.CacheHandler;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
|
@ -33,6 +28,7 @@ public class BlockPlaceLogger {
|
|||
if (user == null || ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Material type = block.getType();
|
||||
if (blockData == null && (forceType == null || (!forceType.equals(Material.WATER)) && (!forceType.equals(Material.LAVA)))) {
|
||||
blockData = block.getBlockData().getAsString();
|
||||
|
@ -59,106 +55,57 @@ 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();
|
||||
long chunkKey = (x >> 4) & 0xffffffffL | ((z >> 4) & 0xffffffffL) << 32;
|
||||
if (ConfigHandler.populatedChunks.get(chunkKey) != null) {
|
||||
boolean isWater = user.equals("#water");
|
||||
boolean isLava = user.equals("#lava");
|
||||
boolean isVine = user.equals("#vine");
|
||||
if (isWater || isLava || isVine) {
|
||||
int timeDelay = isWater ? 60 : 240;
|
||||
long timeSincePopulation = ((System.currentTimeMillis() / 1000L) - ConfigHandler.populatedChunks.getOrDefault(chunkKey, 0L));
|
||||
if (timeSincePopulation <= timeDelay) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (timeSincePopulation > 240) {
|
||||
ConfigHandler.populatedChunks.remove(chunkKey);
|
||||
}
|
||||
}
|
||||
else if (type == Material.WATER || type == Material.LAVA) {
|
||||
ConfigHandler.populatedChunks.remove(chunkKey);
|
||||
}
|
||||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
if (Config.getGlobal().API_ENABLED) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int wid = Util.getWorldId(block.getWorld().getName());
|
||||
int time = (int) (System.currentTimeMillis() / 1000L);
|
||||
int x = block.getX();
|
||||
int y = block.getY();
|
||||
int z = block.getZ();
|
||||
int dx = x;
|
||||
int dy = y;
|
||||
int dz = z;
|
||||
Material doubletype = type;
|
||||
int doubledata = data;
|
||||
int logdouble = 0;
|
||||
|
||||
if (event.getUser().length() > 0) {
|
||||
CacheHandler.lookupCache.put("" + x + "." + y + "." + z + "." + wid + "", new Object[] { time, event.getUser(), type });
|
||||
}
|
||||
|
||||
String doubleBlockData = null;
|
||||
if (type.name().endsWith("_BED") || type == Material.IRON_DOOR || BlockGroup.DOORS.contains(type)) { // properly log double blocks (doors/beds)
|
||||
BlockData blockStateBlockData = block.getBlockData();
|
||||
if (blockStateBlockData instanceof Bed) {
|
||||
Bed bed = (Bed) blockStateBlockData;
|
||||
Bed.Part bedPart = bed.getPart();
|
||||
BlockFace face = bed.getFacing();
|
||||
|
||||
int bedData = 1;
|
||||
switch (face) {
|
||||
case WEST:
|
||||
dx = ((bedPart == Bed.Part.HEAD) ? (x + 1) : (x - 1));
|
||||
bedData = 2;
|
||||
break;
|
||||
case EAST:
|
||||
dx = ((bedPart == Bed.Part.HEAD) ? (x - 1) : (x + 1));
|
||||
bedData = 3;
|
||||
break;
|
||||
case SOUTH:
|
||||
dz = ((bedPart == Bed.Part.HEAD) ? (z - 1) : (z + 1));
|
||||
bedData = 4;
|
||||
break;
|
||||
default:
|
||||
dz = ((bedPart == Bed.Part.HEAD) ? (z + 1) : (z - 1));
|
||||
break;
|
||||
}
|
||||
|
||||
if (bedPart == Bed.Part.HEAD) {
|
||||
data = 4 + bedData;
|
||||
doubledata = bedData;
|
||||
bed.setPart(Bed.Part.FOOT);
|
||||
doubleBlockData = bed.getAsString();
|
||||
}
|
||||
else {
|
||||
data = bedData;
|
||||
doubledata = 4 + bedData;
|
||||
bed.setPart(Bed.Part.HEAD);
|
||||
doubleBlockData = bed.getAsString();
|
||||
}
|
||||
}
|
||||
else if (blockStateBlockData instanceof Door) {
|
||||
Door door = (Door) blockStateBlockData;
|
||||
BlockFace face = door.getFacing();
|
||||
Hinge hinge = door.getHinge();
|
||||
switch (face) {
|
||||
case EAST:
|
||||
data = 0;
|
||||
break;
|
||||
case SOUTH:
|
||||
data = 1;
|
||||
break;
|
||||
case WEST:
|
||||
data = 2;
|
||||
break;
|
||||
default:
|
||||
data = 3;
|
||||
break;
|
||||
}
|
||||
if (hinge.equals(Hinge.RIGHT)) {
|
||||
data = data + 4;
|
||||
}
|
||||
if (data < 8) {
|
||||
dy = y + 1;
|
||||
doubledata = data + 8;
|
||||
}
|
||||
}
|
||||
logdouble = 1;
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int internalType = Util.getBlockId(type.name(), true);
|
||||
int internalDoubleType = Util.getBlockId(doubletype.name(), true);
|
||||
|
||||
if (replacedType > 0 && Util.getType(replacedType) != Material.AIR && Util.getType(replacedType) != Material.CAVE_AIR) {
|
||||
BlockStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, replacedType, replacedData, null, replaceBlockData, 0, 0);
|
||||
}
|
||||
|
||||
BlockStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, internalType, data, meta, blockData, 1, 0);
|
||||
if (logdouble == 1) {
|
||||
BlockStatement.insert(preparedStmt, batchCount, time, userId, wid, dx, dy, dz, internalDoubleType, doubledata, null, doubleBlockData, 1, 0);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.util.Locale;
|
|||
import org.bukkit.Location;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.statement.CommandStatement;
|
||||
import net.coreprotect.database.statement.UserStatement;
|
||||
|
@ -28,7 +29,13 @@ public class CommandLogger {
|
|||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
if (Config.getGlobal().API_ENABLED) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int wid = Util.getWorldId(location.getWorld().getName());
|
||||
|
|
|
@ -19,7 +19,7 @@ public class ContainerBreakLogger {
|
|||
public static void log(PreparedStatement preparedStmt, int batchCount, String player, Location l, Material type, ItemStack[] oldInventory) {
|
||||
try {
|
||||
Util.mergeItems(type, oldInventory);
|
||||
ContainerLogger.logTransaction(preparedStmt, batchCount, player, type, oldInventory, 0, l);
|
||||
ContainerLogger.logTransaction(preparedStmt, batchCount, player, type, null, oldInventory, 0, l);
|
||||
String loggingContainerId = player.toLowerCase(Locale.ROOT) + "." + l.getBlockX() + "." + l.getBlockY() + "." + l.getBlockZ();
|
||||
|
||||
// If there was a pending chest transaction, it would have already been processed.
|
||||
|
|
|
@ -9,11 +9,12 @@ import java.util.Map;
|
|||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.database.statement.ContainerStatement;
|
||||
|
@ -31,11 +32,14 @@ public class ContainerLogger extends Queue {
|
|||
public static void log(PreparedStatement preparedStmtContainer, PreparedStatement preparedStmtItems, int batchCount, String player, Material type, Object container, Location location) {
|
||||
try {
|
||||
ItemStack[] contents = null;
|
||||
if (type.equals(Material.ARMOR_STAND)) {
|
||||
EntityEquipment equipment = (EntityEquipment) container;
|
||||
if (equipment != null) {
|
||||
contents = Util.getArmorStandContents(equipment);
|
||||
}
|
||||
String faceData = null;
|
||||
|
||||
if (type == Material.ITEM_FRAME) {
|
||||
contents = (ItemStack[]) ((Object[]) container)[1];
|
||||
faceData = ((BlockFace) ((Object[]) container)[2]).name();
|
||||
}
|
||||
else if (type == Material.JUKEBOX || type == Material.ARMOR_STAND) {
|
||||
contents = (ItemStack[]) ((Object[]) container)[1];
|
||||
}
|
||||
else {
|
||||
Inventory inventory = (Inventory) container;
|
||||
|
@ -53,6 +57,9 @@ public class ContainerLogger extends Queue {
|
|||
ItemStack[] oi1 = oldList.get(0);
|
||||
ItemStack[] oldInventory = Util.getContainerState(oi1);
|
||||
ItemStack[] newInventory = Util.getContainerState(contents);
|
||||
if (oldInventory == null || newInventory == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<ItemStack[]> forceList = ConfigHandler.forceContainer.get(loggingContainerId);
|
||||
if (forceList != null) {
|
||||
|
@ -133,12 +140,12 @@ public class ContainerLogger extends Queue {
|
|||
Util.mergeItems(type, newInventory);
|
||||
|
||||
if (type != Material.ENDER_CHEST) {
|
||||
logTransaction(preparedStmtContainer, batchCount, player, type, oldInventory, 0, location);
|
||||
logTransaction(preparedStmtContainer, batchCount, player, type, newInventory, 1, location);
|
||||
logTransaction(preparedStmtContainer, batchCount, player, type, faceData, oldInventory, 0, location);
|
||||
logTransaction(preparedStmtContainer, batchCount, player, type, faceData, newInventory, 1, location);
|
||||
}
|
||||
else { // pass ender chest transactions to item logger
|
||||
ItemLogger.logTransaction(preparedStmtItems, batchCount, player, location, oldInventory, ItemLogger.ITEM_REMOVE_ENDER);
|
||||
ItemLogger.logTransaction(preparedStmtItems, batchCount, player, location, newInventory, ItemLogger.ITEM_ADD_ENDER);
|
||||
ItemLogger.logTransaction(preparedStmtItems, batchCount, 0, player, location, oldInventory, ItemLogger.ITEM_REMOVE_ENDER);
|
||||
ItemLogger.logTransaction(preparedStmtItems, batchCount, 0, player, location, newInventory, ItemLogger.ITEM_ADD_ENDER);
|
||||
}
|
||||
|
||||
oldList.remove(0);
|
||||
|
@ -149,23 +156,30 @@ public class ContainerLogger extends Queue {
|
|||
}
|
||||
}
|
||||
|
||||
protected static void logTransaction(PreparedStatement preparedStmt, int batchCount, String user, Material type, ItemStack[] items, int action, Location location) {
|
||||
protected static void logTransaction(PreparedStatement preparedStmt, int batchCount, String user, Material type, String faceData, ItemStack[] items, int action, Location location) {
|
||||
try {
|
||||
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, slot);
|
||||
List<List<Map<String, Object>>> metadata = ItemMetaHandler.serialize(item, type, faceData, slot);
|
||||
if (metadata.size() == 0) {
|
||||
metadata = null;
|
||||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
if (Config.getGlobal().API_ENABLED) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int wid = Util.getWorldId(location.getWorld().getName());
|
||||
|
@ -174,13 +188,20 @@ public class ContainerLogger extends Queue {
|
|||
int y = location.getBlockY();
|
||||
int z = location.getBlockZ();
|
||||
int typeId = Util.getBlockId(item.getType().name(), true);
|
||||
int data = item.getDurability();
|
||||
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();
|
||||
|
|
|
@ -8,7 +8,9 @@ import java.util.Locale;
|
|||
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;
|
||||
|
@ -28,7 +30,13 @@ public class EntityKillLogger {
|
|||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
if (Config.getGlobal().API_ENABLED) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int wid = Util.getWorldId(block.getWorld().getName());
|
||||
|
@ -36,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) {
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.bukkit.Location;
|
|||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.statement.ItemStatement;
|
||||
import net.coreprotect.database.statement.UserStatement;
|
||||
|
@ -25,12 +26,19 @@ public class ItemLogger {
|
|||
public static final int ITEM_PICKUP = 3;
|
||||
public static final int ITEM_REMOVE_ENDER = 4;
|
||||
public static final int ITEM_ADD_ENDER = 5;
|
||||
public static final int ITEM_THROW = 6;
|
||||
public static final int ITEM_SHOOT = 7;
|
||||
public static final int ITEM_BREAK = 8;
|
||||
public static final int ITEM_DESTROY = 9;
|
||||
public static final int ITEM_CREATE = 10;
|
||||
public static final int ITEM_SELL = 11;
|
||||
public static final int ITEM_BUY = 12;
|
||||
|
||||
private ItemLogger() {
|
||||
throw new IllegalStateException("Database class");
|
||||
}
|
||||
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, Location location, String user) {
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, Location location, int offset, String user) {
|
||||
try {
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
|
||||
return;
|
||||
|
@ -38,42 +46,97 @@ public class ItemLogger {
|
|||
|
||||
String loggingItemId = user.toLowerCase(Locale.ROOT) + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
|
||||
|
||||
List<ItemStack> dropList = ConfigHandler.itemsDrop.getOrDefault(loggingItemId, new ArrayList<>());
|
||||
ItemStack[] itemDrops = new ItemStack[dropList.size()];
|
||||
itemDrops = dropList.toArray(itemDrops);
|
||||
dropList.clear();
|
||||
|
||||
List<ItemStack> pickupList = ConfigHandler.itemsPickup.getOrDefault(loggingItemId, new ArrayList<>());
|
||||
ItemStack[] itemPickups = new ItemStack[pickupList.size()];
|
||||
itemPickups = pickupList.toArray(itemPickups);
|
||||
pickupList.clear();
|
||||
|
||||
Util.mergeItems(null, itemDrops);
|
||||
List<ItemStack> dropList = ConfigHandler.itemsDrop.getOrDefault(loggingItemId, new ArrayList<>());
|
||||
ItemStack[] itemDrops = new ItemStack[dropList.size()];
|
||||
itemDrops = dropList.toArray(itemDrops);
|
||||
dropList.clear();
|
||||
|
||||
List<ItemStack> thrownList = ConfigHandler.itemsThrown.getOrDefault(loggingItemId, new ArrayList<>());
|
||||
ItemStack[] itemThrows = new ItemStack[thrownList.size()];
|
||||
itemThrows = thrownList.toArray(itemThrows);
|
||||
thrownList.clear();
|
||||
|
||||
List<ItemStack> shotList = ConfigHandler.itemsShot.getOrDefault(loggingItemId, new ArrayList<>());
|
||||
ItemStack[] itemShots = new ItemStack[shotList.size()];
|
||||
itemShots = shotList.toArray(itemShots);
|
||||
shotList.clear();
|
||||
|
||||
List<ItemStack> breakList = ConfigHandler.itemsBreak.getOrDefault(loggingItemId, new ArrayList<>());
|
||||
ItemStack[] itemBreaks = new ItemStack[breakList.size()];
|
||||
itemBreaks = breakList.toArray(itemBreaks);
|
||||
breakList.clear();
|
||||
|
||||
List<ItemStack> destroyList = ConfigHandler.itemsDestroy.getOrDefault(loggingItemId, new ArrayList<>());
|
||||
ItemStack[] itemDestroys = new ItemStack[destroyList.size()];
|
||||
itemDestroys = destroyList.toArray(itemDestroys);
|
||||
destroyList.clear();
|
||||
|
||||
List<ItemStack> createList = ConfigHandler.itemsCreate.getOrDefault(loggingItemId, new ArrayList<>());
|
||||
ItemStack[] itemCreates = new ItemStack[createList.size()];
|
||||
itemCreates = createList.toArray(itemCreates);
|
||||
createList.clear();
|
||||
|
||||
List<ItemStack> sellList = ConfigHandler.itemsSell.getOrDefault(loggingItemId, new ArrayList<>());
|
||||
ItemStack[] itemSells = new ItemStack[sellList.size()];
|
||||
itemSells = sellList.toArray(itemSells);
|
||||
sellList.clear();
|
||||
|
||||
List<ItemStack> buyList = ConfigHandler.itemsBuy.getOrDefault(loggingItemId, new ArrayList<>());
|
||||
ItemStack[] itemBuys = new ItemStack[buyList.size()];
|
||||
itemBuys = buyList.toArray(itemBuys);
|
||||
buyList.clear();
|
||||
|
||||
Util.mergeItems(null, itemPickups);
|
||||
logTransaction(preparedStmt, batchCount, user, location, itemDrops, ITEM_DROP);
|
||||
logTransaction(preparedStmt, batchCount, user, location, itemPickups, ITEM_PICKUP);
|
||||
Util.mergeItems(null, itemDrops);
|
||||
Util.mergeItems(null, itemThrows);
|
||||
Util.mergeItems(null, itemShots);
|
||||
Util.mergeItems(null, itemBreaks);
|
||||
Util.mergeItems(null, itemDestroys);
|
||||
Util.mergeItems(null, itemCreates);
|
||||
Util.mergeItems(null, itemSells);
|
||||
Util.mergeItems(null, itemBuys);
|
||||
logTransaction(preparedStmt, batchCount, offset, user, location, itemPickups, ITEM_PICKUP);
|
||||
logTransaction(preparedStmt, batchCount, offset, user, location, itemDrops, ITEM_DROP);
|
||||
logTransaction(preparedStmt, batchCount, offset, user, location, itemThrows, ITEM_THROW);
|
||||
logTransaction(preparedStmt, batchCount, offset, user, location, itemShots, ITEM_SHOOT);
|
||||
logTransaction(preparedStmt, batchCount, offset, user, location, itemBreaks, ITEM_BREAK);
|
||||
logTransaction(preparedStmt, batchCount, offset, user, location, itemDestroys, ITEM_DESTROY);
|
||||
logTransaction(preparedStmt, batchCount, offset, user, location, itemCreates, ITEM_CREATE);
|
||||
logTransaction(preparedStmt, batchCount, offset, user, location, itemSells, ITEM_SELL);
|
||||
logTransaction(preparedStmt, batchCount, offset, user, location, itemBuys, ITEM_BUY);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected static void logTransaction(PreparedStatement preparedStmt, int batchCount, String user, Location location, ItemStack[] items, int action) {
|
||||
protected static void logTransaction(PreparedStatement preparedStmt, int batchCount, int offset, String user, Location location, ItemStack[] items, int action) {
|
||||
try {
|
||||
for (ItemStack item : items) {
|
||||
if (item != null && item.getAmount() > 0 && !Util.isAir(item.getType())) {
|
||||
// Object[] metadata = new Object[] { slot, item.getItemMeta() };
|
||||
List<List<Map<String, Object>>> data = ItemMetaHandler.seralize(item, null, 0);
|
||||
List<List<Map<String, Object>>> data = ItemMetaHandler.serialize(item, null, null, 0);
|
||||
if (data.size() == 0) {
|
||||
data = null;
|
||||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
if (Config.getGlobal().API_ENABLED) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int wid = Util.getWorldId(location.getWorld().getName());
|
||||
int time = (int) (System.currentTimeMillis() / 1000L);
|
||||
int time = (int) (System.currentTimeMillis() / 1000L) - offset;
|
||||
int x = location.getBlockX();
|
||||
int y = location.getBlockY();
|
||||
int z = location.getBlockZ();
|
||||
|
|
|
@ -7,6 +7,7 @@ import org.bukkit.Material;
|
|||
import org.bukkit.block.BlockState;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.statement.BlockStatement;
|
||||
import net.coreprotect.database.statement.UserStatement;
|
||||
|
@ -19,15 +20,21 @@ public class PlayerInteractLogger {
|
|||
throw new IllegalStateException("Database class");
|
||||
}
|
||||
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, String user, BlockState block) {
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, String user, BlockState block, Material blockType) {
|
||||
try {
|
||||
int type = Util.getBlockId(block.getType().name(), true);
|
||||
int type = Util.getBlockId(blockType.name(), true);
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || Util.getType(type).equals(Material.AIR) || Util.getType(type).equals(Material.CAVE_AIR)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
if (Config.getGlobal().API_ENABLED) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int wid = Util.getWorldId(block.getWorld().getName());
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.util.Locale;
|
|||
import org.bukkit.block.BlockState;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.statement.BlockStatement;
|
||||
import net.coreprotect.database.statement.UserStatement;
|
||||
|
@ -24,8 +25,18 @@ public class PlayerKillLogger {
|
|||
return;
|
||||
}
|
||||
|
||||
if (ConfigHandler.playerIdCache.get(player.toLowerCase(Locale.ROOT)) == null) {
|
||||
UserStatement.loadId(preparedStmt.getConnection(), player, null);
|
||||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
if (Config.getGlobal().API_ENABLED) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int playerId = ConfigHandler.playerIdCache.get(player.toLowerCase(Locale.ROOT));
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.util.Locale;
|
|||
import org.bukkit.Location;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.statement.SignStatement;
|
||||
import net.coreprotect.database.statement.UserStatement;
|
||||
|
@ -18,14 +19,20 @@ public class SignTextLogger {
|
|||
throw new IllegalStateException("Database class");
|
||||
}
|
||||
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, String user, Location location, int action, int color, int data, String line1, String line2, String line3, String line4, int timeOffset) {
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, String user, Location location, int action, int color, int colorSecondary, int data, boolean isWaxed, boolean isFront, String line1, String line2, String line3, String line4, String line5, String line6, String line7, String line8, int timeOffset) {
|
||||
try {
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
if (Config.getGlobal().API_ENABLED) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int wid = Util.getWorldId(location.getWorld().getName());
|
||||
|
@ -33,7 +40,21 @@ public class SignTextLogger {
|
|||
int x = location.getBlockX();
|
||||
int y = location.getBlockY();
|
||||
int z = location.getBlockZ();
|
||||
SignStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, action, color, data, line1, line2, line3, line4);
|
||||
|
||||
if (line1.isEmpty() && line2.isEmpty() && line3.isEmpty() && line4.isEmpty()) {
|
||||
line1 = null;
|
||||
line2 = null;
|
||||
line3 = null;
|
||||
line4 = null;
|
||||
}
|
||||
if (line5.isEmpty() && line6.isEmpty() && line7.isEmpty() && line8.isEmpty()) {
|
||||
line5 = null;
|
||||
line6 = null;
|
||||
line7 = null;
|
||||
line8 = null;
|
||||
}
|
||||
|
||||
SignStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, action, color, colorSecondary, data, isWaxed ? 1 : 0, isFront ? 0 : 1, line1, line2, line3, line4, line5, line6, line7, line8);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -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,15 +30,22 @@ 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());
|
||||
BlockBreakLogger.log(preparedStmt, batchCount, user, block.getLocation(), type, skullKey, null, block.getBlockData().getAsString(), null);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import net.coreprotect.config.ConfigHandler;
|
|||
import net.coreprotect.database.statement.UserStatement;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.language.Selector;
|
||||
import net.coreprotect.utility.Chat;
|
||||
import net.coreprotect.listener.channel.PluginChannelListener;
|
||||
import net.coreprotect.utility.Color;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
|
@ -45,9 +45,9 @@ public class BlockLookup {
|
|||
int x = block.getX();
|
||||
int y = block.getY();
|
||||
int z = block.getZ();
|
||||
int time = (int) (System.currentTimeMillis() / 1000L);
|
||||
long time = (System.currentTimeMillis() / 1000L);
|
||||
int worldId = Util.getWorldId(block.getWorld().getName());
|
||||
int checkTime = 0;
|
||||
long checkTime = 0;
|
||||
int count = 0;
|
||||
int rowMax = page * limit;
|
||||
int page_start = rowMax - limit;
|
||||
|
@ -57,7 +57,7 @@ public class BlockLookup {
|
|||
|
||||
String blockName = block.getType().name().toLowerCase(Locale.ROOT);
|
||||
|
||||
String query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "block WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action IN(0,1) AND time >= '" + checkTime + "' LIMIT 0, 1";
|
||||
String query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "block " + Util.getWidIndex("block") + "WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action IN(0,1) AND time >= '" + checkTime + "' LIMIT 0, 1";
|
||||
ResultSet results = statement.executeQuery(query);
|
||||
while (results.next()) {
|
||||
count = results.getInt("count");
|
||||
|
@ -65,7 +65,7 @@ public class BlockLookup {
|
|||
results.close();
|
||||
int totalPages = (int) Math.ceil(count / (limit + 0.0));
|
||||
|
||||
query = "SELECT time,user,action,type,data,rolled_back FROM " + ConfigHandler.prefix + "block WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action IN(0,1) AND time >= '" + checkTime + "' ORDER BY rowid DESC LIMIT " + page_start + ", " + limit + "";
|
||||
query = "SELECT time,user,action,type,data,rolled_back FROM " + ConfigHandler.prefix + "block " + Util.getWidIndex("block") + "WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action IN(0,1) AND time >= '" + checkTime + "' ORDER BY rowid DESC LIMIT " + page_start + ", " + limit + "";
|
||||
results = statement.executeQuery(query);
|
||||
|
||||
StringBuilder resultTextBuilder = new StringBuilder();
|
||||
|
@ -75,7 +75,7 @@ public class BlockLookup {
|
|||
int resultAction = results.getInt("action");
|
||||
int resultType = results.getInt("type");
|
||||
int resultData = results.getInt("data");
|
||||
int resultTime = results.getInt("time");
|
||||
long resultTime = results.getLong("time");
|
||||
int resultRolledBack = results.getInt("rolled_back");
|
||||
|
||||
if (ConfigHandler.playerIdCacheReversed.get(resultUserId) == null) {
|
||||
|
@ -92,17 +92,20 @@ public class BlockLookup {
|
|||
|
||||
Phrase phrase = Phrase.LOOKUP_BLOCK;
|
||||
String selector = Selector.FIRST;
|
||||
String tag = Color.WHITE + "-";
|
||||
if (resultAction == 2 || resultAction == 3) {
|
||||
phrase = Phrase.LOOKUP_INTERACTION; // {clicked|killed}
|
||||
selector = (resultAction != 3 ? Selector.FIRST : Selector.SECOND);
|
||||
tag = (resultAction != 3 ? Color.WHITE + "-" : Color.RED + "-");
|
||||
}
|
||||
else {
|
||||
phrase = Phrase.LOOKUP_BLOCK; // {placed|broke}
|
||||
selector = (resultAction != 0 ? Selector.FIRST : Selector.SECOND);
|
||||
tag = (resultAction != 0 ? Color.GREEN + "+" : Color.RED + "-");
|
||||
}
|
||||
|
||||
String rbFormat = "";
|
||||
if (resultRolledBack == 1) {
|
||||
if (resultRolledBack == 1 || resultRolledBack == 3) {
|
||||
rbFormat = Color.STRIKETHROUGH;
|
||||
}
|
||||
|
||||
|
@ -127,7 +130,8 @@ public class BlockLookup {
|
|||
target = target.split(":")[1];
|
||||
}
|
||||
|
||||
resultTextBuilder.append(timeAgo + " " + Color.WHITE + "- ").append(Phrase.build(phrase, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, Color.DARK_AQUA + rbFormat + target + Color.WHITE, selector)).append("\n");
|
||||
resultTextBuilder.append(timeAgo + " " + tag + " ").append(Phrase.build(phrase, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, Color.DARK_AQUA + rbFormat + target + Color.WHITE, selector)).append("\n");
|
||||
PluginChannelListener.getInstance().sendData(commandSender, resultTime, phrase, selector, resultUser, target, -1, x, y, z, worldId, rbFormat, false, tag.contains("+"));
|
||||
}
|
||||
|
||||
resultText = resultTextBuilder.toString();
|
||||
|
@ -136,7 +140,7 @@ public class BlockLookup {
|
|||
if (found) {
|
||||
if (count > limit) {
|
||||
String pageInfo = Color.WHITE + "-----\n";
|
||||
pageInfo = pageInfo + Util.getPageNavigation(command, page, totalPages) + "| " + Phrase.build(Phrase.LOOKUP_VIEW_PAGE, Color.WHITE, "/co l <page>") + "\n";
|
||||
pageInfo = pageInfo + Util.getPageNavigation(command, page, totalPages) + "\n";
|
||||
resultText = resultText + pageInfo;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package net.coreprotect.database.lookup;
|
|||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.Location;
|
||||
|
@ -12,14 +14,14 @@ import net.coreprotect.config.ConfigHandler;
|
|||
import net.coreprotect.database.statement.UserStatement;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.language.Selector;
|
||||
import net.coreprotect.utility.Chat;
|
||||
import net.coreprotect.listener.channel.PluginChannelListener;
|
||||
import net.coreprotect.utility.Color;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class ChestTransactionLookup {
|
||||
|
||||
public static String performLookup(String command, Statement statement, Location l, CommandSender commandSender, int page, int limit, boolean exact) {
|
||||
String result = "";
|
||||
public static List<String> performLookup(String command, Statement statement, Location l, CommandSender commandSender, int page, int limit, boolean exact) {
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
try {
|
||||
if (l == null) {
|
||||
|
@ -48,15 +50,15 @@ public class ChestTransactionLookup {
|
|||
int x2 = (int) Math.ceil(l.getX());
|
||||
int y2 = (int) Math.ceil(l.getY());
|
||||
int z2 = (int) Math.ceil(l.getZ());
|
||||
int time = (int) (System.currentTimeMillis() / 1000L);
|
||||
long time = (System.currentTimeMillis() / 1000L);
|
||||
int worldId = Util.getWorldId(l.getWorld().getName());
|
||||
int count = 0;
|
||||
int rowMax = page * limit;
|
||||
int pageStart = rowMax - limit;
|
||||
|
||||
String query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "container WHERE wid = '" + worldId + "' AND (x = '" + x + "' OR x = '" + x2 + "') AND (z = '" + z + "' OR z = '" + z2 + "') AND y = '" + y + "' LIMIT 0, 1";
|
||||
String query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "container " + Util.getWidIndex("container") + "WHERE wid = '" + worldId + "' AND (x = '" + x + "' OR x = '" + x2 + "') AND (z = '" + z + "' OR z = '" + z2 + "') AND y = '" + y + "' LIMIT 0, 1";
|
||||
if (exact) {
|
||||
query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "container WHERE wid = '" + worldId + "' AND (x = '" + l.getBlockX() + "') AND (z = '" + l.getBlockZ() + "') AND y = '" + y + "' LIMIT 0, 1";
|
||||
query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "container " + Util.getWidIndex("container") + "WHERE wid = '" + worldId + "' AND (x = '" + l.getBlockX() + "') AND (z = '" + l.getBlockZ() + "') AND y = '" + y + "' LIMIT 0, 1";
|
||||
}
|
||||
ResultSet results = statement.executeQuery(query);
|
||||
|
||||
|
@ -67,21 +69,21 @@ public class ChestTransactionLookup {
|
|||
|
||||
int totalPages = (int) Math.ceil(count / (limit + 0.0));
|
||||
|
||||
query = "SELECT time,user,action,type,data,amount,rolled_back FROM " + ConfigHandler.prefix + "container WHERE wid = '" + worldId + "' AND (x = '" + x + "' OR x = '" + x2 + "') AND (z = '" + z + "' OR z = '" + z2 + "') AND y = '" + y + "' ORDER BY rowid DESC LIMIT " + pageStart + ", " + limit + "";
|
||||
query = "SELECT time,user,action,type,data,amount,metadata,rolled_back FROM " + ConfigHandler.prefix + "container " + Util.getWidIndex("container") + "WHERE wid = '" + worldId + "' AND (x = '" + x + "' OR x = '" + x2 + "') AND (z = '" + z + "' OR z = '" + z2 + "') AND y = '" + y + "' ORDER BY rowid DESC LIMIT " + pageStart + ", " + limit + "";
|
||||
if (exact) {
|
||||
query = "SELECT time,user,action,type,data,amount,rolled_back FROM " + ConfigHandler.prefix + "container WHERE wid = '" + worldId + "' AND (x = '" + l.getBlockX() + "') AND (z = '" + l.getBlockZ() + "') AND y = '" + y + "' ORDER BY rowid DESC LIMIT " + pageStart + ", " + limit + "";
|
||||
query = "SELECT time,user,action,type,data,amount,metadata,rolled_back FROM " + ConfigHandler.prefix + "container " + Util.getWidIndex("container") + "WHERE wid = '" + worldId + "' AND (x = '" + l.getBlockX() + "') AND (z = '" + l.getBlockZ() + "') AND y = '" + y + "' ORDER BY rowid DESC LIMIT " + pageStart + ", " + limit + "";
|
||||
}
|
||||
results = statement.executeQuery(query);
|
||||
|
||||
StringBuilder resultBuilder = new StringBuilder();
|
||||
while (results.next()) {
|
||||
int resultUserId = results.getInt("user");
|
||||
int resultAction = results.getInt("action");
|
||||
int resultType = results.getInt("type");
|
||||
int resultData = results.getInt("data");
|
||||
int resultTime = results.getInt("time");
|
||||
long resultTime = results.getLong("time");
|
||||
int resultAmount = results.getInt("amount");
|
||||
int resultRolledBack = results.getInt("rolled_back");
|
||||
byte[] resultMetadata = results.getBytes("metadata");
|
||||
String tooltip = Util.getEnchantments(resultMetadata, resultType, resultAmount);
|
||||
|
||||
if (ConfigHandler.playerIdCacheReversed.get(resultUserId) == null) {
|
||||
UserStatement.loadName(statement.getConnection(), resultUserId);
|
||||
|
@ -91,13 +93,14 @@ public class ChestTransactionLookup {
|
|||
String timeAgo = Util.getTimeSince(resultTime, time, true);
|
||||
|
||||
if (!found) {
|
||||
resultBuilder = new StringBuilder(Color.WHITE + "----- " + Color.DARK_AQUA + Phrase.build(Phrase.CONTAINER_HEADER) + Color.WHITE + " ----- " + Util.getCoordinates(command, worldId, x, y, z, false, false) + "\n");
|
||||
result.add(new StringBuilder(Color.WHITE + "----- " + Color.DARK_AQUA + Phrase.build(Phrase.CONTAINER_HEADER) + Color.WHITE + " ----- " + Util.getCoordinates(command, worldId, x, y, z, false, false)).toString());
|
||||
}
|
||||
found = true;
|
||||
|
||||
String selector = (resultAction != 0 ? Selector.FIRST : Selector.SECOND);
|
||||
String tag = (resultAction != 0 ? Color.GREEN + "+" : Color.RED + "-");
|
||||
String rbFormat = "";
|
||||
if (resultRolledBack == 1) {
|
||||
if (resultRolledBack == 1 || resultRolledBack == 3) {
|
||||
rbFormat = Color.STRIKETHROUGH;
|
||||
}
|
||||
|
||||
|
@ -116,24 +119,23 @@ public class ChestTransactionLookup {
|
|||
target = target.split(":")[1];
|
||||
}
|
||||
|
||||
resultBuilder.append(timeAgo + " " + Color.WHITE + "- ").append(Phrase.build(Phrase.LOOKUP_CONTAINER, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, "x" + resultAmount, Color.DARK_AQUA + rbFormat + target + Color.WHITE, selector)).append("\n");
|
||||
result.add(new StringBuilder(timeAgo + " " + tag + " " + Phrase.build(Phrase.LOOKUP_CONTAINER, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, "x" + resultAmount, Util.createTooltip(Color.DARK_AQUA + rbFormat + target, tooltip) + Color.WHITE, selector)).toString());
|
||||
PluginChannelListener.getInstance().sendData(commandSender, resultTime, Phrase.LOOKUP_CONTAINER, selector, resultUser, target, resultAmount, x, y, z, worldId, rbFormat, true, tag.contains("+"));
|
||||
}
|
||||
result = resultBuilder.toString();
|
||||
results.close();
|
||||
|
||||
if (found) {
|
||||
if (count > limit) {
|
||||
String pageInfo = Color.WHITE + "-----\n";
|
||||
pageInfo = pageInfo + Util.getPageNavigation(command, page, totalPages) + "| " + Phrase.build(Phrase.LOOKUP_VIEW_PAGE, Color.WHITE, "/co l <page>") + "\n";
|
||||
result = result + pageInfo;
|
||||
result.add(Color.WHITE + "-----");
|
||||
result.add(Util.getPageNavigation(command, page, totalPages));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (rowMax > count && count > 0) {
|
||||
result = Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_RESULTS_PAGE, Selector.SECOND);
|
||||
result.add(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_RESULTS_PAGE, Selector.SECOND));
|
||||
}
|
||||
else {
|
||||
result = Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_DATA_LOCATION, Selector.SECOND);
|
||||
result.add(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_DATA_LOCATION, Selector.SECOND));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import net.coreprotect.config.ConfigHandler;
|
|||
import net.coreprotect.database.statement.UserStatement;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.language.Selector;
|
||||
import net.coreprotect.utility.Chat;
|
||||
import net.coreprotect.listener.channel.PluginChannelListener;
|
||||
import net.coreprotect.utility.Color;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
|
@ -55,7 +55,7 @@ public class InteractionLookup {
|
|||
checkTime = time - offset;
|
||||
}
|
||||
|
||||
String query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "block WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action='2' AND time >= '" + checkTime + "' LIMIT 0, 1";
|
||||
String query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "block " + Util.getWidIndex("block") + "WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action='2' AND time >= '" + checkTime + "' LIMIT 0, 1";
|
||||
ResultSet results = statement.executeQuery(query);
|
||||
|
||||
while (results.next()) {
|
||||
|
@ -64,7 +64,7 @@ public class InteractionLookup {
|
|||
results.close();
|
||||
int totalPages = (int) Math.ceil(count / (limit + 0.0));
|
||||
|
||||
query = "SELECT time,user,action,type,data,rolled_back FROM " + ConfigHandler.prefix + "block WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action='2' AND time >= '" + checkTime + "' ORDER BY rowid DESC LIMIT " + pageStart + ", " + limit + "";
|
||||
query = "SELECT time,user,action,type,data,rolled_back FROM " + ConfigHandler.prefix + "block " + Util.getWidIndex("block") + "WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action='2' AND time >= '" + checkTime + "' ORDER BY rowid DESC LIMIT " + pageStart + ", " + limit + "";
|
||||
results = statement.executeQuery(query);
|
||||
|
||||
StringBuilder resultBuilder = new StringBuilder();
|
||||
|
@ -73,7 +73,7 @@ public class InteractionLookup {
|
|||
int resultAction = results.getInt("action");
|
||||
int resultType = results.getInt("type");
|
||||
int resultData = results.getInt("data");
|
||||
int resultTime = results.getInt("time");
|
||||
long resultTime = results.getLong("time");
|
||||
int resultRolledBack = results.getInt("rolled_back");
|
||||
|
||||
if (ConfigHandler.playerIdCacheReversed.get(resultUserId) == null) {
|
||||
|
@ -89,7 +89,7 @@ public class InteractionLookup {
|
|||
found = true;
|
||||
|
||||
String rbFormat = "";
|
||||
if (resultRolledBack == 1) {
|
||||
if (resultRolledBack == 1 || resultRolledBack == 3) {
|
||||
rbFormat = Color.STRIKETHROUGH;
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,7 @@ public class InteractionLookup {
|
|||
}
|
||||
|
||||
resultBuilder.append(timeAgo + " " + Color.WHITE + "- ").append(Phrase.build(Phrase.LOOKUP_INTERACTION, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, Color.DARK_AQUA + rbFormat + target + Color.WHITE, Selector.FIRST)).append("\n");
|
||||
PluginChannelListener.getInstance().sendData(commandSender, resultTime, Phrase.LOOKUP_INTERACTION, Selector.FIRST, resultUser, target, -1, x, y, z, worldId, rbFormat, false, false);
|
||||
}
|
||||
result = resultBuilder.toString();
|
||||
results.close();
|
||||
|
@ -116,7 +117,7 @@ public class InteractionLookup {
|
|||
if (found) {
|
||||
if (count > limit) {
|
||||
String pageInfo = Color.WHITE + "-----\n";
|
||||
pageInfo = pageInfo + Util.getPageNavigation(command, page, totalPages) + "| " + Phrase.build(Phrase.LOOKUP_VIEW_PAGE, Color.WHITE, "/co l <page>") + "\n";
|
||||
pageInfo = pageInfo + Util.getPageNavigation(command, page, totalPages) + "\n";
|
||||
result = result + pageInfo;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import java.sql.ResultSet;
|
|||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
@ -12,11 +14,14 @@ import net.coreprotect.config.ConfigHandler;
|
|||
import net.coreprotect.database.statement.UserStatement;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.language.Selector;
|
||||
import net.coreprotect.listener.channel.PluginChannelListener;
|
||||
import net.coreprotect.utility.Color;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class SignMessageLookup {
|
||||
|
||||
static Pattern pattern = Pattern.compile("§x(§[a-fA-F0-9]){6}");
|
||||
|
||||
public static List<String> performLookup(String command, Statement statement, Location l, CommandSender commandSender, int page, int limit) {
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
|
@ -44,13 +49,13 @@ public class SignMessageLookup {
|
|||
int x = l.getBlockX();
|
||||
int y = l.getBlockY();
|
||||
int z = l.getBlockZ();
|
||||
int time = (int) (System.currentTimeMillis() / 1000L);
|
||||
long time = (System.currentTimeMillis() / 1000L);
|
||||
int worldId = Util.getWorldId(l.getWorld().getName());
|
||||
int count = 0;
|
||||
int rowMax = page * limit;
|
||||
int pageStart = rowMax - limit;
|
||||
|
||||
String query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "sign WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action = '1' AND (LENGTH(line_1) > 0 OR LENGTH(line_2) > 0 OR LENGTH(line_3) > 0 OR LENGTH(line_4) > 0) LIMIT 0, 1";
|
||||
String query = "SELECT COUNT(*) as count from " + ConfigHandler.prefix + "sign " + Util.getWidIndex("sign") + "WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action = '1' AND (LENGTH(line_1) > 0 OR LENGTH(line_2) > 0 OR LENGTH(line_3) > 0 OR LENGTH(line_4) > 0 OR LENGTH(line_5) > 0 OR LENGTH(line_6) > 0 OR LENGTH(line_7) > 0 OR LENGTH(line_8) > 0) LIMIT 0, 1";
|
||||
ResultSet results = statement.executeQuery(query);
|
||||
|
||||
while (results.next()) {
|
||||
|
@ -60,42 +65,79 @@ public class SignMessageLookup {
|
|||
|
||||
int totalPages = (int) Math.ceil(count / (limit + 0.0));
|
||||
|
||||
query = "SELECT time,user,line_1,line_2,line_3,line_4 FROM " + ConfigHandler.prefix + "sign WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action = '1' AND (LENGTH(line_1) > 0 OR LENGTH(line_2) > 0 OR LENGTH(line_3) > 0 OR LENGTH(line_4) > 0) ORDER BY rowid DESC LIMIT " + pageStart + ", " + limit + "";
|
||||
query = "SELECT time,user,face,line_1,line_2,line_3,line_4,line_5,line_6,line_7,line_8 FROM " + ConfigHandler.prefix + "sign " + Util.getWidIndex("sign") + "WHERE wid = '" + worldId + "' AND x = '" + x + "' AND z = '" + z + "' AND y = '" + y + "' AND action = '1' AND (LENGTH(line_1) > 0 OR LENGTH(line_2) > 0 OR LENGTH(line_3) > 0 OR LENGTH(line_4) > 0 OR LENGTH(line_5) > 0 OR LENGTH(line_6) > 0 OR LENGTH(line_7) > 0 OR LENGTH(line_8) > 0) ORDER BY rowid DESC LIMIT " + pageStart + ", " + limit + "";
|
||||
results = statement.executeQuery(query);
|
||||
|
||||
while (results.next()) {
|
||||
int resultTime = results.getInt("time");
|
||||
long resultTime = results.getLong("time");
|
||||
int resultUserId = results.getInt("user");
|
||||
String line1 = results.getString("line_1");
|
||||
String line2 = results.getString("line_2");
|
||||
String line3 = results.getString("line_3");
|
||||
String line4 = results.getString("line_4");
|
||||
String line5 = results.getString("line_5");
|
||||
String line6 = results.getString("line_6");
|
||||
String line7 = results.getString("line_7");
|
||||
String line8 = results.getString("line_8");
|
||||
boolean isFront = results.getInt("face") == 0;
|
||||
|
||||
StringBuilder message = new StringBuilder();
|
||||
if (line1 != null && line1.length() > 0) {
|
||||
if (isFront && line1 != null && line1.length() > 0) {
|
||||
message.append(line1);
|
||||
if (!line1.endsWith(" ")) {
|
||||
message.append(" ");
|
||||
}
|
||||
}
|
||||
if (line2 != null && line2.length() > 0) {
|
||||
if (isFront && line2 != null && line2.length() > 0) {
|
||||
message.append(line2);
|
||||
if (!line2.endsWith(" ")) {
|
||||
message.append(" ");
|
||||
}
|
||||
}
|
||||
if (line3 != null && line3.length() > 0) {
|
||||
if (isFront && line3 != null && line3.length() > 0) {
|
||||
message.append(line3);
|
||||
if (!line3.endsWith(" ")) {
|
||||
message.append(" ");
|
||||
}
|
||||
}
|
||||
if (line4 != null && line4.length() > 0) {
|
||||
if (isFront && line4 != null && line4.length() > 0) {
|
||||
message.append(line4);
|
||||
if (!line4.endsWith(" ")) {
|
||||
message.append(" ");
|
||||
}
|
||||
}
|
||||
if (!isFront && line5 != null && line5.length() > 0) {
|
||||
message.append(line5);
|
||||
if (!line5.endsWith(" ")) {
|
||||
message.append(" ");
|
||||
}
|
||||
}
|
||||
if (!isFront && line6 != null && line6.length() > 0) {
|
||||
message.append(line6);
|
||||
if (!line6.endsWith(" ")) {
|
||||
message.append(" ");
|
||||
}
|
||||
}
|
||||
if (!isFront && line7 != null && line7.length() > 0) {
|
||||
message.append(line7);
|
||||
if (!line7.endsWith(" ")) {
|
||||
message.append(" ");
|
||||
}
|
||||
}
|
||||
if (!isFront && line8 != null && line8.length() > 0) {
|
||||
message.append(line8);
|
||||
if (!line8.endsWith(" ")) {
|
||||
message.append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
String parsedMessage = message.toString();
|
||||
if (parsedMessage.contains("§x")) {
|
||||
for (Matcher matcher = pattern.matcher(parsedMessage); matcher.find(); matcher = pattern.matcher(parsedMessage)) {
|
||||
String color = parsedMessage.substring(matcher.start(), matcher.end());
|
||||
parsedMessage = parsedMessage.replace(color, "");
|
||||
}
|
||||
}
|
||||
|
||||
if (ConfigHandler.playerIdCacheReversed.get(resultUserId) == null) {
|
||||
UserStatement.loadName(statement.getConnection(), resultUserId);
|
||||
|
@ -108,14 +150,15 @@ public class SignMessageLookup {
|
|||
result.add(new StringBuilder(Color.WHITE + "----- " + Color.DARK_AQUA + Phrase.build(Phrase.SIGN_HEADER) + Color.WHITE + " ----- " + Util.getCoordinates(command, worldId, x, y, z, false, false) + "").toString());
|
||||
}
|
||||
found = true;
|
||||
result.add(timeAgo + Color.WHITE + " - " + Color.DARK_AQUA + resultUser + ": " + Color.WHITE + "\n" + message.toString() + Color.WHITE);
|
||||
result.add(timeAgo + Color.WHITE + " - " + Color.DARK_AQUA + resultUser + ": " + Color.WHITE + "\n" + parsedMessage + Color.WHITE);
|
||||
PluginChannelListener.getInstance().sendMessageData(commandSender, resultTime, resultUser, message.toString(), true, x, y, z, worldId);
|
||||
}
|
||||
results.close();
|
||||
|
||||
if (found) {
|
||||
if (count > limit) {
|
||||
result.add(Color.WHITE + "-----");
|
||||
result.add(Util.getPageNavigation(command, page, totalPages) + "| " + Phrase.build(Phrase.LOOKUP_VIEW_PAGE, Color.WHITE, "/co l <page>"));
|
||||
result.add(Util.getPageNavigation(command, page, totalPages));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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) {
|
||||
|
|
|
@ -23,6 +23,7 @@ public class ItemStatement {
|
|||
preparedStmt.setObject(8, byteData);
|
||||
preparedStmt.setInt(9, amount);
|
||||
preparedStmt.setInt(10, action);
|
||||
preparedStmt.setInt(11, 0); // rolled_back
|
||||
preparedStmt.addBatch();
|
||||
|
||||
if (batchCount > 0 && batchCount % 1000 == 0) {
|
||||
|
|
|
@ -4,12 +4,11 @@ import java.sql.PreparedStatement;
|
|||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Sign;
|
||||
|
||||
import net.coreprotect.bukkit.BukkitAdapter;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class SignStatement {
|
||||
|
||||
|
@ -17,7 +16,7 @@ public class SignStatement {
|
|||
throw new IllegalStateException("Database class");
|
||||
}
|
||||
|
||||
public static void insert(PreparedStatement preparedStmt, int batchCount, int time, int id, int wid, int x, int y, int z, int action, int color, int data, String line1, String line2, String line3, String line4) {
|
||||
public static void insert(PreparedStatement preparedStmt, int batchCount, int time, int id, int wid, int x, int y, int z, int action, int color, int colorSecondary, int data, int waxed, int face, String line1, String line2, String line3, String line4, String line5, String line6, String line7, String line8) {
|
||||
try {
|
||||
preparedStmt.setInt(1, time);
|
||||
preparedStmt.setInt(2, id);
|
||||
|
@ -27,11 +26,18 @@ public class SignStatement {
|
|||
preparedStmt.setInt(6, z);
|
||||
preparedStmt.setInt(7, action);
|
||||
preparedStmt.setInt(8, color);
|
||||
preparedStmt.setInt(9, data);
|
||||
preparedStmt.setString(10, line1);
|
||||
preparedStmt.setString(11, line2);
|
||||
preparedStmt.setString(12, line3);
|
||||
preparedStmt.setString(13, line4);
|
||||
preparedStmt.setInt(9, colorSecondary);
|
||||
preparedStmt.setInt(10, data);
|
||||
preparedStmt.setInt(11, waxed);
|
||||
preparedStmt.setInt(12, face);
|
||||
preparedStmt.setString(13, line1);
|
||||
preparedStmt.setString(14, line2);
|
||||
preparedStmt.setString(15, line3);
|
||||
preparedStmt.setString(16, line4);
|
||||
preparedStmt.setString(17, line5);
|
||||
preparedStmt.setString(18, line6);
|
||||
preparedStmt.setString(19, line7);
|
||||
preparedStmt.setString(20, line8);
|
||||
preparedStmt.addBatch();
|
||||
|
||||
if (batchCount > 0 && batchCount % 1000 == 0) {
|
||||
|
@ -54,24 +60,39 @@ public class SignStatement {
|
|||
|
||||
while (resultSet.next()) {
|
||||
int color = resultSet.getInt("color");
|
||||
int colorSecondary = resultSet.getInt("color_secondary");
|
||||
int data = resultSet.getInt("data");
|
||||
boolean isWaxed = resultSet.getInt("waxed") == 1;
|
||||
// boolean isFront = resultSet.getInt("face") == 0;
|
||||
String line1 = resultSet.getString("line_1");
|
||||
String line2 = resultSet.getString("line_2");
|
||||
String line3 = resultSet.getString("line_3");
|
||||
String line4 = resultSet.getString("line_4");
|
||||
String line5 = resultSet.getString("line_5");
|
||||
String line6 = resultSet.getString("line_6");
|
||||
String line7 = resultSet.getString("line_7");
|
||||
String line8 = resultSet.getString("line_8");
|
||||
|
||||
if (color > 0) {
|
||||
sign.setColor(DyeColor.getByColor(Color.fromRGB(color)));
|
||||
BukkitAdapter.ADAPTER.setColor(sign, true, color);
|
||||
}
|
||||
if (colorSecondary > 0) {
|
||||
BukkitAdapter.ADAPTER.setColor(sign, false, colorSecondary);
|
||||
}
|
||||
|
||||
if (data > 0) {
|
||||
BukkitAdapter.ADAPTER.setGlowing(sign, (data == 1 ? true : false));
|
||||
}
|
||||
|
||||
sign.setLine(0, line1);
|
||||
sign.setLine(1, line2);
|
||||
sign.setLine(2, line3);
|
||||
sign.setLine(3, line4);
|
||||
boolean frontGlowing = Util.isSideGlowing(true, data);
|
||||
boolean backGlowing = Util.isSideGlowing(false, data);
|
||||
BukkitAdapter.ADAPTER.setGlowing(sign, true, frontGlowing);
|
||||
BukkitAdapter.ADAPTER.setGlowing(sign, false, backGlowing);
|
||||
BukkitAdapter.ADAPTER.setLine(sign, 0, line1);
|
||||
BukkitAdapter.ADAPTER.setLine(sign, 1, line2);
|
||||
BukkitAdapter.ADAPTER.setLine(sign, 2, line3);
|
||||
BukkitAdapter.ADAPTER.setLine(sign, 3, line4);
|
||||
BukkitAdapter.ADAPTER.setLine(sign, 4, line5);
|
||||
BukkitAdapter.ADAPTER.setLine(sign, 5, line6);
|
||||
BukkitAdapter.ADAPTER.setLine(sign, 6, line7);
|
||||
BukkitAdapter.ADAPTER.setLine(sign, 7, line8);
|
||||
BukkitAdapter.ADAPTER.setWaxed(sign, isWaxed);
|
||||
}
|
||||
|
||||
resultSet.close();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue