mirror of
https://github.com/PlayPro/CoreProtect.git
synced 2026-11-04 16:40:13 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf0e9cf661 | ||
|
|
71b673756f | ||
|
|
2f794d6398 | ||
|
|
f3a1d95b77 | ||
|
|
8c79b3a867 | ||
|
|
d87ecaee42 | ||
|
|
dc4e9f8d60 | ||
|
|
c145fca68c | ||
|
|
b0856b51a5 | ||
|
|
7386f4bd50 | ||
|
|
0f0ceccb7b | ||
|
|
893ce9af46 | ||
|
|
609990e344 | ||
|
|
38166fd381 | ||
|
|
2979af360c | ||
|
|
0712545345 | ||
|
|
d3091f9401 | ||
|
|
de5a064c8d | ||
|
|
1f60dcc3cf | ||
|
|
5276dc57d2 | ||
|
|
49c0f16934 | ||
|
|
322c630af4 | ||
|
|
251b4c56cd | ||
|
|
9de1d16836 | ||
|
|
f5109122ac | ||
|
|
4a8dd716f4 | ||
|
|
6572946b3d | ||
|
|
51d4bf27cd | ||
|
|
d30f6cf8d5 | ||
|
|
f96556a61f | ||
|
|
813fee1017 | ||
|
|
3b58f69263 | ||
|
|
3158fe5268 | ||
|
|
150bd4b0ce | ||
|
|
5ee33c7790 | ||
|
|
d49a8bee73 | ||
|
|
abb0ece3e5 | ||
|
|
8b3e37774a | ||
|
|
6155d4e864 | ||
|
|
252de2f233 | ||
|
|
cec40e384c | ||
|
|
86d164e4b0 | ||
|
|
b3abb70744 | ||
|
|
2373a9c19f | ||
|
|
105d14f11f | ||
|
|
942430c11c | ||
|
|
dcb0864013 | ||
|
|
a4ffbb642c |
No files matched your search
+3
-1
@@ -3,6 +3,8 @@ daysUntilClose: 7
|
||||
exemptLabels:
|
||||
- 'accepted'
|
||||
- 'bug'
|
||||
- 'confirmed bug (tested)'
|
||||
- 'potential bug (needs testing)'
|
||||
- 'suggestion'
|
||||
- 'help wanted'
|
||||
staleLabel: stale
|
||||
@@ -10,4 +12,4 @@ markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
closeComment: false
|
||||
closeComment: false
|
||||
@@ -13,16 +13,11 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
- name: Set up JDK 21
|
||||
- name: Set up JDK 25
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '21'
|
||||
java-version: '25'
|
||||
distribution: 'temurin'
|
||||
- name: Cache Maven packages
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.m2
|
||||
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-m2
|
||||
cache: 'maven'
|
||||
- name: Build
|
||||
run: mvn -B verify
|
||||
@@ -18,7 +18,7 @@ For a detailed description of the plugin, please visit [coreprotect.net](https:/
|
||||
| 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.21: | [coreprotect.net/latest](https://coreprotect.net/latest/) |
|
||||
| Downloads for MC 1.14 - 26.1: | [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>23.0</version>
|
||||
<version>23.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
+3
-3
@@ -4,8 +4,8 @@ The CoreProtect API enables you to log your own block changes, perform lookups,
|
||||
|
||||
| API Details | |
|
||||
| --- | --- |
|
||||
| **API Version:** | 10 |
|
||||
| **Plugin Version:** | v22.4+ |
|
||||
| **API Version:** | 11 |
|
||||
| **Plugin Version:** | v23.1+ |
|
||||
| **Maven:** | [maven.playpro.com](https://maven.playpro.com) |
|
||||
|
||||
*Documentation for the API version 10 can be found [here](/api/version/v10/).*
|
||||
*Documentation for the API version 10 can be found [here](/api/version/v11/).*
|
||||
@@ -0,0 +1,530 @@
|
||||
# API Version 11
|
||||
|
||||
The CoreProtect API enables you to log your own block changes, perform lookups, rollbacks, restores, and more.
|
||||
|
||||
| API Details | |
|
||||
| --- | --- |
|
||||
| **API Version:** | 11 |
|
||||
| **Plugin Version:** | v23.1+ |
|
||||
| **Maven:** | [maven.playpro.com](https://maven.playpro.com) |
|
||||
|
||||
---
|
||||
|
||||
## Upgrading from API v10
|
||||
|
||||
The changes from the previous API version are as follows:
|
||||
|
||||
- The following event was extended to include Location (mutable):
|
||||
```java
|
||||
CoreProtectPreLogEvent(String user, Location location)
|
||||
```
|
||||
- The old constructor remains for backward compatibility and is deprecated:
|
||||
```java
|
||||
@Deprecated
|
||||
CoreProtectPreLogEvent(String user)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Started
|
||||
|
||||
Ensure you're using CoreProtect 23.1 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 (net.coreprotect, 23.1).
|
||||
|
||||
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() < 11) {
|
||||
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 |
|
||||
| Location | The location where the 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();
|
||||
```
|
||||
|
||||
---
|
||||
@@ -16,6 +16,7 @@ ___
|
||||
| [/co reload](#co-reload) | Reload the configuration file |
|
||||
| [/co status](#co-status) | View the plugin status |
|
||||
| [/co consumer](#co-consumer) | Toggle consumer processing |
|
||||
| [/co migrate-db](#co-migrate-db) | Migrate between SQLite and MySQL |
|
||||
|
||||
### Alias Commands
|
||||
|
||||
@@ -128,6 +129,19 @@ ___
|
||||
Console command to pause or resume consumer queue processing.
|
||||
___
|
||||
|
||||
### /co migrate-db
|
||||
Migrate your CoreProtect database between SQLite and MySQL. Console-only command.
|
||||
|
||||
| Command | Parameters |
|
||||
| --- | --- |
|
||||
| /co migrate-db | `<sqlite|mysql>` |
|
||||
|
||||
> **Note:** This feature is exclusive to CoreProtect 23.0+ Patreon builds for Patron supporters.
|
||||
|
||||
For complete migration instructions, safety guidelines, and troubleshooting information, see the [Database Migration documentation](/database-migration/).
|
||||
|
||||
___
|
||||
|
||||
|
||||
## Parameter Details
|
||||
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
# Database Migration (SQLite ↔ MySQL)
|
||||
|
||||
CoreProtect 23.0+ includes the ability to migrate your database between SQLite and MySQL without losing any data.
|
||||
|
||||
> **Note:** Database migration functionality is exclusive to CoreProtect 23.0+ Patreon builds for Patron supporters.
|
||||
|
||||
## Overview
|
||||
|
||||
The `/co migrate-db` command allows you to seamlessly transfer all your CoreProtect data from SQLite to MySQL or vice versa. This is particularly useful when:
|
||||
|
||||
* Starting with SQLite and wanting to upgrade to MySQL for better performance
|
||||
* Moving from MySQL back to SQLite for simpler server setups
|
||||
* Transferring data between different server configurations
|
||||
|
||||
## Command Usage
|
||||
|
||||
| Command | Parameters | Description |
|
||||
| --- | --- | --- |
|
||||
| `/co migrate-db` | `<sqlite|mysql>` | Migrate to the specified database type |
|
||||
|
||||
**Examples:**
|
||||
|
||||
* `/co migrate-db mysql` - Migrate from SQLite to MySQL
|
||||
* `/co migrate-db sqlite` - Migrate from MySQL to SQLite
|
||||
|
||||
> **Console Only:** This command can only be executed from the server console, not from in-game.
|
||||
|
||||
---
|
||||
|
||||
## Migration Process
|
||||
|
||||
### Step 1: Preparation
|
||||
|
||||
**Before starting the migration:**
|
||||
|
||||
1. Ensure your server is running with your current CoreProtect database
|
||||
2. Configure your new database in `config.yml` (ensure `use-mysql` is updated correctly)
|
||||
3. **Important:** Do NOT restart your server or use `/co reload` after modifying the config
|
||||
|
||||
### Step 2: Execute Migration
|
||||
|
||||
#### 1. **Run the migration command from your server console:**
|
||||
```
|
||||
co migrate-db <mysql|sqlite>
|
||||
```
|
||||
|
||||
#### 2. **Monitor the progress:**
|
||||
* The migration will display detailed progress information
|
||||
* Large databases may take considerable time to complete
|
||||
* Progress bars and speed indicators will show current status
|
||||
|
||||
#### 3. **Do not interrupt the process:**
|
||||
* Avoid restarting your server during migration
|
||||
* Let the process complete naturally
|
||||
|
||||
### Step 3: Post-Migration
|
||||
|
||||
**After successful completion:**
|
||||
|
||||
1. **Automatic switchover:** CoreProtect will automatically begin using the new database
|
||||
2. **Verify configuration:** Ensure `use-mysql` is set correctly in your `config.yml` as per step 1
|
||||
3. **Test functionality:** Perform basic CoreProtect operations to verify everything works
|
||||
4. **Clean up:** Once satisfied, you may manually delete your old database files
|
||||
|
||||
---
|
||||
|
||||
## Important Considerations
|
||||
|
||||
### Migration Safety
|
||||
|
||||
* **Non-destructive process:** The migration does not modify or delete your existing database
|
||||
* **Interrupted migration:** If something goes wrong, simply delete the new database and continue using the old one
|
||||
* **Data verification:** The process includes automatic verification to ensure data integrity
|
||||
|
||||
### Performance & Requirements
|
||||
|
||||
* **Processing time:** Large databases with millions of records may take hours to migrate
|
||||
* **Resource usage:** The migration process is resource-intensive and may impact server performance
|
||||
* **Parallel processing:** SQLite to MySQL migrations use optimized parallel processing for better speed
|
||||
|
||||
### Restrictions & Limitations
|
||||
|
||||
* **Console only:** Cannot be executed from in-game chat
|
||||
* **Interruption handling:** If interrupted, the target database must be manually wiped before restarting
|
||||
* **Patreon exclusive:** Only available in CoreProtect 23.0+ Patreon builds
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Migration won't start:**
|
||||
|
||||
* Verify you're using a CoreProtect 23.0+ Patreon build
|
||||
* Ensure you're not trying to migrate to the same database type
|
||||
* Check that no other CoreProtect operations are running
|
||||
|
||||
**Migration interrupted:**
|
||||
|
||||
* Manually delete/wipe the target database
|
||||
* Verify server stability before restarting migration
|
||||
* Consider migrating during low-activity periods
|
||||
|
||||
**Performance issues:**
|
||||
|
||||
* Monitor server resources during migration
|
||||
* Consider temporarily reducing server activity
|
||||
* Large tables may cause temporary slowdowns
|
||||
|
||||
**Data verification failures:**
|
||||
|
||||
* Check database connectivity and permissions
|
||||
* Review server logs for specific error messages
|
||||
* Ensure sufficient disk space on target database
|
||||
|
||||
### Getting Help
|
||||
|
||||
If you encounter issues with database migration:
|
||||
|
||||
1. Check server logs for detailed error messages
|
||||
2. Verify database permissions and connectivity
|
||||
3. Ensure adequate system resources (RAM, CPU, disk space)
|
||||
4. Contact support through the CoreProtect Discord with specific error details
|
||||
|
||||
---
|
||||
|
||||
## Technical Details
|
||||
|
||||
The migration process includes several advanced features:
|
||||
|
||||
* Batch processing with dynamic sizing based on performance
|
||||
* Automatic retry mechanisms for temporary failures
|
||||
* Data integrity verification comparing source and target records
|
||||
* Progress tracking with estimated completion times
|
||||
* Graceful error handling with detailed logging
|
||||
|
||||
The migration handles all CoreProtect data types including:
|
||||
|
||||
* Block changes and rollbacks
|
||||
* Container transactions
|
||||
* Player interactions and sessions
|
||||
* Chat messages and commands
|
||||
* User data and statistics
|
||||
* All metadata and configuration data
|
||||
@@ -18,6 +18,9 @@ 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.
|
||||
|
||||
[**Database Migration**](/database-migration/)
|
||||
Migrate your CoreProtect database between SQLite and MySQL.
|
||||
|
||||
[**Compatible Third-Party Plugins & Tools**](/tools-integrations/)
|
||||
A list of plugins and tools that are compatible with CoreProtect.
|
||||
|
||||
|
||||
@@ -46,6 +46,8 @@ The following permissions can be used to restrict functionality within the plugi
|
||||
|
||||
## Child Permissions
|
||||
|
||||
> **Note:** Child permissions are not presently supported by CoreProtect Hytale Edition.
|
||||
|
||||
* **coreprotect.lookup.block** *(default: op)*
|
||||
Can be optionally used as a negative permission to prevent block lookups.
|
||||
|
||||
|
||||
@@ -9,37 +9,113 @@ These plugins/tools are maintained by third parties, and may have issues outside
|
||||
## Plugins
|
||||
|
||||
* **WorldEdit**
|
||||
Use WorldEdit selections as a radius, and log your WorldEdit changes.
|
||||
Use WorldEdit selections as a radius, and log your WorldEdit changes.
|
||||
[https://dev.bukkit.org/projects/worldedit](https://dev.bukkit.org/projects/worldedit)
|
||||
|
||||
|
||||
* **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.
|
||||
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/)
|
||||
|
||||
|
||||
* **CoreProtect Time-Lapse**
|
||||
CPTL is an add-on tool for CoreProtect used to create a time-lapse from historical data.
|
||||
CPTL is an add-on tool for CoreProtect used to create a time-lapse from historical data.
|
||||
[https://modrinth.com/plugin/cptl](https://modrinth.com/plugin/cptl)
|
||||
|
||||
|
||||
* **LightUp**
|
||||
Conveniently place temporary lighting with rollback safety via CoreProtect integration.
|
||||
[https://modrinth.com/plugin/lightup](https://modrinth.com/plugin/lightup)
|
||||
|
||||
|
||||
* **Lumen**
|
||||
Custom (virtual) lighting with undo/redo and built-in CoreProtect & FAWE integration.
|
||||
[https://modrinth.com/plugin/lumen](https://modrinth.com/plugin/lumen)
|
||||
|
||||
|
||||
* **FRTrustSystem**
|
||||
Simple trust/friends system that uses the CoreProtect API to determine block ownership for protections/notifications.
|
||||
[https://modrinth.com/plugin/frtrustsystem](https://modrinth.com/plugin/frtrustsystem)
|
||||
|
||||
|
||||
* **Movecraft-CoreProtect**
|
||||
Logs Movecraft “craft” movement into CoreProtect for auditing/rollback.
|
||||
[https://hangar.papermc.io/Airship-Pirates/Movecraft-CoreProtect](https://hangar.papermc.io/Airship-Pirates/Movecraft-CoreProtect)
|
||||
|
||||
|
||||
* **M0-CoreCord**
|
||||
Discord bridge for CoreProtect lookups and alerts (SQLite/MySQL supported).
|
||||
[https://www.spigotmc.org/resources/m0-corecord-1-13-1-21-8.91863/](https://www.spigotmc.org/resources/m0-corecord-1-13-1-21-8.91863/)
|
||||
|
||||
|
||||
* **XRayHunter**
|
||||
Hunt potential xrayers by analyzing ore-mining stats pulled from CoreProtect data.
|
||||
[https://modrinth.com/plugin/xrayhunter](https://modrinth.com/plugin/xrayhunter)
|
||||
|
||||
|
||||
* **ShadowTrace (Server Plugin)**
|
||||
Backend for the ShadowTrace client mod; queries CoreProtect to visualize players’ mined blocks in-game.
|
||||
[https://modrinth.com/plugin/shadowtraceplugin](https://modrinth.com/plugin/shadowtraceplugin)
|
||||
|
||||
|
||||
* **WildInspect**
|
||||
Custom inspect-mode powered by CoreProtect (with history/claim limits and more).
|
||||
[https://www.spigotmc.org/resources/%E2%9A%A1%EF%B8%8F-wildinspect-%E2%9A%A1%EF%B8%8F-coreprotect-addon-history-limits-claim-limits-%E2%9A%A1%EF%B8%8F-1-21-5-support.87405/](https://www.spigotmc.org/resources/%E2%9A%A1%EF%B8%8F-wildinspect-%E2%9A%A1%EF%B8%8F-coreprotect-addon-history-limits-claim-limits-%E2%9A%A1%EF%B8%8F-1-21-5-support.87405/)
|
||||
|
||||
|
||||
* **ExplosionProtector**
|
||||
Uses the CoreProtect API to prevent explosions from destroying player-placed blocks.
|
||||
[https://www.spigotmc.org/resources/explosionprotector.124838/](https://www.spigotmc.org/resources/explosionprotector.124838/)
|
||||
|
||||
|
||||
* **Axiom Paper Plugin**
|
||||
Server component for the Axiom editor; includes CoreProtect integration to log Axiom edits.
|
||||
[https://modrinth.com/plugin/axiom-paper-plugin](https://modrinth.com/plugin/axiom-paper-plugin)
|
||||
|
||||
|
||||
* **BlocksHub**
|
||||
Bridge API used by world-editing plugins (e.g., AWE/FAWE) to send edits to loggers like CoreProtect.
|
||||
[https://www.spigotmc.org/resources/blockshub.331/](https://www.spigotmc.org/resources/blockshub.331/)
|
||||
|
||||
|
||||
* **SpitSTIK**
|
||||
Fun projectile plugin with CoreProtect integration for item-frame logging.
|
||||
[https://modrinth.com/plugin/spitstik](https://modrinth.com/plugin/spitstik)
|
||||
|
||||
|
||||
* **XRay Informer**
|
||||
Ore-ratio checker that supports CoreProtect. *(last known MC: 1.12)*
|
||||
[https://dev.bukkit.org/projects/xray-informer](https://dev.bukkit.org/projects/xray-informer)
|
||||
|
||||
|
||||
* **DesirePaths**
|
||||
Logs automatically generated paths into CoreProtect for moderation/rollback.
|
||||
[https://www.spigotmc.org/resources/desirepaths-dynamic-player-made-trails.109043/](https://www.spigotmc.org/resources/desirepaths-dynamic-player-made-trails.109043/)
|
||||
|
||||
|
||||
|
||||
## Tools
|
||||
|
||||
* **CoreProtect Lookup Web Interface**
|
||||
Search through your CoreProtect history with an easy-to-use interface.
|
||||
Search through your CoreProtect history with an easy-to-use web UI.
|
||||
[https://www.spigotmc.org/resources/coreprotect-lookup-web-interface.28033/](https://www.spigotmc.org/resources/coreprotect-lookup-web-interface.28033/)
|
||||
|
||||
|
||||
* **Watson**
|
||||
Watson is a client side Minecraft mod that displays CoreProtect logs in 3D.
|
||||
Client-side mod that displays CoreProtect logs in 3D (optional server helper plugin available).
|
||||
[https://github.com/vacla/Watson](https://github.com/vacla/Watson)
|
||||
|
||||
|
||||
* **ShadowTrace (Client Mod)**
|
||||
Client-side visualizer to view mined-block locations supplied by the ShadowTrace server plugin via CoreProtect.
|
||||
[https://modrinth.com/mod/shadowtrace](https://modrinth.com/mod/shadowtrace)
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
+54
-47
@@ -6,25 +6,26 @@ AMOUNT_CHUNK: "{0} {Chunk|Chunks}"
|
||||
AMOUNT_ENTITY: "{0} {Entität|Entitäten}"
|
||||
AMOUNT_ITEM: "{0} {Item|Items}"
|
||||
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."
|
||||
CACHE_ERROR: "WARNUNG: Fehler beim Überprüfen des {0}-Zwischenspeichers."
|
||||
CACHE_RELOAD: "Erzwingen des Nachladens von {Kartierungs|Welt}caches aus der Datenbank."
|
||||
CHECK_CONFIG: "Bitte überprüfe die 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}."
|
||||
CONSUMER_ERROR: "Die Verarbeitung der Verbraucherwarteschlange wurde bereits {angehalten|fortgesetzt}."
|
||||
CONSUMER_TOGGLED: "Die Verarbeitung der Verbraucherwarteschlange wurde {angehalten|fortgesetzt}."
|
||||
CONTAINER_HEADER: "Containertransaktionen"
|
||||
CPU_CORES: "CPU-Kerne."
|
||||
DATABASE_BUSY: "Datenbank beschäftigt. Bitte versuchen Sie es später erneut."
|
||||
DATABASE_INDEX_ERROR: "Datenbankindizes können nicht validiert werden."
|
||||
DATABASE_INDEX_ERROR: "Datenbankindizes können nicht geprüft werden."
|
||||
DATABASE_LOCKED_1: "Datenbank gesperrt. Warte bis zu 15 Sekunden..."
|
||||
DATABASE_LOCKED_2: "Datenbank wird bereits verwendet. Bitte versuche es später erneut."
|
||||
DATABASE_LOCKED_3: "Um die Datenbanksperre zu deaktivieren, setzen Sie \"database-lock: false\"."
|
||||
DATABASE_LOCKED_4: "Das Deaktivieren der Datenbanksperre kann zu Datenbeschädigungen führen."
|
||||
DATABASE_LOCKED_4: "Deaktivieren der Datenbanksperre kann zu Datenbeschädigungen führen."
|
||||
DATABASE_UNREACHABLE: "Datenbank ist nicht erreichbar. Daten verwerfen und herunterfahren."
|
||||
DEVELOPMENT_BRANCH: "Entwicklungszweig erkannt, Patch-Skripte werden übersprungen."
|
||||
DIRT_BLOCK: "Platziere einen Schmutzblock unter dir."
|
||||
DISABLE_SUCCESS: "Erfolg! Deaktiviert {0}"
|
||||
DIRT_BLOCK: "Ein temporärer Sicherheitsblock wurde unter ihnen platziert."
|
||||
DISABLE_SUCCESS: "{0} erfolgreich deaktiviert!"
|
||||
ENABLE_FAILED: "{0} war nicht in der Lage zu starten."
|
||||
ENABLE_SUCCESS: "{0} ist jetzt aktiviert!"
|
||||
ENJOY_COREPROTECT: "Dir gefällt {0}? Tritt unserem Discord bei!"
|
||||
@@ -32,11 +33,11 @@ FINISHING_CONVERSION: "Abschluss der Datenkonvertierung. Bitte warten..."
|
||||
FINISHING_LOGGING: "Abschluss der Datenprotokollierung. Bitte warten..."
|
||||
FIRST_VERSION: "Anfangs-DB: {0}"
|
||||
GLOBAL_LOOKUP: "Geben Sie keinen Radius an, um eine globale Suche durchzuführen."
|
||||
GLOBAL_ROLLBACK: "Benutze \"{0}\" um einen globalen {Rollback|Restore}"
|
||||
GLOBAL_ROLLBACK: "Benutze \"{0}\" für einen globalen {Rollback|Restore}"
|
||||
HELP_ACTION_1: "Beschränken Sie die Suche auf eine Aktion."
|
||||
HELP_ACTION_2: "Beispiele: [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: "Zusätzliche Informationen anzeigen."
|
||||
HELP_EXCLUDE_1: "Blöcke/Benutzer ausschließen."
|
||||
HELP_EXCLUDE_1: "Bestimmte Blöcke/Benutzer ausschließen."
|
||||
HELP_EXCLUDE_2: "Beispiele: [e:stone], [e:Notch], [e:stone,Notch]"
|
||||
HELP_HEADER: "{0} Hilfe"
|
||||
HELP_INCLUDE_1: "Fügen Sie Blöcke/Entitäten ein."
|
||||
@@ -73,19 +74,19 @@ HELP_ROLLBACK_COMMAND: "Rollback-Blockdaten."
|
||||
HELP_STATUS: "Sehen Sie sich den Plugin-Status an."
|
||||
HELP_STATUS_COMMAND: "Zeigt den Plugin-Status an."
|
||||
HELP_TELEPORT: "Teleportieren."
|
||||
HELP_TIME_1: "Geben Sie die Uhrzeit an."
|
||||
HELP_TIME_1: "Geben Sie einen Zeitraum an."
|
||||
HELP_TIME_2: "Beispiele: [t:2w,5d,7h,2m,10s], [t:5d2h], [t:2.50h]"
|
||||
HELP_USER_1: "Geben Sie die Benutzer an."
|
||||
HELP_USER_1: "Geben Sie den/die Benutzer an."
|
||||
HELP_USER_2: "Beispiele: [u:Notch], [u:Notch,#enderman]"
|
||||
INCOMPATIBLE_ACTION: "\"{0}\" kann mit dieser Aktion nicht verwendet werden."
|
||||
INSPECTOR_ERROR: "Inspektor bereits {aktiviert|deaktiviert}."
|
||||
INSPECTOR_TOGGLED: "Inspektor jetzt {aktiviert|deaktiviert}."
|
||||
INTEGRATION_ERROR: "Unfähig zu {initialisieren|deaktivieren} {0} Protokollierung."
|
||||
INTEGRATION_SUCCESS: "{0} erfolgreich anmelden {initialisiert|deaktiviert}."
|
||||
INTEGRATION_VERSION: "Ungültig {0} Version gefunden."
|
||||
INTEGRATION_ERROR: "Unfähig, {0} Protokollierung zu {initialisieren|deaktivieren}."
|
||||
INTEGRATION_SUCCESS: "{0} Protokollierung erfolgreich {initialisiert|deaktiviert}."
|
||||
INTEGRATION_VERSION: "Ungültige {0} Version gefunden."
|
||||
INTERACTIONS_HEADER: "Spielerinteraktionen"
|
||||
INVALID_ACTION: "Das ist keine gültige Aktion."
|
||||
INVALID_BRANCH_1: "Ungültige Plugin-Version (Verzweigung wurde nicht gesetzt)."
|
||||
INVALID_BRANCH_1: "Ungültige Plugin-Version (Branch wurde nicht gesetzt)."
|
||||
INVALID_BRANCH_2: "Um fortzufahren, setzen Sie den Projektzweig auf \"Entwicklung\"."
|
||||
INVALID_BRANCH_3: "Das Ausführen von Entwicklungscode kann zu Datenbeschädigungen führen."
|
||||
INVALID_CONTAINER: "Bitte überprüfen Sie zuerst einen gültigen Behälter."
|
||||
@@ -102,7 +103,7 @@ LINK_DOWNLOAD: "Herunterladen: {0}"
|
||||
LINK_PATREON: "Patreon: {0}"
|
||||
LINK_WIKI_BLOCK: "Blocknamen: {0}"
|
||||
LINK_WIKI_ENTITY: "Entitätsnamen: {0}"
|
||||
LOGGING_ITEMS: "{0} Elemente, die noch zu loggen sind. Warten Sie mal..."
|
||||
LOGGING_ITEMS: "{0} Elemente, die noch zu loggen sind. Bitte warten..."
|
||||
LOGGING_TIME_LIMIT: "Zeitlimit für die Protokollierung erreicht. Daten verwerfen und herunterfahren."
|
||||
LOOKUP_BLOCK: "{0} {platziert|entfernt} {1}."
|
||||
LOOKUP_CONTAINER: "{0} {hinzugefügt|entfernt} {1} {2}."
|
||||
@@ -113,58 +114,62 @@ LOOKUP_LOGIN: "{0} {ein|aus}geloggt."
|
||||
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_SEARCHING: "Suchen. Bitte warten..."
|
||||
LOOKUP_STORAGE: "{0} {hinterlegt|abgehoben} {1} {2}."
|
||||
LOOKUP_TIME: "vor {0}"
|
||||
LOOKUP_USERNAME: "{0} Eingeloggt als {1}."
|
||||
MAXIMUM_RADIUS: "Das Maximum {Nachschlagen|Rollback|Wiederherstellen} Radius ist {0}."
|
||||
LOOKUP_USERNAME: "{0} eingeloggt als {1}."
|
||||
MAXIMUM_RADIUS: "Der maximale {Nachschlag|Rollback|Restore} 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}."
|
||||
MISSING_LOOKUP_USER: "Bitte geben Sie einen Benutzer an oder {Block|Radius}."
|
||||
MISSING_LOOKUP_TIME: "Bitte geben Sie den Zeitraum an, um {Nachzuschlagen|ein Rollback auszuführen|einen Restore auszuführen}."
|
||||
MISSING_LOOKUP_USER: "Bitte geben Sie einen Benutzer oder {Block|Radius} an."
|
||||
MISSING_PARAMETERS: "Bitte verwenden Sie \"{0}\"."
|
||||
MISSING_ROLLBACK_RADIUS: "Sie haben nicht angegeben a {Zurücksetzen|Wiederherstellen} Radius."
|
||||
MISSING_ROLLBACK_USER: "Sie haben nicht angegeben a {Zurücksetzen|Wiederherstellen} Benutzer."
|
||||
MYSQL_UNAVAILABLE: "Verbindung zu nicht möglich MySQL Server."
|
||||
NO_DATA: "Keine Daten gefunden bei {0}."
|
||||
MISSING_ROLLBACK_RADIUS: "Sie haben keinen {Rollback|Restore} Radius angegeben."
|
||||
MISSING_ROLLBACK_USER: "Sie haben keinen {Rollback|Restore} Benutzer angegeben."
|
||||
MYSQL_UNAVAILABLE: "Verbindung zu MySQL Server nicht möglich."
|
||||
NETWORK_CONNECTION: "Verbindung von {0} {erfolgreich|fehlgeschlagen}. Nutze {1} {2}."
|
||||
NETWORK_TEST: "Netzwerktestdaten wurden erfolgreich gesendet."
|
||||
NO_DATA: "Keine Daten bei {0} gefunden."
|
||||
NO_DATA_LOCATION: "Keine {Daten|Transaktionen|Interaktionen|Nachrichten} gefunden."
|
||||
NO_PERMISSION: "Du hast keine Erlaubnis das zu tun."
|
||||
NO_RESULTS: "Keine Ergebnisse gefunden."
|
||||
NO_RESULTS_PAGE: "Keine {Ergebnisse|Daten} für diese Seite gefunden."
|
||||
NO_ROLLBACK: "Nein {ausstehend|zurück} Rollback/Wiederherstellung gefunden."
|
||||
PATCH_INTERRUPTED: "Upgrade unterbrochen. Werde es beim Neustart nochmal versuchen."
|
||||
PATCH_OUTDATED_1: "Datenbanken, die älter als sind, können nicht aktualisiert werden {0}."
|
||||
PATCH_OUTDATED_2: "Bitte aktualisieren Sie mit einer unterstützten Version von CoreProtect."
|
||||
PATCH_PROCESSING: "Verarbeitung neuer Daten. Warten Sie mal..."
|
||||
PATCH_SKIP_UPDATE: "Überspringen {Tabelle|Index} {Aktualisieren|Erstellen|Entfernen} auf {0}."
|
||||
PATCH_STARTED: "Performing {0} Aktualisierung. Warten Sie mal..."
|
||||
NO_ROLLBACK: "Kein(en) {ausstehende(s|n)|vorherige(s|n)} Rollback/Restore gefunden."
|
||||
PATCH_INTERRUPTED: "Upgrade unterbrochen. Wird bei einem Neustart erneut versucht."
|
||||
PATCH_OUTDATED_1: "Datenbanken, die älter als {0} sind, können nicht aktualisiert werden."
|
||||
PATCH_OUTDATED_2: "Bitte updaten Sie mit einer unterstützten Version von CoreProtect."
|
||||
PATCH_PROCESSING: "Neue Daten werden verarbeitet. Bitte warten..."
|
||||
PATCH_SKIP_UPDATE: "Überspringe {Tabellen|Index}{aktualisierung|erstellung|entfernung} bei {0}."
|
||||
PATCH_STARTED: "Führe {0} Upgrade durch. Bitte warten..."
|
||||
PATCH_SUCCESS: "Erfolgreich aktualisiert auf {0}."
|
||||
PATCH_UPGRADING: "Datenbank-Upgrade im Gange. Warten Sie mal..."
|
||||
PATCH_UPGRADING: "Datenbank-Upgrade im Gange. Bitte warten..."
|
||||
PLEASE_SELECT: "Bitte auswählen: \"{0}\" oder \"{1}\"."
|
||||
PREVIEW_CANCELLED: "Vorschau abgebrochen."
|
||||
PREVIEW_CANCELLING: "Vorschau abbrechen..."
|
||||
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."
|
||||
PREVIEW_IN_GAME: "Sie können Rollbacks nur im Spiel als Vorschau anzeigen."
|
||||
PREVIEW_TRANSACTION: "Sie können keine {Behälter|Inventar}-Transaktionen als Vorschau anzeigen."
|
||||
PRIMARY_THREAD_ERROR: "Diese API-Methode kann nicht im Haupt-Thread verwendet werden."
|
||||
PURGE_ABORTED: "Bereinigung fehlgeschlagen. Die Datenbank ist möglicherweise beschädigt."
|
||||
PURGE_ERROR: "Kann nicht verarbeitet werden {0} Daten!"
|
||||
PURGE_ERROR: "{0} Daten können nicht verarbeitet werden!"
|
||||
PURGE_FAILED: "Bereinigung fehlgeschlagen. Bitte versuchen Sie es später erneut."
|
||||
PURGE_IN_PROGRESS: "Bereinigung läuft. Bitte versuchen Sie es später erneut."
|
||||
PURGE_MINIMUM_TIME: "Sie können nur Daten löschen, die älter sind als {0} {Tage|Stunden}."
|
||||
PURGE_MINIMUM_TIME: "Sie können nur Daten löschen, die älter als {0} {Tage|Stunden} sind."
|
||||
PURGE_NOTICE_1: "Bitte beachten Sie, dass dies einige Zeit dauern kann."
|
||||
PURGE_NOTICE_2: "Starten Sie Ihren Server nicht neu, bis dies abgeschlossen ist."
|
||||
PURGE_OPTIMIZING: "Optimierung der Datenbank. Warten Sie mal..."
|
||||
PURGE_PROCESSING: "wird bearbeitet {0} Daten..."
|
||||
PURGE_OPTIMIZING: "Optimierung der Datenbank. Bitte warten..."
|
||||
PURGE_PROCESSING: "{0} Daten werden verarbeitet..."
|
||||
PURGE_REPAIRING: "Versuch einer Reparatur. Dies könnte eine Weile dauern..."
|
||||
PURGE_ROWS: "{0} {Reihe|Reihen} von Daten gelöscht."
|
||||
PURGE_STARTED: "Datenbereinigung gestartet am \"{0}\"."
|
||||
PURGE_SUCCESS: "Datenbereinigung erfolgreich."
|
||||
RAM_STATS: "{0}GB / {1}GB RAM"
|
||||
RELOAD_STARTED: "Konfiguration wird neu geladen - bitte warten."
|
||||
RELOAD_SUCCESS: "Konfiguration erfolgreich neu geladen."
|
||||
ROLLBACK_ABORTED: "Rollback oder Wiederherstellung abgebrochen."
|
||||
ROLLBACK_ABORTED: "Rollback oder Restore abgebrochen."
|
||||
ROLLBACK_CHUNKS_FOUND: "{0} {bearbeiteter|bearbeitete} {Chunk|Chunks} gefunden."
|
||||
ROLLBACK_CHUNKS_MODIFIED: "{0}/{1} {Chunk|Chunks} bearbeitet."
|
||||
ROLLBACK_COMPLETED: "{Rollback|Wiederherstellen|Vorschau} abgeschlossen für \"{0}\"."
|
||||
ROLLBACK_EXCLUDED_USERS: "Ausgeschlossen {Benutzer|Benutzer}: \"{0}\"."
|
||||
ROLLBACK_INCLUDE: "{Eingeschlossen|Ausgeschlossen} {Block|Entität|Ziel} {Typ|Typen}: \"{0}\"."
|
||||
ROLLBACK_COMPLETED: "{Rollback|Restore|Vorschau} für \"{0}\" abgeschlossen."
|
||||
ROLLBACK_EXCLUDED_USERS: "{Ausgeschlossener Benutzer|Ausgeschlossene Benutzer}: \"{0}\"."
|
||||
ROLLBACK_INCLUDE: "{Block|Entität|Ziel} {Typ|Typen} {einbezogen|ausgeschlossen}: \"{0}\"."
|
||||
ROLLBACK_IN_PROGRESS: "Ein Rollback/Restore ist bereits im Gange."
|
||||
ROLLBACK_LENGTH: "Zeit beansprucht: {0} {Sekunde|Sekunden}."
|
||||
ROLLBACK_MODIFIED: "{Modifiziert|Modifiziert} {0}."
|
||||
@@ -173,11 +178,12 @@ ROLLBACK_SELECTION: "Radius eingestellt auf \"{0}\"."
|
||||
ROLLBACK_STARTED: "{Rollback|Restore|Vorschau} gestartet für \"{0}\"."
|
||||
ROLLBACK_TIME: "Zeitspanne: {0}."
|
||||
ROLLBACK_WORLD_ACTION: "Beschränkt auf {Welt|Aktion} \"{0}\"."
|
||||
SIGN_HEADER: "Nachrichten signieren"
|
||||
SIGN_HEADER: "Schildnachrichten"
|
||||
STATUS_CONSUMER: "Warteschleife: {0} {Datensatz|Datensätze}"
|
||||
STATUS_DATABASE: "Datenbank: {0}."
|
||||
STATUS_INTEGRATION: "{0}: Integration {aktiviert|deaktiviert}."
|
||||
STATUS_LICENSE: "Lizenz: {0}"
|
||||
STATUS_SYSTEM: "System: {0}"
|
||||
STATUS_VERSION: "Version: {0}"
|
||||
TELEPORTED: "Teleportiert nach {0}."
|
||||
TELEPORTED_SAFETY: "Hab dich in Sicherheit teleportiert."
|
||||
@@ -186,16 +192,17 @@ TIME_DAYS: "{0} {Tag|Tage}"
|
||||
TIME_HOURS: "{0} {Stunde|Stunden}"
|
||||
TIME_MINUTES: "{0} {Minute|Minuten}"
|
||||
TIME_SECONDS: "{0} {Sekunde|Sekunden}"
|
||||
TIME_UNITS: "{/m|/h|/d}"
|
||||
TIME_WEEKS: "{0} {Woche|Wochen}"
|
||||
UPDATE_ERROR: "Beim Suchen nach Updates ist ein Fehler aufgetreten."
|
||||
UPDATE_HEADER: "{0} Aktualisieren"
|
||||
UPDATE_NOTICE: "Beachten: {0} ist nun verfügbar."
|
||||
UPDATE_NOTICE: "Hinweis: {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_NOTICE: "Version {0} ist nun verfügbar."
|
||||
VERSION_REQUIRED: "{0} {1} oder höher erforderlich."
|
||||
WORLD_NOT_FOUND: "Welt \"{0}\" nicht gefunden."
|
||||
@@ -194,6 +194,7 @@ TIME_HOURS: "{0} {hour|hours}"
|
||||
TIME_MINUTES: "{0} {minute|minutes}"
|
||||
TIME_MONTHS: "{0} {month|months}"
|
||||
TIME_SECONDS: "{0} {second|seconds}"
|
||||
TIME_UNITS: "{/m|/h|/d}"
|
||||
TIME_WEEKS: "{0} {week|weeks}"
|
||||
TIME_YEARS: "{0} {year|years}"
|
||||
UPDATE_ERROR: "An error occurred while checking for updates."
|
||||
|
||||
@@ -192,6 +192,7 @@ TIME_DAYS: "{0} {día|días}"
|
||||
TIME_HOURS: "{0} {hora|horas}"
|
||||
TIME_MINUTES: "{0} {minuto|minutos}"
|
||||
TIME_SECONDS: "{0} {segundo|segundos}"
|
||||
TIME_UNITS: "{/m|/h|/d}"
|
||||
TIME_WEEKS: "{0} {semana|semanas}"
|
||||
UPDATE_ERROR: "Un error ocurrió mientras se revisaban las actualizaciones."
|
||||
UPDATE_HEADER: "Actualización {0}"
|
||||
|
||||
@@ -186,6 +186,7 @@ TIME_DAYS: "{0} {jour|jours}"
|
||||
TIME_HOURS: "{0} {heure|heures}"
|
||||
TIME_MINUTES: "{0} {minute|minutes}"
|
||||
TIME_SECONDS: "{0} {seconde|secondes}"
|
||||
TIME_UNITS: "{/m|/h|/d}"
|
||||
TIME_WEEKS: "{0} {semaine|semaines}"
|
||||
UPDATE_ERROR: "Une erreur s'est produite lors de la recherche de mises à jour."
|
||||
UPDATE_HEADER: "{0} Mettre à jour"
|
||||
|
||||
+193
-182
@@ -1,201 +1,212 @@
|
||||
# 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: "{マッピング|世界} のリロードを強制する(データベースからのキャッシュ)"
|
||||
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: "初期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]"
|
||||
COMMAND_CONSOLE: "コンソールからコマンドを実行してください"
|
||||
COMMAND_NOT_FOUND: "{0} は不明なコマンドです"
|
||||
COMMAND_THROTTLED: "しばらく待ってから、もう一度お試しください"
|
||||
CONSUMER_ERROR: "コンシューマーキューの処理は既に{一時停止|再開}されています"
|
||||
CONSUMER_TOGGLED: "コンシューマーキューの処理が{一時停止|再開}されました"
|
||||
CONTAINER_HEADER: "コンテナのトランザクション"
|
||||
CPU_CORES: "CPUコア"
|
||||
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} を無効化しました"
|
||||
DONATION_KEY_REQUIRED: "このコマンドには有効な寄付キーが必要です。"
|
||||
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}\" は、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} バージョンが見つかりました。"
|
||||
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}\" は、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: "有効なワールドを指定してください。"
|
||||
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: "記録制限時間に達しました。データを破棄してシャットダウンします。"
|
||||
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: "{1}が{0}としてログイン"
|
||||
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: "プレビューがキャンセルされました。"
|
||||
LOGGING_ITEMS: "ログに記録すべきアイテムが{0}個残っています。しばらくお待ちください..."
|
||||
LOGGING_TIME_LIMIT: "記録制限時間に達しました。データを破棄してシャットダウンします"
|
||||
LOOKUP_BLOCK: "{0}が{1}を{設置した|破壊した}"
|
||||
LOOKUP_CONTAINER: "{0}が{2}個の{1}を{追加した|取り出した}"
|
||||
LOOKUP_HEADER: "{0} の検索結果"
|
||||
LOOKUP_INTERACTION: "{0}が{1}を{クリックした|殺害した}"
|
||||
LOOKUP_ITEM: "{0}が{2}個の{1}を{拾った|落とした}"
|
||||
LOOKUP_LOGIN: "{0}の{ログイン|ログアウト}がログに記録されます"
|
||||
LOOKUP_PAGE: "{0} ページ目"
|
||||
LOOKUP_PROJECTILE: "{0}が{2}個の{1}を{投げた|撃った}"
|
||||
LOOKUP_ROWS_FOUND: "{0}行見つかりました"
|
||||
LOOKUP_SEARCHING: "検索中。しばらくお待ちください..."
|
||||
LOOKUP_STORAGE: "{0}が{2}個の{1}を{預け入れた|引き出した}"
|
||||
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サーバーに接続できません"
|
||||
NETWORK_CONNECTION: "{0}の接続に{成功|失敗}しました。{1}{2}を使用します"
|
||||
NETWORK_TEST: "ネットワーク・テスト・データが正常に送信されました"
|
||||
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: "パージに失敗しました。データベースが破損している可能性があります。"
|
||||
PREVIEW_IN_GAME: "ゲーム内でのみロールバックをプレビューできます"
|
||||
PREVIEW_TRANSACTION: "{コンテナ|インベントリ}のトランザクションをプレビューすることはできません"
|
||||
PRIMARY_THREAD_ERROR: "そのAPIメソッドはメインスレッドでは使用できません"
|
||||
PURGE_ABORTED: "パージに失敗しました。データベースが破損している可能性があります"
|
||||
PURGE_ERROR: "{0} のデータを処理できません"
|
||||
PURGE_FAILED: "パージに失敗しました。後でもう一度やり直してください。"
|
||||
PURGE_IN_PROGRESS: "進行中のパージ。後でもう一度やり直してください。"
|
||||
PURGE_MINIMUM_TIME: "分離できるのは、より古いデータのみです。({0}{日|時間})"
|
||||
PURGE_NOTICE_1: "これには時間がかかる場合がありますのでご注意ください。"
|
||||
PURGE_NOTICE_2: "完了するまでサーバーを再起動しないでください。"
|
||||
PURGE_OPTIMIZING: "データベースの最適化。お待ちください..."
|
||||
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}"
|
||||
PURGE_ROWS: "{0}行のデータが削除されました"
|
||||
PURGE_STARTED: "データの削除は\"{0}\"で開始されました"
|
||||
PURGE_SUCCESS: "データのパージに成功しました"
|
||||
RAM_STATS: "{0}GB / {1}GB RAM"
|
||||
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_SYSTEM: "システム: {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: "更新の確認中にエラーが発生しました。"
|
||||
TELEPORTED: "{0} にテレポートしました"
|
||||
TELEPORTED_SAFETY: "あなたを安全な場所にテレポートさせました"
|
||||
TELEPORT_PLAYERS: "テレポートコマンドはプレイヤーのみが使用できます"
|
||||
TIME_DAYS: "{0}{日|日間}"
|
||||
TIME_HOURS: "{0}{時|時間}"
|
||||
TIME_MINUTES: "{0}{分|分間}"
|
||||
TIME_MONTHS: "{0}{ヶ月|ヶ月間}"
|
||||
TIME_SECONDS: "{0}{秒|秒間}"
|
||||
TIME_UNITS: "{/m|/h|/d}"
|
||||
TIME_WEEKS: "{0}{週|週間}"
|
||||
TIME_YEARS: "{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}\" は見つかりませんでした。"
|
||||
UPDATE_NOTICE: "お知らせ: {0} が利用可能です"
|
||||
UPGRADE_IN_PROGRESS: "アップグレードが進行中です。しばらくしてからもう一度やり直してください"
|
||||
USER_NOT_FOUND: "ユーザー \"{0}\" が見つかりません"
|
||||
USER_OFFLINE: "ユーザー \"{0}\" はオンラインではありません"
|
||||
USING_MYSQL: "MySQL データストレージを使用します"
|
||||
USING_SQLITE: "SQLite データストレージを使用します"
|
||||
VALID_DONATION_KEY: "有効な寄付キーです"
|
||||
VERSION_INCOMPATIBLE: "{0} {1} はサポートされていません"
|
||||
VERSION_NOTICE: "バージョン {0} が利用可能です"
|
||||
VERSION_REQUIRED: "{0} {1} 以上が必要です"
|
||||
WORLD_NOT_FOUND: "ワールド \"{0}\" は見つかりませんでした"
|
||||
+77
-71
@@ -1,35 +1,37 @@
|
||||
# CoreProtect Language File (ko)
|
||||
|
||||
ACTION_NOT_SUPPORTED: "해당 명령어는 해당 작업을 지원하지 않습니다."
|
||||
AMOUNT_BLOCK: "{0} {블록|블록}"
|
||||
AMOUNT_CHUNK: "{0} {청크|청크}"
|
||||
AMOUNT_ENTITY: "{0} {엔티티|엔티티}"
|
||||
AMOUNT_ITEM: "{0} {항목|항목}"
|
||||
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: "콘솔에서 명령어를 실행하세요."
|
||||
CHECK_CONFIG: "config.yml을 확인해주세요"
|
||||
COMMAND_CONSOLE: "이 명령어는 콘솔에서만 실행할 수 있습니다."
|
||||
COMMAND_NOT_FOUND: "\"{0}\" 명령어를 찾을 수 없습니다."
|
||||
COMMAND_THROTTLED: "잠시 기다렸다가 다시 시도하십시오."
|
||||
CONSUMER_ERROR: "소비자 대기열 처리가 이미 {일시 중지|재개}되있습니다!"
|
||||
CONSUMER_TOGGLED: "소비자 대기열 처리가 {일시 중지|재개}되었습니다."
|
||||
COMMAND_THROTTLED: "잠시 기다렸다가 다시 시도하세요."
|
||||
CONSUMER_ERROR: "데이터베이스 처리가 이미 {일시정지|재개}되어 있습니다!"
|
||||
CONSUMER_TOGGLED: "데이터베이스 처리가 {일시정지|재개}되었습니다."
|
||||
CONTAINER_HEADER: "컨테이너 기록"
|
||||
DATABASE_BUSY: "데이터베이스가 사용 중입니다. 나중에 다시 시도하십시오."
|
||||
CPU_CORES: "CPU 코어"
|
||||
DATABASE_BUSY: "데이터베이스가 사용 중입니다. 나중에 다시 시도하세요."
|
||||
DATABASE_INDEX_ERROR: "데이터베이스 인덱스의 유효성을 검사할 수 없습니다."
|
||||
DATABASE_LOCKED_1: "데이터베이스가 잠겼습니다. 최대 15초 대기 중..."
|
||||
DATABASE_LOCKED_2: "데이터베이스가 이미 사용 중입니다. 다시 시도하십시오."
|
||||
DATABASE_LOCKED_3: "데이터베이스 잠금을 비활성화하려면 \"database-lock: false\"로 설정하세요."
|
||||
DATABASE_LOCKED_4: "데이터베이스 잠금을 비활성화하면 데이터가 손상될 수 있습니다."
|
||||
DATABASE_LOCKED_2: "데이터베이스가 이미 사용 중입니다. 다시 시도하세요."
|
||||
DATABASE_LOCKED_3: "데이터베이스 잠금을 해제하려면 \"database-lock: false\"로 설정하세요."
|
||||
DATABASE_LOCKED_4: "데이터베이스 잠금을 비활성화하면 데이터가 손상될 수도 있습니다."
|
||||
DATABASE_UNREACHABLE: "데이터베이스에 연결할 수 없습니다. 데이터를 삭제하고 종료합니다."
|
||||
DEVELOPMENT_BRANCH: "개발 브랜치가 감지되어 패치 스크립트를 건너뜁니다."
|
||||
DIRT_BLOCK: "당신 아래에 흙 블록을 설치했습니다."
|
||||
DIRT_BLOCK: "당신 아래에 임시 안전 블록을 설치했습니다."
|
||||
DISABLE_SUCCESS: "성공! {0} 비활성화됨"
|
||||
DONATION_KEY_REQUIRED: "해당 명령어를 사용하려면 유효한 후원 키가 필요합니다."
|
||||
ENABLE_FAILED: "{0}을(를) 시작할 수 없습니다."
|
||||
ENABLE_SUCCESS: "{0}이(가) 성공적으로 활성화되었습니다!"
|
||||
ENJOY_COREPROTECT: "{0}을(를) 사용중이신가요? Discord 서버에 참여해보세요!"
|
||||
ENJOY_COREPROTECT: "{0}을(를) 잘 사용하고 계신가요? 그렇다면 저희의 Discord 서버에 참여하세요!"
|
||||
FINISHING_CONVERSION: "데이터 변환을 완료하는 중입니다. 잠시 기다려 주세요..."
|
||||
FINISHING_LOGGING: "데이터 로깅을 완료하는 중입니다. 잠시 기다려 주십시오..."
|
||||
FINISHING_LOGGING: "데이터 로깅을 완료하는 중입니다. 잠시 기다려 주세요..."
|
||||
FIRST_VERSION: "초기 DB: {0}"
|
||||
GLOBAL_LOOKUP: "전체 조회를 수행하려면 반경을 지정하지 마세요."
|
||||
GLOBAL_ROLLBACK: "전역 {롤백|복원}을 수행하려면 \"{0}\"을(를) 사용하세요."
|
||||
@@ -42,43 +44,43 @@ 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_2: "블록을 마우스 왼쪽 버튼으로 클릭하면 누가 그 블록을 설치했는지 확인할 수 있습니다."
|
||||
HELP_INSPECT_3: "블록을 마우스 오른쪽 버튼으로 클릭하면 인접한 블록이 부서졌는지 확인할 수 있습니다."
|
||||
HELP_INSPECT_4: "블록을 배치하여 해당 위치에서 어떤 블록이 부서졌는지 확인할 수 있습니다."
|
||||
HELP_INSPECT_5: "누가 설치했는지 확인하려면 액체(등)에 블록을 배치하세요."
|
||||
HELP_INSPECT_6: "문, 상자 등을 마우스 오른쪽 버튼으로 클릭하면 누가 마지막으로 사용했는지 확인할 수 있습니다."
|
||||
HELP_INSPECT_7: "팁: 더 빠른 액세스를 위해 \"/co i\"명령어를 사용할 수 있습니다."
|
||||
HELP_INSPECT_7: "팁: 더 빠른 사용을 위해 \"/co i\"명령어를 사용할 수 있습니다."
|
||||
HELP_INSPECT_COMMAND: "블록 로그 조사를 켜거나 끕니다."
|
||||
HELP_LIST: "모든 명령어 목록을 표시합니다."
|
||||
HELP_LOOKUP_1: "명령어 단축키."
|
||||
HELP_LOOKUP_1: "단축 명령어."
|
||||
HELP_LOOKUP_2: "로그를 보려면 블록을 검사한 후 사용하세요."
|
||||
HELP_LOOKUP_COMMAND: "고급 블록 데이터 조회."
|
||||
HELP_NO_INFO: "\"{0}\" 명령어에 대한 정보를 찾을 수 없습니다."
|
||||
HELP_NO_INFO: "\"{0}\" 명령어에 대한 정보가 없습니다."
|
||||
HELP_PARAMETER: "자세한 매개변수 정보는 \"{0}\"을 참조하세요."
|
||||
HELP_PARAMS_1: "{조회|롤백|복원}을(를) 수행하세요."
|
||||
HELP_PARAMS_2: "{조회|롤백|복원}할 사용자를 지정하세요."
|
||||
HELP_PARAMS_3: "{조회|롤백|복원}에 걸리는 시간을 지정하세요."
|
||||
HELP_PARAMS_4: "{조회|롤백|복원}을(를) 제한할 반경 영역을 지정하세요."
|
||||
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_RADIUS_1: "반경을 지정합니다."
|
||||
HELP_RADIUS_2: "예: [r:10] (10블록 이내에서만 변경합니다.)"
|
||||
HELP_RELOAD_COMMAND: "구성 파일을 다시 로드합니다."
|
||||
HELP_RESTORE_COMMAND: "블록 데이터를 복원합니다."
|
||||
HELP_ROLLBACK_COMMAND: "블록 데이터를 롤백합니다."
|
||||
HELP_STATUS: "플러그인 상태 및 버전 정보를 확인하세요."
|
||||
HELP_STATUS: "플러그인 상태 및 버전 정보를 확인합니다."
|
||||
HELP_STATUS_COMMAND: "플러그인 상태를 표시합니다."
|
||||
HELP_TELEPORT: "특정 위치로 순간이동합니다."
|
||||
HELP_TIME_1: "조회 시간을 지정하세요."
|
||||
HELP_TIME_1: "조회 시간을 지정합니다."
|
||||
HELP_TIME_2: "예: [t:2w,5d,7h,2m,10s], [t:5d2h], [t:2.50h]"
|
||||
HELP_USER_1: "조회할 사용자를 지정하세요."
|
||||
HELP_USER_1: "조회할 사용자를 지정합니다."
|
||||
HELP_USER_2: "예: [u:notch], [u:notch,#enderman]"
|
||||
INCOMPATIBLE_ACTION: "\"{0}\"은(는) 해당 작업과 함께 사용할 수 없습니다."
|
||||
INSPECTOR_ERROR: "로그 조사가 이미 {활성화|비활성화}되있습니다!"
|
||||
INSPECTOR_ERROR: "로그 조사가 이미 {활성화|비활성화}되어 있습니다!"
|
||||
INSPECTOR_TOGGLED: "로그 조사가 {활성화|비활성화}되었습니다."
|
||||
INTEGRATION_ERROR: "{0} 로깅을 {초기화|비활성화}할 수 없습니다."
|
||||
INTEGRATION_SUCCESS: "{0} 로깅이 성공적으로 {초기화|비활성화}되었습니다."
|
||||
@@ -87,13 +89,13 @@ INTERACTIONS_HEADER: "플레이어 상호작용"
|
||||
INVALID_ACTION: "유효하지 않은 작업입니다."
|
||||
INVALID_BRANCH_1: "잘못된 플러그인 버전(브랜치가 설정되지 않음)."
|
||||
INVALID_BRANCH_2: "계속하려면 프로젝트 브랜치를 \"development\"로 설정하세요."
|
||||
INVALID_BRANCH_3: "개발 코드를 실행하면 데이터 손상이 발생할 수 있습니다."
|
||||
INVALID_BRANCH_3: "개발중인 코드를 실행하면 데이터 손상이 발생할 수도 있습니다."
|
||||
INVALID_CONTAINER: "먼저 유효한 컨테이너를 검사하세요."
|
||||
INVALID_DONATION_KEY: "잘못된 후원 키입니다."
|
||||
INVALID_INCLUDE: "\"{0}\"은(는) 잘못된 블록/엔티티 이름입니다."
|
||||
INVALID_INCLUDE_COMBO: "잘못된 블록/엔티티 조합입니다."
|
||||
INVALID_RADIUS: "유효한 반경을 입력하세요."
|
||||
INVALID_SELECTION: "{0} 선택을 찾을 수 없습니다."
|
||||
INVALID_SELECTION: "{0} 선택된 항목을 찾을 수 없습니다."
|
||||
INVALID_USERNAME: "\"{0}\"은(는) 잘못된 사용자 이름입니다."
|
||||
INVALID_WORLD: "유효한 월드를 지정하세요."
|
||||
LATEST_VERSION: "최신 버전: {0}"
|
||||
@@ -103,29 +105,29 @@ 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}이(가) {2}에서 {1}을(를) {추가|제거}했습니다."
|
||||
LOGGING_TIME_LIMIT: "로깅 시간 제한에 도달했습니다. 데이터를 삭제하고 종료합니다."
|
||||
LOOKUP_BLOCK: "{0}이(가) {1}을(를) {설치|파괴}함"
|
||||
LOOKUP_CONTAINER: "{0}이(가) {2}에서 {1}을(를) {추가|제거}함"
|
||||
LOOKUP_HEADER: "{0} 조회 결과"
|
||||
LOOKUP_INTERACTION: "{0}이(가) {1}을(를) {클릭|처치}했습니다."
|
||||
LOOKUP_ITEM: "{0}이(가) {2}에서 {1}을(를) {획득|드롭}했습니다."
|
||||
LOOKUP_LOGIN: "{0}이(가) {로그인|로그아웃}했습니다."
|
||||
LOOKUP_INTERACTION: "{0}이(가) {1}을(를) {클릭함|죽임}
|
||||
LOOKUP_ITEM: "{0}이(가) {2}에서 {1}을(를) {획득|드롭}함"
|
||||
LOOKUP_LOGIN: "{0}이(가) {로그인|로그아웃}함"
|
||||
LOOKUP_PAGE: "페이지 {0}"
|
||||
LOOKUP_PROJECTILE: "{0}이(가) {2}에서 {1}을(를) {던졌|발사했}습니다.."
|
||||
LOOKUP_PROJECTILE: "{0}이(가) {2}에서 {1}을(를) {던짐|발사함}"
|
||||
LOOKUP_ROWS_FOUND: "{0} {열|열}이 발견되었습니다."
|
||||
LOOKUP_SEARCHING: "조회 중입니다. 잠시만 기다려 주세요..."
|
||||
LOOKUP_STORAGE: "{0}이(가) {2}에서 {1}을(를) {추가|제거}했습니다."
|
||||
LOOKUP_STORAGE: "{0}이(가) {2}에서 {1}을(를) {추가|제거}함"
|
||||
LOOKUP_TIME: "{0} 전"
|
||||
LOOKUP_USERNAME: "{0}이(가) {1}으로 로그인했습니다."
|
||||
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: "{롤백|복원} 사용자를 지정하지 않았습니다."
|
||||
MISSING_ROLLBACK_RADIUS: "{롤백|복원}할 반경을 지정하지 않았습니다."
|
||||
MISSING_ROLLBACK_USER: "{롤백|복원}할 사용자를 지정하지 않았습니다."
|
||||
MYSQL_UNAVAILABLE: "MySQL 서버에 연결할 수 없습니다."
|
||||
NETWORK_CONNECTION: "{0} 연결 {성공|실패}. {1} {2} 사용 중."
|
||||
NETWORK_CONNECTION: "{0} 연결 {성공|실패}. {1} {2} 사용 중"
|
||||
NETWORK_TEST: "네트워크 테스트 데이터가 성공적으로 전송되었습니다."
|
||||
NO_DATA: "{0}에서 데이터를 찾을 수 없습니다."
|
||||
NO_DATA_LOCATION: "해당 위치에서 {데이터|거래|상호작용|메시지}(을)를 찾을 수 없습니다."
|
||||
@@ -133,7 +135,7 @@ NO_PERMISSION: "해당 작업을 수행할 권한이 없습니다."
|
||||
NO_RESULTS: "결과를 찾을 수 없습니다."
|
||||
NO_RESULTS_PAGE: "해당 페이지에 대한 {결과|데이터}를 찾을 수 없습니다."
|
||||
NO_ROLLBACK: "{보류 중인|이전} 롤백/복원을 찾을 수 없습니다."
|
||||
PATCH_INTERRUPTED: "업그레이드가 중단되었습니다. 다시 시작할 때 재시도합니다."
|
||||
PATCH_INTERRUPTED: "업그레이드가 중단되었습니다. 서버를 재시작하면 재시도합니다."
|
||||
PATCH_OUTDATED_1: "{0}보다 오래된 데이터베이스를 업그레이드할 수 없습니다."
|
||||
PATCH_OUTDATED_2: "지원되는 CoreProtect 버전으로 업그레이드하세요."
|
||||
PATCH_PROCESSING: "새 데이터를 처리 중입니다. 잠시 기다려 주세요..."
|
||||
@@ -141,45 +143,48 @@ PATCH_SKIP_UPDATE: "{0}에서 {테이블|인덱스} {업데이트|생성|제거}
|
||||
PATCH_STARTED: "{0} 업그레이드를 수행 중입니다. 잠시 기다려 주세요..."
|
||||
PATCH_SUCCESS: "{0}으로 성공적으로 업그레이드되었습니다."
|
||||
PATCH_UPGRADING: "데이터베이스 업그레이드가 진행 중입니다. 잠시 기다려 주세요..."
|
||||
PLEASE_SELECT: "다음을 선택하세요: \"{0}\" 또는 \"{1}\"."
|
||||
PLEASE_SELECT: "\"{0}\" 또는 \"{1}\" 중 하나를 선택하세요."
|
||||
PREVIEW_CANCELLED: "미리보기가 취소되었습니다."
|
||||
PREVIEW_CANCELLING: "미리보기 취소 중..."
|
||||
PREVIEW_IN_GAME: "롤백을 미리보려면 게임 내에서만 가능합니다."
|
||||
PREVIEW_TRANSACTION: "{컨테이너|인벤토리} 기록을 미리볼 수 없습니다."
|
||||
PURGE_ABORTED: "삭제 실패. 데이터베이스가 손상되었을 수 있습니다."
|
||||
PREVIEW_IN_GAME: "게임 내에서만 롤백 미리보기가 가능합니다."
|
||||
PREVIEW_TRANSACTION: "{컨테이너|인벤토리} 기록은 미리보기할 수 없습니다."
|
||||
PRIMARY_THREAD_ERROR: "기본 스레드에서는 API 메소드를 사용할 수 없습니다."
|
||||
PURGE_ABORTED: "삭제에 실패하였습니다. 데이터베이스가 손상되었을 수도 있습니다."
|
||||
PURGE_ERROR: "{0} 데이터를 처리할 수 없습니다!"
|
||||
PURGE_FAILED: "삭제 실패. 나중에 다시 시도하세요."
|
||||
PURGE_FAILED: "삭제에 실패하였습니다. 나중에 다시 시도하세요."
|
||||
PURGE_IN_PROGRESS: "삭제가 진행 중입니다. 나중에 다시 시도하세요."
|
||||
PURGE_MINIMUM_TIME: "{0} {일|시간}보다 오래된 데이터만 삭제할 수 있습니다."
|
||||
PURGE_NOTICE_1: "이 작업은 시간이 걸릴 수 있습니다."
|
||||
PURGE_NOTICE_2: "완료될 때까지 서버를 재시작하지 마세요."
|
||||
PURGE_OPTIMIZING: "데이터베이스 최적화 중입니다. 잠시 기다려 주세요..."
|
||||
PURGE_OPTIMIZING: "데이터베이스를 최적화 중입니다. 잠시 기다려 주세요..."
|
||||
PURGE_PROCESSING: "{0} 데이터를 처리 중입니다..."
|
||||
PURGE_REPAIRING: "복구 시도 중입니다. 시간이 걸릴 수 있습니다..."
|
||||
PURGE_ROWS: "{0} {열|열}의 데이터가 삭제되었습니다."
|
||||
PURGE_STARTED: "\"{0}\"에서 데이터 삭제가 시작되었습니다."
|
||||
PURGE_STARTED: "\"{0}\"에서 데이터 삭제 시작됨"
|
||||
PURGE_SUCCESS: "데이터 삭제가 성공적으로 완료되었습니다."
|
||||
RAM_STATS: "램: {0}GB / {1}GB"
|
||||
RELOAD_STARTED: "구성 리로드 중 - 잠시 기다려 주세요."
|
||||
RELOAD_SUCCESS: "구성이 성공적으로 리로드되었습니다."
|
||||
ROLLBACK_ABORTED: "롤백 또는 복원이 중단되었습니다."
|
||||
ROLLBACK_CHUNKS_FOUND: "{0} {청크|청크}를 수정할 준비가 되었습니다."
|
||||
ROLLBACK_CHUNKS_MODIFIED: "{1} 중 {0} {청크|청크}를 수정했습니다."
|
||||
ROLLBACK_CHUNKS_FOUND: "수정할 {청크|청크} {0}개를 찾았습니다."
|
||||
ROLLBACK_CHUNKS_MODIFIED: "{1}개 중 {0}개의 {청크|청크} 수정됨"
|
||||
ROLLBACK_COMPLETED: "\"{0}\"에 대한 {롤백이|복원이|미리보기가} 완료되었습니다."
|
||||
ROLLBACK_EXCLUDED_USERS: "제외된 {사용자|사용자}: \"{0}\"."
|
||||
ROLLBACK_INCLUDE: "{포함된|제외된} {블록|엔티티|대상} {타입|타입}: \"{0}\"."
|
||||
ROLLBACK_EXCLUDED_USERS: "제외된 {사용자|사용자}: \"{0}\""
|
||||
ROLLBACK_INCLUDE: "{포함된|제외된} {블록|엔티티|대상} {타입|타입}: \"{0}\""
|
||||
ROLLBACK_IN_PROGRESS: "롤백/복원이 이미 진행 중입니다."
|
||||
ROLLBACK_LENGTH: "소요 시간: {0} {초|초}."
|
||||
ROLLBACK_MODIFIED: "{0}이(가) {수정됨|수정 중}."
|
||||
ROLLBACK_RADIUS: "반경: {0} {블록|블록}."
|
||||
ROLLBACK_LENGTH: "소요 시간: {0} {초|초}"
|
||||
ROLLBACK_MODIFIED: "{0}이(가) {수정됨|수정 중}"
|
||||
ROLLBACK_RADIUS: "반경: {0} {블록|블록}"
|
||||
ROLLBACK_SELECTION: "반경이 \"{0}\"로 설정되었습니다."
|
||||
ROLLBACK_STARTED: "\"{0}\"에서 {롤백이|복원이|미리보기가} 시작되었습니다."
|
||||
ROLLBACK_TIME: "시간 범위: {0}."
|
||||
ROLLBACK_WORLD_ACTION: "{월드|작업} \"{0}\"으로 제한됨."
|
||||
ROLLBACK_TIME: "시간 범위: {0}"
|
||||
ROLLBACK_WORLD_ACTION: "{월드|작업} \"{0}\"으로 제한됨"
|
||||
SIGN_HEADER: "표지판 메시지"
|
||||
STATUS_CONSUMER: "소비자: 대기 중인 {0} {항목|항목들}."
|
||||
STATUS_DATABASE: "데이터베이스: {0} 사용 중."
|
||||
STATUS_INTEGRATION: "{0}: 통합 {활성화됨|비활성화됨}."
|
||||
STATUS_CONSUMER: "데이터베이스 처리: 대기 중인 {항목|항목} {0}개"
|
||||
STATUS_DATABASE: "데이터베이스: {0} 사용 중"
|
||||
STATUS_INTEGRATION: "{0}: 통합 {활성화됨|비활성화됨}"
|
||||
STATUS_LICENSE: "라이선스: {0}"
|
||||
STATUS_SYSTEM: "시스템: {0}"
|
||||
STATUS_VERSION: "버전: {0}"
|
||||
TELEPORTED: "{0}(으)로 텔레포트되었습니다."
|
||||
TELEPORTED_SAFETY: "안전하게 텔레포트되었습니다."
|
||||
@@ -188,16 +193,17 @@ TIME_DAYS: "{0} {일|일}"
|
||||
TIME_HOURS: "{0} {시간|시간}"
|
||||
TIME_MINUTES: "{0} {분|분}"
|
||||
TIME_SECONDS: "{0} {초|초}"
|
||||
TIME_UNITS: "{/m|/h|/d}"
|
||||
TIME_WEEKS: "{0} {주|주}"
|
||||
UPDATE_ERROR: "업데이트 확인 중 오류가 발생했습니다."
|
||||
UPDATE_HEADER: "{0} 업데이트"
|
||||
UPDATE_NOTICE: "알림: {0}이(가) 이제 사용할 수 있습니다."
|
||||
UPDATE_NOTICE: "알림: {0}을(를) 사용할 수 있습니다."
|
||||
UPGRADE_IN_PROGRESS: "업그레이드가 진행 중입니다. 나중에 다시 시도하세요."
|
||||
USER_NOT_FOUND: "사용자 \"{0}\"을(를) 찾을 수 없습니다."
|
||||
USER_OFFLINE: "사용자 \"{0}\"이(가) 온라인 상태가 아닙니다."
|
||||
USER_OFFLINE: "사용자 \"{0}\"은(는) 온라인 상태가 아닙니다."
|
||||
USING_MYSQL: "데이터 저장에 MySQL을 사용 중입니다."
|
||||
USING_SQLITE: "데이터 저장에 SQLite를 사용 중입니다."
|
||||
VALID_DONATION_KEY: "유효한 후원 키입니다."
|
||||
VERSION_NOTICE: "버전 {0}(를) 이제 사용할 수 있습니다."
|
||||
VERSION_NOTICE: "버전 {0}(를) 사용할 수 있습니다."
|
||||
VERSION_REQUIRED: "{0} {1} 이상이 필요합니다."
|
||||
WORLD_NOT_FOUND: " \"{0}\"을(를) 찾을 수 없습니다."
|
||||
WORLD_NOT_FOUND: " \"{0}\"을(를) 찾을 수 없습니다."
|
||||
+114
-103
@@ -1,20 +1,21 @@
|
||||
# CoreProtect Language File (pl)
|
||||
|
||||
ACTION_NOT_SUPPORTED: "To działanie nie jest obsługiwane."
|
||||
ACTION_NOT_SUPPORTED: "Ta akcja nie jest obsługiwana."
|
||||
AMOUNT_BLOCK: "{0} {blok|bloki}"
|
||||
AMOUNT_CHUNK: "{0} {kawałek|kawałki}"
|
||||
AMOUNT_ENTITY: "{0} {jednostka|jednostki}"
|
||||
AMOUNT_CHUNK: "{0} {chunk|chunków}"
|
||||
AMOUNT_ENTITY: "{0} {byt|bytów}"
|
||||
AMOUNT_ITEM: "{0} {przedmiot|przedmioty}"
|
||||
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_NOT_FOUND: "Nie znaleziono komendy \"{0}\"."
|
||||
COMMAND_THROTTLED: "Poczekaj chwilę i spróbuj ponownie."
|
||||
CONSUMER_ERROR: "Przetwarzanie kolejki klientów już {wstrzymane|wznowione}."
|
||||
CONSUMER_ERROR: "Przetwarzanie kolejki klientów jest już {wstrzymane|wznowione}."
|
||||
CONSUMER_TOGGLED: "Przetwarzanie kolejki klientów zostało {wstrzymane|wznowione}."
|
||||
CONTAINER_HEADER: "Transakcje kontenerowe"
|
||||
CPU_CORES: "Rdzenie CPU."
|
||||
DATABASE_BUSY: "Baza danych zajęta. Spróbuj ponownie później."
|
||||
DATABASE_INDEX_ERROR: "Nie można zweryfikować indeksów bazy danych."
|
||||
DATABASE_LOCKED_1: "Baza danych zablokowana. Czekam do 15 sekund..."
|
||||
@@ -23,179 +24,189 @@ DATABASE_LOCKED_3: "Aby wyłączyć blokowanie bazy danych, ustaw \"database-loc
|
||||
DATABASE_LOCKED_4: "Wyłączenie blokowania bazy danych może spowodować uszkodzenie danych."
|
||||
DATABASE_UNREACHABLE: "Baza danych jest niedostępna. Odrzucanie danych i zamykanie."
|
||||
DEVELOPMENT_BRANCH: "Wykryto gałąź deweloperską, pomijam skrypty poprawek."
|
||||
DIRT_BLOCK: "Umieściłem pod tobą blok brudu."
|
||||
DISABLE_SUCCESS: "Sukces! Niepełnosprawny {0}"
|
||||
ENABLE_FAILED: "{0} nie mógł rozpocząć."
|
||||
DIRT_BLOCK: "Umieściłem pod Tobą tymczasowy blok bezpieczeństwa."
|
||||
DONATION_KEY_REQUIRED: "Dla tej komendy wymagany jest prawidłowy klucz darowizny."
|
||||
DISABLE_SUCCESS: "Sukces! Wyłączono {0}"
|
||||
ENABLE_FAILED: "{0} nie mógł wystartować."
|
||||
ENABLE_SUCCESS: "{0} jest teraz włączony!"
|
||||
ENJOY_COREPROTECT: "Cieszyć się {0}? Dołączć do naszego Discord!"
|
||||
FINISHING_CONVERSION: "Zakończenie konwersji danych. Proszę czekać..."
|
||||
FINISHING_LOGGING: "Zakończenie rejestracji danych. Proszę czekać..."
|
||||
ENJOY_COREPROTECT: "Podoba Ci się {0}? Dołącz do naszego Discorda!"
|
||||
FINISHING_CONVERSION: "Kończenie konwersji danych. Proszę czekać..."
|
||||
FINISHING_LOGGING: "Kończenie rejestracji danych. Proszę czekać..."
|
||||
FIRST_VERSION: "Początkowa baza danych: {0}"
|
||||
GLOBAL_LOOKUP: "Nie określaj promienia, aby wykonać globalne wyszukiwanie."
|
||||
GLOBAL_ROLLBACK: "Posługiwać się \"{0}\" zrobić globalny {wycofywanie|przywracanie}"
|
||||
HELP_ACTION_1: "Ogranicz wyszukiwanie do akcji."
|
||||
GLOBAL_ROLLBACK: "Użyj \"{0}\", aby zrobić globalne {wycofywanie|przywracanie}"
|
||||
HELP_ACTION_1: "Ogranicz wyszukiwanie do konkretnej akcji."
|
||||
HELP_ACTION_2: "Przykłady: [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: "Wyświetl dodatkowe informacje."
|
||||
HELP_EXCLUDE_1: "Wyklucz bloki/użytkowników."
|
||||
HELP_EXCLUDE_2: "Przykłady: [e:stone], [e:Notch], [e:stone,Notch]"
|
||||
HELP_HEADER: "{0} Wsparcie"
|
||||
HELP_HEADER: "{0} Pomoc"
|
||||
HELP_INCLUDE_1: "Uwzględnij bloki/elementy."
|
||||
HELP_INCLUDE_2: "Przykłady: [i:stone], [i:zombie], [i:stone,wood,bedrock]"
|
||||
HELP_INSPECT_1: "Po włączeniu inspektora możesz:"
|
||||
HELP_INSPECT_2: "Kliknij lewym przyciskiem myszy, aby zobaczyć miejsce docelowe."
|
||||
HELP_INSPECT_3: "Kliknij prawym przyciskiem myszy, aby zobaczyć sąsiednie usunięcia."
|
||||
HELP_INSPECT_4: "Umieść blok, aby zobaczyć usunięcie."
|
||||
HELP_INSPECT_5: "Umieść blok w płynie, aby zobaczyć umieszczenie."
|
||||
HELP_INSPECT_6: "Kliknij prawym przyciskiem myszy, aby zobaczyć transakcje w skrzyniach."
|
||||
HELP_INSPECT_7: "Wskazówka: możesz użyć tylko „/co i”."
|
||||
HELP_INSPECT_2: "Kliknij lewym przyciskiem myszy, aby zobaczyć kto postawił ten blok."
|
||||
HELP_INSPECT_3: "Kliknij prawym przyciskiem myszy, aby zobaczyć jaki sąsiedni blok został usunięty."
|
||||
HELP_INSPECT_4: "Umieść blok, aby zobaczyć jaki blok został usunięty w tym miejscu."
|
||||
HELP_INSPECT_5: "Umieść blok w płynie, aby zobaczyć kto go postawił."
|
||||
HELP_INSPECT_6: "Kliknij prawym przyciskiem myszy na drzwi, skrzynię, itp., aby zobaczyć, kto ostatnio z nich korzystał."
|
||||
HELP_INSPECT_7: "Wskazówka: możesz użyć po prostu \"/co i\"."
|
||||
HELP_INSPECT_COMMAND: "Przełącza inspektora bloków."
|
||||
HELP_LIST: "Wyświetla listę wszystkich poleceń."
|
||||
HELP_LOOKUP_1: "Skrót poleceń."
|
||||
HELP_LOOKUP_2: "Zobacz dodatkowe strony."
|
||||
HELP_LOOKUP_COMMAND: "Dane bloku wyszukiwania."
|
||||
HELP_NO_INFO: "Informacje do polecenia \"{0}\" nie znaleziono."
|
||||
HELP_PARAMETER: "Proszę zobaczyć \"{0}\" , aby uzyskać szczegółowe informacje o parametrach."
|
||||
HELP_PARAMS_1: "Wykonaj {wyszukiwanie|przywracanie|przywracanie}."
|
||||
HELP_PARAMS_2: "Określ użytkowników do {wyszukiwanie|przywracanie|przywracanie}."
|
||||
HELP_PARAMS_3: "Określ czas, aby {wyszukiwanie|przywracanie|przywracanie}."
|
||||
HELP_PARAMS_4: "Ogranicz {wyszukiwanie|wycofywanie|przywracanie} do promienia."
|
||||
HELP_PARAMS_5: "Ogranicz {wyszukiwanie|wycofywanie|przywracanie} do działania."
|
||||
HELP_PARAMS_6: "Uwzględnij bloki/elementy w {wyszukiwanie|przywracanie|przywracanie}."
|
||||
HELP_PARAMS_7: "Wyklucz bloki/użytkowników z {wyszukiwanie|przywracanie|przywracanie}."
|
||||
HELP_PURGE_1: "Usuń stare dane."
|
||||
HELP_NO_INFO: "Nie znaleziono informacji dla polecenia \"{0}\"."
|
||||
HELP_PARAMETER: "Proszę zobaczyć \"{0}\", aby uzyskać szczegółowe informacje o parametrach."
|
||||
HELP_PARAMS_1: "Wykonaj {wyszukiwanie|wycofywanie|przywracanie}."
|
||||
HELP_PARAMS_2: "Określ użytkowników do {wyszukiwania|wycofywania|przywracania}."
|
||||
HELP_PARAMS_3: "Określ czas do {wyszukiwania|wycofywania|przywracania}."
|
||||
HELP_PARAMS_4: "Ogranicz promień {wyszukiwania|wycofywania|przywracania}."
|
||||
HELP_PARAMS_5: "Ogranicz akcję {wyszukiwania|wycofywania|przywracania}."
|
||||
HELP_PARAMS_6: "Uwzględnij bloki/byty w {wyszukiwaniu|wycofywaniu|przywracaniu}."
|
||||
HELP_PARAMS_7: "Wyklucz bloki/użytkowników z {wyszukiwania|wycofywania|przywracania}."
|
||||
HELP_PURGE_1: "Usuń dane starsze od określonego czasu."
|
||||
HELP_PURGE_2: "Na przykład, \"{0}” usunie wszystkie dane starsze niż jeden miesiąc i zachowa tylko dane z ostatnich 30 dni."
|
||||
HELP_PURGE_COMMAND: "Usuń stare dane bloku."
|
||||
HELP_RADIUS_1: "Określ obszar promienia."
|
||||
HELP_RADIUS_1: "Określ promień obszaru."
|
||||
HELP_RADIUS_2: "Przykłady: [r:10] (Dokonuj zmian tylko w promieniu 10 bloków od Ciebie)"
|
||||
HELP_RELOAD_COMMAND: "Ponownie ładuje plik konfiguracyjny."
|
||||
HELP_RESTORE_COMMAND: "Przywróć dane bloku."
|
||||
HELP_ROLLBACK_COMMAND: "Wycofaj dane bloku."
|
||||
HELP_STATUS: "Wyświetl stan wtyczki."
|
||||
HELP_STATUS_COMMAND: "Wyświetla stan wtyczki."
|
||||
HELP_STATUS: "Wyświetl stan i wersję pluginu."
|
||||
HELP_STATUS_COMMAND: "Wyświetla stan pluginu."
|
||||
HELP_TELEPORT: "Teleport."
|
||||
HELP_TIME_1: "Określ czas."
|
||||
HELP_TIME_2: "Przykłady: [t:2w,5d,7h,2m,10s], [t:5d2h], [t:2.50h]"
|
||||
HELP_USER_1: "Określ użytkowników."
|
||||
HELP_USER_2: "Przykłady: [u:Notch], [u:Notch,#enderman]"
|
||||
INCOMPATIBLE_ACTION: "\"{0}nie można użyć z tą akcją."
|
||||
INSPECTOR_ERROR: "Inspektor już {włączone|wyłączone}."
|
||||
INSPECTOR_TOGGLED: "Inspektor teraz {włączone|wyłączone}."
|
||||
INTEGRATION_ERROR: "Niezdolny do {inicjalizuj|wyłącz} {0} Logowanie."
|
||||
INTEGRATION_SUCCESS: "{0} logowanie pomyślnie {zainicjowane|wyłączone}."
|
||||
INTEGRATION_VERSION: "Nieważny {0} znaleziono wersję."
|
||||
INCOMPATIBLE_ACTION: "\"{0}\" nie może być użyte z tą akcją."
|
||||
INSPECTOR_ERROR: "Inspektor jest już {włączony|wyłączony}."
|
||||
INSPECTOR_TOGGLED: "{Włączono|Wyłączono} inspektor."
|
||||
INTEGRATION_ERROR: "Nie można {zainicjalizować|wyłączyć} logowania {0}."
|
||||
INTEGRATION_SUCCESS: "Logowanie {0} pomyślnie {zainicjowane|wyłączone}."
|
||||
INTEGRATION_VERSION: "Znaleziono nieprawidłową wersję {0}."
|
||||
INTERACTIONS_HEADER: "Interakcje graczy"
|
||||
INVALID_ACTION: "To nie jest prawidłowe działanie."
|
||||
INVALID_BRANCH_1: "Nieprawidłowa wersja wtyczki (nie ustawiono gałęzi)."
|
||||
INVALID_ACTION: "To nie jest prawidłowa akcja."
|
||||
INVALID_BRANCH_1: "Nieprawidłowa wersja pluginu (nie ustawiono gałęzi)."
|
||||
INVALID_BRANCH_2: "Aby kontynuować, ustaw gałąź projektu na \"development\"."
|
||||
INVALID_BRANCH_3: "Uruchomienie kodu programistycznego może spowodować uszkodzenie danych."
|
||||
INVALID_CONTAINER: "Proszę najpierw sprawdzić prawidłowy pojemnik."
|
||||
INVALID_DONATION_KEY: "Nieprawidłowy klucz darowizny."
|
||||
INVALID_INCLUDE: "\"{0}„ to nieprawidłowa wartość."
|
||||
INVALID_INCLUDE: "\"{0}\" to nieprawidłowa nazwa bloku/bytu."
|
||||
INVALID_INCLUDE_COMBO: "To jest nieprawidłowa kombinacja typów."
|
||||
INVALID_RADIUS: "Podaj poprawny promień."
|
||||
INVALID_SELECTION: "{0} nie znaleziono wyboru."
|
||||
INVALID_USERNAME: "\"{0}„ to nieprawidłowa nazwa użytkownika."
|
||||
INVALID_USERNAME: "\"{0}\" to nieprawidłowa nazwa użytkownika."
|
||||
INVALID_WORLD: "Podaj poprawny świat."
|
||||
LATEST_VERSION: "Najnowsza wersja: {0}"
|
||||
LINK_DISCORD: "Discord: {0}"
|
||||
LINK_DOWNLOAD: "Ściągnij: {0}"
|
||||
LINK_DOWNLOAD: "Pobierz: {0}"
|
||||
LINK_PATREON: "Patreon: {0}"
|
||||
LINK_WIKI_BLOCK: "Nazwy bloków: {0}"
|
||||
LINK_WIKI_ENTITY: "Nazwy podmiotów: {0}"
|
||||
LOGGING_ITEMS: "{0} elementy pozostawione do zarejestrowania. Proszę czekać..."
|
||||
LINK_WIKI_ENTITY: "Nazwy bytów: {0}"
|
||||
LOGGING_ITEMS: "Pozostało {0} elementów do logowania. Proszę czekać..."
|
||||
LOGGING_TIME_LIMIT: "Osiągnięto limit czasu logowania. Odrzucanie danych i zamykanie."
|
||||
LOOKUP_BLOCK: "{0} {umieszczony|złamany} {1}."
|
||||
LOOKUP_CONTAINER: "{0} {dodano|usunięto} {1} {2}."
|
||||
LOOKUP_HEADER: "{0} Wyniki"
|
||||
LOOKUP_INTERACTION: "{0} {kliknięty|zabity} {1}."
|
||||
LOOKUP_ITEM: "{0} {odebrany|upuszczony} {1} {2}."
|
||||
LOOKUP_LOGIN: "{0} zalogowany {w|na zewnątrz}."
|
||||
LOOKUP_BLOCK: "{0} {postawił|zniszczył} {1}."
|
||||
LOOKUP_CONTAINER: "{0} {dodał|usunął} {1} {2}."
|
||||
LOOKUP_HEADER: "{0} Wyników Wyszukiwania"
|
||||
LOOKUP_INTERACTION: "{0} {kliknął|zabił} {1}."
|
||||
LOOKUP_ITEM: "{0} {podniósł|upuścił} {1} {2}."
|
||||
LOOKUP_LOGIN: "{0} się {zalogował|wylogował}."
|
||||
LOOKUP_PAGE: "Strona {0}"
|
||||
LOOKUP_PROJECTILE: "{0} {rzucił|strzał} {1} {2}."
|
||||
LOOKUP_ROWS_FOUND: "{0} {wiersz|wiersze} znaleziony."
|
||||
LOOKUP_PROJECTILE: "{0} {rzucił|strzelił} {1} {2}."
|
||||
LOOKUP_ROWS_FOUND: "Znaleziono {0} {wiersz|wierszy}."
|
||||
LOOKUP_SEARCHING: "Wyszukiwanie wyszukiwania. Proszę czekać..."
|
||||
LOOKUP_STORAGE: "{0} {zdeponowane|wycofane} {1} {2}."
|
||||
LOOKUP_STORAGE: "{0} {zdeponował|wyciągnął} {1} {2}."
|
||||
LOOKUP_TIME: "{0} temu"
|
||||
LOOKUP_USERNAME: "{0} zalogowany jako {1}."
|
||||
MAXIMUM_RADIUS: "Maksymalny {wyszukiwanie|wycofywanie|przywracanie} promień to {0}."
|
||||
MAXIMUM_RADIUS: "Maksymalny promień {wyszukiwania|wycofywania|przywracania} 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}."
|
||||
MISSING_LOOKUP_TIME: "Proszę określić czas {wyszukiwania|wycofywania|przywracania}."
|
||||
MISSING_LOOKUP_USER: "Podaj użytkownika lub {blok|promień}."
|
||||
MISSING_PARAMETERS: "Proszę użyć \"{0}”."
|
||||
MISSING_ROLLBACK_RADIUS: "Nie podałeś {wycofywanie|przywracanie} promień."
|
||||
MISSING_ROLLBACK_USER: "Nie podałeś {wycofywanie|przywracanie} użytkownik."
|
||||
MYSQL_UNAVAILABLE: "Nie można się połączyć z MySQL serwer."
|
||||
MISSING_PARAMETERS: "Proszę użyć \"{0}\"."
|
||||
MISSING_ROLLBACK_RADIUS: "Nie podałeś promienia {wycofywania|przywracania}."
|
||||
MISSING_ROLLBACK_USER: "Nie podałeś użytkownika {wycofywania|przywracania}."
|
||||
MYSQL_UNAVAILABLE: "Nie można się połączyć z serwerem MySQL."
|
||||
NETWORK_CONNECTION: "Połączenie przez {0} {pomyślne|nieudane}. Używam {1} {2}."
|
||||
NETWORK_TEST: "Pomyślnie wysłano dane testu sieci."
|
||||
NO_DATA: "Nie znaleziono danych w {0}."
|
||||
NO_DATA_LOCATION: "Nie {dane|transakcje|interakcje|wiadomości} znaleziony."
|
||||
NO_DATA_LOCATION: "Nie znaleziono {danych|transakcji|interakcji|wiadomości} w tym miejscu."
|
||||
NO_PERMISSION: "Nie masz na to pozwolenia."
|
||||
NO_RESULTS: "Nie znaleziono wyników."
|
||||
NO_RESULTS_PAGE: "Nie {wyniki|dane} znalezione dla tej strony."
|
||||
NO_ROLLBACK: "Nie {oczekujące|poprzednie} znaleziono wycofywanie/przywracanie."
|
||||
PATCH_INTERRUPTED: "Aktualizacja przerwana. Spróbuje ponownie po ponownym uruchomieniu."
|
||||
NO_RESULTS_PAGE: "Nie znaleziono {wyników|danych} dla tej strony."
|
||||
NO_ROLLBACK: "Nie znaleziono {oczekujących|poprzednich} wycofywań/przywracań."
|
||||
PATCH_INTERRUPTED: "Aktualizacja przerwana. Spróbuję ponownie przy restarcie."
|
||||
PATCH_OUTDATED_1: "Nie można zaktualizować baz danych starszych niż {0}."
|
||||
PATCH_OUTDATED_2: "Uaktualnij do obsługiwanej wersji CoreProtect."
|
||||
PATCH_PROCESSING: "Przetwarzanie nowych danych. Proszę czekać..."
|
||||
PATCH_SKIP_UPDATE: "Skaczący {tabela|indeks} {aktualizacja|tworzenie|usuwanie} na {0}."
|
||||
PATCH_STARTED: "Działający {0} Aktualizacja. Proszę czekać..."
|
||||
PATCH_SKIP_UPDATE: "Pomijam {tabeli|indeksu} {aktualizację|tworzenie|usuwanie} na {0}."
|
||||
PATCH_STARTED: "Przeprowadzam aktualizację do {0}. Proszę czekać..."
|
||||
PATCH_SUCCESS: "Pomyślnie uaktualniono do {0}."
|
||||
PATCH_UPGRADING: "Trwa aktualizacja bazy danych. Proszę czekać..."
|
||||
PLEASE_SELECT: "Proszę wybrać: \"{0}\" lub \"{1}”."
|
||||
PLEASE_SELECT: "Proszę wybrać: \"{0}\" lub \"{1}\"."
|
||||
PREVIEW_CANCELLED: "Podgląd anulowany."
|
||||
PREVIEW_CANCELLING: "Anulowanie podglądu..."
|
||||
PREVIEW_IN_GAME: "Możesz tylko podglądać wycofania w grze."
|
||||
PREVIEW_TRANSACTION: "Nie możesz wyświetlić podglądu {kontener|inwentarz} transakcje."
|
||||
PREVIEW_TRANSACTION: "Nie możesz wyświetlić podglądu transakcji {kontenera|ekwipunku}."
|
||||
PRIMARY_THREAD_ERROR: "Ta metoda API nie może być używana w głównym wątku."
|
||||
PURGE_ABORTED: "Czyszczenie nie powiodło się. Baza danych może być uszkodzona."
|
||||
PURGE_ERROR: "Nie można przetworzyć {0} dane!"
|
||||
PURGE_ERROR: "Nie można przetworzyć danych {0}!"
|
||||
PURGE_FAILED: "Czyszczenie nie powiodło się. Spróbuj ponownie później."
|
||||
PURGE_IN_PROGRESS: "Trwa czyszczenie. Spróbuj ponownie później."
|
||||
PURGE_MINIMUM_TIME: "Możesz usunąć tylko dane starsze niż {0} {dni|godziny}."
|
||||
PURGE_NOTICE_1: "Pamiętaj, że może to zająć trochę czasu."
|
||||
PURGE_NOTICE_2: "Nie uruchamiaj ponownie serwera przed zakończeniem."
|
||||
PURGE_MINIMUM_TIME: "Możesz usunąć tylko dane starsze niż {0} {dni|godzin}."
|
||||
PURGE_NOTICE_1: "Uwaga, może to zająć trochę czasu."
|
||||
PURGE_NOTICE_2: "Nie restartuj serwera przed zakończeniem."
|
||||
PURGE_OPTIMIZING: "Optymalizacja bazy danych. Proszę czekać..."
|
||||
PURGE_PROCESSING: "Przetwarzanie {0} dane..."
|
||||
PURGE_PROCESSING: "Przetwarzanie danych {0}..."
|
||||
PURGE_REPAIRING: "Próba naprawy. To może zająć troche czasu..."
|
||||
PURGE_ROWS: "{0} {wiersz|wiersze} usuniętych danych."
|
||||
PURGE_STARTED: "Usuwanie danych rozpoczęte w dniu „{0}”."
|
||||
PURGE_SUCCESS: "Udało się czyszczenie danych."
|
||||
PURGE_ROWS: "Usunięto {0} {wiersz|wierszy} danych."
|
||||
PURGE_STARTED: "Usuwanie danych rozpoczęte na \"{0}\"."
|
||||
PURGE_SUCCESS: "Czyszczenie danych zakończono pomyślnie."
|
||||
RAM_STATS: "{0}GB / {1}GB RAM"
|
||||
RELOAD_STARTED: "Ponowne ładowanie konfiguracji - proszę czekać."
|
||||
RELOAD_SUCCESS: "Pomyślnie wczytano konfigurację."
|
||||
ROLLBACK_ABORTED: "Wycofanie lub przywracanie zostało przerwane."
|
||||
ROLLBACK_CHUNKS_FOUND: "Znaleziony {0} {kawałek|kawałki} modyfikować."
|
||||
ROLLBACK_CHUNKS_MODIFIED: "Zmodyfikowane {0}/{1} {kawałek|kawałki}."
|
||||
ROLLBACK_COMPLETED: "{Wycofanie|Przywróć|Podgląd} ukończone dla „{0}”."
|
||||
ROLLBACK_EXCLUDED_USERS: "Wyłączony {użytkownik|użytkownicy}: \"{0}”."
|
||||
ROLLBACK_INCLUDE: "{Zawarte|Wykluczone} {blok|jednostka|cel} {typ|typy}: \"{0}”."
|
||||
ROLLBACK_IN_PROGRESS: "Trwa wycofywanie/przywracanie."
|
||||
ROLLBACK_LENGTH: "Zajęty czas: {0} {sekunda|sekundy}."
|
||||
ROLLBACK_CHUNKS_FOUND: "Znaleziono {0} {chunk|chunków} do zmodyfikowania."
|
||||
ROLLBACK_CHUNKS_MODIFIED: "Zmodyfikowano {0}/{1} {chunk|chunków}."
|
||||
ROLLBACK_COMPLETED: "{Wycofywanie|Przywrócenie|Podgląd} ukończone dla \"{0}\"."
|
||||
ROLLBACK_EXCLUDED_USERS: "{Wykluczony użytkownik|Wykluczeni użytkownicy}: \"{0}\"."
|
||||
ROLLBACK_INCLUDE: "{Zawarte|Wykluczone} {bloku|bytu|celu} {typ|typy}: \"{0}\"."
|
||||
ROLLBACK_IN_PROGRESS: "Już trwa wycofywanie/przywracanie."
|
||||
ROLLBACK_LENGTH: "Zajęty czas: {0} {sekunda|sekund}."
|
||||
ROLLBACK_MODIFIED: "{Zmodyfikowane|Modyfikowanie} {0}."
|
||||
ROLLBACK_RADIUS: "Promień: {0} {blok|bloki}."
|
||||
ROLLBACK_SELECTION: "Promień ustawiony na „{0}”."
|
||||
ROLLBACK_STARTED: "{Wycofanie|Przywróć|Podgląd} zaczęło się \"{0}”."
|
||||
ROLLBACK_RADIUS: "Promień: {0} {blok|bloków}."
|
||||
ROLLBACK_SELECTION: "Promień ustawiony na \"{0}\"."
|
||||
ROLLBACK_STARTED: "{Wycofywanie|Przywrócenie|Podgląd} zaczęło się na \"{0}\"."
|
||||
ROLLBACK_TIME: "Zakres czasu: {0}."
|
||||
ROLLBACK_WORLD_ACTION: "Ograniczony do {świat|działanie} \"{0}”."
|
||||
SIGN_HEADER: "Podpisz wiadomości"
|
||||
STATUS_CONSUMER: "Konsument: {0} {przedmiot|przedmioty} w kolejce."
|
||||
STATUS_DATABASE: "Baza danych: Korzystanie {0}."
|
||||
STATUS_INTEGRATION: "{0}: Integracja {włączone|wyłączone}."
|
||||
ROLLBACK_WORLD_ACTION: "Ograniczony do {świata|akcji} \"{0}\"."
|
||||
SIGN_HEADER: "Wiadomości Tabliczki"
|
||||
STATUS_CONSUMER: "Konsument: {0} {przedmiot|przedmiotów} w kolejce."
|
||||
STATUS_DATABASE: "Baza danych: Używa {0}."
|
||||
STATUS_INTEGRATION: "{0}: Integracja {włączona|wyłączona}."
|
||||
STATUS_LICENSE: "Licencja: {0}"
|
||||
STATUS_SYSTEM: "System: {0}"
|
||||
STATUS_VERSION: "Wersja: {0}"
|
||||
TELEPORTED: "Teleportowany do {0}."
|
||||
TELEPORTED_SAFETY: "Teleportowano cię w bezpieczne miejsce."
|
||||
TELEPORTED_SAFETY: "Teleportowano Cię w bezpieczne miejsce."
|
||||
TELEPORT_PLAYERS: "Polecenie Teleport może być używane tylko przez graczy."
|
||||
TIME_DAYS: "{0} {dzień|dni}"
|
||||
TIME_HOURS: "{0} {godzina|godziny}"
|
||||
TIME_MINUTES: "{0} {minuta|minuty}"
|
||||
TIME_SECONDS: "{0} {sekunda|sekundy}"
|
||||
TIME_WEEKS: "{0} {tydzień|tygodnie}"
|
||||
TIME_HOURS: "{0} {godzina|godzin(y)}"
|
||||
TIME_MINUTES: "{0} {minuta|minut(y)}"
|
||||
TIME_MONTHS: "{0} {miesiąc|miesięcy}"
|
||||
TIME_SECONDS: "{0} {sekunda|sekund(y)}"
|
||||
TIME_UNITS: "{/m|/h|/d}"
|
||||
TIME_WEEKS: "{0} {tydzień|tygodni(e)}"
|
||||
TIME_YEARS: "{0} {rok|lat(a)}"
|
||||
UPDATE_ERROR: "Wystąpił błąd podczas sprawdzania aktualizacji."
|
||||
UPDATE_HEADER: "{0} Aktualizacja"
|
||||
UPDATE_HEADER: "Aktualizacja {0}"
|
||||
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_NOT_FOUND: "Nie znaleziono użytkownika \"{0}\"."
|
||||
USER_OFFLINE: "Użytkownik \"{0}\" nie jest online."
|
||||
USING_MYSQL: "Za pomocą MySQL do przechowywania danych."
|
||||
USING_SQLITE: "Za pomocą SQLite do przechowywania danych."
|
||||
USING_MYSQL: "MySQL używany do przechowywania danych."
|
||||
USING_SQLITE: "SQLite używany do przechowywania danych."
|
||||
VALID_DONATION_KEY: "Ważny klucz darowizny."
|
||||
VERSION_NOTICE: "Wersja {0} jest teraz dostępne."
|
||||
VERSION_INCOMPATIBLE: "{0} {1} nie jest wspierany."
|
||||
VERSION_NOTICE: "Wersja {0} jest teraz dostępna."
|
||||
VERSION_REQUIRED: "{0} {1} lub wyższy jest wymagany."
|
||||
WORLD_NOT_FOUND: "Świat \"{0}\" nie znaleziono."
|
||||
WORLD_NOT_FOUND: "Nie znaleziono świata \"{0}\"."
|
||||
+7
-6
@@ -46,7 +46,7 @@ HELP_INSPECT_2: "Щелкните левой кнопкой мыши по бло
|
||||
HELP_INSPECT_3: "Щелкните блок правой кнопкой мыши, чтобы увидеть, какой соседний блок был сломан.."
|
||||
HELP_INSPECT_4: "Поместите блок, чтобы увидеть, какой блок был сломан в этом месте."
|
||||
HELP_INSPECT_5: "Поместите блок в жидкость (и т.п.), чтобы увидеть, кто его поместил."
|
||||
HELP_INSPECT_6: "Щелкните правой кнопкой мыши дверь, сундук и т. Д., Чтобы узнать, кто последний использовал их."
|
||||
HELP_INSPECT_6: "Щелкните правой кнопкой мыши дверь, сундук и т.д., чтобы узнать, кто последний использовал их."
|
||||
HELP_INSPECT_7: "Подсказка: Вы можете использовать «/co i» для быстрого переключения режима инспектора."
|
||||
HELP_INSPECT_COMMAND: "Включает или выключает режим инспектора блоков."
|
||||
HELP_LIST: "Отображает список всех команд."
|
||||
@@ -139,7 +139,7 @@ PATCH_SKIP_UPDATE: "{Пропущена таблица|Пропущен инде
|
||||
PATCH_STARTED: "Выполняется обновление {0}. Пожалуйста, подождите..."
|
||||
PATCH_SUCCESS: "Успешно обновлен до {0}."
|
||||
PATCH_UPGRADING: "Выполняется обновление базы данных. Пожалуйста, подождите..."
|
||||
PLEASE_SELECT: "Пожалуйта выберете: «{0}» или «{1}»."
|
||||
PLEASE_SELECT: "Пожалуйста выберите: «{0}» или «{1}»."
|
||||
PREVIEW_CANCELLED: "Предварительный просмотр отменен."
|
||||
PREVIEW_CANCELLING: "Отмена предварительного просмотра..."
|
||||
PREVIEW_IN_GAME: "Предварительный просмотр откатов доступен только в игре."
|
||||
@@ -180,22 +180,23 @@ STATUS_INTEGRATION: "{0}: Интеграция {включена|отключе
|
||||
STATUS_LICENSE: "Лицензия: {0}"
|
||||
STATUS_VERSION: "Версия: {0}"
|
||||
TELEPORTED: "Телепортирование в {0}."
|
||||
TELEPORTED_SAFETY: "Телепортирование вас в безопасное место."
|
||||
TELEPORT_PLAYERS: "Команду телепортации могут использовать только игроки.."
|
||||
TELEPORTED_SAFETY: "Телепортируем вас в безопасное место."
|
||||
TELEPORT_PLAYERS: "Команду телепортации могут использовать только игроки."
|
||||
TIME_DAYS: "{0} {дня|дней}"
|
||||
TIME_HOURS: "{0} {час|часов}"
|
||||
TIME_MINUTES: "{0} {минута|минут}"
|
||||
TIME_SECONDS: "{0} {секунда|секунд}"
|
||||
TIME_UNITS: "{/m|/h|/d}"
|
||||
TIME_WEEKS: "{0} {неделя|недель}"
|
||||
UPDATE_ERROR: "Произошла ошибка при проверке обновлений."
|
||||
UPDATE_HEADER: "{0} Обновление"
|
||||
UPDATE_NOTICE: "Примечание: теперь доступен {0}."
|
||||
UPGRADE_IN_PROGRESS: "Выполняется обновление. Пожалуйста, повторите попытку позже."
|
||||
USER_NOT_FOUND: "Пользователь «{0}» не найден."
|
||||
USER_OFFLINE: "Пользователь \"{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}» не найден."
|
||||
@@ -186,6 +186,7 @@ TIME_DAYS: "{0} {gün|gün}"
|
||||
TIME_HOURS: "{0} {saat|saat}"
|
||||
TIME_MINUTES: "{0} {dakika|dakika}"
|
||||
TIME_SECONDS: "{0} {saniye|saniye}"
|
||||
TIME_UNITS: "{/m|/h|/d}"
|
||||
TIME_WEEKS: "{0} {hafta|hafta}"
|
||||
UPDATE_ERROR: "Güncellemeler kontrol edilirken bir hata oluştu."
|
||||
UPDATE_HEADER: "{0} Güncelleme"
|
||||
|
||||
@@ -186,6 +186,7 @@ TIME_DAYS: "{0} {день|дні}"
|
||||
TIME_HOURS: "{0} {година|години}"
|
||||
TIME_MINUTES: "{0} {хвилина|хвилини}"
|
||||
TIME_SECONDS: "{0} {секунда|секунди}"
|
||||
TIME_UNITS: "{/m|/h|/d}"
|
||||
TIME_WEEKS: "{0} {тиждень|тиждень}"
|
||||
UPDATE_ERROR: "Під час перевірки оновлень сталася помилка."
|
||||
UPDATE_HEADER: "{0} Оновлення"
|
||||
|
||||
@@ -186,6 +186,7 @@ TIME_DAYS: "{0} {ngày|ngày}"
|
||||
TIME_HOURS: "{0} {giờ|giờ}"
|
||||
TIME_MINUTES: "{0} {phút|phút}"
|
||||
TIME_SECONDS: "{0} {giây|giây}"
|
||||
TIME_UNITS: "{/m|/h|/d}"
|
||||
TIME_WEEKS: "{0} {tuần|tuần}"
|
||||
UPDATE_ERROR: "Đã xảy ra lỗi khi kiểm tra các bản cập nhật."
|
||||
UPDATE_HEADER: "{0} Cập nhật"
|
||||
|
||||
+130
-119
@@ -1,202 +1,213 @@
|
||||
# CoreProtect Language File (zh-CN)
|
||||
# Origin: Intelli, Translator: DreamVoid, StarWishsama, YuanYuanOwO
|
||||
# Origin: Intelli, Translator: DreamVoid, StarWishsama, YuanYuanOwO, Halogly
|
||||
|
||||
ACTION_NOT_SUPPORTED: "该命令不支持该操作。"
|
||||
ACTION_NOT_SUPPORTED: "此命令不支持该操作。"
|
||||
AMOUNT_BLOCK: "{0}个{方块|方块}"
|
||||
AMOUNT_CHUNK: "{0}个{区块|区块}"
|
||||
AMOUNT_ENTITY: "{0}个{实体|实体}"
|
||||
AMOUNT_ITEM: "{0}个{物品|物品}"
|
||||
API_TEST: "API 测试成功。"
|
||||
CACHE_ERROR: "警告: 验证缓存 {0} 时出错。"
|
||||
CACHE_RELOAD: "正在强制从数据库中重新加载{映射|世界}的缓存。"
|
||||
CACHE_ERROR: "警告:验证缓存 {0} 时出错。"
|
||||
CACHE_RELOAD: "正在强制从数据库中重新加载{映射|世界}缓存。"
|
||||
CHECK_CONFIG: "请检查 config.yml 文件"
|
||||
COMMAND_CONSOLE: "请在控制台中运行此命令。"
|
||||
COMMAND_NOT_FOUND: "找不到命令 \"{0}\""
|
||||
COMMAND_THROTTLED: "请稍等片刻,然后重试。"
|
||||
COMMAND_NOT_FOUND: "命令 \"{0}\" 未找到。"
|
||||
COMMAND_THROTTLED: "请稍后再试。"
|
||||
CONSUMER_ERROR: "数据处理队列已经{暂停|恢复}。"
|
||||
CONSUMER_TOGGLED: "数据处理队列现已{暂停|恢复}。"
|
||||
CONSUMER_TOGGLED: "数据处理队列已{暂停|恢复}。"
|
||||
CONTAINER_HEADER: "容器物品变更记录"
|
||||
DATABASE_BUSY: "数据库繁忙,请稍后重试。"
|
||||
CPU_CORES: "CPU 核心。"
|
||||
DATABASE_BUSY: "数据库繁忙,请稍后再试。"
|
||||
DATABASE_INDEX_ERROR: "无法验证数据库索引。"
|
||||
DATABASE_LOCKED_1: "数据库已被锁定,请等待至少15秒后重试..."
|
||||
DATABASE_LOCKED_2: "数据库已在使用,请再试一次。"
|
||||
DATABASE_LOCKED_3: "禁用数据库锁定,请在配置文件中设置 \"database-lock: false\"。"
|
||||
DATABASE_LOCKED_1: "数据库已锁定,请等待约15秒后再试..."
|
||||
DATABASE_LOCKED_2: "数据库正在使用中,请稍后再试。"
|
||||
DATABASE_LOCKED_3: "要禁用数据库锁定,请在配置文件中设置 \"database-lock: false\"。"
|
||||
DATABASE_LOCKED_4: "禁用数据库锁定可能会导致数据损坏。"
|
||||
DATABASE_UNREACHABLE: "数据库无法访问。正在丢弃数据并关闭。"
|
||||
DATABASE_UNREACHABLE: "数据库连接失败,正在丢弃数据并关闭。"
|
||||
DEVELOPMENT_BRANCH: "检测到正在使用开发分支的版本,跳过使用补丁脚本。"
|
||||
DIRT_BLOCK: "已在你的下方放置了一个泥土。"
|
||||
DISABLE_SUCCESS: "禁用 {0} 成功!"
|
||||
ENABLE_FAILED: "无法启用 {0}!"
|
||||
ENABLE_SUCCESS: "{0} 已成功启用!"
|
||||
DISABLE_SUCCESS: "已成功禁用 {0}!"
|
||||
DONATION_KEY_REQUIRED: "需要有效的捐赠密钥才能执行此命令。"
|
||||
ENABLE_FAILED: "无法启用 {0}。"
|
||||
ENABLE_SUCCESS: "已成功启用 {0}!"
|
||||
ENJOY_COREPROTECT: "对 {0} 感到满意吗?请加入我们的 Discord 频道!"
|
||||
FINISHING_CONVERSION: "正在完成数据转换,请稍等..."
|
||||
FINISHING_LOGGING: "正在完成数据记录,请稍等..."
|
||||
FIRST_VERSION: "初始化数据库: {0}"
|
||||
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_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_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_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_INSPECT_7: "提示:你可以使用 \"/co i\" 进行快速查询。"
|
||||
HELP_INSPECT_COMMAND: "开启或关闭方块检查器。"
|
||||
HELP_LIST: "列出所有命令。"
|
||||
HELP_LOOKUP_1: "命令快捷方式。"
|
||||
HELP_LOOKUP_2: "在查询记录后使用以查看日志"
|
||||
HELP_LOOKUP_2: "检查方块后使用以查看日志。"
|
||||
HELP_LOOKUP_COMMAND: "高级方块数据查询。"
|
||||
HELP_NO_INFO: "命令的信息 \"{0}\" 未找到。"
|
||||
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_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] (只会影响你周围十格方块的范围)"
|
||||
HELP_RADIUS_2: "例子:[r: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: "检查器已经{启用|禁用}了。"
|
||||
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} 的版本不兼容。"
|
||||
INTEGRATION_ERROR: "无法{初始化|禁用} {0} 的日志记录。"
|
||||
INTEGRATION_SUCCESS: "已成功{初始化|禁用} {0} 的日志记录。"
|
||||
INTEGRATION_VERSION: "{0} 版本无效。"
|
||||
INTERACTIONS_HEADER: "玩家交互"
|
||||
INVALID_ACTION: "这不是有效的动作。"
|
||||
INVALID_BRANCH_1: "插件版本无效(未设置分支)。"
|
||||
INVALID_BRANCH_2: "要继续,请将项目分支设置为 \"开发\"。"
|
||||
INVALID_ACTION: "这不是一个有效的操作。"
|
||||
INVALID_BRANCH_1: "插件版本无效(尚未设置分支)。"
|
||||
INVALID_BRANCH_2: "请将项目分支设置为 \"development\" 以继续。"
|
||||
INVALID_BRANCH_3: "运行开发版本的插件可能会导致数据损坏。"
|
||||
INVALID_CONTAINER: "请检查有效的容器。"
|
||||
INVALID_CONTAINER: "请先检查一个有效的容器。"
|
||||
INVALID_DONATION_KEY: "无效的捐赠密钥。"
|
||||
INVALID_INCLUDE: "\"{0}\" 是无效的方块/实体名称。"
|
||||
INVALID_INCLUDE_COMBO: "那是无效的方块/实体组合。"
|
||||
INVALID_RADIUS: "请输入有效的半径。"
|
||||
INVALID_SELECTION: "没有找到 {0} 的选择。"
|
||||
INVALID_USERNAME: "玩家名 \"{0}\" 不存在或已离线。"
|
||||
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}。"
|
||||
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_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}."
|
||||
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_LOOKUP_TIME: "请指定要{查找|回滚|恢复}的时间。"
|
||||
MISSING_LOOKUP_USER: "请指定要查找的玩家或{方块|半径}。"
|
||||
MISSING_PARAMETERS: "请使用 \"{0}\"。"
|
||||
MISSING_ROLLBACK_RADIUS: "你没有指定{回滚|恢复}半径。"
|
||||
MISSING_ROLLBACK_USER: "你没有指定{回滚|恢复}的玩家操作。"
|
||||
MISSING_ROLLBACK_RADIUS: "你没有指定{回滚|恢复}的半径。"
|
||||
MISSING_ROLLBACK_USER: "你没有指定{回滚|恢复}的玩家。"
|
||||
MYSQL_UNAVAILABLE: "无法连接到 MySQL 服务器。"
|
||||
NO_DATA: "没有在 {0} 中找到数据"
|
||||
NO_DATA_LOCATION: "此位置找不到任何{数据|存取|交互|消息}的记录。"
|
||||
NETWORK_CONNECTION: "{0} 连接{成功|失败},正在使用 {1} {2}。"
|
||||
NETWORK_TEST: "网络测试数据已成功发送。"
|
||||
NO_DATA: "没有在 {0} 中找到数据。"
|
||||
NO_DATA_LOCATION: "此位置找不到任何{数据|存取|交互|消息}记录。"
|
||||
NO_PERMISSION: "你没有权限执行此操作。"
|
||||
NO_RESULTS: "未找到结果。"
|
||||
NO_RESULTS_PAGE: "没有在指定页面找到{结果|数据}。"
|
||||
NO_ROLLBACK: "没有找到{等待的|上一个}回滚/恢复。"
|
||||
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}\"。"
|
||||
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: "你不能预览{容器|背包}物品交换。"
|
||||
PRIMARY_THREAD_ERROR: "该 API 方法不能在主线程上使用。"
|
||||
PURGE_ABORTED: "清除失败,数据库可能已损坏。"
|
||||
PURGE_ERROR: "无法处理 {0} 数据!"
|
||||
PURGE_FAILED: "数据清除失败,请稍后再试。"
|
||||
PURGE_FAILED: "清除失败,请稍后再试。"
|
||||
PURGE_IN_PROGRESS: "正在清除数据,请稍后再试。"
|
||||
PURGE_MINIMUM_TIME: "你只能清除早于 {0} {天|小时}的数据."
|
||||
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: "数据清除成功。"
|
||||
PURGE_NOTICE_2: "完成前请勿重新启动服务器。"
|
||||
PURGE_OPTIMIZING: "正在优化数据库,请稍候..."
|
||||
PURGE_PROCESSING: "正在处理 {0} 的数据..."
|
||||
PURGE_REPAIRING: "正在尝试修复。这可能需要一些时间..."
|
||||
PURGE_ROWS: "{0}{行|行}数据已删除。"
|
||||
PURGE_STARTED: "数据清除开始于 \"{0}\"。"
|
||||
PURGE_SUCCESS: "数据已清除。"
|
||||
RAM_STATS: "{0}GB / {1}GB 内存"
|
||||
RELOAD_STARTED: "正在重新加载配置文件 - 请稍候。"
|
||||
RELOAD_SUCCESS: "配置文件已重新加载成功。"
|
||||
RELOAD_SUCCESS: "配置文件已重新加载。"
|
||||
ROLLBACK_ABORTED: "回滚或恢复已中止。"
|
||||
ROLLBACK_CHUNKS_FOUND: "找到 {0} 个{区块|区块}需要更改。"
|
||||
ROLLBACK_CHUNKS_MODIFIED: "已修改 {0}/{1} 个{区块|区块}."
|
||||
ROLLBACK_COMPLETED: "{回滚|恢复|预览}已对以下对象完成: {0}。"
|
||||
ROLLBACK_EXCLUDED_USERS: "已排除{玩家|玩家}: \"{0}\"。"
|
||||
ROLLBACK_INCLUDE: "{包括|不包括}{方块|实体|目标}{类型|类型}: \"{0}\"。"
|
||||
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: "将你传送到安全地点。"
|
||||
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_SYSTEM: "系统:{0}"
|
||||
STATUS_VERSION: "版本:{0}"
|
||||
TELEPORTED: "传送到 {0}。"
|
||||
TELEPORTED_SAFETY: "将你传送到安全的位置。"
|
||||
TELEPORT_PLAYERS: "只有玩家才能使用传送命令。"
|
||||
TIME_DAYS: "{0}{天|天}"
|
||||
TIME_HOURS: "{0}{小时|小时}"
|
||||
TIME_MINUTES: "{0}{分钟|分钟}"
|
||||
TIME_MONTHS: "{0} {月|月}"
|
||||
TIME_SECONDS: "{0}{秒|秒}"
|
||||
TIME_UNITS: "{分钟|小时|天}"
|
||||
TIME_WEEKS: "{0}{周|周}"
|
||||
TIME_YEARS: "{0} {年|年}"
|
||||
UPDATE_ERROR: "检查更新时出错。"
|
||||
UPDATE_HEADER: "{0} 更新"
|
||||
UPDATE_NOTICE: "注意: {0} 现在可用。"
|
||||
UPDATE_NOTICE: "注意:{0} 现在可用。"
|
||||
UPGRADE_IN_PROGRESS: "正在进行升级,请稍后再试。"
|
||||
USER_NOT_FOUND: "玩家\"{0}\"未找到。"
|
||||
USER_OFFLINE: "玩家\"{0}\"不在线。"
|
||||
USER_NOT_FOUND: "玩家 \"{0}\" 未找到。"
|
||||
USER_OFFLINE: "玩家 \"{0}\" 不在线。"
|
||||
USING_MYSQL: "使用 MySQL 用于数据存储。"
|
||||
USING_SQLITE: "使用 SQLite 用于数据存储。"
|
||||
VALID_DONATION_KEY: "有效的捐赠密钥。"
|
||||
VERSION_INCOMPATIBLE: "{0} {1} 不受支持。"
|
||||
VERSION_NOTICE: "版本 {0} 现在可用。"
|
||||
VERSION_REQUIRED: "{0} 需要使用 {1} 或更高版本。"
|
||||
WORLD_NOT_FOUND: "找不到世界 \"{0}\"。"
|
||||
WORLD_NOT_FOUND: "世界 \"{0}\" 未找到。"
|
||||
@@ -193,6 +193,7 @@ TIME_DAYS: "{0} {天|天}"
|
||||
TIME_HOURS: "{0} {小時|小時}"
|
||||
TIME_MINUTES: "{0} {分鐘|分鐘}"
|
||||
TIME_SECONDS: "{0} {秒|秒}"
|
||||
TIME_UNITS: "{/m|/h|/d}"
|
||||
TIME_WEEKS: "{0} {週|週}"
|
||||
UPDATE_ERROR: "檢查更新時發生錯誤。"
|
||||
UPDATE_HEADER: "{0} 更新"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>net.coreprotect</groupId>
|
||||
<artifactId>CoreProtect</artifactId>
|
||||
<version>23.0</version>
|
||||
<version>23.2</version>
|
||||
<properties>
|
||||
<project.branch></project.branch>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
@@ -26,7 +26,7 @@
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<version>3.15.0</version>
|
||||
<configuration>
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
@@ -47,7 +47,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<version>3.5.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestEntries>
|
||||
@@ -59,7 +59,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.4</version>
|
||||
<version>3.6.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
@@ -105,7 +105,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.2.3</version>
|
||||
<version>3.5.5</version>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<plugin.version>${project.version}</plugin.version>
|
||||
@@ -113,6 +113,31 @@
|
||||
<skipTests>${skipTests}</skipTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<version>3.6.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>validate</phase>
|
||||
<goals><goal>enforce</goal></goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<requireNoRepositories>
|
||||
<allowedRepositories>
|
||||
<allowedRepository>central</allowedRepository>
|
||||
<allowedRepository>enginehub-repo</allowedRepository>
|
||||
<allowedRepository>spigot-repo</allowedRepository>
|
||||
<allowedRepository>paper-repo</allowedRepository>
|
||||
<allowedRepository>codemc-repo</allowedRepository>
|
||||
<allowedRepository>jitpack.io</allowedRepository>
|
||||
</allowedRepositories>
|
||||
</requireNoRepositories>
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
@@ -127,7 +152,7 @@
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<version>3.2.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>install-validation</id>
|
||||
@@ -152,6 +177,18 @@
|
||||
</profile>
|
||||
</profiles>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>central</id>
|
||||
<url>https://repo.maven.apache.org/maven2/</url>
|
||||
<releases><enabled>true</enabled></releases>
|
||||
<snapshots><enabled>false</enabled></snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>enginehub-repo</id>
|
||||
<url>https://maven.enginehub.org/repo/</url>
|
||||
<releases><enabled>true</enabled></releases>
|
||||
<snapshots><enabled>true</enabled></snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
|
||||
@@ -169,71 +206,62 @@
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.intellectualsites.bom</groupId>
|
||||
<artifactId>bom-newest</artifactId> <!-- Ref: https://github.com/IntellectualSites/bom -->
|
||||
<version>1.45</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<dependencies>
|
||||
<!--
|
||||
paper-api: io.papermc.paper
|
||||
paper-api (<= 1.16): com.destroystokyo.paper
|
||||
paper-api (<= 1.16): com.destroystokyo.paper / 1.16.1-R0.1-SNAPSHOT
|
||||
spigot-api: org.spigotmc
|
||||
bukkit: org.bukkit
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>io.papermc.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<version>1.21.1-R0.1-SNAPSHOT</version>
|
||||
<version>26.1.2.build.9-alpha</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<version>3.2.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fastasyncworldedit</groupId>
|
||||
<artifactId>FastAsyncWorldEdit-Core</artifactId>
|
||||
<version>2.15.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fastasyncworldedit</groupId>
|
||||
<artifactId>FastAsyncWorldEdit-Bukkit</artifactId>
|
||||
<version>2.15.0</version>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>FastAsyncWorldEdit-Core</artifactId>
|
||||
<groupId>*</groupId>
|
||||
<artifactId>FastAsyncWorldEdit-Core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>5.0.1</version>
|
||||
<version>7.0.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.oshi</groupId>
|
||||
<artifactId>oshi-core</artifactId>
|
||||
<version>6.6.2</version>
|
||||
<version>6.12.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.19.0</version>
|
||||
<version>2.25.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>2.19.0</version>
|
||||
<version>2.25.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.DeadSilenceIV</groupId>
|
||||
@@ -245,31 +273,31 @@
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.10.1</version>
|
||||
<version>5.14.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.10.1</version>
|
||||
<version>5.14.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-params</artifactId>
|
||||
<version>5.10.1</version>
|
||||
<version>5.14.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>5.16.1</version>
|
||||
<version>5.23.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-junit-jupiter</artifactId>
|
||||
<version>5.16.1</version>
|
||||
<version>5.23.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -281,26 +309,26 @@
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.45.1.0</version>
|
||||
<version>3.53.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>2.0.12</version>
|
||||
<version>2.0.17</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
<artifactId>byte-buddy</artifactId>
|
||||
<version>1.16.1</version>
|
||||
<version>1.18.8</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
<artifactId>byte-buddy-agent</artifactId>
|
||||
<version>1.16.1</version>
|
||||
<version>1.18.8</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
</project>
|
||||
@@ -41,7 +41,7 @@ public class CoreProtectAPI extends Queue {
|
||||
/**
|
||||
* Current version of the API
|
||||
*/
|
||||
private static final int API_VERSION = 10;
|
||||
private static final int API_VERSION = 11;
|
||||
|
||||
public static class ParseResult extends net.coreprotect.api.result.ParseResult {
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package net.coreprotect.bukkit;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.DyeColor;
|
||||
@@ -19,7 +22,10 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.block.BlockExplodeEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
@@ -85,6 +91,7 @@ public class BukkitAdapter implements BukkitInterface {
|
||||
}
|
||||
|
||||
// -------------------- Basic data conversion methods --------------------
|
||||
public static Set<Material> EMPTY_SET = new HashSet<>(Arrays.asList());
|
||||
|
||||
@Override
|
||||
public String parseLegacyName(String name) {
|
||||
@@ -311,6 +318,17 @@ public class BukkitAdapter implements BukkitInterface {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldLogExplosion(Event event){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getExplodedBlock(BlockExplodeEvent event){
|
||||
// accoding to the Bukkit docs this will always return air
|
||||
return event.getBlock().getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGlowing(Sign sign, boolean isFront, boolean isGlowing) {
|
||||
// Base implementation does nothing
|
||||
@@ -350,4 +368,35 @@ public class BukkitAdapter implements BukkitInterface {
|
||||
public Object getRegistryValue(String key, Object tClass) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCrafter(InventoryType type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isBundle(Material material) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCopperChest(Material material) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShelf(Material material){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Material> copperChestMaterials() {
|
||||
return EMPTY_SET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Material> shelfMaterials() {
|
||||
return EMPTY_SET;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package net.coreprotect.bukkit;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
@@ -13,7 +14,10 @@ import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.block.BlockExplodeEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
@@ -130,6 +134,17 @@ public interface BukkitInterface {
|
||||
*/
|
||||
boolean isChiseledBookshelf(Material material);
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a material is a shelf of any wood kind.
|
||||
*
|
||||
* @param material
|
||||
* The material to check
|
||||
* @return true if the material is a shelf, false otherwise
|
||||
*/
|
||||
boolean isShelf(Material material);
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a material is a bookshelf book.
|
||||
*
|
||||
@@ -139,6 +154,17 @@ public interface BukkitInterface {
|
||||
*/
|
||||
boolean isBookshelfBook(Material material);
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a material is a bundle.
|
||||
*
|
||||
* @param material
|
||||
* The material to check
|
||||
* @return true if the material is a bundle, false otherwise
|
||||
*/
|
||||
boolean isBundle(Material material);
|
||||
|
||||
|
||||
/**
|
||||
* Gets the seeds material for a plant material.
|
||||
*
|
||||
@@ -400,6 +426,27 @@ public interface BukkitInterface {
|
||||
*/
|
||||
boolean isSignFront(SignChangeEvent event);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether an explosion event should be logged or not. (i.e. wind charge explosions)
|
||||
*
|
||||
* @param event
|
||||
* The explosion event (Block or Entity ExplodeEvent)
|
||||
* @return true if the explosion should affect blocks
|
||||
*/
|
||||
boolean shouldLogExplosion(Event event);
|
||||
|
||||
|
||||
/**
|
||||
* Gets the material of the block that exploded
|
||||
*
|
||||
* @param event
|
||||
* The block explosion event
|
||||
* @return the material of the block that caused the explosion
|
||||
*/
|
||||
Material getExplodedBlock(BlockExplodeEvent event);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Registry methods
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -432,4 +479,13 @@ public interface BukkitInterface {
|
||||
* @return The parsed name
|
||||
*/
|
||||
String parseLegacyName(String name);
|
||||
|
||||
boolean isCrafter(InventoryType type);
|
||||
|
||||
boolean isCopperChest(Material material);
|
||||
|
||||
Set<Material> copperChestMaterials();
|
||||
|
||||
Set<Material> shelfMaterials();
|
||||
|
||||
}
|
||||
@@ -152,9 +152,15 @@ public class Bukkit_v1_17 extends BukkitAdapter {
|
||||
return super.getItemMeta(itemMeta, list, metadata, slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBundle(Material material) {
|
||||
return material == Material.BUNDLE;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean setItemMeta(Material rowType, ItemStack itemstack, List<Map<String, Object>> map) {
|
||||
if (rowType == Material.BUNDLE) {
|
||||
if (BukkitAdapter.ADAPTER.isBundle(rowType)) {
|
||||
BundleMeta meta = (BundleMeta) itemstack.getItemMeta();
|
||||
for (Map<String, Object> itemData : map) {
|
||||
ItemStack itemStack = ItemUtils.unserializeItemStack(itemData);
|
||||
|
||||
@@ -13,6 +13,7 @@ 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.BlockExplodeEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -297,4 +298,10 @@ public class Bukkit_v1_20 extends Bukkit_v1_19 {
|
||||
return super.getArrowMeta(arrow, itemStack);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getExplodedBlock(BlockExplodeEvent event){
|
||||
// accoding to the Bukkit docs this will always return air
|
||||
return event.getExplodedBlockState().getType();
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,22 @@
|
||||
package net.coreprotect.bukkit;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ExplosionResult;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.block.BlockExplodeEvent;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
|
||||
|
||||
import net.coreprotect.model.BlockGroup;
|
||||
|
||||
@@ -20,7 +28,11 @@ import net.coreprotect.model.BlockGroup;
|
||||
* - Registry handling for named objects
|
||||
* - Updated interaction blocks
|
||||
*/
|
||||
public class Bukkit_v1_21 extends Bukkit_v1_20 implements BukkitInterface {
|
||||
public class Bukkit_v1_21 extends Bukkit_v1_20 {
|
||||
|
||||
public static Set<Material> COPPER_CHESTS = new HashSet<>(Arrays.asList());
|
||||
public static Set<Material> SHELVES = new HashSet<>(Arrays.asList());
|
||||
public static Set<Material> BUNDLES = new HashSet<>(Arrays.asList());
|
||||
|
||||
/**
|
||||
* Initializes the Bukkit_v1_21 adapter with 1.21-specific block groups and mappings.
|
||||
@@ -29,6 +41,11 @@ public class Bukkit_v1_21 extends Bukkit_v1_20 implements BukkitInterface {
|
||||
public Bukkit_v1_21() {
|
||||
initializeBlockGroups();
|
||||
initializeTrapdoorBlocks();
|
||||
initializeBundles();
|
||||
BlockGroup.INTERACT_BLOCKS.addAll(copperChestMaterials());
|
||||
BlockGroup.CONTAINERS.addAll(copperChestMaterials());
|
||||
BlockGroup.UPDATE_STATE.addAll(copperChestMaterials());
|
||||
BlockGroup.CONTAINERS.addAll(shelfMaterials());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,6 +75,20 @@ public class Bukkit_v1_21 extends Bukkit_v1_20 implements BukkitInterface {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the bundles group to enable the ability to roll back dyed bundles correctly.
|
||||
* It needs to check whether dyed bundles exist because they were added in 1.21.2.
|
||||
*/
|
||||
public void initializeBundles(){
|
||||
if (BUNDLES.isEmpty()) {
|
||||
Material bundle = Material.getMaterial("RED_BUNDLE");
|
||||
if (bundle != null) {
|
||||
BUNDLES.addAll(Tag.ITEMS_BUNDLES.getValues());
|
||||
}
|
||||
BUNDLES.add(Material.BUNDLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to add a block to a block group if it's not already present.
|
||||
*
|
||||
@@ -103,6 +134,7 @@ public class Bukkit_v1_21 extends Bukkit_v1_20 implements BukkitInterface {
|
||||
return ((Keyed) value).getKey().toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a registry value from a key string and class.
|
||||
* Used for deserializing registry objects.
|
||||
@@ -154,4 +186,77 @@ public class Bukkit_v1_21 extends Bukkit_v1_20 implements BukkitInterface {
|
||||
wolf.setVariant(variant);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCrafter(InventoryType type) {
|
||||
return type == InventoryType.CRAFTER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCopperChest(Material material) {
|
||||
if (COPPER_CHESTS.contains(material) && material != Material.CHEST) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShelf(Material material) {
|
||||
return SHELVES.contains(material);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBundle(Material material) {
|
||||
return Tag.ITEMS_BUNDLES.getValues().contains(material);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<Material> copperChestMaterials() {
|
||||
if (COPPER_CHESTS.isEmpty()) {
|
||||
Material copperChest = Material.getMaterial("COPPER_CHEST");
|
||||
if (copperChest == null) {
|
||||
COPPER_CHESTS.add(Material.CHEST);
|
||||
}
|
||||
else {
|
||||
COPPER_CHESTS.add(Material.getMaterial("COPPER_CHEST"));
|
||||
COPPER_CHESTS.add(Material.getMaterial("EXPOSED_COPPER_CHEST"));
|
||||
COPPER_CHESTS.add(Material.getMaterial("WEATHERED_COPPER_CHEST"));
|
||||
COPPER_CHESTS.add(Material.getMaterial("OXIDIZED_COPPER_CHEST"));
|
||||
COPPER_CHESTS.add(Material.getMaterial("WAXED_COPPER_CHEST"));
|
||||
COPPER_CHESTS.add(Material.getMaterial("WAXED_EXPOSED_COPPER_CHEST"));
|
||||
COPPER_CHESTS.add(Material.getMaterial("WAXED_WEATHERED_COPPER_CHEST"));
|
||||
COPPER_CHESTS.add(Material.getMaterial("WAXED_OXIDIZED_COPPER_CHEST"));
|
||||
}
|
||||
}
|
||||
|
||||
return COPPER_CHESTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Material> shelfMaterials() {
|
||||
if (SHELVES.isEmpty()) {
|
||||
Material shelf = Material.getMaterial("OAK_SHELF");
|
||||
if (shelf != null) {
|
||||
SHELVES.addAll(Tag.WOODEN_SHELVES.getValues());
|
||||
}
|
||||
}
|
||||
|
||||
return SHELVES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldLogExplosion(Event event){
|
||||
ExplosionResult result = null;
|
||||
|
||||
if (event instanceof EntityExplodeEvent){
|
||||
result = ((EntityExplodeEvent)event).getExplosionResult();
|
||||
} else if (event instanceof BlockExplodeEvent){
|
||||
result = ((BlockExplodeEvent)event).getExplosionResult();
|
||||
}
|
||||
return !(result == ExplosionResult.KEEP ||
|
||||
result == ExplosionResult.TRIGGER_BLOCK
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -39,9 +39,13 @@ public class StatusCommand {
|
||||
String versionCheck = "";
|
||||
if (Config.getGlobal().CHECK_UPDATES) {
|
||||
String latestVersion = NetworkHandler.latestVersion();
|
||||
String latestEdgeVersion = NetworkHandler.latestEdgeVersion();
|
||||
if (latestVersion != null) {
|
||||
versionCheck = " (" + Phrase.build(Phrase.LATEST_VERSION, "v" + latestVersion) + ")";
|
||||
}
|
||||
else if (latestEdgeVersion != null && !VersionUtils.isCommunityEdition()) {
|
||||
versionCheck = " (" + Phrase.build(Phrase.LATEST_VERSION, "v" + latestEdgeVersion) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
Chat.sendMessage(player, Color.WHITE + "----- " + Color.DARK_AQUA + "CoreProtect" + (VersionUtils.isCommunityEdition() ? " " + ConfigHandler.COMMUNITY_EDITION : "") + Color.WHITE + " -----");
|
||||
|
||||
@@ -40,6 +40,11 @@ import net.coreprotect.utility.VersionUtils;
|
||||
import oshi.hardware.CentralProcessor;
|
||||
|
||||
public class ConfigHandler extends Queue {
|
||||
|
||||
public enum CacheType {
|
||||
MATERIALS, BLOCKDATA, ART, ENTITIES, WORLDS
|
||||
}
|
||||
|
||||
public static int SERVER_VERSION = 0;
|
||||
public static final int EDITION_VERSION = 2;
|
||||
public static final String EDITION_BRANCH = VersionUtils.getBranch();
|
||||
@@ -47,7 +52,8 @@ public class ConfigHandler extends Queue {
|
||||
public static final String COMMUNITY_EDITION = "Community Edition";
|
||||
public static final String JAVA_VERSION = "11.0";
|
||||
public static final String MINECRAFT_VERSION = "1.16";
|
||||
public static final String LATEST_VERSION = "1.21.8";
|
||||
public static final String PATCH_VERSION = "23.2";
|
||||
public static final String LATEST_VERSION = "26.1";
|
||||
public static String path = "plugins/CoreProtect/";
|
||||
public static String sqlite = "database.db";
|
||||
public static String host = "127.0.0.1";
|
||||
@@ -268,7 +274,7 @@ public class ConfigHandler extends Queue {
|
||||
Database.createDatabaseTables(ConfigHandler.prefix, false, null, Config.getGlobal().MYSQL, false);
|
||||
}
|
||||
|
||||
public static void loadTypes(Statement statement) {
|
||||
public static void loadMaterials(Statement statement) {
|
||||
try {
|
||||
String query = "SELECT id,material FROM " + ConfigHandler.prefix + "material_map";
|
||||
ResultSet rs = statement.executeQuery(query);
|
||||
@@ -286,9 +292,16 @@ public class ConfigHandler extends Queue {
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
query = "SELECT id,data FROM " + ConfigHandler.prefix + "blockdata_map";
|
||||
rs = statement.executeQuery(query);
|
||||
public static void loadBlockdata(Statement statement) {
|
||||
try {
|
||||
String query = "SELECT id,data FROM " + ConfigHandler.prefix + "blockdata_map";
|
||||
ResultSet rs = statement.executeQuery(query);
|
||||
ConfigHandler.blockdata.clear();
|
||||
ConfigHandler.blockdataReversed.clear();
|
||||
blockdataId = 0;
|
||||
@@ -303,9 +316,16 @@ public class ConfigHandler extends Queue {
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
query = "SELECT id,art FROM " + ConfigHandler.prefix + "art_map";
|
||||
rs = statement.executeQuery(query);
|
||||
public static void loadArt(Statement statement) {
|
||||
try {
|
||||
String query = "SELECT id,art FROM " + ConfigHandler.prefix + "art_map";
|
||||
ResultSet rs = statement.executeQuery(query);
|
||||
ConfigHandler.art.clear();
|
||||
ConfigHandler.artReversed.clear();
|
||||
artId = 0;
|
||||
@@ -320,9 +340,16 @@ public class ConfigHandler extends Queue {
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
query = "SELECT id,entity FROM " + ConfigHandler.prefix + "entity_map";
|
||||
rs = statement.executeQuery(query);
|
||||
public static void loadEntities(Statement statement) {
|
||||
try {
|
||||
String query = "SELECT id,entity FROM " + ConfigHandler.prefix + "entity_map";
|
||||
ResultSet rs = statement.executeQuery(query);
|
||||
ConfigHandler.entities.clear();
|
||||
ConfigHandler.entitiesReversed.clear();
|
||||
entityId = 0;
|
||||
@@ -343,6 +370,67 @@ public class ConfigHandler extends Queue {
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadTypes(Statement statement) {
|
||||
loadMaterials(statement);
|
||||
loadBlockdata(statement);
|
||||
loadArt(statement);
|
||||
loadEntities(statement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unified method to reload cache from database when DATABASE_LOCK is false (multi-server setup)
|
||||
*
|
||||
* @param type
|
||||
* The type of cache to reload
|
||||
* @param name
|
||||
* The name to look up after reload
|
||||
* @return The ID if found after reload, or -1 if not found
|
||||
*/
|
||||
public static int reloadAndGetId(CacheType type, String name) {
|
||||
// Only reload if DATABASE_LOCK is false (multi-server setup)
|
||||
if (Config.getGlobal().DATABASE_LOCK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
try (Connection connection = Database.getConnection(true)) {
|
||||
if (connection != null) {
|
||||
Statement statement = connection.createStatement();
|
||||
|
||||
// Reload appropriate cache based on type
|
||||
switch (type) {
|
||||
case MATERIALS:
|
||||
loadMaterials(statement);
|
||||
statement.close();
|
||||
return materials.getOrDefault(name, -1);
|
||||
case BLOCKDATA:
|
||||
loadBlockdata(statement);
|
||||
statement.close();
|
||||
return blockdata.getOrDefault(name, -1);
|
||||
case ART:
|
||||
loadArt(statement);
|
||||
statement.close();
|
||||
return art.getOrDefault(name, -1);
|
||||
case ENTITIES:
|
||||
loadEntities(statement);
|
||||
statement.close();
|
||||
return entities.getOrDefault(name, -1);
|
||||
case WORLDS:
|
||||
loadWorlds(statement);
|
||||
statement.close();
|
||||
return worlds.getOrDefault(name, -1);
|
||||
default:
|
||||
statement.close();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static void loadWorlds(Statement statement) {
|
||||
try {
|
||||
String query = "SELECT id,world FROM " + ConfigHandler.prefix + "world";
|
||||
|
||||
@@ -54,17 +54,18 @@ public class BlockBreakLogger {
|
||||
blockData = overrideData;
|
||||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user, location);
|
||||
if (Config.getGlobal().API_ENABLED && !Bukkit.isPrimaryThread()) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int wid = WorldUtils.getWorldId(location.getWorld().getName());
|
||||
Location eventLocation = event.getLocation();
|
||||
int wid = WorldUtils.getWorldId(eventLocation.getWorld().getName());
|
||||
int time = (int) (System.currentTimeMillis() / 1000L);
|
||||
int x = location.getBlockX();
|
||||
int y = location.getBlockY();
|
||||
int z = location.getBlockZ();
|
||||
int x = eventLocation.getBlockX();
|
||||
int y = eventLocation.getBlockY();
|
||||
int z = eventLocation.getBlockZ();
|
||||
CacheHandler.breakCache.put("" + x + "." + y + "." + z + "." + wid + "", new Object[] { time, event.getUser(), type });
|
||||
|
||||
if (event.isCancelled()) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.Locale;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.BlockState;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
@@ -85,15 +86,21 @@ public class BlockPlaceLogger {
|
||||
}
|
||||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user, block.getLocation());
|
||||
if (Config.getGlobal().API_ENABLED && !Bukkit.isPrimaryThread()) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int wid = WorldUtils.getWorldId(block.getWorld().getName());
|
||||
Location eventLocation = event.getLocation();
|
||||
int wid = WorldUtils.getWorldId(eventLocation.getWorld().getName());
|
||||
int time = (int) (System.currentTimeMillis() / 1000L);
|
||||
|
||||
// Use event location for subsequent logging
|
||||
x = eventLocation.getBlockX();
|
||||
y = eventLocation.getBlockY();
|
||||
z = eventLocation.getBlockZ();
|
||||
|
||||
if (event.getUser().length() > 0) {
|
||||
CacheHandler.lookupCache.put("" + x + "." + y + "." + z + "." + wid + "", new Object[] { time, event.getUser(), type });
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public class CommandLogger {
|
||||
return;
|
||||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user, location);
|
||||
if (Config.getGlobal().API_ENABLED && !Bukkit.isPrimaryThread()) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
@@ -39,10 +39,11 @@ public class CommandLogger {
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int wid = WorldUtils.getWorldId(location.getWorld().getName());
|
||||
int x = location.getBlockX();
|
||||
int y = location.getBlockY();
|
||||
int z = location.getBlockZ();
|
||||
Location eventLocation = event.getLocation();
|
||||
int wid = WorldUtils.getWorldId(eventLocation.getWorld().getName());
|
||||
int x = eventLocation.getBlockX();
|
||||
int y = eventLocation.getBlockY();
|
||||
int z = eventLocation.getBlockZ();
|
||||
CommandStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, message);
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
||||
@@ -67,7 +67,7 @@ public class ContainerLogger extends Queue {
|
||||
}
|
||||
|
||||
// Check if this is a dispenser with no actual changes
|
||||
if (player.equals("#dispenser") && ItemUtils.compareContainers(oldInventory, newInventory)) {
|
||||
if ("#dispenser".equals(player) && ItemUtils.compareContainers(oldInventory, newInventory)) {
|
||||
// No changes detected, mark this dispenser in the dispenserNoChange map
|
||||
// Extract the location key from the loggingContainerId
|
||||
// Format: #dispenser.x.y.z
|
||||
@@ -95,7 +95,7 @@ public class ContainerLogger extends Queue {
|
||||
|
||||
// If we reach here, the dispenser event resulted in changes
|
||||
// Remove any pending event for this dispenser
|
||||
if (player.equals("#dispenser")) {
|
||||
if ("#dispenser".equals(player)) {
|
||||
String[] parts = loggingContainerId.split("\\.");
|
||||
if (parts.length >= 4) {
|
||||
int x = Integer.parseInt(parts[1]);
|
||||
@@ -223,7 +223,7 @@ public class ContainerLogger extends Queue {
|
||||
metadata = null;
|
||||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user, location);
|
||||
if (Config.getGlobal().API_ENABLED && !Bukkit.isPrimaryThread()) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
@@ -233,11 +233,12 @@ public class ContainerLogger extends Queue {
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int wid = WorldUtils.getWorldId(location.getWorld().getName());
|
||||
Location eventLocation = event.getLocation();
|
||||
int wid = WorldUtils.getWorldId(eventLocation.getWorld().getName());
|
||||
int time = (int) (System.currentTimeMillis() / 1000L);
|
||||
int x = location.getBlockX();
|
||||
int y = location.getBlockY();
|
||||
int z = location.getBlockZ();
|
||||
int x = eventLocation.getBlockX();
|
||||
int y = eventLocation.getBlockY();
|
||||
int z = eventLocation.getBlockZ();
|
||||
int typeId = MaterialUtils.getBlockId(item.getType().name(), true);
|
||||
int data = 0;
|
||||
int amount = item.getAmount();
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.BlockState;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
@@ -30,7 +31,8 @@ public class EntityKillLogger {
|
||||
return;
|
||||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
Location initialLocation = new Location(block.getWorld(), block.getX(), block.getY(), block.getZ());
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user, initialLocation);
|
||||
if (Config.getGlobal().API_ENABLED && !Bukkit.isPrimaryThread()) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
@@ -40,11 +42,12 @@ public class EntityKillLogger {
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int wid = WorldUtils.getWorldId(block.getWorld().getName());
|
||||
Location eventLocation = event.getLocation();
|
||||
int wid = WorldUtils.getWorldId(eventLocation.getWorld().getName());
|
||||
int time = (int) (System.currentTimeMillis() / 1000L);
|
||||
int x = block.getX();
|
||||
int y = block.getY();
|
||||
int z = block.getZ();
|
||||
int x = eventLocation.getBlockX();
|
||||
int y = eventLocation.getBlockY();
|
||||
int z = eventLocation.getBlockZ();
|
||||
int entity_key = 0;
|
||||
|
||||
ResultSet resultSet = EntityStatement.insert(preparedStmt2, time, data);
|
||||
|
||||
@@ -129,7 +129,7 @@ public class ItemLogger {
|
||||
data = null;
|
||||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user, location);
|
||||
if (Config.getGlobal().API_ENABLED && !Bukkit.isPrimaryThread()) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
@@ -139,11 +139,12 @@ public class ItemLogger {
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int wid = WorldUtils.getWorldId(location.getWorld().getName());
|
||||
Location eventLocation = event.getLocation();
|
||||
int wid = WorldUtils.getWorldId(eventLocation.getWorld().getName());
|
||||
int time = (int) (System.currentTimeMillis() / 1000L) - offset;
|
||||
int x = location.getBlockX();
|
||||
int y = location.getBlockY();
|
||||
int z = location.getBlockZ();
|
||||
int x = eventLocation.getBlockX();
|
||||
int y = eventLocation.getBlockY();
|
||||
int z = eventLocation.getBlockZ();
|
||||
int typeId = MaterialUtils.getBlockId(item.getType().name(), true);
|
||||
int amount = item.getAmount();
|
||||
ItemStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, typeId, data, amount, action);
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.Locale;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.BlockState;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
@@ -29,7 +30,7 @@ public class PlayerInteractLogger {
|
||||
return;
|
||||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user, block.getLocation());
|
||||
if (Config.getGlobal().API_ENABLED && !Bukkit.isPrimaryThread()) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
@@ -39,11 +40,12 @@ public class PlayerInteractLogger {
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int wid = WorldUtils.getWorldId(block.getWorld().getName());
|
||||
Location eventLocation = event.getLocation();
|
||||
int wid = WorldUtils.getWorldId(eventLocation.getWorld().getName());
|
||||
int time = (int) (System.currentTimeMillis() / 1000L);
|
||||
int x = block.getX();
|
||||
int y = block.getY();
|
||||
int z = block.getZ();
|
||||
int x = eventLocation.getBlockX();
|
||||
int y = eventLocation.getBlockY();
|
||||
int z = eventLocation.getBlockZ();
|
||||
int data = 0;
|
||||
BlockStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, type, data, null, null, 2, 0);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.sql.PreparedStatement;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.BlockState;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
@@ -30,7 +31,8 @@ public class PlayerKillLogger {
|
||||
UserStatement.loadId(preparedStmt.getConnection(), player, null);
|
||||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
Location initialLocation = new Location(block.getWorld(), block.getX(), block.getY(), block.getZ());
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user, initialLocation);
|
||||
if (Config.getGlobal().API_ENABLED && !Bukkit.isPrimaryThread()) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
@@ -41,11 +43,12 @@ public class PlayerKillLogger {
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int playerId = ConfigHandler.playerIdCache.get(player.toLowerCase(Locale.ROOT));
|
||||
int wid = WorldUtils.getWorldId(block.getWorld().getName());
|
||||
Location eventLocation = event.getLocation();
|
||||
int wid = WorldUtils.getWorldId(eventLocation.getWorld().getName());
|
||||
int time = (int) (System.currentTimeMillis() / 1000L);
|
||||
int x = block.getX();
|
||||
int y = block.getY();
|
||||
int z = block.getZ();
|
||||
int x = eventLocation.getBlockX();
|
||||
int y = eventLocation.getBlockY();
|
||||
int z = eventLocation.getBlockZ();
|
||||
BlockStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, 0, playerId, null, null, 3, 0);
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
||||
@@ -26,7 +26,7 @@ public class SignTextLogger {
|
||||
return;
|
||||
}
|
||||
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
|
||||
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user, location);
|
||||
if (Config.getGlobal().API_ENABLED && !Bukkit.isPrimaryThread()) {
|
||||
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
@@ -36,11 +36,12 @@ public class SignTextLogger {
|
||||
}
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
int wid = WorldUtils.getWorldId(location.getWorld().getName());
|
||||
Location eventLocation = event.getLocation();
|
||||
int wid = WorldUtils.getWorldId(eventLocation.getWorld().getName());
|
||||
int time = (int) (System.currentTimeMillis() / 1000L) - timeOffset;
|
||||
int x = location.getBlockX();
|
||||
int y = location.getBlockY();
|
||||
int z = location.getBlockZ();
|
||||
int x = eventLocation.getBlockX();
|
||||
int y = eventLocation.getBlockY();
|
||||
int z = eventLocation.getBlockZ();
|
||||
|
||||
if (line1.isEmpty() && line2.isEmpty() && line3.isEmpty() && line4.isEmpty()) {
|
||||
line1 = null;
|
||||
|
||||
@@ -1,25 +1,18 @@
|
||||
package net.coreprotect.database.lookup;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.database.statement.UserStatement;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.language.Selector;
|
||||
import net.coreprotect.listener.channel.PluginChannelListener;
|
||||
import net.coreprotect.utility.ChatUtils;
|
||||
import net.coreprotect.utility.Color;
|
||||
import net.coreprotect.utility.EntityUtils;
|
||||
import net.coreprotect.utility.MaterialUtils;
|
||||
import net.coreprotect.utility.StringUtils;
|
||||
import net.coreprotect.utility.Util;
|
||||
import net.coreprotect.utility.WorldUtils;
|
||||
import net.coreprotect.utility.*;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.Locale;
|
||||
|
||||
public class BlockLookup {
|
||||
|
||||
@@ -157,7 +150,7 @@ public class BlockLookup {
|
||||
// resultText = Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Color.WHITE + "No block data found at " + Color.ITALIC + "x" + x + "/y" + y + "/z" + z + ".";
|
||||
resultText = Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_DATA_LOCATION, Selector.FIRST);
|
||||
if (!blockName.equals("air") && !blockName.equals("cave_air")) {
|
||||
resultText = Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_DATA, Color.ITALIC + block.getType().name().toLowerCase(Locale.ROOT)) + "\n";
|
||||
resultText = Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_DATA, Color.ITALIC + block.getType().name().toLowerCase(Locale.ROOT) + Color.WHITE) + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ public class RollbackProcessor {
|
||||
BlockData checkData = rowType == Material.AIR ? blockData : rawBlockData;
|
||||
if (checkData != null) {
|
||||
if (checkData.getAsString().equals(pendingChangeData.getAsString()) || checkData instanceof org.bukkit.block.data.MultipleFacing || checkData instanceof org.bukkit.block.data.type.Stairs || checkData instanceof org.bukkit.block.data.type.RedstoneWire) {
|
||||
if (rowType != Material.CHEST && rowType != Material.TRAPPED_CHEST) { // always update double chests
|
||||
if (rowType != Material.CHEST && rowType != Material.TRAPPED_CHEST && !BukkitAdapter.ADAPTER.isCopperChest(rowType)) { // always update double chests
|
||||
changeBlock = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.coreprotect.event;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
@@ -9,16 +10,33 @@ public class CoreProtectPreLogEvent extends Event implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancelled = false;
|
||||
private String user;
|
||||
private Location location;
|
||||
|
||||
public CoreProtectPreLogEvent(String user, Location location) {
|
||||
super(true); // async
|
||||
this.user = user;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards-compatible constructor for API v10 and earlier.
|
||||
* Defaults location to null; listeners expecting v10 signature can still subscribe.
|
||||
*/
|
||||
@Deprecated
|
||||
public CoreProtectPreLogEvent(String user) {
|
||||
super(true); // async
|
||||
this.user = user;
|
||||
this.location = null;
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
@@ -37,6 +55,14 @@ public class CoreProtectPreLogEvent extends Event implements Cancellable {
|
||||
this.user = newUser;
|
||||
}
|
||||
|
||||
public void setLocation(Location newLocation) {
|
||||
if (newLocation == null) {
|
||||
throw new IllegalArgumentException("Invalid location");
|
||||
}
|
||||
|
||||
this.location = newLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
|
||||
@@ -223,6 +223,7 @@ public class Language {
|
||||
phrases.put(Phrase.TIME_MINUTES, "{0} {minute|minutes}");
|
||||
phrases.put(Phrase.TIME_MONTHS, "{0} {month|months}");
|
||||
phrases.put(Phrase.TIME_SECONDS, "{0} {second|seconds}");
|
||||
phrases.put(Phrase.TIME_UNITS, "{/m|/h|/d}");
|
||||
phrases.put(Phrase.TIME_WEEKS, "{0} {week|weeks}");
|
||||
phrases.put(Phrase.TIME_YEARS, "{0} {year|years}");
|
||||
phrases.put(Phrase.UPDATE_ERROR, "An error occurred while checking for updates.");
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package net.coreprotect.language;
|
||||
|
||||
import net.coreprotect.utility.ChatMessage;
|
||||
import net.coreprotect.utility.Color;
|
||||
import net.coreprotect.utility.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.coreprotect.utility.ChatMessage;
|
||||
import net.coreprotect.utility.Color;
|
||||
import net.coreprotect.utility.StringUtils;
|
||||
|
||||
public enum Phrase {
|
||||
|
||||
ACTION_NOT_SUPPORTED,
|
||||
@@ -206,6 +206,7 @@ public enum Phrase {
|
||||
TIME_MINUTES,
|
||||
TIME_MONTHS,
|
||||
TIME_SECONDS,
|
||||
TIME_UNITS,
|
||||
TIME_WEEKS,
|
||||
TIME_YEARS,
|
||||
UPDATE_ERROR,
|
||||
|
||||
@@ -55,6 +55,7 @@ import net.coreprotect.listener.world.LeavesDecayListener;
|
||||
import net.coreprotect.listener.world.PortalCreateListener;
|
||||
import net.coreprotect.listener.world.StructureGrowListener;
|
||||
import net.coreprotect.paper.listener.BlockPreDispenseListener;
|
||||
import net.coreprotect.paper.listener.CopperGolemChestListener;
|
||||
import net.coreprotect.paper.listener.PaperChatListener;
|
||||
|
||||
public final class ListenerHandler {
|
||||
@@ -72,6 +73,14 @@ public final class ListenerHandler {
|
||||
BlockPreDispenseListener.useBlockPreDispenseEvent = false;
|
||||
}
|
||||
|
||||
try {
|
||||
Class.forName("io.papermc.paper.event.entity.ItemTransportingEntityValidateTargetEvent"); // Paper 1.21.10+
|
||||
pluginManager.registerEvents(new CopperGolemChestListener(plugin), plugin);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Ignore registration failures to remain compatible with older servers.
|
||||
}
|
||||
|
||||
// Block Listeners
|
||||
pluginManager.registerEvents(new BlockBreakListener(), plugin);
|
||||
pluginManager.registerEvents(new BlockBurnListener(), plugin);
|
||||
|
||||
@@ -146,18 +146,25 @@ public final class BlockExplodeListener extends Queue implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
protected void onBlockExplode(BlockExplodeEvent event) {
|
||||
Block eventBlock = event.getBlock();
|
||||
World world = eventBlock.getLocation().getWorld();
|
||||
Material eventMaterial = BukkitAdapter.ADAPTER.getExplodedBlock(event);
|
||||
World world = event.getBlock().getLocation().getWorld();
|
||||
|
||||
if (!BukkitAdapter.ADAPTER.shouldLogExplosion(event)){
|
||||
return;
|
||||
}
|
||||
|
||||
String user = "";
|
||||
if (!eventBlock.getType().equals(Material.AIR) && !eventBlock.getType().equals(Material.CAVE_AIR)) {
|
||||
user = eventBlock.getType().name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
if (user.contains("tnt")) {
|
||||
user = "#tnt";
|
||||
}
|
||||
else if (user.contains("end_crystal")) {
|
||||
user = "#end_crystal";
|
||||
if (!eventMaterial.equals(Material.AIR) && !eventMaterial.equals(Material.CAVE_AIR)) {
|
||||
user = eventMaterial.name().toLowerCase(Locale.ROOT);
|
||||
|
||||
if (user.contains("respawn_anchor")) {
|
||||
user = "#respawn_anchor";
|
||||
}
|
||||
else if (user.contains("_bed")) {
|
||||
user = "#bed";
|
||||
}
|
||||
}
|
||||
|
||||
if (!user.startsWith("#")) {
|
||||
user = "#explosion";
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.coreprotect.listener.entity;
|
||||
|
||||
import org.bukkit.ExplosionResult;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Creeper;
|
||||
import org.bukkit.entity.EnderCrystal;
|
||||
@@ -15,6 +16,7 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
|
||||
import net.coreprotect.bukkit.BukkitAdapter;
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.listener.block.BlockExplodeListener;
|
||||
@@ -24,7 +26,8 @@ public final class EntityExplodeListener extends Queue implements Listener {
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
protected void onEntityExplode(EntityExplodeEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
if (entity.getType().name().equals("WIND_CHARGE") || entity.getType().name().equals("BREEZE_WIND_CHARGE")) {
|
||||
|
||||
if (!BukkitAdapter.ADAPTER.shouldLogExplosion(event)){
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,12 +10,14 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.DoubleChest;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryAction;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
@@ -27,6 +29,7 @@ import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.bukkit.BukkitAdapter;
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.consumer.Queue;
|
||||
@@ -342,9 +345,58 @@ public final class InventoryChangeListener extends Queue implements Listener {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkCrafterSlotChange(InventoryClickEvent event) {
|
||||
// Check if the clicked inventory is a crafter
|
||||
if (!BukkitAdapter.ADAPTER.isCrafter(event.getInventory().getType())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that the Action is NOTHING
|
||||
if (event.getAction() != InventoryAction.NOTHING) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the clicked slot is one of the crafter slots
|
||||
if (event.getRawSlot() < 0 || event.getRawSlot() > 8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that the click type is not a middle click
|
||||
if (!(event.getClick() == ClickType.LEFT || event.getClick() == ClickType.RIGHT)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Gather other necessary information
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
Inventory inventory = event.getInventory();
|
||||
|
||||
Location location = null;
|
||||
try {
|
||||
location = inventory.getLocation();
|
||||
}
|
||||
catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (location == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Block block = location.getBlock();
|
||||
BlockState blockState = block.getState();
|
||||
|
||||
Queue.queueBlockPlace(player.getName(), blockState, block.getType(), blockState, block.getType(), -1, 0, blockState.getBlockData().getAsString());
|
||||
return true;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
protected void onInventoryClick(InventoryClickEvent event) {
|
||||
InventoryAction inventoryAction = event.getAction();
|
||||
|
||||
if (checkCrafterSlotChange(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (inventoryAction == InventoryAction.NOTHING) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -18,12 +18,14 @@ import org.bukkit.block.Jukebox;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.data.Bisected;
|
||||
import org.bukkit.block.data.Bisected.Half;
|
||||
import org.bukkit.block.data.SideChaining.ChainPart;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.Lightable;
|
||||
import org.bukkit.block.data.Waterlogged;
|
||||
import org.bukkit.block.data.type.Bed;
|
||||
import org.bukkit.block.data.type.Bed.Part;
|
||||
import org.bukkit.block.data.type.Cake;
|
||||
import org.bukkit.block.data.type.Shelf;
|
||||
import org.bukkit.entity.EnderCrystal;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -37,6 +39,7 @@ import org.bukkit.inventory.BlockInventoryHolder;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.bukkit.BukkitAdapter;
|
||||
@@ -145,7 +148,7 @@ public final class PlayerInteractListener extends Queue implements Listener {
|
||||
}
|
||||
else if (isContainerBlock && Config.getConfig(world).ITEM_TRANSACTIONS) {
|
||||
Location location = null;
|
||||
if (type.equals(Material.CHEST) || type.equals(Material.TRAPPED_CHEST)) {
|
||||
if (type.equals(Material.CHEST) || type.equals(Material.TRAPPED_CHEST) || BukkitAdapter.ADAPTER.isCopperChest(type)) {
|
||||
Chest chest = (Chest) clickedBlock.getState();
|
||||
InventoryHolder inventoryHolder = chest.getInventory().getHolder();
|
||||
|
||||
@@ -465,6 +468,49 @@ public final class PlayerInteractListener extends Queue implements Listener {
|
||||
InventoryChangeListener.inventoryTransaction(player.getName(), blockState.getLocation(), null);
|
||||
}
|
||||
}
|
||||
} else if (BukkitAdapter.ADAPTER.isShelf(type) ){
|
||||
BlockData blockState = block.getBlockData();
|
||||
if (blockState instanceof Shelf){
|
||||
Shelf shelf = (Shelf) blockState;
|
||||
|
||||
// ignore clicking on the back face
|
||||
if (event.getBlockFace() != shelf.getFacing()){
|
||||
return;
|
||||
}
|
||||
|
||||
if (shelf.getSideChain() == ChainPart.UNCONNECTED){
|
||||
InventoryChangeListener.inventoryTransaction(player.getName(), block.getLocation(), null);
|
||||
} else {
|
||||
Block center = block;
|
||||
Vector direction = shelf.getFacing().getDirection();
|
||||
|
||||
if (shelf.getSideChain() == ChainPart.LEFT){
|
||||
center = center.getRelative(direction.getBlockZ(), 0, -direction.getBlockX());
|
||||
} else if (shelf.getSideChain() == ChainPart.RIGHT){
|
||||
center = center.getRelative(-direction.getBlockZ(), 0, direction.getBlockX());
|
||||
}
|
||||
|
||||
BlockData centerBlockData = center.getBlockData();
|
||||
if (centerBlockData instanceof Shelf){
|
||||
// log center
|
||||
InventoryChangeListener.inventoryTransaction(player.getName(), center.getLocation(), null);
|
||||
|
||||
if (((Shelf)centerBlockData).getSideChain() != ChainPart.CENTER){
|
||||
// if it's not the center it's just a chain of 2
|
||||
InventoryChangeListener.inventoryTransaction(player.getName(), block.getLocation(), null);
|
||||
} else {
|
||||
Block left = center.getRelative(-direction.getBlockZ(), 0, direction.getBlockX());
|
||||
InventoryChangeListener.inventoryTransaction(player.getName(), left.getLocation(), null);
|
||||
|
||||
Block right = center.getRelative(direction.getBlockZ(), 0, -direction.getBlockX());
|
||||
InventoryChangeListener.inventoryTransaction(player.getName(), right.getLocation(), null);
|
||||
}
|
||||
} else {
|
||||
// fallback if invalid block is found just log clicked shelf
|
||||
InventoryChangeListener.inventoryTransaction(player.getName(), block.getLocation(), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (BukkitAdapter.ADAPTER.isDecoratedPot(type)) {
|
||||
BlockState blockState = block.getState();
|
||||
|
||||
@@ -0,0 +1,806 @@
|
||||
package net.coreprotect.paper.listener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.GameEvent;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.DoubleChest;
|
||||
import org.bukkit.entity.CopperGolem;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.GenericGameEvent;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.bukkit.BukkitAdapter;
|
||||
import net.coreprotect.config.Config;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.listener.player.InventoryChangeListener;
|
||||
import net.coreprotect.thread.Scheduler;
|
||||
import net.coreprotect.utility.ItemUtils;
|
||||
|
||||
public final class CopperGolemChestListener implements Listener {
|
||||
|
||||
private static final String USERNAME = "#copper_golem";
|
||||
private static final long OPEN_INTERACTION_TIMEOUT_MILLIS = 20000L;
|
||||
private static final long CLEANUP_INTERVAL_MILLIS = 60000L;
|
||||
private static final long EMPTY_COPPER_CHEST_SKIP_TTL_MILLIS = 6000L;
|
||||
private static final long CLOSE_FINALIZE_DELAY_TICKS = 1L;
|
||||
private static final int CLOSE_FINALIZE_MAX_ATTEMPTS = 3;
|
||||
private static final int CLOSE_FALLBACK_MAX_ATTEMPTS = 2;
|
||||
|
||||
private final CoreProtect plugin;
|
||||
private final Map<UUID, OpenInteraction> openInteractions = new ConcurrentHashMap<>();
|
||||
private final Map<UUID, RecentEmptyCopperChestSkip> recentEmptyCopperChestSkips = new ConcurrentHashMap<>();
|
||||
private final Map<TransactionKey, OpenInteractionIndex> openInteractionIndexByContainerKey = new ConcurrentHashMap<>();
|
||||
private final Map<TransactionKey, Set<UUID>> emptySkipGolemsByContainerKey = new ConcurrentHashMap<>();
|
||||
private volatile long lastCleanupMillis;
|
||||
|
||||
public CopperGolemChestListener(CoreProtect plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onGenericGameEvent(GenericGameEvent event) {
|
||||
if (event == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
GameEvent gameEvent = event.getEvent();
|
||||
if (gameEvent != GameEvent.CONTAINER_OPEN && gameEvent != GameEvent.CONTAINER_CLOSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entity entity = event.getEntity();
|
||||
if (gameEvent == GameEvent.CONTAINER_OPEN) {
|
||||
if (!(entity instanceof CopperGolem)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (entity != null && !(entity instanceof CopperGolem)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Location eventLocation = event.getLocation();
|
||||
if (eventLocation == null || eventLocation.getWorld() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Config.getConfig(eventLocation.getWorld()).ITEM_TRANSACTIONS) {
|
||||
return;
|
||||
}
|
||||
|
||||
BlockState blockState = eventLocation.getBlock().getState();
|
||||
if (!(blockState instanceof InventoryHolder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Location containerLocation = blockState.getLocation();
|
||||
if (containerLocation == null || containerLocation.getWorld() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Material containerType = blockState.getType();
|
||||
boolean isCopperChest = isCopperChest(containerType);
|
||||
boolean isStandardChest = containerType == Material.CHEST || containerType == Material.TRAPPED_CHEST;
|
||||
if (!isCopperChest && !isStandardChest) {
|
||||
return;
|
||||
}
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
cleanupOpenInteractions(now);
|
||||
|
||||
InventoryHolder inventoryHolder = (InventoryHolder) blockState;
|
||||
Inventory inventory = inventoryHolder.getInventory();
|
||||
Location canonicalLocation = getCanonicalContainerLocation(containerLocation, inventory);
|
||||
TransactionKey containerKey = TransactionKey.of(canonicalLocation);
|
||||
|
||||
if (gameEvent == GameEvent.CONTAINER_OPEN) {
|
||||
handleContainerOpen((CopperGolem) entity, canonicalLocation, containerKey, containerType, inventoryHolder, now);
|
||||
}
|
||||
else {
|
||||
if (entity instanceof CopperGolem) {
|
||||
handleContainerClose((CopperGolem) entity, canonicalLocation, containerKey, containerType, inventoryHolder, now);
|
||||
}
|
||||
else if (entity == null) {
|
||||
handleContainerCloseWithoutEntity(containerKey, containerType, now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Location getCanonicalContainerLocation(Location containerLocation, Inventory inventory) {
|
||||
if (containerLocation == null || containerLocation.getWorld() == null || inventory == null) {
|
||||
return containerLocation;
|
||||
}
|
||||
|
||||
InventoryHolder holder = inventory.getHolder();
|
||||
if (!(holder instanceof DoubleChest)) {
|
||||
return containerLocation;
|
||||
}
|
||||
|
||||
Location doubleChestLocation = ((DoubleChest) holder).getLocation();
|
||||
if (doubleChestLocation == null) {
|
||||
return containerLocation;
|
||||
}
|
||||
|
||||
Location canonical = new Location(containerLocation.getWorld(), doubleChestLocation.getBlockX(), doubleChestLocation.getBlockY(), doubleChestLocation.getBlockZ());
|
||||
if (canonical.getWorld() == null) {
|
||||
return containerLocation;
|
||||
}
|
||||
|
||||
return canonical;
|
||||
}
|
||||
|
||||
private static boolean isCopperChest(Material material) {
|
||||
return BukkitAdapter.ADAPTER != null && BukkitAdapter.ADAPTER.isCopperChest(material);
|
||||
}
|
||||
|
||||
private void handleContainerOpen(CopperGolem golem, Location containerLocation, TransactionKey containerKey, Material containerType, InventoryHolder inventoryHolder, long nowMillis) {
|
||||
Inventory inventory = inventoryHolder.getInventory();
|
||||
if (inventory == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
HeldItemSnapshot held = getHeldItemSnapshot(golem);
|
||||
boolean isCopperChest = isCopperChest(containerType);
|
||||
if (isCopperChest) {
|
||||
if (held.material != null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (held.material == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack[] contents = inventory.getContents();
|
||||
if (contents == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isCopperChest) {
|
||||
if (isInventoryEmpty(contents)) {
|
||||
UUID golemId = golem.getUniqueId();
|
||||
RecentEmptyCopperChestSkip previous = recentEmptyCopperChestSkips.put(golemId, new RecentEmptyCopperChestSkip(containerKey, nowMillis));
|
||||
if (previous != null) {
|
||||
unindexEmptySkip(previous.containerKey, golemId);
|
||||
}
|
||||
indexEmptySkip(containerKey, golemId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!isInventoryEmpty(contents) && !containsOnlyMaterial(contents, held.material)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasSpaceForMaterial(contents, held.material)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack[] baseline = ItemUtils.getContainerState(contents);
|
||||
if (baseline == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Material heldMaterial = isCopperChest ? null : held.material;
|
||||
int heldAmount = isCopperChest ? 0 : held.amount;
|
||||
OpenInteraction interaction = new OpenInteraction(containerKey, containerLocation.clone(), containerType, baseline, heldMaterial, heldAmount, nowMillis);
|
||||
UUID golemId = golem.getUniqueId();
|
||||
RecentEmptyCopperChestSkip removedSkip = recentEmptyCopperChestSkips.remove(golemId);
|
||||
if (removedSkip != null) {
|
||||
unindexEmptySkip(removedSkip.containerKey, golemId);
|
||||
}
|
||||
|
||||
OpenInteraction previous = openInteractions.put(golemId, interaction);
|
||||
if (previous != null) {
|
||||
openInteractionIndexByContainerKey.remove(previous.containerKey, new OpenInteractionIndex(golemId, previous.openedAtMillis));
|
||||
}
|
||||
openInteractionIndexByContainerKey.put(containerKey, new OpenInteractionIndex(golemId, nowMillis));
|
||||
}
|
||||
|
||||
private void handleContainerClose(CopperGolem golem, Location containerLocation, TransactionKey containerKey, Material containerType, InventoryHolder inventoryHolder, long nowMillis) {
|
||||
UUID golemId = golem.getUniqueId();
|
||||
OpenInteraction interaction = openInteractions.get(golemId);
|
||||
if (interaction == null) {
|
||||
if (isCopperChest(containerType)) {
|
||||
RecentEmptyCopperChestSkip emptySkip = recentEmptyCopperChestSkips.get(golemId);
|
||||
if (emptySkip != null && emptySkip.containerKey.equals(containerKey) && (nowMillis - emptySkip.skippedAtMillis) <= EMPTY_COPPER_CHEST_SKIP_TTL_MILLIS) {
|
||||
if (recentEmptyCopperChestSkips.remove(golemId, emptySkip)) {
|
||||
unindexEmptySkip(emptySkip.containerKey, golemId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
scheduleUntrackedCopperChestCloseFinalize(golemId, containerLocation.clone(), containerType, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (nowMillis - interaction.openedAtMillis > OPEN_INTERACTION_TIMEOUT_MILLIS) {
|
||||
if (openInteractions.remove(golemId, interaction)) {
|
||||
openInteractionIndexByContainerKey.remove(interaction.containerKey, new OpenInteractionIndex(golemId, interaction.openedAtMillis));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!interaction.containerKey.equals(containerKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
openInteractions.remove(golemId, interaction);
|
||||
openInteractionIndexByContainerKey.remove(interaction.containerKey, new OpenInteractionIndex(golemId, interaction.openedAtMillis));
|
||||
scheduleCloseFinalize(golemId, interaction, containerKey, 1);
|
||||
}
|
||||
|
||||
private void handleContainerCloseWithoutEntity(TransactionKey containerKey, Material containerType, long nowMillis) {
|
||||
if (containerKey == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isCopperChest(containerType)) {
|
||||
clearRecentEmptyCopperChestSkipsByKey(containerKey);
|
||||
}
|
||||
|
||||
OpenInteractionIndex index = openInteractionIndexByContainerKey.get(containerKey);
|
||||
if (index == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
UUID golemId = index.golemId;
|
||||
OpenInteraction interaction = openInteractions.get(golemId);
|
||||
if (interaction == null) {
|
||||
openInteractionIndexByContainerKey.remove(containerKey, index);
|
||||
return;
|
||||
}
|
||||
if (interaction.openedAtMillis != index.openedAtMillis || !interaction.containerKey.equals(containerKey)) {
|
||||
openInteractionIndexByContainerKey.remove(containerKey, index);
|
||||
return;
|
||||
}
|
||||
if (nowMillis - interaction.openedAtMillis > OPEN_INTERACTION_TIMEOUT_MILLIS) {
|
||||
if (openInteractions.remove(golemId, interaction)) {
|
||||
openInteractionIndexByContainerKey.remove(containerKey, index);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (openInteractions.remove(golemId, interaction)) {
|
||||
openInteractionIndexByContainerKey.remove(containerKey, index);
|
||||
scheduleCloseFinalize(golemId, interaction, containerKey, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearRecentEmptyCopperChestSkipsByKey(TransactionKey containerKey) {
|
||||
Set<UUID> golemIds = emptySkipGolemsByContainerKey.remove(containerKey);
|
||||
if (golemIds == null || golemIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (UUID golemId : golemIds) {
|
||||
RecentEmptyCopperChestSkip skip = recentEmptyCopperChestSkips.get(golemId);
|
||||
if (skip != null && skip.containerKey.equals(containerKey)) {
|
||||
recentEmptyCopperChestSkips.remove(golemId, skip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void indexEmptySkip(TransactionKey containerKey, UUID golemId) {
|
||||
emptySkipGolemsByContainerKey.computeIfAbsent(containerKey, key -> ConcurrentHashMap.newKeySet()).add(golemId);
|
||||
}
|
||||
|
||||
private void unindexEmptySkip(TransactionKey containerKey, UUID golemId) {
|
||||
if (containerKey == null || golemId == null) {
|
||||
return;
|
||||
}
|
||||
Set<UUID> golemIds = emptySkipGolemsByContainerKey.get(containerKey);
|
||||
if (golemIds == null) {
|
||||
return;
|
||||
}
|
||||
golemIds.remove(golemId);
|
||||
if (golemIds.isEmpty()) {
|
||||
emptySkipGolemsByContainerKey.remove(containerKey, golemIds);
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleCloseFinalize(UUID golemId, OpenInteraction interaction, TransactionKey containerKey, int attempt) {
|
||||
Scheduler.scheduleSyncDelayedTask(plugin, () -> finalizeContainerClose(golemId, interaction, containerKey, attempt), interaction.location, (int) CLOSE_FINALIZE_DELAY_TICKS);
|
||||
}
|
||||
|
||||
private void scheduleUntrackedCopperChestCloseFinalize(UUID golemId, Location containerLocation, Material containerType, int attempt) {
|
||||
Scheduler.scheduleSyncDelayedTask(plugin, () -> finalizeUntrackedCopperChestClose(golemId, containerLocation, containerType, attempt), containerLocation, (int) CLOSE_FINALIZE_DELAY_TICKS);
|
||||
}
|
||||
|
||||
private void finalizeContainerClose(UUID golemId, OpenInteraction interaction, TransactionKey containerKey, int attempt) {
|
||||
Entity entity = plugin.getServer().getEntity(golemId);
|
||||
if (!(entity instanceof CopperGolem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
BlockState blockState = interaction.location.getBlock().getState();
|
||||
if (!(blockState instanceof InventoryHolder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Inventory inventory = ((InventoryHolder) blockState).getInventory();
|
||||
if (inventory == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack[] currentContents = inventory.getContents();
|
||||
if (currentContents == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean changed = hasInventoryChanged(interaction.baselineState, currentContents);
|
||||
if (!changed) {
|
||||
if (attempt < CLOSE_FINALIZE_MAX_ATTEMPTS) {
|
||||
scheduleCloseFinalize(golemId, interaction, containerKey, attempt + 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
CopperGolem golem = (CopperGolem) entity;
|
||||
if (!isAttributableToGolem(golem, interaction, currentContents)) {
|
||||
return;
|
||||
}
|
||||
|
||||
recordForcedContainerState(interaction.location, currentContents);
|
||||
InventoryChangeListener.inventoryTransaction(USERNAME, interaction.location, interaction.baselineState);
|
||||
}
|
||||
|
||||
private void finalizeUntrackedCopperChestClose(UUID golemId, Location containerLocation, Material containerType, int attempt) {
|
||||
Entity entity = plugin.getServer().getEntity(golemId);
|
||||
if (!(entity instanceof CopperGolem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isCopperChest(containerType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CopperGolem golem = (CopperGolem) entity;
|
||||
ItemStack heldNowStack = getHeldItemStack(golem);
|
||||
if (isEmptyItem(heldNowStack) || heldNowStack == null || heldNowStack.getAmount() <= 0) {
|
||||
if (attempt < CLOSE_FALLBACK_MAX_ATTEMPTS) {
|
||||
scheduleUntrackedCopperChestCloseFinalize(golemId, containerLocation, containerType, attempt + 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int heldAmount = heldNowStack.getAmount();
|
||||
if (heldAmount > 16) {
|
||||
return;
|
||||
}
|
||||
|
||||
BlockState blockState = containerLocation.getBlock().getState();
|
||||
if (!(blockState instanceof InventoryHolder) || !isCopperChest(blockState.getType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Inventory inventory = ((InventoryHolder) blockState).getInventory();
|
||||
if (inventory == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack[] currentContents = inventory.getContents();
|
||||
if (currentContents == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack[] baselineCandidate = reconstructCopperChestBaseline(currentContents, heldNowStack);
|
||||
if (baselineCandidate == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
recordForcedContainerState(containerLocation, currentContents);
|
||||
InventoryChangeListener.inventoryTransaction(USERNAME, containerLocation, baselineCandidate);
|
||||
}
|
||||
|
||||
private boolean isAttributableToGolem(CopperGolem golem, OpenInteraction interaction, ItemStack[] currentContents) {
|
||||
boolean isCopperChest = isCopperChest(interaction.containerType);
|
||||
HeldItemSnapshot heldNow = getHeldItemSnapshot(golem);
|
||||
|
||||
if (isCopperChest) {
|
||||
if (heldNow.material == null || heldNow.amount <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int baselineTotal = sumAllItems(interaction.baselineState);
|
||||
int currentTotal = sumAllItems(currentContents);
|
||||
int totalRemoved = baselineTotal - currentTotal;
|
||||
if (totalRemoved != heldNow.amount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int removedSameMaterial = sumMaterialAmount(interaction.baselineState, heldNow.material) - sumMaterialAmount(currentContents, heldNow.material);
|
||||
return removedSameMaterial == heldNow.amount;
|
||||
}
|
||||
|
||||
Material heldMaterial = interaction.heldMaterial;
|
||||
if (heldMaterial == null || interaction.heldAmount <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!containsOnlyMaterial(currentContents, heldMaterial)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int baselineCount = sumMaterialAmount(interaction.baselineState, heldMaterial);
|
||||
int currentCount = sumMaterialAmount(currentContents, heldMaterial);
|
||||
int added = currentCount - baselineCount;
|
||||
if (added <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int heldAfter = (heldNow.material == heldMaterial ? heldNow.amount : 0);
|
||||
int removedFromGolem = interaction.heldAmount - heldAfter;
|
||||
return added == removedFromGolem;
|
||||
}
|
||||
|
||||
private ItemStack getHeldItemStack(CopperGolem copperGolem) {
|
||||
if (copperGolem == null) {
|
||||
return null;
|
||||
}
|
||||
EntityEquipment equipment = copperGolem.getEquipment();
|
||||
if (equipment == null) {
|
||||
return null;
|
||||
}
|
||||
ItemStack mainHand = equipment.getItemInMainHand();
|
||||
if (isEmptyItem(mainHand)) {
|
||||
return null;
|
||||
}
|
||||
return mainHand.clone();
|
||||
}
|
||||
|
||||
private ItemStack[] reconstructCopperChestBaseline(ItemStack[] currentContents, ItemStack heldNowStack) {
|
||||
if (currentContents == null || heldNowStack == null || isEmptyItem(heldNowStack) || heldNowStack.getAmount() <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ItemStack[] baseline = ItemUtils.getContainerState(currentContents);
|
||||
if (baseline == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int addAmount = heldNowStack.getAmount();
|
||||
int maxStack = heldNowStack.getMaxStackSize();
|
||||
|
||||
for (int i = 0; i < baseline.length; i++) {
|
||||
ItemStack item = baseline[i];
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
if (item.isSimilar(heldNowStack)) {
|
||||
if (item.getAmount() + addAmount > maxStack) {
|
||||
return null;
|
||||
}
|
||||
item.setAmount(item.getAmount() + addAmount);
|
||||
return baseline;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < baseline.length; i++) {
|
||||
ItemStack item = baseline[i];
|
||||
if (isEmptyItem(item)) {
|
||||
ItemStack placed = heldNowStack.clone();
|
||||
placed.setAmount(addAmount);
|
||||
baseline[i] = placed;
|
||||
return baseline;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void recordForcedContainerState(Location location, ItemStack[] contents) {
|
||||
if (location == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack[] snapshot = ItemUtils.getContainerState(contents);
|
||||
if (snapshot == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String loggingContainerId = USERNAME + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
|
||||
|
||||
List<ItemStack[]> forceList = ConfigHandler.forceContainer.get(loggingContainerId);
|
||||
List<ItemStack[]> oldList = ConfigHandler.oldContainer.get(loggingContainerId);
|
||||
|
||||
boolean hasPendingBaseline = oldList != null && !oldList.isEmpty();
|
||||
boolean hasStaleForceSnapshots = forceList != null && !forceList.isEmpty() && (forceList.get(0) == null || forceList.get(0).length != snapshot.length);
|
||||
|
||||
if (!hasPendingBaseline || hasStaleForceSnapshots) {
|
||||
ConfigHandler.forceContainer.remove(loggingContainerId);
|
||||
forceList = null;
|
||||
}
|
||||
|
||||
if (forceList == null) {
|
||||
forceList = Collections.synchronizedList(new ArrayList<>());
|
||||
ConfigHandler.forceContainer.put(loggingContainerId, forceList);
|
||||
}
|
||||
|
||||
forceList.add(snapshot);
|
||||
}
|
||||
|
||||
private void cleanupOpenInteractions(long nowMillis) {
|
||||
long last = lastCleanupMillis;
|
||||
if (nowMillis - last < CLEANUP_INTERVAL_MILLIS) {
|
||||
return;
|
||||
}
|
||||
lastCleanupMillis = nowMillis;
|
||||
|
||||
for (Map.Entry<UUID, OpenInteraction> entry : openInteractions.entrySet()) {
|
||||
UUID golemId = entry.getKey();
|
||||
OpenInteraction interaction = entry.getValue();
|
||||
if (interaction == null || nowMillis - interaction.openedAtMillis > OPEN_INTERACTION_TIMEOUT_MILLIS || plugin.getServer().getEntity(golemId) == null) {
|
||||
if (openInteractions.remove(golemId, interaction) && interaction != null) {
|
||||
openInteractionIndexByContainerKey.remove(interaction.containerKey, new OpenInteractionIndex(golemId, interaction.openedAtMillis));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<UUID, RecentEmptyCopperChestSkip> entry : recentEmptyCopperChestSkips.entrySet()) {
|
||||
UUID golemId = entry.getKey();
|
||||
RecentEmptyCopperChestSkip skip = entry.getValue();
|
||||
if (skip == null || nowMillis - skip.skippedAtMillis > EMPTY_COPPER_CHEST_SKIP_TTL_MILLIS || plugin.getServer().getEntity(golemId) == null) {
|
||||
if (recentEmptyCopperChestSkips.remove(golemId, skip) && skip != null) {
|
||||
unindexEmptySkip(skip.containerKey, golemId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasInventoryChanged(ItemStack[] previousState, ItemStack[] currentState) {
|
||||
if (previousState == null || currentState == null) {
|
||||
return true;
|
||||
}
|
||||
if (previousState.length != currentState.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < previousState.length; i++) {
|
||||
ItemStack previousItem = previousState[i];
|
||||
ItemStack currentItem = currentState[i];
|
||||
|
||||
if (previousItem == null && currentItem == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (previousItem == null || currentItem == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!previousItem.equals(currentItem)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isInventoryEmpty(ItemStack[] state) {
|
||||
if (state == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (ItemStack item : state) {
|
||||
if (!isEmptyItem(item)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isEmptyItem(ItemStack item) {
|
||||
return item == null || item.getType().isAir() || item.getAmount() <= 0;
|
||||
}
|
||||
|
||||
private boolean containsOnlyMaterial(ItemStack[] state, Material material) {
|
||||
if (state == null || material == null) {
|
||||
return false;
|
||||
}
|
||||
for (ItemStack item : state) {
|
||||
if (isEmptyItem(item)) {
|
||||
continue;
|
||||
}
|
||||
if (item.getType() != material) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean hasSpaceForMaterial(ItemStack[] state, Material material) {
|
||||
if (state == null || material == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int maxStackSize = material.getMaxStackSize();
|
||||
for (ItemStack item : state) {
|
||||
if (isEmptyItem(item)) {
|
||||
return true;
|
||||
}
|
||||
if (item.getType() == material && item.getAmount() < maxStackSize) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private int sumMaterialAmount(ItemStack[] state, Material material) {
|
||||
if (state == null || material == null) {
|
||||
return 0;
|
||||
}
|
||||
int total = 0;
|
||||
for (ItemStack item : state) {
|
||||
if (!isEmptyItem(item) && item.getType() == material) {
|
||||
total += item.getAmount();
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
private int sumAllItems(ItemStack[] state) {
|
||||
if (state == null) {
|
||||
return 0;
|
||||
}
|
||||
int total = 0;
|
||||
for (ItemStack item : state) {
|
||||
if (!isEmptyItem(item)) {
|
||||
total += item.getAmount();
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
private HeldItemSnapshot getHeldItemSnapshot(CopperGolem copperGolem) {
|
||||
if (copperGolem == null) {
|
||||
return HeldItemSnapshot.EMPTY;
|
||||
}
|
||||
EntityEquipment equipment = copperGolem.getEquipment();
|
||||
if (equipment == null) {
|
||||
return HeldItemSnapshot.EMPTY;
|
||||
}
|
||||
ItemStack mainHand = equipment.getItemInMainHand();
|
||||
if (isEmptyItem(mainHand)) {
|
||||
return HeldItemSnapshot.EMPTY;
|
||||
}
|
||||
return new HeldItemSnapshot(mainHand.getType(), mainHand.getAmount());
|
||||
}
|
||||
|
||||
private static final class OpenInteraction {
|
||||
|
||||
private final TransactionKey containerKey;
|
||||
private final Location location;
|
||||
private final Material containerType;
|
||||
private final ItemStack[] baselineState;
|
||||
private final Material heldMaterial;
|
||||
private final int heldAmount;
|
||||
private final long openedAtMillis;
|
||||
|
||||
private OpenInteraction(TransactionKey containerKey, Location location, Material containerType, ItemStack[] baselineState, Material heldMaterial, int heldAmount, long openedAtMillis) {
|
||||
this.containerKey = containerKey;
|
||||
this.location = location;
|
||||
this.containerType = containerType;
|
||||
this.baselineState = baselineState;
|
||||
this.heldMaterial = heldMaterial;
|
||||
this.heldAmount = heldAmount;
|
||||
this.openedAtMillis = openedAtMillis;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class RecentEmptyCopperChestSkip {
|
||||
|
||||
private final TransactionKey containerKey;
|
||||
private final long skippedAtMillis;
|
||||
|
||||
private RecentEmptyCopperChestSkip(TransactionKey containerKey, long skippedAtMillis) {
|
||||
this.containerKey = containerKey;
|
||||
this.skippedAtMillis = skippedAtMillis;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class HeldItemSnapshot {
|
||||
|
||||
private static final HeldItemSnapshot EMPTY = new HeldItemSnapshot(null, 0);
|
||||
|
||||
private final Material material;
|
||||
private final int amount;
|
||||
|
||||
private HeldItemSnapshot(Material material, int amount) {
|
||||
this.material = material;
|
||||
this.amount = amount;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class TransactionKey {
|
||||
|
||||
private final UUID worldId;
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int z;
|
||||
|
||||
private TransactionKey(UUID worldId, int x, int y, int z) {
|
||||
this.worldId = worldId;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
private static TransactionKey of(Location location) {
|
||||
if (location == null || location.getWorld() == null) {
|
||||
throw new IllegalArgumentException("Location must have world");
|
||||
}
|
||||
return new TransactionKey(location.getWorld().getUID(), location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof TransactionKey)) {
|
||||
return false;
|
||||
}
|
||||
TransactionKey other = (TransactionKey) obj;
|
||||
return worldId.equals(other.worldId) && x == other.x && y == other.y && z == other.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(worldId, x, y, z);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class OpenInteractionIndex {
|
||||
|
||||
private final UUID golemId;
|
||||
private final long openedAtMillis;
|
||||
|
||||
private OpenInteractionIndex(UUID golemId, long openedAtMillis) {
|
||||
this.golemId = golemId;
|
||||
this.openedAtMillis = openedAtMillis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof OpenInteractionIndex)) {
|
||||
return false;
|
||||
}
|
||||
OpenInteractionIndex other = (OpenInteractionIndex) obj;
|
||||
return openedAtMillis == other.openedAtMillis && golemId.equals(other.golemId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(golemId, openedAtMillis);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,14 +26,23 @@ public class VersionCheckService {
|
||||
public static boolean performVersionChecks() {
|
||||
try {
|
||||
// Check Minecraft version compatibility
|
||||
String[] bukkitVersion = Bukkit.getServer().getBukkitVersion().split("[-.]");
|
||||
if (VersionUtils.newVersion(bukkitVersion[0] + "." + bukkitVersion[1], ConfigHandler.MINECRAFT_VERSION)) {
|
||||
String numericVersion = Bukkit.getServer().getBukkitVersion().split("-", 2)[0];
|
||||
String[] bukkitVersion = numericVersion.split("\\.");
|
||||
if (bukkitVersion.length < 2 || !bukkitVersion[0].matches("\\d+") || !bukkitVersion[1].matches("\\d+")) {
|
||||
Chat.console(Phrase.build(Phrase.VERSION_INCOMPATIBLE, "Minecraft", numericVersion));
|
||||
return false;
|
||||
}
|
||||
|
||||
String minimumVersion = bukkitVersion[0] + "." + bukkitVersion[1];
|
||||
String currentVersion = minimumVersion + (bukkitVersion.length > 2 && bukkitVersion[2].matches("\\d+") ? "." + bukkitVersion[2] : "");
|
||||
|
||||
if (VersionUtils.newVersion(minimumVersion, ConfigHandler.MINECRAFT_VERSION)) {
|
||||
Chat.console(Phrase.build(Phrase.VERSION_REQUIRED, "Minecraft", ConfigHandler.MINECRAFT_VERSION));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (VersionUtils.newVersion(ConfigHandler.LATEST_VERSION, bukkitVersion[0] + "." + bukkitVersion[1] + (bukkitVersion.length > 2 ? "." + bukkitVersion[2] : "")) && VersionUtils.isCommunityEdition()) {
|
||||
Chat.console(Phrase.build(Phrase.VERSION_INCOMPATIBLE, "Minecraft", bukkitVersion[0] + "." + bukkitVersion[1] + (bukkitVersion.length > 2 ? "." + bukkitVersion[2] : "")));
|
||||
if (VersionUtils.newVersion(ConfigHandler.LATEST_VERSION, currentVersion) && VersionUtils.isCommunityEdition()) {
|
||||
Chat.console(Phrase.build(Phrase.VERSION_INCOMPATIBLE, "Minecraft", currentVersion));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -44,6 +53,13 @@ public class VersionCheckService {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Patch version validation
|
||||
if (VersionUtils.newVersion(ConfigHandler.PATCH_VERSION, VersionUtils.getPluginVersion()) && !VersionUtils.isBranch("dev")) {
|
||||
Chat.console(Phrase.build(Phrase.VERSION_INCOMPATIBLE, "CoreProtect", "v" + VersionUtils.getPluginVersion()));
|
||||
Chat.sendConsoleMessage(Color.GREY + "[CoreProtect] " + Phrase.build(Phrase.INVALID_BRANCH_2));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Branch validation
|
||||
if (ConfigHandler.EDITION_BRANCH.length() == 0) {
|
||||
Chat.sendConsoleMessage(Color.RED + "[CoreProtect] " + Phrase.build(Phrase.INVALID_BRANCH_1));
|
||||
@@ -53,7 +69,9 @@ public class VersionCheckService {
|
||||
}
|
||||
|
||||
// Store Minecraft server version for later use
|
||||
ConfigHandler.SERVER_VERSION = Integer.parseInt(bukkitVersion[1]);
|
||||
int major = Integer.parseInt(bukkitVersion[0]);
|
||||
int minor = Integer.parseInt(bukkitVersion[1]);
|
||||
ConfigHandler.SERVER_VERSION = (major == 1 ? minor : major);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -2,12 +2,10 @@ package net.coreprotect.thread;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
|
||||
@@ -22,10 +20,10 @@ public class Scheduler {
|
||||
if (regionData instanceof Location) {
|
||||
Location location = (Location) regionData;
|
||||
if (delay == 0) {
|
||||
Bukkit.getServer().getRegionScheduler().run(plugin, location, value -> task.run());
|
||||
plugin.getServer().getRegionScheduler().run(plugin, location, value -> task.run());
|
||||
}
|
||||
else {
|
||||
Bukkit.getServer().getRegionScheduler().runDelayed(plugin, location, value -> task.run(), delay);
|
||||
plugin.getServer().getRegionScheduler().runDelayed(plugin, location, value -> task.run(), delay);
|
||||
}
|
||||
}
|
||||
else if (regionData instanceof Entity) {
|
||||
@@ -39,19 +37,19 @@ public class Scheduler {
|
||||
}
|
||||
else {
|
||||
if (delay == 0) {
|
||||
Bukkit.getServer().getGlobalRegionScheduler().run(plugin, value -> task.run());
|
||||
plugin.getServer().getGlobalRegionScheduler().run(plugin, value -> task.run());
|
||||
}
|
||||
else {
|
||||
Bukkit.getServer().getGlobalRegionScheduler().runDelayed(plugin, value -> task.run(), delay);
|
||||
plugin.getServer().getGlobalRegionScheduler().runDelayed(plugin, value -> task.run(), delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (delay == 0) {
|
||||
Bukkit.getServer().getScheduler().runTask(plugin, task);
|
||||
plugin.getServer().getScheduler().runTask(plugin, task);
|
||||
}
|
||||
else {
|
||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, task, delay);
|
||||
plugin.getServer().getScheduler().runTaskLater(plugin, task, delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,36 +58,36 @@ public class Scheduler {
|
||||
if (ConfigHandler.isFolia) {
|
||||
if (regionData instanceof Location) {
|
||||
Location location = (Location) regionData;
|
||||
return Bukkit.getServer().getRegionScheduler().runAtFixedRate(plugin, location, value -> task.run(), delay, period);
|
||||
return plugin.getServer().getRegionScheduler().runAtFixedRate(plugin, location, value -> task.run(), delay, period);
|
||||
}
|
||||
else if (regionData instanceof Entity) {
|
||||
Entity entity = (Entity) regionData;
|
||||
return entity.getScheduler().runAtFixedRate(plugin, value -> task.run(), task, delay, period);
|
||||
}
|
||||
else {
|
||||
return Bukkit.getServer().getGlobalRegionScheduler().runAtFixedRate(plugin, value -> task.run(), delay, period);
|
||||
return plugin.getServer().getGlobalRegionScheduler().runAtFixedRate(plugin, value -> task.run(), delay, period);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, task, delay, period);
|
||||
return plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, task, delay, period);
|
||||
}
|
||||
}
|
||||
|
||||
public static void scheduleAsyncDelayedTask(CoreProtect plugin, Runnable task, int delay) {
|
||||
if (ConfigHandler.isFolia) {
|
||||
if (delay == 0) {
|
||||
Bukkit.getServer().getAsyncScheduler().runNow(plugin, value -> task.run());
|
||||
plugin.getServer().getAsyncScheduler().runNow(plugin, value -> task.run());
|
||||
}
|
||||
else {
|
||||
Bukkit.getServer().getAsyncScheduler().runDelayed(plugin, value -> task.run(), (delay * 50L), TimeUnit.MILLISECONDS);
|
||||
plugin.getServer().getAsyncScheduler().runDelayed(plugin, value -> task.run(), (delay * 50L), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (delay == 0) {
|
||||
Bukkit.getServer().getScheduler().runTaskAsynchronously(plugin, task);
|
||||
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, task);
|
||||
}
|
||||
else {
|
||||
Bukkit.getServer().getScheduler().runTaskLaterAsynchronously(plugin, task, delay);
|
||||
plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, task, delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,8 +114,8 @@ public class Scheduler {
|
||||
|
||||
public static void cancelTask(Object task) {
|
||||
if (ConfigHandler.isFolia) {
|
||||
if (task instanceof ScheduledTask) {
|
||||
ScheduledTask scheduledTask = (ScheduledTask) task;
|
||||
if (task instanceof io.papermc.paper.threadedregions.scheduler.ScheduledTask) {
|
||||
io.papermc.paper.threadedregions.scheduler.ScheduledTask scheduledTask = (io.papermc.paper.threadedregions.scheduler.ScheduledTask) task;
|
||||
scheduledTask.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +207,8 @@ public class BlockUtils {
|
||||
try {
|
||||
if (blockState instanceof BlockInventoryHolder) {
|
||||
if (singleBlock) {
|
||||
List<Material> chests = java.util.Arrays.asList(Material.CHEST, Material.TRAPPED_CHEST);
|
||||
List<Material> chests = new java.util.ArrayList<>(java.util.Arrays.asList(Material.CHEST, Material.TRAPPED_CHEST));
|
||||
chests.addAll(BukkitAdapter.ADAPTER.copperChestMaterials());
|
||||
Material type = blockState.getType();
|
||||
if (chests.contains(type)) {
|
||||
inventory = ((org.bukkit.block.Chest) blockState).getBlockInventory();
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package net.coreprotect.utility;
|
||||
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.language.Selector;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
|
||||
import net.coreprotect.language.Phrase;
|
||||
|
||||
public class ChatUtils {
|
||||
|
||||
private ChatUtils() {
|
||||
@@ -137,24 +137,26 @@ public class ChatUtils {
|
||||
timeSince = 0.00;
|
||||
}
|
||||
|
||||
DecimalFormat decimalFormat = new DecimalFormat("0.00");
|
||||
|
||||
// minutes
|
||||
timeSince = timeSince / 60;
|
||||
if (timeSince < 60.0) {
|
||||
message.append(Phrase.build(Phrase.LOOKUP_TIME, new DecimalFormat("0.00").format(timeSince) + "/m"));
|
||||
message.append(Phrase.build(Phrase.LOOKUP_TIME, decimalFormat.format(timeSince) + Phrase.build(Phrase.TIME_UNITS, Selector.FIRST)));
|
||||
}
|
||||
|
||||
// hours
|
||||
if (message.length() == 0) {
|
||||
timeSince = timeSince / 60;
|
||||
if (timeSince < 24.0) {
|
||||
message.append(Phrase.build(Phrase.LOOKUP_TIME, new DecimalFormat("0.00").format(timeSince) + "/h"));
|
||||
message.append(Phrase.build(Phrase.LOOKUP_TIME, decimalFormat.format(timeSince) + Phrase.build(Phrase.TIME_UNITS, Selector.SECOND)));
|
||||
}
|
||||
}
|
||||
|
||||
// days
|
||||
if (message.length() == 0) {
|
||||
timeSince = timeSince / 24;
|
||||
message.append(Phrase.build(Phrase.LOOKUP_TIME, new DecimalFormat("0.00").format(timeSince) + "/d"));
|
||||
message.append(Phrase.build(Phrase.LOOKUP_TIME, decimalFormat.format(timeSince) + Phrase.build(Phrase.TIME_UNITS, Selector.THIRD)));
|
||||
}
|
||||
|
||||
if (component) {
|
||||
|
||||
@@ -33,6 +33,12 @@ public class EntityUtils extends Queue {
|
||||
id = ConfigHandler.entities.get(name);
|
||||
}
|
||||
else if (internal) {
|
||||
// Check if another server has already added this entity (multi-server setup)
|
||||
id = ConfigHandler.reloadAndGetId(ConfigHandler.CacheType.ENTITIES, name);
|
||||
if (id != -1) {
|
||||
return id;
|
||||
}
|
||||
|
||||
int entityID = ConfigHandler.entityId + 1;
|
||||
ConfigHandler.entities.put(name, entityID);
|
||||
ConfigHandler.entitiesReversed.put(entityID, name);
|
||||
|
||||
@@ -35,6 +35,12 @@ public class MaterialUtils extends Queue {
|
||||
id = ConfigHandler.materials.get(name);
|
||||
}
|
||||
else if (internal) {
|
||||
// Check if another server has already added this material (multi-server setup)
|
||||
id = ConfigHandler.reloadAndGetId(ConfigHandler.CacheType.MATERIALS, name);
|
||||
if (id != -1) {
|
||||
return id;
|
||||
}
|
||||
|
||||
int mid = ConfigHandler.materialId + 1;
|
||||
ConfigHandler.materials.put(name, mid);
|
||||
ConfigHandler.materialsReversed.put(mid, name);
|
||||
@@ -54,6 +60,12 @@ public class MaterialUtils extends Queue {
|
||||
id = ConfigHandler.blockdata.get(data);
|
||||
}
|
||||
else if (internal) {
|
||||
// Check if another server has already added this blockdata (multi-server setup)
|
||||
id = ConfigHandler.reloadAndGetId(ConfigHandler.CacheType.BLOCKDATA, data);
|
||||
if (id != -1) {
|
||||
return id;
|
||||
}
|
||||
|
||||
int bid = ConfigHandler.blockdataId + 1;
|
||||
ConfigHandler.blockdata.put(data, bid);
|
||||
ConfigHandler.blockdataReversed.put(bid, data);
|
||||
@@ -135,6 +147,12 @@ public class MaterialUtils extends Queue {
|
||||
id = ConfigHandler.art.get(name);
|
||||
}
|
||||
else if (internal) {
|
||||
// Check if another server has already added this art (multi-server setup)
|
||||
id = ConfigHandler.reloadAndGetId(ConfigHandler.CacheType.ART, name);
|
||||
if (id != -1) {
|
||||
return id;
|
||||
}
|
||||
|
||||
int artID = ConfigHandler.artId + 1;
|
||||
ConfigHandler.art.put(name, artID);
|
||||
ConfigHandler.artReversed.put(artID, name);
|
||||
|
||||
@@ -16,6 +16,12 @@ public class WorldUtils extends Queue {
|
||||
int id = -1;
|
||||
try {
|
||||
if (ConfigHandler.worlds.get(name) == null) {
|
||||
// Check if another server has already added this world (multi-server setup)
|
||||
id = ConfigHandler.reloadAndGetId(ConfigHandler.CacheType.WORLDS, name);
|
||||
if (id != -1) {
|
||||
return id;
|
||||
}
|
||||
|
||||
int wid = ConfigHandler.worldId + 1;
|
||||
ConfigHandler.worlds.put(name, wid);
|
||||
ConfigHandler.worldsReversed.put(wid, name);
|
||||
@@ -84,7 +90,7 @@ public class WorldUtils extends Queue {
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
public static String getWidIndex(String queryTable) {
|
||||
String index = "";
|
||||
boolean isMySQL = net.coreprotect.config.Config.getGlobal().MYSQL;
|
||||
@@ -121,4 +127,4 @@ public class WorldUtils extends Queue {
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,4 +196,9 @@ public final class WorldEditBlockState implements BlockState {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuffocating() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,7 @@ name: CoreProtect
|
||||
main: net.coreprotect.CoreProtect
|
||||
version: ${project.version}
|
||||
branch: ${project.branch}
|
||||
api-version: 1.13
|
||||
api-version: 1.16
|
||||
folia-supported: true
|
||||
website: http://coreprotect.net
|
||||
author: Intelli
|
||||
|
||||
Reference in new issue
Block a user