26 Commits
Author SHA1 Message Date
Intelli 78ef45d049 CoreProtect v21.3 release 2022-12-09 14:55:54 -07:00
Intelli 2f28183261 Fixed NoSuchMethodErrorr when stopping server using Paper 1.14 2022-12-08 17:55:30 -07:00
Intelli d82f92e06b Fixed tab completion not fully respecting player permissions (#226) 2022-12-08 17:35:03 -07:00
Intelli ce5c1c50bf Added logging for player inventory transactions with allays 2022-12-08 16:24:53 -07:00
Intelli 026b9ce322 Fixed IllegalStateException when modifying containers using FAWE 2022-12-08 13:56:14 -07:00
Intelli 3cedc69205 Added extended support for mangrove blocks 2022-12-07 19:52:54 -07:00
Intelli f4fe410141 Added logging and rollback support for tadpole age data 2022-12-07 19:14:44 -07:00
Intelli e3b82858b4 Updated config description regarding donation keys 2022-12-07 18:56:18 -07:00
Intelli 990f90bab9 Rename #sculk to #sculk_catalyst 2022-12-07 18:38:40 -07:00
Ryan HustonandIntelli 3b349c9d07 Add support for 1.19 specific features. (#239)
* Added support for 1.19 specific features.

* Removed leftover import from testing

* Added missing sculk materials for the catalyst and changed user field to #sculk

* Reverted version to v21.2

Co-authored-by: Intelli <6790859+Intelli@users.noreply.github.com>
2022-12-07 18:26:45 -07:00
Intelli 319d104622 Fixed NullPointerException when killing NPC (#261) 2022-12-07 17:49:50 -07:00
Intelli 9f8c2e8a2f Set Hikari maxLifetime to 5m, keepaliveTime to 1m (fixes #199) 2022-09-26 15:22:07 -06:00
Intelli fcd789ef5b Bump mkdocs from 1.2.3 to 1.3.1 2022-09-09 16:01:48 -06:00
dkim19375 b450f4d05a Make version comparisons by long - Support WorldEdit 7.2.11 Beta 1 (#240) (Fixes #245) 2022-06-27 20:15:23 -06:00
Intelli 606c043bf0 Fixed NullPointerException when processing hopper transactions 2022-04-19 20:07:56 -06:00
Intelli 4b056d9474 Added default Turkish language file 2022-04-19 20:00:53 -06:00
Intelli 1cca7bc573 Updated de.yml (fixes #203) 2022-04-13 19:41:18 -06:00
Intelli 204456d6c5 Fixed queueLookup API method returning data in wrong order 2022-03-25 16:50:05 -06:00
Intelli d34b60dc8f Improved database index handling 2022-03-24 19:16:57 -06:00
Intelli 070c5139e1 Fixed IllegalArgumentException when processing corrupt data 2022-03-24 17:11:58 -06:00
流光溢彩Last 1974838f74 Update v21.0 Simplified Chinese translation. (#182)
* Update v21.0 Simplified Chinese translation.

* 完善翻译
2022-03-23 19:08:47 -06:00
Intelli acdfb3515b Fixed NullPointerException on disable if plugin failed to load 2022-03-23 18:56:53 -06:00
vaclaandIntelli 8cdf99429d Added Networking API (#180)
* sent data to client

* send more data + debug + add docs + switch to handshake

* add diff between container and normal changes

* fix docs

* changes according guidelines

* make requested changes + cleanup

* correct documentation

* Improved Networking API documentation

* Moved networking API channel registration out of main class

* Cleanup

* Removed debug on chat/command lookups

* Optimized array merging

* Fixed ClassCastException when running console commands

* Skip preparing networking data if not a channel player

* Renamed "networking-debug" to "network-debug"

* Fixed failed handshake still registering players

* Adjusted networking phrases

* Renamed pluginchannel to channel

Co-authored-by: Intelli <contact@intelli.software>
2022-03-23 18:49:46 -06:00
Intelli e848d65b93 Added missing command/permissions to documentation 2022-03-22 17:24:54 -06:00
Intelli 85ebd53e5f Minor Spanish tweaks 2022-03-21 18:48:40 -06:00
KrazyxWolfandIntelli 209c63b009 Improved Spanish translation (#179)
* Not too literal spanish

* Fixes and adjustments

* Fix

* Minor fixes

Co-authored-by: Intelli <6790859+Intelli@users.noreply.github.com>
2022-03-21 18:21:08 -06:00
45 changed files with 1169 additions and 239 deletions

No files matched your search

+2 -3
View File
@@ -7,7 +7,7 @@ plugins {
}
group = 'net.coreprotect'
String projectVersion = '21.2'
String projectVersion = '21.3'
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.'
@@ -34,7 +34,7 @@ dependencies {
compileOnly('com.sk89q.worldedit:worldedit-bukkit:7.0.0-SNAPSHOT') {
exclude group: 'org.bukkit'
}
compileOnly 'io.papermc.paper:paper-api:1.18.1-R0.1-SNAPSHOT'
compileOnly 'io.papermc.paper:paper-api:1.19-R0.1-SNAPSHOT'
implementation 'org.bstats:bstats-bukkit-lite:1.8'
implementation 'com.zaxxer:HikariCP:4.0.3'
}
@@ -85,4 +85,3 @@ processResources {
}
})
}
+99
View File
@@ -0,0 +1,99 @@
# Networking API
The CoreProtect Networking API allows clients to receive data using packets.
| Networking Details | |
|-------------------------|--------|
| **Networking Version:** | 1 |
| **Plugin Version:** | v21.3+ |
---
## Packets
The server will not respond unless the player has the correct permission, which is `coreprotect.networking`.
---
## Server to Client
### Data Packet
Sends data from the database.
* Channel: `coreprotect:data`
| Type: `Int` | 1 | 2 | 3 | 4 |
|-------------|------------------------|------------------------|--------------------|--------------------|
| | Time: `long` | Time: `long` | Time: `long` | Time: `long` |
| | Phrase selector: `UTF` | Phrase selector: `UTF` | Result User: `UTF` | Result User: `UTF` |
| | Result User: `UTF` | Result User: `UTF` | Message: `UTF` | Target: `UTF` |
| | Target: `UTF` | Amount: `Int` | Sign: `Boolean` | |
| | Amount: `Int` | X: `Int` | X: `Int` | |
| | X: `Int` | Y: `Int` | Y: `Int` | |
| | Y: `Int` | Z: `Int` | Z: `Int` | |
| | Z: `Int` | World name: `UTF` | World name: `UTF` | |
| | World name: `UTF` | | | |
| | Rolledback: `Boolean` | | | |
| | isContainer: `Boolean` | | | |
| | Added: `Boolean` | | | |
Example (Fabric):
```
ByteArrayInputStream in = new ByteArrayInputStream(buf.getWrittenBytes());
DataInputStream dis = new DataInputStream(in);
int type = dis.readInt();
long time = dis.readLong();
String selector = dis.readUTF();
String resultUser = dis.readUTF();
String target = dis.readUTF();
int amount = dis.readInt();
int x = dis.readInt();
int y = dis.readInt();
int z = dis.readInt();
String worldName = dis.readUTF();
boolean rolledback = dis.readBoolean();
boolean isContainer = dis.readBoolean();
boolean added = dis.readBoolean();
```
### Handshake Packet
Sends handshake if player is registered.
* Channel: `coreprotect:handshake`
* Registered: `Boolean`
---
## Client to Server
### Handshake Packet
Sends handshake to register
* Channel: `coreprotect:handshake`
* Mod Version: `UTF`
* Mod Id: `UTF`
* CoreProtect Protocol: `Int`
Example (Fabric):
```
PacketByteBuf packetByteBuf = new PacketByteBuf(Unpooled.buffer());
ByteArrayOutputStream msgBytes = new ByteArrayOutputStream();
DataOutputStream msgOut = new DataOutputStream(msgBytes);
msgOut.writeUTF(modVersion);
msgOut.writeUTF(modId);
msgOut.writeInt(coreprotectProtocol);
packetByteBuf.writeBytes(msgBytes.toByteArray());
```
---
## Debugging
### /co network-debug
Allows you to debug the networking API if you are registered and have correct permissions.
To utilize the command, `network-debug: true` must be set in the CoreProtect `config.yml`.
**Example**
`/co network-debug <type>`
___
+5
View File
@@ -15,6 +15,7 @@ ___
| [/co purge](#co-purge) | Delete old block data |
| [/co reload](#co-reload) | Reload the configuration file |
| [/co status](#co-status) | View the plugin status |
| [/co consumer](#co-consumer) | Toggle consumer processing |
### Alias Commands
@@ -119,6 +120,10 @@ ___
Displays the plugin status and version information.
___
### /co consumer
Console command to pause or resume consumer queue processing.
___
## Parameter Details
+3
View File
@@ -12,6 +12,9 @@ A list of all commands that can be used within CoreProtect.
[**CoreProtect Permissions**](/permissions/)
A list of all permissions that can be used with CoreProtect.
[**CoreProtect Language Codes**](/languages/)
A list of all language codes that can be used with CoreProtect.
[**CoreProtect API Documentation**](/api/)
Log your own block changes, perform lookups, rollbacks, restores, and more.
+9
View File
@@ -35,6 +35,12 @@ The following permissions can be used to restrict functionality within the plugi
&nbsp;
* **coreprotect.status** *(default: op)*
Allows access to the CoreProtect status command.
&nbsp;
* **coreprotect.consumer** *(default: op)*
Allows access to the CoreProtect consumer command.
&nbsp;
* **coreprotect.networking** *(default: op)*
Allows access to the CoreProtect networking API.
---
@@ -58,6 +64,9 @@ The following permissions can be used to restrict functionality within the plugi
* **coreprotect.lookup.inventory** *(default: op)*
Can be optionally used as a negative permission to prevent inventory lookups.
&nbsp;
* **coreprotect.lookup.item** *(default: op)*
Can be optionally used as a negative permission to prevent item lookups.
&nbsp;
* **coreprotect.lookup.kill** *(default: op)*
Can be optionally used as a negative permission to prevent entity kill lookups.
&nbsp;
+2 -2
View File
@@ -104,7 +104,7 @@ LINK_WIKI_BLOCK: "Blocknamen: {0}"
LINK_WIKI_ENTITY: "Entitätsnamen: {0}"
LOGGING_ITEMS: "{0} Elemente, die noch zu loggen sind. Warten Sie mal..."
LOGGING_TIME_LIMIT: "Zeitlimit für die Protokollierung erreicht. Daten verwerfen und herunterfahren."
LOOKUP_BLOCK: "{0} {platziert|kaputt} {1}."
LOOKUP_BLOCK: "{0} {platziert|entfernt} {1}."
LOOKUP_CONTAINER: "{0} {hinzugefügt|entfernt} {1} {2}."
LOOKUP_HEADER: "{0} Ergebnisse"
LOOKUP_INTERACTION: "{0} {angeklickt|getötet} {1}."
@@ -198,4 +198,4 @@ USING_SQLITE: "Verwenden von SQLite zur Datenspeicherung."
VALID_DONATION_KEY: "Gültiger Spendenschlüssel."
VERSION_NOTICE: "Ausführung {0} ist nun verfügbar."
VERSION_REQUIRED: "{0} {1} oder höher erforderlich."
WORLD_NOT_FOUND: "Welt \"{0}\" nicht gefunden."
WORLD_NOT_FOUND: "Welt \"{0}\" nicht gefunden."
+2
View File
@@ -125,6 +125,8 @@ MISSING_PARAMETERS: "Please use \"{0}\"."
MISSING_ROLLBACK_RADIUS: "You did not specify a {rollback|restore} radius."
MISSING_ROLLBACK_USER: "You did not specify a {rollback|restore} user."
MYSQL_UNAVAILABLE: "Unable to connect to MySQL server."
NETWORK_CONNECTION: "Connection by {0} {successful|failed}. Using {1} {2}."
NETWORK_TEST: "Network test data has been successful sent."
NO_DATA: "No data found at {0}."
NO_DATA_LOCATION: "No {data|transactions|interactions|messages} found at this location."
NO_PERMISSION: "You do not have permission to do that."
+166 -166
View File
@@ -1,201 +1,201 @@
# CoreProtect Language File (es)
ACTION_NOT_SUPPORTED: "Esa acción no es compatible."
ACTION_NOT_SUPPORTED: "Está acción no es compatible con el comando."
AMOUNT_BLOCK: "{0} {bloque|bloques}"
AMOUNT_CHUNK: "{0} {trozo|trozos}"
AMOUNT_CHUNK: "{0} {chunk|chunks}"
AMOUNT_ENTITY: "{0} {entidad|entidades}"
AMOUNT_ITEM: "{0} {artículo|artículos}"
API_TEST: "Prueba de API exitosa."
CACHE_ERROR: "ADVERTENCIA: Error al validar {0} cache."
CACHE_RELOAD: "Forzando la recarga de {mapeo|mundo} cachés de la base de datos."
CHECK_CONFIG: "Por favor revise config.yml"
COMMAND_CONSOLE: "Ejecute el comando desde la consola."
COMMAND_NOT_FOUND: "Comando \"{0}\" extraviado."
COMMAND_THROTTLED: "Espere un momento y vuelva a intentarlo."
CONSUMER_ERROR: "Procesamiento de colas de consumidores ya {en pausa|reanudado}."
CONSUMER_TOGGLED: "El procesamiento de la cola del consumidor ha sido {en pausa|reanudado}."
CONTAINER_HEADER: "Transacciones de contenedores"
DATABASE_BUSY: "Base de datos ocupado. Por favor, inténtelo de nuevo más tarde."
DATABASE_INDEX_ERROR: "No se pueden validar los índices de la base de datos."
DATABASE_LOCKED_1: "Base de datos bloqueada. Esperando hasta 15 segundos..."
DATABASE_LOCKED_2: "La base de datos ya está en uso. Inténtalo de nuevo."
DATABASE_LOCKED_3: "Para deshabilitar el bloqueo de la base de datos, establezca \"database-lock: false\"."
DATABASE_LOCKED_4: "La desactivación del bloqueo de la base de datos puede provocar daños en los datos."
DATABASE_UNREACHABLE: "La base de datos es inalcanzable. Descartando datos y cerrando."
DEVELOPMENT_BRANCH: "Se detectó una rama de desarrollo, omitiendo los scripts de parches."
DIRT_BLOCK: "Colocó un bloque de tierra debajo de usted."
DISABLE_SUCCESS: "¡Éxito! Discapacitado {0}"
ENABLE_FAILED: "{0} fue incapaz de comenzar."
ENABLE_SUCCESS: "{0} ahora está habilitado!"
ENJOY_COREPROTECT: "Disfrutar {0}? Únete a nuestro Discord!"
FINISHING_CONVERSION: "Terminando la conversión de datos. Espere por favor..."
FINISHING_LOGGING: "Terminando el registro de datos. Espere por favor..."
FIRST_VERSION: "DB inicial: {0}"
GLOBAL_LOOKUP: "No especifique un radio para realizar una búsqueda global."
GLOBAL_ROLLBACK: "Usar \"{0}\" para hacer un global {deshacer|restaurar}"
HELP_ACTION_1: "Restrinja la búsqueda a una acción."
AMOUNT_ITEM: "{0} {objeto|objetos}"
API_TEST: "Testeo de la API exitosa."
CACHE_ERROR: "ADVERTENCIA: Error mientras se validaba el caché {0}."
CACHE_RELOAD: "Forzando recarga de cachés desde la base de datos de {mapeado|mundo}."
CHECK_CONFIG: "Por favor revise su config.yml"
COMMAND_CONSOLE: "Intente ejecutar el comando desde la consola."
COMMAND_NOT_FOUND: "Comando \"{0}\" no encontrado."
COMMAND_THROTTLED: "Espere un momento e intente nuevamente."
CONSUMER_ERROR: "La espera en el procesamiento del consumidor ha sido {pausada|continuada}."
CONSUMER_TOGGLED: "Consumer queue processing has been {pausado|continuado}."
CONTAINER_HEADER: "Transacciones del contenedor"
DATABASE_BUSY: "Base de datos ocupada. Intente más tarde."
DATABASE_INDEX_ERROR: "Imposible validar los indices de la base de datos."
DATABASE_LOCKED_1: "Base de datos bloqueada. Espere en los siguientes 15 segundos..."
DATABASE_LOCKED_2: "Base de datos ya en uso. Intente nuevamente."
DATABASE_LOCKED_3: "Para desactivar el bloqueo de la base de datos, coloque \"database-lock: false\"."
DATABASE_LOCKED_4: "Desactivando el bloqueo en la base de datos resultaría en una posible corrupción de datos."
DATABASE_UNREACHABLE: "No se pudo alcanzar la base de datos. Descartando datos y apagando."
DEVELOPMENT_BRANCH: "Rama de desarrollo detectada, saltando scripts de parche."
DIRT_BLOCK: "Se ha colocado un bloque de tierra debajo de tí."
DISABLE_SUCCESS: "¡Se ha desactivado extosamente {0}!"
ENABLE_FAILED: "Imposible de iniciar {0}."
ENABLE_SUCCESS: "¡{0} ha sido exitosamente activado!"
ENJOY_COREPROTECT: "¿Disfrutando {0}? ¡Ingrese a nuestro Discord!"
FINISHING_CONVERSION: "Terminando la conversión de datos. Espere..."
FINISHING_LOGGING: "Terminando el registro de datos. Espere..."
FIRST_VERSION: "Base de datos inicial: {0}"
GLOBAL_LOOKUP: "No especificaste el radio para una busqueda global."
GLOBAL_ROLLBACK: "Usa \"{0}\" para hacer un {respaldo|restauración} global"
HELP_ACTION_1: "Restringir la busqueda a una acción."
HELP_ACTION_2: "Ejemplos: [a:block], [a:+block], [a:-block] [a:click], [a:container], [a:inventory], [a:item], [a:kill], [a:chat], [a:command], [a:sign], [a:session], [a:username]"
HELP_COMMAND: "Muestra información adicional."
HELP_EXCLUDE_1: "Excluir bloques / usuarios."
HELP_COMMAND: "Mostrar información sobre un comando."
HELP_EXCLUDE_1: "Excluir bloques/usuarios."
HELP_EXCLUDE_2: "Ejemplos: [e:stone], [e:Notch], [e:stone,Notch]"
HELP_HEADER: "{0} Ayudar"
HELP_INCLUDE_1: "Incluya bloques / entidades."
HELP_HEADER: "Ayuda {0}"
HELP_INCLUDE_1: "Incluir bloques/entidades exactos."
HELP_INCLUDE_2: "Ejemplos: [i:stone], [i:zombie], [i:stone,wood,bedrock]"
HELP_INSPECT_1: "Con el inspector habilitado, puede:"
HELP_INSPECT_2: "Haga clic con el botón izquierdo para ver la ubicación."
HELP_INSPECT_3: "Haga clic derecho para ver las eliminaciones adyacentes."
HELP_INSPECT_4: "Coloque un bloque para ver la eliminación."
HELP_INSPECT_5: "Coloque un bloque en líquido para ver la ubicación."
HELP_INSPECT_6: "Haga clic derecho para ver las transacciones del cofre."
HELP_INSPECT_7: "Sugerencia: puede usar solo \"/co i\"."
HELP_INSPECT_COMMAND: "Alterna el inspector de bloques."
HELP_INSPECT_1: "Con el inspeccionador activo, puedes hacer lo siguiente:"
HELP_INSPECT_2: "Clic izquierdo para ver quien colocó ese bloque."
HELP_INSPECT_3: "Clic derecho para ver quien rompió el bloque de encima."
HELP_INSPECT_4: "Coloca un bloque para ver si se ha roto alguno en la zona."
HELP_INSPECT_5: "Coloca el bloque en un liquido (etc) para ver quien lo colocó."
HELP_INSPECT_6: "Clic derecho sobre un cofres y ver sus transacciones."
HELP_INSPECT_7: "Consejo: Puedes usar \"/co i\" para un acceso rápido."
HELP_INSPECT_COMMAND: "Alterna el revisor de bloques."
HELP_LIST: "Muestra una lista de todos los comandos."
HELP_LOOKUP_1: "Atajo de comando."
HELP_LOOKUP_2: "Ver páginas adicionales."
HELP_LOOKUP_COMMAND: "Búsqueda de datos de bloques."
HELP_NO_INFO: "Información para el mando \"{0}\" extraviado."
HELP_PARAMETER: "Por favor mira \"{0}\" para obtener información detallada sobre los parámetros."
HELP_PARAMS_1: "Realizar el {buscar|deshacer|restaurar}."
HELP_PARAMS_2: "Especifique los usuarios para {buscar|deshacer|restaurar}."
HELP_PARAMS_3: "Especifique el tiempo para {buscar|deshacer|restaurar}."
HELP_PARAMS_4: "Restringir el {buscar|deshacer|restaurar} a un radio."
HELP_PARAMS_5: "Restringir el {buscar|deshacer|restaurar} a una acción."
HELP_PARAMS_6: "Incluir bloques / entidades en el {buscar|deshacer|restaurar}."
HELP_PARAMS_7: "Excluir bloques / usuarios del {buscar|deshacer|restaurar}."
HELP_PURGE_1: "Eliminar datos antiguos."
HELP_PURGE_2: "Por ejemplo, \"{0}\" eliminará todos los datos anteriores a un mes y solo conservará los datos de los últimos 30 días."
HELP_PURGE_COMMAND: "Elimina los datos del bloque antiguo."
HELP_RADIUS_1: "Especifique un área de radio."
HELP_RADIUS_2: "Ejemplos: [r:10] (Solo haga cambios dentro de las 10 cuadras de usted)"
HELP_RELOAD_COMMAND: "Vuelve a cargar el archivo de configuración."
HELP_RESTORE_COMMAND: "Restaurar los datos del bloque."
HELP_ROLLBACK_COMMAND: "Revertir los datos del bloque."
HELP_STATUS: "Ver el estado del complemento."
HELP_STATUS_COMMAND: "Muestra el estado del complemento."
HELP_TELEPORT: "Teletransportarse."
HELP_TIME_1: "Especifique la hora."
HELP_LOOKUP_1: "Atajo de comandos."
HELP_LOOKUP_2: "Mostrar páginas adicionales."
HELP_LOOKUP_COMMAND: "Busqueda de bloques avanzada."
HELP_NO_INFO: "Información para el comando \"{0}\" no encontrada."
HELP_PARAMETER: "Revisa \"{0}\" para una información más detallada."
HELP_PARAMS_1: "Ingrese la {búsqueda|respaldo|restauración}."
HELP_PARAMS_2: "Especifique al usuario a {buscar|respaldar|restaurar}."
HELP_PARAMS_3: "Especifique la cantidad de tiempo a {buscar|respaldar|restaurar}."
HELP_PARAMS_4: "Especifique el radio de area a {buscar|respaldar|restaurar}."
HELP_PARAMS_5: "Restringir la {búsqueda|respaldo|restauración} a una acción dada."
HELP_PARAMS_6: "Incluir bloques/entidades exactas a {buscar|respaldar|restaurar}."
HELP_PARAMS_7: "Excluir bloques/usuarios a {buscar|respaldar|resturar}."
HELP_PURGE_1: "Eliminar los datos en un tiempo dado."
HELP_PURGE_2: "Por ejemplo, \"{0}\" eliminará los datos que sean más viejos, y solo mantendrá lo que está en los 30d."
HELP_PURGE_COMMAND: "Elimina los datos de bloques viejos."
HELP_RADIUS_1: "Especifica un radio del area."
HELP_RADIUS_2: "Ejemplos: [r:10] (Solo cambiará 10 bloques delante de ti)"
HELP_RELOAD_COMMAND: "Recarga los archivos de configuración."
HELP_RESTORE_COMMAND: "Restaurar los datos de bloques."
HELP_ROLLBACK_COMMAND: "Restaurar bloques."
HELP_STATUS: "Muestra el estado del plugin y su información."
HELP_STATUS_COMMAND: "Muestra el estado del plugin."
HELP_TELEPORT: "Teletransportar a una coordenada."
HELP_TIME_1: "Especifique una cantidad de tiempo."
HELP_TIME_2: "Ejemplos: [t:2w,5d,7h,2m,10s], [t:5d2h], [t:2.50h]"
HELP_USER_1: "Especifique los usuarios."
HELP_USER_1: "Especifica al usuario para buscar."
HELP_USER_2: "Ejemplos: [u:Notch], [u:Notch,#enderman]"
INCOMPATIBLE_ACTION: "\"{0}\" no se puede utilizar con esa acción."
INSPECTOR_ERROR: "Inspector ya {habilitado|deshabilitado}."
INSPECTOR_TOGGLED: "Inspector ahora {habilitado|deshabilitado}."
INTEGRATION_ERROR: "Incapaz de {inicializar|deshabilitar} {0} Inicio sesión."
INTEGRATION_SUCCESS: "{0} registrando exitosamente {inicializado|deshabilitado}."
INTEGRATION_VERSION: "Inválido {0} versión encontrada."
INCOMPATIBLE_ACTION: "\"{0}\" no puede ser usado para esta acción."
INSPECTOR_ERROR: "Inspeccionador ya {activado|desactivado}."
INSPECTOR_TOGGLED: "Inspeccionador {activado|desactivado}."
INTEGRATION_ERROR: "Imposible {inicializar|desactivar} los registros {0}."
INTEGRATION_SUCCESS: "Registros en {0} han sido correctamente {inicializados|desactivados}."
INTEGRATION_VERSION: "Versión inválida {0} encontrada."
INTERACTIONS_HEADER: "Interacciones del jugador"
INVALID_ACTION: "Esa no es una acción válida."
INVALID_BRANCH_1: "Versión de complemento no válida (la rama no se ha configurado)."
INVALID_BRANCH_2: "Para continuar, establezca la rama del proyecto en \"desarrollo\"."
INVALID_BRANCH_3: "La ejecución de código de desarrollo puede provocar daños en los datos."
INVALID_CONTAINER: "Primero inspeccione un contenedor válido."
INVALID_DONATION_KEY: "Clave de donación no válida."
INVALID_INCLUDE: "\"{0}\" es un valor no válido."
INVALID_INCLUDE_COMBO: "Esa es una combinación de tipos no válida."
INVALID_RADIUS: "Ingrese un radio válido."
INVALID_SELECTION: "{0} selección no encontrada."
INVALID_USERNAME: "\"{0}\" es un nombre de usuario no válido."
INVALID_ACTION: "No es una acción válida."
INVALID_BRANCH_1: "Versión del plugin inválida (la rama no ha sido definida)."
INVALID_BRANCH_2: "Para continuar, coloque la rama del proyecto a \"development\"."
INVALID_BRANCH_3: "Ejecutar códigos en desarrollo puede resultar en una corrupción de datos."
INVALID_CONTAINER: "Intente inspeccionar un contenedor válido primero."
INVALID_DONATION_KEY: "Clave de donación inválida."
INVALID_INCLUDE: "\"{0}\" es un bloque inválido/ o nombre de entidad."
INVALID_INCLUDE_COMBO: "Es una combinación inválida de bloque/entidad."
INVALID_RADIUS: "Coloque un radio válido."
INVALID_SELECTION: "{0} sección no encontrada."
INVALID_USERNAME: "\"{0}\" no es usuario existente."
INVALID_WORLD: "Especifique un mundo válido."
LATEST_VERSION: "Última versión: {0}"
LINK_DISCORD: "Discord: {0}"
LINK_DOWNLOAD: "Descargar: {0}"
LINK_DOWNLOAD: "Descarga: {0}"
LINK_PATREON: "Patreon: {0}"
LINK_WIKI_BLOCK: "Nombres de bloque: {0}"
LINK_WIKI_BLOCK: "Nombres de bloques: {0}"
LINK_WIKI_ENTITY: "Nombres de entidades: {0}"
LOGGING_ITEMS: "{0} elementos que quedan por registrar. Espere por favor..."
LOGGING_TIME_LIMIT: "Se alcanzó el límite de tiempo de registro. Descartando datos y cerrando."
LOOKUP_BLOCK: "{0} {colocado|roto} {1}."
LOOKUP_CONTAINER: "{0} {añadido|eliminado} {1} {2}."
LOGGING_ITEMS: "{0} objetos restantes por registrar. Espere un momento..."
LOGGING_TIME_LIMIT: "Limite de tiempo de registros. Descartamdo pérdida de información."
LOOKUP_BLOCK: "{0} {colocó|rompió} {1}."
LOOKUP_CONTAINER: "{0} {agregó|removió} {1} {2}."
LOOKUP_HEADER: "{0} Resultados"
LOOKUP_INTERACTION: "{0} {clickeado|muerto} {1}."
LOOKUP_ITEM: "{0} {recogido|caído} {1} {2}."
LOOKUP_LOGIN: "{0} registrado {adentro|afuera}."
LOOKUP_INTERACTION: "{0} {clickeó|mató} {1}."
LOOKUP_ITEM: "{0} {recogió|soltó} {1} {2}."
LOOKUP_LOGIN: "{0} ha {entrado|salido}."
LOOKUP_PAGE: "Página {0}"
LOOKUP_PROJECTILE: "{0} {tiró|disparó} {1} {2}."
LOOKUP_ROWS_FOUND: "{0} {fila|filas} encontró."
LOOKUP_SEARCHING: "Búsqueda de búsqueda. Espere por favor..."
LOOKUP_STORAGE: "{0} {depositado|retirado} {1} {2}."
LOOKUP_TIME: "{0} atrás"
LOOKUP_USERNAME: "{0} Conectado como {1}."
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 se encontraron {datos|transacciones|interacciones|mensajes}."
NO_PERMISSION: "No tienes permiso para hacer eso."
NO_RESULTS: "No se han encontrado resultados."
NO_RESULTS_PAGE: "No {resultados|datos} encontrado para esa página."
NO_ROLLBACK: "No {pendiente|anterior} deshacer / restaurar encontrado."
PATCH_INTERRUPTED: "Actualización interrumpida. Intentará de nuevo al reiniciar."
PATCH_OUTDATED_1: "No se pueden actualizar las bases de datos anteriores a {0}."
PATCH_OUTDATED_2: "Actualice con una versión compatible de CoreProtect."
PATCH_PROCESSING: "Procesando nuevos datos. Espere por favor..."
PATCH_SKIP_UPDATE: "Salto a la comba {tabla|índice} {actualización|creación|eliminación} en {0}."
PATCH_STARTED: "Ejecutando {0} potenciar. Espere por favor..."
PATCH_SUCCESS: "Actualizado con éxito a {0}."
PATCH_UPGRADING: "Actualización de la base de datos en curso. Espere por favor..."
LOOKUP_ROWS_FOUND: "{0} {fila|filas} encontradas."
LOOKUP_SEARCHING: "Busqueda iniciada. Espere..."
LOOKUP_STORAGE: "{0} {depositó|retiró} {1} {2}."
LOOKUP_TIME: "Hace {0}"
LOOKUP_USERNAME: "{0} entró como {1}."
MAXIMUM_RADIUS: "El radio máximo de {búsqueda|retorno|restauración} es {0}."
MISSING_ACTION_USER: "Para usar esta acción, especifique a un usuario."
MISSING_LOOKUP_TIME: "Especifique la cantidad de tiempo para {buscar|retornar|restaurar}."
MISSING_LOOKUP_USER: "Especifique un usuario o {bloque|radio} para buscar."
MISSING_PARAMETERS: "Usa \"{0}\"."
MISSING_ROLLBACK_RADIUS: "No especificaste un radio para {retornar|resturar}."
MISSING_ROLLBACK_USER: "No especificaste a un usuario para {retornar|restaurar}."
MYSQL_UNAVAILABLE: "No se pudo conectar con el servidor de MySQL."
NO_DATA: "Sin datos para {0}."
NO_DATA_LOCATION: "Sin {datos|transacciones|interacciones|mensajes} encontrados acá."
NO_PERMISSION: "No tienes permisos para hacer esto."
NO_RESULTS: "No se hallaron resultados."
NO_RESULTS_PAGE: "Sin {resultados|datos} encontados para esta página."
NO_ROLLBACK: "No hay rollbacks {pendientes|previos} encontrados."
PATCH_INTERRUPTED: "Mejora interrumpida. Se intentará nuevamente en el reinicio."
PATCH_OUTDATED_1: "No se puede mejorar base de datos más antiguas de {0}."
PATCH_OUTDATED_2: "Actualice con una versión soportada de CoreProtect."
PATCH_PROCESSING: "Procesando nueva información. Espere un momento..."
PATCH_SKIP_UPDATE: "Saltando {tabla|índice} {actualización|creación|remoción} en {0}."
PATCH_STARTED: "Intentando actualizar {0}. Espere..."
PATCH_SUCCESS: "Exitosamente actualizada a {0}."
PATCH_UPGRADING: "Mejora de base de datos en progreso. Espere un momento..."
PLEASE_SELECT: "Seleccione: \"{0}\" o \"{1}\"."
PREVIEW_CANCELLED: "Vista previa cancelada."
PREVIEW_CANCELLING: "Cancelando vista previa..."
PREVIEW_IN_GAME: "Solo puedes obtener una vista previa de las reversiones en el juego."
PREVIEW_TRANSACTION: "No puedes previsualizar {contenedor|inventario} actas."
PURGE_ABORTED: "La purga falló. La base de datos puede estar dañada."
PURGE_ERROR: "No se puede procesar {0} ¡datos!"
PURGE_FAILED: "La purga falló. Por favor, inténtelo de nuevo más tarde."
PURGE_IN_PROGRESS: "Purga en curso. Por favor, inténtelo de nuevo más tarde."
PURGE_MINIMUM_TIME: "Solo puede depurar datos anteriores a {0} {días|horas}."
PURGE_NOTICE_1: "Tenga en cuenta que esto puede llevar algún tiempo."
PURGE_NOTICE_2: "No reinicie su servidor hasta que haya terminado."
PURGE_OPTIMIZING: "Optimización de la base de datos. Espere por favor..."
PREVIEW_CANCELLED: "Muestra cancelada."
PREVIEW_CANCELLING: "Cancelando muestra..."
PREVIEW_IN_GAME: "Solo puedes mostrar respaldos en el juego."
PREVIEW_TRANSACTION: "No puedes mostrar transacciones de {contenedor|inventario}."
PURGE_ABORTED: "Purga fallida. La base de datos debe estar corrupta."
PURGE_ERROR: "¡No se pudo procesar {0} datos!"
PURGE_FAILED: "Purga fallida. Intente nuevamente."
PURGE_IN_PROGRESS: "Purga en progreso. Intentelo nuevamente."
PURGE_MINIMUM_TIME: "Solo puedes limpiar datos viejos desde {0} {días|horas}."
PURGE_NOTICE_1: "Ten en cuenta que va a demorar un poco."
PURGE_NOTICE_2: "No reinicies el servidor hasta que se complete."
PURGE_OPTIMIZING: "Optimizando base de datos. Espere..."
PURGE_PROCESSING: "Procesando {0} datos..."
PURGE_REPAIRING: "Intentando reparar. Esto puede tomar algo de tiempo..."
PURGE_ROWS: "{0} {fila|filas} de datos eliminados."
PURGE_STARTED: "La depuración de datos comenzó el \"{0}\"."
PURGE_REPAIRING: "Intentando reparar. Esto tomará algo de tiempo..."
PURGE_ROWS: "{0} {fila|filas} de datos limpiados."
PURGE_STARTED: "Purga de datos iniciada en \"{0}\"."
PURGE_SUCCESS: "Purga de datos exitosa."
RELOAD_STARTED: "Recargando la configuración - espere."
RELOAD_SUCCESS: "Configuración recargada correctamente."
ROLLBACK_ABORTED: "Reversión o restauración abortada."
ROLLBACK_CHUNKS_FOUND: "Encontró {0} {trozo|trozos} Modificar."
ROLLBACK_CHUNKS_MODIFIED: "Modificado {0}/{1} {trozo|trozos}."
ROLLBACK_COMPLETED: "{Retroceder|Restaurar|Vista previa} completado para \"{0}\"."
ROLLBACK_EXCLUDED_USERS: "Excluido {usuario|usuarios}: \"{0}\"."
RELOAD_STARTED: "Recargando configuración - espere."
RELOAD_SUCCESS: "Configuración exitosamente recargada."
ROLLBACK_ABORTED: "Retorno o restauración abortado."
ROLLBACK_CHUNKS_FOUND: "Encontrado {0} {chunk|chunks} para modificar."
ROLLBACK_CHUNKS_MODIFIED: "Se han modificado {0}/{1} {chunk|chunks}."
ROLLBACK_COMPLETED: "{Respaldo|Restauración|Muestra} completado por \"{0}\"."
ROLLBACK_EXCLUDED_USERS: "Excluir al {usuario|usuarios}: \"{0}\"."
ROLLBACK_INCLUDE: "{Incluido|Excluido} {bloque|entidad|objetivo} {tipo|tipos}: \"{0}\"."
ROLLBACK_IN_PROGRESS: "Ya se está realizando una reversión / restauración."
ROLLBACK_LENGTH: "Tiempo tomado: {0} {segundo|segundos}."
ROLLBACK_IN_PROGRESS: "Un retorno/resturación ya está en progreso."
ROLLBACK_LENGTH: "Tiempo gastado: {0} {segundo|segundos}."
ROLLBACK_MODIFIED: "{Modificado|Modificando} {0}."
ROLLBACK_RADIUS: "Radio: {0} {bloque|bloques}."
ROLLBACK_SELECTION: "Radio establecido en \"{0}\"."
ROLLBACK_STARTED: "{Retroceder|Restaurar|Vista previa} comenzó en \"{0}\"."
ROLLBACK_TIME: "Intervalo de tiempo: {0}."
ROLLBACK_WORLD_ACTION: "Prohibido para {mundo|acción} \"{0}\"."
SIGN_HEADER: "Firmar mensajes"
STATUS_CONSUMER: "Consumidor: {0} {artículo|artículos} en la cola."
ROLLBACK_SELECTION: "Radio definido a \"{0}\"."
ROLLBACK_STARTED: "{Retorno|Restauración|Muestra} iniciado en \"{0}\"."
ROLLBACK_TIME: "Tiempo hecho: {0}."
ROLLBACK_WORLD_ACTION: "Restringido para {mundo|acción} \"{0}\"."
SIGN_HEADER: "Mensajes de cartel"
STATUS_CONSUMER: "Consumidor: {0} {objeto|objetos} en espera."
STATUS_DATABASE: "Base de datos: Usando {0}."
STATUS_INTEGRATION: "{0}: Integración {habilitado|deshabilitado}."
STATUS_INTEGRATION: "{0}: Integración {activada|desactivada}."
STATUS_LICENSE: "Licencia: {0}"
STATUS_VERSION: "Versión: {0}"
TELEPORTED: "Teletransportado a {0}."
TELEPORTED_SAFETY: "Te teletransportó a un lugar seguro."
TELEPORT_PLAYERS: "El comando de teletransporte solo puede ser utilizado por jugadores."
TELEPORTED_SAFETY: "Te he teletransportado a un lugar seguro."
TELEPORT_PLAYERS: "El comando de teletransporte solo puede ser usado por jugadores."
TIME_DAYS: "{0} {día|días}"
TIME_HOURS: "{0} {hora|horas}"
TIME_MINUTES: "{0} {minuto|minutos}"
TIME_SECONDS: "{0} {segundo|segundos}"
TIME_WEEKS: "{0} {semana|semanas}"
UPDATE_ERROR: "Se produjo un error al buscar actualizaciones."
UPDATE_HEADER: "{0} Actualizar"
UPDATE_NOTICE: "Darse cuenta: {0} Ya está disponible."
UPGRADE_IN_PROGRESS: "Actualización en curso. Por favor, inténtelo de nuevo más tarde."
USER_NOT_FOUND: "Usuario \"{0}\" extraviado."
USER_OFFLINE: "El usuario \"{0}\" no está en línea."
USING_MYSQL: "Utilizando MySQL para el almacenamiento de datos."
USING_SQLITE: "Utilizando SQLite para el almacenamiento de datos."
UPDATE_ERROR: "Un error ocurrió mientras se revisaban las actualizaciones."
UPDATE_HEADER: "Actualización {0}"
UPDATE_NOTICE: "Noticia: {0} está disponible."
UPGRADE_IN_PROGRESS: "Actualización en progreso. Intente nuevamente."
USER_NOT_FOUND: "Usuario \"{0}\" no encontrado."
USER_OFFLINE: "El usuario \"{0}\" no está conectado."
USING_MYSQL: "Usando MySQL para el guardado de información."
USING_SQLITE: "Usando SQLite para el guardado de información."
VALID_DONATION_KEY: "Clave de donación válida."
VERSION_NOTICE: "Versión {0} Ya está disponible."
VERSION_REQUIRED: "{0} {1} se requiere o superior."
WORLD_NOT_FOUND: "Mundo \"{0}\" extraviado."
VERSION_NOTICE: "Versión {0} está disponible."
VERSION_REQUIRED: "{0} {1} o súperior es requerida."
WORLD_NOT_FOUND: "Mundo \"{0}\" inexistente."
+201
View File
@@ -0,0 +1,201 @@
# CoreProtect Language File (tr)
ACTION_NOT_SUPPORTED: "Bu işlem desteklenmiyor."
AMOUNT_BLOCK: "{0} {blok|bloklar}"
AMOUNT_CHUNK: "{0} {yığın|parçalar}"
AMOUNT_ENTITY: "{0} {varlık|kuruluşlar}"
AMOUNT_ITEM: "{0} {öğe|öğeler}"
API_TEST: "API testi başarılı."
CACHE_ERROR: "UYARI: Doğrulama sırasında hata {0} önbellek."
CACHE_RELOAD: "Yeniden yüklemeye zorlama {haritalama|dünya} veritabanından önbellekler."
CHECK_CONFIG: "Lütfen config.yml'yi kontrol edin"
COMMAND_CONSOLE: "Lütfen komutu konsoldan çalıştırın."
COMMAND_NOT_FOUND: "Emretmek \"{0}\" bulunamadı."
COMMAND_THROTTLED: "Lütfen biraz bekleyin ve tekrar deneyin."
CONSUMER_ERROR: "Tüketici kuyruğu işleme zaten {duraklatıldı|devam ettirildi}."
CONSUMER_TOGGLED: "Tüketici kuyruğu işleme {duraklatıldı|devam ettirildi}."
CONTAINER_HEADER: "Konteyner İşlemleri"
DATABASE_BUSY: "Veritabanı meşgul. Lütfen daha sonra tekrar deneyiniz."
DATABASE_INDEX_ERROR: "Veritabanı dizinleri doğrulanamıyor."
DATABASE_LOCKED_1: "Veritabanı kilitlendi. 15 saniyeye kadar bekleniyor..."
DATABASE_LOCKED_2: "Veritabanı zaten kullanılıyor. Lütfen tekrar deneyin."
DATABASE_LOCKED_3: "Veritabanı kilitlemeyi devre dışı bırakmak için \"veritabanı kilidi: yanlış\" olarak ayarlayın."
DATABASE_LOCKED_4: "Veritabanı kilitlemeyi devre dışı bırakmak, verilerin bozulmasına neden olabilir."
DATABASE_UNREACHABLE: "Veritabanına erişilemiyor. Verileri atma ve kapatma."
DEVELOPMENT_BRANCH: "Geliştirme dalı algılandı, yama komut dosyaları atlandı."
DIRT_BLOCK: "Altına bir toprak bloğu yerleştirdi."
DISABLE_SUCCESS: "Başarı! Engelli {0}"
ENABLE_FAILED: "{0} başlayamadı."
ENABLE_SUCCESS: "{0} şimdi etkinleştirildi!"
ENJOY_COREPROTECT: "Eğlence {0}? Bize katılın Discord!"
FINISHING_CONVERSION: "Veri dönüştürme işlemi tamamlanıyor. Lütfen bekle..."
FINISHING_LOGGING: "Veri kaydının tamamlanması. Lütfen bekle..."
FIRST_VERSION: "İlk Veri Tabanı: {0}"
GLOBAL_LOOKUP: "Genel arama yapmak için bir yarıçap belirlemeyin."
GLOBAL_ROLLBACK: "Kullanmak \"{0}\" küresel yapmak {geri alma|geri yükleme}"
HELP_ACTION_1: "Aramayı bir eylemle sınırlayın."
HELP_ACTION_2: "Örnekler: [a:block], [a:+block], [a:-block] [a:click], [a:container], [a:inventory], [a:item], [a:kill], [a:chat], [a:command], [a:sign], [a:session], [a:username]"
HELP_COMMAND: "Ek bilgileri görüntüleyin."
HELP_EXCLUDE_1: "Blokları/kullanıcıları hariç tutun."
HELP_EXCLUDE_2: "Örnekler: [e:stone], [e:Notch], [e:stone,Notch]"
HELP_HEADER: "{0} Yardım"
HELP_INCLUDE_1: "Blokları/varlıkları dahil et."
HELP_INCLUDE_2: "Örnekler: [i:stone], [i:zombie], [i:stone,wood,bedrock]"
HELP_INSPECT_1: "Müfettiş etkinken şunları yapabilirsiniz:"
HELP_INSPECT_2: "Yerleşimi görmek için sol tıklayın."
HELP_INSPECT_3: "Bitişik kaldırmaları görmek için sağ tıklayın."
HELP_INSPECT_4: "Kaldırma işlemini görmek için bir blok yerleştirin."
HELP_INSPECT_5: "Yerleşimi görmek için sıvıya bir blok yerleştirin."
HELP_INSPECT_6: "Sandık işlemlerini görmek için sağ tıklayın."
HELP_INSPECT_7: "İpucu: Yalnızca \"/co i\" kullanabilirsiniz."
HELP_INSPECT_COMMAND: "Blok denetçisini değiştirir."
HELP_LIST: "Tüm komutların bir listesini görüntüler."
HELP_LOOKUP_1: "Komut kısayolu."
HELP_LOOKUP_2: "Ek sayfaları görüntüleyin."
HELP_LOOKUP_COMMAND: "Blok verilerini arayın."
HELP_NO_INFO: "Komut için bilgi \"{0}\" bulunamadı."
HELP_PARAMETER: "Bakınız \"{0}\" detaylı parametre bilgisi için."
HELP_PARAMS_1: "Gerçekleştir {arama|geri alma|geri yükleme}."
HELP_PARAMS_2: "Kullanıcıları belirtin {arama|geri alma|geri yükleme}."
HELP_PARAMS_3: "Zamanı belirtin {arama|geri alma|geri yükleme}."
HELP_PARAMS_4: "kısıtlamak {arama|geri alma|geri yükleme} bir yarıçapa."
HELP_PARAMS_5: "kısıtlamak {arama|geri alma|geri yükleme} bir eyleme."
HELP_PARAMS_6: "Blokları/varlıkları dahil et {arama|geri alma|geri yükleme}."
HELP_PARAMS_7: "Blokları/kullanıcıları {arama|geri alma|geri yükleme}."
HELP_PURGE_1: "Eski verileri kaldırın."
HELP_PURGE_2: "Örneğin, \"{0}\" bir aydan eski tüm verileri silecek ve yalnızca son 30 güne ait verileri tutacaktır."
HELP_PURGE_COMMAND: "Eski blok verilerini silin."
HELP_RADIUS_1: "Bir yarıçap alanı belirtin."
HELP_RADIUS_2: "Örnekler: [r:10] (Sadece 10 blok içinde değişiklik yapın)"
HELP_RELOAD_COMMAND: "Yapılandırma dosyasını yeniden yükler."
HELP_RESTORE_COMMAND: "Blok verilerini geri yükleyin."
HELP_ROLLBACK_COMMAND: "Geri alma blok verileri."
HELP_STATUS: "Eklenti durumunu görüntüleyin."
HELP_STATUS_COMMAND: "Eklenti durumunu görüntüler."
HELP_TELEPORT: "Işınlanma."
HELP_TIME_1: "Zamanı belirtin."
HELP_TIME_2: "Örnekler: [t:2w,5d,7h,2m,10s], [t:5d2h], [t:2.50h]"
HELP_USER_1: "Kullanıcıları belirtin."
HELP_USER_2: "Örnekler: [u:Notch], [u:Notch,#enderman]"
INCOMPATIBLE_ACTION: "\"{0}\" bu eylemle kullanılamaz."
INSPECTOR_ERROR: "Müfettiş zaten {etkin|devre dışı}."
INSPECTOR_TOGGLED: "Müfettiş şimdi {etkin|devre dışı}."
INTEGRATION_ERROR: "Olanaksız {başlat|devre dışı bırak} {0} Kerestecilik."
INTEGRATION_SUCCESS: "{0} başarıyla giriş yapmak {başlatıldı|devre dışı}."
INTEGRATION_VERSION: "Geçersiz {0} sürüm bulundu."
INTERACTIONS_HEADER: "Oyuncu Etkileşimleri"
INVALID_ACTION: "Bu geçerli bir eylem değil."
INVALID_BRANCH_1: "Geçersiz eklenti sürümü (dal ayarlanmadı)."
INVALID_BRANCH_2: "Devam etmek için proje dalını \"geliştirme\" olarak ayarlayın."
INVALID_BRANCH_3: "Geliştirme kodunu çalıştırmak, verilerin bozulmasına neden olabilir."
INVALID_CONTAINER: "Lütfen önce geçerli bir kapsayıcıyı inceleyin."
INVALID_DONATION_KEY: "Geçersiz bağış anahtarı."
INVALID_INCLUDE: "\"{0}\" geçersiz bir değerdir."
INVALID_INCLUDE_COMBO: "Bu geçersiz bir tür birleşimidir."
INVALID_RADIUS: "Lütfen geçerli bir yarıçap girin."
INVALID_SELECTION: "{0} seçim bulunamadı."
INVALID_USERNAME: "\"{0}\" geçersiz bir kullanıcı adıdır."
INVALID_WORLD: "Lütfen geçerli bir dünya belirtin."
LATEST_VERSION: "En son sürüm: {0}"
LINK_DISCORD: "Discord: {0}"
LINK_DOWNLOAD: "İndirmek: {0}"
LINK_PATREON: "Patreon: {0}"
LINK_WIKI_BLOCK: "Blok İsimleri: {0}"
LINK_WIKI_ENTITY: "Varlık Adları: {0}"
LOGGING_ITEMS: "{0} günlüğe bırakılan öğeler. Lütfen bekle..."
LOGGING_TIME_LIMIT: "Günlüğe kaydetme zaman sınırına ulaşıldı. Verileri atma ve kapatma."
LOOKUP_BLOCK: "{0} {yerleştirilmiş|kırıldı} {1}."
LOOKUP_CONTAINER: "{0} {eklendi|kaldırıldı} {1} {2}."
LOOKUP_HEADER: "{0} Sonuçlar"
LOOKUP_INTERACTION: "{0} {tıklandı|öldürüldü} {1}."
LOOKUP_ITEM: "{0} {aldı|bıraktı} {1} {2}."
LOOKUP_LOGIN: "{0} günlüğe kaydedildi {içeri|dışarı}."
LOOKUP_PAGE: "Sayfa {0}"
LOOKUP_PROJECTILE: "{0} {fırlattı|vuruş} {1} {2}."
LOOKUP_ROWS_FOUND: "{0} {satır|satır} kurmak."
LOOKUP_SEARCHING: "Arama arama. Lütfen bekle..."
LOOKUP_STORAGE: "{0} {yatırıldı|geri çekildi} {1} {2}."
LOOKUP_TIME: "{0} evvel"
LOOKUP_USERNAME: "{0} olarak giriş yaptı {1}."
MAXIMUM_RADIUS: "Maksimum {arama|geri alma|geri yükleme} yarıçap {0}."
MISSING_ACTION_USER: "Bu eylemi kullanmak için lütfen bir kullanıcı belirtin."
MISSING_LOOKUP_TIME: "Lütfen zamanı belirtin {arama|geri alma|geri yükleme}."
MISSING_LOOKUP_USER: "Lütfen bir kullanıcı belirtin veya {blok|yarıçap}."
MISSING_PARAMETERS: "Lütfen kullan \"{0}\"."
MISSING_ROLLBACK_RADIUS: "bir belirtmemişsin {geri alma|geri yükleme} yarıçap."
MISSING_ROLLBACK_USER: "bir belirtmemişsin {geri alma|geri yükleme} kullanıcı."
MYSQL_UNAVAILABLE: "Bağlantı kurulamıyor MySQL sunucu."
NO_DATA: "şurada veri bulunamadı {0}."
NO_DATA_LOCATION: "Numara {veri|işlemler|etkileşimler|mesajlar} kurmak."
NO_PERMISSION: "Bunu yapmaya iznin yok."
NO_RESULTS: "Sonuç bulunamadı."
NO_RESULTS_PAGE: "Numara {sonuçlar|veri} o sayfa için bulundu."
NO_ROLLBACK: "Numara {beklemede|önceki} geri alma/geri yükleme bulundu."
PATCH_INTERRUPTED: "Yükseltme kesintiye uğradı. Yeniden başlatıldığında tekrar deneyecek."
PATCH_OUTDATED_1: "Daha eski veritabanları yükseltilemiyor {0}."
PATCH_OUTDATED_2: "Lütfen desteklenen bir sürümle yükseltin CoreProtect."
PATCH_PROCESSING: "Yeni veriler işleniyor. Lütfen bekle..."
PATCH_SKIP_UPDATE: "Atlama {tablo|dizin} {güncelleme|oluşturma|kaldırma} üzerinde {0}."
PATCH_STARTED: "performans {0} Yükselt. Lütfen bekle..."
PATCH_SUCCESS: "Başarıyla yükseltildi {0}."
PATCH_UPGRADING: "Veritabanı yükseltmesi devam ediyor. Lütfen bekle..."
PLEASE_SELECT: "Lütfen seçin: \"{0}\" veya \"{1}\"."
PREVIEW_CANCELLED: "Önizleme iptal edildi."
PREVIEW_CANCELLING: "Önizleme iptal ediliyor..."
PREVIEW_IN_GAME: "Geri almaları yalnızca oyun içinde önizleyebilirsiniz."
PREVIEW_TRANSACTION: "önizleme yapamazsınız {konteyner|envanter} işlemler."
PURGE_ABORTED: "Temizleme başarısız oldu. Veritabanı bozuk olabilir."
PURGE_ERROR: "işlenemiyor {0} veri!"
PURGE_FAILED: "Temizleme başarısız oldu. Lütfen daha sonra tekrar deneyiniz."
PURGE_IN_PROGRESS: "Temizleme işlemi devam ediyor. Lütfen daha sonra tekrar deneyiniz."
PURGE_MINIMUM_TIME: "Yalnızca şu tarihten daha eski verileri temizleyebilirsiniz: {0} {gün|saat}."
PURGE_NOTICE_1: "Lütfen bunun biraz zaman alabileceğini unutmayın."
PURGE_NOTICE_2: "Tamamlanana kadar sunucunuzu yeniden başlatmayın."
PURGE_OPTIMIZING: "Veritabanını optimize etme. Lütfen bekle..."
PURGE_PROCESSING: "İşleme {0} veri..."
PURGE_REPAIRING: "Tamir etmeye çalışmak. Bu biraz zaman alabilir..."
PURGE_ROWS: "{0} {satır|satır} silinen veriler."
PURGE_STARTED: "Veri temizleme başladı \"{0}\"."
PURGE_SUCCESS: "Veri temizleme başarılı."
RELOAD_STARTED: "Yapılandırma yeniden yükleniyor - lütfen bekleyin."
RELOAD_SUCCESS: "Yapılandırma başarıyla yeniden yüklendi."
ROLLBACK_ABORTED: "Geri alma veya geri yükleme iptal edildi."
ROLLBACK_CHUNKS_FOUND: "Kurmak {0} {yığın|parçalar} düzenlemek."
ROLLBACK_CHUNKS_MODIFIED: "Değiştirilmiş {0}/{1} {yığın|parçalar}."
ROLLBACK_COMPLETED: "{Geri Alma|Geri Yükleme|Önizleme} için tamamlandı \"{0}\"."
ROLLBACK_EXCLUDED_USERS: "Hariç tutulan {kullanıcı|kullanıcılar}: \"{0}\"."
ROLLBACK_INCLUDE: "{Dahil|Hariç} {blok|varlık|hedef} {tip|tür}: \"{0}\"."
ROLLBACK_IN_PROGRESS: "Halihazırda bir geri alma/geri yükleme işlemi devam ediyor."
ROLLBACK_LENGTH: "Geçen süre: {0} {saniye|saniye}."
ROLLBACK_MODIFIED: "{Değiştirildi|Değiştiriliyor} {0}."
ROLLBACK_RADIUS: "yarıçap: {0} {blok|bloklar}."
ROLLBACK_SELECTION: "Yarıçap \" olarak ayarlandı{0}\"."
ROLLBACK_STARTED: "{Geri Alma|Geri Yükleme|Önizleme} başladı \"{0}\"."
ROLLBACK_TIME: "Zaman aralığı: {0}."
ROLLBACK_WORLD_ACTION: "Sınırlı {dünya|eylem} \"{0}\"."
SIGN_HEADER: "Mesajları İmzala"
STATUS_CONSUMER: "Tüketici: {0} {öğe|öğeler} sırada."
STATUS_DATABASE: "Veri tabanı: kullanma {0}."
STATUS_INTEGRATION: "{0}: Entegrasyon {etkin|devre dışı}."
STATUS_LICENSE: "Lisans: {0}"
STATUS_VERSION: "Sürüm: {0}"
TELEPORTED: "Işınlandı {0}."
TELEPORTED_SAFETY: "Sizi emniyete ışınladım."
TELEPORT_PLAYERS: "Teleport komutu sadece oyuncular tarafından kullanılabilir."
TIME_DAYS: "{0} {gün|gün}"
TIME_HOURS: "{0} {saat|saat}"
TIME_MINUTES: "{0} {dakika|dakika}"
TIME_SECONDS: "{0} {saniye|saniye}"
TIME_WEEKS: "{0} {hafta|hafta}"
UPDATE_ERROR: "Güncellemeler kontrol edilirken bir hata oluştu."
UPDATE_HEADER: "{0} Güncelleme"
UPDATE_NOTICE: "Fark etme: {0} şimdi kullanılabilir."
UPGRADE_IN_PROGRESS: "Yükseltme devam ediyor. Lütfen daha sonra tekrar deneyiniz."
USER_NOT_FOUND: "kullanıcı \"{0}\" bulunamadı."
USER_OFFLINE: "Kullanıcı \"{0}\" çevrimiçi değil."
USING_MYSQL: "kullanma MySQL veri depolama için."
USING_SQLITE: "kullanma SQLite veri depolama için."
VALID_DONATION_KEY: "Geçerli bağış anahtarı."
VERSION_NOTICE: "sürüm {0} şimdi kullanılabilir."
VERSION_REQUIRED: "{0} {1} veya daha yüksek gereklidir."
WORLD_NOT_FOUND: "Dünya \"{0}\" bulunamadı."
+7 -7
View File
@@ -10,11 +10,11 @@ API_TEST: "API 测试成功。"
CACHE_ERROR: "警告: 验证缓存 {0} 时出错。"
CACHE_RELOAD: "正在强制从数据库中重新加载{映射|世界}的缓存。"
CHECK_CONFIG: "请检查 config.yml 文件"
COMMAND_CONSOLE: "请从控制台运行命令。"
COMMAND_CONSOLE: "请在控制台中运行此命令。"
COMMAND_NOT_FOUND: "找不到命令 \"{0}\""
COMMAND_THROTTLED: "请稍等片刻,然后重试。"
CONSUMER_ERROR: "消费者队列处理已经 {暂停|继续}."
CONSUMER_TOGGLED: "消费者队列处理已 {暂停|继续}."
CONSUMER_ERROR: "数据处理队列已经{暂停|恢复}。"
CONSUMER_TOGGLED: "数据处理队列现已{暂停|恢复}。"
CONTAINER_HEADER: "容器物品变更记录"
DATABASE_BUSY: "数据库繁忙,请稍后重试。"
DATABASE_INDEX_ERROR: "无法验证数据库索引。"
@@ -112,7 +112,7 @@ LOOKUP_INTERACTION: "{0} {点击|击杀} {1}."
LOOKUP_ITEM: "{0} {拾起|丢弃} {1} {2}."
LOOKUP_LOGIN: "{0} {登入|离开}."
LOOKUP_PAGE: "第 {0} 页"
LOOKUP_PROJECTILE: "{0} {扔|射} {1} {2}."
LOOKUP_PROJECTILE: "{0} {扔出|发射} {1} {2}."
LOOKUP_ROWS_FOUND: "已找到 {0}{行|行}。"
LOOKUP_SEARCHING: "正在搜索,请稍等..."
LOOKUP_STORAGE: "{0} {放入|取出} {1} {2}."
@@ -144,7 +144,7 @@ PLEASE_SELECT: "请选择: \"{0}\"或\"{1}\"。"
PREVIEW_CANCELLED: "预览已取消。"
PREVIEW_CANCELLING: "正在取消预览..."
PREVIEW_IN_GAME: "你只能在游戏中预览回滚操作。"
PREVIEW_TRANSACTION: "您无法预览 {集装箱|库存} 交易。"
PREVIEW_TRANSACTION: "你不能预览{容器|背包}物品交换。"
PURGE_ABORTED: "清除失败,数据库可能已损坏。"
PURGE_ERROR: "无法处理 {0} 数据!"
PURGE_FAILED: "数据清除失败,请稍后再试。"
@@ -193,10 +193,10 @@ UPDATE_HEADER: "{0} 更新"
UPDATE_NOTICE: "注意: {0} 现在可用。"
UPGRADE_IN_PROGRESS: "正在进行升级,请稍后再试。"
USER_NOT_FOUND: "玩家\"{0}\"未找到。"
USER_OFFLINE: "用户 \"{0}\"不在线。"
USER_OFFLINE: "玩家\"{0}\"不在线。"
USING_MYSQL: "使用 MySQL 用于数据存储。"
USING_SQLITE: "使用 SQLite 用于数据存储。"
VALID_DONATION_KEY: "有效的捐赠密钥。"
VERSION_NOTICE: "版本 {0} 现在可用。"
VERSION_REQUIRED: "{0} 需要使用 {1} 或更高版本。"
WORLD_NOT_FOUND: "找不到世界 \"{0}\"。"
WORLD_NOT_FOUND: "找不到世界 \"{0}\"。"
+2 -2
View File
@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>net.coreprotect</groupId>
<artifactId>CoreProtect</artifactId>
<version>21.2</version>
<version>21.3</version>
<properties>
<project.branch></project.branch>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -94,7 +94,7 @@
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.18.1-R0.1-SNAPSHOT</version>
<version>1.19-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
+1 -1
View File
@@ -1 +1 @@
mkdocs==1.2.3
mkdocs==1.3.1
@@ -14,7 +14,6 @@ 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;
@@ -162,7 +161,7 @@ public final class CoreProtect extends JavaPlugin {
private static void safeShutdown(CoreProtect plugin) {
try {
/* if server is stopping, log disconnections of online players */
if (PaperAdapter.ADAPTER.isStopping(plugin.getServer())) {
if (ConfigHandler.serverRunning && PaperAdapter.ADAPTER.isStopping(plugin.getServer())) {
for (Player player : plugin.getServer().getOnlinePlayers()) {
PlayerQuitListener.queuePlayerQuit(player);
}
@@ -200,7 +199,7 @@ public final class CoreProtect extends JavaPlugin {
Thread.sleep(100);
}
Database.closeConnection();
ConfigHandler.performDisable();
Chat.console(Phrase.build(Phrase.DISABLE_SUCCESS, "CoreProtect v" + plugin.getDescription().getVersion()));
}
catch (Exception e) {
@@ -1,6 +1,7 @@
package net.coreprotect.api;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -74,6 +75,7 @@ public class QueueLookup extends Queue {
}
}
Collections.reverse(result);
}
catch (Exception e) {
e.printStackTrace();
@@ -30,6 +30,7 @@ public class BukkitAdapter implements BukkitInterface {
public static final int BUKKIT_V1_16 = 16;
public static final int BUKKIT_V1_17 = 17;
public static final int BUKKIT_V1_18 = 18;
public static final int BUKKIT_V1_19 = 19;
public static void loadAdapter() {
switch (ConfigHandler.SERVER_VERSION) {
@@ -47,9 +48,11 @@ public class BukkitAdapter implements BukkitInterface {
BukkitAdapter.ADAPTER = new Bukkit_v1_17();
break;
case BUKKIT_V1_18:
default:
BukkitAdapter.ADAPTER = new Bukkit_v1_18();
break;
case BUKKIT_V1_19:
default:
BukkitAdapter.ADAPTER = new Bukkit_v1_19();
}
}
@@ -0,0 +1,94 @@
package net.coreprotect.bukkit;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Frog;
import org.bukkit.entity.Goat;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Tadpole;
import net.coreprotect.model.BlockGroup;
public class Bukkit_v1_19 extends Bukkit_v1_18 implements BukkitInterface {
public Bukkit_v1_19() {
BlockGroup.TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.MANGROVE_PROPAGULE, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.MANGROVE_SIGN, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP, Material.SOUL_TORCH, Material.TWISTING_VINES, Material.CRIMSON_FUNGUS, Material.WARPED_FUNGUS, Material.CRIMSON_ROOTS, Material.WARPED_ROOTS, Material.NETHER_SPROUTS, Material.CRIMSON_SIGN, Material.WARPED_SIGN, Material.AZALEA, Material.FLOWERING_AZALEA, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF));
BlockGroup.TRACK_SIDE = new HashSet<>(Arrays.asList(Material.WALL_TORCH, Material.REDSTONE_WALL_TORCH, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.ACTIVATOR_RAIL, Material.WHITE_BED, Material.ORANGE_BED, Material.MAGENTA_BED, Material.LIGHT_BLUE_BED, Material.YELLOW_BED, Material.LIME_BED, Material.PINK_BED, Material.GRAY_BED, Material.LIGHT_GRAY_BED, Material.CYAN_BED, Material.PURPLE_BED, Material.BLUE_BED, Material.BROWN_BED, Material.GREEN_BED, Material.RED_BED, Material.BLACK_BED, Material.LADDER, Material.MANGROVE_WALL_SIGN, Material.ACACIA_WALL_SIGN, Material.BIRCH_WALL_SIGN, Material.DARK_OAK_WALL_SIGN, Material.JUNGLE_WALL_SIGN, Material.OAK_WALL_SIGN, Material.SPRUCE_WALL_SIGN, Material.VINE, Material.COCOA, Material.TRIPWIRE_HOOK, Material.WHITE_WALL_BANNER, Material.ORANGE_WALL_BANNER, Material.MAGENTA_WALL_BANNER, Material.LIGHT_BLUE_WALL_BANNER, Material.YELLOW_WALL_BANNER, Material.LIME_WALL_BANNER, Material.PINK_WALL_BANNER, Material.GRAY_WALL_BANNER, Material.LIGHT_GRAY_WALL_BANNER, Material.CYAN_WALL_BANNER, Material.PURPLE_WALL_BANNER, Material.BLUE_WALL_BANNER, Material.BROWN_WALL_BANNER, Material.GREEN_WALL_BANNER, Material.RED_WALL_BANNER, Material.BLACK_WALL_BANNER, Material.SOUL_WALL_TORCH, Material.CRIMSON_WALL_SIGN, Material.WARPED_WALL_SIGN));
BlockGroup.DOORS = new HashSet<>(Arrays.asList(Material.OAK_DOOR, Material.SPRUCE_DOOR, Material.BIRCH_DOOR, Material.JUNGLE_DOOR, Material.MANGROVE_DOOR, Material.ACACIA_DOOR, Material.DARK_OAK_DOOR, Material.CRIMSON_DOOR, Material.WARPED_DOOR));
BlockGroup.BUTTONS = new HashSet<>(Arrays.asList(Material.STONE_BUTTON, Material.OAK_BUTTON, Material.MANGROVE_BUTTON, Material.ACACIA_BUTTON, Material.BIRCH_BUTTON, Material.DARK_OAK_BUTTON, Material.JUNGLE_BUTTON, Material.SPRUCE_BUTTON, Material.POLISHED_BLACKSTONE_BUTTON, Material.CRIMSON_BUTTON, Material.WARPED_BUTTON));
BlockGroup.PRESSURE_PLATES = new HashSet<>(Arrays.asList(Material.STONE_PRESSURE_PLATE, Material.MANGROVE_PRESSURE_PLATE, Material.ACACIA_PRESSURE_PLATE, Material.BIRCH_PRESSURE_PLATE, Material.DARK_OAK_PRESSURE_PLATE, Material.HEAVY_WEIGHTED_PRESSURE_PLATE, Material.JUNGLE_PRESSURE_PLATE, Material.LIGHT_WEIGHTED_PRESSURE_PLATE, Material.OAK_PRESSURE_PLATE, Material.SPRUCE_PRESSURE_PLATE, Material.CRIMSON_PRESSURE_PLATE, Material.WARPED_PRESSURE_PLATE, Material.POLISHED_BLACKSTONE_PRESSURE_PLATE));
BlockGroup.INTERACT_BLOCKS = new HashSet<>(Arrays.asList(Material.SPRUCE_FENCE_GATE, Material.BIRCH_FENCE_GATE, Material.JUNGLE_FENCE_GATE, Material.DARK_OAK_FENCE_GATE, Material.MANGROVE_FENCE_GATE, Material.ACACIA_FENCE_GATE, Material.DISPENSER, Material.NOTE_BLOCK, Material.CHEST, Material.FURNACE, Material.LEVER, Material.REPEATER, Material.MANGROVE_TRAPDOOR, Material.ACACIA_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.DARK_OAK_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.OAK_TRAPDOOR, Material.OAK_FENCE_GATE, Material.BREWING_STAND, Material.ANVIL, Material.CHIPPED_ANVIL, Material.DAMAGED_ANVIL, Material.ENDER_CHEST, Material.TRAPPED_CHEST, Material.COMPARATOR, Material.HOPPER, Material.DROPPER, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.GRINDSTONE, Material.LOOM, Material.SMOKER, Material.CRAFTING_TABLE, Material.CARTOGRAPHY_TABLE, Material.ENCHANTING_TABLE, Material.SMITHING_TABLE, Material.STONECUTTER, Material.CRIMSON_FENCE_GATE, Material.WARPED_FENCE_GATE, Material.CRIMSON_TRAPDOOR, Material.WARPED_TRAPDOOR));
BlockGroup.SAFE_INTERACT_BLOCKS = new HashSet<>(Arrays.asList(Material.LEVER, Material.MANGROVE_TRAPDOOR, Material.ACACIA_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.DARK_OAK_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.OAK_TRAPDOOR, Material.OAK_FENCE_GATE, Material.SPRUCE_FENCE_GATE, Material.BIRCH_FENCE_GATE, Material.JUNGLE_FENCE_GATE, Material.DARK_OAK_FENCE_GATE, Material.MANGROVE_FENCE_GATE, Material.ACACIA_FENCE_GATE, Material.CRIMSON_FENCE_GATE, Material.WARPED_FENCE_GATE, Material.CRIMSON_TRAPDOOR, Material.WARPED_TRAPDOOR));
BlockGroup.NON_ATTACHABLE = new HashSet<>(Arrays.asList(Material.AIR, Material.CAVE_AIR, Material.BARRIER, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.MANGROVE_PROPAGULE, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.WATER, Material.LAVA, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.GRASS, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.LADDER, Material.RAIL, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.SNOW, Material.SUGAR_CANE, Material.NETHER_PORTAL, Material.REPEATER, Material.KELP, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.LIGHT, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF, Material.BIG_DRIPLEAF_STEM, Material.GLOW_LICHEN, Material.HANGING_ROOTS));
BlockGroup.SCULK = new HashSet<>(Arrays.asList(Material.SCULK, Material.SCULK_VEIN, Material.SCULK_SENSOR, Material.SCULK_SHRIEKER));
}
@Override
public boolean getEntityMeta(LivingEntity entity, List<Object> info) {
if (entity instanceof Frog) {
Frog frog = (Frog) entity;
info.add(frog.getVariant());
}
else if (entity instanceof Tadpole) {
Tadpole tadpole = (Tadpole) entity;
info.add(tadpole.getAge());
}
else if (entity instanceof Goat) {
Goat goat = (Goat) entity;
info.add(goat.isScreaming());
info.add(goat.hasLeftHorn());
info.add(goat.hasRightHorn());
}
else if (super.getEntityMeta(entity, info)) {
return true;
}
else {
return false;
}
return true;
}
@Override
public boolean setEntityMeta(Entity entity, Object value, int count) {
if (entity instanceof Frog) {
Frog frog = (Frog) entity;
if (count == 0) {
Frog.Variant set = (Frog.Variant) value;
frog.setVariant(set);
}
}
else if (entity instanceof Tadpole) {
Tadpole tadpole = (Tadpole) entity;
if (count == 0) {
int set = (int) value;
tadpole.setAge(set);
}
}
else if (entity instanceof Goat) {
Goat goat = (Goat) entity;
boolean set = (Boolean) value;
if (count == 0) {
goat.setScreaming(set);
}
else if (count == 1) {
goat.setLeftHorn(set);
}
else if (count == 2) {
goat.setRightHorn(set);
}
}
else if (super.setEntityMeta(entity, value, count)) {
return true;
}
else {
return false;
}
return true;
}
}
@@ -1196,6 +1196,9 @@ public class CommandHandler implements CommandExecutor {
else if (user.hasPermission("coreprotect.consumer") && corecommand.equals("consumer")) {
permission = true;
}
else if (user.hasPermission("coreprotect.networking") && corecommand.equals("network-debug")) {
permission = true;
}
}
if (corecommand.equals("rollback") || corecommand.equals("restore") || corecommand.equals("rb") || corecommand.equals("rs") || corecommand.equals("ro") || corecommand.equals("re")) {
@@ -1237,6 +1240,9 @@ public class CommandHandler implements CommandExecutor {
else if (corecommand.equals("consumer")) {
ConsumerCommand.runCommand(user, permission, argumentArray);
}
else if (corecommand.equals("network-debug")) {
NetworkDebugCommand.runCommand(user, permission, argumentArray);
}
else {
Chat.sendMessage(user, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.COMMAND_NOT_FOUND, Color.WHITE, "/co " + corecommand));
}
@@ -34,6 +34,8 @@ import net.coreprotect.database.lookup.SignMessageLookup;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.listener.channel.PluginChannelHandshakeListener;
import net.coreprotect.listener.channel.PluginChannelListener;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.ChatMessage;
import net.coreprotect.utility.Color;
@@ -832,6 +834,13 @@ public class LookupCommand {
String message = data[2];
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
Chat.sendComponent(player2, timeago + " " + Color.WHITE + "- " + Color.DARK_AQUA + dplayer + ": " + Color.WHITE, message);
if (PluginChannelHandshakeListener.getInstance().isPluginChannelPlayer(player2)) {
int wid = Integer.parseInt(data[3]);
int x = Integer.parseInt(data[4]);
int y = Integer.parseInt(data[5]);
int z = Integer.parseInt(data[6]);
PluginChannelListener.getInstance().sendMessageData(player2, Integer.parseInt(time), dplayer, message, false, x, y, z, wid);
}
}
}
else if (finalArgAction.contains(8)) { // login/logouts
@@ -856,6 +865,7 @@ public class LookupCommand {
String tag = (action != 0 ? Color.GREEN + "+" : Color.RED + "-");
Chat.sendComponent(player2, timeago + " " + tag + " " + Color.DARK_AQUA + Phrase.build(Phrase.LOOKUP_LOGIN, Color.DARK_AQUA + dplayer + Color.WHITE, (action != 0 ? Selector.FIRST : Selector.SECOND)));
Chat.sendComponent(player2, Color.WHITE + leftPadding + Color.GREY + "^ " + Util.getCoordinates(command.getName(), wid, x, y, z, true, true) + "");
PluginChannelListener.getInstance().sendInfoData(player2, Integer.parseInt(time), Phrase.LOOKUP_LOGIN, (action != 0 ? Selector.FIRST : Selector.SECOND), dplayer, -1, x, y, z, wid);
}
}
else if (finalArgAction.contains(9)) { // username-changes
@@ -865,6 +875,7 @@ public class LookupCommand {
String username = data[2];
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
Chat.sendComponent(player2, timeago + " " + Color.WHITE + "- " + Phrase.build(Phrase.LOOKUP_USERNAME, Color.DARK_AQUA + user + Color.WHITE, Color.DARK_AQUA + username + Color.WHITE));
PluginChannelListener.getInstance().sendUsernameData(player2, Integer.parseInt(time), user, username);
}
}
else if (finalArgAction.contains(10)) { // sign messages
@@ -888,6 +899,7 @@ public class LookupCommand {
Chat.sendComponent(player2, timeago + " " + Color.WHITE + "- " + Color.DARK_AQUA + dplayer + ": " + Color.WHITE, message);
Chat.sendComponent(player2, Color.WHITE + leftPadding + Color.GREY + "^ " + Util.getCoordinates(command.getName(), wid, x, y, z, true, true) + "");
PluginChannelListener.getInstance().sendMessageData(player2, Integer.parseInt(time), dplayer, message, true, x, y, z, wid);
}
}
else if (finalArgAction.contains(4) && finalArgAction.contains(11)) { // inventory transactions
@@ -898,6 +910,10 @@ public class LookupCommand {
int ddata = Integer.parseInt(data[6]);
int daction = Integer.parseInt(data[7]);
int amount = Integer.parseInt(data[10]);
int wid = Integer.parseInt(data[9]);
int x = Integer.parseInt(data[2]);
int y = Integer.parseInt(data[3]);
int z = Integer.parseInt(data[4]);
String rbd = ((Integer.parseInt(data[8]) == 2 || Integer.parseInt(data[8]) == 3) ? Color.STRIKETHROUGH : "");
String timeago = Util.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
Material blockType = Util.itemFilter(Util.getType(Integer.parseInt(dtype)), (Integer.parseInt(data[13]) == 0));
@@ -931,6 +947,7 @@ public class LookupCommand {
}
Chat.sendComponent(player2, timeago + " " + tag + " " + Phrase.build(Phrase.LOOKUP_CONTAINER, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, "x" + amount, Color.DARK_AQUA + rbd + dname + Color.WHITE, selector));
PluginChannelListener.getInstance().sendData(player2, Integer.parseInt(time), Phrase.LOOKUP_CONTAINER, selector, dplayer, dname, amount, x, y, z, wid, rbd, true, tag.contains("+"));
}
}
else {
@@ -1024,6 +1041,7 @@ public class LookupCommand {
}
Chat.sendComponent(player2, timeago + " " + tag + " " + Phrase.build(phrase, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, "x" + amount, Color.DARK_AQUA + rbd + dname + Color.WHITE, selector));
PluginChannelListener.getInstance().sendData(player2, Integer.parseInt(time), phrase, selector, dplayer, dname, (tag.contains("+") ? 1 : -1), x, y, z, wid, rbd, action.contains("container"), tag.contains("+"));
}
else {
if (daction == 2 || daction == 3) {
@@ -1039,6 +1057,7 @@ public class LookupCommand {
}
Chat.sendComponent(player2, timeago + " " + tag + " " + Phrase.build(phrase, Color.DARK_AQUA + rbd + dplayer + Color.WHITE + rbd, Color.DARK_AQUA + rbd + dname + Color.WHITE, selector));
PluginChannelListener.getInstance().sendData(player2, Integer.parseInt(time), phrase, selector, dplayer, dname, (tag.contains("+") ? 1 : -1), x, y, z, wid, rbd, false, tag.contains("+"));
}
action = (finalArgAction.size() == 0 ? " (" + action + ")" : "");
@@ -0,0 +1,25 @@
package net.coreprotect.command;
import org.bukkit.command.CommandSender;
import net.coreprotect.config.Config;
import net.coreprotect.language.Phrase;
import net.coreprotect.listener.channel.PluginChannelListener;
import net.coreprotect.utility.Chat;
import net.coreprotect.utility.Color;
public class NetworkDebugCommand {
protected static void runCommand(CommandSender player, boolean permission, String[] args) {
if (!permission || !Config.getGlobal().NETWORK_DEBUG) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION));
return;
}
try {
PluginChannelListener.getInstance().sendTest(player, args.length == 2 ? args[1] : "");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -141,11 +141,11 @@ public class TabHandler implements TabCompleter {
}
}
if (lastArg.equals("a:") || lastArg.equals("action:")) {
if ((lastArg.equals("a:") || lastArg.equals("action:")) && (sender.hasPermission("coreprotect.lookup") || sender.hasPermission("coreprotect.rollback") || sender.hasPermission("coreprotect.restore"))) {
List<String> completions = new ArrayList<>(Arrays.asList(ACTIONS));
return StringUtil.copyPartialMatches(currentArg, completions, new ArrayList<>(completions.size()));
}
else if (currentArg.startsWith("a:") || currentArg.startsWith("action:")) {
else if ((currentArg.startsWith("a:") || currentArg.startsWith("action:")) && (sender.hasPermission("coreprotect.lookup") || sender.hasPermission("coreprotect.rollback") || sender.hasPermission("coreprotect.restore"))) {
String arg = "";
String[] split = currentArg.split(":", 2);
String filter = split[0] + ":";
@@ -159,10 +159,10 @@ public class TabHandler implements TabCompleter {
}
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
}
else if (lastArg.equals("u:") || lastArg.equals("user:") || lastArg.equals("users:") || lastArg.equals("p:")) {
else if ((lastArg.equals("u:") || lastArg.equals("user:") || lastArg.equals("users:") || lastArg.equals("p:")) && (sender.hasPermission("coreprotect.lookup") || sender.hasPermission("coreprotect.rollback") || sender.hasPermission("coreprotect.restore"))) {
return null;
}
else if (currentArg.startsWith("u:") || currentArg.startsWith("user:") || currentArg.startsWith("users:") || currentArg.startsWith("p:")) {
else if ((currentArg.startsWith("u:") || currentArg.startsWith("user:") || currentArg.startsWith("users:") || currentArg.startsWith("p:")) && (sender.hasPermission("coreprotect.lookup") || sender.hasPermission("coreprotect.rollback") || sender.hasPermission("coreprotect.restore"))) {
String arg = "";
String[] split = currentArg.split(":", 2);
String filter = split[0] + ":";
@@ -177,7 +177,7 @@ public class TabHandler implements TabCompleter {
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
}
else if (lastArg.equals("t:") || lastArg.equals("time:") || currentArg.startsWith("t:") || currentArg.startsWith("time:")) {
else if ((lastArg.equals("t:") || lastArg.equals("time:") || currentArg.startsWith("t:") || currentArg.startsWith("time:")) && (sender.hasPermission("coreprotect.lookup") || sender.hasPermission("coreprotect.rollback") || sender.hasPermission("coreprotect.restore") || sender.hasPermission("coreprotect.purge"))) {
String filter = lastArg;
String arg = "";
if (currentArg.contains(":")) {
@@ -215,7 +215,7 @@ public class TabHandler implements TabCompleter {
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
}
else if (lastArg.equals("page:") || currentArg.startsWith("page:")) {
else if ((lastArg.equals("page:") || currentArg.startsWith("page:")) && (sender.hasPermission("coreprotect.lookup") || sender.hasPermission("coreprotect.lookup.near") || sender.hasPermission("coreprotect.inspect"))) {
String filter = lastArg;
String arg = "";
if (currentArg.contains(":")) {
@@ -243,7 +243,7 @@ public class TabHandler implements TabCompleter {
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
}
}
else if (lastArg.equals("r:") || lastArg.equals("radius:") || currentArg.startsWith("r:") || currentArg.startsWith("radius:")) {
else if ((lastArg.equals("r:") || lastArg.equals("radius:") || currentArg.startsWith("r:") || currentArg.startsWith("radius:")) && (sender.hasPermission("coreprotect.lookup") || sender.hasPermission("coreprotect.rollback") || sender.hasPermission("coreprotect.restore") || sender.hasPermission("coreprotect.purge"))) {
String filter = lastArg;
String arg = "";
if (currentArg.contains(":")) {
@@ -284,7 +284,7 @@ public class TabHandler implements TabCompleter {
return StringUtil.copyPartialMatches(filter + arg, completions, new ArrayList<>(completions.size()));
}
}
else if (lastArg.equals("i:") || lastArg.equals("include:") || lastArg.equals("item:") || lastArg.equals("items:") || lastArg.equals("b:") || lastArg.equals("block:") || lastArg.equals("blocks:") || currentArg.startsWith("i:") || currentArg.startsWith("include:") || currentArg.startsWith("item:") || currentArg.startsWith("items:") || currentArg.startsWith("b:") || currentArg.startsWith("block:") || currentArg.startsWith("blocks:") || lastArg.equals("e:") || lastArg.equals("exclude:") || currentArg.startsWith("e:") || currentArg.startsWith("exclude:")) {
else if ((sender.hasPermission("coreprotect.lookup") || sender.hasPermission("coreprotect.rollback") || sender.hasPermission("coreprotect.restore")) && (lastArg.equals("i:") || lastArg.equals("include:") || lastArg.equals("item:") || lastArg.equals("items:") || lastArg.equals("b:") || lastArg.equals("block:") || lastArg.equals("blocks:") || currentArg.startsWith("i:") || currentArg.startsWith("include:") || currentArg.startsWith("item:") || currentArg.startsWith("items:") || currentArg.startsWith("b:") || currentArg.startsWith("block:") || currentArg.startsWith("blocks:") || lastArg.equals("e:") || lastArg.equals("exclude:") || currentArg.startsWith("e:") || currentArg.startsWith("exclude:"))) {
String filter = lastArg;
String arg = "";
if (currentArg.contains(":")) {
@@ -328,21 +328,21 @@ public class TabHandler implements TabCompleter {
}
else if (args.length == 2) {
if (argument0.equals("help")) {
if (argument0.equals("help") && sender.hasPermission("coreprotect.help")) {
List<String> completions = new ArrayList<>(Arrays.asList(HELP));
return StringUtil.copyPartialMatches(argument1, completions, new ArrayList<>(completions.size()));
}
else if (argument0.equals("purge")) {
else if (argument0.equals("purge") && sender.hasPermission("coreprotect.purge")) {
List<String> completions = new ArrayList<>(Arrays.asList("t:", "r:"));
return StringUtil.copyPartialMatches(argument1, completions, new ArrayList<>(completions.size()));
}
else if (argument0.equals("l") || argument0.equals("lookup") || argument0.equals("rollback") || argument0.equals("rb") || argument0.equals("ro") || argument0.equals("restore") || argument0.equals("rs") || argument0.equals("re")) {
else if ((sender.hasPermission("coreprotect.lookup") && (argument0.equals("l") || argument0.equals("lookup"))) || (sender.hasPermission("coreprotect.rollback") && (argument0.equals("rollback") || argument0.equals("rb") || argument0.equals("ro"))) || (sender.hasPermission("coreprotect.restore") && (argument0.equals("restore") || argument0.equals("rs") || argument0.equals("re")))) {
List<String> completions = new ArrayList<>(filterParams(true, argument0, argument1, hasUser, hasAction, hasInclude, hasExclude, hasRadius, hasTime, hasContainer, hasCount, hasPreview, pageLookup, validContainer));
completions.addAll(Bukkit.getOnlinePlayers().stream().filter(player -> player.getName().toLowerCase(Locale.ROOT).startsWith(argument1)).map(Player::getName).collect(Collectors.toList()));
return StringUtil.copyPartialMatches(argument1, completions, new ArrayList<>(completions.size()));
}
}
else if (args.length == 3 && argument0.equals("purge")) {
else if (args.length == 3 && argument0.equals("purge") && sender.hasPermission("coreprotect.purge")) {
if (argument1.startsWith("t:")) {
List<String> completions = new ArrayList<>(Arrays.asList("r:"));
return StringUtil.copyPartialMatches(args[2].toLowerCase(Locale.ROOT), completions, new ArrayList<>(completions.size()));
@@ -353,7 +353,7 @@ public class TabHandler implements TabCompleter {
}
return Arrays.asList("");
}
else if (argument0.equals("l") || argument0.equals("lookup") || argument0.equals("rollback") || argument0.equals("rb") || argument0.equals("ro") || argument0.equals("restore") || argument0.equals("rs") || argument0.equals("re")) {
else if ((sender.hasPermission("coreprotect.lookup") && (argument0.equals("l") || argument0.equals("lookup"))) || (sender.hasPermission("coreprotect.rollback") && (argument0.equals("rollback") || argument0.equals("rb") || argument0.equals("ro"))) || (sender.hasPermission("coreprotect.restore") && (argument0.equals("restore") || argument0.equals("rs") || argument0.equals("re")))) {
if ((!argument0.equals("l") && !argument0.equals("lookup")) || !hasPage) {
ArrayList<String> params = filterParams(false, argument0, currentArg, hasUser, hasAction, hasInclude, hasExclude, hasRadius, hasTime, hasContainer, hasCount, hasPreview, pageLookup, validContainer);
List<String> completions = new ArrayList<>(params);
@@ -48,6 +48,7 @@ public class Config extends Language {
public boolean LOG_CANCELLED_CHAT;
public boolean HOPPER_FILTER_META;
public boolean EXCLUDE_TNT;
public boolean NETWORK_DEBUG;
public boolean MYSQL;
public boolean CHECK_UPDATES;
public boolean API_ENABLED;
@@ -71,6 +72,7 @@ public class Config extends Language {
public boolean TREE_GROWTH;
public boolean MUSHROOM_GROWTH;
public boolean VINE_GROWTH;
public boolean SCULK_SPREAD;
public boolean PORTALS;
public boolean WATER_FLOW;
public boolean LAVA_FLOW;
@@ -123,6 +125,7 @@ public class Config extends Language {
DEFAULT_VALUES.put("tree-growth", "true");
DEFAULT_VALUES.put("mushroom-growth", "true");
DEFAULT_VALUES.put("vine-growth", "true");
DEFAULT_VALUES.put("sculk-spread", "true");
DEFAULT_VALUES.put("portals", "true");
DEFAULT_VALUES.put("water-flow", "true");
DEFAULT_VALUES.put("lava-flow", "true");
@@ -138,7 +141,7 @@ public class Config extends Language {
DEFAULT_VALUES.put("username-changes", "true");
DEFAULT_VALUES.put("worldedit", "true");
HEADERS.put("donation-key", new String[] { "# CoreProtect is donationware. For more information, visit our project page." });
HEADERS.put("donation-key", new String[] { "# CoreProtect is donationware. Obtain a donation key from coreprotect.net/donate/" });
HEADERS.put("use-mysql", new String[] { "# MySQL is optional and not required.", "# If you prefer to use MySQL, enable the following and fill out the fields." });
HEADERS.put("language", new String[] { "# If modified, will automatically attempt to translate languages phrases.", "# List of language codes: https://coreprotect.net/languages/" });
HEADERS.put("check-updates", new String[] { "# If enabled, CoreProtect will check for updates when your server starts up.", "# If an update is available, you'll be notified via your server console.", });
@@ -165,6 +168,7 @@ public class Config extends Language {
HEADERS.put("tree-growth", new String[] { "# Logs tree growth. Trees are linked to the player who planted the sappling." });
HEADERS.put("mushroom-growth", new String[] { "# Logs mushroom growth." });
HEADERS.put("vine-growth", new String[] { "# Logs natural vine growth." });
HEADERS.put("sculk-spread", new String[] { "# Logs the spread of sculk blocks from sculk catalysts." });
HEADERS.put("portals", new String[] { "# Logs when portals such as Nether portals generate naturally." });
HEADERS.put("water-flow", new String[] { "# Logs water flow. If water destroys other blocks, such as torches,", "# this allows it to be properly rolled back." });
HEADERS.put("lava-flow", new String[] { "# Logs lava flow. If lava destroys other blocks, such as torches,", "# this allows it to be properly rolled back." });
@@ -189,6 +193,7 @@ public class Config extends Language {
this.LOG_CANCELLED_CHAT = this.getBoolean("log-cancelled-chat", true);
this.HOPPER_FILTER_META = this.getBoolean("hopper-filter-meta", false);
this.EXCLUDE_TNT = this.getBoolean("exclude-tnt", false);
this.NETWORK_DEBUG = this.getBoolean("network-debug", false);
this.DONATION_KEY = this.getString("donation-key");
this.MYSQL = this.getBoolean("use-mysql");
this.PREFIX = this.getString("table-prefix");
@@ -222,6 +227,7 @@ public class Config extends Language {
this.TREE_GROWTH = this.getBoolean("tree-growth");
this.MUSHROOM_GROWTH = this.getBoolean("mushroom-growth");
this.VINE_GROWTH = this.getBoolean("vine-growth");
this.SCULK_SPREAD = this.getBoolean("sculk-spread");
this.PORTALS = this.getBoolean("portals");
this.WATER_FLOW = this.getBoolean("water-flow");
this.LAVA_FLOW = this.getBoolean("lava-flow");
@@ -28,6 +28,7 @@ import net.coreprotect.consumer.Queue;
import net.coreprotect.database.Database;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.listener.ListenerHandler;
import net.coreprotect.model.BlockGroup;
import net.coreprotect.paper.PaperAdapter;
import net.coreprotect.patch.Patch;
@@ -228,6 +229,8 @@ public class ConfigHandler extends Queue {
config.setJdbcUrl("jdbc:mysql://" + ConfigHandler.host + ":" + ConfigHandler.port + "/" + ConfigHandler.database);
config.setUsername(ConfigHandler.username);
config.setPassword(ConfigHandler.password);
config.setMaxLifetime(300000);
config.setKeepaliveTime(60000);
config.addDataSourceProperty("characterEncoding", "UTF-8");
config.addDataSourceProperty("connectionTimeout", "10000");
/* https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration */
@@ -411,7 +414,7 @@ public class ConfigHandler extends Queue {
ConfigHandler.loadConfig(); // Load (or create) the configuration file.
ConfigHandler.loadDatabase(); // Initialize MySQL and create tables if necessary.
ListenerHandler.registerNetworking(); // Register channels for networking API
}
catch (Exception e) {
e.printStackTrace();
@@ -455,4 +458,14 @@ public class ConfigHandler extends Queue {
return false;
}
public static void performDisable() {
try {
Database.closeConnection();
ListenerHandler.unregisterNetworking(); // Unregister channels for networking API
}
catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -22,6 +22,7 @@ import net.coreprotect.consumer.Consumer;
import net.coreprotect.consumer.Queue;
import net.coreprotect.database.logger.ItemLogger;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.listener.channel.PluginChannelHandshakeListener;
import net.coreprotect.thread.CacheHandler;
import net.coreprotect.utility.Util;
@@ -147,6 +148,13 @@ public class Lookup extends Queue {
String resultMessage = results.getString("message");
Object[] dataArray = new Object[] { resultId, resultTime, resultUserId, resultMessage };
if (PluginChannelHandshakeListener.getInstance().isPluginChannelPlayer(user)) {
int resultWorldId = results.getInt("wid");
int resultX = results.getInt("x");
int resultY = results.getInt("y");
int resultZ = results.getInt("z");
dataArray = new Object[] { resultId, resultTime, resultUserId, resultMessage, resultWorldId, resultX, resultY, resultZ };
}
list.add(dataArray);
}
else if (actionList.contains(8)) {
@@ -619,6 +627,9 @@ public class Lookup extends Queue {
else if (actionList.contains(6) || actionList.contains(7)) {
queryTable = "chat";
rows = "rowid as id,time,user,message";
if (PluginChannelHandshakeListener.getInstance().isPluginChannelPlayer(user)) {
rows += ",wid,x,y,z";
}
if (actionList.contains(7)) {
queryTable = "command";
@@ -650,24 +661,17 @@ public class Lookup extends Queue {
String unionSelect = "SELECT * FROM (";
if (Config.getGlobal().MYSQL) {
if (radius == null || users.length() > 0 || includeBlock.length() > 0 || includeEntity.length() > 0) {
// index_mysql = "IGNORE INDEX(wid) ";
if (users.length() > 0) {
// index_mysql = "IGNORE INDEX(wid,type,action) ";
}
}
if (queryTable.equals("block")) {
if (includeBlock.length() > 0 || includeEntity.length() > 0) {
index = "USE INDEX(type) ";
index = "USE INDEX(type) IGNORE INDEX(user,wid) ";
}
if (users.length() > 0) {
index = "USE INDEX(user) ";
index = "USE INDEX(user) IGNORE INDEX(type,wid) ";
}
if ((index.equals("") && restrictWorld)) {
index = "USE INDEX(wid) ";
if (radius != null && (radius[2] - radius[1]) <= 50 && (radius[6] - radius[5]) <= 50) {
index = "USE INDEX(wid) IGNORE INDEX(type,user) ";
}
if ((radius != null || actionList.size() > 0)) {
if ((restrictWorld && (users.length() > 0 || includeBlock.length() > 0 || includeEntity.length() > 0))) {
index = "";
}
}
@@ -682,10 +686,10 @@ public class Lookup extends Queue {
if (users.length() > 0) {
index = "INDEXED BY block_user_index ";
}
if ((index.equals("") && restrictWorld)) {
if (radius != null && (radius[2] - radius[1]) <= 50 && (radius[6] - radius[5]) <= 50) {
index = "INDEXED BY block_index ";
}
if ((radius != null || actionList.size() > 0)) {
if ((restrictWorld && (users.length() > 0 || includeBlock.length() > 0 || includeEntity.length() > 0))) {
index = "";
}
}
@@ -1914,7 +1914,7 @@ public class Rollback extends Queue {
}
itemstack.setItemMeta(meta);
}
else if ((rowType == Material.MAP)) {
else if (rowType == Material.MAP || rowType == Material.FILLED_MAP) {
for (Map<String, Object> colorData : map) {
MapMeta meta = (MapMeta) itemstack.getItemMeta();
org.bukkit.Color color = org.bukkit.Color.deserialize(colorData);
@@ -24,6 +24,10 @@ public class PlayerKillLogger {
return;
}
if (ConfigHandler.playerIdCache.get(player.toLowerCase(Locale.ROOT)) == null) {
UserStatement.loadId(preparedStmt.getConnection(), player, null);
}
CoreProtectPreLogEvent event = new CoreProtectPreLogEvent(user);
CoreProtect.getInstance().getServer().getPluginManager().callEvent(event);
@@ -12,6 +12,7 @@ import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.listener.channel.PluginChannelListener;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
@@ -130,6 +131,7 @@ public class BlockLookup {
}
resultTextBuilder.append(timeAgo + " " + tag + " ").append(Phrase.build(phrase, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, Color.DARK_AQUA + rbFormat + target + Color.WHITE, selector)).append("\n");
PluginChannelListener.getInstance().sendData(commandSender, resultTime, phrase, selector, resultUser, target, -1, x, y, z, worldId, rbFormat, false, tag.contains("+"));
}
resultText = resultTextBuilder.toString();
@@ -12,6 +12,7 @@ import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.listener.channel.PluginChannelListener;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
@@ -117,6 +118,7 @@ public class ChestTransactionLookup {
}
resultBuilder.append(timeAgo + " " + tag + " ").append(Phrase.build(Phrase.LOOKUP_CONTAINER, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, "x" + resultAmount, Color.DARK_AQUA + rbFormat + target + Color.WHITE, selector)).append("\n");
PluginChannelListener.getInstance().sendData(commandSender, resultTime, Phrase.LOOKUP_CONTAINER, selector, resultUser, target, resultAmount, x, y, z, worldId, rbFormat, true, tag.contains("+"));
}
result = resultBuilder.toString();
results.close();
@@ -12,6 +12,7 @@ import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.listener.channel.PluginChannelListener;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
@@ -108,6 +109,7 @@ public class InteractionLookup {
}
resultBuilder.append(timeAgo + " " + Color.WHITE + "- ").append(Phrase.build(Phrase.LOOKUP_INTERACTION, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, Color.DARK_AQUA + rbFormat + target + Color.WHITE, Selector.FIRST)).append("\n");
PluginChannelListener.getInstance().sendData(commandSender, resultTime, Phrase.LOOKUP_INTERACTION, Selector.FIRST, resultUser, target, -1, x, y, z, worldId, rbFormat, false, false);
}
result = resultBuilder.toString();
results.close();
@@ -12,6 +12,7 @@ import net.coreprotect.config.ConfigHandler;
import net.coreprotect.database.statement.UserStatement;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.listener.channel.PluginChannelListener;
import net.coreprotect.utility.Color;
import net.coreprotect.utility.Util;
@@ -109,6 +110,7 @@ public class SignMessageLookup {
}
found = true;
result.add(timeAgo + Color.WHITE + " - " + Color.DARK_AQUA + resultUser + ": " + Color.WHITE + "\n" + message.toString() + Color.WHITE);
PluginChannelListener.getInstance().sendMessageData(commandSender, resultTime, resultUser, message.toString(), true, x, y, z, worldId);
}
results.close();
@@ -154,6 +154,8 @@ public class Language {
phrases.put(Phrase.MISSING_ROLLBACK_RADIUS, "You did not specify a {rollback|restore} radius.");
phrases.put(Phrase.MISSING_ROLLBACK_USER, "You did not specify a {rollback|restore} user.");
phrases.put(Phrase.MYSQL_UNAVAILABLE, "Unable to connect to MySQL server.");
phrases.put(Phrase.NETWORK_CONNECTION, "Connection by {0} {successful|failed}. Using {1} {2}.");
phrases.put(Phrase.NETWORK_TEST, "Network test data has been successful sent.");
phrases.put(Phrase.NO_DATA, "No data found at {0}.");
phrases.put(Phrase.NO_DATA_LOCATION, "No {data|transactions|interactions|messages} found at this location.");
phrases.put(Phrase.NO_PERMISSION, "You do not have permission to do that.");
@@ -3,6 +3,8 @@ package net.coreprotect.language;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.coreprotect.utility.ChatMessage;
import net.coreprotect.utility.Color;
@@ -135,6 +137,8 @@ public enum Phrase {
MISSING_ROLLBACK_RADIUS,
MISSING_ROLLBACK_USER,
MYSQL_UNAVAILABLE,
NETWORK_CONNECTION,
NETWORK_TEST,
NO_DATA,
NO_DATA_LOCATION,
NO_PERMISSION,
@@ -287,4 +291,16 @@ public enum Phrase {
return output;
}
public static String getPhraseSelector(Phrase phrase, String selector) {
String translatedPhrase = phrase.getTranslatedPhrase();
Pattern phrasePattern = Pattern.compile("(\\{[a-zA-Z| ]+})");
Matcher patternMatch = phrasePattern.matcher(translatedPhrase);
String match = "";
if (patternMatch.find()) {
match = patternMatch.group(1);
match = Selector.processSelection(match, selector, "");
}
return match;
}
}
@@ -15,6 +15,8 @@ import net.coreprotect.listener.block.BlockIgniteListener;
import net.coreprotect.listener.block.BlockPistonListener;
import net.coreprotect.listener.block.BlockPlaceListener;
import net.coreprotect.listener.block.BlockSpreadListener;
import net.coreprotect.listener.channel.PluginChannelHandshakeListener;
import net.coreprotect.listener.channel.PluginChannelListener;
import net.coreprotect.listener.entity.CreatureSpawnListener;
import net.coreprotect.listener.entity.EntityBlockFormListener;
import net.coreprotect.listener.entity.EntityChangeBlockListener;
@@ -122,6 +124,20 @@ public final class ListenerHandler {
pluginManager.registerEvents(new PlayerChatListener(), plugin);
}
// Plugin channel events
pluginManager.registerEvents(new PluginChannelListener(), plugin);
}
public static void registerNetworking() {
CoreProtect.getInstance().getServer().getMessenger().registerIncomingPluginChannel(CoreProtect.getInstance(), PluginChannelHandshakeListener.pluginChannel, new PluginChannelHandshakeListener());
CoreProtect.getInstance().getServer().getMessenger().registerOutgoingPluginChannel(CoreProtect.getInstance(), PluginChannelHandshakeListener.pluginChannel);
CoreProtect.getInstance().getServer().getMessenger().registerOutgoingPluginChannel(CoreProtect.getInstance(), PluginChannelListener.pluginChannel);
}
public static void unregisterNetworking() {
CoreProtect.getInstance().getServer().getMessenger().unregisterIncomingPluginChannel(CoreProtect.getInstance(), PluginChannelHandshakeListener.pluginChannel);
CoreProtect.getInstance().getServer().getMessenger().unregisterOutgoingPluginChannel(CoreProtect.getInstance(), PluginChannelHandshakeListener.pluginChannel);
CoreProtect.getInstance().getServer().getMessenger().unregisterOutgoingPluginChannel(CoreProtect.getInstance(), PluginChannelListener.pluginChannel);
}
}
@@ -27,20 +27,16 @@ public final class BlockSpreadListener extends Queue implements Listener {
* block-change: true
*
*/
if (event.isCancelled()) {
return;
}
if (!event.isCancelled() && Config.getConfig(event.getBlock().getWorld()).VINE_GROWTH) {
BlockState blockstate = event.getNewState();
Material type = blockstate.getType();
if (!BlockGroup.VINES.contains(type) && !BlockGroup.AMETHYST.contains(type) && type != Material.CHORUS_FLOWER && type != Material.BAMBOO) {
return;
}
BlockState blockstate = event.getNewState();
Material type = blockstate.getType();
if (Config.getConfig(event.getBlock().getWorld()).VINE_GROWTH && (BlockGroup.VINES.contains(type) || BlockGroup.AMETHYST.contains(type) || type == Material.CHORUS_FLOWER || type == Material.BAMBOO)) {
Block block = event.getBlock();
Location location = block.getLocation();
int timestamp = (int) (System.currentTimeMillis() / 1000L);
Object[] cacheData = CacheHandler.spreadCache.get(location);
CacheHandler.spreadCache.put(location, new Object[] { timestamp, type });
if (cacheData != null && ((Material) cacheData[1]) == type) {
if (checkCacheData(block, type)) {
return;
}
@@ -74,6 +70,25 @@ public final class BlockSpreadListener extends Queue implements Listener {
Queue.queueBlockPlaceDelayed("#bamboo", block.getLocation(), type, null, block.getState(), 0);
}
}
else if (Config.getConfig(event.getBlock().getWorld()).SCULK_SPREAD && BlockGroup.SCULK.contains(type)) {
Block block = event.getBlock();
if (checkCacheData(block, type)) {
return;
}
queueBlockPlace("#sculk_catalyst", block.getState(), block.getType(), block.getState(), type, -1, 0, blockstate.getBlockData().getAsString());
}
}
private boolean checkCacheData(Block block, Material type) {
Location location = block.getLocation();
int timestamp = (int) (System.currentTimeMillis() / 1000L);
Object[] cacheData = CacheHandler.spreadCache.get(location);
CacheHandler.spreadCache.put(location, new Object[] { timestamp, type });
if (cacheData != null && ((Material) cacheData[1]) == type) {
return true;
}
return false;
}
}
@@ -0,0 +1,109 @@
package net.coreprotect.listener.channel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.messaging.PluginMessageListener;
import net.coreprotect.CoreProtect;
import net.coreprotect.config.Config;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.utility.Chat;
public class PluginChannelHandshakeListener implements PluginMessageListener, Listener {
public static final String pluginChannel = "coreprotect:handshake";
private final int networkingProtocolVersion = 1;
private final Set<UUID> pluginChannelPlayers;
private static PluginChannelHandshakeListener instance;
public PluginChannelHandshakeListener() {
instance = this;
pluginChannelPlayers = new HashSet<>();
}
public static PluginChannelHandshakeListener getInstance() {
return instance;
}
public Set<UUID> getPluginChannelPlayers() {
return pluginChannelPlayers;
}
public boolean isPluginChannelPlayer(CommandSender commandSender) {
if (!(commandSender instanceof Player)) {
return false;
}
return getPluginChannelPlayers().contains(((Player) commandSender).getUniqueId());
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
getPluginChannelPlayers().remove(event.getPlayer().getUniqueId());
}
@Override
public void onPluginMessageReceived(String s, Player player, byte[] bytes) {
handleHandshake(s, player, bytes);
}
private void handleHandshake(String channel, Player player, byte[] bytes) {
if (!player.hasPermission("coreprotect.networking")) {
return;
}
if (!channel.equals(pluginChannel)) {
return;
}
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
DataInputStream dis = new DataInputStream(in);
try {
String modVersion = dis.readUTF();
String modId = dis.readUTF();
int protocolVersion = dis.readInt();
if (Config.getGlobal().NETWORK_DEBUG) {
Chat.console(new String(bytes));
Chat.console(modVersion);
Chat.console(modId);
Chat.console(String.valueOf(protocolVersion));
}
if (protocolVersion != networkingProtocolVersion) {
Chat.console(Phrase.build(Phrase.NETWORK_CONNECTION, player.getName(), modId, modVersion, Selector.SECOND));
return;
}
getPluginChannelPlayers().add(player.getUniqueId());
Chat.console(Phrase.build(Phrase.NETWORK_CONNECTION, player.getName(), modId, modVersion, Selector.FIRST));
player.sendPluginMessage(CoreProtect.getInstance(), pluginChannel, sendRegistered());
}
catch (Exception exception) {
Chat.console(exception.toString());
exception.printStackTrace();
}
}
private byte[] sendRegistered() throws IOException {
ByteArrayOutputStream msgBytes = new ByteArrayOutputStream();
DataOutputStream msgOut = new DataOutputStream(msgBytes);
msgOut.writeBoolean(true);
return msgBytes.toByteArray();
}
}
@@ -0,0 +1,218 @@
package net.coreprotect.listener.channel;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Random;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import net.coreprotect.CoreProtect;
import net.coreprotect.config.Config;
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 PluginChannelListener implements Listener {
public static final String pluginChannel = "coreprotect:data";
private static PluginChannelListener instance;
public PluginChannelListener() {
instance = this;
}
public static PluginChannelListener getInstance() {
return instance;
}
public void sendData(CommandSender commandSender, long timeAgo, Phrase phrase, String selector, String resultUser, String target, int amount, int x, int y, int z, int worldId, String rbFormat, boolean isContainer, boolean added) throws IOException {
if (!PluginChannelHandshakeListener.getInstance().isPluginChannelPlayer(commandSender)) {
return;
}
String phraseSelector = Phrase.getPhraseSelector(phrase, selector);
String worldName = Util.getWorldName(worldId);
ByteArrayOutputStream msgBytes = new ByteArrayOutputStream();
DataOutputStream msgOut = new DataOutputStream(msgBytes);
msgOut.writeInt(1);
msgOut.writeLong(timeAgo * 1000);
msgOut.writeUTF(phraseSelector);
msgOut.writeUTF(resultUser);
msgOut.writeUTF(target);
msgOut.writeInt(amount);
msgOut.writeInt(x);
msgOut.writeInt(y);
msgOut.writeInt(z);
msgOut.writeUTF(worldName);
msgOut.writeBoolean(!rbFormat.isEmpty());
msgOut.writeBoolean(isContainer);
msgOut.writeBoolean(added);
if (Config.getGlobal().NETWORK_DEBUG) {
Chat.console(String.valueOf(timeAgo * 1000));
Chat.console(phraseSelector);
Chat.console(resultUser);
Chat.console(target);
Chat.console(String.valueOf(amount));
Chat.console(String.valueOf(x));
Chat.console(String.valueOf(y));
Chat.console(String.valueOf(z));
Chat.console(worldName);
Chat.console(String.valueOf(!rbFormat.isEmpty()));
Chat.console(String.valueOf(isContainer));
Chat.console(String.valueOf(added));
Chat.console("");
}
send(commandSender, msgBytes.toByteArray());
}
public void sendInfoData(CommandSender commandSender, long timeAgo, Phrase phrase, String selector, String resultUser, int amount, int x, int y, int z, int worldId) throws IOException {
if (!PluginChannelHandshakeListener.getInstance().isPluginChannelPlayer(commandSender)) {
return;
}
String phraseSelector = Phrase.getPhraseSelector(phrase, selector);
String worldName = Util.getWorldName(worldId);
ByteArrayOutputStream msgBytes = new ByteArrayOutputStream();
DataOutputStream msgOut = new DataOutputStream(msgBytes);
msgOut.writeInt(2);
msgOut.writeLong(timeAgo * 1000);
msgOut.writeUTF(phraseSelector);
msgOut.writeUTF(resultUser);
msgOut.writeInt(amount);
msgOut.writeInt(x);
msgOut.writeInt(y);
msgOut.writeInt(z);
msgOut.writeUTF(worldName);
if (Config.getGlobal().NETWORK_DEBUG) {
Chat.console(String.valueOf(timeAgo * 1000));
Chat.console(phraseSelector);
Chat.console(resultUser);
Chat.console(String.valueOf(amount));
Chat.console(String.valueOf(x));
Chat.console(String.valueOf(y));
Chat.console(String.valueOf(z));
Chat.console(worldName);
Chat.console("");
}
send(commandSender, msgBytes.toByteArray());
}
public void sendMessageData(CommandSender commandSender, long timeAgo, String resultUser, String message, boolean sign, int x, int y, int z, int worldId) throws IOException {
if (!PluginChannelHandshakeListener.getInstance().isPluginChannelPlayer(commandSender)) {
return;
}
String worldName = Util.getWorldName(worldId);
ByteArrayOutputStream msgBytes = new ByteArrayOutputStream();
DataOutputStream msgOut = new DataOutputStream(msgBytes);
msgOut.writeInt(3);
msgOut.writeLong(timeAgo * 1000);
msgOut.writeUTF(resultUser);
msgOut.writeUTF(message);
msgOut.writeBoolean(sign);
msgOut.writeInt(x);
msgOut.writeInt(y);
msgOut.writeInt(z);
msgOut.writeUTF(worldName);
if (Config.getGlobal().NETWORK_DEBUG) {
Chat.console(String.valueOf(timeAgo * 1000));
Chat.console(resultUser);
Chat.console(message);
Chat.console(String.valueOf(sign));
Chat.console(String.valueOf(x));
Chat.console(String.valueOf(y));
Chat.console(String.valueOf(z));
Chat.console(worldName);
Chat.console("");
}
send(commandSender, msgBytes.toByteArray());
}
public void sendUsernameData(CommandSender commandSender, long timeAgo, String resultUser, String target) throws IOException {
if (!PluginChannelHandshakeListener.getInstance().isPluginChannelPlayer(commandSender)) {
return;
}
ByteArrayOutputStream msgBytes = new ByteArrayOutputStream();
DataOutputStream msgOut = new DataOutputStream(msgBytes);
msgOut.writeInt(4);
msgOut.writeLong(timeAgo * 1000);
msgOut.writeUTF(resultUser);
msgOut.writeUTF(target);
if (Config.getGlobal().NETWORK_DEBUG) {
Chat.console(String.valueOf(timeAgo * 1000));
Chat.console(resultUser);
Chat.console(target);
Chat.console("");
}
send(commandSender, msgBytes.toByteArray());
}
public void sendTest(CommandSender commandSender, String type) throws IOException {
if (!PluginChannelHandshakeListener.getInstance().isPluginChannelPlayer(commandSender)) {
return;
}
int worldId = 1;
Random rand = new Random();
int timeAgo = rand.nextInt(20);
String selector = Selector.FIRST;
String resultUser = "Anne";
int amount = 5;
int x = rand.nextInt(10);
int y = rand.nextInt(10);
int z = rand.nextInt(10);
String rbFormat = "test";
String message = "This is a test";
boolean sign = true;
switch (type) {
case "2":
sendInfoData(commandSender, timeAgo, Phrase.LOOKUP_LOGIN, selector, resultUser, amount, x, y, z, worldId);
break;
case "3":
sendMessageData(commandSender, timeAgo, resultUser, message, sign, x, y, z, worldId);
break;
case "4":
sendUsernameData(commandSender, timeAgo, resultUser, "Arne");
break;
default:
sendData(commandSender, timeAgo, Phrase.LOOKUP_CONTAINER, selector, resultUser, "clay_ball", amount, x, y, z, worldId, rbFormat, false, true);
break;
}
commandSender.sendMessage(Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NETWORK_TEST));
}
private void send(CommandSender commandSender, byte[] msgBytes) {
if (!(commandSender instanceof Player)) {
return;
}
PluginChannelListener.getInstance().sendCoreProtectData((Player) commandSender, msgBytes);
}
private void sendCoreProtectData(Player player, byte[] data) {
if (!player.hasPermission("coreprotect.networking")) {
return;
}
player.sendPluginMessage(CoreProtect.getInstance(), pluginChannel, data);
}
}
@@ -122,7 +122,7 @@ public final class InventoryChangeListener extends Queue implements Listener {
ConfigHandler.forceContainer.computeIfAbsent(loggingChestIdViewer, k -> new ArrayList<>());
List<ItemStack[]> list = ConfigHandler.forceContainer.get(loggingChestIdViewer);
if (list.size() < sizeOld) {
if (list != null && list.size() < sizeOld) {
ItemStack[] containerState = Util.getContainerState(inventoryData);
// If items have been removed by a hopper, merge into containerState
@@ -7,6 +7,7 @@ import java.util.Locale;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Entity;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.Player;
@@ -21,6 +22,7 @@ import org.bukkit.inventory.ItemStack;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Queue;
import net.coreprotect.database.logger.ItemLogger;
import net.coreprotect.model.BlockGroup;
import net.coreprotect.utility.Util;
@@ -74,6 +76,36 @@ public final class PlayerInteractEntityListener extends Queue implements Listene
queueFrameTransaction(player.getName(), frame, false);
}
}
else if (!event.isCancelled() && entity instanceof Creature && entity.getType().name().equals("ALLAY")) {
ItemStack handItem = new ItemStack(Material.AIR);
ItemStack mainHand = player.getInventory().getItemInMainHand();
ItemStack offHand = player.getInventory().getItemInOffHand();
if (event.getHand().equals(EquipmentSlot.HAND) && mainHand.getType() != Material.AIR) {
handItem = mainHand;
}
else if (event.getHand().equals(EquipmentSlot.OFF_HAND) && offHand.getType() != Material.AIR) {
handItem = offHand;
}
else if (event.getHand().equals(EquipmentSlot.OFF_HAND)) {
return;
}
ItemStack allayItem = ((Creature) entity).getEquipment().getItemInMainHand();
if (handItem.getType().equals(allayItem.getType())) {
return;
}
if (allayItem.getType().equals(Material.AIR)) {
ItemStack removedItem = handItem.clone();
removedItem.setAmount(1);
CraftItemListener.logCraftedItem(player.getLocation(), player.getName(), removedItem, ItemLogger.ITEM_SELL);
}
else if (handItem.getType().equals(Material.AIR)) {
ItemStack addItem = allayItem.clone();
addItem.setAmount(1);
CraftItemListener.logCraftedItem(player.getLocation(), player.getName(), addItem, ItemLogger.ITEM_BUY);
}
}
}
public static void queueFrameTransaction(String user, ItemFrame frame, boolean logDrop) {
@@ -6,6 +6,7 @@ import java.util.Locale;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.TreeType;
import org.bukkit.World;
import org.bukkit.block.BlockState;
@@ -35,7 +36,7 @@ public final class StructureGrowListener extends Queue implements Listener {
List<BlockState> blocks = event.getBlocks();
if (blocks.size() <= 4) {
for (BlockState block : blocks) {
if (block.getType().equals(Material.OAK_SAPLING) || block.getType().equals(Material.SPRUCE_SAPLING) || block.getType().equals(Material.BIRCH_SAPLING) || block.getType().equals(Material.JUNGLE_SAPLING) || block.getType().equals(Material.ACACIA_SAPLING) || block.getType().equals(Material.DARK_OAK_SAPLING) || block.getType().equals(Material.BROWN_MUSHROOM) || block.getType().equals(Material.RED_MUSHROOM)) {
if (Tag.SAPLINGS.isTagged(block.getType()) || block.getType().equals(Material.BROWN_MUSHROOM) || block.getType().equals(Material.RED_MUSHROOM)) {
return;
}
}
@@ -33,6 +33,7 @@ public final class BlockGroup {
public static Set<Material> SAFE_INTERACT_BLOCKS = new HashSet<>(Arrays.asList(Material.LEVER, Material.ACACIA_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.DARK_OAK_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.OAK_TRAPDOOR, Material.OAK_FENCE_GATE, Material.SPRUCE_FENCE_GATE, Material.BIRCH_FENCE_GATE, Material.JUNGLE_FENCE_GATE, Material.DARK_OAK_FENCE_GATE, Material.ACACIA_FENCE_GATE));
public static Set<Material> UPDATE_STATE = new HashSet<>(Arrays.asList(Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FURNACE, Material.BLAST_FURNACE, Material.SMOKER, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.GLOWSTONE, Material.JACK_O_LANTERN, Material.REPEATER, Material.REDSTONE_LAMP, Material.BEACON, Material.COMPARATOR, Material.DAYLIGHT_DETECTOR, Material.REDSTONE_BLOCK, Material.HOPPER, Material.CHEST, Material.TRAPPED_CHEST, Material.ACTIVATOR_RAIL));
public static Set<Material> NATURAL_BLOCKS = new HashSet<>(Arrays.asList(Material.STONE, Material.GOLD_ORE, Material.IRON_ORE, Material.COAL_ORE, Material.LAPIS_ORE, Material.SANDSTONE, Material.COBWEB, 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.OBSIDIAN, Material.DIAMOND_ORE, Material.WHEAT, Material.REDSTONE_ORE, Material.SNOW, Material.ICE, Material.CACTUS, Material.CLAY, Material.SUGAR_CANE, Material.PUMPKIN, Material.NETHERRACK, Material.SOUL_SAND, Material.MELON, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.MYCELIUM, Material.LILY_PAD, Material.NETHER_WART, Material.END_STONE, Material.EMERALD_ORE, Material.CARROT, Material.POTATO, Material.KELP, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH));
public static Set<Material> SCULK = new HashSet<>(Arrays.asList());
/* blocks that support vertical scanning */
public static Set<Material> VERTICAL_TOP_BOTTOM = new HashSet<>(Arrays.asList());
@@ -17,6 +17,7 @@ public class PaperAdapter implements PaperInterface {
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 final int PAPER_V1_19 = BukkitAdapter.BUKKIT_V1_19;
public static void loadAdapter() {
int paperVersion = ConfigHandler.SERVER_VERSION;
@@ -26,16 +27,17 @@ public class PaperAdapter implements PaperInterface {
switch (paperVersion) {
case PAPER_UNAVAILABLE:
PaperAdapter.ADAPTER = new PaperAdapter();
break;
case PAPER_V1_13:
case PAPER_V1_14:
PaperAdapter.ADAPTER = new PaperAdapter();
break;
case PAPER_V1_15:
PaperAdapter.ADAPTER = new PaperHandler();
break;
case PAPER_V1_16:
case PAPER_V1_17:
case PAPER_V1_18:
case PAPER_V1_19:
default:
PaperAdapter.ADAPTER = new Paper_v1_16();
break;
@@ -19,6 +19,7 @@ public class SpigotAdapter implements SpigotInterface {
public static final int SPIGOT_V1_16 = BukkitAdapter.BUKKIT_V1_16;
public static final int SPIGOT_V1_17 = BukkitAdapter.BUKKIT_V1_17;
public static final int SPIGOT_V1_18 = BukkitAdapter.BUKKIT_V1_18;
public static final int SPIGOT_V1_19 = BukkitAdapter.BUKKIT_V1_19;
public static void loadAdapter() {
int spigotVersion = ConfigHandler.SERVER_VERSION;
@@ -38,6 +39,7 @@ public class SpigotAdapter implements SpigotInterface {
case SPIGOT_V1_16:
case SPIGOT_V1_17:
case SPIGOT_V1_18:
case SPIGOT_V1_19:
default:
SpigotAdapter.ADAPTER = new Spigot_v1_16();
break;
@@ -1019,7 +1019,7 @@ public class Util extends Queue {
if (version.contains("-beta-")) {
version = version.split(";")[0];
version = version.split("-beta-")[1];
int value = Integer.parseInt(version.replaceAll("[^0-9]", ""));
long value = Long.parseLong(version.replaceAll("[^0-9]", ""));
if (value < 6) {
validVersion = false;
}
@@ -1033,7 +1033,7 @@ public class Util extends Queue {
}
if (version.contains("-")) {
int value = Integer.parseInt(((version.split("-"))[0]).replaceAll("[^0-9]", ""));
long value = Long.parseLong(((version.split("-"))[0]).replaceAll("[^0-9]", ""));
if (value > 0 && value < 4268) {
validVersion = false;
}
@@ -1386,12 +1386,16 @@ public class Util extends Queue {
}
public static BlockData createBlockData(Material material) {
BlockData result = material.createBlockData();
if (result instanceof Waterlogged) {
((Waterlogged) result).setWaterlogged(false);
try {
BlockData result = material.createBlockData();
if (result instanceof Waterlogged) {
((Waterlogged) result).setWaterlogged(false);
}
return result;
}
catch (Exception e) {
return null;
}
return result;
}
public static void prepareTypeAndData(Map<Block, BlockData> map, Block block, Material type, BlockData blockData, boolean update) {
@@ -1413,7 +1417,9 @@ public class Util extends Queue {
blockData = createBlockData(type);
}
block.setBlockData(blockData, update);
if (blockData != null) {
block.setBlockData(blockData, update);
}
}
public static boolean successfulQuery(Connection connection, String query) {
@@ -26,6 +26,10 @@ public class CoreProtectEditSessionEvent {
return initialized;
}
public static boolean isFAWE() {
return isFAWE;
}
public static void register() {
if (isInitialized()) {
return;
@@ -46,7 +46,7 @@ public class CoreProtectLogger extends AbstractDelegateExtent {
// No clear way to get container content data from within the WorldEdit API
// Data may be available by converting oldBlock.toBaseBlock().getNbtData()
// e.g. BaseBlock block = eventWorld.getBlock(position);
ItemStack[] containerData = Util.getContainerContents(oldType, null, location);
ItemStack[] containerData = CoreProtectEditSessionEvent.isFAWE() ? null : Util.getContainerContents(oldType, null, location);
if (eventExtent.setBlock(position, block)) {
WorldEditLogger.postProcess(eventExtent, eventActor, position, location, block, baseBlock, oldType, oldBlock, containerData);
+5
View File
@@ -50,6 +50,8 @@ permissions:
coreprotect.teleport: true
coreprotect.reload: true
coreprotect.status: true
coreprotect.consumer: true
coreprotect.networking: true
coreprotect.co:
description: Has permission to access the CoreProtect /co command
default: true
@@ -137,4 +139,7 @@ permissions:
default: op
coreprotect.consumer:
description: Has permission to use the consumer command
default: op
coreprotect.networking:
description: Has permission to use the networking API
default: op