73 Commits
Author SHA1 Message Date
Intelli d9f5411e87 CoreProtect v20.4 release 2022-01-04 19:26:11 -07:00
Intelli 19ed0162e5 Fixed MySQL purges not being gracefully interrupted on shutdown 2022-01-04 19:19:08 -07:00
Intelli 03bd19480e Fixed SQLite purges not successfully completing on some systems 2022-01-04 17:55:52 -07:00
Intelli 947c59882e Fixed MySQL connections not being released when performing a reload 2022-01-04 16:49:57 -07:00
Intelli 8ed4216c64 Fixed SQLException when MySQL driver isn't automatically detected (#117) 2022-01-04 16:32:30 -07:00
Intelli 64188f5a75 Fixed the top block of bamboo growth not being logged (#129) 2022-01-04 15:58:09 -07:00
Intelli 55fec1d092 Moved entity & teleport methods out of Util class 2022-01-04 15:20:01 -07:00
Intelli c1eecefa6f Fixed radius selections not supporting negative heights 2021-12-21 15:31:08 -07:00
Intelli 204d6c8d5f Added base Japanese language file 2021-12-20 15:24:49 -07:00
Intelli fffe75f1f4 CoreProtect v20.3 release 2021-12-18 11:35:55 -07:00
Intelli 3201a18b16 Fixed PoolInitializationException when initializing HikariCP 2021-12-17 17:00:06 -07:00
Intelli 085e410ab1 Fixed NoClassDefFoundError when using Paper 1.16 (#120) 2021-12-17 11:31:04 -07:00
Intelli 4f977d394c Minor description update to documentation 2021-12-17 11:25:05 -07:00
Intelli a4c21ec8f3 Added MC 1.18 to adapters 2021-12-17 11:24:29 -07:00
Intelli d7ee5257dd Changed additional timestamp values to long types 2021-12-16 18:08:56 -07:00
Intelli 08aeb5d5aa Updated GitHub workflow to use Java 17 2021-12-16 15:25:38 -07:00
Intelli c1a4323ce4 Added base Ukrainian language file (#119) 2021-12-16 15:10:34 -07:00
Intelli a5d063dced CoreProtect v20.2 release 2021-12-16 14:01:43 -07:00
Intelli f0779d288c Incremented API version to 8 2021-12-16 14:01:23 -07:00
Intelli 550c3038b8 Added support for Paper AsyncChatEvent (fixes #75) 2021-11-30 19:11:19 -07:00
Intelli d864bbe233 Replaced commons-lang with Guava 2021-11-22 15:39:57 -07:00
Jan Erik Petersen fc99c24a0a Add HikariCP connection pool for MySQL (#86)
* Add HikariCP connection pool for MySQL

* Make code more compatible with connection pooling

- Remove connection caching in Process/Consumer
- Use try-with-resources to make sure Connections always get closed, even in
  when an Exception occurs.

* Disable SSL for MySQL
2021-11-15 17:57:33 -07:00
Intelli 2d90f9cc08 Fixed moving pistons logged during explosions not rolling back correctly (#92) 2021-11-09 16:42:48 -07:00
dependabot[bot] ba0ad6c15c Bump mkdocs from 1.2.1 to 1.2.3 (#108)
Bumps [mkdocs](https://github.com/mkdocs/mkdocs) from 1.2.1 to 1.2.3.
- [Release notes](https://github.com/mkdocs/mkdocs/releases)
- [Commits](https://github.com/mkdocs/mkdocs/compare/1.2.1...1.2.3)

---
updated-dependencies:
- dependency-name: mkdocs
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-09 15:27:12 -07:00
Intelli 370558cec5 Fixed piston heads not being logged when the piston base is broken 2021-11-09 14:53:42 -07:00
Intelli 69184302c9 Fixed ClassCastException when logging chat and command messages 2021-11-04 13:59:48 -06:00
Intelli a61df070e6 Fixed InventoryMoveItemEvent still processing if both hopper & item transactions are disabled 2021-10-16 16:05:39 -06:00
Intelli 3742e018c4 Minor readability improvements in EntityDamageByBlockListener 2021-10-04 16:09:08 -06:00
Intelli 554e17df02 Use isAlive for monitoring consumer thread 2021-10-04 15:55:54 -06:00
Intelli bc39bc03d6 Fixed NullPointerException when logging player death item drops (fixes #71) 2021-08-22 14:25:26 -06:00
bermudalocketandIntelli da718de252 Make user mutable via CoreProtectPreLogEvent (#66)
* Make user mutable via CoreProtectPreLogEvent

* Cleanup & added missing toLowerCase in getId

* Docs: add Event category; add CoreProtectPreLogEvent

* Merged event documentation into API documentation

* Removed event.getUser() equality check

* Added IllegalArgumentException check within PreLogEvent

* Reverted docs/index.md

Co-authored-by: Intelli <contact@intelli.software>
2021-08-06 18:40:21 -06:00
Ghost_chu 39cd888440 Fixed sign message phrase in zh-cn.yml (#63)
It shouldn't translate to `Signature Message`, this commit fixed it to `Sign Message`
2021-08-03 13:07:25 -06:00
Intelli 697ad1b3ce Minor cleanup in adapters 2021-08-01 16:53:14 -06:00
Intelli 922e4478dc Improved hopper logging performance when using Paper
Disables snapshot creation when getting inventory holders
2021-08-01 16:42:07 -06:00
Intelli 2fd366389b Changed base dependency to Paper 2021-08-01 16:36:17 -06:00
Intelli 5e3a19f208 Added base Vietnamese language file 2021-07-27 18:45:52 -06:00
Intelli 37d49a0900 Added stale.yml configuration file 2021-07-27 15:10:14 -06:00
Intelli adef057590 CoreProtect v20.1 release 2021-07-27 14:16:20 -06:00
Intelli ac1726a1a5 Added base Polish language file 2021-07-27 13:20:29 -06:00
Intelli aeba1918f3 Changed name of "coreprotect.lookup.item" permission to "coreprotect.lookup.inventory" 2021-07-26 18:49:39 -06:00
Intelli 490b5eb0ee Removed unnecessary array length check 2021-07-26 18:09:17 -06:00
Intelli 40b52fa321 Changed all timestamp values utilized by the API to long types 2021-07-26 18:00:21 -06:00
Intelli 3c82dc337a Simplified regex when parsing server version 2021-07-26 17:56:30 -06:00
Intelli f6f9c27f08 Added private constructors to utility classes 2021-07-26 17:34:45 -06:00
a7eb6a48c9 Fix Traditional Chinese translation (#54)
* Fix Traditional Chinese translation 

Fixed some wrong usages and punctuations.

* Update zh-tw.yml

* Apply suggestions from code review

Co-authored-by: KID <jyhsu2000@yahoo.com.tw>

* Reverted colon punctuation marks to english characters

* Fixed spacing in zh-tw.yml

Co-authored-by: Intelli <6790859+Intelli@users.noreply.github.com>
Co-authored-by: KID <jyhsu2000@yahoo.com.tw>
2021-07-26 14:32:02 -06:00
Intelli 40ff1e7778 Additional cleanup in ChestTool 2021-07-25 21:15:53 -06:00
Intelli e178ed91ca Fixed double chests not rolling back correctly when each half is in a separate chunk 2021-07-25 21:08:53 -06:00
div2005andIntelli 5d6388fff7 Improved Russian translation (#55)
* Update ru.yml

* Fixed ru.yml regressions

Co-authored-by: Intelli <6790859+Intelli@users.noreply.github.com>
2021-07-25 17:17:57 -06:00
Intelli d2614ed6dc Fixed risk of NullPointerException when logging container transactions 2021-07-25 16:53:58 -06:00
Intelli 130614bfdd Minor refactoring in PlayerInteractListener and BlockExplodeListener 2021-07-22 18:06:24 -06:00
Intelli ae3768695f Skip extra checks on furnaces when processing hopper transactions
This more aggressively aborts transaction logging to improve performance
2021-07-22 14:11:45 -06:00
Intelli 2f1c45cae1 Moved inventory checkTasks to directly before onInventoryInteract
This improves performance (allows unused threads to return faster), and resolves issues with pass-through transactions
2021-07-22 13:31:08 -06:00
Intelli 6fce87386d Fixed hopper transactions not always detecting invalid events 2021-07-22 13:17:40 -06:00
Intelli 3f0291e0d5 Fixed AssertionError when logging hopper transactions 2021-07-21 22:49:44 -06:00
Intelli 718d7d7a80 Fixed NullPointerException when logging container transactions 2021-07-21 19:01:32 -06:00
Intelli 45e1fee9ff Fixed hopper transaction logging not always logging all items 2021-07-21 18:48:04 -06:00
Intelli aa55472c1a Utilize item caching on invalid hopper events 2021-07-21 18:47:23 -06:00
Intelli bd98bdfe05 Added Gradle build folder to .gitignore 2021-07-21 14:31:22 -06:00
Intelli 38f1e304e0 Fixed entities not being excluded when using the "exclude" parameter 2021-07-20 15:00:10 -06:00
Intelli e68daef7db Added FUNDING file 2021-07-20 13:17:56 -06:00
流光溢彩 72bcadea55 Update Simplified Chinese Translation (#49)
* Update Simplified Chinese Translation

Changes:
- Replace all "." char to "。"
- Modify some strings to conform to Chinese usage habits

* Add spaces and units where necessary

* Replace all "您" chat to "你"

* Change "PREVIEW_CONTAINER" translation
2021-07-20 13:10:51 -06:00
Intelli b5b6acaa9d Minor refactoring in Util class 2021-07-19 17:19:35 -06:00
Intelli fae4c9e690 Fixed blocks broken by portal events not being logged (#45) 2021-07-19 16:29:43 -06:00
Intelli 03bac937c3 Minor refactoring in PortalCreateListener 2021-07-19 16:28:40 -06:00
Andrew 1d828e3b68 Improved ru translation (#51) 2021-07-19 13:59:28 -06:00
YuanYuanOwO c71ea224a4 Fix Simplified Chinese translation (#48)
* Fix Simplified Chinese translation

* Update zh-cn.yml
2021-07-17 18:25:28 -06:00
NatsuHana 7ea46fb585 improve(trans/zh-CN): optimize zh-CN translation (#44)
correct some sentences cause ambiguity
2021-07-17 12:39:37 -06:00
Intelli 2bc8a00657 Updated badges in README 2021-07-16 16:57:00 -06:00
Intelli b696abd655 Set workflow Java version back to 8 2021-07-16 16:54:53 -06:00
Intelli 5e2a99b2a8 Updated workflow & removed SonarCloud 2021-07-16 16:38:55 -06:00
HeroCC 79ad6de362 Update WorldEdit Maven Repo & use Java 11 (#43)
* Use HTTPS for sk89q maven repo

Newer Maven releases don't allow use of http endpoints. Bump this to the secure https endpoint.

* Migrate sk89q maven repo to enginehub

Both URLs point to the same place, but according to https://worldguard.enginehub.org/en/latest/developer/dependency/ enginehub is the preferred source.

* Bump Java to Adoptium Hotspot JDK 11
2021-07-16 16:25:24 -06:00
Intelli 3a1e5a356b Updated PR guidelines & added GitHub workflow build file 2021-07-16 15:25:59 -06:00
Intelli db817e603e Fixed French translation 2021-07-16 13:06:44 -06:00
115 changed files with 3635 additions and 2441 deletions

No files matched your search

+1
View File
@@ -0,0 +1 @@
patreon: coreprotect
+13
View File
@@ -0,0 +1,13 @@
daysUntilStale: 60
daysUntilClose: 7
exemptLabels:
- 'accepted'
- 'bug'
- 'suggestion'
- 'help wanted'
staleLabel: stale
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
+28
View File
@@ -0,0 +1,28 @@
name: Build
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
java-version: '17'
distribution: 'temurin'
- name: Cache Maven packages
uses: actions/cache@v1
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: Build
run: mvn -B verify
+1
View File
@@ -62,6 +62,7 @@ mvnw.cmd
## Gradle
#################
build
gradle
# Wrapper files
+1
View File
@@ -11,6 +11,7 @@ Please note we have a code of conduct, please follow it in all your interactions
- Use descriptiveCamelCase for variable/method names. Names containing underscore or abbreviations should be changed.
- Restrict changes in a commit to a single event or section of code (e.g. refactor BlockBreakEvent and BlockPlaceEvent in separate commits)
- Attempt to keep the amount of code modified in a single commit small and readable.
- Please utilize [SonarLint](https://www.sonarlint.org) in your IDE. Contributions are automatically analyzed.
- When adding new functionality, please also be sure to update the documentation as well.
- Use common sense. If you have a suggestion for a contribution guideline, post it on Discord.
+5 -3
View File
@@ -1,8 +1,10 @@
![CoreProtect](https://userfolio.com/uploads/coreprotect-banner-v19.png)
[![Artistic License 2.0](https://img.shields.io/github/license/PlayPro/CoreProtect?&logo=github)](LICENSE)
[![GitHub Workflows](https://github.com/PlayPro/CoreProtect/actions/workflows/build.yml/badge.svg)](https://github.com/PlayPro/CoreProtect/actions)
[![Netlify Status](https://img.shields.io/netlify/c1d26a0f-65c5-4e4b-95d7-e08af671ab67)](https://app.netlify.com/sites/coreprotect/deploys)
[![CodeFactor](https://www.codefactor.io/repository/github/playpro/coreprotect/badge)](https://www.codefactor.io/repository/github/playpro/coreprotect)
[![Join us on Discord](https://img.shields.io/discord/348680641560313868.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/b4DZ4jy)
[![Netlify Status](https://api.netlify.com/api/v1/badges/c1d26a0f-65c5-4e4b-95d7-e08af671ab67/deploy-status)](https://app.netlify.com/sites/coreprotect/deploys)
CoreProtect
===========
@@ -16,7 +18,7 @@ For a detailed description of the plugin, please visit [spigotmc.org/resources/c
| CoreProtect Discord: | [discord.gg/b4DZ4jy](https://discord.gg/b4DZ4jy) |
| CoreProtect Patreon: | [patreon.com/coreprotect](https://www.patreon.com/coreprotect) |
| CoreProtect Documentation: | [docs.coreprotect.net](https://docs.coreprotect.net) |
| Downloads for MC 1.14 - 1.17: | [spigotmc.org/resources/coreprotect.8631](https://www.spigotmc.org/resources/coreprotect.8631/) |
| Downloads for MC 1.14 - 1.18: | [spigotmc.org/resources/coreprotect.8631](https://www.spigotmc.org/resources/coreprotect.8631/) |
| Downloads for MC 1.8 - 1.12: | [coreprotect.net/legacy](https://coreprotect.net/legacy/) |
bStats
@@ -39,7 +41,7 @@ Maven
<dependency>
<groupId>net.coreprotect</groupId>
<artifactId>coreprotect</artifactId>
<version>20.0</version>
<version>20.4</version>
<scope>provided</scope>
</dependency>
```
+4 -2
View File
@@ -7,7 +7,7 @@ plugins {
}
group = 'net.coreprotect'
String projectVersion = '20.0'
String projectVersion = '20.4'
String projectBranch = ''
version = projectVersion // `version` might be modified, we don't always want that (e.g. plugin.yml)
description = 'Provides block protection for your server.'
@@ -36,7 +36,8 @@ dependencies {
exclude group: 'org.bukkit'
}
compileOnly 'org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT'
implementation 'org.bstats:bstats-bukkit-lite:1.7'
implementation 'org.bstats:bstats-bukkit-lite:1.8'
implementation 'com.zaxxer:HikariCP:4.0.3'
}
jar {
@@ -51,6 +52,7 @@ shadowJar {
dependencies {
// #toString because #getGroup technically returns an Object
relocate('org.bstats', project.group.toString())
relocate('com.zaxxer', project.group.toString())
}
archiveClassifier.set(null)
}
+37 -19
View File
@@ -4,8 +4,8 @@ The CoreProtect API enables you to log your own block changes, perform lookups,
| API Details | |
| --- | --- |
| **API Version:** | 7 |
| **Plugin Version:** | v20.0+ |
| **API Version:** | 8 |
| **Plugin Version:** | v20.2+ |
| **Maven:** | [maven.playpro.com](https://maven.playpro.com) |
*Documentation for the previous API version can be found [here](https://www.minerealm.com/community/viewtopic.php?f=32&t=16687).*
@@ -39,8 +39,8 @@ parseResult(String[] result).getTypeId()
## Getting Started
Ensure you're using CoreProtect 20.0 or higher. Add it as an external jar to your plugin in your IDE.
Alternatively, if using Maven, you can add it via the repository [https://maven.playpro.com](https://maven.playpro.com) (net.coreprotect, 20.0).
Ensure you're using CoreProtect 20.2 or higher. Add it as an external jar to your plugin in your IDE.
Alternatively, if using Maven, you can add it via the repository [https://maven.playpro.com](https://maven.playpro.com) (net.coreprotect, 20.2).
The first thing you need to do is get access to CoreProtect. You can do this by using code similar to the following:
@@ -122,21 +122,39 @@ boolean hasRemoved(String user, Block block, int time, int offset)
void performPurge(int time)
```
### Usage
---
`isEnabled()`
### Available Events
*The following events are emitted by CoreProtect.*
#### CoreProtectPreLogEvent
Fired when a CoreProtect logger is about to log an action. Not cancellable.
| Property | Description | Mutable |
| --- | --- | --- |
| User | The name of the user under which this action will be logged. | Yes |
---
### Method Usage
*Detailed method information is listed below.*
#### `isEnabled()`
Calling this will return true if the server has the CoreProtect API enabled, and false if it does not.
---
`testAPI()`
#### `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)`
#### `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.
@@ -151,7 +169,7 @@ This will perform a lookup.
---
`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)`
#### `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.
@@ -166,7 +184,7 @@ This will perform a rollback. Method must be called async.
---
`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)`
#### `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.
@@ -181,7 +199,7 @@ This will perform a restore.
---
`blockLookup(Block block, int time)`
#### `blockLookup(Block block, int time)`
This will perform a full lookup on a single block.
@@ -190,7 +208,7 @@ This will perform a full lookup on a single block.
---
`ParseResult parseResult(String[] result)`
#### `ParseResult parseResult(String[] result)`
This will parse results from a lookup. You'll then be able to view the following:
@@ -208,7 +226,7 @@ This will parse results from a lookup. You'll then be able to view the following
---
`logPlacement(String user, Location location, Material type, BlockData blockData)`
#### `logPlacement(String user, Location location, Material type, BlockData blockData)`
This will log a block as being placed.
@@ -219,7 +237,7 @@ This will log a block as being placed.
---
`logRemoval(String user, Location location, Material type, BlockData blockData)`
#### `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).
@@ -230,7 +248,7 @@ This will log a block as being removed/broken, and will log the block's inventor
---
`logContainerTransaction(String user, Location location)`
#### `logContainerTransaction(String user, Location location)`
This will log any transactions made to a block's inventory immediately after calling the method.
@@ -239,7 +257,7 @@ This will log any transactions made to a block's inventory immediately after cal
---
`logInteraction(String user, Location location)`
#### `logInteraction(String user, Location location)`
This will log a block as having been interacted with.
@@ -248,7 +266,7 @@ This will log a block as having been interacted with.
---
`hasPlaced(String user, Block block, int time, int offset)`
#### `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.
@@ -259,7 +277,7 @@ This will return true if a user has already placed a block at the location withi
---
`hasRemoved(String user, Block block, int time, int 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.
@@ -270,7 +288,7 @@ This will return true if a user has already removed a block at the location with
---
`performPurge(int time)`
#### `performPurge(int time)`
This will perform a purge on the CoreProtect database.
+1 -2
View File
@@ -4,8 +4,7 @@ For more information about CoreProtect, visit [coreprotect.net](http://coreprote
## Getting Started
These documents are still a work in progress.
Please be sure to visit the following links for more information.
Please visit one of the following links for more information.
[**CoreProtect Commands**](/commands/)
A list of all commands that can be used within CoreProtect.
+2 -2
View File
@@ -55,8 +55,8 @@ The following permissions can be used to restrict functionality within the plugi
* **coreprotect.lookup.container** *(default: op)*
Can be optionally used as a negative permission to prevent container lookups.
&nbsp;
* **coreprotect.lookup.item** *(default: op)*
Can be optionally used as a negative permission to prevent item lookups.
* **coreprotect.lookup.inventory** *(default: op)*
Can be optionally used as a negative permission to prevent inventory lookups.
&nbsp;
* **coreprotect.lookup.kill** *(default: op)*
Can be optionally used as a negative permission to prevent entity kill lookups.
+192 -192
View File
@@ -1,197 +1,197 @@
# CoreProtect Language File (fr)
ACTION_NOT_SUPPORTED: "Esa acción no es compatible."
AMOUNT_BLOCK: "{0} {bloque|bloques}"
AMOUNT_CHUNK: "{0} {trozo|trozos}"
AMOUNT_ENTITY: "{0} {entidad|entidades}"
AMOUNT_ITEM: "{0} {artículo|artículos}"
API_TEST: "Prueba de API exitosa."
CACHE_ERROR: "ADVERTENCIA: Error al validar {0} cache."
CACHE_RELOAD: "Forzando la recarga de {mapeo|mundo} cachés de la base de datos."
CHECK_CONFIG: "Por favor revise config.yml"
COMMAND_NOT_FOUND: "Comando \"{0}\" extraviado."
COMMAND_THROTTLED: "Espere un momento y vuelva a intentarlo."
CONTAINER_HEADER: "Transacciones de contenedores"
DATABASE_BUSY: "Base de datos ocupado. Por favor, inténtelo de nuevo más tarde."
DATABASE_INDEX_ERROR: "No se pueden validar los índices de la base de datos."
DATABASE_LOCKED_1: "Base de datos bloqueada. Esperando hasta 15 segundos..."
DATABASE_LOCKED_2: "La base de datos ya está en uso. Inténtalo de nuevo."
DATABASE_LOCKED_3: "Para deshabilitar el bloqueo de la base de datos, establezca \"database-lock: false\"."
DATABASE_LOCKED_4: "La desactivación del bloqueo de la base de datos puede provocar daños en los datos."
DATABASE_UNREACHABLE: "La base de datos es inalcanzable. Descartando datos y cerrando."
DEVELOPMENT_BRANCH: "Se detectó una rama de desarrollo, omitiendo los scripts de parches."
DIRT_BLOCK: "Colocó un bloque de tierra debajo de usted."
DISABLE_SUCCESS: "¡Éxito! Discapacitado {0}"
ENABLE_FAILED: "{0} fue incapaz de comenzar."
ENABLE_SUCCESS: "{0} ahora está habilitado!"
ENJOY_COREPROTECT: "Disfrutar {0}? Únete a nuestro Discord!"
FINISHING_CONVERSION: "Terminando la conversión de datos. Espere por favor..."
FINISHING_LOGGING: "Terminando el registro de datos. Espere por favor..."
FIRST_VERSION: "DB inicial: {0}"
GLOBAL_LOOKUP: "No especifique un radio para realizar una búsqueda global."
GLOBAL_ROLLBACK: "Usar \"{0}\" para hacer un global {deshacer|restaurar}"
HELP_ACTION_1: "Restrinja la búsqueda a una acción."
HELP_ACTION_2: "Ejemplos: [a:block], [a:+block], [a:-block] [a:click], [a:container], [a:inventory], [a:item], [a:kill], [a:chat], [a:command], [a:sign], [a:session], [a:username]"
HELP_COMMAND: "Muestra información adicional."
HELP_EXCLUDE_1: "Excluir bloques / usuarios."
HELP_EXCLUDE_2: "Ejemplos: [e:stone], [e:Notch], [e:stone,Notch]"
HELP_HEADER: "{0} Ayudar"
HELP_INCLUDE_1: "Incluya bloques / entidades."
HELP_INCLUDE_2: "Ejemplos: [i:stone], [i:zombie], [i:stone,wood,bedrock]"
HELP_INSPECT_1: "Con el inspector habilitado, puede:"
HELP_INSPECT_2: "Haga clic con el botón izquierdo para ver la ubicación."
HELP_INSPECT_3: "Haga clic derecho para ver las eliminaciones adyacentes."
HELP_INSPECT_4: "Coloque un bloque para ver la eliminación."
HELP_INSPECT_5: "Coloque un bloque en líquido para ver la ubicación."
HELP_INSPECT_6: "Haga clic derecho para ver las transacciones del cofre."
HELP_INSPECT_7: "Sugerencia: puede usar solo \"/co i\"."
HELP_INSPECT_COMMAND: "Alterna el inspector de bloques."
HELP_LIST: "Muestra una lista de todos los comandos."
HELP_LOOKUP_1: "Atajo de comando."
HELP_LOOKUP_2: "Ver páginas adicionales."
HELP_LOOKUP_COMMAND: "Búsqueda de datos de bloques."
HELP_NO_INFO: "Información para el mando \"{0}\" extraviado."
HELP_PARAMETER: "Por favor mira \"{0}\" para obtener información detallada sobre los parámetros."
HELP_PARAMS_1: "Realizar el {buscar|deshacer|restaurar}."
HELP_PARAMS_2: "Especifique los usuarios para {buscar|deshacer|restaurar}."
HELP_PARAMS_3: "Especifique el tiempo para {buscar|deshacer|restaurar}."
HELP_PARAMS_4: "Restringir el {buscar|deshacer|restaurar} a un radio."
HELP_PARAMS_5: "Restringir el {buscar|deshacer|restaurar} a una acción."
HELP_PARAMS_6: "Incluir bloques / entidades en el {buscar|deshacer|restaurar}."
HELP_PARAMS_7: "Excluir bloques / usuarios del {buscar|deshacer|restaurar}."
HELP_PURGE_1: "Eliminar datos antiguos."
HELP_PURGE_2: "Por ejemplo, \"{0}\" eliminará todos los datos anteriores a un mes y solo conservará los datos de los últimos 30 días."
HELP_PURGE_COMMAND: "Elimina los datos del bloque antiguo."
HELP_RADIUS_1: "Especifique un área de radio."
HELP_RADIUS_2: "Ejemplos: [r:10] (Solo haga cambios dentro de las 10 cuadras de usted)"
HELP_RELOAD_COMMAND: "Vuelve a cargar el archivo de configuración."
HELP_RESTORE_COMMAND: "Restaurar los datos del bloque."
HELP_ROLLBACK_COMMAND: "Revertir los datos del bloque."
HELP_STATUS: "Ver el estado del complemento."
HELP_STATUS_COMMAND: "Muestra el estado del complemento."
HELP_TELEPORT: "Teletransportarse."
HELP_TIME_1: "Especifique la hora."
HELP_TIME_2: "Ejemplos: [t:2w,5d,7h,2m,10s], [t:5d2h], [t:2.50h]"
HELP_USER_1: "Especifique los usuarios."
HELP_USER_2: "Ejemplos: [u:Notch], [u:Notch,#enderman]"
INCOMPATIBLE_ACTION: "\"{0}\" no se puede utilizar con esa acción."
INSPECTOR_ERROR: "Inspector ya {habilitado|deshabilitado}."
INSPECTOR_TOGGLED: "Inspector ahora {habilitado|deshabilitado}."
INTEGRATION_ERROR: "Incapaz de {inicializar|deshabilitar} {0} Inicio sesión."
INTEGRATION_SUCCESS: "{0} registrando exitosamente {inicializado|deshabilitado}."
INTEGRATION_VERSION: "Inválido {0} versión encontrada."
INTERACTIONS_HEADER: "Interacciones del jugador"
INVALID_ACTION: "Esa no es una acción válida."
INVALID_BRANCH_1: "Versión de complemento no válida (la rama no se ha configurado)."
INVALID_BRANCH_2: "Para continuar, establezca la rama del proyecto en \"desarrollo\"."
INVALID_BRANCH_3: "La ejecución de código de desarrollo puede provocar daños en los datos."
INVALID_CONTAINER: "Primero inspeccione un contenedor válido."
INVALID_DONATION_KEY: "Clave de donación no válida."
INVALID_INCLUDE: "\"{0}\" es un valor no válido."
INVALID_INCLUDE_COMBO: "Esa es una combinación de tipos no válida."
INVALID_RADIUS: "Ingrese un radio válido."
INVALID_SELECTION: "{0} selección no encontrada."
INVALID_USERNAME: "\"{0}\" es un nombre de usuario no válido."
INVALID_WORLD: "Especifique un mundo válido."
LATEST_VERSION: "Última versión: {0}"
ACTION_NOT_SUPPORTED: "Cette action n'est pas prise en charge."
AMOUNT_BLOCK: "{0} {bloquer|blocs}"
AMOUNT_CHUNK: "{0} {morceau|morceaux}"
AMOUNT_ENTITY: "{0} {entité|entités}"
AMOUNT_ITEM: "{0} {article|articles}"
API_TEST: "Test API réussi."
CACHE_ERROR: "ATTENTION: Erreur lors de la validation {0} cache."
CACHE_RELOAD: "Forcer le rechargement de {cartographie|monde} cache de la base de données."
CHECK_CONFIG: "Veuillez vérifier config.yml"
COMMAND_NOT_FOUND: "Commande \"{0}\" pas trouvé."
COMMAND_THROTTLED: "Veuillez patienter un instant et réessayer."
CONTAINER_HEADER: "Transactions de conteneurs"
DATABASE_BUSY: "Base de données occupée. Veuillez réessayer plus tard."
DATABASE_INDEX_ERROR: "Impossible de valider les index de la base de données."
DATABASE_LOCKED_1: "Base de données verrouillée. Attendre jusqu'à 15 secondes..."
DATABASE_LOCKED_2: "La base de données est déjà utilisée. Veuillez réessayer."
DATABASE_LOCKED_3: "Pour désactiver le verrouillage de la base de données, définissez \"database-lock: false\"."
DATABASE_LOCKED_4: "La désactivation du verrouillage de la base de données peut entraîner une corruption des données."
DATABASE_UNREACHABLE: "La base de données est inaccessible. Suppression des données et arrêt."
DEVELOPMENT_BRANCH: "Branche de développement détectée, ignorant les scripts de correctif."
DIRT_BLOCK: "Placé un bloc de terre sous vous."
DISABLE_SUCCESS: "Succès! Désactivée {0}"
ENABLE_FAILED: "{0} n'a pas pu démarrer."
ENABLE_SUCCESS: "{0} est maintenant activé !"
ENJOY_COREPROTECT: "Prendre plaisir {0}? Rejoignez notre Discord!"
FINISHING_CONVERSION: "Fin de la conversion des données. S'il vous plaît, attendez..."
FINISHING_LOGGING: "Fin de l'enregistrement des données. S'il vous plaît, attendez..."
FIRST_VERSION: "BD initiale: {0}"
GLOBAL_LOOKUP: "Ne spécifiez pas de rayon pour effectuer une recherche globale."
GLOBAL_ROLLBACK: "Utiliser \"{0}\" pour faire une globalité {restauration|restauration}"
HELP_ACTION_1: "Restreindre la recherche à une action."
HELP_ACTION_2: "Exemples: [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: "Afficher des informations supplémentaires."
HELP_EXCLUDE_1: "Exclure les blocs/utilisateurs."
HELP_EXCLUDE_2: "Exemples: [e:stone], [e:Notch], [e:stone,Notch]"
HELP_HEADER: "{0} Aider"
HELP_INCLUDE_1: "Inclure les blocs/entités."
HELP_INCLUDE_2: "Exemples: [i:stone], [i:zombie], [i:stone,wood,bedrock]"
HELP_INSPECT_1: "Avec l'inspecteur activé, vous pouvez:"
HELP_INSPECT_2: "Faites un clic gauche pour voir l'emplacement."
HELP_INSPECT_3: "Cliquez avec le bouton droit pour voir les suppressions adjacentes."
HELP_INSPECT_4: "Placez un bloc pour voir la suppression."
HELP_INSPECT_5: "Placer un bloc dans du liquide pour voir le placement."
HELP_INSPECT_6: "Faites un clic droit pour voir les transactions de coffre."
HELP_INSPECT_7: "Astuce: Vous pouvez utiliser uniquement \"/co i\"."
HELP_INSPECT_COMMAND: "Bascule l'inspecteur de bloc."
HELP_LIST: "Affiche une liste de toutes les commandes."
HELP_LOOKUP_1: "Raccourci de commande."
HELP_LOOKUP_2: "Afficher des pages supplémentaires."
HELP_LOOKUP_COMMAND: "Rechercher des données de bloc."
HELP_NO_INFO: "Informations pour la commande \"{0}\" pas trouvé."
HELP_PARAMETER: "S'il te plait regarde \"{0}\" pour des informations détaillées sur les paramètres."
HELP_PARAMS_1: "Effectuer la {recherche|restauration|restauration}."
HELP_PARAMS_2: "Spécifiez les utilisateurs à {recherche|restauration|restauration}."
HELP_PARAMS_3: "Précisez l'heure de {recherche|restauration|restauration}."
HELP_PARAMS_4: "Restreindre le {recherche|restauration|restauration} à un rayon."
HELP_PARAMS_5: "Restreindre le {recherche|restauration|restauration} à une action."
HELP_PARAMS_6: "Inclure des blocs/entités dans le {recherche|restauration|restauration}."
HELP_PARAMS_7: "Exclure les blocs/utilisateurs du {recherche|restauration|restauration}."
HELP_PURGE_1: "Supprimer les anciennes données."
HELP_PURGE_2: "Par example, \"{0}\" supprimera toutes les données de plus d'un mois et ne conservera que les 30 derniers jours de données."
HELP_PURGE_COMMAND: "Supprimez les anciennes données de bloc."
HELP_RADIUS_1: "Spécifiez une zone de rayon."
HELP_RADIUS_2: "Exemples: [r:10] (N'apportez des modifications qu'à moins de 10 blocs de vous)"
HELP_RELOAD_COMMAND: "Recharge le fichier de configuration."
HELP_RESTORE_COMMAND: "Restaurer les données de bloc."
HELP_ROLLBACK_COMMAND: "Données de bloc d'annulation."
HELP_STATUS: "Afficher l'état du plug-in."
HELP_STATUS_COMMAND: "Affiche l'état du plug-in."
HELP_TELEPORT: "Téléportation."
HELP_TIME_1: "Précisez l'heure."
HELP_TIME_2: "Exemples: [t:2w,5d,7h,2m,10s], [t:5d2h], [t:2.50h]"
HELP_USER_1: "Spécifiez les utilisateurs."
HELP_USER_2: "Exemples: [u:Notch], [u:Notch,#enderman]"
INCOMPATIBLE_ACTION: "\"{0}\" ne peut pas être utilisé avec cette action."
INSPECTOR_ERROR: "Inspecteur déjà {activé|désactivé}."
INSPECTOR_TOGGLED: "Inspecteur maintenant {activé|désactivé}."
INTEGRATION_ERROR: "Incapable de {initialiser|désactiver} {0} enregistrement."
INTEGRATION_SUCCESS: "{0} connexion avec succès {initialisé|désactivé}."
INTEGRATION_VERSION: "Invalide {0} version trouvée."
INTERACTIONS_HEADER: "Interactions avec les joueurs"
INVALID_ACTION: "Ce n'est pas une action valable."
INVALID_BRANCH_1: "Version du plugin non valide (la branche n'a pas été définie)."
INVALID_BRANCH_2: "Pour continuer, définissez la branche du projet sur \"développement\"."
INVALID_BRANCH_3: "L'exécution du code de développement peut entraîner une corruption des données."
INVALID_CONTAINER: "Veuillez d'abord inspecter un conteneur valide."
INVALID_DONATION_KEY: "Clé de don invalide."
INVALID_INCLUDE: "\"{0}\" est une valeur invalide."
INVALID_INCLUDE_COMBO: "C'est une combinaison de type invalide."
INVALID_RADIUS: "Veuillez saisir un rayon valide."
INVALID_SELECTION: "{0} sélection introuvable."
INVALID_USERNAME: "\"{0}\" est un nom d'utilisateur invalide."
INVALID_WORLD: "Veuillez spécifier un monde valide."
LATEST_VERSION: "Dernière version: {0}"
LINK_DISCORD: "Discord: {0}"
LINK_DOWNLOAD: "Descargar: {0}"
LINK_DOWNLOAD: "Télécharger: {0}"
LINK_PATREON: "Patreon: {0}"
LINK_WIKI_BLOCK: "Nombres de bloque: {0}"
LINK_WIKI_ENTITY: "Nombres de entidades: {0}"
LOGGING_ITEMS: "{0} elementos que quedan por registrar. Espere por favor..."
LOGGING_TIME_LIMIT: "Se alcanzó el límite de tiempo de registro. Descartando datos y cerrando."
LOOKUP_BLOCK: "{0} {colocado|roto} {1}."
LOOKUP_CONTAINER: "{0} {añadido|eliminado} {1} {2}."
LOOKUP_HEADER: "{0} Resultados"
LOOKUP_INTERACTION: "{0} {clickeado|muerto} {1}."
LOOKUP_ITEM: "{0} {recogido|caído} {1} {2}."
LOOKUP_LOGIN: "{0} registrado {adentro|afuera}."
LOOKUP_PAGE: "Página {0}"
LOOKUP_ROWS_FOUND: "{0} {fila|filas} encontró."
LOOKUP_SEARCHING: "Búsqueda de búsqueda. Espere por favor..."
LINK_WIKI_BLOCK: "Noms de bloc: {0}"
LINK_WIKI_ENTITY: "Noms des entités: {0}"
LOGGING_ITEMS: "{0} éléments laissés à enregistrer. S'il vous plaît, attendez..."
LOGGING_TIME_LIMIT: "Limite de temps d'enregistrement atteinte. Suppression des données et arrêt."
LOOKUP_BLOCK: "{0} {placé|cassé} {1}."
LOOKUP_CONTAINER: "{0} {ajouté|supprimé} {1} {2}."
LOOKUP_HEADER: "{0} Résultats"
LOOKUP_INTERACTION: "{0} {cliqué|tué} {1}."
LOOKUP_ITEM: "{0} {ramassé|lâché} {1} {2}."
LOOKUP_LOGIN: "{0} connecté {entrée|sortie}."
LOOKUP_PAGE: "Page {0}"
LOOKUP_ROWS_FOUND: "{0} {ligne|lignes} trouvé."
LOOKUP_SEARCHING: "Recherche de recherche. S'il vous plaît, attendez..."
LOOKUP_STORAGE: "{0} {déposé|retiré} {1} {2}."
LOOKUP_TIME: "{0} atrás"
LOOKUP_USERNAME: "{0} Conectado como {1}."
LOOKUP_VIEW_PAGE: "Para ver una página, escriba \"{0}\"."
MAXIMUM_RADIUS: "El maximo {buscar|deshacer|restaurar} el radio es {0}."
MISSING_ACTION_USER: "Para utilizar esa acción, especifique un usuario."
MISSING_LOOKUP_TIME: "Por favor, especifique el tiempo para {buscar|deshacer|restaurar}."
MISSING_LOOKUP_USER: "Especifique un usuario o {bloque|radio}."
MISSING_PARAMETERS: "Por favor use \"{0}\"."
MISSING_ROLLBACK_RADIUS: "No especificó un {deshacer|restaurar} radio."
MISSING_ROLLBACK_USER: "No especificó un {deshacer|restaurar} usuario."
MYSQL_UNAVAILABLE: "Incapaz de conectarse a MySQL servidor."
NO_DATA: "No se encontraron datos en {0}."
NO_DATA_LOCATION: "No {datos|transacciones|interacciones|mensajes} encontró."
NO_PERMISSION: "No tienes permiso para hacer eso."
NO_RESULTS: "No se han encontrado resultados."
NO_RESULTS_PAGE: "No {resultados|datos} encontrado para esa página."
NO_ROLLBACK: "No {pendiente|anterior} deshacer / restaurar encontrado."
PATCH_INTERRUPTED: "Actualización interrumpida. Intentará de nuevo al reiniciar."
PATCH_OUTDATED_1: "No se pueden actualizar las bases de datos anteriores a {0}."
PATCH_OUTDATED_2: "Actualice con una versión compatible de CoreProtect."
PATCH_PROCESSING: "Procesando nuevos datos. Espere por favor..."
PATCH_SKIP_UPDATE: "Salto a la comba {tabla|índice} {actualización|creación|eliminación} en {0}."
PATCH_STARTED: "Ejecutando {0} potenciar. Espere por favor..."
PATCH_SUCCESS: "Actualizado con éxito a {0}."
PATCH_UPGRADING: "Actualización de la base de datos en curso. Espere por favor..."
PLEASE_SELECT: "Seleccione: \"{0}\" o \"{1}\"."
PREVIEW_CANCELLED: "Vista previa cancelada."
PREVIEW_CANCELLING: "Cancelando vista previa..."
PREVIEW_CONTAINER: "No puede obtener una vista previa de las transacciones de contenedor."
PREVIEW_IN_GAME: "Solo puedes obtener una vista previa de las reversiones en el juego."
PURGE_ABORTED: "La purga falló. La base de datos puede estar dañada."
PURGE_ERROR: "No se puede procesar {0} ¡datos!"
PURGE_FAILED: "La purga falló. Por favor, inténtelo de nuevo más tarde."
PURGE_IN_PROGRESS: "Purga en curso. Por favor, inténtelo de nuevo más tarde."
PURGE_MINIMUM_TIME: "Solo puede depurar datos anteriores a {0} {días|horas}."
PURGE_NOTICE_1: "Tenga en cuenta que esto puede llevar algún tiempo."
PURGE_NOTICE_2: "No reinicie su servidor hasta que haya terminado."
PURGE_OPTIMIZING: "Optimización de la base de datos. Espere por favor..."
PURGE_PROCESSING: "Procesando {0} datos..."
PURGE_REPAIRING: "Intentando reparar. Esto puede tomar algo de tiempo..."
PURGE_ROWS: "{0} {fila|filas} de datos eliminados."
PURGE_STARTED: "La depuración de datos comenzó el \"{0}\"."
PURGE_SUCCESS: "Purga de datos exitosa."
RELOAD_STARTED: "Recargando la configuración - espere."
RELOAD_SUCCESS: "Configuración recargada correctamente."
ROLLBACK_ABORTED: "Reversión o restauración abortada."
ROLLBACK_CHUNKS_FOUND: "Encontró {0} {trozo|trozos} Modificar."
ROLLBACK_CHUNKS_MODIFIED: "Modificado {0}/{1} {trozo|trozos}."
ROLLBACK_COMPLETED: "{Retroceder|Restaurar|Vista previa} completado para \"{0}\"."
ROLLBACK_EXCLUDED_USERS: "Excluido {usuario|usuarios}: \"{0}\"."
ROLLBACK_INCLUDE: "{Incluido|Excluido} {bloque|entidad|objetivo} {tipo|tipos}: \"{0}\"."
ROLLBACK_IN_PROGRESS: "Ya se está realizando una reversión / restauración."
ROLLBACK_LENGTH: "Tiempo tomado: {0} {segundo|segundos}."
ROLLBACK_MODIFIED: "{Modificado|Modificando} {0}."
ROLLBACK_RADIUS: "Radio: {0} {bloque|bloques}."
ROLLBACK_SELECTION: "Radio establecido en \"{0}\"."
ROLLBACK_STARTED: "{Retroceder|Restaurar|Vista previa} comenzó en \"{0}\"."
ROLLBACK_TIME: "Intervalo de tiempo: {0}."
ROLLBACK_WORLD_ACTION: "Prohibido para {mundo|acción} \"{0}\"."
SIGN_HEADER: "Firmar mensajes"
STATUS_CONSUMER: "Consumidor: {0} {artículo|artículos} en fila."
STATUS_DATABASE: "Base de datos: Usando {0}."
STATUS_INTEGRATION: "{0}: Integración {habilitado|deshabilitado}."
STATUS_LICENSE: "Licencia: {0}"
STATUS_VERSION: "Versión: {0}"
TELEPORTED: "Teletransportado a {0}."
TELEPORTED_SAFETY: "Te teletransportó a un lugar seguro."
TELEPORT_PLAYERS: "El comando de teletransporte solo puede ser utilizado por jugadores."
TIME_DAYS: "{0} {día|días}"
TIME_HOURS: "{0} {hora|horas}"
TIME_MINUTES: "{0} {minuto|minutos}"
TIME_SECONDS: "{0} {segundo|segundos}"
TIME_WEEKS: "{0} {semana|semanas}"
UPDATE_ERROR: "Se produjo un error al buscar actualizaciones."
UPDATE_HEADER: "{0} Actualizar"
UPDATE_NOTICE: "Darse cuenta: {0} Ya está disponible."
UPGRADE_IN_PROGRESS: "Actualización en curso. Por favor, inténtelo de nuevo más tarde."
USER_NOT_FOUND: "Usuario \"{0}\" extraviado."
USING_MYSQL: "Utilizando MySQL para el almacenamiento de datos."
USING_SQLITE: "Utilizando SQLite para el almacenamiento de datos."
VALID_DONATION_KEY: "Clave de donación válida."
VERSION_NOTICE: "Versión {0} Ya está disponible."
VERSION_REQUIRED: "{0} {1} se requiere o superior."
WORLD_NOT_FOUND: "Mundo \"{0}\" extraviado."
LOOKUP_TIME: "{0} depuis"
LOOKUP_USERNAME: "{0} connecté en tant que {1}."
LOOKUP_VIEW_PAGE: "Pour afficher une page, tapez \"{0}\"."
MAXIMUM_RADIUS: "Le maximum {recherche|restauration|restauration} le rayon est {0}."
MISSING_ACTION_USER: "Pour utiliser cette action, veuillez spécifier un utilisateur."
MISSING_LOOKUP_TIME: "Veuillez préciser l'heure à laquelle {recherche|restauration|restauration}."
MISSING_LOOKUP_USER: "Veuillez spécifier un utilisateur ou {bloc|rayon}."
MISSING_PARAMETERS: "Veuillez utiliser \"{0}\"."
MISSING_ROLLBACK_RADIUS: "Vous n'avez pas spécifié de {restauration|restauration} rayon."
MISSING_ROLLBACK_USER: "Vous n'avez pas spécifié de {restauration|restauration} utilisateur."
MYSQL_UNAVAILABLE: "Impossible de se connecter MySQL serveur."
NO_DATA: "Aucune donnée trouvée sur {0}."
NO_DATA_LOCATION: "Non {données|transactions|interactions|messages} trouvé."
NO_PERMISSION: "Vous n'avez pas la permission de le faire."
NO_RESULTS: "Aucun résultat trouvé."
NO_RESULTS_PAGE: "Non {résultats|données} trouvé pour cette page."
NO_ROLLBACK: "Non {en attente|précédent} annulation/restauration trouvée."
PATCH_INTERRUPTED: "Mise à niveau interrompue. Je réessayerai au redémarrage."
PATCH_OUTDATED_1: "Impossible de mettre à niveau les bases de données antérieures à {0}."
PATCH_OUTDATED_2: "Veuillez mettre à niveau avec une version prise en charge de CoreProtect."
PATCH_PROCESSING: "Traitement de nouvelles données. S'il vous plaît, attendez..."
PATCH_SKIP_UPDATE: "Saut {table|index} {mise à jour|création|suppression} au {0}."
PATCH_STARTED: "Performant {0} améliorer. S'il vous plaît, attendez..."
PATCH_SUCCESS: "Mise à niveau réussie vers {0}."
PATCH_UPGRADING: "Mise à niveau de la base de données en cours. S'il vous plaît, attendez..."
PLEASE_SELECT: "Veuillez sélectionner: \"{0}\" ou alors \"{1}\"."
PREVIEW_CANCELLED: "Aperçu annulé."
PREVIEW_CANCELLING: "Annulation de l'aperçu..."
PREVIEW_CONTAINER: "Vous ne pouvez pas prévisualiser les transactions de conteneur."
PREVIEW_IN_GAME: "Vous ne pouvez prévisualiser les rollbacks que dans le jeu."
PURGE_ABORTED: "Échec de la purge. La base de données est peut-être corrompue."
PURGE_ERROR: "Impossible de traiter {0} Les données!"
PURGE_FAILED: "Échec de la purge. Veuillez réessayer plus tard."
PURGE_IN_PROGRESS: "Purge en cours. Veuillez réessayer plus tard."
PURGE_MINIMUM_TIME: "Vous ne pouvez purger que les données antérieures à {0} {jours|heures}."
PURGE_NOTICE_1: "Veuillez noter que cela peut prendre un certain temps."
PURGE_NOTICE_2: "Ne redémarrez pas votre serveur avant d'avoir terminé."
PURGE_OPTIMIZING: "Optimisation de la base de données. S'il vous plaît, attendez..."
PURGE_PROCESSING: "Traitement {0} Les données..."
PURGE_REPAIRING: "Tenter de réparer. Cela peut prendre un certain temps..."
PURGE_ROWS: "{0} {ligne|lignes} de données supprimées."
PURGE_STARTED: "La purge des données a commencé le \"{0}\"."
PURGE_SUCCESS: "Purge des données réussie."
RELOAD_STARTED: "Rechargement de la configuration - veuillez patienter."
RELOAD_SUCCESS: "Configuration rechargée avec succès."
ROLLBACK_ABORTED: "Annulation de l'annulation ou de la restauration."
ROLLBACK_CHUNKS_FOUND: "Trouvé {0} {morceau|morceaux} modifier."
ROLLBACK_CHUNKS_MODIFIED: "Modifié {0}/{1} {morceau|morceaux}."
ROLLBACK_COMPLETED: "{Retour en arrière|Restaurer|Aperçu} terminé pour \"{0}\"."
ROLLBACK_EXCLUDED_USERS: "Exclu {utilisateur|utilisateurs}: \"{0}\"."
ROLLBACK_INCLUDE: "{Inclus|Exclus} {bloc|entité|cible} {type|types}: \"{0}\"."
ROLLBACK_IN_PROGRESS: "Une annulation/restauration est déjà en cours."
ROLLBACK_LENGTH: "Temps pris: {0} {seconde|secondes}."
ROLLBACK_MODIFIED: "{Modifié|Modification} {0}."
ROLLBACK_RADIUS: "Rayon: {0} {bloquer|blocs}."
ROLLBACK_SELECTION: "Rayon réglé sur \"{0}\"."
ROLLBACK_STARTED: "{Retour en arrière|Restaurer|Aperçu} commencé sur \"{0}\"."
ROLLBACK_TIME: "Intervalle de temps: {0}."
ROLLBACK_WORLD_ACTION: "Limité à {monde|action} \"{0}\"."
SIGN_HEADER: "Signer des messages"
STATUS_CONSUMER: "Consommateur: {0} {article|articles} dans la queue."
STATUS_DATABASE: "Base de données: Utilisation {0}."
STATUS_INTEGRATION: "{0}: Intégration {activé|désactivé}."
STATUS_LICENSE: "Licence: {0}"
STATUS_VERSION: "Version: {0}"
TELEPORTED: "Téléporté à {0}."
TELEPORTED_SAFETY: "Vous a téléporté en lieu sûr."
TELEPORT_PLAYERS: "La commande de téléportation ne peut être utilisée que par les joueurs."
TIME_DAYS: "{0} {jour|jours}"
TIME_HOURS: "{0} {heure|heures}"
TIME_MINUTES: "{0} {minute|minutes}"
TIME_SECONDS: "{0} {seconde|secondes}"
TIME_WEEKS: "{0} {semaine|semaines}"
UPDATE_ERROR: "Une erreur s'est produite lors de la recherche de mises à jour."
UPDATE_HEADER: "{0} Mettre à jour"
UPDATE_NOTICE: "Remarquer: {0} est maintenant disponible."
UPGRADE_IN_PROGRESS: "Mise à niveau en cours. Veuillez réessayer plus tard."
USER_NOT_FOUND: "Utilisateur \"{0}\" pas trouvé."
USING_MYSQL: "Utilisant MySQL pour le stockage des données."
USING_SQLITE: "Utilisant SQLite pour le stockage des données."
VALID_DONATION_KEY: "Clé de don valide."
VERSION_NOTICE: "Version {0} est maintenant disponible."
VERSION_REQUIRED: "{0} {1} ou supérieur est requis."
WORLD_NOT_FOUND: "Monde \"{0}\" pas trouvé."
+197
View File
@@ -0,0 +1,197 @@
# CoreProtect Language File (ja)
ACTION_NOT_SUPPORTED: "そのアクションはサポートされていません。"
AMOUNT_BLOCK: "{0} {ブロック|ブロック}"
AMOUNT_CHUNK: "{0} {チャンク|チャンク}"
AMOUNT_ENTITY: "{0} {エンティティ|エンティティ}"
AMOUNT_ITEM: "{0} {item|items}"
API_TEST: "APIテストが成功しました。"
CACHE_ERROR: "警告:検証中にエラーが発生しました {0} キャッシュ。"
CACHE_RELOAD: "のリロードを強制する {マッピング|世界} データベースからのキャッシュ。"
CHECK_CONFIG: "config.ymlを確認してください"
COMMAND_NOT_FOUND: "指示 \"{0}\" 見つかりません。"
COMMAND_THROTTLED: "しばらく待ってから、もう一度お試しください。"
CONTAINER_HEADER: "コンテナトランザクション"
DATABASE_BUSY: "データベースがビジーです。後でもう一度やり直してください。"
DATABASE_INDEX_ERROR: "データベースインデックスを検証できません。"
DATABASE_LOCKED_1: "データベースがロックされています。最大15秒待機しています..."
DATABASE_LOCKED_2: "データベースはすでに使用されています。もう一度やり直してください。"
DATABASE_LOCKED_3: "データベースロックを無効にするには、「database-lock:false」を設定します。"
DATABASE_LOCKED_4: "データベースロックを無効にすると、データが破損する可能性があります。"
DATABASE_UNREACHABLE: "データベースにアクセスできません。データを破棄してシャットダウンします。"
DEVELOPMENT_BRANCH: "開発ブランチが検出され、パッチスクリプトをスキップしました。"
DIRT_BLOCK: "あなたの下にダートブロックを置きました。"
DISABLE_SUCCESS: "成功!無効 {0}"
ENABLE_FAILED: "{0} 開始できませんでした。"
ENABLE_SUCCESS: "{0} これで有効になります!"
ENJOY_COREPROTECT: "楽しみ {0}?私たちに参加する Discord!"
FINISHING_CONVERSION: "データ変換を終了します。お待ちください..."
FINISHING_LOGGING: "データロギングの終了。お待ちください..."
FIRST_VERSION: "初期DB:{0}"
GLOBAL_LOOKUP: "グローバルルックアップを実行するために半径を指定しないでください。"
GLOBAL_ROLLBACK: "つかいます \"{0}「グローバルに {ロールバック|復元}"
HELP_ACTION_1: "ルックアップをアクションに制限します。"
HELP_ACTION_2: "例:[a:block]、 [a:+block]、 [a:-block] [a:click]、 [a:container]、 [a:inventory]、 [a:item]、 [a:kill]、 [a:chat]、 [a:command]、 [a:sign]、 [a:session]、 [a:username]"
HELP_COMMAND: "追加情報を表示します。"
HELP_EXCLUDE_1: "ブロック/ユーザーを除外します。"
HELP_EXCLUDE_2: "例:[e:stone]、 [e:Notch]、 [e:stone,Notch]"
HELP_HEADER: "{0} ヘルプ"
HELP_INCLUDE_1: "ブロック/エンティティを含めます。"
HELP_INCLUDE_2: "例:[i:stone]、 [i:zombie]、 [i:stone,wood,bedrock]"
HELP_INSPECT_1: "インスペクターを有効にすると、次のことができます。"
HELP_INSPECT_2: "左クリックして配置を確認します。"
HELP_INSPECT_3: "右クリックして、隣接する削除を表示します。"
HELP_INSPECT_4: "ブロックを配置して、削除を確認します。"
HELP_INSPECT_5: "ブロックを液体に入れて配置を確認します。"
HELP_INSPECT_6: "右クリックしてチェストトランザクションを表示します。"
HELP_INSPECT_7: "ヒント:「/coi」だけを使用できます。"
HELP_INSPECT_COMMAND: "ブロックインスペクターを切り替えます。"
HELP_LIST: "すべてのコマンドのリストを表示します。"
HELP_LOOKUP_1: "コマンドショートカット。"
HELP_LOOKUP_2: "追加のページを表示します。"
HELP_LOOKUP_COMMAND: "ルックアップブロックデータ。"
HELP_NO_INFO: "コマンドの情報 \"{0}\" 見つかりません。"
HELP_PARAMETER: "見てください \"{0}詳細なパラメータ情報については、「」を参照してください。"
HELP_PARAMS_1: "を実行します {ルックアップ|ロールバック|復元}。"
HELP_PARAMS_2: "ユーザーを指定して {ルックアップ|ロールバック|復元}。"
HELP_PARAMS_3: "時間を指定します {ルックアップ|ロールバック|復元}。"
HELP_PARAMS_4: "制限する {ルックアップ|ロールバック|復元} 半径に。"
HELP_PARAMS_5: "制限する {ルックアップ|ロールバック|復元} アクションに。"
HELP_PARAMS_6: "ブロック/エンティティをに含める {ルックアップ|ロールバック|復元}。"
HELP_PARAMS_7: "ブロック/ユーザーをから除外する {ルックアップ|ロールバック|復元}。"
HELP_PURGE_1: "古いデータを削除します。"
HELP_PURGE_2: "例えば、 \"{0}\" は、1か月より古いすべてのデータを削除し、過去30日間のデータのみを保持します。"
HELP_PURGE_COMMAND: "古いブロックデータを削除します。"
HELP_RADIUS_1: "半径領域を指定します。"
HELP_RADIUS_2: "例:[r:10] (変更は10ブロック以内でのみ行ってください)"
HELP_RELOAD_COMMAND: "構成ファイルを再ロードします。"
HELP_RESTORE_COMMAND: "ブロックデータを復元します。"
HELP_ROLLBACK_COMMAND: "ブロックデータをロールバックします。"
HELP_STATUS: "プラグインのステータスを表示します。"
HELP_STATUS_COMMAND: "プラグインのステータスを表示します。"
HELP_TELEPORT: "テレポート。"
HELP_TIME_1: "時間を指定します。"
HELP_TIME_2: "例:[t:2w,5d,7h,2m,10s]、 [t:5d2h]、 [t:2.50h]"
HELP_USER_1: "ユーザーを指定します。"
HELP_USER_2: "例:[u:Notch]、 [u:Notch,#enderman]"
INCOMPATIBLE_ACTION: "「」{0}「そのアクションでは使用できません。"
INSPECTOR_ERROR: "すでに検査官 {有効|無効}。"
INSPECTOR_TOGGLED: "今インスペクター {有効|無効}。"
INTEGRATION_ERROR: "できません {初期化|無効化} {0} ロギング。"
INTEGRATION_SUCCESS: "{0} 正常にロギング {初期化|無効}。"
INTEGRATION_VERSION: "無効 {0} バージョンが見つかりました。"
INTERACTIONS_HEADER: "プレイヤーの相互作用"
INVALID_ACTION: "それは有効なアクションではありません。"
INVALID_BRANCH_1: "プラグインのバージョンが無効です(ブランチが設定されていません)。"
INVALID_BRANCH_2: "続行するには、プロジェクトブランチを「開発」に設定します。"
INVALID_BRANCH_3: "開発コードを実行すると、データが破損する可能性があります。"
INVALID_CONTAINER: "最初に有効なコンテナを調べてください。"
INVALID_DONATION_KEY: "寄付キーが無効です。"
INVALID_INCLUDE: "「」{0}\" は無効な値です。"
INVALID_INCLUDE_COMBO: "これは無効な型の組み合わせです。"
INVALID_RADIUS: "有効な半径を入力してください。"
INVALID_SELECTION: "{0} 選択が見つかりません。"
INVALID_USERNAME: "「」{0}\" は無効なユーザー名です。"
INVALID_WORLD: "有効なワールドを指定してください。"
LATEST_VERSION: "最新バージョン: {0}"
LINK_DISCORD: "Discord: {0}"
LINK_DOWNLOAD: "ダウンロード:{0}"
LINK_PATREON: "Patreon: {0}"
LINK_WIKI_BLOCK: "ブロック名:{0}"
LINK_WIKI_ENTITY: "エンティティ名:{0}"
LOGGING_ITEMS: "{0} ログに残されたアイテム。お待ちください..."
LOGGING_TIME_LIMIT: "ロギングの制限時間に達しました。データを破棄してシャットダウンします。"
LOOKUP_BLOCK: "{0} {配置|壊れた} {1}。"
LOOKUP_CONTAINER: "{0} {追加|削除} {1} {2}。"
LOOKUP_HEADER: "{0} 結果"
LOOKUP_INTERACTION: "{0} {クリック|殺された} {1}。"
LOOKUP_ITEM: "{0} {拾った|落とした} {1} {2}。"
LOOKUP_LOGIN: "{0} ログに記録されます {in|out}。"
LOOKUP_PAGE: "ページ {0}"
LOOKUP_ROWS_FOUND: "{0} {行|行} 見つかった。"
LOOKUP_SEARCHING: "ルックアップ検索。お待ちください..."
LOOKUP_STORAGE: "{0} {預け入れ|撤回} {1} {2}。"
LOOKUP_TIME: "{0} 前に"
LOOKUP_USERNAME: "{0} としてログイン {1}。"
LOOKUP_VIEW_PAGE: "ページを表示するには、「{0}\" 。"
MAXIMUM_RADIUS: "最大 {ルックアップ|ロールバック|復元} 半径は {0}。"
MISSING_ACTION_USER: "そのアクションを使用するには、ユーザーを指定してください。"
MISSING_LOOKUP_TIME: "時間を指定してください {ルックアップ|ロールバック|復元}。"
MISSING_LOOKUP_USER: "ユーザーを指定するか、 {ブロック|半径}。"
MISSING_PARAMETERS: "使ってください \"{0}\" 。"
MISSING_ROLLBACK_RADIUS: "指定しませんでした {ロールバック|復元} 半径。"
MISSING_ROLLBACK_USER: "指定しませんでした {ロールバック|復元} ユーザー。"
MYSQL_UNAVAILABLE: "接続できません MySQL サーバ。"
NO_DATA: "でデータが見つかりません {0}。"
NO_DATA_LOCATION: "番号 {データ|トランザクション|相互作用|メッセージ} 見つかった。"
NO_PERMISSION: "あなたにはそれをする許可がありません。"
NO_RESULTS: "結果が見つかりません。"
NO_RESULTS_PAGE: "番号 {結果|データ} そのページで見つかりました。"
NO_ROLLBACK: "番号 {保留中|前へ} ロールバック/復元が見つかりました。"
PATCH_INTERRUPTED: "アップグレードが中断されました。再起動時に再試行します。"
PATCH_OUTDATED_1: "古いデータベースをアップグレードできません {0}。"
PATCH_OUTDATED_2: "サポートされているバージョンでアップグレードしてください CoreProtect。"
PATCH_PROCESSING: "新しいデータを処理しています。お待ちください..."
PATCH_SKIP_UPDATE: "スキップ {テーブル|インデックス} {更新|作成|削除} の上 {0}。"
PATCH_STARTED: "実行する {0} アップグレード。お待ちください..."
PATCH_SUCCESS: "正常にアップグレードされました {0}。"
PATCH_UPGRADING: "データベースのアップグレードが進行中です。お待ちください..."
PLEASE_SELECT: "選んでください: \"{0}\" また \"{1}\" 。"
PREVIEW_CANCELLED: "プレビューがキャンセルされました。"
PREVIEW_CANCELLING: "プレビューをキャンセルしています..."
PREVIEW_CONTAINER: "コンテナトランザクションをプレビューすることはできません。"
PREVIEW_IN_GAME: "ゲーム内でのみロールバックをプレビューできます。"
PURGE_ABORTED: "パージに失敗しました。データベースが破損している可能性があります。"
PURGE_ERROR: "処理できません {0} データ!"
PURGE_FAILED: "パージに失敗しました。後でもう一度やり直してください。"
PURGE_IN_PROGRESS: "進行中のパージ。後でもう一度やり直してください。"
PURGE_MINIMUM_TIME: "パージできるのは、より古いデータのみです。 {0} {日|時間}。"
PURGE_NOTICE_1: "これには時間がかかる場合がありますのでご注意ください。"
PURGE_NOTICE_2: "完了するまでサーバーを再起動しないでください。"
PURGE_OPTIMIZING: "データベースの最適化。お待ちください..."
PURGE_PROCESSING: "処理 {0} データ..."
PURGE_REPAIRING: "修復しようとしています。これには時間がかかる場合があります..."
PURGE_ROWS: "{0} {行|行} 削除されたデータの。"
PURGE_STARTED: "データの削除は \"で開始されました{0}\" 。"
PURGE_SUCCESS: "データのパージに成功しました。"
RELOAD_STARTED: "構成の再読み込み-しばらくお待ちください。"
RELOAD_SUCCESS: "構成が正常に再ロードされました。"
ROLLBACK_ABORTED: "ロールバックまたは復元が中止されました。"
ROLLBACK_CHUNKS_FOUND: "見つかった {0} {チャンク|チャンク} 変更します。"
ROLLBACK_CHUNKS_MODIFIED: "変更 {0}/{1} {チャンク|チャンク}。"
ROLLBACK_COMPLETED: "{ロールバック|復元|プレビュー} 「のために完成{0}\" 。"
ROLLBACK_EXCLUDED_USERS: "除外 {ユーザー|ユーザー}: \"{0}\" 。"
ROLLBACK_INCLUDE: "{含まれる|除外される} {ブロック|エンティティ|ターゲット} {タイプ|タイプ}: \"{0}\" 。"
ROLLBACK_IN_PROGRESS: "ロールバック/復元はすでに進行中です。"
ROLLBACK_LENGTH: "所要時間:{0} {秒|秒}。"
ROLLBACK_MODIFIED: "{変更|変更} {0}。"
ROLLBACK_RADIUS: "半径:{0} {ブロック|ブロック}。"
ROLLBACK_SELECTION: "半径を「{0}\" 。"
ROLLBACK_STARTED: "{ロールバック|復元|プレビュー} 「で始まった{0}\" 。"
ROLLBACK_TIME: "時間範囲:{0}。"
ROLLBACK_WORLD_ACTION: "に制限 {世界|アクション} 「」{0}\" 。"
SIGN_HEADER: "メッセージに署名する"
STATUS_CONSUMER: "消費者: {0} {item|items} 順番待ち。"
STATUS_DATABASE: "データベース: 使用する {0}。"
STATUS_INTEGRATION: "{0}: 統合 {有効|無効}。"
STATUS_LICENSE: "ライセンス: {0}"
STATUS_VERSION: "バージョン: {0}"
TELEPORTED: "にテレポート {0}。"
TELEPORTED_SAFETY: "安全にテレポートしました。"
TELEPORT_PLAYERS: "テレポートコマンドはプレイヤーだけが使用できます。"
TIME_DAYS: "{0} {日|日}"
TIME_HOURS: "{0} {時間|時間}"
TIME_MINUTES: "{0} {分|分}"
TIME_SECONDS: "{0} {秒|秒}"
TIME_WEEKS: "{0} {週|週}"
UPDATE_ERROR: "更新の確認中にエラーが発生しました。"
UPDATE_HEADER: "{0} アップデート"
UPDATE_NOTICE: "知らせ:{0} 現在利用できます。"
UPGRADE_IN_PROGRESS: "アップグレードが進行中です。後でもう一度やり直してください。"
USER_NOT_FOUND: "ユーザー \"{0}\" 見つかりません。"
USING_MYSQL: "使用する MySQL データストレージ用。"
USING_SQLITE: "使用する SQLite データストレージ用。"
VALID_DONATION_KEY: "有効な寄付キー。"
VERSION_NOTICE: "バージョン {0} 現在利用できます。"
VERSION_REQUIRED: "{0} {1} 以上が必要です。"
WORLD_NOT_FOUND: "世界 \"{0}\" 見つかりません。"
+197
View File
@@ -0,0 +1,197 @@
# CoreProtect Language File (pl)
ACTION_NOT_SUPPORTED: "To działanie nie jest obsługiwane."
AMOUNT_BLOCK: "{0} {blok|bloki}"
AMOUNT_CHUNK: "{0} {kawałek|kawałki}"
AMOUNT_ENTITY: "{0} {jednostka|jednostki}"
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_NOT_FOUND: "Komenda \"{0}\" nie znaleziono."
COMMAND_THROTTLED: "Poczekaj chwilę i spróbuj ponownie."
CONTAINER_HEADER: "Transakcje kontenerowe"
DATABASE_BUSY: "Baza danych zajęta. Spróbuj ponownie później."
DATABASE_INDEX_ERROR: "Nie można zweryfikować indeksów bazy danych."
DATABASE_LOCKED_1: "Baza danych zablokowana. Czekam do 15 sekund..."
DATABASE_LOCKED_2: "Baza danych jest już używana. Proszę spróbuj ponownie."
DATABASE_LOCKED_3: "Aby wyłączyć blokowanie bazy danych, ustaw \"database-lock: false\"."
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ąć."
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ć..."
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."
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_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_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_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_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_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ę."
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_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_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_WORLD: "Podaj poprawny świat."
LATEST_VERSION: "Najnowsza wersja: {0}"
LINK_DISCORD: "Discord: {0}"
LINK_DOWNLOAD: "Ściągnij: {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ć..."
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_PAGE: "Strona {0}"
LOOKUP_ROWS_FOUND: "{0} {wiersz|wiersze} znaleziony."
LOOKUP_SEARCHING: "Wyszukiwanie wyszukiwania. Proszę czekać..."
LOOKUP_STORAGE: "{0} {zdeponowane|wycofane} {1} {2}."
LOOKUP_TIME: "{0} temu"
LOOKUP_USERNAME: "{0} zalogowany jako {1}."
LOOKUP_VIEW_PAGE: "Aby wyświetlić stronę, wpisz „{0}”."
MAXIMUM_RADIUS: "Maksymalny {wyszukiwanie|wycofywanie|przywracanie} promień to {0}."
MISSING_ACTION_USER: "Aby skorzystać z tej akcji, określ użytkownika."
MISSING_LOOKUP_TIME: "Proszę określić czas na {wyszukiwanie|przywracanie|przywracanie}."
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."
NO_DATA: "Nie znaleziono danych w {0}."
NO_DATA_LOCATION: "Nie {dane|transakcje|interakcje|wiadomości} znaleziony."
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."
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_SUCCESS: "Pomyślnie uaktualniono do {0}."
PATCH_UPGRADING: "Trwa aktualizacja bazy danych. Proszę czekać..."
PLEASE_SELECT: "Proszę wybrać: \"{0}\" lub \"{1}”."
PREVIEW_CANCELLED: "Podgląd anulowany."
PREVIEW_CANCELLING: "Anulowanie podglądu..."
PREVIEW_CONTAINER: "Nie możesz wyświetlić podglądu transakcji kontenerowych."
PREVIEW_IN_GAME: "Możesz tylko podglądać wycofania w grze."
PURGE_ABORTED: "Czyszczenie nie powiodło się. Baza danych może być uszkodzona."
PURGE_ERROR: "Nie można przetworzyć {0} dane!"
PURGE_FAILED: "Czyszczenie nie powiodło się. Spróbuj ponownie później."
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_OPTIMIZING: "Optymalizacja bazy danych. Proszę czekać..."
PURGE_PROCESSING: "Przetwarzanie {0} dane..."
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."
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_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_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}."
STATUS_LICENSE: "Licencja: {0}"
STATUS_VERSION: "Wersja: {0}"
TELEPORTED: "Teleportowany do {0}."
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}"
UPDATE_ERROR: "Wystąpił błąd podczas sprawdzania aktualizacji."
UPDATE_HEADER: "{0} Aktualizacja"
UPDATE_NOTICE: "Ogłoszenie: {0} jest teraz dostępne."
UPGRADE_IN_PROGRESS: "Trwa aktualizacja. Spróbuj ponownie później."
USER_NOT_FOUND: "Użytkownik \"{0}\" nie znaleziono."
USING_MYSQL: "Za pomocą MySQL do przechowywania danych."
USING_SQLITE: "Za pomocą SQLite do przechowywania danych."
VALID_DONATION_KEY: "Ważny klucz darowizny."
VERSION_NOTICE: "Wersja {0} jest teraz dostępne."
VERSION_REQUIRED: "{0} {1} lub wyższy jest wymagany."
WORLD_NOT_FOUND: "Świat \"{0}\" nie znaleziono."
+28 -28
View File
@@ -9,19 +9,19 @@ API_TEST: "Тест API прошёл успешно!"
CACHE_ERROR: "ВНИМАНИЕ: Ошибка при проверке кеша {0}."
CACHE_RELOAD: "Принудительная перезагрузка кеша {отображения|мира} из базы данных."
CHECK_CONFIG: "Пожалуйста, проверьте config.yml"
COMMAND_NOT_FOUND: "Команда \"{0}\" не найдена."
COMMAND_NOT_FOUND: "Команда «{0}» не найдена."
COMMAND_THROTTLED: "Подождите немного и попробуйте еще раз."
CONTAINER_HEADER: "Контейнерные транзакции"
DATABASE_BUSY: "База данных занята. Пожалуйста, повторите попытку позже."
DATABASE_INDEX_ERROR: "Невозможно проверить индексы базы данных."
DATABASE_LOCKED_1: "База данных заблокирована. Подождите около 15 секунд..."
DATABASE_LOCKED_2: "База данных уже используется. Пожалуйста, попробуйте еще раз."
DATABASE_LOCKED_3: "Чтобы отключить блокировку базы данных, установите \"database-lock: false\"."
DATABASE_LOCKED_3: "Чтобы отключить блокировку базы данных, установите «database-lock: false»."
DATABASE_LOCKED_4: "Отключение блокировки базы данных может привести к повреждению данных."
DATABASE_UNREACHABLE: "База данных недоступна. Удаление данных и завершение работы."
DEVELOPMENT_BRANCH: "Обнаружена ветвь разработки, скрипты исправлений пропущены."
DIRT_BLOCK: "Под тебя установлен блок грязи."
DISABLE_SUCCESS: "Успех! Отключено {0}"
DIRT_BLOCK: "Под вами установлен блок грязи."
DISABLE_SUCCESS: "{0} был успешно отключён!"
ENABLE_FAILED: "{0} не удалось запустить."
ENABLE_SUCCESS: "{0} был успешно запущен!"
ENJOY_COREPROTECT: "Нравится {0}? Присоединяйтесь к нашему Discord!"
@@ -29,7 +29,7 @@ FINISHING_CONVERSION: "Завершение преобразования дан
FINISHING_LOGGING: "Завершение регистрации данных. Пожалуйста, подождите..."
FIRST_VERSION: "Исходная БД: {0}"
GLOBAL_LOOKUP: "Не указывайте радиус для глобального поиска."
GLOBAL_ROLLBACK: "Используйте \"{0}\", чтобы сделать {откат|восстановление} глобально"
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: "Показать дополнительную информацию."
@@ -44,14 +44,14 @@ 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_2: "Используйте после проверки блока для просмотра журналов."
HELP_LOOKUP_COMMAND: "Расширенный поиск данных блока."
HELP_NO_INFO: "Информация о команде \"{0}\" не найдена."
HELP_PARAMETER: "Пожалуйста, просмотрите \"{0}\" для получения подробной информации о параметрах."
HELP_LOOKUP_COMMAND: "Глобальный поиск данных блоков."
HELP_NO_INFO: "Информация о команде «{0}» не найдена."
HELP_PARAMETER: "Пожалуйста, просмотрите «{0}» для получения подробной информации о параметрах."
HELP_PARAMS_1: "Выполните {поиск|откат|восстановление}."
HELP_PARAMS_2: "Укажите пользователей для {поиска|отката|восстановления}."
HELP_PARAMS_3: "Укажите время для {поиска|отката|восстановления}."
@@ -60,7 +60,7 @@ HELP_PARAMS_5: "Ограничьте {поиск|откат|восстановл
HELP_PARAMS_6: "Включите определенные блоки/объекты в {поиск|откат|восстановление}."
HELP_PARAMS_7: "Исключите блоки/пользователей из {поиска|отката|восстановления}."
HELP_PURGE_1: "Удалить данные старше указанного времени."
HELP_PURGE_2: "Например, \"{0}\" удалит все данные старше одного месяца и сохранит данные только за последние 30 дней."
HELP_PURGE_2: "Например, «{0}» удалит все данные старше одного месяца и сохранит данные только за последние 30 дней."
HELP_PURGE_COMMAND: "Удалит старые данные блока."
HELP_RADIUS_1: "Укажите радиус области."
HELP_RADIUS_2: "Например: [r:10] (Внесёт изменения только в пределах 10 блоков от вас)"
@@ -74,7 +74,7 @@ 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}\" нельзя использовать с этим действием."
INCOMPATIBLE_ACTION: "«{0}» нельзя использовать с этим действием."
INSPECTOR_ERROR: "Режим инспектора уже {включён|выключен}."
INSPECTOR_TOGGLED: "Режим инспектора теперь {включён|выключен}."
INTEGRATION_ERROR: "Невозможно {инициализировать|отключить} регистрацию {0}."
@@ -83,15 +83,15 @@ INTEGRATION_VERSION: "Обнаружена недопустимая версия
INTERACTIONS_HEADER: "Взаимодействие с игроками"
INVALID_ACTION: "Это недопустимое действие."
INVALID_BRANCH_1: "Неверная версия плагина (ветка не задана)."
INVALID_BRANCH_2: "Чтобы продолжить, установите ветку проекта на \"development\"."
INVALID_BRANCH_2: "Чтобы продолжить, установите ветку проекта на «development»."
INVALID_BRANCH_3: "Запуск кода который находится в разработке может привести к повреждению данных."
INVALID_CONTAINER: "Пожалуйста, сначала проверьте действующий контейнер."
INVALID_DONATION_KEY: "Недействительный ключ пожертвования."
INVALID_INCLUDE: "\"{0}\" неверное имя блока/сущности."
INVALID_INCLUDE: "«{0}» неверное имя блока/сущности."
INVALID_INCLUDE_COMBO: "Это недопустимая комбинация блока/сущности."
INVALID_RADIUS: "Пожалуйста, введите допустимый радиус."
INVALID_SELECTION: "Выбор {0} не найден."
INVALID_USERNAME: "\"{0}\" неверное имя пользователя."
INVALID_USERNAME: "«{0}» неверное имя пользователя."
INVALID_WORLD: "Укажите действительный мир."
LATEST_VERSION: "Последняя версия: {0}"
LINK_DISCORD: "Discord: {0}"
@@ -101,7 +101,7 @@ LINK_WIKI_BLOCK: "Названия блоков: {0}"
LINK_WIKI_ENTITY: "Названия сущностей: {0}"
LOGGING_ITEMS: "{0} предметы регистрируются. Пожалуйста, подождите..."
LOGGING_TIME_LIMIT: "Достигнуто ограничение по времени регистрации. Удаление данных и завершение работы."
LOOKUP_BLOCK: "{0} {установил|сломал} {1}."
LOOKUP_BLOCK: "{0} {поставил|сломал} {1}."
LOOKUP_CONTAINER: "{0} {добавил|забрал} {1} {2}."
LOOKUP_HEADER: "{0} Результаты поиска"
LOOKUP_INTERACTION: "{0} {нажал|убил} {1}."
@@ -113,12 +113,12 @@ LOOKUP_SEARCHING: "Ведётся поиск. Пожалуйста подожд
LOOKUP_STORAGE: "{0} {положил|забрал} {1} {2}."
LOOKUP_TIME: "{0} назад"
LOOKUP_USERNAME: "{0} зарегистрирован как {1}."
LOOKUP_VIEW_PAGE: "Чтобы просмотреть страницу, введите \"{0}\"."
LOOKUP_VIEW_PAGE: "Чтобы просмотреть страницу, введите «{0}»."
MAXIMUM_RADIUS: "Максимальный радиус для {поиска|отката|восстановления} - {0}."
MISSING_ACTION_USER: "Чтобы использовать это действие, укажите пользователя."
MISSING_LOOKUP_TIME: "Пожалуйста, укажите количество времени, чтобы использовать {поиск|откат|восстановление}."
MISSING_LOOKUP_USER: "Укажите пользователя или {блок|радиус} для поиска."
MISSING_PARAMETERS: "Пожалуйста используйте \"{0}\"."
MISSING_PARAMETERS: "Пожалуйста используйте «{0}»."
MISSING_ROLLBACK_RADIUS: "Вы не указали радиус {отката|восстановления}."
MISSING_ROLLBACK_USER: "Вы не указали пользователя для {отката|восстановления}."
MYSQL_UNAVAILABLE: "Невозможно подключиться к серверу MySQL."
@@ -136,7 +136,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_CONTAINER: "Вы не можете предварительно просмотреть контейнерные транзакции."
@@ -150,26 +150,26 @@ PURGE_NOTICE_1: "Учтите, что это может занять некот
PURGE_NOTICE_2: "Не перезагружайте сервер до завершения."
PURGE_OPTIMIZING: "Оптимизация базы данных. Пожалуйста, подождите..."
PURGE_PROCESSING: "Обработка данных {0}..."
PURGE_REPAIRING: "Попытка починки. Это может занять некоторое время..."
PURGE_REPAIRING: "Попытка исправления. Это может занять некоторое время..."
PURGE_ROWS: "{0} {строка|строки} данных очищены."
PURGE_STARTED: "Очистка данных началась \"{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_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_SELECTION: "Радиус установлен «{0}»."
ROLLBACK_STARTED: "{Откат|Восстановление|Предварительный просмотр} начат «{0}»."
ROLLBACK_TIME: "Временной интервал: {0}."
ROLLBACK_WORLD_ACTION: "Только {мир|действие} \"{0}\"."
ROLLBACK_WORLD_ACTION: "Только {мир|действие} «{0}»."
SIGN_HEADER: "Сообщения на табличке"
STATUS_CONSUMER: "Потребитель: {0} {предмет|предметы} в очереди."
STATUS_DATABASE: "База данных: Использует {0}."
@@ -188,10 +188,10 @@ UPDATE_ERROR: "Произошла ошибка при проверке обно
UPDATE_HEADER: "{0} Обновление"
UPDATE_NOTICE: "Примечание: теперь доступен {0}."
UPGRADE_IN_PROGRESS: "Выполняется обновление. Пожалуйста, повторите попытку позже."
USER_NOT_FOUND: "Пользователь \"{0}\" не найден."
USER_NOT_FOUND: "Пользователь «{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}» не найден."
+197
View File
@@ -0,0 +1,197 @@
# CoreProtect Language File (uk)
ACTION_NOT_SUPPORTED: "Ця дія не підтримується."
AMOUNT_BLOCK: "{0} {блок|блоки}"
AMOUNT_CHUNK: "{0} {шматок|шматки}"
AMOUNT_ENTITY: "{0} {сутність|сутності}"
AMOUNT_ITEM: "{0} {пункт|предмети}"
API_TEST: "Тест API успішний."
CACHE_ERROR: "УВАГА: Помилка під час перевірки {0} кеш."
CACHE_RELOAD: "Примусове перезавантаження {картографування|світу} кеші з бази даних."
CHECK_CONFIG: "Перевірте config.yml"
COMMAND_NOT_FOUND: "Команда \"{0}\" не знайдено."
COMMAND_THROTTLED: "Зачекайте хвилину і повторіть спробу."
CONTAINER_HEADER: "Контейнерні операції"
DATABASE_BUSY: "База даних зайнята. Будь-ласка спробуйте пізніше."
DATABASE_INDEX_ERROR: "Неможливо перевірити індекси бази даних."
DATABASE_LOCKED_1: "База даних заблокована. Очікування до 15 секунд..."
DATABASE_LOCKED_2: "База даних вже використовується. Будь ласка спробуйте ще раз."
DATABASE_LOCKED_3: "Щоб вимкнути блокування бази даних, встановіть \"database-lock: false\"."
DATABASE_LOCKED_4: "Вимкнення блокування бази даних може призвести до пошкодження даних."
DATABASE_UNREACHABLE: "База даних недоступна. Видалення даних та завершення роботи."
DEVELOPMENT_BRANCH: "Виявлено гілку розробки, пропущено сценарії виправлення."
DIRT_BLOCK: "Поклали під себе брудний блок."
DISABLE_SUCCESS: "Успіху! Інвалід {0}"
ENABLE_FAILED: "{0} не вдалося почати."
ENABLE_SUCCESS: "{0} тепер увімкнено!"
ENJOY_COREPROTECT: "Насолоджуйтесь {0}? Приєднуйтесь до наших Discord!"
FINISHING_CONVERSION: "Завершення перетворення даних. Будь ласка, зачекайте..."
FINISHING_LOGGING: "Завершення реєстрації даних. Будь ласка, зачекайте..."
FIRST_VERSION: "Початкова БД: {0}"
GLOBAL_LOOKUP: "Не вказуйте радіус для глобального пошуку."
GLOBAL_ROLLBACK: "Використовувати \"{0}\" зробити глобальний {відкат|відновлення}"
HELP_ACTION_1: "Обмежити пошук до дії."
HELP_ACTION_2: "Приклади: [a:block], [a:+block], [a:-block] [a:click], [a:container], [a:inventory], [a:item], [a:kill], [a:chat], [a:command], [a:sign], [a:session], [a:username]"
HELP_COMMAND: "Відображення додаткової інформації."
HELP_EXCLUDE_1: "Виключити блоки/користувачів."
HELP_EXCLUDE_2: "Приклади: [e:stone], [e:Notch], [e:stone,Notch]"
HELP_HEADER: "{0} Довідка"
HELP_INCLUDE_1: "Включити блоки/сутності."
HELP_INCLUDE_2: "Приклади: [i:stone], [i:zombie], [i:stone,wood,bedrock]"
HELP_INSPECT_1: "Якщо інспектор увімкнено, ви можете:"
HELP_INSPECT_2: "Клацніть лівою кнопкою миші, щоб побачити місце розташування."
HELP_INSPECT_3: "Клацніть правою кнопкою миші, щоб побачити суміжні видалення."
HELP_INSPECT_4: "Поставте блок, щоб побачити видалення."
HELP_INSPECT_5: "Помістіть блок у рідину, щоб побачити розташування."
HELP_INSPECT_6: "Клацніть правою кнопкою миші, щоб побачити операції з суднами."
HELP_INSPECT_7: "Порада: Ви можете використовувати лише \"/co i\"."
HELP_INSPECT_COMMAND: "Перемикає інспектор блоків."
HELP_LIST: "Відображає список усіх команд."
HELP_LOOKUP_1: "Ярлик команди."
HELP_LOOKUP_2: "Переглянути додаткові сторінки."
HELP_LOOKUP_COMMAND: "Перегляд даних блоку."
HELP_NO_INFO: "Інформація для команди \"{0}\" не знайдено."
HELP_PARAMETER: "Будь ласка, подивіться \"{0}\" для отримання детальної інформації про параметри."
HELP_PARAMS_1: "Виконайте {пошук|відкат|відновлення}."
HELP_PARAMS_2: "Вкажіть користувачів для {пошук|відкат|відновлення}."
HELP_PARAMS_3: "Вкажіть час до {пошук|відкат|відновлення}."
HELP_PARAMS_4: "Обмежте {пошук|відкат|відновлення} до радіусу."
HELP_PARAMS_5: "Обмежте {пошук|відкат|відновлення} до дії."
HELP_PARAMS_6: "Включити блоки/сутності до {пошук|відкат|відновлення}."
HELP_PARAMS_7: "Виключити блокування/користувачів із {пошук|відкат|відновлення}."
HELP_PURGE_1: "Видаліть старі дані."
HELP_PURGE_2: "Наприклад, \"{0}\" видалить усі дані старше одного місяця та збереже дані лише за останні 30 днів."
HELP_PURGE_COMMAND: "Видалити дані старого блоку."
HELP_RADIUS_1: "Вкажіть зону радіуса."
HELP_RADIUS_2: "Приклади: [r:10] (Вносити зміни лише в межах 10 блоків від вас)"
HELP_RELOAD_COMMAND: "Перезавантажує файл конфігурації."
HELP_RESTORE_COMMAND: "Відновлення даних блоку."
HELP_ROLLBACK_COMMAND: "Дані блоку відкату."
HELP_STATUS: "Переглянути стан плагіна."
HELP_STATUS_COMMAND: "Відображає стан плагіна."
HELP_TELEPORT: "Телепорт."
HELP_TIME_1: "Вкажіть час."
HELP_TIME_2: "Приклади: [t:2w,5d,7h,2m,10s], [t:5d2h], [t:2.50h]"
HELP_USER_1: "Вкажіть користувачів."
HELP_USER_2: "Приклади: [u:Notch], [u:Notch,#enderman]"
INCOMPATIBLE_ACTION: "\"{0}\" не можна використовувати з цією дією."
INSPECTOR_ERROR: "Вже інспектор {включено|вимкнено}."
INSPECTOR_TOGGLED: "Зараз інспектор {включено|вимкнено}."
INTEGRATION_ERROR: "Вдалося {ініціалізувати|вимкнути} {0} лісозаготівлі."
INTEGRATION_SUCCESS: "{0} реєстрація успішно {ініціалізовано|відключено}."
INTEGRATION_VERSION: "Недійсний {0} версія знайдена."
INTERACTIONS_HEADER: "Взаємодії гравців"
INVALID_ACTION: "Це не дійсна дія."
INVALID_BRANCH_1: "Недійсна версія плагіна (гілка не встановлена)."
INVALID_BRANCH_2: "Щоб продовжити, встановіть гілку проекту на \"розвиток\"."
INVALID_BRANCH_3: "Запуск коду розробки може призвести до пошкодження даних."
INVALID_CONTAINER: "Спочатку перевірте дійсний контейнер."
INVALID_DONATION_KEY: "Недійсний ключ пожертви."
INVALID_INCLUDE: "\"{0}\" є недійсним значенням."
INVALID_INCLUDE_COMBO: "Це недійсна комбінація типів."
INVALID_RADIUS: "Введіть дійсний радіус."
INVALID_SELECTION: "{0} виділення не знайдено."
INVALID_USERNAME: "\"{0}\" є недійсним ім'ям користувача."
INVALID_WORLD: "Укажіть дійсний світ."
LATEST_VERSION: "Остання версія: {0}"
LINK_DISCORD: "Discord: {0}"
LINK_DOWNLOAD: "Завантажити: {0}"
LINK_PATREON: "Patreon: {0}"
LINK_WIKI_BLOCK: "Імена блоків: {0}"
LINK_WIKI_ENTITY: "Назви сутностей: {0}"
LOGGING_ITEMS: "{0} елементи, залишені для реєстрації. Будь ласка, зачекайте..."
LOGGING_TIME_LIMIT: "Досягнуто обмеження часу реєстрації. Видалення даних та завершення роботи."
LOOKUP_BLOCK: "{0} {розміщено|зламано} {1}."
LOOKUP_CONTAINER: "{0} {додано|видалено} {1} {2}."
LOOKUP_HEADER: "{0} Результати"
LOOKUP_INTERACTION: "{0} {натиснув|убитий} {1}."
LOOKUP_ITEM: "{0} {взяв|скинув} {1} {2}."
LOOKUP_LOGIN: "{0} зареєстрований {в|з ~ ~}."
LOOKUP_PAGE: "Сторінка {0}"
LOOKUP_ROWS_FOUND: "{0} {рядок|рядки} знайдено."
LOOKUP_SEARCHING: "Пошук під час пошуку. Будь ласка, зачекайте..."
LOOKUP_STORAGE: "{0} {здано на зберігання|вилучено} {1} {2}."
LOOKUP_TIME: "{0} тому"
LOOKUP_USERNAME: "{0} Ви увійшли як {1}."
LOOKUP_VIEW_PAGE: "Щоб переглянути сторінку, введіть \"{0}\"."
MAXIMUM_RADIUS: "Максимум {пошук|відкат|відновлення} радіус дорівнює {0}."
MISSING_ACTION_USER: "Щоб використати цю дію, вкажіть користувача."
MISSING_LOOKUP_TIME: "Будь ласка, вкажіть час до {пошук|відкат|відновлення}."
MISSING_LOOKUP_USER: "Будь ласка, вкажіть користувача або {блок|радіус}."
MISSING_PARAMETERS: "Будь ласка, використовуйте \"{0}\"."
MISSING_ROLLBACK_RADIUS: "Ви не вказали a {відкат|відновлення} радіус."
MISSING_ROLLBACK_USER: "Ви не вказали a {відкат|відновлення} користувача."
MYSQL_UNAVAILABLE: "Не вдається підключитися до MySQL сервер."
NO_DATA: "Дані не знайдені за адресою {0}."
NO_DATA_LOCATION: "Ні {дані|транзакції|взаємодії|повідомлення} знайдено."
NO_PERMISSION: "У вас немає дозволу на це."
NO_RESULTS: "Нічого не знайдено."
NO_RESULTS_PAGE: "Ні {результати|дані} знайдено для цієї сторінки."
NO_ROLLBACK: "Ні {в очікуванні|попередній} відкат/відновлення знайдено."
PATCH_INTERRUPTED: "Оновлення перервано. Спробую ще раз при перезавантаженні."
PATCH_OUTDATED_1: "Не вдається оновити бази даних старші {0}."
PATCH_OUTDATED_2: "Оновіть підтримувану версію CoreProtect."
PATCH_PROCESSING: "Обробка нових даних. Будь ласка, зачекайте..."
PATCH_SKIP_UPDATE: "Пропуск {таблиця|індекс} {оновлення|створення|видалення} на {0}."
PATCH_STARTED: "Виконання {0} оновлення. Будь ласка, зачекайте..."
PATCH_SUCCESS: "Успішно оновлено до {0}."
PATCH_UPGRADING: "Триває оновлення бази даних. Будь ласка, зачекайте..."
PLEASE_SELECT: "Виберіть будь ласка: \"{0}\" або \"{1}\"."
PREVIEW_CANCELLED: "Попередній перегляд скасовано."
PREVIEW_CANCELLING: "Скасування попереднього перегляду..."
PREVIEW_CONTAINER: "Ви не можете переглядати транзакційні контейнери."
PREVIEW_IN_GAME: "Попередній перегляд можна лише в грі."
PURGE_ABORTED: "Помилка очищення. Можливо, база даних пошкоджена."
PURGE_ERROR: "Не вдається обробити {0} дані!"
PURGE_FAILED: "Помилка очищення. Будь-ласка спробуйте пізніше."
PURGE_IN_PROGRESS: "Триває чистка. Будь-ласка спробуйте пізніше."
PURGE_MINIMUM_TIME: "Очистити дані можна лише старше {0} {днів|годин}."
PURGE_NOTICE_1: "Зверніть увагу, що це може зайняти деякий час."
PURGE_NOTICE_2: "Не перезавантажуйте сервер до завершення."
PURGE_OPTIMIZING: "Оптимізація бази даних. Будь ласка, зачекайте..."
PURGE_PROCESSING: "Обробка {0} дані..."
PURGE_REPAIRING: "Спроба ремонту. Це може зайняти деякий час..."
PURGE_ROWS: "{0} {рядок|рядки} даних видалено."
PURGE_STARTED: "Очищення даних розпочато \"{0}\"."
PURGE_SUCCESS: "Очищення даних успішно."
RELOAD_STARTED: "Перезавантаження конфігурації - зачекайте."
RELOAD_SUCCESS: "Конфігурацію успішно перезавантажено."
ROLLBACK_ABORTED: "Відкат або відновлення припинено."
ROLLBACK_CHUNKS_FOUND: "Знайдено {0} {шматок|шматки} змінити."
ROLLBACK_CHUNKS_MODIFIED: "Змінено {0}/{1} {шматок|шматки}."
ROLLBACK_COMPLETED: "{Відкат|Відновлення|Попередній перегляд} завершено за \"{0}\"."
ROLLBACK_EXCLUDED_USERS: "Виключено {користувач|користувачі}: \"{0}\"."
ROLLBACK_INCLUDE: "{Включено|Виключено} {блок|сутність|ціль} {тип|типи}: \"{0}\"."
ROLLBACK_IN_PROGRESS: "Відкат/відновлення вже триває."
ROLLBACK_LENGTH: "Витрачений час: {0} {секунда|секунди}."
ROLLBACK_MODIFIED: "{Змінено|Змінюється} {0}."
ROLLBACK_RADIUS: "Радіус: {0} {блок|блоки}."
ROLLBACK_SELECTION: "Радіус встановлено на \"{0}\"."
ROLLBACK_STARTED: "{Відкат|Відновлення|Попередній перегляд} почав \"{0}\"."
ROLLBACK_TIME: "Часовий діапазон: {0}."
ROLLBACK_WORLD_ACTION: "Обмежено до {світ|дія} \"{0}\"."
SIGN_HEADER: "Підписуйте повідомлення"
STATUS_CONSUMER: "Споживач: {0} {пункт|предмети} в черзі."
STATUS_DATABASE: "База даних: Використання {0}."
STATUS_INTEGRATION: "{0}: Інтеграція {включено|вимкнено}."
STATUS_LICENSE: "Ліцензія: {0}"
STATUS_VERSION: "Версія: {0}"
TELEPORTED: "Телепортувався до {0}."
TELEPORTED_SAFETY: "Телепортував вас у безпечне місце."
TELEPORT_PLAYERS: "Команду телепорту можуть використовувати лише гравці."
TIME_DAYS: "{0} {день|дні}"
TIME_HOURS: "{0} {година|години}"
TIME_MINUTES: "{0} {хвилина|хвилини}"
TIME_SECONDS: "{0} {секунда|секунди}"
TIME_WEEKS: "{0} {тиждень|тиждень}"
UPDATE_ERROR: "Під час перевірки оновлень сталася помилка."
UPDATE_HEADER: "{0} Оновлення"
UPDATE_NOTICE: "Примітка: {0} тепер доступний."
UPGRADE_IN_PROGRESS: "Оновлення триває. Будь-ласка спробуйте пізніше."
USER_NOT_FOUND: "Користувач \"{0}\" не знайдено."
USING_MYSQL: "Використання MySQL для зберігання даних."
USING_SQLITE: "Використання SQLite для зберігання даних."
VALID_DONATION_KEY: "Дійсний ключ пожертви."
VERSION_NOTICE: "Версія {0} тепер доступний."
VERSION_REQUIRED: "{0} {1} або вище."
WORLD_NOT_FOUND: "Світ \"{0}\" не знайдено."
+197
View File
@@ -0,0 +1,197 @@
# CoreProtect Language File (vi)
ACTION_NOT_SUPPORTED: "Hành động đó không được hỗ trợ."
AMOUNT_BLOCK: "{0} {khối|khối}"
AMOUNT_CHUNK: "{0} {chunk|chunks}"
AMOUNT_ENTITY: "{0} {thực thể|thực thể}"
AMOUNT_ITEM: "{0} {item|item}"
API_TEST: "Kiểm tra API thành công."
CACHE_ERROR: "CẢNH BÁO: Lỗi khi xác thực {0} bộ nhớ đệm."
CACHE_RELOAD: "Buộc tải lại {lập bản đồ|thế giới} bộ nhớ đệm từ cơ sở dữ liệu."
CHECK_CONFIG: "Vui lòng kiểm tra config.yml"
COMMAND_NOT_FOUND: "Yêu cầu \"{0}\" không tìm thấy."
COMMAND_THROTTLED: "Vui lòng đợi trong giây lát và thử lại."
CONTAINER_HEADER: "Giao dịch vùng chứa"
DATABASE_BUSY: "Cơ sở dữ liệu bận rộn. Vui lòng thử lại sau."
DATABASE_INDEX_ERROR: "Không thể xác thực các chỉ mục cơ sở dữ liệu."
DATABASE_LOCKED_1: "Cơ sở dữ liệu bị khóa. Chờ tối đa 15 giây..."
DATABASE_LOCKED_2: "Cơ sở dữ liệu đã được sử dụng. Vui lòng thử lại."
DATABASE_LOCKED_3: "Để tắt khóa cơ sở dữ liệu, hãy đặt \"khóa cơ sở dữ liệu: false\"."
DATABASE_LOCKED_4: "Vô hiệu hóa khóa cơ sở dữ liệu có thể dẫn đến hỏng dữ liệu."
DATABASE_UNREACHABLE: "Cơ sở dữ liệu không thể truy cập được. Đang hủy bỏ dữ liệu và tắt."
DEVELOPMENT_BRANCH: "Đã phát hiện nhánh phát triển, bỏ qua các tập lệnh vá lỗi."
DIRT_BLOCK: "Đặt một khối bẩn dưới bạn."
DISABLE_SUCCESS: "Sự thành công! Tàn tật {0}"
ENABLE_FAILED: "{0} đã không thể bắt đầu."
ENABLE_SUCCESS: "{0} hiện đã được kích hoạt!"
ENJOY_COREPROTECT: "Vui thích {0}? Gia nhập với chúng tôi Discord!"
FINISHING_CONVERSION: "Kết thúc chuyển đổi dữ liệu. Vui lòng chờ..."
FINISHING_LOGGING: "Hoàn thành việc ghi dữ liệu. Vui lòng chờ..."
FIRST_VERSION: "DB ban đầu: {0}"
GLOBAL_LOOKUP: "Không chỉ định bán kính để thực hiện tra cứu toàn cục."
GLOBAL_ROLLBACK: "Sử dụng \"{0}\" để làm một toàn cầu {quay lại|khôi phục}"
HELP_ACTION_1: "Hạn chế tra cứu đối với một hành động."
HELP_ACTION_2: "Ví dụ: [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: "Hiển thị thông tin bổ sung."
HELP_EXCLUDE_1: "Loại trừ khối / người dùng."
HELP_EXCLUDE_2: "Ví dụ: [e:stone], [e:Notch], [e:stone,Notch]"
HELP_HEADER: "{0} Trợ giúp"
HELP_INCLUDE_1: "Bao gồm các khối / thực thể."
HELP_INCLUDE_2: "Ví dụ: [i:stone], [i:zombie], [i:stone,wood,bedrock]"
HELP_INSPECT_1: "Với trình kiểm tra được bật, bạn có thể:"
HELP_INSPECT_2: "Nhấp chuột trái để xem vị trí."
HELP_INSPECT_3: "Nhấp chuột phải để xem các lần xóa liền kề."
HELP_INSPECT_4: "Đặt một khối để xem việc loại bỏ."
HELP_INSPECT_5: "Đặt một khối vào chất lỏng để xem vị trí."
HELP_INSPECT_6: "Nhấp chuột phải để xem các giao dịch rương."
HELP_INSPECT_7: "Mẹo: Bạn chỉ có thể sử dụng \"/co i\"."
HELP_INSPECT_COMMAND: "Chuyển đổi trình kiểm tra khối."
HELP_LIST: "Hiển thị danh sách tất cả các lệnh."
HELP_LOOKUP_1: "Phím tắt lệnh."
HELP_LOOKUP_2: "Xem các trang bổ sung."
HELP_LOOKUP_COMMAND: "Dữ liệu khối tra cứu."
HELP_NO_INFO: "Thông tin cho lệnh \"{0}\" không tìm thấy."
HELP_PARAMETER: "Hãy xem \"{0}\" để biết thông tin chi tiết về thông số."
HELP_PARAMS_1: "Thực hiện {tra cứu|khôi phục|khôi phục}."
HELP_PARAMS_2: "Chỉ định người dùng {tra cứu|khôi phục|khôi phục}."
HELP_PARAMS_3: "Chỉ định thời gian để {tra cứu|khôi phục|khôi phục}."
HELP_PARAMS_4: "Hạn chế {tra cứu|khôi phục|khôi phục} đến một bán kính."
HELP_PARAMS_5: "Hạn chế {tra cứu|khôi phục|khôi phục} cho một hành động."
HELP_PARAMS_6: "Bao gồm các khối / thực thể trong {tra cứu|khôi phục|khôi phục}."
HELP_PARAMS_7: "Loại trừ các khối / người dùng khỏi {tra cứu|khôi phục|khôi phục}."
HELP_PURGE_1: "Xóa dữ liệu cũ."
HELP_PURGE_2: "Ví dụ, \"{0}\" sẽ xóa tất cả dữ liệu cũ hơn một tháng và chỉ giữ lại dữ liệu trong 30 ngày qua."
HELP_PURGE_COMMAND: "Xóa dữ liệu khối cũ."
HELP_RADIUS_1: "Chỉ định một khu vực bán kính."
HELP_RADIUS_2: "Ví dụ: [r:10] (Chỉ thực hiện các thay đổi trong vòng 10 khối nhà bạn)"
HELP_RELOAD_COMMAND: "Tải lại tệp cấu hình."
HELP_RESTORE_COMMAND: "Khôi phục dữ liệu khối."
HELP_ROLLBACK_COMMAND: "Dữ liệu khối khôi phục."
HELP_STATUS: "Xem trạng thái plugin."
HELP_STATUS_COMMAND: "Hiển thị trạng thái plugin."
HELP_TELEPORT: "Dịch chuyển."
HELP_TIME_1: "Chỉ định thời gian."
HELP_TIME_2: "Ví dụ: [t:2w,5d,7h,2m,10s], [t:5d2h], [t:2.50h]"
HELP_USER_1: "Chỉ định người dùng."
HELP_USER_2: "Ví dụ: [u:Notch], [u:Notch,#enderman]"
INCOMPATIBLE_ACTION: "\"{0}\" không thể được sử dụng với hành động đó."
INSPECTOR_ERROR: "Thanh tra đã {đã bật|đã tắt}."
INSPECTOR_TOGGLED: "Thanh tra ngay {đã bật|đã tắt}."
INTEGRATION_ERROR: "Không có khả năng {khởi tạo|vô hiệu hóa} {0} khai thác gỗ."
INTEGRATION_SUCCESS: "{0} ghi nhật ký thành công {khởi tạo|bị vô hiệu hóa}."
INTEGRATION_VERSION: "Không hợp lệ {0} phiên bản được tìm thấy."
INTERACTIONS_HEADER: "Tương tác của người chơi"
INVALID_ACTION: "Đó không phải là một hành động hợp lệ."
INVALID_BRANCH_1: "Phiên bản plugin không hợp lệ (chưa đặt nhánh)."
INVALID_BRANCH_2: "Để tiếp tục, hãy đặt nhánh dự án thành \"phát triển\"."
INVALID_BRANCH_3: "Chạy mã phát triển có thể dẫn đến hỏng dữ liệu."
INVALID_CONTAINER: "Vui lòng kiểm tra một thùng chứa hợp lệ trước."
INVALID_DONATION_KEY: "Khóa quyên góp không hợp lệ."
INVALID_INCLUDE: "\"{0}\" là một giá trị không hợp lệ."
INVALID_INCLUDE_COMBO: "Đó là sự kết hợp kiểu không hợp lệ."
INVALID_RADIUS: "Vui lòng nhập bán kính hợp lệ."
INVALID_SELECTION: "{0} lựa chọn không được tìm thấy."
INVALID_USERNAME: "\"{0}\" là tên người dùng không hợp lệ."
INVALID_WORLD: "Vui lòng chỉ định một thế giới hợp lệ."
LATEST_VERSION: "Phiên bản mới nhất: {0}"
LINK_DISCORD: "Discord: {0}"
LINK_DOWNLOAD: "Tải xuống: {0}"
LINK_PATREON: "Patreon: {0}"
LINK_WIKI_BLOCK: "Tên khối: {0}"
LINK_WIKI_ENTITY: "Tên thực thể: {0}"
LOGGING_ITEMS: "{0} mục còn lại để ghi. Vui lòng chờ..."
LOGGING_TIME_LIMIT: "Đã đạt đến giới hạn thời gian ghi nhật ký. Đang hủy bỏ dữ liệu và tắt."
LOOKUP_BLOCK: "{0} {đặt|đã phá vỡ} {1}."
LOOKUP_CONTAINER: "{0} {đã thêm|đã loại bỏ} {1} {2}."
LOOKUP_HEADER: "{0} Kết quả"
LOOKUP_INTERACTION: "{0} {đã nhấp vào|giết} {1}."
LOOKUP_ITEM: "{0} {nhặt lên|đánh rơi} {1} {2}."
LOOKUP_LOGIN: "{0} ghi nhật ký {vào|ra}."
LOOKUP_PAGE: "Trang {0}"
LOOKUP_ROWS_FOUND: "{0} {hàng|hàng} tìm."
LOOKUP_SEARCHING: "Tra cứu tìm kiếm. Vui lòng chờ..."
LOOKUP_STORAGE: "{0} {ký gửi|rút tiền} {1} {2}."
LOOKUP_TIME: "{0} trước kia"
LOOKUP_USERNAME: "{0} đăng nhập với tư cách {1}."
LOOKUP_VIEW_PAGE: "Để xem một trang, hãy nhập \"{0}\"."
MAXIMUM_RADIUS: "Giá trị lớn nhất {tra cứu|khôi phục|khôi phục} bán kính là {0}."
MISSING_ACTION_USER: "Để sử dụng hành động đó, vui lòng chỉ định người dùng."
MISSING_LOOKUP_TIME: "Vui lòng xác định thời gian để {tra cứu|khôi phục|khôi phục}."
MISSING_LOOKUP_USER: "Vui lòng chỉ định người dùng hoặc {khối|bán kính}."
MISSING_PARAMETERS: "Vui lòng sử dụng \"{0}\"."
MISSING_ROLLBACK_RADIUS: "Bạn đã không chỉ định một {khôi phục lại|khôi phục} bán kính."
MISSING_ROLLBACK_USER: "Bạn đã không chỉ định một {khôi phục lại|khôi phục} người sử dụng."
MYSQL_UNAVAILABLE: "Không thể kết nối MySQL người phục vụ."
NO_DATA: "Không tìm thấy dữ liệu tại {0}."
NO_DATA_LOCATION: "Không {dữ liệu|giao dịch|tương tác|tin nhắn} tìm."
NO_PERMISSION: "Bạn không có quyền để làm điều đó."
NO_RESULTS: "Không tìm thấy kết quả nào."
NO_RESULTS_PAGE: "Không {kết quả|dữ liệu} được tìm thấy cho trang đó."
NO_ROLLBACK: "Không {đang chờ xử lý|trước đó} khôi phục / khôi phục được tìm thấy."
PATCH_INTERRUPTED: "Nâng cấp bị gián đoạn. Sẽ thử lại khi khởi động lại."
PATCH_OUTDATED_1: "Không thể nâng cấp cơ sở dữ liệu cũ hơn {0}."
PATCH_OUTDATED_2: "Vui lòng nâng cấp bằng phiên bản được hỗ trợ của CoreProtect."
PATCH_PROCESSING: "Xử lý dữ liệu mới. Vui lòng chờ..."
PATCH_SKIP_UPDATE: "Bỏ qua {bảng|chỉ mục} {cập nhật|tạo|loại bỏ} trên {0}."
PATCH_STARTED: "Biểu diễn {0} nâng cấp. Vui lòng chờ..."
PATCH_SUCCESS: "Đã nâng cấp thành công lên {0}."
PATCH_UPGRADING: "Đang nâng cấp cơ sở dữ liệu. Vui lòng chờ..."
PLEASE_SELECT: "Xin hãy lựa chọn: \"{0}\" hoặc \"{1}\"."
PREVIEW_CANCELLED: "Đã hủy bản xem trước."
PREVIEW_CANCELLING: "Đang hủy bản xem trước..."
PREVIEW_CONTAINER: "Bạn không thể xem trước các giao dịch vùng chứa."
PREVIEW_IN_GAME: "Bạn chỉ có thể xem trước các lần quay lại trong trò chơi."
PURGE_ABORTED: "Thanh trừng không thành công. Cơ sở dữ liệu có thể bị hỏng."
PURGE_ERROR: "Không thể xử lý {0} dữ liệu!"
PURGE_FAILED: "Thanh trừng không thành công. Vui lòng thử lại sau."
PURGE_IN_PROGRESS: "Đang tiến hành thanh lọc. Vui lòng thử lại sau."
PURGE_MINIMUM_TIME: "Bạn chỉ có thể xóa dữ liệu cũ hơn {0} {ngày|giờ}."
PURGE_NOTICE_1: "Xin lưu ý rằng điều này có thể mất một thời gian."
PURGE_NOTICE_2: "Không khởi động lại máy chủ của bạn cho đến khi hoàn thành."
PURGE_OPTIMIZING: "Tối ưu hóa cơ sở dữ liệu. Vui lòng chờ..."
PURGE_PROCESSING: "Xử lý {0} dữ liệu..."
PURGE_REPAIRING: "Đang cố gắng sửa chữa. Điều này có thể mất một thời gian..."
PURGE_ROWS: "{0} {hàng|hàng} dữ liệu bị xóa."
PURGE_STARTED: "Quá trình thanh lọc dữ liệu bắt đầu vào \"{0}\"."
PURGE_SUCCESS: "Xóa dữ liệu thành công."
RELOAD_STARTED: "Đang tải lại cấu hình - vui lòng đợi."
RELOAD_SUCCESS: "Đã tải lại cấu hình thành công."
ROLLBACK_ABORTED: "Đã hủy bỏ khôi phục hoặc khôi phục."
ROLLBACK_CHUNKS_FOUND: "Tìm {0} {khối|khối} để sửa đổi."
ROLLBACK_CHUNKS_MODIFIED: "Đã sửa đổi {0}/{1} {chunk|chunks}."
ROLLBACK_COMPLETED: "{Quay lại|Khôi phục|Xem trước} hoàn thành cho \"{0}\"."
ROLLBACK_EXCLUDED_USERS: "Bị loại trừ {người dùng|người dùng}: \"{0}\"."
ROLLBACK_INCLUDE: "{Đã bao gồm|Đã loại trừ} {khối|thực thể|mục tiêu} {loại|loại}: \"{0}\"."
ROLLBACK_IN_PROGRESS: "Quá trình khôi phục / khôi phục đang được tiến hành."
ROLLBACK_LENGTH: "Mất thời gian: {0} {giây|giây}."
ROLLBACK_MODIFIED: "{Đã sửa đổi|Đang sửa đổi} {0}."
ROLLBACK_RADIUS: "Bán kính: {0} {khối|khối}."
ROLLBACK_SELECTION: "Bán kính được đặt thành \"{0}\"."
ROLLBACK_STARTED: "{Quay lại|Khôi phục|Xem trước} Bắt đầu vào \"{0}\"."
ROLLBACK_TIME: "Phạm vi thời gian: {0}."
ROLLBACK_WORLD_ACTION: "Bị hạn chế đối với {thế giới|hành động} \"{0}\"."
SIGN_HEADER: "Ký tin nhắn"
STATUS_CONSUMER: "Khách hàng: {0} {mặt hàng|mặt hàng} đợi."
STATUS_DATABASE: "Cơ sở dữ liệu: Sử dụng {0}."
STATUS_INTEGRATION: "{0}: Hội nhập {đã bật|đã tắt}."
STATUS_LICENSE: "Giấy phép: {0}"
STATUS_VERSION: "Phiên bản: {0}"
TELEPORTED: "Dịch chuyển đến {0}."
TELEPORTED_SAFETY: "Dịch chuyển bạn đến nơi an toàn."
TELEPORT_PLAYERS: "Lệnh dịch chuyển chỉ có thể được sử dụng bởi người chơi."
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_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"
UPDATE_NOTICE: "Lưu ý: {0} hiện đã có sẵn."
UPGRADE_IN_PROGRESS: "Đang nâng cấp. Vui lòng thử lại sau."
USER_NOT_FOUND: "Người sử dụng \"{0}\" không tìm thấy."
USING_MYSQL: "Sử dụng MySQL để lưu trữ dữ liệu."
USING_SQLITE: "Sử dụng SQLite để lưu trữ dữ liệu."
VALID_DONATION_KEY: "Chìa khóa quyên góp hợp lệ."
VERSION_NOTICE: "Phiên bản {0} hiện đã có sẵn."
VERSION_REQUIRED: "{0} {1} hoặc cao hơn là bắt buộc."
WORLD_NOT_FOUND: "Thế giới \"{0}\" không tìm thấy."
+89 -89
View File
@@ -1,36 +1,36 @@
# CoreProtect Language File (zh-CN)
# Origin: Intelli, Translator: DreamVoid
# Origin: Intelli, Translator: DreamVoid, StarWishsama, YuanYuanOwO
ACTION_NOT_SUPPORTED: "不支持该操作。"
AMOUNT_BLOCK: "{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_NOT_FOUND: "找不到命令 “{0}”"
CACHE_RELOAD: "正在强制从数据库中重新加载{映射|世界}的缓存。"
CHECK_CONFIG: "请检查 config.yml 文件"
COMMAND_NOT_FOUND: "找不到命令 \"{0}\""
COMMAND_THROTTLED: "请稍等片刻,然后重试。"
CONTAINER_HEADER: "容器物品变更"
CONTAINER_HEADER: "容器物品变更记录"
DATABASE_BUSY: "数据库繁忙,请稍后重试。"
DATABASE_INDEX_ERROR: "无法验证数据库索引。"
DATABASE_LOCKED_1: "数据库已被锁定,请等待至少15秒后重试..."
DATABASE_LOCKED_2: "数据库已在使用,请再试一次。"
DATABASE_LOCKED_3: "要禁用数据库锁定,请在配置文件中设置“database-lock: false”。"
DATABASE_LOCKED_3: "禁用数据库锁定,请在配置文件中设置 \"database-lock: false\"。"
DATABASE_LOCKED_4: "禁用数据库锁定可能会导致数据损坏。"
DATABASE_UNREACHABLE: "数据库无法访问。正在丢弃数据并关闭。"
DEVELOPMENT_BRANCH: "检测到开发分支,已跳过补丁脚本。"
DIRT_BLOCK: "已在你下方放置了一个泥土。"
DISABLE_SUCCESS: "成功!已禁用 {0}"
ENABLE_FAILED: "{0} 无法启动。"
DEVELOPMENT_BRANCH: "检测到正在使用开发分支的版本,跳过使用补丁脚本。"
DIRT_BLOCK: "已在你的下方放置了一个泥土。"
DISABLE_SUCCESS: "禁用 {0} 成功!"
ENABLE_FAILED: "无法启用 {0}!"
ENABLE_SUCCESS: "{0} 已成功启用!"
ENJOY_COREPROTECT: "对 {0} 感到满意吗?请加入我们 Discord!"
ENJOY_COREPROTECT: "对 {0} 感到满意吗?请加入我们的 Discord 频道!"
FINISHING_CONVERSION: "正在完成数据转换,请稍等..."
FINISHING_LOGGING: "正在完成数据记录,请稍等..."
FIRST_VERSION: "初始化数据库: {0}"
GLOBAL_LOOKUP: "请勿在执行全局查询时指定半径。"
GLOBAL_ROLLBACK: "使用 ”{0}“做一个全局{回滚|恢复}"
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: "显示附加信息。"
@@ -39,147 +39,147 @@ 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_1: "启用检查器后,你可以: "
HELP_INSPECT_2: "左键单击以查看方块放置记录。"
HELP_INSPECT_3: "右键单击以查看相邻方块破坏记录。"
HELP_INSPECT_4: "放置一个方块以查看放置位置的破坏记录。"
HELP_INSPECT_5: "在液体中放置一个方块以查看谁放置的液体。"
HELP_INSPECT_6: "右键单击门、箱子等以查看交互情况。"
HELP_INSPECT_7: "提示: 您可以只使用“/co i”进行快速查询。"
HELP_INSPECT_COMMAND: "切换方块检查开启或关闭。"
HELP_INSPECT_5: "在液体中放置一个方块以查看液体变更记录。"
HELP_INSPECT_6: "右键单击门、箱子等以查看交互记录。"
HELP_INSPECT_7: "提示: 你可以使用 \"/co i\" 进行快速查询。"
HELP_INSPECT_COMMAND: "开启或关闭方块检查状态。"
HELP_LIST: "显示所有命令的列表。"
HELP_LOOKUP_1: "命令快捷方式。"
HELP_LOOKUP_2: "在查询记录后使用以查看日志"
HELP_LOOKUP_COMMAND: "高级方块数据查询。"
HELP_NO_INFO: "命令的信息“{0}“ 未找到。"
HELP_PARAMETER: "请参阅 ”{0}\" 了解详细的参数信息。"
HELP_PARAMS_1: "执行{查找|回滚|恢复}."
HELP_PARAMS_2: "指定{查找|回滚|恢复}的玩家."
HELP_PARAMS_3: "指定{查找|回滚|恢复}的时间."
HELP_PARAMS_4: "限制{查找|回滚|恢复}到一个半径。"
HELP_PARAMS_5: "限制{查找|回滚|恢复}到一个动作。"
HELP_PARAMS_6: "包括方块/实体{查找|回滚|恢复}."
HELP_PARAMS_7: "排除方块/玩家{查找|回滚|恢复}."
HELP_PURGE_1: "删除旧数据。"
HELP_PURGE_2: "例如,”{0}” 将删除超过一个月的所有数据,只保留最近30天的数据。"
HELP_NO_INFO: "命令的信息 \"{0}\" 未找到。"
HELP_PARAMETER: "请参阅 \"{0}\" 了解详细的参数信息。"
HELP_PARAMS_1: "执行{查找|回滚|恢复}操作。"
HELP_PARAMS_2: "指定{查找|回滚|恢复}的玩家。"
HELP_PARAMS_3: "指定{查找|回滚|恢复}的时间。"
HELP_PARAMS_4: "限制{查找|回滚|恢复}的作用范围。"
HELP_PARAMS_5: "限制{查找|回滚|恢复}的动作。"
HELP_PARAMS_6: "{查找|回滚|恢复}时包括方块/实体。"
HELP_PARAMS_7: "{查找|回滚|恢复}时排除方块/玩家。"
HELP_PURGE_1: "删除指定时间的数据。"
HELP_PURGE_2: "例如,\"{0}\" 将删除超过一个月的所有数据,只保留最近30天的数据。"
HELP_PURGE_COMMAND: "删除旧的方块数据。"
HELP_RADIUS_1: "指定半径区域。"
HELP_RADIUS_2: "例子: [r:10] (只影响以你为中心的10个区块)"
HELP_RADIUS_2: "例子: [r:10] (只会影响你周围十格方块的范围)"
HELP_RELOAD_COMMAND: "重新加载配置文件。"
HELP_RESTORE_COMMAND: "恢复方块数据。"
HELP_ROLLBACK_COMMAND: "回滚方块数据。"
HELP_STATUS: "查看插件状态。"
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} 版本。"
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_BRANCH_2: "要继续,请将项目分支设置为 \"开发\"。"
INVALID_BRANCH_3: "运行开发版本的插件可能会导致数据损坏。"
INVALID_CONTAINER: "请检查有效的容器。"
INVALID_DONATION_KEY: "无效的捐赠密钥。"
INVALID_INCLUDE: "”{0}\" 是无效的方块/实体名称。"
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_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}."
LOGGING_TIME_LIMIT: "已达到数据记录时间限制。正在丢弃剩余的数据并关闭。"
LOOKUP_BLOCK: "{0} {放置|破坏} {1}。"
LOOKUP_CONTAINER: "{0} {放入|取出} {1} {2}。"
LOOKUP_HEADER: "{0} 查询结果"
LOOKUP_INTERACTION: "{0} {点击|击杀} {1}."
LOOKUP_ITEM: "{0} {拾起|丢弃} {1} {2}."
LOOKUP_LOGIN: "{0} {登入|离开}."
LOOKUP_PAGE: "页 {0}"
LOOKUP_ROWS_FOUND: "已找到{0}{行|行}。"
LOOKUP_PAGE: "第 {0} 页"
LOOKUP_ROWS_FOUND: "已找到 {0}{行|行}。"
LOOKUP_SEARCHING: "正在搜索,请稍等..."
LOOKUP_STORAGE: "{0} {放入|取出} {1} {2}."
LOOKUP_TIME: "{0} 前"
LOOKUP_USERNAME: "{0} 已登入为 {1}."
LOOKUP_VIEW_PAGE: "要查看一个页面,请输入“{0}”。"
LOOKUP_VIEW_PAGE: "查看指定操作记录,请输入\"{0}\"。"
MAXIMUM_RADIUS: "最大{查找|回滚|恢复}半径是 {0}."
MISSING_ACTION_USER: "要使用该标识符,请指定玩家名。"
MISSING_LOOKUP_TIME: "请指定{查找|回滚|恢复}时间."
MISSING_LOOKUP_USER: "请指定查找玩家或查找{方块|半径}."
MISSING_PARAMETERS: "请使用 ”{0}”。"
MISSING_PARAMETERS: "请使用 \"{0}\"。"
MISSING_ROLLBACK_RADIUS: "你没有指定{回滚|恢复}半径。"
MISSING_ROLLBACK_USER: "你没有指定{回滚|恢复}的玩家操作。"
MYSQL_UNAVAILABLE: "无法连接到 MySQL 服务器。"
NO_DATA: "在{0}中没有找到数据"
NO_DATA_LOCATION: "没有{数据|存取|交互|消息}在此位置被找到。"
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 版本."
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_SKIP_UPDATE: "在 {0} 跳过{表|索引}的{更新|创建|删除}。"
PATCH_STARTED: "正在准备更新到版本 {0},请稍等..."
PATCH_SUCCESS: "成功升级到版本 {0}。"
PATCH_UPGRADING: "正在进行数据库升级,请稍等..."
PLEASE_SELECT: "请选择: ”{0}“或”{1}”。"
PLEASE_SELECT: "请选择: \"{0}\"或\"{1}\"。"
PREVIEW_CANCELLED: "预览已取消。"
PREVIEW_CANCELLING: "正在取消预览..."
PREVIEW_CONTAINER: "您无法预览容器存取。"
PREVIEW_IN_GAME: "您只能在游戏中预览回滚操作。"
PREVIEW_CONTAINER: "你无法预览容器的存入取出操作。"
PREVIEW_IN_GAME: "你只能在游戏中预览回滚操作。"
PURGE_ABORTED: "清除失败,数据库可能已损坏。"
PURGE_ERROR: "无法处理 {0} 数据!"
PURGE_FAILED: "数据清除失败,请稍后再试。"
PURGE_IN_PROGRESS: "正在清除数据,请稍后再试。"
PURGE_MINIMUM_TIME: "您只能清除早于{0}{天|小时}的数据."
PURGE_MINIMUM_TIME: "你只能清除早于 {0} {天|小时}的数据."
PURGE_NOTICE_1: "请注意,这可能需要一些时间。"
PURGE_NOTICE_2: "在完成之前不要重新启动服务器。"
PURGE_NOTICE_2: "完成前不要重新启动服务器。"
PURGE_OPTIMIZING: "正在优化数据库,请稍等..."
PURGE_PROCESSING: "处理{0}数据..."
PURGE_PROCESSING: "正在处理表 {0} 中的数据..."
PURGE_REPAIRING: "正在尝试修复,这可能需要一定的时间..."
PURGE_ROWS: "{0}{行|行}的数据已被删除。"
PURGE_STARTED: "数据清除开始于“{0}”。"
PURGE_ROWS: "已删除 {0} {行|行}数据。"
PURGE_STARTED: "数据清除开始于\"{0}\"。"
PURGE_SUCCESS: "数据清除成功。"
RELOAD_STARTED: "正在重新加载配置 - 请稍候。"
RELOAD_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_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_RADIUS: "半径: {0}个{方块|方块}."
ROLLBACK_SELECTION: "半径设置为\"{0}\"。"
ROLLBACK_STARTED: "{回滚|恢复|预览}于 \"{0}\" 开始。"
ROLLBACK_TIME: "时间范围: {0}."
ROLLBACK_WORLD_ACTION: "限制{世界|行动}为 ”{0}”。"
SIGN_HEADER: "签名消息"
STATUS_CONSUMER: "消费者: {0}个{项目|项目} 在队列中。" # TO DO: What is "CONSUMER" in game?
ROLLBACK_WORLD_ACTION: "限制{世界|动作}为 \"{0}\"。"
SIGN_HEADER: "木牌消息"
STATUS_CONSUMER: "数据处理器: {0}个{数据|数据}待处理。"
STATUS_DATABASE: "数据库: 正在使用 {0}."
STATUS_INTEGRATION: "{0}: 合并{启用|禁用}."
STATUS_LICENSE: "协议: {0}"
STATUS_VERSION: "版本: {0}"
TELEPORTED: "传送到 {0}."
TELEPORTED_SAFETY: "将你传送到安全地点。"
TELEPORT_PLAYERS: "传送命令只能作为玩家使用。"
TELEPORT_PLAYERS: "只有玩家才能使用传送命令。"
TIME_DAYS: "{0}{天|天}"
TIME_HOURS: "{0}{小时|小时}"
TIME_MINUTES: "{0}{分钟|分钟}"
@@ -189,10 +189,10 @@ UPDATE_ERROR: "检查更新时出错。"
UPDATE_HEADER: "{0} 更新"
UPDATE_NOTICE: "注意: {0} 现在可用。"
UPGRADE_IN_PROGRESS: "正在进行升级,请稍后再试。"
USER_NOT_FOUND: "玩家“{0}”未找到。"
USER_NOT_FOUND: "玩家\"{0}\"未找到。"
USING_MYSQL: "使用 MySQL 用于数据存储。"
USING_SQLITE: "使用 SQLite 用于数据存储。"
VALID_DONATION_KEY: "有效的捐赠密钥。"
VERSION_NOTICE: "版本{0}现在可用。"
VERSION_REQUIRED: "{0} {1} 或更高的要求。"
WORLD_NOT_FOUND: "世界“{0}”未找到。"
VERSION_NOTICE: "版本 {0} 现在可用。"
VERSION_REQUIRED: "{0} 需要使用 {1} 或更高版本。"
WORLD_NOT_FOUND: "找不到世界 \"{0}\"。"
+145 -144
View File
@@ -1,179 +1,180 @@
# CoreProtect Language File (zh-TW)
# Translators: whitebear13579, Flandre_tw
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_NOT_FOUND: "未知的指令。"
COMMAND_THROTTLED: "你已受到速率限制,請稍後重試。"
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: "完成數據紀錄中,請稍後..."
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_NOT_FOUND: "未知的指令 \"{0}\"。"
COMMAND_THROTTLED: "請稍後再試。"
CONTAINER_HEADER: "儲存容器變更記錄。"
DATABASE_BUSY: "資料庫繁忙,請稍後再試。"
DATABASE_INDEX_ERROR: "無法驗證資料庫索引。"
DATABASE_LOCKED_1: "資料庫已被鎖定,請等待 15 秒後再試……"
DATABASE_LOCKED_2: "資料庫正在使用,請稍後再試一次。"
DATABASE_LOCKED_3: "若要關閉資料庫鎖定功能,請設定 \"database-lock: false\"。"
DATABASE_LOCKED_4: "關閉資料庫鎖定功能,可能導致資料損壞。"
DATABASE_UNREACHABLE: "資料庫無法存取,正在拋棄資料並關閉。"
DEVELOPMENT_BRANCH: "檢測到正在使用開發分支的版本,已跳過使用補丁腳本。"
DIRT_BLOCK: "已在你的下方放置了泥土。"
DISABLE_SUCCESS: "執行成功 ! 關閉 {0} !"
ENABLE_FAILED: "無法啟用 {0}。"
ENABLE_SUCCESS: "已經成功啟用 {0} !"
ENJOY_COREPROTECT: "喜歡 {0} 嗎 ? 加入我們的 Discord !"
FINISHING_CONVERSION: "正在完成資料轉換,請稍候……"
FINISHING_LOGGING: "正在完成資料記錄,請稍候……"
FIRST_VERSION: "初始化資料庫: {0}"
GLOBAL_LOOKUP: "請不要指定一個範圍來進行整個世界的搜尋。"
GLOBAL_ROLLBACK: "使用 \"{0}\" 來進行全面的 {回朔|恢復}"
HELP_ACTION_1: "將某個尋找的東西限制。"
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_COMMAND: "顯示該指令的更多資訊。"
HELP_EXCLUDE_1: "排除方塊/玩家"
HELP_EXCLUDE_2: "範例: [e:stone], [e:Notch], [e:stone,Notch]"
HELP_HEADER: "{0} 幫助"
HELP_INCLUDE_1: "包括指定的 方塊 / 實體"
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_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_1: "指令捷徑"
HELP_LOOKUP_2: "在使用檢查器檢查後以便查看日誌。"
HELP_LOOKUP_COMMAND: "進階查詢方塊的資料。"
HELP_NO_INFO: "未找到相關的命令訊息: \"{0}\""
HELP_PARAMETER: "若需查看相關詳細參數訊息,請查閱\"{0}\"。"
HELP_PARAMS_1: "執行 {查詢|回朔|恢復}。"
HELP_PARAMS_2: "指定一個需要 {查詢|回朔|恢復}的玩家。"
HELP_PARAMS_3: "指定一個需要 {查詢|回朔|恢復}的時間軸。"
HELP_PARAMS_4: "指定一個範圍來限制 {查詢|回朔|恢復} 。"
HELP_PARAMS_5: "將 {查詢|回朔|恢復} 限制在某個動作內。"
HELP_PARAMS_6: "在 {查詢|回朔|恢復} 中指定一個特定的 實體 / 方塊。"
HELP_PARAMS_7: "從 {查詢|回朔|恢復} 中排除一項特定的 實體 / 方塊。"
HELP_PURGE_1: "刪除了早於指定時間軸的資料。"
HELP_PURGE_2: "舉例來說,\"{0}\" 會刪除已廢棄的方塊資料,只保留近30天的資料。"
HELP_NO_INFO: "未找到 \"{0}\" 的相關指令資訊。"
HELP_PARAMETER: "若需查看相關詳細參數資訊,請查閱 \"{0}\"。"
HELP_PARAMS_1: "執行{查詢|回滾|恢復}。"
HELP_PARAMS_2: "指定需要{查詢|回滾|恢復}的玩家。"
HELP_PARAMS_3: "指定需要{查詢|回滾|恢復}的時間範圍。"
HELP_PARAMS_4: "指定限制{查詢|回滾|恢復}的範圍。"
HELP_PARAMS_5: "將{查詢|回滾|恢復}限制在某個行為。"
HELP_PARAMS_6: "在{查詢|回滾|恢復}中指定特定的實體/方塊。"
HELP_PARAMS_7: "從{查詢|回滾|恢復}中排除特定的方塊/玩家。"
HELP_PURGE_1: "刪除了指定時間範圍的資料。"
HELP_PURGE_2: "舉例來說,\"{0}\" 將會刪除超過一個月的所有方塊資料,只保留最近 30 天的資料。"
HELP_PURGE_COMMAND: "刪除舊的方塊資料。"
HELP_RADIUS_1: "指定一個範圍。"
HELP_RADIUS_2: "範例: [r:10] (僅會更改你周圍的10格方塊)"
HELP_RELOAD_COMMAND: "重新載入配置文件。"
HELP_RADIUS_1: "指定半徑範圍。"
HELP_RADIUS_2: "範例: [r:10] (僅會更改你周圍的 10 格方塊)"
HELP_RELOAD_COMMAND: "重新載入配置檔案。"
HELP_RESTORE_COMMAND: "恢復方塊資料。"
HELP_ROLLBACK_COMMAND: "回朔方塊資料。"
HELP_ROLLBACK_COMMAND: "回滾方塊資料。"
HELP_STATUS: "查看插件狀態與版本資訊。"
HELP_STATUS_COMMAND: "顯示插件狀態。"
HELP_TELEPORT: "傳送到一個位置。"
HELP_TIME_1: "指定查找的時間軸。"
HELP_TELEPORT: "傳送到座標。"
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_TOGGLED: "檢查器現在已 {開啟|關閉}。"
INTEGRATION_ERROR: "無法 {初始化|關閉} {0} 日誌紀錄。"
INTEGRATION_SUCCESS: "{0} 成功紀錄 {初始化|關閉}."
INTEGRATION_VERSION: "發現無效的版本: {0}"
INSPECTOR_ERROR: "已{開啟|關閉}檢查器了。"
INSPECTOR_TOGGLED: "已{開啟|關閉}檢查器。"
INTEGRATION_ERROR: "無法{初始化|關閉} {0} 日誌記錄。"
INTEGRATION_SUCCESS: "{0} 成功記錄{初始化|關閉}。"
INTEGRATION_VERSION: "發現 {0} 版本無效。"
INTERACTIONS_HEADER: "玩家互動"
INVALID_ACTION: "這不是一個有效的行為。"
INVALID_BRANCH_1: "CoreProtect插件版本無效(未設置分支)。"
INVALID_BRANCH_2: "若要繼續動作,請將你的項目分之設定為 \"development\"。"
INVALID_BRANCH_3: "執行開發中的代碼可能會導致資料損毀。"
INVALID_ACTION: "這不是有效的行為。"
INVALID_BRANCH_1: "插件版本無效 (未設定分支)。"
INVALID_BRANCH_2: "若要繼續行為,請將你的項目分之設定為 \"development\"。"
INVALID_BRANCH_3: "執行開發中的插件可能會導致資料損毀。"
INVALID_CONTAINER: "請先檢查有效的容器。"
INVALID_DONATION_KEY: "無效的贈品密鑰。"
INVALID_INCLUDE: "\"{0}\" 是無效的 方塊 / 實體 名稱。"
INVALID_INCLUDE_COMBO: "這是一個無效的塊/實體組合。"
INVALID_RADIUS: "請輸入一個有效的範圍。"
INVALID_SELECTION: "你選擇的內容 {0} 未找到。"
INVALID_USERNAME: "\"{0}\" 是一個無效的玩名稱。"
INVALID_WORLD: "請指定一個有效的世界。"
INVALID_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: "已達到紀錄的時間上限。刪除資料並關閉中..."
LINK_WIKI_BLOCK: "方塊名稱: {0}"
LINK_WIKI_ENTITY: "實體名稱: {0}"
LOGGING_ITEMS: "還剩 {0} 項要進行記錄,請稍候……"
LOGGING_TIME_LIMIT: "已達到記錄的時間上限,正在刪除資料並關閉……"
LOOKUP_BLOCK: "{0} {放置|破壞} {1}。"
LOOKUP_CONTAINER: "{0} {增加|刪除} {1} {2}."
LOOKUP_HEADER: "{0} 尋找結果。"
LOOKUP_INTERACTION: "{0} {點擊|殺死} {1}."
LOOKUP_ITEM: "{0} {拾起|放下} {1} {2}."
LOOKUP_LOGIN: "{0} 你已登 {入|出}。"
LOOKUP_PAGE: "頁數 {0}"
LOOKUP_ROWS_FOUND: "{0} {row|rows} 找到。"
LOOKUP_SEARCHING: "尋找結果中,請稍後..."
LOOKUP_STORAGE: "{0} {存|取} {1} {2}."
LOOKUP_CONTAINER: "{0} {新增|刪除} {1} {2}。"
LOOKUP_HEADER: "{0} 搜尋結果。"
LOOKUP_INTERACTION: "{0} {點擊|殺死} {1}。"
LOOKUP_ITEM: "{0} {撿起|拋棄} {1} {2}。"
LOOKUP_LOGIN: "{0} 已登{入|出}。"
LOOKUP_PAGE: "第 {0} 頁"
LOOKUP_ROWS_FOUND: "已找到 {0} {行|行}。"
LOOKUP_SEARCHING: "正在搜尋,請稍候……"
LOOKUP_STORAGE: "{0} {存|取} {1} {2}。"
LOOKUP_TIME: "{0} 前"
LOOKUP_USERNAME: "{0} 以 {1}的身分登入。"
LOOKUP_USERNAME: "{0} 以 {1} 的身分登入。"
LOOKUP_VIEW_PAGE: "若要查看指定頁面,請輸入 \"{0}\"。"
MAXIMUM_RADIUS: "最大 {查詢|回朔|恢復} 的範圍為 {0}。"
MAXIMUM_RADIUS: "最大 {查詢|回滾|恢復} 的範圍為 {0}。"
MISSING_ACTION_USER: "若要使用此操作,請指定玩家。"
MISSING_LOOKUP_TIME: "請指定 {查詢|回朔|恢復}的時間軸。"
MISSING_LOOKUP_USER: "請指定要尋找的玩家或是 {方塊|範圍} 。"
MISSING_PARAMETERS: "請使用 \"{0}\"."
MISSING_ROLLBACK_RADIUS: "你沒有指定 {回朔|恢復} 的範圍。"
MISSING_ROLLBACK_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_DATA: "找不到 {0} §f的資料。"
NO_DATA_LOCATION: "找不到這個位置的{資料|交易|互動|訊息}。"
NO_PERMISSION: "你沒有使用該操作的權限。"
NO_RESULTS: "未找到相關結果。"
NO_RESULTS_PAGE: "未找到該頁面相關的 {結果|資料}。"
NO_ROLLBACK: "未找到 {待處理|舊的} 回朔 / 恢復。"
PATCH_INTERRUPTED: "更新時遭到無預警的中斷! 系統會在下次重啟時重新嘗試。"
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_OUTDATED_2: "請使用受到支援的 CoreProtect 版本。"
PATCH_PROCESSING: "正在處理新資訊,請稍候……"
PATCH_SKIP_UPDATE: "已在 {0} 上跳過{列表|索引}的{更新|建立|刪除}。"
PATCH_STARTED: "正在執行 {0} 更新,請稍候……"
PATCH_SUCCESS: "已成功升級到 {0}。"
PATCH_UPGRADING: "正在進行資料庫升級中,請稍後..."
PLEASE_SELECT: "請選擇 \"{0}\" 或是 \"{1}\"。"
PATCH_UPGRADING: "正在進行資料庫升級,請稍候……"
PLEASE_SELECT: "請選擇: \"{0}\" 或是 \"{1}\"。"
PREVIEW_CANCELLED: "預覽已取消。"
PREVIEW_CANCELLING: "正在取消預覽。"
PREVIEW_CANCELLING: "正在取消預覽……"
PREVIEW_CONTAINER: "你無法預覽容器內的物品資料。"
PREVIEW_IN_GAME: "你只能在遊戲中預覽回朔。"
PREVIEW_IN_GAME: "你只能在遊戲中預覽回滾。"
PURGE_ABORTED: "清除失敗,你的資料可能已損毀。"
PURGE_ERROR: "無法處理 {0} 條資料。"
PURGE_FAILED: "清除失敗,請稍後在重試。"
PURGE_IN_PROGRESS: "正在執行清除作業中,請稍後在重試。"
PURGE_ERROR: "無法處理 {0} 條資料 !"
PURGE_FAILED: "清除失敗,請稍後再試。"
PURGE_IN_PROGRESS: "正在執行清除作業,請稍後再試。"
PURGE_MINIMUM_TIME: "你只能清除早於 {0} {天|小時}的資料。"
PURGE_NOTICE_1: "請注意,此操作可能需要一些時間!"
PURGE_NOTICE_2: "在系統完成此進程前請不要重新啟動伺服器。"
PURGE_OPTIMIZING: "最佳化資料庫中,請稍後..."
PURGE_PROCESSING: " 正在處理 {0} 條資料。"
PURGE_REPAIRING: "系統嘗試修復此問題中,這可能會花上一段時間。"
PURGE_ROWS: "{0} {行數|行數} 資料已刪除。"
PURGE_STARTED: "資料刪除進程開始於 \"{0}\"。"
PURGE_SUCCESS: "資料清除成功!"
RELOAD_STARTED: "正在重新載入配置文件中,請稍後..."
RELOAD_SUCCESS: "配置文件已重新載入成功!"
ROLLBACK_ABORTED: "回朔 / 恢復 已中止。"
ROLLBACK_CHUNKS_FOUND: "找到 {0} {區塊|區塊} 進行修改。"
ROLLBACK_CHUNKS_MODIFIED: "修改了 {0}/{1} {區塊|區塊}。"
ROLLBACK_COMPLETED: "\"{0}\" 的 {回朔|恢復|預覽} 已完成。"
ROLLBACK_EXCLUDED_USERS: "排除的 {玩家|玩家}: \"{0}\"。"
ROLLBACK_INCLUDE: "{包含|不包含} {方塊|實體|目標} {類型|類型}: \"{0}\"。"
ROLLBACK_IN_PROGRESS: "回朔 / 恢復 已在進行中。"
ROLLBACK_LENGTH: "所用時間: {0} {秒|秒}。"
ROLLBACK_MODIFIED: "{更動|更動} {0}。"
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}\"."
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_CONSUMER: "玩家: {0} 個{物品|物品}已在隊列中。"
STATUS_DATABASE: "資料庫: 使用 {0}。"
STATUS_INTEGRATION: "{0}: 整合{開啟|關閉}。"
STATUS_LICENSE: "憑證: {0}"
STATUS_VERSION: "版本: {0}"
TELEPORTED: "傳送到 {0}。"
@@ -183,15 +184,15 @@ TIME_DAYS: "{0} {天|天}"
TIME_HOURS: "{0} {小時|小時}"
TIME_MINUTES: "{0} {分鐘|分鐘}"
TIME_SECONDS: "{0} {秒|秒}"
TIME_WEEKS: "{0} {周|周}"
UPDATE_ERROR: "檢查更新時出現錯誤!"
TIME_WEEKS: "{0} {週|週}"
UPDATE_ERROR: "檢查更新時發生錯誤。"
UPDATE_HEADER: "{0} 更新"
UPDATE_NOTICE: "通知: {0} 現已推出。"
UPGRADE_IN_PROGRESS: "正在進行更新中,請稍後再試。"
USER_NOT_FOUND: "玩家: \"{0}\"不存在(或為未上線)。"
UPGRADE_IN_PROGRESS: "正在進行更新,請稍後再試。"
USER_NOT_FOUND: "找不到玩家 \"{0}\"。"
USING_MYSQL: "使用 MySQL 進行資料儲存。"
USING_SQLITE: "使用 SQLite 進行資料儲存。"
VALID_DONATION_KEY: "有效的贈品金鑰"
VERSION_NOTICE: "版本 {0} 現已推出。"
VERSION_REQUIRED: "需要有 {0} {1} 或更高的權限"
VERSION_REQUIRED: "{0} 需要使用 {1} 或更高版本。 "
WORLD_NOT_FOUND: "世界: \"{0}\" 不存在。"
-4
View File
@@ -1,4 +0,0 @@
# netlify.toml
[build]
ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF docs/"
+18 -18
View File
@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>net.coreprotect</groupId>
<artifactId>CoreProtect</artifactId>
<version>20.0</version>
<version>20.4</version>
<properties>
<project.branch></project.branch>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -56,6 +56,10 @@
<pattern>org.bstats</pattern>
<shadedPattern>net.coreprotect</shadedPattern>
</relocation>
<relocation>
<pattern>com.zaxxer</pattern>
<shadedPattern>net.coreprotect</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
@@ -64,12 +68,6 @@
</plugins>
</build>
<repositories>
<!--
<repository>
<id>public</id>
<url>http://repo.mvdw-software.be/content/groups/public/</url>
</repository>
-->
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
@@ -83,25 +81,22 @@
<url>https://repo.codemc.org/repository/maven-public/</url>
</repository>
<repository>
<id>sk89q-repo</id>
<url>http://maven.sk89q.com/repo/</url>
<id>enginehub-repo</id>
<url>https://maven.enginehub.org/repo/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.17-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!--
paper-api (<= 1.16): com.destroystokyo.paper
spigot-api: org.spigotmc
bukkit: org.bukkit
-->
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.17-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
-->
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit-lite</artifactId>
@@ -120,5 +115,10 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>4.0.3</version>
</dependency>
</dependencies>
</project>
+1 -1
View File
@@ -1 +1 @@
mkdocs==1.2.1
mkdocs==1.2.3
@@ -13,6 +13,7 @@ import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.consumer.process.Process;
import net.coreprotect.database.Database;
import net.coreprotect.language.Language;
import net.coreprotect.language.Phrase;
import net.coreprotect.listener.ListenerHandler;
@@ -127,7 +128,7 @@ public final class CoreProtect extends JavaPlugin {
private static boolean performVersionChecks() {
try {
String[] bukkitVersion = Bukkit.getServer().getBukkitVersion().split("-|\\.");
String[] bukkitVersion = Bukkit.getServer().getBukkitVersion().split("[-.]");
if (Util.newVersion(bukkitVersion[0] + "." + bukkitVersion[1], ConfigHandler.SPIGOT_VERSION)) {
Chat.console(Phrase.build(Phrase.VERSION_REQUIRED, "Spigot", ConfigHandler.SPIGOT_VERSION));
return false;
@@ -189,6 +190,7 @@ public final class CoreProtect extends JavaPlugin {
Thread.sleep(100);
}
Database.closeConnection();
Chat.console(Phrase.build(Phrase.DISABLE_SUCCESS, "CoreProtect v" + plugin.getDescription().getVersion()));
}
catch (Exception e) {
@@ -142,7 +142,7 @@ public class CoreProtectAPI extends Queue {
}
public int APIVersion() {
return 7;
return 8;
}
public List<String[]> blockLookup(Block block, int time) {
@@ -157,13 +157,13 @@ public class CoreProtectAPI extends Queue {
boolean match = false;
if (Config.getGlobal().API_ENABLED) {
int unixTimestamp = (int) (System.currentTimeMillis() / 1000L);
int offsetTime = unixTimestamp - offset;
long timestamp = System.currentTimeMillis() / 1000L;
long offsetTime = timestamp - offset;
List<String[]> check = blockLookup(block, time);
for (String[] value : check) {
ParseResult result = parseResult(value);
if (user.equalsIgnoreCase(result.getPlayer()) && result.getActionId() == 1 && result.getTime() <= offsetTime) {
if (user.equalsIgnoreCase(result.getPlayer()) && result.getActionId() == 1 && result.getTimestamp() <= offsetTime) {
match = true;
break;
}
@@ -178,13 +178,13 @@ public class CoreProtectAPI extends Queue {
boolean match = false;
if (Config.getGlobal().API_ENABLED) {
int unixTimestamp = (int) (System.currentTimeMillis() / 1000L);
int offsetTime = unixTimestamp - offset;
long timestamp = System.currentTimeMillis() / 1000L;
long offsetTime = timestamp - offset;
List<String[]> check = blockLookup(block, time);
for (String[] value : check) {
ParseResult result = parseResult(value);
if (user.equalsIgnoreCase(result.getPlayer()) && result.getActionId() == 0 && result.getTime() <= offsetTime) {
if (user.equalsIgnoreCase(result.getPlayer()) && result.getActionId() == 0 && result.getTimestamp() <= offsetTime) {
match = true;
break;
}
@@ -202,9 +202,9 @@ public class CoreProtectAPI extends Queue {
if (Config.getGlobal().API_ENABLED && player != null && Config.getConfig(player.getWorld()).PLAYER_MESSAGES) {
if (message != null) {
if (message.length() > 0 && !message.startsWith("/")) {
int time = (int) (System.currentTimeMillis() / 1000L);
long timestamp = System.currentTimeMillis() / 1000L;
Queue.queuePlayerChat(player, message, time);
Queue.queuePlayerChat(player, message, timestamp);
return true;
}
}
@@ -217,9 +217,9 @@ public class CoreProtectAPI extends Queue {
if (Config.getGlobal().API_ENABLED && player != null && Config.getConfig(player.getWorld()).PLAYER_COMMANDS) {
if (command != null) {
if (command.length() > 0 && command.startsWith("/")) {
int time = (int) (System.currentTimeMillis() / 1000L);
long timestamp = System.currentTimeMillis() / 1000L;
Queue.queuePlayerCommand(player, command, time);
Queue.queuePlayerCommand(player, command, timestamp);
return true;
}
}
@@ -430,8 +430,8 @@ public class CoreProtectAPI extends Queue {
restrictUsers.add("#global");
}
int unixTimestamp = (int) (System.currentTimeMillis() / 1000L);
int timePeriod = unixTimestamp - time;
long timestamp = System.currentTimeMillis() / 1000L;
long timePeriod = timestamp - time;
if (radius < 1) {
radius = -1;
@@ -445,8 +445,7 @@ public class CoreProtectAPI extends Queue {
return null;
}
try {
Connection connection = Database.getConnection(false, 1000);
try (Connection connection = Database.getConnection(false, 1000)) {
if (connection != null) {
Statement statement = connection.createStatement();
boolean restrictWorld = false;
@@ -465,7 +464,7 @@ public class CoreProtectAPI extends Queue {
int xMax = location.getBlockX() + radius;
int zMin = location.getBlockZ() - radius;
int zMax = location.getBlockZ() + radius;
argRadius = new Integer[] { radius, xMin, xMax, -1, -1, zMin, zMax, 0 };
argRadius = new Integer[] { radius, xMin, xMax, null, null, zMin, zMax, 0 };
}
if (lookup == 1) {
@@ -488,7 +487,6 @@ public class CoreProtectAPI extends Queue {
}
statement.close();
connection.close();
}
}
catch (Exception e) {
@@ -22,25 +22,27 @@ import net.coreprotect.utility.Util;
public class BukkitAdapter implements BukkitInterface {
public static BukkitInterface ADAPTER;
public static final int BUKKIT_v1_13 = 13;
public static final int BUKKIT_v1_14 = 14;
public static final int BUKKIT_v1_15 = 15;
public static final int BUKKIT_v1_16 = 16;
public static final int BUKKIT_v1_17 = 17;
public static final int BUKKIT_V1_13 = 13;
public static final int BUKKIT_V1_14 = 14;
public static final int BUKKIT_V1_15 = 15;
public static final int BUKKIT_V1_16 = 16;
public static final int BUKKIT_V1_17 = 17;
public static final int BUKKIT_V1_18 = 18;
public static void loadAdapter() {
switch (ConfigHandler.SERVER_VERSION) {
case BUKKIT_v1_13:
case BUKKIT_v1_14:
case BUKKIT_V1_13:
case BUKKIT_V1_14:
BukkitAdapter.ADAPTER = new BukkitAdapter();
break;
case BUKKIT_v1_15:
case BUKKIT_V1_15:
BukkitAdapter.ADAPTER = new Bukkit_v1_15();
break;
case BUKKIT_v1_16:
case BUKKIT_V1_16:
BukkitAdapter.ADAPTER = new Bukkit_v1_16();
break;
case BUKKIT_v1_17:
case BUKKIT_V1_17:
case BUKKIT_V1_18:
default:
BukkitAdapter.ADAPTER = new Bukkit_v1_17();
break;
@@ -29,7 +29,7 @@ import net.coreprotect.utility.Util;
public class Bukkit_v1_17 extends Bukkit_v1_16 implements BukkitInterface {
public Bukkit_v1_17() {
BlockGroup.TRACK_ANY = new HashSet<>(Arrays.asList(Material.MOVING_PISTON, Material.LEVER, Material.BELL, Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER, Material.GLOW_LICHEN));
BlockGroup.TRACK_ANY = new HashSet<>(Arrays.asList(Material.PISTON_HEAD, Material.LEVER, Material.BELL, Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER, Material.GLOW_LICHEN));
BlockGroup.TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP, Material.SOUL_TORCH, Material.TWISTING_VINES, Material.CRIMSON_FUNGUS, Material.WARPED_FUNGUS, Material.CRIMSON_ROOTS, Material.WARPED_ROOTS, Material.NETHER_SPROUTS, Material.CRIMSON_SIGN, Material.WARPED_SIGN, Material.AZALEA, Material.FLOWERING_AZALEA, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF));
BlockGroup.TRACK_TOP_BOTTOM = new HashSet<>(Arrays.asList(Material.POINTED_DRIPSTONE, Material.BIG_DRIPLEAF_STEM));
BlockGroup.TRACK_BOTTOM = new HashSet<>(Arrays.asList(Material.WEEPING_VINES, Material.CAVE_VINES, Material.CAVE_VINES_PLANT, Material.HANGING_ROOTS));
@@ -11,14 +11,13 @@ import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class ApplyCommand {
protected static void runCommand(CommandSender user, Command command, boolean permission, String[] args) {
try {
if (ConfigHandler.lastRollback.get(user.getName()) != null) {
List<Object> list = ConfigHandler.lastRollback.get(user.getName());
int time = (Integer) list.get(0);
long time = (Long) list.get(0);
args = (String[]) list.get(1);
Location location = (Location) list.get(2);
boolean valid = false;
@@ -11,14 +11,13 @@ import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class CancelCommand {
protected static void runCommand(CommandSender user, Command command, boolean permission, String[] args) {
try {
if (ConfigHandler.lastRollback.get(user.getName()) != null) {
List<Object> list = ConfigHandler.lastRollback.get(user.getName());
int time = (Integer) list.get(0);
long time = (Long) list.get(0);
args = (String[]) list.get(1);
Location location = (Location) list.get(2);
boolean valid = false;
@@ -563,12 +563,12 @@ public class CommandHandler implements CommandExecutor {
rcount++;
}
if (location != null) {
int xmin = location.getBlockX() - r_x;
int xmax = location.getBlockX() + r_x;
int ymin = -1;
int ymax = -1;
int zmin = location.getBlockZ() - r_z;
int zmax = location.getBlockZ() + r_z;
Integer xmin = location.getBlockX() - r_x;
Integer xmax = location.getBlockX() + r_x;
Integer ymin = null;
Integer ymax = null;
Integer zmin = location.getBlockZ() - r_z;
Integer zmax = location.getBlockZ() + r_z;
if (r_y > -1) {
ymin = location.getBlockY() - r_y;
ymax = location.getBlockY() + r_y;
@@ -691,9 +691,9 @@ public class CommandHandler implements CommandExecutor {
return restricted;
}
protected static int parseTime(String[] inputArguments) {
protected static long parseTime(String[] inputArguments) {
String[] argumentArray = inputArguments.clone();
int time = 0;
long time = 0;
int count = 0;
int next = 0;
double w = 0;
@@ -754,7 +754,7 @@ public class CommandHandler implements CommandExecutor {
}
}
double rs = ((w * 7 * 24 * 60 * 60) + (d * 24 * 60 * 60) + (h * 60 * 60) + (m * 60) + s);
time = (int) rs;
time = (long) rs;
next = 0;
}
else {
@@ -763,6 +763,7 @@ public class CommandHandler implements CommandExecutor {
}
count++;
}
return time;
}
@@ -7,7 +7,6 @@ import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class InspectCommand {
protected static void runCommand(CommandSender player, boolean permission, String[] args) {
@@ -7,7 +7,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -19,6 +18,8 @@ import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import com.google.common.base.Strings;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.Database;
@@ -50,7 +51,7 @@ public class LookupCommand {
List<Object> argExclude = CommandHandler.parseExcluded(player, args, argAction);
List<String> argExcludeUsers = CommandHandler.parseExcludedUsers(player, args);
String ts = CommandHandler.parseTimeString(args);
int rbseconds = CommandHandler.parseTime(args);
long rbseconds = CommandHandler.parseTime(args);
int argWid = CommandHandler.parseWorld(args, true, true);
int parseRows = CommandHandler.parseRows(args);
boolean count = CommandHandler.parseCount(args);
@@ -227,7 +228,7 @@ public class LookupCommand {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
if (argAction.contains(11) && !player.hasPermission("coreprotect.lookup.item")) {
if (argAction.contains(11) && (!player.hasPermission("coreprotect.lookup.inventory") || !player.hasPermission("coreprotect.lookup.item"))) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
@@ -324,9 +325,8 @@ public class LookupCommand {
class BasicThread implements Runnable {
@Override
public void run() {
try {
try (Connection connection = Database.getConnection(true)) {
ConfigHandler.lookupThrottle.put(player2.getName(), new Object[] { true, System.currentTimeMillis() });
Connection connection = Database.getConnection(true);
if (connection != null) {
Statement statement = connection.createStatement();
String blockdata = ChestTransactionLookup.performLookup(command.getName(), statement, location, player2, p2, finalLimit, false);
@@ -339,7 +339,6 @@ public class LookupCommand {
Chat.sendComponent(player2, blockdata);
}
statement.close();
connection.close();
}
else {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
@@ -422,9 +421,8 @@ public class LookupCommand {
class BasicThread implements Runnable {
@Override
public void run() {
try {
try (Connection connection = Database.getConnection(true)) {
ConfigHandler.lookupThrottle.put(player2.getName(), new Object[] { true, System.currentTimeMillis() });
Connection connection = Database.getConnection(true);
if (connection != null) {
Statement statement = connection.createStatement();
if (t == 8) {
@@ -461,7 +459,6 @@ public class LookupCommand {
}
}
statement.close();
connection.close();
}
else {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
@@ -557,7 +554,7 @@ public class LookupCommand {
c++;
}
int cs = -1;
long cs = -1;
int x = 0;
int y = 0;
int z = 0;
@@ -570,7 +567,7 @@ public class LookupCommand {
y = Integer.parseInt(data[1]);
z = Integer.parseInt(data[2]);
wid = Integer.parseInt(data[3]);
cs = Integer.parseInt(data[4]);
cs = Long.parseLong(data[4]);
// arg_radius = Integer.parseInt(data[5]);
argNoisy = Integer.parseInt(data[5]);
argExcluded = Integer.parseInt(data[6]);
@@ -643,7 +640,7 @@ public class LookupCommand {
}
final List<String> rollbackusers2 = rollbackusers;
int unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
long unixtimestamp = (System.currentTimeMillis() / 1000L);
if (cs == -1) {
if (rbseconds <= 0) {
cs = 0;
@@ -652,7 +649,7 @@ public class LookupCommand {
cs = unixtimestamp - rbseconds;
}
}
final int stime = cs;
final long stime = cs;
final Integer[] radius = argRadius;
try {
@@ -681,7 +678,7 @@ public class LookupCommand {
class BasicThread2 implements Runnable {
@Override
public void run() {
try {
try (Connection connection = Database.getConnection(true)) {
ConfigHandler.lookupThrottle.put(player2.getName(), new Object[] { true, System.currentTimeMillis() });
List<String> uuidList = new ArrayList<>();
@@ -699,7 +696,6 @@ public class LookupCommand {
ConfigHandler.lookupAlist.put(player2.getName(), finalArgAction);
ConfigHandler.lookupRadius.put(player2.getName(), radius);
Connection connection = Database.getConnection(true);
if (connection != null) {
Statement statement = connection.createStatement();
String baduser = "";
@@ -802,7 +798,7 @@ public class LookupCommand {
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
double time_length = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, false).replaceAll("[^0-9]", "").length() * 1.50;
int padding = (int) (time_length + 12.50);
String leftPadding = StringUtils.leftPad("", padding, ' ');
String leftPadding = Strings.padStart("", padding, ' ');
Chat.sendComponent(player2, timeago + " " + Color.WHITE + "- " + Color.DARK_AQUA + Phrase.build(Phrase.LOOKUP_LOGIN, Color.DARK_AQUA + dplayer + Color.WHITE, (action != 0 ? Selector.FIRST : Selector.SECOND)));
Chat.sendComponent(player2, Color.WHITE + leftPadding + Color.GREY + "^ " + Util.getCoordinates(command.getName(), wid, x, y, z, true, true) + "");
}
@@ -828,7 +824,7 @@ public class LookupCommand {
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
double time_length = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, false).replaceAll("[^0-9]", "").length() * 1.50;
int padding = (int) (time_length + 12.50);
String leftPadding = StringUtils.leftPad("", padding, ' ');
String leftPadding = Strings.padStart("", padding, ' ');
Chat.sendComponent(player2, timeago + " " + Color.WHITE + "- " + Color.DARK_AQUA + dplayer + ": " + Color.WHITE, message);
Chat.sendComponent(player2, Color.WHITE + leftPadding + Color.GREY + "^ " + Util.getCoordinates(command.getName(), wid, x, y, z, true, true) + "");
}
@@ -856,7 +852,7 @@ public class LookupCommand {
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
double timeLength = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, false).replaceAll("[^0-9]", "").length() * 1.50;
int padding = (int) (timeLength + 12.50);
String leftPadding = StringUtils.leftPad("", padding, ' ');
String leftPadding = Strings.padStart("", padding, ' ');
String dname = "";
boolean isPlayer = false;
@@ -950,7 +946,6 @@ public class LookupCommand {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.USER_NOT_FOUND, baduser));
}
statement.close();
connection.close();
}
else {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
@@ -31,7 +31,7 @@ public class PurgeCommand extends Consumer {
int resultc = args.length;
Location location = CommandHandler.parseLocation(player, args);
final Integer[] argRadius = CommandHandler.parseRadius(args, player, location);
final int seconds = CommandHandler.parseTime(args);
final long seconds = CommandHandler.parseTime(args);
final int argWid = CommandHandler.parseWorld(args, false, false);
final List<Integer> argAction = CommandHandler.parseAction(args);
final List<Integer> supportedActions = Arrays.asList();
@@ -95,8 +95,8 @@ public class PurgeCommand extends Consumer {
@Override
public void run() {
try {
int timestamp = (int) (System.currentTimeMillis() / 1000L);
int ptime = timestamp - seconds;
long timestamp = (System.currentTimeMillis() / 1000L);
long ptime = timestamp - seconds;
long removed = 0;
Connection connection = null;
@@ -329,6 +329,11 @@ public class PurgeCommand extends Consumer {
}
}
catch (Exception e) {
if (!ConfigHandler.serverRunning) {
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_FAILED));
return;
}
e.printStackTrace();
}
}
@@ -31,7 +31,7 @@ import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class RollbackRestoreCommand {
protected static void runCommand(CommandSender player, Command command, boolean permission, String[] args, Location argLocation, int forceSeconds) {
protected static void runCommand(CommandSender player, Command command, boolean permission, String[] args, Location argLocation, long forceSeconds) {
Location lo = (argLocation != null ? argLocation : CommandHandler.parseLocation(player, args));
List<String> argUuids = new ArrayList<>();
List<String> argUsers = CommandHandler.parseUsers(args);
@@ -42,7 +42,7 @@ public class RollbackRestoreCommand {
List<Object> argExclude = CommandHandler.parseExcluded(player, args, argAction);
List<String> argExcludeUsers = CommandHandler.parseExcludedUsers(player, args);
String ts = CommandHandler.parseTimeString(args);
int rbSeconds = CommandHandler.parseTime(args);
long rbSeconds = CommandHandler.parseTime(args);
int argWid = CommandHandler.parseWorld(args, true, true);
boolean count = CommandHandler.parseCount(args);
boolean worldedit = CommandHandler.parseWorldEdit(args);
@@ -157,7 +157,7 @@ public class RollbackRestoreCommand {
int xmax = location.getBlockX() + DEFAULT_RADIUS;
int zmin = location.getBlockZ() - DEFAULT_RADIUS;
int zmax = location.getBlockZ() + DEFAULT_RADIUS;
argRadius = new Integer[] { DEFAULT_RADIUS, xmin, xmax, -1, -1, zmin, zmax, 0 };
argRadius = new Integer[] { DEFAULT_RADIUS, xmin, xmax, null, null, zmin, zmax, 0 };
}
// if (arg_radius==-2)arg_radius = -1;
@@ -284,12 +284,12 @@ public class RollbackRestoreCommand {
final List<String> rollbackusers2 = rollbackusers;
if (rbSeconds > 0) {
int unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
int seconds = unixtimestamp - rbSeconds;
long unixtimestamp = (System.currentTimeMillis() / 1000L);
long seconds = unixtimestamp - rbSeconds;
if (forceSeconds > 0) {
seconds = forceSeconds;
}
final int stime = seconds;
final long stime = seconds;
final Integer[] radius = argRadius;
try {
final CommandSender player2 = player;
@@ -310,11 +310,10 @@ public class RollbackRestoreCommand {
class BasicThread2 implements Runnable {
@Override
public void run() {
try {
try (Connection connection = Database.getConnection(false, 1000)) {
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { true, System.currentTimeMillis() });
int action = finalAction;
Location location = locationFinal;
Connection connection = Database.getConnection(false, 1000);
if (connection != null) {
Statement statement = connection.createStatement();
String baduser = "";
@@ -407,7 +406,6 @@ public class RollbackRestoreCommand {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.USER_NOT_FOUND, baduser));
}
statement.close();
connection.close();
}
else {
Chat.sendMessage(player2, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
@@ -11,6 +11,7 @@ import net.coreprotect.language.Phrase;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.ChatMessage;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Teleport;
import net.coreprotect.utility.Util;
public class TeleportCommand {
@@ -103,7 +104,7 @@ public class TeleportCommand {
}
// Teleport the player to a safe location
Util.performSafeTeleport(((Player) player), location, true);
Teleport.performSafeTeleport(((Player) player), location, true);
ConfigHandler.teleportThrottle.put(player.getName(), new Object[] { false, System.currentTimeMillis() });
}
@@ -11,14 +11,13 @@ import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
public class UndoCommand {
protected static void runCommand(CommandSender user, Command command, boolean permission, String[] args) {
try {
if (ConfigHandler.lastRollback.get(user.getName()) != null) {
List<Object> list = ConfigHandler.lastRollback.get(user.getName());
int time = (Integer) list.get(0);
long time = (Long) list.get(0);
args = (String[]) list.get(1);
Location location = (Location) list.get(2);
for (String arg : args) {
@@ -21,13 +21,16 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import net.coreprotect.bukkit.BukkitAdapter;
import net.coreprotect.consumer.Consumer;
import net.coreprotect.consumer.Queue;
import net.coreprotect.database.Database;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.model.BlockGroup;
import net.coreprotect.paper.PaperAdapter;
import net.coreprotect.patch.Patch;
import net.coreprotect.spigot.SpigotAdapter;
import net.coreprotect.utility.Chat;
@@ -49,6 +52,7 @@ public class ConfigHandler extends Queue {
public static String username = "root";
public static String password = "";
public static String prefix = "co_";
public static HikariDataSource hikariDataSource = null;
public static final boolean isSpigot = Util.isSpigot();
public static final boolean isPaper = Util.isPaper();
public static volatile boolean serverRunning = false;
@@ -85,7 +89,7 @@ public class ConfigHandler extends Queue {
public static ConcurrentHashMap<String, List<ItemStack[]>> oldContainer = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, List<ItemStack>> itemsDrop = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, List<ItemStack>> itemsPickup = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, Boolean> hopperAbort = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, Object[]> hopperAbort = new ConcurrentHashMap<>();
public static Map<String, List<ItemStack[]>> forceContainer = syncMap();
public static Map<String, Integer> lookupType = syncMap();
public static Map<String, Object[]> lookupThrottle = syncMap();
@@ -170,6 +174,9 @@ public class ConfigHandler extends Queue {
}
public static void loadDatabase() {
// close old pool when we reload the database, e.g. in purge command
Database.closeConnection();
if (!Config.getGlobal().MYSQL) {
try {
File tempFile = File.createTempFile("CoreProtect_" + System.currentTimeMillis(), ".tmp");
@@ -198,10 +205,38 @@ public class ConfigHandler extends Queue {
e.printStackTrace();
}
}
else {
HikariConfig config = new HikariConfig();
try {
Class.forName("com.mysql.cj.jdbc.Driver");
config.setDriverClassName("com.mysql.cj.jdbc.Driver");
}
catch (Exception e) {
config.setDriverClassName("com.mysql.jdbc.Driver");
}
if (ConfigHandler.serverRunning) {
Consumer.resetConnection = true;
config.setJdbcUrl("jdbc:mysql://" + ConfigHandler.host + ":" + ConfigHandler.port + "/" + ConfigHandler.database);
config.setUsername(ConfigHandler.username);
config.setPassword(ConfigHandler.password);
config.addDataSourceProperty("characterEncoding", "UTF-8");
config.addDataSourceProperty("connectionTimeout", "10000");
/* https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration */
/* https://cdn.oreillystatic.com/en/assets/1/event/21/Connector_J%20Performance%20Gems%20Presentation.pdf */
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
config.addDataSourceProperty("useServerPrepStmts", "true");
config.addDataSourceProperty("useLocalSessionState", "true");
config.addDataSourceProperty("rewriteBatchedStatements", "true");
config.addDataSourceProperty("cacheServerConfiguration", "true");
config.addDataSourceProperty("maintainTimeStats", "false");
/* Disable SSL to suppress the unverified server identity warning */
config.addDataSourceProperty("allowPublicKeyRetrieval", "true");
config.addDataSourceProperty("useSSL", "false");
ConfigHandler.hikariDataSource = new HikariDataSource(config);
}
Database.createDatabaseTables(ConfigHandler.prefix, false);
}
@@ -361,12 +396,18 @@ public class ConfigHandler extends Queue {
try {
BukkitAdapter.loadAdapter();
SpigotAdapter.loadAdapter();
PaperAdapter.loadAdapter();
BlockGroup.initialize();
ConfigHandler.loadConfig(); // Load (or create) the configuration file.
ConfigHandler.loadDatabase(); // Initialize MySQL and create tables if necessary.
Connection connection = Database.getConnection(true, 0);
}
catch (Exception e) {
e.printStackTrace();
}
try (Connection connection = Database.getConnection(true, 0)) {
Statement statement = connection.createStatement();
ConfigHandler.checkPlayers(connection);
@@ -394,7 +435,6 @@ public class ConfigHandler extends Queue {
}
statement.close();
connection.close();
return validVersion && databaseLock;
}
@@ -17,12 +17,11 @@ import net.coreprotect.consumer.process.Process;
public class Consumer extends Process implements Runnable, Thread.UncaughtExceptionHandler {
public static volatile boolean resetConnection = false;
private static Thread consumerThread = null;
public static volatile int currentConsumer = 0;
public static volatile boolean isPaused = false;
public static volatile boolean transacting = false;
public static volatile boolean interrupt = false;
private static volatile boolean running = false;
protected static volatile boolean pausedSuccess = false;
public static ConcurrentHashMap<Integer, ArrayList<Object[]>> consumer = new ConcurrentHashMap<>(4, 0.75f, 2);
@@ -96,19 +95,13 @@ public class Consumer extends Process implements Runnable, Thread.UncaughtExcept
}
public static boolean isRunning() {
return running;
return consumerThread != null && consumerThread.isAlive();
}
private static void pauseConsumer(int process_id) {
try {
while ((ConfigHandler.serverRunning || ConfigHandler.converterRunning) && (Consumer.isPaused || ConfigHandler.purgeRunning || Consumer.consumer_id.get(process_id)[1] == 1)) {
pausedSuccess = true;
if (Consumer.isPaused || ConfigHandler.purgeRunning) {
if (connection != null) {
connection.close();
connection = null;
}
}
Thread.sleep(100);
}
}
@@ -120,7 +113,6 @@ public class Consumer extends Process implements Runnable, Thread.UncaughtExcept
@Override
public void run() {
running = true;
boolean lastRun = false;
while (ConfigHandler.serverRunning || ConfigHandler.converterRunning || !lastRun) {
@@ -145,20 +137,17 @@ public class Consumer extends Process implements Runnable, Thread.UncaughtExcept
errorDelay();
}
}
running = false;
}
@Override
public void uncaughtException(Thread thread, Throwable e) {
running = false;
e.printStackTrace();
Bukkit.getPluginManager().disablePlugin(CoreProtect.getInstance());
}
public static void startConsumer() {
if (running == false) {
Thread consumerThread = new Thread(new Consumer());
if (!isRunning()) {
consumerThread = new Thread(new Consumer());
consumerThread.setUncaughtExceptionHandler(new Consumer());
consumerThread.start();
}
@@ -306,20 +306,20 @@ public class Queue {
queueStandardData(consumerId, currentConsumer, new String[] { user, null }, block);
}
protected static void queuePlayerChat(Player player, String message, int time) {
protected static void queuePlayerChat(Player player, String message, long timestamp) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.PLAYER_CHAT, null, 0, null, 0, time, null });
addConsumer(currentConsumer, new Object[] { consumerId, Process.PLAYER_CHAT, null, 0, null, 0, 0, null });
Consumer.consumerStrings.get(currentConsumer).put(consumerId, message);
queueStandardData(consumerId, currentConsumer, new String[] { player.getName(), null }, player.getLocation().clone());
queueStandardData(consumerId, currentConsumer, new String[] { player.getName(), null }, new Object[] { timestamp, player.getLocation().clone() });
}
protected static void queuePlayerCommand(Player player, String message, int time) {
protected static void queuePlayerCommand(Player player, String message, long timestamp) {
int currentConsumer = Consumer.currentConsumer;
int consumerId = Consumer.newConsumerId(currentConsumer);
addConsumer(currentConsumer, new Object[] { consumerId, Process.PLAYER_COMMAND, null, 0, null, 0, time, null });
addConsumer(currentConsumer, new Object[] { consumerId, Process.PLAYER_COMMAND, null, 0, null, 0, 0, null });
Consumer.consumerStrings.get(currentConsumer).put(consumerId, message);
queueStandardData(consumerId, currentConsumer, new String[] { player.getName(), null }, player.getLocation().clone());
queueStandardData(consumerId, currentConsumer, new String[] { player.getName(), null }, new Object[] { timestamp, player.getLocation().clone() });
}
protected static void queuePlayerInteraction(String user, BlockState block) {
@@ -8,7 +8,7 @@ import org.bukkit.entity.EntityType;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.EntityStatement;
import net.coreprotect.utility.Util;
import net.coreprotect.utility.entity.EntityUtil;
class EntitySpawnProcess {
@@ -18,7 +18,7 @@ class EntitySpawnProcess {
EntityType type = (EntityType) ((Object[]) object)[1];
String query = "SELECT data FROM " + ConfigHandler.prefix + "entity WHERE rowid='" + rowId + "' LIMIT 0, 1";
List<Object> data = EntityStatement.getData(statement, block, query);
Util.spawnEntity(block, type, data);
EntityUtil.spawnEntity(block, type, data);
}
}
}
@@ -2,14 +2,14 @@ package net.coreprotect.consumer.process;
import org.bukkit.block.BlockState;
import net.coreprotect.utility.Util;
import net.coreprotect.utility.entity.HangingUtil;
class HangingRemoveProcess {
static void process(Object object, int delay) {
if (object instanceof BlockState) {
BlockState block = (BlockState) object;
Util.removeHanging(block, delay);
HangingUtil.removeHanging(block, delay);
}
}
}
@@ -3,14 +3,14 @@ package net.coreprotect.consumer.process;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import net.coreprotect.utility.Util;
import net.coreprotect.utility.entity.HangingUtil;
class HangingSpawnProcess {
static void process(Object object, Material type, int data, int delay) {
if (object instanceof BlockState) {
BlockState block = (BlockState) object;
Util.spawnHanging(block, type, data, delay);
HangingUtil.spawnHanging(block, type, data, delay);
}
}
}
@@ -10,13 +10,19 @@ import net.coreprotect.database.logger.ChatLogger;
class PlayerChatProcess {
static void process(PreparedStatement preparedStmt, int batchCount, int processId, int id, Object object, int time, String user) {
if (object instanceof Location) {
static void process(PreparedStatement preparedStmt, int batchCount, int processId, int id, Object object, String user) {
if (!(object instanceof Object[])) {
return;
}
Object[] data = (Object[]) object;
if (data[1] instanceof Location) {
Map<Integer, String> strings = Consumer.consumerStrings.get(processId);
if (strings.get(id) != null) {
String message = strings.get(id);
Location location = (Location) object;
ChatLogger.log(preparedStmt, batchCount, time, location, user, message);
Long timestamp = (Long) data[0];
Location location = (Location) data[1];
ChatLogger.log(preparedStmt, batchCount, timestamp, location, user, message);
strings.remove(id);
}
}
@@ -10,13 +10,19 @@ import net.coreprotect.database.logger.CommandLogger;
class PlayerCommandProcess {
static void process(PreparedStatement preparedStmt, int batchCount, int processId, int id, Object object, int time, String user) {
if (object instanceof Location) {
static void process(PreparedStatement preparedStmt, int batchCount, int processId, int id, Object object, String user) {
if (!(object instanceof Object[])) {
return;
}
Object[] data = (Object[]) object;
if (data[1] instanceof Location) {
Map<Integer, String> strings = Consumer.consumerStrings.get(processId);
if (strings.get(id) != null) {
String message = strings.get(id);
Location location = (Location) object;
CommandLogger.log(preparedStmt, batchCount, time, location, user, message);
Long timestamp = (Long) data[0];
Location location = (Location) data[1];
CommandLogger.log(preparedStmt, batchCount, timestamp, location, user, message);
strings.remove(id);
}
}
@@ -45,36 +45,13 @@ public class Process {
public static final int BLOCKDATA_INSERT = 25;
public static final int ITEM_TRANSACTION = 26;
protected static Connection connection = null;
public static int lastLockUpdate = 0;
private static int lastConnection = 0;
private static volatile int currentConsumerSize = 0;
public static int getCurrentConsumerSize() {
return currentConsumerSize;
}
private static void validateConnection(boolean lastRun) {
try {
if (connection != null) {
int timeSinceLastConnection = ((int) (System.currentTimeMillis() / 1000L)) - lastConnection;
if ((!lastRun && timeSinceLastConnection > 900) || !connection.isValid(5) || Consumer.resetConnection) {
connection.close();
connection = null;
Consumer.resetConnection = false;
}
}
if (connection == null && ConfigHandler.serverRunning) {
connection = Database.getConnection(false, 500);
lastConnection = (int) (System.currentTimeMillis() / 1000L);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
protected static void updateLockTable(Statement statement, int locked) {
try {
int unixTimestamp = (int) (System.currentTimeMillis() / 1000L);
@@ -90,9 +67,7 @@ public class Process {
}
protected static void processConsumer(int processId, boolean lastRun) {
try {
// Connection
validateConnection(lastRun);
try (Connection connection = Database.getConnection(false, 500)) {
if (connection == null) {
return;
}
@@ -141,13 +116,13 @@ public class Process {
for (int i = 0; i < consumerDataSize; i++) {
Object[] data = consumerData.get(i);
if (data != null) {
int id = (Integer) data[0];
int action = (Integer) data[1];
int id = (int) data[0];
int action = (int) data[1];
Material blockType = (Material) data[2];
int blockData = (Integer) data[3];
Material replace_type = (Material) data[4];
int replaceData = (Integer) data[5];
int forceData = (Integer) data[6];
int blockData = (int) data[3];
Material replaceType = (Material) data[4];
int replaceData = (int) data[5];
int forceData = (int) data[6];
if (users.get(id) != null && consumerObject.get(id) != null) {
String user = users.get(id)[0];
@@ -156,10 +131,10 @@ public class Process {
try {
switch (action) {
case Process.BLOCK_BREAK:
BlockBreakProcess.process(preparedStmtBlocks, preparedStmtSkulls, i, processId, id, blockType, blockData, replace_type, forceData, user, object, (String) data[7]);
BlockBreakProcess.process(preparedStmtBlocks, preparedStmtSkulls, i, processId, id, blockType, blockData, replaceType, forceData, user, object, (String) data[7]);
break;
case Process.BLOCK_PLACE:
BlockPlaceProcess.process(preparedStmtBlocks, preparedStmtSkulls, i, blockType, blockData, replace_type, replaceData, forceData, user, object, (String) data[7], (String) data[8]);
BlockPlaceProcess.process(preparedStmtBlocks, preparedStmtSkulls, i, blockType, blockData, replaceType, replaceData, forceData, user, object, (String) data[7], (String) data[8]);
break;
case Process.SIGN_TEXT:
SignTextProcess.process(preparedStmtSigns, i, processId, id, forceData, user, object, replaceData, blockData);
@@ -195,10 +170,10 @@ public class Process {
SkullUpdateProcess.process(statement, object, forceData);
break;
case Process.PLAYER_CHAT:
PlayerChatProcess.process(preparedStmtChat, i, processId, id, object, forceData, user);
PlayerChatProcess.process(preparedStmtChat, i, processId, id, object, user);
break;
case Process.PLAYER_COMMAND:
PlayerCommandProcess.process(preparedStmtCommand, i, processId, id, object, forceData, user);
PlayerCommandProcess.process(preparedStmtCommand, i, processId, id, object, user);
break;
case Process.PLAYER_LOGIN:
PlayerLoginProcess.process(connection, preparedStmtSession, i, processId, id, object, blockData, replaceData, forceData, user);
@@ -243,7 +218,6 @@ public class Process {
for (int index = (i - 1); index >= 0; index--) {
consumerData.remove(index);
}
connection = null;
currentConsumerSize = 0;
Consumer.isPaused = false;
return;
@@ -288,11 +262,6 @@ public class Process {
users.clear();
consumerObject.clear();
consumerData.clear();
if (lastRun) {
connection.close();
connection = null;
}
}
catch (Exception e) {
e.printStackTrace();
@@ -24,7 +24,7 @@ import net.coreprotect.utility.Util;
public class ContainerRollback extends Queue {
public static void performContainerRollbackRestore(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, String timeString, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, final Location location, Integer[] radius, int checkTime, boolean restrictWorld, boolean lookup, boolean verbose, final int rollbackType) {
public static void performContainerRollbackRestore(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, String timeString, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, final Location location, Integer[] radius, long checkTime, boolean restrictWorld, boolean lookup, boolean verbose, final int rollbackType) {
try {
long startTime = System.currentTimeMillis();
@@ -138,15 +138,7 @@ public class Database extends Queue {
}
if (Config.getGlobal().MYSQL) {
try {
/* Using useServerPrepStmts, cachePrepStmts, and rewriteBatchedStatements per https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration */
String database = "jdbc:mysql://" + ConfigHandler.host + ":" + ConfigHandler.port + "/" + ConfigHandler.database + "?useUnicode=true&characterEncoding=utf-8&connectTimeout=10000&useSSL=false&allowPublicKeyRetrieval=true&useCursorFetch=true&useLocalSessionState=true&rewriteBatchedStatements=true&maintainTimeStats=false";
connection = DriverManager.getConnection(database, ConfigHandler.username, ConfigHandler.password);
/* Recommended implementation per https://dev.mysql.com/doc/refman/5.0/en/charset-applications.html & https://dev.mysql.com/doc/refman/5.0/en/charset-syntax.html */
Statement statement = connection.createStatement();
statement.executeUpdate("SET NAMES 'utf8mb4'"); // COLLATE 'utf8mb4mb4_general_ci'
statement.close();
connection = ConfigHandler.hikariDataSource.getConnection();
ConfigHandler.databaseReachable = true;
}
catch (Exception e) {
@@ -183,6 +175,18 @@ public class Database extends Queue {
return connection;
}
public static void closeConnection() {
try {
if (ConfigHandler.hikariDataSource != null) {
ConfigHandler.hikariDataSource.close();
ConfigHandler.hikariDataSource = null;
}
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void performUpdate(Statement statement, long id, int action, int table) {
try {
int rolledBack = 1;
@@ -316,8 +320,7 @@ public class Database extends Queue {
if (Config.getGlobal().MYSQL) {
boolean success = false;
try {
Connection connection = Database.getConnection(true, true, true, 0);
try (Connection connection = Database.getConnection(true, true, true, 0)) {
if (connection != null) {
String index = "";
Statement statement = connection.createStatement();
@@ -357,7 +360,6 @@ public class Database extends Queue {
initializeTables(prefix, statement);
}
statement.close();
connection.close();
success = true;
}
}
@@ -369,8 +371,7 @@ public class Database extends Queue {
}
}
if (!Config.getGlobal().MYSQL) {
try {
Connection connection = Database.getConnection(true, 0);
try (Connection connection = Database.getConnection(true, 0)) {
Statement statement = connection.createStatement();
List<String> tableData = new ArrayList<>();
List<String> indexData = new ArrayList<>();
@@ -553,7 +554,6 @@ public class Database extends Queue {
initializeTables(prefix, statement);
}
statement.close();
connection.close();
}
catch (Exception e) {
e.printStackTrace();
@@ -75,7 +75,7 @@ public class Lookup extends Queue {
return newList;
}
public static int countLookupRows(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, int checkTime, boolean restrictWorld, boolean lookup) {
public static int countLookupRows(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, long checkTime, boolean restrictWorld, boolean lookup) {
int rows = 0;
try {
@@ -99,7 +99,7 @@ public class Lookup extends Queue {
return rows;
}
public static List<String[]> performLookup(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, int checkTime, boolean restrictWorld, boolean lookup) {
public static List<String[]> performLookup(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, long checkTime, boolean restrictWorld, boolean lookup) {
List<String[]> newList = new ArrayList<>();
try {
@@ -113,7 +113,7 @@ public class Lookup extends Queue {
return newList;
}
static List<Object[]> performLookupRaw(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, int checkTime, int limitOffset, int limitCount, boolean restrictWorld, boolean lookup) {
static List<Object[]> performLookupRaw(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, long checkTime, int limitOffset, int limitCount, boolean restrictWorld, boolean lookup) {
List<Object[]> list = new ArrayList<>();
List<Integer> invalidRollbackActions = new ArrayList<>();
invalidRollbackActions.add(2);
@@ -256,7 +256,7 @@ public class Lookup extends Queue {
return list;
}
public static List<String[]> performPartialLookup(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, int checkTime, int limitOffset, int limitCount, boolean restrictWorld, boolean lookup) {
public static List<String[]> performPartialLookup(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, long checkTime, int limitOffset, int limitCount, boolean restrictWorld, boolean lookup) {
List<String[]> newList = new ArrayList<>();
try {
@@ -270,7 +270,7 @@ public class Lookup extends Queue {
return newList;
}
private static ResultSet rawLookupResultSet(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, int checkTime, int limitOffset, int limitCount, boolean restrictWorld, boolean lookup, boolean count) {
private static ResultSet rawLookupResultSet(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, long checkTime, int limitOffset, int limitCount, boolean restrictWorld, boolean lookup, boolean count) {
ResultSet results = null;
try {
@@ -484,15 +484,15 @@ public class Lookup extends Queue {
}
if (radius != null) {
int xmin = radius[1];
int xmax = radius[2];
int ymin = radius[3];
int ymax = radius[4];
int zmin = radius[5];
int zmax = radius[6];
Integer xmin = radius[1];
Integer xmax = radius[2];
Integer ymin = radius[3];
Integer ymax = radius[4];
Integer zmin = radius[5];
Integer zmax = radius[6];
String queryY = "";
if (ymin > -1 && ymax > -1) {
if (ymin != null && ymax != null) {
queryY = " y >= '" + ymin + "' AND y <= '" + ymax + "' AND";
}
@@ -559,7 +559,7 @@ public class Lookup extends Queue {
queryEntity = queryEntity.replace("type NOT IN(" + (excludeBlock.length() > 0 ? excludeBlock : "0") + ")", "type NOT IN(" + (excludeEntity.length() > 0 ? excludeEntity : "0") + ")");
}
String baseQuery = (includeEntity.length() > 0 ? queryEntity : queryBlock);
String baseQuery = ((!includeEntity.isEmpty() || !excludeEntity.isEmpty()) ? queryEntity : queryBlock);
if (limitOffset > -1 && limitCount > -1) {
queryLimit = " LIMIT " + limitOffset + ", " + limitCount + "";
}
@@ -48,6 +48,7 @@ import org.bukkit.block.data.type.PistonHead;
import org.bukkit.block.data.type.RedstoneWire;
import org.bukkit.block.data.type.Snow;
import org.bukkit.block.data.type.Stairs;
import org.bukkit.block.data.type.TechnicalPiston;
import org.bukkit.block.data.type.TrapDoor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.ArmorStand;
@@ -83,11 +84,12 @@ import net.coreprotect.thread.CacheHandler;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.ChestTool;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Teleport;
import net.coreprotect.utility.Util;
public class Rollback extends Queue {
public static List<String[]> performRollbackRestore(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, String timeString, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, int checkTime, boolean restrictWorld, boolean lookup, boolean verbose, final int rollbackType, final int preview) {
public static List<String[]> performRollbackRestore(Statement statement, CommandSender user, List<String> checkUuids, List<String> checkUsers, String timeString, List<Object> restrictList, List<Object> excludeList, List<String> excludeUserList, List<Integer> actionList, Location location, Integer[] radius, long checkTime, boolean restrictWorld, boolean lookup, boolean verbose, final int rollbackType, final int preview) {
List<String[]> list = new ArrayList<>();
try {
@@ -480,7 +482,7 @@ public class Rollback extends Queue {
Block block = location1.getBlock();
Material blockType = block.getType();
if (!BukkitAdapter.ADAPTER.isItemFrame(blockType) && !blockType.equals(Material.PAINTING) && !blockType.equals(Material.ARMOR_STAND)) {
Util.sendBlockChange(player, location1, blockType, block.getBlockData());
Util.sendBlockChange(player, location1, block.getBlockData());
blockCount1++;
}
}
@@ -490,7 +492,7 @@ public class Rollback extends Queue {
if (sendBlockData == null) {
sendBlockData = rowType.createBlockData();
}
Util.sendBlockChange(player, location1, rowType, sendBlockData);
Util.sendBlockChange(player, location1, sendBlockData);
blockCount1++;
}
}
@@ -685,6 +687,12 @@ public class Rollback extends Queue {
pistonBlock.setBlockData(piston, false);
}
}
else if (rowType == Material.MOVING_PISTON && blockData instanceof TechnicalPiston && !(blockData instanceof PistonHead)) {
TechnicalPiston technicalPiston = (TechnicalPiston) blockData;
rowType = (technicalPiston.getType() == org.bukkit.block.data.type.TechnicalPiston.Type.STICKY ? Material.STICKY_PISTON : Material.PISTON);
blockData = rowType.createBlockData();
((Piston) blockData).setFacing(technicalPiston.getFacing());
}
if ((rowType == Material.AIR) && ((BukkitAdapter.ADAPTER.isItemFrame(oldTypeMaterial)) || (oldTypeMaterial == Material.PAINTING))) {
int delay = Util.getHangingDelay(hangingDelay, rowWorldId, rowX, rowY, rowZ);
@@ -1041,8 +1049,11 @@ public class Rollback extends Queue {
else if (rowType != changeType && (BlockGroup.CONTAINERS.contains(rowType) || BlockGroup.CONTAINERS.contains(changeType))) {
block.setType(Material.AIR); // Clear existing container to prevent errors
boolean update = (blockData instanceof Chest);
Util.setTypeAndData(block, rowType, blockData, update);
boolean isChest = (blockData instanceof Chest);
Util.setTypeAndData(block, rowType, blockData, (isChest));
if (isChest) {
ChestTool.updateDoubleChest(block, blockData, false);
}
if (countBlock) {
blockCount1++;
@@ -1050,7 +1061,7 @@ public class Rollback extends Queue {
}
else if (BlockGroup.UPDATE_STATE.contains(rowType) || rowType.name().contains("CANDLE")) {
Util.setTypeAndData(block, rowType, blockData, true);
ChestTool.updateDoubleChest(block, blockData);
ChestTool.updateDoubleChest(block, blockData, true);
if (countBlock) {
blockCount1++;
}
@@ -1086,6 +1097,7 @@ public class Rollback extends Queue {
if (blockData instanceof MultipleFacing || BukkitAdapter.ADAPTER.isWall(blockData) || blockData instanceof Snow || blockData instanceof Stairs || blockData instanceof RedstoneWire || blockData instanceof Chest) {
physics = !(blockData instanceof Snow) || block.getY() <= BukkitAdapter.ADAPTER.getMinHeight(block.getWorld()) || (block.getWorld().getBlockAt(block.getX(), block.getY() - 1, block.getZ()).getType().equals(Material.GRASS_BLOCK));
}
Util.setTypeAndData(block, rowType, blockData, physics);
if (countBlock) {
blockCount1++;
@@ -1216,7 +1228,7 @@ public class Rollback extends Queue {
int chunkZ = playerLocation.getBlockZ() >> 4;
if (chunkX == finalChunkX && chunkZ == finalChunkZ) {
Util.performSafeTeleport(player, playerLocation, false);
Teleport.performSafeTeleport(player, playerLocation, false);
}
}
}
@@ -7,13 +7,20 @@ import java.util.Locale;
import org.bukkit.Location;
import org.bukkit.Material;
import net.coreprotect.CoreProtect;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.BlockStatement;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.event.CoreProtectPreLogEvent;
import net.coreprotect.thread.CacheHandler;
import net.coreprotect.utility.Util;
public class BlockBreakLogger {
private BlockBreakLogger() {
throw new IllegalStateException("Database class");
}
public static void log(PreparedStatement preparedStmt, int batchCount, String user, Location location, int type, int data, List<Object> meta, String blockData) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || location == null) {
@@ -36,13 +43,16 @@ public class BlockBreakLogger {
blockData = blockData.replaceFirst("has_book=true", "has_book=false");
}
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
int wid = Util.getWorldId(location.getWorld().getName());
int time = (int) (System.currentTimeMillis() / 1000L);
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
CacheHandler.breakCache.put("" + x + "." + y + "." + z + "." + wid + "", new Object[] { time, user, type });
int userId = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
CacheHandler.breakCache.put("" + x + "." + y + "." + z + "." + wid + "", new Object[] { time, event.getUser(), type });
BlockStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, type, data, meta, blockData, 0, 0);
}
catch (Exception e) {
@@ -12,15 +12,22 @@ import org.bukkit.block.data.type.Bed;
import org.bukkit.block.data.type.Door;
import org.bukkit.block.data.type.Door.Hinge;
import net.coreprotect.CoreProtect;
import net.coreprotect.bukkit.BukkitAdapter;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.BlockStatement;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.event.CoreProtectPreLogEvent;
import net.coreprotect.model.BlockGroup;
import net.coreprotect.thread.CacheHandler;
import net.coreprotect.utility.Util;
public class BlockPlaceLogger {
private BlockPlaceLogger() {
throw new IllegalStateException("Database class");
}
public static void log(PreparedStatement preparedStmt, int batchCount, String user, BlockState block, int replacedType, int replacedData, Material forceType, int forceData, boolean force, List<Object> meta, String blockData, String replaceBlockData) {
try {
if (user == null || ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
@@ -51,7 +58,11 @@ public class BlockPlaceLogger {
if (type.equals(Material.AIR) || type.equals(Material.CAVE_AIR)) {
return;
}
int userId = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
int wid = Util.getWorldId(block.getWorld().getName());
int time = (int) (System.currentTimeMillis() / 1000L);
int x = block.getX();
@@ -64,8 +75,8 @@ public class BlockPlaceLogger {
int doubledata = data;
int logdouble = 0;
if (user.length() > 0) {
CacheHandler.lookupCache.put("" + x + "." + y + "." + z + "." + wid + "", new Object[] { time, user, type });
if (event.getUser().length() > 0) {
CacheHandler.lookupCache.put("" + x + "." + y + "." + z + "." + wid + "", new Object[] { time, event.getUser(), type });
}
String doubleBlockData = null;
@@ -11,7 +11,11 @@ import net.coreprotect.utility.Util;
public class ChatLogger {
public static void log(PreparedStatement preparedStmt, int batchCount, int time, Location location, String user, String message) {
private ChatLogger() {
throw new IllegalStateException("Database class");
}
public static void log(PreparedStatement preparedStmt, int batchCount, long time, Location location, String user, String message) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
@@ -5,13 +5,20 @@ import java.util.Locale;
import org.bukkit.Location;
import net.coreprotect.CoreProtect;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.CommandStatement;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.event.CoreProtectPreLogEvent;
import net.coreprotect.utility.Util;
public class CommandLogger {
public static void log(PreparedStatement preparedStmt, int batchCount, int time, Location location, String user, String message) {
private CommandLogger() {
throw new IllegalStateException("Database class");
}
public static void log(PreparedStatement preparedStmt, int batchCount, long time, Location location, String user, String message) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
@@ -19,11 +26,15 @@ public class CommandLogger {
if (ConfigHandler.blacklist.get(((message + " ").split(" "))[0].toLowerCase(Locale.ROOT)) != null) {
return;
}
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
int wid = Util.getWorldId(location.getWorld().getName());
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
int wid = Util.getWorldId(location.getWorld().getName());
int userId = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
CommandStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, message);
}
catch (Exception e) {
@@ -12,6 +12,10 @@ import net.coreprotect.utility.Util;
public class ContainerBreakLogger {
private ContainerBreakLogger() {
throw new IllegalStateException("Database class");
}
public static void log(PreparedStatement preparedStmt, int batchCount, String player, Location l, Material type, ItemStack[] oldInventory) {
try {
Util.mergeItems(type, oldInventory);
@@ -13,14 +13,21 @@ import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import net.coreprotect.CoreProtect;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Queue;
import net.coreprotect.database.statement.ContainerStatement;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.event.CoreProtectPreLogEvent;
import net.coreprotect.utility.Util;
import net.coreprotect.utility.serialize.ItemMetaHandler;
public class ContainerLogger extends Queue {
private ContainerLogger() {
throw new IllegalStateException("Database class");
}
public static void log(PreparedStatement preparedStmtContainer, PreparedStatement preparedStmtItems, int batchCount, String player, Material type, Object container, Location location) {
try {
ItemStack[] contents = null;
@@ -46,10 +53,14 @@ public class ContainerLogger extends Queue {
ItemStack[] oi1 = oldList.get(0);
ItemStack[] oldInventory = Util.getContainerState(oi1);
ItemStack[] newInventory = Util.getContainerState(contents);
if (ConfigHandler.forceContainer.get(loggingContainerId) != null) {
List<ItemStack[]> forceList = ConfigHandler.forceContainer.get(loggingContainerId);
newInventory = Util.getContainerState(forceList.get(0));
int forceSize = modifyForceContainer(loggingContainerId, null);
List<ItemStack[]> forceList = ConfigHandler.forceContainer.get(loggingContainerId);
if (forceList != null) {
int forceSize = 0;
if (!forceList.isEmpty()) {
newInventory = Util.getContainerState(forceList.get(0));
forceSize = modifyForceContainer(loggingContainerId, null);
}
if (forceSize == 0) {
ConfigHandler.forceContainer.remove(loggingContainerId);
}
@@ -153,8 +164,11 @@ public class ContainerLogger extends Queue {
metadata = null;
}
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
int wid = Util.getWorldId(location.getWorld().getName());
int userid = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
int time = (int) (System.currentTimeMillis() / 1000L);
int x = location.getBlockX();
int y = location.getBlockY();
@@ -162,7 +176,7 @@ public class ContainerLogger extends Queue {
int typeId = Util.getBlockId(item.getType().name(), true);
int data = item.getDurability();
int amount = item.getAmount();
ContainerStatement.insert(preparedStmt, batchCount, time, userid, wid, x, y, z, typeId, data, amount, metadata, action, 0);
ContainerStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, typeId, data, amount, metadata, action, 0);
}
}
slot++;
@@ -7,30 +7,41 @@ import java.util.Locale;
import org.bukkit.block.BlockState;
import net.coreprotect.CoreProtect;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.BlockStatement;
import net.coreprotect.database.statement.EntityStatement;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.event.CoreProtectPreLogEvent;
import net.coreprotect.utility.Util;
public class EntityKillLogger {
private EntityKillLogger() {
throw new IllegalStateException("Database class");
}
public static void log(PreparedStatement preparedStmt, PreparedStatement preparedStmt2, int batchCount, String user, BlockState block, List<Object> data, int type) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
}
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
int wid = Util.getWorldId(block.getWorld().getName());
int time = (int) (System.currentTimeMillis() / 1000L);
int x = block.getX();
int y = block.getY();
int z = block.getZ();
int userid = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
EntityStatement.insert(preparedStmt2, time, data);
ResultSet keys = preparedStmt2.getGeneratedKeys();
keys.next();
int entity_key = keys.getInt(1);
keys.close();
BlockStatement.insert(preparedStmt, batchCount, time, userid, wid, x, y, z, type, entity_key, null, null, 3, 0);
BlockStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, type, entity_key, null, null, 3, 0);
}
catch (Exception e) {
e.printStackTrace();
@@ -9,8 +9,11 @@ import java.util.Map;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import net.coreprotect.CoreProtect;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.ItemStatement;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.event.CoreProtectPreLogEvent;
import net.coreprotect.utility.Util;
import net.coreprotect.utility.serialize.ItemMetaHandler;
@@ -23,6 +26,10 @@ public class ItemLogger {
public static final int ITEM_REMOVE_ENDER = 4;
public static final int ITEM_ADD_ENDER = 5;
private ItemLogger() {
throw new IllegalStateException("Database class");
}
public static void log(PreparedStatement preparedStmt, int batchCount, Location location, String user) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
@@ -61,15 +68,18 @@ public class ItemLogger {
data = null;
}
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
int wid = Util.getWorldId(location.getWorld().getName());
int userid = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
int time = (int) (System.currentTimeMillis() / 1000L);
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
int typeId = Util.getBlockId(item.getType().name(), true);
int amount = item.getAmount();
ItemStatement.insert(preparedStmt, batchCount, time, userid, wid, x, y, z, typeId, data, amount, action);
ItemStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, typeId, data, amount, action);
}
}
}
@@ -6,20 +6,31 @@ import java.util.Locale;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import net.coreprotect.CoreProtect;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.BlockStatement;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.event.CoreProtectPreLogEvent;
import net.coreprotect.utility.Util;
public class PlayerInteractLogger {
private PlayerInteractLogger() {
throw new IllegalStateException("Database class");
}
public static void log(PreparedStatement preparedStmt, int batchCount, String user, BlockState block) {
try {
int type = Util.getBlockId(block.getType().name(), true);
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || Util.getType(type).equals(Material.AIR) || Util.getType(type).equals(Material.CAVE_AIR)) {
return;
}
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
int wid = Util.getWorldId(block.getWorld().getName());
int userId = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
int time = (int) (System.currentTimeMillis() / 1000L);
int x = block.getX();
int y = block.getY();
@@ -5,28 +5,35 @@ import java.util.Locale;
import org.bukkit.block.BlockState;
import net.coreprotect.CoreProtect;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.BlockStatement;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.event.CoreProtectPreLogEvent;
import net.coreprotect.utility.Util;
public class PlayerKillLogger {
private PlayerKillLogger() {
throw new IllegalStateException("Database class");
}
public static void log(PreparedStatement preparedStmt, int batchCount, String user, BlockState block, String player) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
}
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
int playerId = ConfigHandler.playerIdCache.get(player.toLowerCase(Locale.ROOT));
int wid = Util.getWorldId(block.getWorld().getName());
int time = (int) (System.currentTimeMillis() / 1000L);
int x = block.getX();
int y = block.getY();
int z = block.getZ();
int userId = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
if (ConfigHandler.playerIdCache.get(player.toLowerCase(Locale.ROOT)) == null) {
UserStatement.loadId(preparedStmt.getConnection(), player, null);
}
int playerId = ConfigHandler.playerIdCache.get(player.toLowerCase(Locale.ROOT));
BlockStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, 0, playerId, null, null, 3, 0);
}
catch (Exception e) {
@@ -11,6 +11,10 @@ import net.coreprotect.utility.Util;
public class PlayerSessionLogger {
private PlayerSessionLogger() {
throw new IllegalStateException("Database class");
}
public static void log(PreparedStatement preparedStmt, int batchCount, String user, Location location, int time, int action) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
@@ -5,18 +5,29 @@ import java.util.Locale;
import org.bukkit.Location;
import net.coreprotect.CoreProtect;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.SignStatement;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.event.CoreProtectPreLogEvent;
import net.coreprotect.utility.Util;
public class SignTextLogger {
private SignTextLogger() {
throw new IllegalStateException("Database class");
}
public static void log(PreparedStatement preparedStmt, int batchCount, String user, Location location, int action, int color, int data, String line1, String line2, String line3, String line4, int timeOffset) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
}
int userId = ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
int wid = Util.getWorldId(location.getWorld().getName());
int time = (int) (System.currentTimeMillis() / 1000L) - timeOffset;
int x = location.getBlockX();
@@ -13,6 +13,10 @@ import net.coreprotect.utility.Util;
public class SkullBreakLogger {
private SkullBreakLogger() {
throw new IllegalStateException("Database class");
}
public static void log(PreparedStatement preparedStmt, PreparedStatement preparedStmt2, int batchCount, String user, BlockState block) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || block == null) {
@@ -13,6 +13,10 @@ import net.coreprotect.database.statement.SkullStatement;
public class SkullPlaceLogger {
private SkullPlaceLogger() {
throw new IllegalStateException("Database class");
}
public static void log(PreparedStatement preparedStmt, PreparedStatement preparedStmt2, int batchCount, String user, BlockState block, int replaceType, int replaceData) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || block == null) {
@@ -9,6 +9,10 @@ import net.coreprotect.config.ConfigHandler;
public class UsernameLogger {
private UsernameLogger() {
throw new IllegalStateException("Database class");
}
public static void log(Connection connection, String user, String uuid, int configUsernames, int time) {
try {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
@@ -12,7 +12,6 @@ import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
@@ -45,9 +44,9 @@ public class BlockLookup {
int x = block.getX();
int y = block.getY();
int z = block.getZ();
int time = (int) (System.currentTimeMillis() / 1000L);
long time = (System.currentTimeMillis() / 1000L);
int worldId = Util.getWorldId(block.getWorld().getName());
int checkTime = 0;
long checkTime = 0;
int count = 0;
int rowMax = page * limit;
int page_start = rowMax - limit;
@@ -75,7 +74,7 @@ public class BlockLookup {
int resultAction = results.getInt("action");
int resultType = results.getInt("type");
int resultData = results.getInt("data");
int resultTime = results.getInt("time");
long resultTime = results.getLong("time");
int resultRolledBack = results.getInt("rolled_back");
if (ConfigHandler.playerIdCacheReversed.get(resultUserId) == null) {
@@ -18,7 +18,7 @@ public class BlockLookupAPI {
public static List<String[]> performLookup(Block block, int offset) {
List<String[]> result = new ArrayList<>();
try {
try (Connection connection = Database.getConnection(false, 1000)) {
if (block == null) {
return result;
}
@@ -33,7 +33,6 @@ public class BlockLookupAPI {
checkTime = time - offset;
}
Connection connection = Database.getConnection(false, 1000);
if (connection == null) {
return result;
}
@@ -62,7 +61,6 @@ public class BlockLookupAPI {
}
results.close();
statement.close();
connection.close();
}
catch (Exception e) {
e.printStackTrace();
@@ -12,7 +12,6 @@ import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
@@ -48,7 +47,7 @@ public class ChestTransactionLookup {
int x2 = (int) Math.ceil(l.getX());
int y2 = (int) Math.ceil(l.getY());
int z2 = (int) Math.ceil(l.getZ());
int time = (int) (System.currentTimeMillis() / 1000L);
long time = (System.currentTimeMillis() / 1000L);
int worldId = Util.getWorldId(l.getWorld().getName());
int count = 0;
int rowMax = page * limit;
@@ -79,7 +78,7 @@ public class ChestTransactionLookup {
int resultAction = results.getInt("action");
int resultType = results.getInt("type");
int resultData = results.getInt("data");
int resultTime = results.getInt("time");
long resultTime = results.getLong("time");
int resultAmount = results.getInt("amount");
int resultRolledBack = results.getInt("rolled_back");
@@ -12,7 +12,6 @@ import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
@@ -73,7 +72,7 @@ public class InteractionLookup {
int resultAction = results.getInt("action");
int resultType = results.getInt("type");
int resultData = results.getInt("data");
int resultTime = results.getInt("time");
long resultTime = results.getLong("time");
int resultRolledBack = results.getInt("rolled_back");
if (ConfigHandler.playerIdCacheReversed.get(resultUserId) == null) {
@@ -44,7 +44,7 @@ public class SignMessageLookup {
int x = l.getBlockX();
int y = l.getBlockY();
int z = l.getBlockZ();
int time = (int) (System.currentTimeMillis() / 1000L);
long time = (System.currentTimeMillis() / 1000L);
int worldId = Util.getWorldId(l.getWorld().getName());
int count = 0;
int rowMax = page * limit;
@@ -64,7 +64,7 @@ public class SignMessageLookup {
results = statement.executeQuery(query);
while (results.next()) {
int resultTime = results.getInt("time");
long resultTime = results.getLong("time");
int resultUserId = results.getInt("user");
String line1 = results.getString("line_1");
String line2 = results.getString("line_2");
@@ -7,6 +7,10 @@ import net.coreprotect.utility.Util;
public class BlockStatement {
private BlockStatement() {
throw new IllegalStateException("Database class");
}
public static void insert(PreparedStatement preparedStmt, int batchCount, int time, int id, int wid, int x, int y, int z, int type, int data, List<Object> meta, String blockData, int action, int rolledBack) {
try {
byte[] bBlockData = Util.stringToByteData(blockData, type);
@@ -4,9 +4,13 @@ import java.sql.PreparedStatement;
public class ChatStatement {
public static void insert(PreparedStatement preparedStmt, int batchCount, int time, int user, int wid, int x, int y, int z, String message) {
private ChatStatement() {
throw new IllegalStateException("Database class");
}
public static void insert(PreparedStatement preparedStmt, int batchCount, long time, int user, int wid, int x, int y, int z, String message) {
try {
preparedStmt.setInt(1, time);
preparedStmt.setLong(1, time);
preparedStmt.setInt(2, user);
preparedStmt.setInt(3, wid);
preparedStmt.setInt(4, x);
@@ -4,9 +4,13 @@ import java.sql.PreparedStatement;
public class CommandStatement {
public static void insert(PreparedStatement preparedStmt, int batchCount, int time, int user, int wid, int x, int y, int z, String message) {
private CommandStatement() {
throw new IllegalStateException("Database class");
}
public static void insert(PreparedStatement preparedStmt, int batchCount, long time, int user, int wid, int x, int y, int z, String message) {
try {
preparedStmt.setInt(1, time);
preparedStmt.setLong(1, time);
preparedStmt.setInt(2, user);
preparedStmt.setInt(3, wid);
preparedStmt.setInt(4, x);
@@ -6,6 +6,10 @@ import net.coreprotect.utility.Util;
public class ContainerStatement {
private ContainerStatement() {
throw new IllegalStateException("Database class");
}
public static void insert(PreparedStatement preparedStmt, int batchCount, int time, int id, int wid, int x, int y, int z, int type, int data, int amount, Object metadata, int action, int rolledBack) {
try {
byte[] byteData = Util.convertByteData(metadata);
@@ -14,6 +14,10 @@ import org.bukkit.util.io.BukkitObjectOutputStream;
public class EntityStatement {
private EntityStatement() {
throw new IllegalStateException("Database class");
}
public static void insert(PreparedStatement preparedStmt, int time, List<Object> data) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
@@ -6,6 +6,10 @@ import net.coreprotect.utility.Util;
public class ItemStatement {
private ItemStatement() {
throw new IllegalStateException("Database class");
}
public static void insert(PreparedStatement preparedStmt, int batchCount, int time, int id, int wid, int x, int y, int z, int type, Object data, int amount, int action) {
try {
byte[] byteData = Util.convertByteData(data);
@@ -6,6 +6,10 @@ import java.sql.Statement;
public class MaterialStatement {
private MaterialStatement() {
throw new IllegalStateException("Database class");
}
public static void insert(PreparedStatement preparedStmt, int batchCount, int id, String name) {
try {
preparedStmt.setInt(1, id);
@@ -4,6 +4,10 @@ import java.sql.PreparedStatement;
public class SessionStatement {
private SessionStatement() {
throw new IllegalStateException("Database class");
}
public static void insert(PreparedStatement preparedStmt, int batchCount, int time, int user, int wid, int x, int y, int z, int action) {
try {
preparedStmt.setInt(1, time);
@@ -13,6 +13,10 @@ import net.coreprotect.bukkit.BukkitAdapter;
public class SignStatement {
private SignStatement() {
throw new IllegalStateException("Database class");
}
public static void insert(PreparedStatement preparedStmt, int batchCount, int time, int id, int wid, int x, int y, int z, int action, int color, int data, String line1, String line2, String line3, String line4) {
try {
preparedStmt.setInt(1, time);
@@ -11,6 +11,10 @@ import org.bukkit.block.Skull;
public class SkullStatement {
private SkullStatement() {
throw new IllegalStateException("Database class");
}
public static void insert(PreparedStatement preparedStmt, int time, String owner) {
try {
preparedStmt.setInt(1, time);
@@ -3,6 +3,7 @@ package net.coreprotect.database.statement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Locale;
@@ -11,6 +12,10 @@ import net.coreprotect.config.ConfigHandler;
public class UserStatement {
private UserStatement() {
throw new IllegalStateException("Database class");
}
public static int insert(Connection connection, String user) {
int id = -1;
@@ -32,6 +37,14 @@ public class UserStatement {
return id;
}
public static int getId(PreparedStatement preparedStatement, String user, boolean load) throws SQLException {
if (load && !ConfigHandler.playerIdCache.containsKey(user.toLowerCase(Locale.ROOT))) {
UserStatement.loadId(preparedStatement.getConnection(), user, null);
}
return ConfigHandler.playerIdCache.get(user.toLowerCase(Locale.ROOT));
}
public static int loadId(Connection connection, String user, String uuid) {
// generate if doesn't exist
int id = -1;
@@ -4,6 +4,10 @@ import java.sql.PreparedStatement;
public class WorldStatement {
private WorldStatement() {
throw new IllegalStateException("Database class");
}
public static void insert(PreparedStatement preparedStmt, int batchCount, int id, String world) {
try {
preparedStmt.setInt(1, id);
@@ -0,0 +1,37 @@
package net.coreprotect.event;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class CoreProtectPreLogEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private String user;
public CoreProtectPreLogEvent(String user) {
super(true); // async
this.user = user;
}
public String getUser() {
return user;
}
public void setUser(String newUser) {
if (newUser == null || newUser.isEmpty()) {
throw new IllegalArgumentException("Invalid user");
}
this.user = newUser;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}
@@ -15,6 +15,10 @@ public class Selector {
final protected static Set<String> SELECTORS = new HashSet<>(Arrays.asList(Selector.FIRST, Selector.SECOND, Selector.THIRD, Selector.FOURTH));
private Selector() {
throw new IllegalStateException("Utility class");
}
protected static String processSelection(String output, String param, String color) {
String substring = output;
try {
@@ -45,6 +45,7 @@ import net.coreprotect.listener.player.SignChangeListener;
import net.coreprotect.listener.world.LeavesDecayListener;
import net.coreprotect.listener.world.PortalCreateListener;
import net.coreprotect.listener.world.StructureGrowListener;
import net.coreprotect.paper.listener.PaperChatListener;
public final class ListenerHandler {
@@ -85,7 +86,6 @@ public final class ListenerHandler {
pluginManager.registerEvents(new ArmorStandManipulateListener(), plugin);
pluginManager.registerEvents(new PlayerBucketEmptyListener(), plugin);
pluginManager.registerEvents(new PlayerBucketFillListener(), plugin);
pluginManager.registerEvents(new PlayerChatListener(), plugin);
pluginManager.registerEvents(new PlayerCommandListener(), plugin);
pluginManager.registerEvents(new PlayerDeathListener(), plugin);
pluginManager.registerEvents(new PlayerDropItemListener(), plugin);
@@ -101,6 +101,16 @@ public final class ListenerHandler {
pluginManager.registerEvents(new StructureGrowListener(), plugin);
pluginManager.registerEvents(new LeavesDecayListener(), plugin);
pluginManager.registerEvents(new PortalCreateListener(), plugin);
// Paper Listeners / Fallbacks
try {
Class.forName("net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer");
pluginManager.registerEvents(new PaperChatListener(), plugin);
}
catch (Exception e) {
pluginManager.registerEvents(new PlayerChatListener(), plugin);
}
}
}
@@ -204,7 +204,7 @@ public final class BlockBreakListener extends Queue implements Listener {
}
}
if (!log) {
if (type.equals(Material.MOVING_PISTON)) {// broke a piston extension
if (type.equals(Material.PISTON_HEAD)) {// broke a piston extension
if (scanType.equals(Material.STICKY_PISTON) || scanType.equals(Material.PISTON)) { // adjacent piston
log = true;
}
@@ -218,7 +218,7 @@ public final class BlockBreakListener extends Queue implements Listener {
}
else {
// determine if side block is attached
if (scanType.equals(Material.MOVING_PISTON)) {
if (scanType.equals(Material.PISTON_HEAD)) {
if (!type.equals(Material.STICKY_PISTON) && !type.equals(Material.PISTON)) {
log = false;
}
@@ -29,10 +29,10 @@ import net.coreprotect.model.BlockGroup;
public class BlockExplodeListener extends Queue implements Listener {
protected static void processBlockExplode(String user, World world, List<Block> b) {
protected static void processBlockExplode(String user, World world, List<Block> blockList) {
HashMap<Location, Block> blockMap = new HashMap<>();
for (Block block : b) {
for (Block block : blockList) {
blockMap.put(block.getLocation(), block);
}
@@ -46,11 +46,11 @@ public class BlockExplodeListener extends Queue implements Listener {
int z = block.getZ();
Location[] locationMap = new Location[5];
locationMap[0] = new Location(world, x + 1, y, z);
locationMap[1] = new Location(world, x - 1, y, z);
locationMap[2] = new Location(world, x, y, z + 1);
locationMap[3] = new Location(world, x, y, z - 1);
locationMap[4] = new Location(world, x, y + 1, z);
locationMap[0] = new Location(world, (x + 1), y, z);
locationMap[1] = new Location(world, (x - 1), y, z);
locationMap[2] = new Location(world, x, y, (z + 1));
locationMap[3] = new Location(world, x, y, (z - 1));
locationMap[4] = new Location(world, x, (y + 1), z);
int scanMin = 0;
int scanMax = 5;
@@ -114,22 +114,20 @@ public class BlockExplodeListener extends Queue implements Listener {
Block block = entry.getValue();
Material blockType = block.getType();
BlockState blockState = block.getState();
if (Tag.SIGNS.isTagged(blockType)) {
if (Config.getConfig(world).SIGN_TEXT) {
try {
Location location = blockState.getLocation();
Sign sign = (Sign) blockState;
String line1 = sign.getLine(0);
String line2 = sign.getLine(1);
String line3 = sign.getLine(2);
String line4 = sign.getLine(3);
int color = sign.getColor().getColor().asRGB();
boolean isGlowing = BukkitAdapter.ADAPTER.isGlowing(sign);
Queue.queueSignText(user, location, 0, color, isGlowing, line1, line2, line3, line4, 5);
}
catch (Exception e) {
e.printStackTrace();
}
if (Tag.SIGNS.isTagged(blockType) && Config.getConfig(world).SIGN_TEXT) {
try {
Location location = blockState.getLocation();
Sign sign = (Sign) blockState;
String line1 = sign.getLine(0);
String line2 = sign.getLine(1);
String line3 = sign.getLine(2);
String line4 = sign.getLine(3);
int color = sign.getColor().getColor().asRGB();
boolean isGlowing = BukkitAdapter.ADAPTER.isGlowing(sign);
Queue.queueSignText(user, location, 0, color, isGlowing, line1, line2, line3, line4, 5);
}
catch (Exception e) {
e.printStackTrace();
}
}
@@ -9,6 +9,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockSpreadEvent;
import net.coreprotect.bukkit.BukkitAdapter;
import net.coreprotect.config.Config;
import net.coreprotect.consumer.Queue;
import net.coreprotect.model.BlockGroup;
@@ -59,7 +60,7 @@ public final class BlockSpreadListener extends Queue implements Listener {
Location below = sourceBlock.getLocation().clone();
below.setY(below.getY() - 2);
for (int i = 0; i < 2; i++) {
if (below.getY() >= 0) {
if (below.getY() >= BukkitAdapter.ADAPTER.getMinHeight(block.getWorld())) {
Block belowBlock = below.getBlock();
if (belowBlock.getType().equals(Material.BAMBOO)) {
Queue.queueBlockPlaceDelayed("#bamboo", belowBlock.getLocation(), belowBlock.getType(), null, belowBlock.getState(), 0);
@@ -69,8 +70,8 @@ public final class BlockSpreadListener extends Queue implements Listener {
}
below = null;
Queue.queueBlockPlaceDelayed("#bamboo", sourceBlock.getLocation(), sourceBlock.getType(), null, sourceBlock.getState(), 0);
Queue.queueBlockPlaceDelayed("#bamboo", block.getLocation(), block.getType(), null, block.getState(), 0);
Queue.queueBlockPlaceDelayed("#bamboo", sourceBlock.getLocation(), type, null, sourceBlock.getState(), 0);
Queue.queueBlockPlaceDelayed("#bamboo", block.getLocation(), type, null, block.getState(), 0);
}
}
}
@@ -23,37 +23,44 @@ public final class EntityDamageByBlockListener extends Queue implements Listener
@EventHandler(priority = EventPriority.MONITOR)
protected void onEntityDamageByBlock(EntityDamageByBlockEvent event) {
Block damager = event.getDamager();
if (event.getEntity() instanceof ItemFrame || event.getEntity() instanceof ArmorStand || event.getEntity() instanceof EnderCrystal) {
if (damager != null && damager.getType() != Material.MAGMA_BLOCK) {
final Entity entity = event.getEntity();
Block block = entity.getLocation().getBlock();
String user = "#" + damager.getType().name().toLowerCase(Locale.ROOT);
if (user.contains("tnt")) {
user = "#tnt";
}
Entity entity = event.getEntity();
if (!(entity instanceof ItemFrame) && !(entity instanceof ArmorStand) && !(entity instanceof EnderCrystal)) {
return;
}
if (!event.isCancelled() && Config.getConfig(entity.getWorld()).BLOCK_BREAK) {
if (entity instanceof ItemFrame) {
Material frameType = BukkitAdapter.ADAPTER.getFrameType(entity);
ItemFrame frame = (ItemFrame) event.getEntity();
int data = 0;
if (frame.getItem() != null) {
data = Util.getBlockId(frame.getItem().getType());
}
Queue.queueBlockBreak(user, block.getState(), frameType, null, data);
Queue.queueBlockPlace(user, block.getState(), frameType, null, frameType, -1, 0, null);
}
else if (entity instanceof ArmorStand) {
Database.containerBreakCheck(user, Material.ARMOR_STAND, entity, null, block.getLocation());
Queue.queueBlockBreak(user, block.getState(), Material.ARMOR_STAND, null, (int) entity.getLocation().getYaw());
}
else if (entity instanceof EnderCrystal) {
EnderCrystal crystal = (EnderCrystal) event.getEntity();
Queue.queueBlockBreak(user, block.getState(), Material.END_CRYSTAL, null, crystal.isShowingBottom() ? 1 : 0);
}
}
Block damager = event.getDamager();
if (damager == null || damager.getType() == Material.MAGMA_BLOCK) {
return;
}
if (event.isCancelled() || !Config.getConfig(entity.getWorld()).BLOCK_BREAK) {
return;
}
Block block = entity.getLocation().getBlock();
String user = "#" + damager.getType().name().toLowerCase(Locale.ROOT);
if (user.contains("tnt")) {
user = "#tnt";
}
if (entity instanceof ItemFrame) {
Material frameType = BukkitAdapter.ADAPTER.getFrameType(entity);
ItemFrame frame = (ItemFrame) event.getEntity();
int data = 0;
if (frame.getItem() != null) {
data = Util.getBlockId(frame.getItem().getType());
}
Queue.queueBlockBreak(user, block.getState(), frameType, null, data);
Queue.queueBlockPlace(user, block.getState(), frameType, null, frameType, -1, 0, null);
}
else if (entity instanceof ArmorStand) {
Database.containerBreakCheck(user, Material.ARMOR_STAND, entity, null, block.getLocation());
Queue.queueBlockBreak(user, block.getState(), Material.ARMOR_STAND, null, (int) entity.getLocation().getYaw());
}
else if (entity instanceof EnderCrystal) {
EnderCrystal crystal = (EnderCrystal) event.getEntity();
Queue.queueBlockBreak(user, block.getState(), Material.END_CRYSTAL, null, crystal.isShowingBottom() ? 1 : 0);
}
}
@@ -33,8 +33,7 @@ public final class HangingBreakByEntityListener extends Queue implements Listene
class BasicThread implements Runnable {
@Override
public void run() {
try {
Connection connection = Database.getConnection(true);
try (Connection connection = Database.getConnection(true)) {
if (connection != null) {
Statement statement = connection.createStatement();
String blockData = BlockLookup.performLookup(null, statement, block, player, 0, 1, 7);
@@ -49,7 +48,6 @@ public final class HangingBreakByEntityListener extends Queue implements Listene
}
statement.close();
connection.close();
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
@@ -53,25 +53,24 @@ public final class ArmorStandManipulateListener extends Queue implements Listene
class BasicThread implements Runnable {
@Override
public void run() {
try {
if (ConfigHandler.converterRunning) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
if (ConfigHandler.converterRunning) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
return;
}
if (ConfigHandler.purgeRunning) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
return;
}
if (ConfigHandler.lookupThrottle.get(finalPlayer.getName()) != null) {
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(finalPlayer.getName());
if ((boolean) lookupThrottle[0] || ((System.currentTimeMillis() - (long) lookupThrottle[1])) < 100) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
return;
}
if (ConfigHandler.purgeRunning) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
return;
}
if (ConfigHandler.lookupThrottle.get(finalPlayer.getName()) != null) {
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(finalPlayer.getName());
if ((boolean) lookupThrottle[0] || ((System.currentTimeMillis() - (long) lookupThrottle[1])) < 100) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
return;
}
}
ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { true, System.currentTimeMillis() });
}
ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { true, System.currentTimeMillis() });
Connection connection = Database.getConnection(true);
try (Connection connection = Database.getConnection(true)) {
if (connection != null) {
Statement statement = connection.createStatement();
Location standLocation = armorStand.getLocation();
@@ -86,7 +85,6 @@ public final class ArmorStandManipulateListener extends Queue implements Listene
Chat.sendComponent(finalPlayer, blockData);
}
statement.close();
connection.close();
}
else {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
@@ -37,12 +37,12 @@ public final class FoodLevelChangeListener extends Queue implements Listener {
String coordinates = x + "." + y + "." + z + "." + worldId + "." + userUUID;
Object[] data = CacheHandler.interactCache.get(coordinates);
if (data != null) {
if (data != null && data[1] == Material.CAKE) {
long newTime = System.currentTimeMillis();
long oldTime = (long) data[0];
if ((newTime - oldTime) < 20) { // 50ms = 1 tick
final BlockState oldBlockState = (BlockState) data[1];
final BlockState oldBlockState = (BlockState) data[2];
Material oldType = oldBlockState.getType();
if (oldType.name().endsWith(Material.CAKE.name())) {
@@ -1,9 +1,14 @@
package net.coreprotect.listener.player;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.inventory.BrewerInventory;
import org.bukkit.inventory.FurnaceInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
@@ -15,30 +20,46 @@ import net.coreprotect.utility.Util;
public final class HopperPullListener {
static void processHopperPull(Location location, InventoryHolder sourceHolder, InventoryHolder destinationHolder, ItemStack item, ItemStack movedItem) {
static void processHopperPull(Location location, InventoryHolder sourceHolder, InventoryHolder destinationHolder, ItemStack item) {
String loggingChestId = "#hopper-pull." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
Object[] lastAbort = ConfigHandler.hopperAbort.get(loggingChestId);
if (lastAbort != null) {
ItemStack[] destinationContents = destinationHolder.getInventory().getContents();
if (((Set<?>) lastAbort[0]).contains(item) && Arrays.equals(destinationContents, (ItemStack[]) lastAbort[1])) {
return;
}
}
ItemStack[] containerState = null;
if (!ConfigHandler.isPaper) {
containerState = Util.getContainerState(sourceHolder.getInventory().getContents());
}
ItemStack[] sourceContainer = containerState;
ItemStack movedItem = item.clone();
final long taskStarted = InventoryChangeListener.tasksStarted.incrementAndGet();
Bukkit.getServer().getScheduler().runTaskAsynchronously(CoreProtect.getInstance(), () -> {
try {
InventoryChangeListener.checkTasks(taskStarted);
if (sourceHolder == null || destinationHolder == null) {
return;
}
boolean hopperTransactions = Config.getConfig(location.getWorld()).HOPPER_TRANSACTIONS;
int itemHash = Util.getItemStackHashCode(item);
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
String loggingChestId = "#hopper." + x + "." + y + "." + z;
boolean abort = false;
if (ConfigHandler.isPaper) {
boolean abort = false;
for (ItemStack itemStack : sourceHolder.getInventory().getContents()) {
if (itemStack != null && Util.getItemStackHashCode(itemStack) == itemHash) {
if (itemHash != Util.getItemStackHashCode(movedItem) || destinationHolder.getInventory().firstEmpty() == -1 || destinationHolder.getInventory() instanceof BrewerInventory || destinationHolder.getInventory() instanceof FurnaceInventory) {
abort = true;
}
break;
}
}
/*
for (ItemStack itemStack : sourceHolder.getInventory().getContents()) {
if (itemStack != null && Util.getItemStackHashCode(itemStack) == itemHash) {
abort = true;
@@ -49,62 +70,52 @@ public final class HopperPullListener {
if (abort) {
for (ItemStack itemStack : destinationHolder.getInventory().getContents()) {
if (itemStack != null && Util.getItemStackHashCode(itemStack) == Util.getItemStackHashCode(movedItem)) {
abort = false;
if (itemHash == Util.getItemStackHashCode(itemStack) && destinationHolder.getInventory().firstEmpty() > -1) {
abort = false;
}
break;
}
}
if (abort) {
ConfigHandler.hopperAbort.put(loggingChestId, true);
return;
}
}
*/
}
else {
ItemStack[] sourceContents = sourceHolder.getInventory().getContents();
boolean addedInventory = Util.addedContainer(sourceContainer, sourceContents);
if (addedInventory) {
ConfigHandler.hopperAbort.put(loggingChestId, true);
return;
abort = true;
}
}
boolean lastAborted = false;
if (abort) {
Set<ItemStack> movedItems = new HashSet<>();
ItemStack[] destinationContents = destinationHolder.getInventory().getContents();
if (lastAbort != null && Arrays.equals(destinationContents, (ItemStack[]) lastAbort[1])) {
((Set<?>) lastAbort[0]).forEach(itemStack -> movedItems.add((ItemStack) itemStack));
}
movedItems.add(movedItem);
ConfigHandler.hopperAbort.put(loggingChestId, new Object[] { movedItems, Util.getContainerState(destinationContents) });
return;
}
if (ConfigHandler.hopperAbort.get(loggingChestId) != null) {
ConfigHandler.hopperAbort.remove(loggingChestId);
lastAborted = true;
}
boolean mergeMoved = true;
if (lastAborted) {
for (String loggingChestIdViewer : ConfigHandler.oldContainer.keySet()) {
if (loggingChestIdViewer.equals(loggingChestId) || !loggingChestIdViewer.endsWith("." + x + "." + y + "." + z)) {
continue;
}
if (ConfigHandler.oldContainer.get(loggingChestIdViewer) != null) { // pending consumer item by another user
mergeMoved = false;
break;
}
}
}
if (!hopperTransactions) {
if (mergeMoved) {
List<Object> list = ConfigHandler.transactingChest.get(location.getWorld().getUID().toString() + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ());
if (list != null) {
list.add(movedItem);
}
List<Object> list = ConfigHandler.transactingChest.get(location.getWorld().getUID().toString() + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ());
if (list != null) {
list.add(movedItem);
}
return;
}
if (mergeMoved) {
Location destinationLocation = destinationHolder.getInventory().getLocation();
List<Object> list = ConfigHandler.transactingChest.get(destinationLocation.getWorld().getUID().toString() + "." + destinationLocation.getBlockX() + "." + destinationLocation.getBlockY() + "." + destinationLocation.getBlockZ());
if (list != null) {
list.add(new ItemStack[] { null, movedItem });
}
Location destinationLocation = destinationHolder.getInventory().getLocation();
List<Object> list = ConfigHandler.transactingChest.get(destinationLocation.getWorld().getUID().toString() + "." + destinationLocation.getBlockX() + "." + destinationLocation.getBlockY() + "." + destinationLocation.getBlockZ());
if (list != null) {
list.add(new ItemStack[] { null, movedItem });
}
if (Config.getConfig(location.getWorld()).HOPPER_FILTER_META && !movedItem.hasItemMeta()) {
@@ -121,10 +132,8 @@ public final class HopperPullListener {
}
}
if (mergeMoved) {
originalSource[inventoryContents.length] = movedItem;
}
originalSource[inventoryContents.length] = movedItem;
InventoryChangeListener.checkTasks(taskStarted);
InventoryChangeListener.onInventoryInteract("#hopper", sourceInventory, originalSource, null, sourceInventory.getLocation(), true);
}
catch (Exception e) {
@@ -1,9 +1,14 @@
package net.coreprotect.listener.player;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.inventory.BrewerInventory;
import org.bukkit.inventory.FurnaceInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
@@ -15,28 +20,38 @@ import net.coreprotect.utility.Util;
public final class HopperPushListener {
static void processHopperPush(Location location, InventoryHolder sourceHolder, InventoryHolder destinationHolder, ItemStack item, ItemStack movedItem) {
static void processHopperPush(Location location, InventoryHolder sourceHolder, InventoryHolder destinationHolder, ItemStack item) {
String loggingChestId = "#hopper-push." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
Object[] lastAbort = ConfigHandler.hopperAbort.get(loggingChestId);
if (lastAbort != null) {
ItemStack[] destinationContents = destinationHolder.getInventory().getContents();
if (((Set<?>) lastAbort[0]).contains(item) && Arrays.equals(destinationContents, (ItemStack[]) lastAbort[1])) {
return;
}
}
ItemStack[] containerState = null;
if (!ConfigHandler.isPaper) {
containerState = Util.getContainerState(destinationHolder.getInventory().getContents());
}
ItemStack[] destinationContainer = containerState;
ItemStack movedItem = item.clone();
final long taskStarted = InventoryChangeListener.tasksStarted.incrementAndGet();
Bukkit.getServer().getScheduler().runTaskAsynchronously(CoreProtect.getInstance(), () -> {
try {
InventoryChangeListener.checkTasks(taskStarted);
if (sourceHolder == null || destinationHolder == null) {
return;
}
int itemHash = Util.getItemStackHashCode(item);
boolean abort = false;
if (ConfigHandler.isPaper) {
for (ItemStack itemStack : sourceHolder.getInventory().getContents()) {
if (itemStack != null && Util.getItemStackHashCode(itemStack) == itemHash) {
if (itemHash != Util.getItemStackHashCode(movedItem) || destinationHolder.getInventory().firstEmpty() == -1) {
return;
if (itemHash != Util.getItemStackHashCode(movedItem) || destinationHolder.getInventory().firstEmpty() == -1 || destinationHolder.getInventory() instanceof BrewerInventory || destinationHolder.getInventory() instanceof FurnaceInventory) {
abort = true;
}
break;
@@ -47,10 +62,22 @@ public final class HopperPushListener {
ItemStack[] destinationContents = destinationHolder.getInventory().getContents();
boolean addedInventory = Util.addedContainer(destinationContainer, destinationContents);
if (!addedInventory) {
return;
abort = true;
}
}
if (abort) {
Set<ItemStack> movedItems = new HashSet<>();
ItemStack[] destinationContents = destinationHolder.getInventory().getContents();
if (lastAbort != null && Arrays.equals(destinationContents, (ItemStack[]) lastAbort[1])) {
((Set<?>) lastAbort[0]).forEach(itemStack -> movedItems.add((ItemStack) itemStack));
}
movedItems.add(movedItem);
ConfigHandler.hopperAbort.put(loggingChestId, new Object[] { movedItems, Util.getContainerState(destinationContents) });
return;
}
List<Object> list = ConfigHandler.transactingChest.get(location.getWorld().getUID().toString() + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ());
if (list != null) {
list.add(movedItem);
@@ -68,22 +95,22 @@ public final class HopperPushListener {
break;
}
ItemStack itemStack = originalDestination[i];
ItemStack itemStack = (originalDestination[i] != null ? originalDestination[i].clone() : null);
if (itemStack != null && itemStack.isSimilar(movedItem)) {
itemStack = itemStack.clone();
if (itemStack.getAmount() >= removeAmount) {
itemStack.setAmount(itemStack.getAmount() - removeAmount);
removeAmount = 0;
}
else {
removeAmount = removeAmount - itemStack.getAmount();
itemStack.setAmount(0);
itemStack = null;
}
originalDestination[i] = itemStack;
}
}
InventoryChangeListener.checkTasks(taskStarted);
InventoryChangeListener.onInventoryInteract("#hopper", destinationInventory, originalDestination, null, destinationInventory.getLocation(), true);
}
catch (Exception e) {
@@ -31,6 +31,7 @@ import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Queue;
import net.coreprotect.model.BlockGroup;
import net.coreprotect.paper.PaperAdapter;
import net.coreprotect.utility.Util;
import net.coreprotect.utility.Validate;
@@ -125,9 +126,10 @@ public final class InventoryChangeListener extends Queue implements Listener {
ItemStack[] containerState = Util.getContainerState(inventoryData);
// If items have been removed by a hopper, merge into containerState
if (ConfigHandler.transactingChest.get(transactingChestId) != null) {
List<Object> transactingChestList = Collections.synchronizedList(new ArrayList<>(ConfigHandler.transactingChest.get(transactingChestId)));
if (transactingChestList.size() > 0) {
List<Object> transactingChest = ConfigHandler.transactingChest.get(transactingChestId);
if (transactingChest != null) {
List<Object> transactingChestList = Collections.synchronizedList(new ArrayList<>(transactingChest));
if (!transactingChestList.isEmpty()) {
ItemStack[] newState = new ItemStack[containerState.length + transactingChestList.size()];
int count = 0;
@@ -174,8 +176,9 @@ public final class InventoryChangeListener extends Queue implements Listener {
int chestId = getChestId(loggingChestId);
if (chestId > 0) {
if (ConfigHandler.forceContainer.get(loggingChestId) != null) {
int forceSize = ConfigHandler.forceContainer.get(loggingChestId).size();
List<ItemStack[]> forceList = ConfigHandler.forceContainer.get(loggingChestId);
if (forceList != null) {
int forceSize = forceList.size();
List<ItemStack[]> list = ConfigHandler.oldContainer.get(loggingChestId);
if (list != null && list.size() <= forceSize) {
@@ -226,8 +229,8 @@ public final class InventoryChangeListener extends Queue implements Listener {
final long taskStarted = InventoryChangeListener.tasksStarted.incrementAndGet();
Bukkit.getServer().getScheduler().runTaskAsynchronously(CoreProtect.getInstance(), () -> {
try {
InventoryChangeListener.checkTasks(taskStarted);
Material containerType = (enderChest != true ? null : Material.ENDER_CHEST);
InventoryChangeListener.checkTasks(taskStarted);
onInventoryInteract(player.getName(), inventory, containerState, containerType, inventoryLocation, true);
}
catch (Exception e) {
@@ -304,31 +307,36 @@ public final class InventoryChangeListener extends Queue implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
protected void onInventoryMoveItemEvent(InventoryMoveItemEvent event) {
if (event.isCancelled()) {
return;
}
Location location = event.getSource().getLocation();
if (location == null) {
return;
}
InventoryHolder sourceHolder = event.getSource().getHolder();
boolean hopperTransactions = Config.getConfig(location.getWorld()).HOPPER_TRANSACTIONS;
if (!hopperTransactions && !Config.getConfig(location.getWorld()).ITEM_TRANSACTIONS) {
return;
}
InventoryHolder sourceHolder = PaperAdapter.ADAPTER.getHolder(event.getSource(), false);
if (sourceHolder == null) {
return;
}
InventoryHolder destinationHolder = event.getDestination().getHolder();
InventoryHolder destinationHolder = PaperAdapter.ADAPTER.getHolder(event.getDestination(), false);
if (destinationHolder == null) {
return;
}
if (Config.getConfig(location.getWorld()).HOPPER_TRANSACTIONS) {
if (hopperTransactions) {
if (Validate.isHopper(destinationHolder) && (Validate.isContainer(sourceHolder) && !Validate.isHopper(sourceHolder))) {
ItemStack item = event.getItem();
ItemStack movedItem = item.clone();
HopperPullListener.processHopperPull(location, sourceHolder, destinationHolder, item, movedItem);
HopperPullListener.processHopperPull(location, sourceHolder, destinationHolder, event.getItem());
}
else if (Validate.isHopper(sourceHolder) && (Validate.isContainer(destinationHolder) && !Validate.isHopper(destinationHolder))) {
ItemStack item = event.getItem();
ItemStack movedItem = item.clone();
HopperPushListener.processHopperPush(location, sourceHolder, destinationHolder, item, movedItem);
HopperPushListener.processHopperPush(location, sourceHolder, destinationHolder, event.getItem());
}
return;
@@ -343,6 +351,6 @@ public final class InventoryChangeListener extends Queue implements Listener {
return;
}
HopperPullListener.processHopperPull(location, sourceHolder, destinationHolder, event.getItem(), event.getItem().clone());
HopperPullListener.processHopperPull(location, sourceHolder, destinationHolder, event.getItem());
}
}
@@ -20,8 +20,8 @@ public final class PlayerChatListener extends Queue implements Listener {
Player player = event.getPlayer();
if (!message.startsWith("/") && Config.getConfig(player.getWorld()).PLAYER_MESSAGES) {
int time = (int) (System.currentTimeMillis() / 1000L);
Queue.queuePlayerChat(player, message, time);
long timestamp = System.currentTimeMillis() / 1000L;
Queue.queuePlayerChat(player, message, timestamp);
}
}
}
@@ -15,8 +15,8 @@ public final class PlayerCommandListener extends Queue implements Listener {
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
Player player = event.getPlayer();
if (Config.getConfig(player.getWorld()).PLAYER_COMMANDS) {
int time = (int) (System.currentTimeMillis() / 1000L);
Queue.queuePlayerCommand(player, event.getMessage(), time);
long timestamp = System.currentTimeMillis() / 1000L;
Queue.queuePlayerCommand(player, event.getMessage(), timestamp);
}
}
}
@@ -20,6 +20,10 @@ import net.coreprotect.consumer.Queue;
public final class PlayerDropItemListener extends Queue implements Listener {
protected static void playerDropItem(Location location, Player player, ItemStack itemStack) {
if (itemStack == null) {
return;
}
String loggingItemId = player.getName().toLowerCase(Locale.ROOT) + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
int itemId = getItemId(loggingItemId);
@@ -41,10 +45,6 @@ public final class PlayerDropItemListener extends Queue implements Listener {
Player player = event.getPlayer();
ItemStack itemStack = item.getItemStack();
if (itemStack == null) {
return;
}
playerDropItem(location, player, itemStack);
}
@@ -61,474 +61,454 @@ public final class PlayerInteractListener extends Queue implements Listener {
public static ConcurrentHashMap<String, Object[]> lastInspectorEvent = new ConcurrentHashMap<>();
@EventHandler(priority = EventPriority.LOWEST)
protected void onPlayerInteract(PlayerInteractEvent event) {
protected void onPlayerInspect(PlayerInteractEvent event) {
Player player = event.getPlayer();
World world = player.getWorld();
if (event.getAction().equals(Action.LEFT_CLICK_BLOCK)) {
if (ConfigHandler.inspecting.get(player.getName()) != null) {
if (ConfigHandler.inspecting.get(player.getName())) {
// block check
BlockState checkBlock = event.getClickedBlock().getState();
int x = checkBlock.getX();
int y = checkBlock.getY();
int z = checkBlock.getZ();
if (!Boolean.TRUE.equals(ConfigHandler.inspecting.get(player.getName()))) {
return;
}
/* Check if clicking top half of double plant */
BlockData checkBlockData = checkBlock.getBlockData();
if (checkBlockData instanceof Bisected && !(checkBlockData instanceof Waterlogged)) {
if (((Bisected) checkBlockData).getHalf().equals(Half.TOP) && y > BukkitAdapter.ADAPTER.getMinHeight(world)) {
checkBlock = world.getBlockAt(checkBlock.getX(), checkBlock.getY() - 1, checkBlock.getZ()).getState();
if (event.getAction().equals(Action.LEFT_CLICK_BLOCK)) {
BlockState checkBlock = event.getClickedBlock().getState();
int x = checkBlock.getX();
int y = checkBlock.getY();
int z = checkBlock.getZ();
/* Check if clicking top half of double plant */
BlockData checkBlockData = checkBlock.getBlockData();
if (checkBlockData instanceof Bisected && !(checkBlockData instanceof Waterlogged)) {
if (((Bisected) checkBlockData).getHalf().equals(Half.TOP) && y > BukkitAdapter.ADAPTER.getMinHeight(world)) {
checkBlock = world.getBlockAt(checkBlock.getX(), checkBlock.getY() - 1, checkBlock.getZ()).getState();
}
}
final BlockState blockFinal = checkBlock;
class BasicThread implements Runnable {
@Override
public void run() {
if (ConfigHandler.converterRunning) {
player.sendMessage(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
return;
}
if (ConfigHandler.purgeRunning) {
player.sendMessage(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
return;
}
if (ConfigHandler.lookupThrottle.get(player.getName()) != null) {
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(player.getName());
if ((boolean) lookupThrottle[0] || (System.currentTimeMillis() - (long) lookupThrottle[1]) < 100) {
player.sendMessage(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
return;
}
}
final BlockState blockFinal = checkBlock;
final Player playerFinal = player;
try (Connection connection = Database.getConnection(true)) {
if (connection != null) {
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { true, System.currentTimeMillis() });
Statement statement = connection.createStatement();
class BasicThread implements Runnable {
@Override
public void run() {
try {
String resultData = BlockLookup.performLookup(null, statement, blockFinal, player, 0, 1, 7);
if (resultData.contains("\n")) {
for (String b : resultData.split("\n")) {
Chat.sendComponent(player, b);
}
}
else if (resultData.length() > 0) {
Chat.sendComponent(player, resultData);
}
statement.close();
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { false, System.currentTimeMillis() });
if (blockFinal instanceof Sign && player.getGameMode() != GameMode.CREATIVE) {
Thread.sleep(1500);
Sign sign = (Sign) blockFinal;
BukkitAdapter.ADAPTER.sendSignChange(player, sign);
}
}
else {
player.sendMessage(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
if (checkBlockData instanceof Bisected) {
int worldMaxHeight = world.getMaxHeight();
if (y < (worldMaxHeight - 1)) {
Block y1 = world.getBlockAt(x, y + 1, z);
player.sendBlockChange(y1.getLocation(), y1.getBlockData());
}
int worldMinHeight = BukkitAdapter.ADAPTER.getMinHeight(world);
if (y > worldMinHeight) {
Block y2 = world.getBlockAt(x, y - 1, z);
player.sendBlockChange(y2.getLocation(), y2.getBlockData());
}
}
Block x1 = world.getBlockAt(x + 1, y, z);
Block x2 = world.getBlockAt(x - 1, y, z);
Block z1 = world.getBlockAt(x, y, z + 1);
Block z2 = world.getBlockAt(x, y, z - 1);
player.sendBlockChange(x1.getLocation(), x1.getBlockData());
player.sendBlockChange(x2.getLocation(), x2.getBlockData());
player.sendBlockChange(z1.getLocation(), z1.getBlockData());
player.sendBlockChange(z2.getLocation(), z2.getBlockData());
event.setCancelled(true);
}
else if (event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
Block block = event.getClickedBlock();
if (block != null) {
final Material type = block.getType();
boolean isInteractBlock = BlockGroup.INTERACT_BLOCKS.contains(type);
boolean isContainerBlock = BlockGroup.CONTAINERS.contains(type);
boolean isSignBlock = Tag.SIGNS.isTagged(type);
if (isInteractBlock || isContainerBlock || isSignBlock) {
final Block clickedBlock = event.getClickedBlock();
if (isSignBlock) {
Location location = clickedBlock.getLocation();
// sign messages
class BasicThread implements Runnable {
@Override
public void run() {
if (ConfigHandler.converterRunning) {
playerFinal.sendMessage(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
return;
}
if (ConfigHandler.purgeRunning) {
playerFinal.sendMessage(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
return;
}
if (ConfigHandler.lookupThrottle.get(playerFinal.getName()) != null) {
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(playerFinal.getName());
if ((boolean) lookupThrottle[0] || ((System.currentTimeMillis() - (long) lookupThrottle[1])) < 100) {
playerFinal.sendMessage(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
if (ConfigHandler.lookupThrottle.get(player.getName()) != null) {
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(player.getName());
if ((boolean) lookupThrottle[0] || (System.currentTimeMillis() - (long) lookupThrottle[1]) < 100) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
return;
}
}
Connection connection = Database.getConnection(true);
if (connection != null) {
ConfigHandler.lookupThrottle.put(playerFinal.getName(), new Object[] { true, System.currentTimeMillis() });
Statement statement = connection.createStatement();
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { true, System.currentTimeMillis() });
String resultData = BlockLookup.performLookup(null, statement, blockFinal, playerFinal, 0, 1, 7);
if (resultData.contains("\n")) {
for (String b : resultData.split("\n")) {
Chat.sendComponent(playerFinal, b);
}
}
else if (resultData.length() > 0) {
Chat.sendComponent(playerFinal, resultData);
}
try (Connection connection = Database.getConnection(true)) {
if (connection != null) {
Statement statement = connection.createStatement();
List<String> signData = SignMessageLookup.performLookup(null, statement, location, player, 1, 7);
for (String signMessage : signData) {
String bypass = null;
statement.close();
connection.close();
ConfigHandler.lookupThrottle.put(playerFinal.getName(), new Object[] { false, System.currentTimeMillis() });
if (blockFinal instanceof Sign && playerFinal.getGameMode() != GameMode.CREATIVE) {
Thread.sleep(1500);
Sign sign = (Sign) blockFinal;
BukkitAdapter.ADAPTER.sendSignChange(playerFinal, sign);
}
}
else {
playerFinal.sendMessage(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
if (checkBlockData instanceof Bisected) {
int worldMaxHeight = world.getMaxHeight();
if (y < (worldMaxHeight - 1)) {
Block y1 = world.getBlockAt(x, y + 1, z);
player.sendBlockChange(y1.getLocation(), y1.getBlockData());
}
int worldMinHeight = BukkitAdapter.ADAPTER.getMinHeight(world);
if (y > worldMinHeight) {
Block y2 = world.getBlockAt(x, y - 1, z);
player.sendBlockChange(y2.getLocation(), y2.getBlockData());
}
}
Block x1 = world.getBlockAt(x + 1, y, z);
Block x2 = world.getBlockAt(x - 1, y, z);
Block z1 = world.getBlockAt(x, y, z + 1);
Block z2 = world.getBlockAt(x, y, z - 1);
player.sendBlockChange(x1.getLocation(), x1.getBlockData());
player.sendBlockChange(x2.getLocation(), x2.getBlockData());
player.sendBlockChange(z1.getLocation(), z1.getBlockData());
player.sendBlockChange(z2.getLocation(), z2.getBlockData());
event.setCancelled(true);
}
}
}
else if (event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
if (ConfigHandler.inspecting.get(player.getName()) != null) {
if (ConfigHandler.inspecting.get(player.getName())) {
Block block = event.getClickedBlock();
if (block != null) {
final Material type = block.getType();
boolean isInteractBlock = BlockGroup.INTERACT_BLOCKS.contains(type);
boolean isContainerBlock = BlockGroup.CONTAINERS.contains(type);
boolean isSignBlock = Tag.SIGNS.isTagged(type);
if (isInteractBlock || isContainerBlock || isSignBlock) {
final Block clickedBlock = event.getClickedBlock();
final Player finalPlayer = player;
if (isSignBlock) {
Location location = clickedBlock.getLocation();
// sign messages
class BasicThread implements Runnable {
@Override
public void run() {
try {
if (ConfigHandler.converterRunning) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
return;
if (signMessage.contains("\n")) {
String[] split = signMessage.split("\n");
signMessage = split[0];
bypass = split[1];
}
if (ConfigHandler.purgeRunning) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
return;
}
if (ConfigHandler.lookupThrottle.get(finalPlayer.getName()) != null) {
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(finalPlayer.getName());
if ((boolean) lookupThrottle[0] || ((System.currentTimeMillis() - (long) lookupThrottle[1])) < 100) {
System.out.println((boolean) lookupThrottle[0] + " / " + ((System.currentTimeMillis() - (long) lookupThrottle[1])));
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
return;
}
}
ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { true, System.currentTimeMillis() });
Connection connection = Database.getConnection(true);
if (connection != null) {
Statement statement = connection.createStatement();
List<String> signData = SignMessageLookup.performLookup(null, statement, location, finalPlayer, 1, 7);
for (String signMessage : signData) {
String bypass = null;
if (signMessage.contains("\n")) {
String[] split = signMessage.split("\n");
signMessage = split[0];
bypass = split[1];
}
if (signMessage.length() > 0) {
Chat.sendComponent(finalPlayer, signMessage, bypass);
}
}
statement.close();
connection.close();
}
else {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
if (signMessage.length() > 0) {
Chat.sendComponent(player, signMessage, bypass);
}
}
catch (Exception e) {
e.printStackTrace();
}
ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { false, System.currentTimeMillis() });
}
}
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
event.setCancelled(true);
}
else if (isContainerBlock && Config.getConfig(world).ITEM_TRANSACTIONS) {
Location location = null;
if (type.equals(Material.CHEST) || type.equals(Material.TRAPPED_CHEST)) {
Chest chest = (Chest) clickedBlock.getState();
InventoryHolder inventoryHolder = chest.getInventory().getHolder();
if (inventoryHolder instanceof DoubleChest) {
DoubleChest doubleChest = (DoubleChest) inventoryHolder;
location = doubleChest.getLocation();
statement.close();
}
else {
location = chest.getLocation();
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
}
}
if (location == null) {
location = clickedBlock.getLocation();
catch (Exception e) {
e.printStackTrace();
}
Location finalLocation = location;
// logged chest items
class BasicThread implements Runnable {
@Override
public void run() {
try {
if (ConfigHandler.converterRunning) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
return;
}
if (ConfigHandler.purgeRunning) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
return;
}
if (ConfigHandler.lookupThrottle.get(finalPlayer.getName()) != null) {
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(finalPlayer.getName());
if ((boolean) lookupThrottle[0] || ((System.currentTimeMillis() - (long) lookupThrottle[1])) < 100) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
return;
}
}
ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { true, System.currentTimeMillis() });
Connection connection = Database.getConnection(true);
if (connection != null) {
Statement statement = connection.createStatement();
String blockData = ChestTransactionLookup.performLookup(null, statement, finalLocation, finalPlayer, 1, 7, false);
if (blockData.contains("\n")) {
for (String splitData : blockData.split("\n")) {
Chat.sendComponent(finalPlayer, splitData);
}
}
else {
Chat.sendComponent(finalPlayer, blockData);
}
statement.close();
connection.close();
}
else {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
}
}
catch (Exception e) {
e.printStackTrace();
}
ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { false, System.currentTimeMillis() });
}
}
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
event.setCancelled(true);
}
else if (isInteractBlock) {
// standard player interactions
Block interactBlock = clickedBlock;
if (BlockGroup.DOORS.contains(type)) {
int y = interactBlock.getY() - 1;
Block blockUnder = interactBlock.getWorld().getBlockAt(interactBlock.getX(), y, interactBlock.getZ());
if (blockUnder.getType().equals(type)) {
interactBlock = blockUnder;
}
}
final Block finalInteractBlock = interactBlock;
class BasicThread implements Runnable {
@Override
public void run() {
try {
if (ConfigHandler.converterRunning) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
return;
}
if (ConfigHandler.purgeRunning) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
return;
}
if (ConfigHandler.lookupThrottle.get(finalPlayer.getName()) != null) {
Object[] lookup_throttle = ConfigHandler.lookupThrottle.get(finalPlayer.getName());
if ((boolean) lookup_throttle[0] || ((System.currentTimeMillis() - (long) lookup_throttle[1])) < 100) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
return;
}
}
ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { true, System.currentTimeMillis() });
Connection connection = Database.getConnection(true);
if (connection != null) {
Statement statement = connection.createStatement();
String blockData = InteractionLookup.performLookup(null, statement, finalInteractBlock, finalPlayer, 0, 1, 7);
if (blockData.contains("\n")) {
for (String splitData : blockData.split("\n")) {
Chat.sendComponent(finalPlayer, splitData);
}
}
else {
Chat.sendComponent(finalPlayer, blockData);
}
statement.close();
connection.close();
}
else {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
}
}
catch (Exception e) {
e.printStackTrace();
}
ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { false, System.currentTimeMillis() });
}
}
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
if (!BlockGroup.SAFE_INTERACT_BLOCKS.contains(type)) {
event.setCancelled(true);
}
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { false, System.currentTimeMillis() });
}
}
else {
boolean performLookup = true;
EquipmentSlot eventHand = event.getHand();
String uuid = event.getPlayer().getUniqueId().toString();
long systemTime = System.currentTimeMillis();
if (lastInspectorEvent.get(uuid) != null) {
Object[] lastEvent = lastInspectorEvent.get(uuid);
long lastTime = (long) lastEvent[0];
EquipmentSlot lastHand = (EquipmentSlot) lastEvent[1];
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
event.setCancelled(true);
}
else if (isContainerBlock && Config.getConfig(world).ITEM_TRANSACTIONS) {
Location location = null;
if (type.equals(Material.CHEST) || type.equals(Material.TRAPPED_CHEST)) {
Chest chest = (Chest) clickedBlock.getState();
InventoryHolder inventoryHolder = chest.getInventory().getHolder();
long timeSince = systemTime - lastTime;
if (timeSince < 50 && !eventHand.equals(lastHand)) {
performLookup = false;
}
if (inventoryHolder instanceof DoubleChest) {
DoubleChest doubleChest = (DoubleChest) inventoryHolder;
location = doubleChest.getLocation();
}
else {
location = chest.getLocation();
}
}
if (performLookup) {
final Player finalPlayer = player;
final BlockState finalBlock = event.getClickedBlock().getRelative(event.getBlockFace()).getState();
if (location == null) {
location = clickedBlock.getLocation();
}
class BasicThread implements Runnable {
@Override
public void run() {
try {
if (ConfigHandler.converterRunning) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
return;
}
Location finalLocation = location;
if (ConfigHandler.purgeRunning) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
return;
}
// logged chest items
class BasicThread implements Runnable {
@Override
public void run() {
if (ConfigHandler.converterRunning) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
return;
}
if (ConfigHandler.lookupThrottle.get(finalPlayer.getName()) != null) {
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(finalPlayer.getName());
if ((boolean) lookupThrottle[0] || ((System.currentTimeMillis() - (long) lookupThrottle[1])) < 100) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
return;
}
}
if (ConfigHandler.purgeRunning) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
return;
}
ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { true, System.currentTimeMillis() });
Connection connection = Database.getConnection(true);
if (connection != null) {
Statement statement = connection.createStatement();
if (finalBlock.getType().equals(Material.AIR) || finalBlock.getType().equals(Material.CAVE_AIR)) {
String blockData = BlockLookup.performLookup(null, statement, finalBlock, finalPlayer, 0, 1, 7);
if (blockData.contains("\n")) {
for (String b : blockData.split("\n")) {
Chat.sendComponent(finalPlayer, b);
}
}
else if (blockData.length() > 0) {
Chat.sendComponent(finalPlayer, blockData);
}
}
else {
String blockData = BlockLookup.performLookup(null, statement, finalBlock, finalPlayer, 0, 1, 7);
if (blockData.contains("\n")) {
for (String splitData : blockData.split("\n")) {
Chat.sendComponent(finalPlayer, splitData);
}
}
else if (blockData.length() > 0) {
Chat.sendComponent(finalPlayer, blockData);
}
}
statement.close();
connection.close();
}
else {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
}
}
catch (Exception e) {
e.printStackTrace();
}
ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { false, System.currentTimeMillis() });
if (ConfigHandler.lookupThrottle.get(player.getName()) != null) {
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(player.getName());
if ((boolean) lookupThrottle[0] || (System.currentTimeMillis() - (long) lookupThrottle[1]) < 100) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
return;
}
}
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { true, System.currentTimeMillis() });
Util.updateInventory(event.getPlayer());
lastInspectorEvent.put(uuid, new Object[] { systemTime, eventHand });
try (Connection connection = Database.getConnection(true)) {
if (connection != null) {
Statement statement = connection.createStatement();
String blockData = ChestTransactionLookup.performLookup(null, statement, finalLocation, player, 1, 7, false);
if (event.hasItem()) {
Material eventItem = event.getItem().getType();
if (eventItem.isBlock() && (eventItem.createBlockData() instanceof Bisected)) {
int x = finalBlock.getX();
int y = finalBlock.getY();
int z = finalBlock.getZ();
int worldMaxHeight = world.getMaxHeight();
if (y < (worldMaxHeight - 1)) {
Block blockBisected = world.getBlockAt(x, y + 1, z);
player.sendBlockChange(blockBisected.getLocation(), blockBisected.getBlockData());
if (blockData.contains("\n")) {
for (String splitData : blockData.split("\n")) {
Chat.sendComponent(player, splitData);
}
}
int worldMinHeight = BukkitAdapter.ADAPTER.getMinHeight(world);
if (y > worldMinHeight) {
Block blockBisected = world.getBlockAt(x, y - 1, z);
player.sendBlockChange(blockBisected.getLocation(), blockBisected.getBlockData());
else {
Chat.sendComponent(player, blockData);
}
statement.close();
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
}
}
}
catch (Exception e) {
e.printStackTrace();
}
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { false, System.currentTimeMillis() });
}
}
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
event.setCancelled(true);
}
else if (isInteractBlock) {
// standard player interactions
Block interactBlock = clickedBlock;
if (BlockGroup.DOORS.contains(type)) {
int y = interactBlock.getY() - 1;
Block blockUnder = interactBlock.getWorld().getBlockAt(interactBlock.getX(), y, interactBlock.getZ());
if (blockUnder.getType().equals(type)) {
interactBlock = blockUnder;
}
}
final Block finalInteractBlock = interactBlock;
class BasicThread implements Runnable {
@Override
public void run() {
if (ConfigHandler.converterRunning) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
return;
}
if (ConfigHandler.purgeRunning) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
return;
}
if (ConfigHandler.lookupThrottle.get(player.getName()) != null) {
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(player.getName());
if ((boolean) lookupThrottle[0] || (System.currentTimeMillis() - (long) lookupThrottle[1]) < 100) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
return;
}
}
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { true, System.currentTimeMillis() });
try (Connection connection = Database.getConnection(true)) {
if (connection != null) {
Statement statement = connection.createStatement();
String blockData = InteractionLookup.performLookup(null, statement, finalInteractBlock, player, 0, 1, 7);
if (blockData.contains("\n")) {
for (String splitData : blockData.split("\n")) {
Chat.sendComponent(player, splitData);
}
}
else {
Chat.sendComponent(player, blockData);
}
statement.close();
}
else {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
}
}
catch (Exception e) {
e.printStackTrace();
}
ConfigHandler.lookupThrottle.put(player.getName(), new Object[] { false, System.currentTimeMillis() });
}
}
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
if (!BlockGroup.SAFE_INTERACT_BLOCKS.contains(type)) {
event.setCancelled(true);
}
}
}
else {
boolean performLookup = true;
EquipmentSlot eventHand = event.getHand();
String uuid = event.getPlayer().getUniqueId().toString();
long systemTime = System.currentTimeMillis();
if (lastInspectorEvent.get(uuid) != null) {
Object[] lastEvent = lastInspectorEvent.get(uuid);
long lastTime = (long) lastEvent[0];
EquipmentSlot lastHand = (EquipmentSlot) lastEvent[1];
long timeSince = systemTime - lastTime;
if (timeSince < 50 && !eventHand.equals(lastHand)) {
performLookup = false;
}
}
if (performLookup) {
final Player finalPlayer = player;
final BlockState finalBlock = event.getClickedBlock().getRelative(event.getBlockFace()).getState();
class BasicThread implements Runnable {
@Override
public void run() {
if (ConfigHandler.converterRunning) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
return;
}
if (ConfigHandler.purgeRunning) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS));
return;
}
if (ConfigHandler.lookupThrottle.get(finalPlayer.getName()) != null) {
Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(finalPlayer.getName());
if ((boolean) lookupThrottle[0] || (System.currentTimeMillis() - (long) lookupThrottle[1]) < 100) {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
return;
}
}
ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { true, System.currentTimeMillis() });
try (Connection connection = Database.getConnection(true)) {
if (connection != null) {
Statement statement = connection.createStatement();
if (finalBlock.getType().equals(Material.AIR) || finalBlock.getType().equals(Material.CAVE_AIR)) {
String blockData = BlockLookup.performLookup(null, statement, finalBlock, finalPlayer, 0, 1, 7);
if (blockData.contains("\n")) {
for (String b : blockData.split("\n")) {
Chat.sendComponent(finalPlayer, b);
}
}
else if (blockData.length() > 0) {
Chat.sendComponent(finalPlayer, blockData);
}
}
else {
String blockData = BlockLookup.performLookup(null, statement, finalBlock, finalPlayer, 0, 1, 7);
if (blockData.contains("\n")) {
for (String splitData : blockData.split("\n")) {
Chat.sendComponent(finalPlayer, splitData);
}
}
else if (blockData.length() > 0) {
Chat.sendComponent(finalPlayer, blockData);
}
}
statement.close();
}
else {
Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY));
}
}
catch (Exception e) {
e.printStackTrace();
}
ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { false, System.currentTimeMillis() });
}
}
Runnable runnable = new BasicThread();
Thread thread = new Thread(runnable);
thread.start();
Util.updateInventory(event.getPlayer());
lastInspectorEvent.put(uuid, new Object[] { systemTime, eventHand });
if (event.hasItem()) {
Material eventItem = event.getItem().getType();
if (eventItem.isBlock() && (eventItem.createBlockData() instanceof Bisected)) {
int x = finalBlock.getX();
int y = finalBlock.getY();
int z = finalBlock.getZ();
int worldMaxHeight = world.getMaxHeight();
if (y < (worldMaxHeight - 1)) {
Block blockBisected = world.getBlockAt(x, y + 1, z);
player.sendBlockChange(blockBisected.getLocation(), blockBisected.getBlockData());
}
int worldMinHeight = BukkitAdapter.ADAPTER.getMinHeight(world);
if (y > worldMinHeight) {
Block blockBisected = world.getBlockAt(x, y - 1, z);
player.sendBlockChange(blockBisected.getLocation(), blockBisected.getBlockData());
}
}
}
}
event.setCancelled(true);
}
}
}
}
@EventHandler(priority = EventPriority.MONITOR)
protected void onPlayerInteract_Monitor(PlayerInteractEvent event) {
protected void onPlayerInteract(PlayerInteractEvent event) {
/* Logging for players punching out fire blocks. */
if (event.getAction().equals(Action.LEFT_CLICK_BLOCK)) {
World world = event.getClickedBlock().getWorld();
@@ -554,7 +534,7 @@ public final class PlayerInteractListener extends Queue implements Listener {
if (Tag.SIGNS.isTagged(type)) {
// check if right clicked sign with dye
Set<Material> DYES = EnumSet.of(Material.BLACK_DYE, Material.BLUE_DYE, Material.BROWN_DYE, Material.CYAN_DYE, Material.GRAY_DYE, Material.GREEN_DYE, Material.LIGHT_BLUE_DYE, Material.LIGHT_GRAY_DYE, Material.LIME_DYE, Material.MAGENTA_DYE, Material.ORANGE_DYE, Material.PINK_DYE, Material.PURPLE_DYE, Material.RED_DYE, Material.WHITE_DYE, Material.YELLOW_DYE);
Set<Material> dyeSet = EnumSet.of(Material.BLACK_DYE, Material.BLUE_DYE, Material.BROWN_DYE, Material.CYAN_DYE, Material.GRAY_DYE, Material.GREEN_DYE, Material.LIGHT_BLUE_DYE, Material.LIGHT_GRAY_DYE, Material.LIME_DYE, Material.MAGENTA_DYE, Material.ORANGE_DYE, Material.PINK_DYE, Material.PURPLE_DYE, Material.RED_DYE, Material.WHITE_DYE, Material.YELLOW_DYE);
Material handType = null;
ItemStack mainHand = player.getInventory().getItemInMainHand();
@@ -562,7 +542,7 @@ public final class PlayerInteractListener extends Queue implements Listener {
handType = mainHand.getType();
}
if (handType != null && (DYES.contains(handType) || handType.name().endsWith("INK_SAC")) && Config.getConfig(block.getWorld()).SIGN_TEXT) {
if (handType != null && (dyeSet.contains(handType) || handType.name().endsWith("INK_SAC")) && Config.getConfig(block.getWorld()).SIGN_TEXT) {
BlockState blockState = block.getState();
Sign sign = (Sign) blockState;
String line1 = sign.getLine(0);
@@ -574,11 +554,11 @@ public final class PlayerInteractListener extends Queue implements Listener {
boolean oldGlowing = BukkitAdapter.ADAPTER.isGlowing(sign);
boolean newGlowing = oldGlowing;
if (DYES.contains(handType)) {
if (dyeSet.contains(handType)) {
newColor = (DyeColor.valueOf(handType.name().replaceFirst("_DYE", ""))).getColor().asRGB();
}
else {
newGlowing = (handType == Material.INK_SAC ? false : true);
newGlowing = (handType != Material.INK_SAC);
}
if (oldGlowing != newGlowing || oldColor != newColor) {
@@ -590,20 +570,18 @@ public final class PlayerInteractListener extends Queue implements Listener {
}
}
else if (BlockGroup.INTERACT_BLOCKS.contains(type)) {
if (event.getHand().equals(EquipmentSlot.HAND)) {
if (Config.getConfig(world).PLAYER_INTERACTIONS) {
Block interactBlock = event.getClickedBlock();
if (BlockGroup.DOORS.contains(type)) {
int y = interactBlock.getY() - 1;
Block blockUnder = interactBlock.getWorld().getBlockAt(interactBlock.getX(), y, interactBlock.getZ());
if (event.getHand().equals(EquipmentSlot.HAND) && Config.getConfig(world).PLAYER_INTERACTIONS) {
Block interactBlock = event.getClickedBlock();
if (BlockGroup.DOORS.contains(type)) {
int y = interactBlock.getY() - 1;
Block blockUnder = interactBlock.getWorld().getBlockAt(interactBlock.getX(), y, interactBlock.getZ());
if (blockUnder.getType().equals(type)) {
interactBlock = blockUnder;
}
if (blockUnder.getType().equals(type)) {
interactBlock = blockUnder;
}
Queue.queuePlayerInteraction(player.getName(), interactBlock.getState());
}
Queue.queuePlayerInteraction(player.getName(), interactBlock.getState());
}
}
else if (BlockGroup.LIGHTABLES.contains(type)) { // extinguishing a lit block such as a campfire
@@ -611,6 +589,7 @@ public final class PlayerInteractListener extends Queue implements Listener {
if (blockData instanceof Lightable && ((Lightable) blockData).isLit() && ((BlockGroup.CANDLES.contains(type) && event.getMaterial() == Material.AIR) || (!BlockGroup.CANDLES.contains(type) && event.getMaterial().name().endsWith("_SHOVEL")))) {
((Lightable) blockData).setLit(false);
Queue.queueBlockPlace(player.getName(), block.getState(), type, block.getState(), type, -1, 0, blockData.getAsString());
/*
BlockState blockState = block.getState();
Bukkit.getServer().getScheduler().runTask(CoreProtect.getInstance(), () -> {
@@ -659,7 +638,7 @@ public final class PlayerInteractListener extends Queue implements Listener {
int y = location.getBlockY();
int z = location.getBlockZ();
String coordinates = x + "." + y + "." + z + "." + wid + "." + userUUID;
CacheHandler.interactCache.put(coordinates, new Object[] { time, block.getState() });
CacheHandler.interactCache.put(coordinates, new Object[] { time, Material.CAKE, block.getState() });
}
}
@@ -686,11 +665,9 @@ public final class PlayerInteractListener extends Queue implements Listener {
boolean exists = false;
for (Entity entity : crystalLocation.getChunk().getEntities()) {
if (entity instanceof EnderCrystal) {
if (entity.getLocation().getBlockX() == crystalLocation.getBlockX() && entity.getLocation().getBlockY() == crystalLocation.getBlockY() && entity.getLocation().getBlockZ() == crystalLocation.getBlockZ()) {
exists = true;
break;
}
if (entity instanceof EnderCrystal && entity.getLocation().getBlockX() == crystalLocation.getBlockX() && entity.getLocation().getBlockY() == crystalLocation.getBlockY() && entity.getLocation().getBlockZ() == crystalLocation.getBlockZ()) {
exists = true;
break;
}
}
@@ -703,13 +680,11 @@ public final class PlayerInteractListener extends Queue implements Listener {
int showingBottom = 0;
for (Entity entity : locationFinal.getChunk().getEntities()) {
if (entity instanceof EnderCrystal) {
if (entity.getLocation().getBlockX() == locationFinal.getBlockX() && entity.getLocation().getBlockY() == locationFinal.getBlockY() && entity.getLocation().getBlockZ() == locationFinal.getBlockZ()) {
EnderCrystal enderCrystal = (EnderCrystal) entity;
showingBottom = enderCrystal.isShowingBottom() ? 1 : 0;
blockExists = true;
break;
}
if (entity instanceof EnderCrystal && entity.getLocation().getBlockX() == locationFinal.getBlockX() && entity.getLocation().getBlockY() == locationFinal.getBlockY() && entity.getLocation().getBlockZ() == locationFinal.getBlockZ()) {
EnderCrystal enderCrystal = (EnderCrystal) entity;
showingBottom = enderCrystal.isShowingBottom() ? 1 : 0;
blockExists = true;
break;
}
}
if (blockExists) {
@@ -739,10 +714,7 @@ public final class PlayerInteractListener extends Queue implements Listener {
}
else if (event.getAction().equals(Action.PHYSICAL)) {
Block block = event.getClickedBlock();
if (block == null) {
return;
}
else if (!block.getType().equals(Material.FARMLAND) && !block.getType().equals(Material.TURTLE_EGG)) {
if (block == null || (!block.getType().equals(Material.FARMLAND) && !block.getType().equals(Material.TURTLE_EGG))) {
return;
}
@@ -11,34 +11,41 @@ import org.bukkit.event.world.PortalCreateEvent;
import net.coreprotect.config.Config;
import net.coreprotect.consumer.Queue;
import net.coreprotect.database.Lookup;
import net.coreprotect.utility.Util;
public final class PortalCreateListener extends Queue implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
protected void OnPortalCreate(PortalCreateEvent event) {
protected void onPortalCreate(PortalCreateEvent event) {
World world = event.getWorld();
if (!event.isCancelled() && Config.getConfig(world).PORTALS) {
String user = "#portal";
if (event.isCancelled() || !Config.getConfig(world).PORTALS) {
return;
}
for (BlockState block : event.getBlocks()) {
Material type = block.getType();
if (type == Material.NETHER_PORTAL || type == Material.FIRE) {
String resultData = Lookup.whoPlacedCache(block);
if (resultData.length() > 0) {
user = resultData;
break;
}
String user = "#portal";
for (BlockState block : event.getBlocks()) {
Material type = block.getType();
if (type == Material.NETHER_PORTAL || type == Material.FIRE) {
String resultData = Lookup.whoPlacedCache(block);
if (resultData.length() > 0) {
user = resultData;
break;
}
}
}
for (BlockState blockState : event.getBlocks()) {
Material type = blockState.getType();
if (user.equals("#portal")) {
Queue.queueBlockPlace(user, blockState, blockState.getBlock().getType(), null, type, -1, 0, blockState.getBlockData().getAsString());
}
else if (!type.equals(Material.OBSIDIAN)) {
Queue.queueBlockPlace(user, blockState, blockState.getBlock().getType(), null, type, -1, 0, blockState.getBlockData().getAsString());
}
for (BlockState blockState : event.getBlocks()) {
Material type = blockState.getType();
BlockState oldBlock = blockState.getBlock().getState();
if (oldBlock.equals(blockState)) {
continue;
}
if (Util.isAir(type)) {
Queue.queueBlockBreak(user, oldBlock, oldBlock.getType(), oldBlock.getBlockData().getAsString(), 0);
}
else {
Queue.queueBlockPlace(user, blockState, oldBlock.getType(), oldBlock, type, -1, 0, blockState.getBlockData().getAsString());
}
}
}
@@ -11,7 +11,7 @@ import net.coreprotect.config.ConfigHandler;
public final class BlockGroup {
public static Set<Material> TRACK_ANY = new HashSet<>(Arrays.asList(Material.MOVING_PISTON, Material.LEVER, Material.BELL));
public static Set<Material> TRACK_ANY = new HashSet<>(Arrays.asList(Material.PISTON_HEAD, Material.LEVER, Material.BELL));
public static Set<Material> TRACK_TOP_BOTTOM = new HashSet<>(Arrays.asList());
public static Set<Material> TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP));
public static Set<Material> TRACK_BOTTOM = new HashSet<>(Arrays.asList());
@@ -0,0 +1,49 @@
package net.coreprotect.paper;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import net.coreprotect.bukkit.BukkitAdapter;
import net.coreprotect.config.ConfigHandler;
public class PaperAdapter implements PaperInterface {
public static PaperInterface ADAPTER;
public static final int PAPER_UNAVAILABLE = 0;
public static final int PAPER_V1_13 = BukkitAdapter.BUKKIT_V1_13;
public static final int PAPER_V1_14 = BukkitAdapter.BUKKIT_V1_14;
public static final int PAPER_V1_15 = BukkitAdapter.BUKKIT_V1_15;
public static final int PAPER_V1_16 = BukkitAdapter.BUKKIT_V1_16;
public static final int PAPER_V1_17 = BukkitAdapter.BUKKIT_V1_17;
public static final int PAPER_V1_18 = BukkitAdapter.BUKKIT_V1_18;
public static void loadAdapter() {
int paperVersion = ConfigHandler.SERVER_VERSION;
if (!ConfigHandler.isPaper) {
paperVersion = PAPER_UNAVAILABLE;
}
switch (paperVersion) {
case PAPER_UNAVAILABLE:
PaperAdapter.ADAPTER = new PaperAdapter();
break;
case PAPER_V1_13:
case PAPER_V1_14:
case PAPER_V1_15:
PaperAdapter.ADAPTER = new PaperHandler();
break;
case PAPER_V1_16:
case PAPER_V1_17:
case PAPER_V1_18:
default:
PaperAdapter.ADAPTER = new Paper_v1_16();
break;
}
}
@Override
public InventoryHolder getHolder(Inventory holder, boolean useSnapshot) {
return holder.getHolder();
}
}
@@ -0,0 +1,5 @@
package net.coreprotect.paper;
public class PaperHandler extends PaperAdapter implements PaperInterface {
}
Loaded 100 of 115 files, more files were not shown because too many files have changed in this diff. Show more