diff --git a/.poggit.yml b/.poggit.yml
index f18d160b..252a4469 100644
--- a/.poggit.yml
+++ b/.poggit.yml
@@ -4,7 +4,11 @@ projects:
icon: resources/bedcoreprotect_logo.png
libs:
- src: poggit/libasynql/libasynql
- version: ^3.2.0
+ version: 3.2.0
- src: JackMD/UpdateNotifier/UpdateNotifier
- version: ^1.0.0
+ version: 1.0.0
+ - src: matcracker/FormLib/FormLib
+ version: 1.1.0
+ - src: SOF3/await-generator/await-generator
+ version: 2.2.0
...
diff --git a/plugin.yml b/plugin.yml
index 8ae59ed7..092bfd3d 100644
--- a/plugin.yml
+++ b/plugin.yml
@@ -1,11 +1,12 @@
name: BedcoreProtect
main: matcracker\BedcoreProtect\Main
-version: 0.4.2
+version: 0.5.0
api: [3.4.0]
mcpe-protcol:
- 354
- 361
+softdepend: BlockSniper
load: POSTWORLD
author: matcracker
description: "BedcoreProtect is a fast, efficient, data logging and anti-griefing tool for PocketMine server. Rollback and restore any amount of damage"
@@ -32,4 +33,6 @@ permissions:
bcp.subcommand.restore:
description: "Allows the user to run the sub-command /bedcoreprotect restore"
bcp.subcommand.purge:
- description: "Allows the user to run the sub-command /bedcoreprotect purge"
\ No newline at end of file
+ description: "Allows the user to run the sub-command /bedcoreprotect purge"
+ bcp.subcommand.menu:
+ description: "Allows the user to run the sub-command /bedcoreprotect menu"
\ No newline at end of file
diff --git a/resources/config.yml b/resources/config.yml
index 906eb038..1cfda3c7 100644
--- a/resources/config.yml
+++ b/resources/config.yml
@@ -1,4 +1,7 @@
-#BedcoreProtect Config
+# Plugin language
+language: eng
+
+# Database settings
database:
# The database type. "sqlite" and "mysql" are supported.
type: sqlite
@@ -16,6 +19,9 @@ database:
password: ""
# The database name where plugin stores data.
schema:
+ # The maximum number of simultaneous SQL queries
+ # Recommended: 1 for sqlite, 2 for MySQL. You may want to further increase this value if your MySQL connection is very slow.
+ worker-limit: 1
# The timezone where you are located. This is necessary to correctly log the time of events.
# To find your timezone, check here: https://www.php.net/manual/en/timezones.php
@@ -64,7 +70,7 @@ block-ignite: true
# Logs explosions, such as TNT and Creepers.
explosions: true
-# Track when an entity changes a block, such as an Enderman destroying blocks. (NOT FULLY IMPLEMENTED BY POCKETMINE YET)
+# Track when an entity changes a block, such as an Enderman destroying blocks. (NOT FULLY IMPLEMENTED IN POCKETMINE YET)
entity-change: true
# Logs killed entities, such as killed cows and enderman.
@@ -79,13 +85,13 @@ buckets: true
# Logs natural tree leaves decay.
leaves-decay: true
-# Logs tree growth. Trees are linked to the player who planted the sappling. (NOT IMPLEMENTED BY POCKETMINE YET)
+# Logs tree growth. Trees are linked to the player who planted the sappling. (NOT IMPLEMENTED IN POCKETMINE YET)
tree-growth: true
-# Logs mushroom growth. (NOT IMPLEMENTED BY POCKETMINE YET)
+# Logs mushroom growth. (NOT IMPLEMENTED IN POCKETMINE YET)
mushroom-growth: true
-# Logs natural vine growth. (NOT IMPLEMENTED BY POCKETMINE YET)
+# Logs natural vine growth. (NOT IMPLEMENTED IN POCKETMINE YET)
vine-growth: true
# Logs water flow. If water destroys other blocks, such as torches,
@@ -108,3 +114,6 @@ item-transactions: true
# Track player interactions, such as when a player opens a door, presses
# a button, or opens a chest. Player interactions can't be rolled back.
player-interactions: true
+
+# Logs changes made via the plugin "BlockSniper" if it's in use on your server.
+blocksniper-hook: true
diff --git a/resources/languages/eng.ini b/resources/languages/eng.ini
new file mode 100644
index 00000000..53392847
--- /dev/null
+++ b/resources/languages/eng.ini
@@ -0,0 +1,119 @@
+action.place = placed
+action.break = broke
+action.click = clicked
+action.kill = killed
+action.add = added
+action.remove = removed
+blocksniper.hook.success = BlockSniper properly hooked!
+blocksniper.hook.no-hook = Unable to hook BlockSniper. Check if the plugin has been properly enabled.
+command.description = It runs the BedcoreProtect commands.
+command.usage = Usage: /bcp help to display commands list
+command.no-permission = You don't have permission to run this command.
+command.reload.success = Plugin configuration reloaded.
+command.reload.no-success = Plugin configuration not reloaded due to some errors. Check your console to see the errors. Until you fix them, it will be used the old configuration.
+command.status.version = Version: §f{%0}
+command.status.database-connection = Database connection: §f{%0}
+command.status.database-version = Database version: §f{%0}
+command.status.blocksniper-hook = BlockSniper hook: §f{%0}
+command.status.author = Author: §f{%0}
+command.status.website = Website: §f{%0}
+command.error.no-numeric-value = You need to insert a numeric value.
+command.error.one-parameter = You must add at least one parameter.
+command.error.no-console = You can't run this command from console.
+command.purge.started = Data purge started. This may take some time.
+command.purge.no-restart = Do not restart your server until completed.
+command.purge.success = Data purge successful.
+command.purge.deleted-rows = {%0} rows of data deleted.
+command.inspect.enabled = Enabled inspector mode.
+command.inspect.disabled = Disabled inspector mode.
+command.near.range-value = The near value must be between 1 and {%0}!
+command.rollback.started = Rollback started on "{%0}".
+command.restore.started = Restore started on "{%0}".
+command.help.title = Help Page
+command.help.help = Display more info for that command.
+command.help.help2 = Displays a list of all commands.
+command.help.menu = Allows to use commands with a graphic interface.
+command.help.inspect = Turns the blocks inspector on or off.
+command.help.inspect1 = With the inspector enabled, you can do the following:
+command.help.inspect2 = Left-click a block to see who placed that block.
+command.help.inspect3 = Right-click a block to see what adjacent block was removed.
+command.help.inspect4 = Place a block to see what block was removed at the location.
+command.help.inspect5 = Place a block in liquid (etc) to see who placed it.
+command.help.inspect6 = Right-click on a door, chest, etc, to see who last used it.
+command.help.inspect7 = Tip: You can use just §3"/bcp i"§7 for quicker access.
+command.help.parameters1 = Perform the command {%0}.
+command.help.parameters2 = Specify the user(s) to {%0}.
+command.help.parameters3 = Specify the amount of time to {%0}.
+command.help.parameters4 = Specify a radius area to limit the {%0} to.
+command.help.parameters5 = Restrict the {%0} to a certain action.
+command.help.parameters6 = Restrict the {%0} to certain block types.
+command.help.parameters7 = Exclude blocks/users from the {%0}.
+command.help.parameters8 = Please see §3"/bcp help "§7 for detailed parameter info.
+command.help.radius-example = Only make changes within 10 blocks of you
+command.help.rollback = Rollback block data.
+command.help.restore = Restore block data.
+command.help.lookup = Advanced block data lookup.
+command.help.lookup1 = Use after inspecting a block to view different logs pages.
+command.help.lookup2 = Use after inspecting a block to view more lines of logs in a page.
+command.help.lookup3 = Please see "/bcp help params" for detailed parameters.
+command.help.purge = Delete old block data.
+command.help.purge1 = Delete data older than specified time.
+command.help.purge2 = For example, "/bcp purge t:30d" will delete all data older than one month, and only keep the last 30 days of data.
+command.help.reload = Reloads the configuration file.
+command.help.status = Displays the plugin status.
+command.help.examples = Examples
+command.help.shortcut = Command shortcut.
+command.help.block-names = Block names
+command.help.info-not-found = Information for command "/bcp help {%0}" not found.
+database.version.higher = Your database is running a higher version than BedcoreProtect. Please update the plugin if you want to use it.
+database.version.updated = Your database is now updated from v{%0} to v{%1}.
+database.connection.fail = Could not connect to the database! Check your connection, database settings or plugin configuration file.
+form.menu.title = Main Menu
+form.menu.option = Select an option:
+form.menu.inspector = Enable/Disable inspector mode
+form.menu.lookup = Lookup data
+form.menu.purge = Purge data
+form.menu.reload = Reload plugin
+form.menu.status = Show plugin status
+form.purge-menu.time = Delete data older than
+form.input-menu.required-fields = Required fields:
+form.input-menu.optional-fields = Optional fields:
+form.input-menu.time = Time
+form.input-menu.radius = Radius
+form.input-menu.user-entity = User/Entity name
+form.input-menu.user-entity-placeholder = Insert player name or #entity
+form.input-menu.restrict-blocks = Restrict blocks (accepts ID:meta)
+form.input-menu.exclude-blocks = Exclude blocks (accepts ID:meta)
+general.action = Action
+general.rollback = Rollback
+general.restore = Restore
+general.lookup = Lookup
+generic.yes = Yes
+generic.no = No
+inspector.no-data = No block data found for this location.
+inspector.more-lines = The lines number must be greater than 1.
+inspector.page-not-exist = The page §6{%0}§c does not exist!
+inspector.page = Page {%0}/{%1}
+inspector.view-old-data = View older data by typing
+language.name = English
+parser.few-many-parameters = You are using too few or too many parameters (Max: {%0})
+parser.invalid-parameter = Please specify a valid parameter. ({%0}).
+parser.no-entity = The entity "{%0}" does not exist. (The name is case-sensitive)
+parser.no-player = The player "{%0}" does not exist.
+parser.invalid-amount-time = Please specify the amount of time.
+parser.invalid-amount-radius = Please specify the amount of radius.
+parser.invalid-radius = Please specify a valid radius.
+parser.invalid-action = Please specify a valid action.
+parser.invalid-block-include = Invalid block "{%0}" to include.
+parser.invalid-block-exclude = Invalid block "{%0}" to exclude.
+parser.missing-parameters = You are missing one of the following parameters: {%0}
+rollback.completed = Rollback completed for {%0}.
+rollback.date = Rolled back {%0}.
+rollback.radius = Radius: {%0} block(s).
+rollback.blocks = Approx. {%0} block(s) changed.
+rollback.items = Approx. {%0} item(s) changed.
+rollback.entities = Approx. {%0} entities(s) changed.
+rollback.modified-chunks = Modified {%0} chunk(s).
+rollback.time-taken = Time taken: {%0} second(s).
+restore.completed = Restore completed for {%0}.
+restore.date = Restored {%0}.
\ No newline at end of file
diff --git a/resources/languages/ita.ini b/resources/languages/ita.ini
new file mode 100644
index 00000000..5cab44af
--- /dev/null
+++ b/resources/languages/ita.ini
@@ -0,0 +1,119 @@
+action.place = ha piazzato
+action.break = ha rotto
+action.click = ha cliccato
+action.kill = ha ucciso
+action.add = ha aggiunto
+action.remove = ha rimosso
+blocksniper.hook.success = BlockSniper agganciato correttamente!
+blocksniper.hook.no-hook = Non è possibile aggangiare BlockSniper. Controlla se il plugin è abilitato.
+command.description = Esegue i comandi di BedcoreProtect.
+command.usage = Usa: /bcp help per mostrare la lista di comandi
+command.no-permission = Non hai il permesso di eseguire questo comando.
+command.reload.success = Configurazione del plugin ricaricate.
+command.reload.no-success = Configurazione del plugin non ricaricata a causa di alcuni errori. Controlla la console per vederli. Finchè non li sistemerai, verrà usata la vecchia configurazione.
+command.status.version = Versione: §f{%0}
+command.status.database-connection = Connessione database: §f{%0}
+command.status.database-version = Versione database: §f{%0}
+command.status.blocksniper-hook = BlockSniper agganciato: §f{%0}
+command.status.author = Autore: §f{%0}
+command.status.website = Sito web: §f{%0}
+command.error.no-numeric-value = Devi inserire un valore numerico.
+command.error.one-parameter = Devi almeno aggiungere un parametro.
+command.error.no-console = Non puoi eseguire questo comando dalla console.
+command.purge.started = Eliminazione dei dati iniziata. Potrebbe richiedere del tempo.
+command.purge.no-restart = Non riavviare il server finchè non sarà completato.
+command.purge.success = Eliminazione dei dati eseguita con successo.
+command.purge.deleted-rows = {%0} righe di dati eliminati.
+command.inspect.enabled = Abilitata modalià ispettore.
+command.inspect.disabled = Disabilitata modalità ispettore.
+command.near.range-value = IL valore del raggio deve essere compreso tra 1 e {%0}!
+command.rollback.started = Rollback iniziato in "{%0}".
+command.restore.started = Ripristino iniziato in "{%0}".
+command.help.title = Pagina d'aiuto
+command.help.help = Mostra più informazioni per questo comando.
+command.help.help2 = Mostra una lista di tutti i comandi.
+command.help.menu = Permette di usare i comandi con una interfaccia grafica.
+command.help.inspect = Attiva/Disattiva l'ispettore dei blocchi.
+command.help.inspect1 = Con l'ispettore abilitato, puoi fare le seguenti cose:
+command.help.inspect2 = Click sinistro su un blocco per vedere chi ha piazzato quel blocco.
+command.help.inspect3 = Click destro su un blocco per vedere il blocco adiacente rimosso.
+command.help.inspect4 = Piazza un blocco per vedere quale blocco è stato rimosso in quella posizione.
+command.help.inspect5 = Piazza un blocco in un liquido (etc) per vedere chi l'ha piazzato.
+command.help.inspect6 = Click destro su una porta, cassa, etc, per vedere chi l'ha usata per ultimo.
+command.help.inspect7 = Suggerimento: puoi usare §3"/bcp i"§7 per un accesso rapido.
+command.help.parameters1 = Esegue il comando {%0}.
+command.help.parameters2 = Specifica l'utente/i da {%0}.
+command.help.parameters3 = Specifica la quantità di tempo da {%0}.
+command.help.parameters4 = Specifica un raggio per limitare la {%0}.
+command.help.parameters5 = Restringe il {%0} in una certa azione.
+command.help.parameters6 = Restringe il {%0} in alcuni tipi di blocco.
+command.help.parameters7 = Esclude blocchi/utenti dal {%0}.
+command.help.parameters8 = Per favore vedi §3"/bcp help "§7 per informazioni dettagliate.
+command.help.radius-example = Esegue cambiamenti solo nei 10 blocchi vicini a te
+command.help.rollback = Rollback dati dei blocchi.
+command.help.restore = Ripristina dati dei blocchi.
+command.help.lookup = Consultazione avanzata dei dati dei blocchi.
+command.help.lookup1 = Usa dopo aver ispezionato un blocco per vedere pagine di log differenti.
+command.help.lookup2 = Usa dopo aver ispezionato un blocco per vedere più righe di log in una pagina.
+command.help.lookup3 = Per favore vedi "/bcp help params" per il dettaglio dei parametri.
+command.help.purge = Cancella vecchi dati dei blocchi.
+command.help.purge1 = Cancella dati più vecchi del tempo specificato.
+command.help.purge2 = Per esempio, "/bcp purge t:30d" cancellerà tutti i dati pù vecchi di un mese, e manterrà sono gli ultimi 30 giorni di dati.
+command.help.reload = Ricarica la configurazione del plugin.
+command.help.status = Mostra lo stato del plugin.
+command.help.examples = Esempi
+command.help.shortcut = Scorciatoia del comando.
+command.help.block-names = Nomi dei blocchi
+command.help.info-not-found = Informazioni per il comando "/bcp help {%0}" non trovate.
+database.version.higher = Il tuo database sta eseguendo una versione più aggiornata di BedcoreProtect. Per favore aggiorna il tuo plugin se vuoi usarlo.
+database.version.updated = Il tuo database è stato aggiornato dalla versione v{%0} alla v{%1}.
+database.connection.fail = Impossibile connettersi al database! Controlla la tua connessione, impostazioni del database o la configurazione del plugin.
+form.menu.title = Menu principale
+form.menu.option = Seleziona un'opzione:
+form.menu.inspector = Attiva/Disattiva modalità ispettore
+form.menu.lookup = Consulta i dati
+form.menu.purge = Elimina dati
+form.menu.reload = Ricarica il plugin
+form.menu.status = Mostra stato del plugin
+form.purge-menu.time = Elimina dati più vecchi di
+form.input-menu.required-fields = Campi richiesti:
+form.input-menu.optional-fields = Campi opzionali:
+form.input-menu.time = Tempo
+form.input-menu.radius = Raggio
+form.input-menu.user-entity = Nome dell'utente/entità
+form.input-menu.user-entity-placeholder = Inserisci nome del giocatore o #entità
+form.input-menu.restrict-blocks = Restringi blocks (accetta ID:meta)
+form.input-menu.exclude-blocks = Escludi blocchi (accetta ID:meta)
+general.action = Azione
+general.rollback = Rollback
+general.restore = Ripristino
+general.lookup = Consulta
+generic.yes = Si
+generic.no = No
+inspector.no-data = Nessun dato trovato in questa posizione.
+inspector.more-lines = Il numero di linee deve essere più grande di 1.
+inspector.page-not-exist = La pagina §6{%0}§c non esiste!
+inspector.page = Pagina {%0}/{%1}
+inspector.view-old-data = Vedi i dati vecchi scrivendo
+language.name = Italiano
+parser.few-many-parameters = You are using too few or too many parameters (Max: {%0})
+parser.invalid-parameter = Per favore specifica un parametro valido. ({%0}).
+parser.no-entity = L'entità "{%0}" non esiste (il nome è case-sensitive)
+parser.no-player = Il giocatore "{%0}" non esiste.
+parser.invalid-amount-time = Per favore specifica la quantità del tempo.
+parser.invalid-amount-radius = Per favore specifica la quantità del raggio.
+parser.invalid-radius = Per favore specifica un raggio valido.
+parser.invalid-action = Per favore specifica un'azione valida.
+parser.invalid-block-include = Blocco "{%0}" invalido da includere.
+parser.invalid-block-exclude = Blocco "{%0}" invalido da escludere.
+parser.missing-parameters = Stai dimenticando uno dei seguenti paramentri: {%0}
+rollback.completed = Rollback completato per {%0}.
+rollback.date = Rolled back {%0}.
+rollback.radius = Raggio: {%0} block(s).
+rollback.blocks = Circa {%0} blocco/hi cambiato/i.
+rollback.items = Circa. {%0} oggetto/i cambiato/i.
+rollback.entities = Circa {%0} entità cambiate.
+rollback.modified-chunks = Modificato/i {%0} chunk.
+rollback.time-taken = Tempo impiegato: {%0} secondo/i.
+restore.completed = Ripristino completato per {%0}.
+restore.date = Ripristinato {%0}.
\ No newline at end of file
diff --git a/resources/mysql.sql b/resources/mysql.sql
index fa8f66bb..88622231 100644
--- a/resources/mysql.sql
+++ b/resources/mysql.sql
@@ -4,55 +4,44 @@
-- # {entities
CREATE TABLE IF NOT EXISTS entities
(
- uuid VARCHAR(36) UNIQUE NOT NULL PRIMARY KEY,
- entity_name VARCHAR(16) NOT NULL,
- entity_classpath TEXT NOT NULL,
- address VARCHAR(15) DEFAULT '127.0.0.1'
-);
--- # }
--- # {blocks
-CREATE TABLE IF NOT EXISTS blocks
-(
- id INTEGER UNSIGNED NOT NULL,
- meta TINYINT(2) UNSIGNED NOT NULL,
- block_name VARCHAR(30) NOT NULL,
- PRIMARY KEY (id, meta)
+ uuid VARCHAR(36) UNIQUE PRIMARY KEY NOT NULL,
+ entity_name VARCHAR(16) NOT NULL,
+ entity_classpath TEXT NOT NULL,
+ address VARCHAR(15) DEFAULT '127.0.0.1' NOT NULL
);
-- # }
-- # {log_history
CREATE TABLE IF NOT EXISTS log_history
(
- log_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
- who VARCHAR(36) NOT NULL,
- x BIGINT NOT NULL,
- y TINYINT UNSIGNED NOT NULL,
- z BIGINT NOT NULL,
- world_name VARCHAR(255) NOT NULL,
- action TINYINT UNSIGNED NOT NULL,
- time TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP,
- rollback BOOLEAN DEFAULT FALSE,
+ log_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
+ who VARCHAR(36) NOT NULL,
+ x BIGINT NOT NULL,
+ y TINYINT UNSIGNED NOT NULL,
+ z BIGINT NOT NULL,
+ world_name VARCHAR(255) NOT NULL,
+ action TINYINT UNSIGNED NOT NULL,
+ time TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ rollback BOOLEAN DEFAULT FALSE NOT NULL,
FOREIGN KEY (who) REFERENCES entities (uuid)
);
-- # }
-- # {blocks_log
CREATE TABLE IF NOT EXISTS blocks_log
(
- history_id BIGINT UNSIGNED,
- old_block_id INTEGER UNSIGNED NOT NULL,
- old_block_meta TINYINT(2) UNSIGNED NOT NULL,
- old_block_nbt LONGBLOB DEFAULT NULL,
- new_block_id INTEGER UNSIGNED NOT NULL,
- new_block_meta TINYINT(2) UNSIGNED NOT NULL,
- new_block_nbt LONGBLOB DEFAULT NULL,
- FOREIGN KEY (history_id) REFERENCES log_history (log_id) ON DELETE CASCADE,
- FOREIGN KEY (old_block_id, old_block_meta) REFERENCES blocks (id, meta),
- FOREIGN KEY (new_block_id, new_block_meta) REFERENCES blocks (id, meta)
+ history_id BIGINT UNSIGNED NOT NULL,
+ old_id INTEGER UNSIGNED NOT NULL,
+ old_meta TINYINT(2) UNSIGNED NOT NULL,
+ old_nbt LONGBLOB DEFAULT NULL,
+ new_id INTEGER UNSIGNED NOT NULL,
+ new_meta TINYINT(2) UNSIGNED NOT NULL,
+ new_nbt LONGBLOB DEFAULT NULL,
+ FOREIGN KEY (history_id) REFERENCES log_history (log_id) ON DELETE CASCADE
);
-- # }
-- # {entities_log
CREATE TABLE IF NOT EXISTS entities_log
(
- history_id BIGINT UNSIGNED,
+ history_id BIGINT UNSIGNED NOT NULL,
entityfrom_uuid VARCHAR(36) NOT NULL,
entityfrom_id INTEGER UNSIGNED NOT NULL,
entityfrom_nbt LONGBLOB DEFAULT NULL,
@@ -63,19 +52,28 @@ CREATE TABLE IF NOT EXISTS entities_log
-- # {inventories_log
CREATE TABLE IF NOT EXISTS inventories_log
(
- history_id BIGINT UNSIGNED,
- slot TINYINT UNSIGNED NOT NULL,
- old_item_id INTEGER UNSIGNED DEFAULT 0,
- old_item_meta TINYINT(2) UNSIGNED DEFAULT 0,
- old_item_nbt LONGBLOB DEFAULT NULL,
- old_item_amount TINYINT UNSIGNED DEFAULT 0,
- new_item_id INTEGER UNSIGNED DEFAULT 0,
- new_item_meta TINYINT(2) UNSIGNED DEFAULT 0,
- new_item_nbt LONGBLOB DEFAULT NULL,
- new_item_amount TINYINT UNSIGNED DEFAULT 0,
+ history_id BIGINT UNSIGNED NOT NULL,
+ slot TINYINT UNSIGNED NOT NULL,
+ old_id INTEGER UNSIGNED DEFAULT 0 NOT NULL,
+ old_meta TINYINT(2) UNSIGNED DEFAULT 0 NOT NULL,
+ old_nbt LONGBLOB DEFAULT NULL,
+ old_amount TINYINT UNSIGNED DEFAULT 0 NOT NULL,
+ new_id INTEGER UNSIGNED DEFAULT 0 NOT NULL,
+ new_meta TINYINT(2) UNSIGNED DEFAULT 0 NOT NULL,
+ new_nbt LONGBLOB DEFAULT NULL,
+ new_amount TINYINT UNSIGNED DEFAULT 0 NOT NULL,
FOREIGN KEY (history_id) REFERENCES log_history (log_id) ON DELETE CASCADE
);
-- # }
+-- # {db_status
+CREATE TABLE IF NOT EXISTS status
+(
+ only_one_row BOOLEAN PRIMARY KEY DEFAULT TRUE NOT NULL,
+ version VARCHAR(20) NOT NULL,
+ upgraded_on TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ CHECK (only_one_row)
+);
+-- # }
-- # }
-- # {add
-- # {entity
@@ -87,14 +85,11 @@ INSERT INTO entities (uuid, entity_name, entity_classpath, address)
VALUES (:uuid, :name, :path, :address)
ON DUPLICATE KEY UPDATE address=:address;
-- # }
--- # {block
--- # :id int
--- # :meta int
--- # :name string
-INSERT INTO blocks (id, meta, block_name)
-VALUES (:id, :meta, :name)
-ON DUPLICATE KEY UPDATE id=VALUES(id),
- meta=VALUES(meta);
+-- # {db_version
+-- # :version string
+INSERT INTO status (version)
+VALUES (:version)
+ON DUPLICATE KEY UPDATE version=version;
-- # }
-- # {log
-- # {main
@@ -108,60 +103,148 @@ INSERT INTO log_history(who, x, y, z, world_name,
action)
VALUES ((SELECT uuid FROM entities WHERE uuid = :uuid), :x, :y, :z, :world_name, :action);
-- # }
--- # {to_block
--- # :old_block_id int
--- # :old_block_meta int
--- # :old_block_nbt ?string
--- # :new_block_id int
--- # :new_block_meta int
--- # :new_block_nbt ?string
-INSERT INTO blocks_log(history_id, old_block_id, old_block_meta, old_block_nbt, new_block_id, new_block_meta,
- new_block_nbt)
-VALUES (LAST_INSERT_ID(),
- (SELECT id FROM blocks WHERE blocks.id = :old_block_id AND meta = :old_block_meta),
- (SELECT meta FROM blocks WHERE blocks.id = :old_block_id AND meta = :old_block_meta),
- :old_block_nbt,
- (SELECT id FROM blocks WHERE blocks.id = :new_block_id AND meta = :new_block_meta),
- (SELECT meta FROM blocks WHERE blocks.id = :new_block_id AND meta = :new_block_meta),
- :new_block_nbt);
+-- # {block
+-- # :old_id int
+-- # :old_meta int
+-- # :old_nbt ?string
+-- # :new_id int
+-- # :new_meta int
+-- # :new_nbt ?string
+INSERT INTO blocks_log(history_id, old_id, old_meta, old_nbt, new_id, new_meta,
+ new_nbt)
+VALUES (LAST_INSERT_ID(), :old_id, :old_meta, :old_nbt, :new_id, :new_meta,
+ :new_nbt);
-- # }
--- # {to_entity
+-- # {entity
-- # :uuid string
-- # :id int
-- # :nbt ?string
INSERT INTO entities_log(history_id, entityfrom_uuid, entityfrom_id, entityfrom_nbt)
VALUES (LAST_INSERT_ID(), (SELECT uuid FROM entities WHERE uuid = :uuid), :id, :nbt);
-- # }
--- # {to_inventory
+-- # {inventory
-- # :slot int
--- # :old_item_id int 0
--- # :old_item_meta int 0
--- # :old_item_nbt ?string
--- # :old_item_amount int 0
--- # :new_item_id int 0
--- # :new_item_meta int 0
--- # :new_item_nbt ?string
--- # :new_item_amount int 0
-INSERT INTO inventories_log(history_id, slot, old_item_id, old_item_meta, old_item_nbt, old_item_amount, new_item_id,
- new_item_meta, new_item_nbt, new_item_amount)
-VALUES (LAST_INSERT_ID(), :slot, :old_item_id, :old_item_meta, :old_item_nbt, :old_item_amount, :new_item_id,
- :new_item_meta, :new_item_nbt, :new_item_amount);
+-- # :old_id int 0
+-- # :old_meta int 0
+-- # :old_nbt ?string
+-- # :old_amount int 0
+-- # :new_id int 0
+-- # :new_meta int 0
+-- # :new_nbt ?string
+-- # :new_amount int 0
+INSERT INTO inventories_log(history_id, slot, old_id, old_meta, old_nbt, old_amount, new_id,
+ new_meta, new_nbt, new_amount)
+VALUES (LAST_INSERT_ID(), :slot, :old_id, :old_meta, :old_nbt, :old_amount, :new_id,
+ :new_meta, :new_nbt, :new_amount);
-- # }
--- # {update_entity_id
--- # :log_id int
--- # :entity_id int
+-- # }
+-- # }
+-- # {update
+-- # {entity_id
+-- # :log_id int
+-- # :entity_id int
UPDATE entities_log
SET entityfrom_id = :entity_id
WHERE history_id = :log_id;
--- # }
+-- # }
+-- # {db_version
+-- # :version string
+UPDATE status
+SET version = :version,
+ upgraded_on = DEFAULT
+LIMIT 1;
+-- # }
+-- # {rollback_status
+-- # :rollback bool
+-- # :log_ids list:int
+UPDATE log_history
+SET rollback = :rollback
+WHERE log_id IN :log_ids;
-- # }
-- # }
-- # {get
+-- # {db_status
+SELECT *
+FROM status
+LIMIT 1;
+-- # }
-- # {log
-- # {last_id
SELECT MAX(log_id) AS lastId
FROM log_history;
-- # }
+-- # {old_blocks
+-- # :log_ids list:int
+SELECT history_id,
+ bl.old_id,
+ bl.old_meta,
+ bl.old_nbt,
+ x,
+ y,
+ z,
+ world_name
+FROM log_history
+ INNER JOIN blocks_log bl ON log_history.log_id = bl.history_id
+WHERE log_id IN :log_ids;
+-- # }
+-- # {new_blocks
+-- # :log_ids list:int
+SELECT history_id,
+ bl.new_id,
+ bl.new_meta,
+ bl.new_nbt,
+ x,
+ y,
+ z,
+ world_name
+FROM log_history
+ INNER JOIN blocks_log bl ON log_history.log_id = bl.history_id
+WHERE log_id IN :log_ids;
+-- # }
+-- # {old_inventories
+-- # :log_ids list:int
+SELECT history_id,
+ il.slot,
+ il.old_id,
+ il.old_meta,
+ il.old_nbt,
+ il.old_amount,
+ x,
+ y,
+ z
+FROM log_history
+ INNER JOIN inventories_log il ON log_history.log_id = il.history_id
+WHERE log_id IN :log_ids;
+-- # }
+-- # {new_inventories
+-- # :log_ids list:int
+SELECT history_id,
+ il.slot,
+ il.new_id,
+ il.new_meta,
+ il.new_nbt,
+ il.new_amount,
+ x,
+ y,
+ z
+FROM log_history
+ INNER JOIN inventories_log il ON log_history.log_id = il.history_id
+WHERE log_id IN :log_ids;
+-- # }
+-- # {entities
+-- # :log_ids list:int
+SELECT e.entity_classpath,
+ el.entityfrom_id,
+ el.entityfrom_nbt,
+ x,
+ y,
+ z,
+ action
+FROM log_history
+ INNER JOIN entities_log el ON log_history.log_id = el.history_id
+ INNER JOIN entities e ON e.uuid = el.entityfrom_uuid
+WHERE log_id IN :log_ids;
+-- # }
-- # {block
-- # :min_x int
-- # :max_x int
@@ -170,12 +253,12 @@ FROM log_history;
-- # :min_z int
-- # :max_z int
-- # :world_name string
-SELECT bl.old_block_id,
- bl.old_block_meta,
- bl.old_block_nbt,
- bl.new_block_id,
- bl.new_block_meta,
- bl.new_block_nbt,
+SELECT bl.old_id,
+ bl.old_meta,
+ bl.old_nbt,
+ bl.new_id,
+ bl.new_meta,
+ bl.new_nbt,
e.entity_name AS entity_from,
x,
y,
@@ -230,12 +313,12 @@ ORDER BY time DESC;
-- # :min_z int
-- # :max_z int
-- # :world_name string
-SELECT bl.old_block_id,
- bl.old_block_meta,
- bl.old_block_nbt,
- bl.new_block_id,
- bl.new_block_meta,
- bl.new_block_nbt,
+SELECT bl.old_id,
+ bl.old_meta,
+ bl.old_nbt,
+ bl.new_id,
+ bl.new_meta,
+ bl.new_nbt,
e1.entity_name AS entity_from,
e2.entity_name AS entity_to,
x,
@@ -265,14 +348,14 @@ ORDER BY time DESC;
-- # :min_z int
-- # :max_z int
-- # :world_name string
-SELECT il.old_item_id,
- il.old_item_meta,
- il.old_item_nbt,
- il.old_item_amount,
- il.new_item_id,
- il.new_item_meta,
- il.new_item_nbt,
- il.new_item_amount,
+SELECT il.old_id,
+ il.old_meta,
+ il.old_nbt,
+ il.old_amount,
+ il.new_id,
+ il.new_meta,
+ il.new_nbt,
+ il.new_amount,
e.entity_name AS entity_from,
x,
y,
diff --git a/resources/patches/.patches b/resources/patches/.patches
new file mode 100644
index 00000000..07b061ab
--- /dev/null
+++ b/resources/patches/.patches
@@ -0,0 +1 @@
+# !!! DON'T EDIT THIS FILE !!!
\ No newline at end of file
diff --git a/resources/patches/mysql_patch.sql b/resources/patches/mysql_patch.sql
new file mode 100644
index 00000000..5ffac0ec
--- /dev/null
+++ b/resources/patches/mysql_patch.sql
@@ -0,0 +1,3 @@
+-- #!mysql
+-- #{patch
+-- #}
\ No newline at end of file
diff --git a/resources/patches/sqlite_patch.sql b/resources/patches/sqlite_patch.sql
new file mode 100644
index 00000000..9e6073ff
--- /dev/null
+++ b/resources/patches/sqlite_patch.sql
@@ -0,0 +1,3 @@
+-- #!sqlite
+-- #{patch
+-- #}
\ No newline at end of file
diff --git a/resources/sqlite.sql b/resources/sqlite.sql
index 6cedb123..333d15f7 100644
--- a/resources/sqlite.sql
+++ b/resources/sqlite.sql
@@ -4,55 +4,44 @@
-- # {entities
CREATE TABLE IF NOT EXISTS "entities"
(
- uuid VARCHAR(36) UNIQUE NOT NULL PRIMARY KEY,
- entity_name VARCHAR(16) NOT NULL,
- entity_classpath TEXT NOT NULL,
- address VARCHAR(15) DEFAULT '127.0.0.1'
-);
--- # }
--- # {blocks
-CREATE TABLE IF NOT EXISTS "blocks"
-(
- id UNSIGNED INTEGER NOT NULL,
- meta UNSIGNED TINYINT(2) NOT NULL,
- block_name VARCHAR(30) NOT NULL,
- PRIMARY KEY (id, meta)
+ uuid VARCHAR(36) UNIQUE PRIMARY KEY NOT NULL,
+ entity_name VARCHAR(16) NOT NULL,
+ entity_classpath TEXT NOT NULL,
+ address VARCHAR(15) DEFAULT '127.0.0.1' NOT NULL
);
-- # }
-- # {log_history
CREATE TABLE IF NOT EXISTS "log_history"
(
- log_id INTEGER PRIMARY KEY AUTOINCREMENT,
- who VARCHAR(36) NOT NULL,
- x BIGINT NOT NULL,
- y TINYINT UNSIGNED NOT NULL,
- z BIGINT NOT NULL,
- world_name VARCHAR(255) NOT NULL,
- action TINYINT UNSIGNED NOT NULL,
- time TIMESTAMP DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'now', 'localtime')),
- "rollback" TINYINT(1) DEFAULT 0,
+ log_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ who VARCHAR(36) NOT NULL,
+ x BIGINT NOT NULL,
+ y TINYINT UNSIGNED NOT NULL,
+ z BIGINT NOT NULL,
+ world_name VARCHAR(255) NOT NULL,
+ action TINYINT UNSIGNED NOT NULL,
+ time TIMESTAMP DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'now', 'localtime')) NOT NULL,
+ "rollback" TINYINT(1) DEFAULT 0 NOT NULL,
FOREIGN KEY (who) REFERENCES "entities" (uuid)
);
-- # }
-- # {blocks_log
CREATE TABLE IF NOT EXISTS "blocks_log"
(
- history_id UNSIGNED BIG INT,
- old_block_id UNSIGNED INTEGER NOT NULL,
- old_block_meta UNSIGNED TINYINT(2) NOT NULL,
- old_block_nbt BLOB DEFAULT NULL,
- new_block_id UNSIGNED INTEGER NOT NULL,
- new_block_meta UNSIGNED TINYINT(2) NOT NULL,
- new_block_nbt BLOB DEFAULT NULL,
- FOREIGN KEY (history_id) REFERENCES "log_history" (log_id) ON DELETE CASCADE,
- FOREIGN KEY (old_block_id, old_block_meta) REFERENCES "blocks" (id, meta),
- FOREIGN KEY (new_block_id, new_block_meta) REFERENCES "blocks" (id, meta)
+ history_id UNSIGNED BIG INT NOT NULL,
+ old_id UNSIGNED INTEGER NOT NULL,
+ old_meta UNSIGNED TINYINT(2) NOT NULL,
+ old_nbt BLOB DEFAULT NULL,
+ new_id UNSIGNED INTEGER NOT NULL,
+ new_meta UNSIGNED TINYINT(2) NOT NULL,
+ new_nbt BLOB DEFAULT NULL,
+ FOREIGN KEY (history_id) REFERENCES "log_history" (log_id) ON DELETE CASCADE
);
-- # }
-- # {entities_log
CREATE TABLE IF NOT EXISTS "entities_log"
(
- history_id UNSIGNED BIG INT,
+ history_id UNSIGNED BIG INT NOT NULL,
entityfrom_uuid VARCHAR(36) NOT NULL,
entityfrom_id UNSIGNED INTEGER NOT NULL,
entityfrom_nbt BLOB DEFAULT NULL,
@@ -63,19 +52,28 @@ CREATE TABLE IF NOT EXISTS "entities_log"
-- # {inventories_log
CREATE TABLE IF NOT EXISTS "inventories_log"
(
- history_id UNSIGNED BIG INT,
- slot UNSIGNED TINYINT NOT NULL,
- old_item_id UNSIGNED INTEGER DEFAULT 0,
- old_item_meta UNSIGNED TINYINT(2) DEFAULT 0,
- old_item_nbt BLOB DEFAULT NULL,
- old_item_amount UNSIGNED TINYINT DEFAULT 0,
- new_item_id UNSIGNED INTEGER DEFAULT 0,
- new_item_meta UNSIGNED TINYINT(2) DEFAULT 0,
- new_item_nbt BLOB DEFAULT NULL,
- new_item_amount UNSIGNED TINYINT DEFAULT 0,
+ history_id UNSIGNED BIG INT NOT NULL,
+ slot UNSIGNED TINYINT NOT NULL,
+ old_id UNSIGNED INTEGER DEFAULT 0 NOT NULL,
+ old_meta UNSIGNED TINYINT(2) DEFAULT 0 NOT NULL,
+ old_nbt BLOB DEFAULT NULL,
+ old_amount UNSIGNED TINYINT DEFAULT 0 NOT NULL,
+ new_id UNSIGNED INTEGER DEFAULT 0 NOT NULL,
+ new_meta UNSIGNED TINYINT(2) DEFAULT 0 NOT NULL,
+ new_nbt BLOB DEFAULT NULL,
+ new_amount UNSIGNED TINYINT DEFAULT 0 NOT NULL,
FOREIGN KEY (history_id) REFERENCES "log_history" (log_id) ON DELETE CASCADE
);
-- # }
+-- # {db_status
+CREATE TABLE IF NOT EXISTS status
+(
+ only_one_row TINYINT(1) PRIMARY KEY DEFAULT 1 NOT NULL,
+ version VARCHAR(20) NOT NULL,
+ upgraded_on TIMESTAMP(6) DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'now', 'localtime')) NOT NULL,
+ CHECK (only_one_row)
+);
+-- # }
-- # }
-- # {transaction
-- # {begin
@@ -96,14 +94,11 @@ REPLACE
INTO "entities" (uuid, entity_name, entity_classpath, address)
VALUES (:uuid, :name, :path, :address);
-- # }
--- # {block
--- # :id int
--- # :meta int
--- # :name string
-INSERT OR
-REPLACE
-INTO "blocks" (id, meta, block_name)
-VALUES (:id, :meta, :name);
+-- # {db_version
+-- # :version string
+INSERT OR IGNORE
+INTO status (version)
+VALUES (:version);
-- # }
-- # {log
-- # {main
@@ -117,60 +112,147 @@ INSERT INTO "log_history"(who, x, y, z, world_name,
action)
VALUES ((SELECT uuid FROM entities WHERE uuid = :uuid), :x, :y, :z, :world_name, :action);
-- # }
--- # {to_block
--- # :old_block_id int
--- # :old_block_meta int
--- # :old_block_nbt ?string
--- # :new_block_id int
--- # :new_block_meta int
--- # :new_block_nbt ?string
-INSERT INTO "blocks_log"(history_id, old_block_id, old_block_meta, old_block_nbt, new_block_id, new_block_meta,
- new_block_nbt)
-VALUES (LAST_INSERT_ROWID(),
- (SELECT id FROM "blocks" WHERE blocks.id = :old_block_id AND meta = :old_block_meta),
- (SELECT meta FROM "blocks" WHERE blocks.id = :old_block_id AND meta = :old_block_meta),
- :old_block_nbt,
- (SELECT id FROM "blocks" WHERE blocks.id = :new_block_id AND meta = :new_block_meta),
- (SELECT meta FROM "blocks" WHERE blocks.id = :new_block_id AND meta = :new_block_meta),
- :new_block_nbt);
+-- # {block
+-- # :old_id int
+-- # :old_meta int
+-- # :old_nbt ?string
+-- # :new_id int
+-- # :new_meta int
+-- # :new_nbt ?string
+INSERT INTO "blocks_log"(history_id, old_id, old_meta, old_nbt, new_id, new_meta,
+ new_nbt)
+VALUES (LAST_INSERT_ROWID(), :old_id, :old_meta, :old_nbt, :new_id, :new_meta,
+ :new_nbt);
-- # }
--- # {to_entity
+-- # {entity
-- # :uuid string
-- # :id int
-- # :nbt ?string
INSERT INTO "entities_log"(history_id, entityfrom_uuid, entityfrom_id, entityfrom_nbt)
VALUES (LAST_INSERT_ROWID(), (SELECT uuid FROM entities WHERE uuid = :uuid), :id, :nbt);
-- # }
--- # {to_inventory
+-- # {inventory
-- # :slot int
--- # :old_item_id int 0
--- # :old_item_meta int 0
--- # :old_item_nbt ?string
--- # :old_item_amount int 0
--- # :new_item_id int 0
--- # :new_item_meta int 0
--- # :new_item_nbt ?string
--- # :new_item_amount int 0
-INSERT INTO "inventories_log"(history_id, slot, old_item_id, old_item_meta, old_item_nbt, old_item_amount, new_item_id,
- new_item_meta, new_item_nbt, new_item_amount)
-VALUES (LAST_INSERT_ROWID(), :slot, :old_item_id, :old_item_meta, :old_item_nbt, :old_item_amount, :new_item_id,
- :new_item_meta, :new_item_nbt, :new_item_amount);
+-- # :old_id int 0
+-- # :old_meta int 0
+-- # :old_nbt ?string
+-- # :old_amount int 0
+-- # :new_id int 0
+-- # :new_meta int 0
+-- # :new_nbt ?string
+-- # :new_amount int 0
+INSERT INTO "inventories_log"(history_id, slot, old_id, old_meta, old_nbt, old_amount, new_id,
+ new_meta, new_nbt, new_amount)
+VALUES (LAST_INSERT_ROWID(), :slot, :old_id, :old_meta, :old_nbt, :old_amount, :new_id,
+ :new_meta, :new_nbt, :new_amount);
-- # }
--- # {update_entity_id
--- # :log_id int
--- # :entity_id int
+-- # }
+-- # }
+-- # {update
+-- # {entity_id
+-- # :log_id int
+-- # :entity_id int
UPDATE entities_log
SET entityfrom_id = :entity_id
WHERE history_id = :log_id;
--- # }
+-- # }
+-- # {db_version
+-- # :version string
+UPDATE status
+SET version = :version,
+ upgraded_on = (STRFTIME('%Y-%m-%d %H:%M:%f', 'now', 'localtime'));
+-- # }
+-- # {rollback_status
+-- # :rollback bool
+-- # :log_ids list:int
+UPDATE log_history
+SET "rollback" = :rollback
+WHERE log_id IN :log_ids;
-- # }
-- # }
-- # {get
+-- # {db_status
+SELECT *
+FROM status
+LIMIT 1;
+-- # }
-- # {log
-- # {last_id
SELECT MAX(log_id) AS lastId
FROM "log_history";
-- # }
+-- # {old_blocks
+-- # :log_ids list:int
+SELECT history_id,
+ bl.old_id,
+ bl.old_meta,
+ bl.old_nbt,
+ x,
+ y,
+ z,
+ world_name
+FROM "log_history"
+ INNER JOIN blocks_log bl ON log_history.log_id = bl.history_id
+WHERE log_id IN :log_ids;
+-- # }
+-- # {new_blocks
+-- # :log_ids list:int
+SELECT history_id,
+ bl.new_id,
+ bl.new_meta,
+ bl.new_nbt,
+ x,
+ y,
+ z,
+ world_name
+FROM "log_history"
+ INNER JOIN blocks_log bl ON log_history.log_id = bl.history_id
+WHERE log_id IN :log_ids;
+-- # }
+-- # {old_inventories
+-- # :log_ids list:int
+SELECT history_id,
+ il.slot,
+ il.old_id,
+ il.old_meta,
+ il.old_nbt,
+ il.old_amount,
+ x,
+ y,
+ z
+FROM "log_history"
+ INNER JOIN inventories_log il ON log_history.log_id = il.history_id
+WHERE log_id IN :log_ids;
+-- # }
+-- # {new_inventories
+-- # :log_ids list:int
+SELECT history_id,
+ il.slot,
+ il.new_id,
+ il.new_meta,
+ il.new_nbt,
+ il.new_amount,
+ x,
+ y,
+ z
+FROM "log_history"
+ INNER JOIN inventories_log il ON log_history.log_id = il.history_id
+WHERE log_id IN :log_ids;
+-- # }
+-- # {entities
+-- # :log_ids list:int
+SELECT e.entity_classpath,
+ el.entityfrom_id,
+ el.entityfrom_nbt,
+ x,
+ y,
+ z,
+ action
+FROM "log_history"
+ INNER JOIN entities_log el ON log_history.log_id = el.history_id
+ INNER JOIN entities e ON e.uuid = el.entityfrom_uuid
+WHERE log_id IN :log_ids;
+-- # }
-- # {block
-- # :min_x int
-- # :max_x int
@@ -179,12 +261,12 @@ FROM "log_history";
-- # :min_z int
-- # :max_z int
-- # :world_name string
-SELECT bl.old_block_id,
- bl.old_block_meta,
- bl.old_block_nbt,
- bl.new_block_id,
- bl.new_block_meta,
- bl.new_block_nbt,
+SELECT bl.old_id,
+ bl.old_meta,
+ bl.old_nbt,
+ bl.new_id,
+ bl.new_meta,
+ bl.new_nbt,
e.entity_name AS entity_from,
x,
y,
@@ -239,12 +321,12 @@ ORDER BY time DESC;
-- # :min_z int
-- # :max_z int
-- # :world_name string
-SELECT bl.old_block_id,
- bl.old_block_meta,
- bl.old_block_nbt,
- bl.new_block_id,
- bl.new_block_meta,
- bl.new_block_nbt,
+SELECT bl.old_id,
+ bl.old_meta,
+ bl.old_nbt,
+ bl.new_id,
+ bl.new_meta,
+ bl.new_nbt,
e1.entity_name AS entity_from,
e2.entity_name AS entity_to,
x,
@@ -274,14 +356,14 @@ ORDER BY time DESC;
-- # :min_z int
-- # :max_z int
-- # :world_name string
-SELECT il.old_item_id,
- il.old_item_meta,
- il.old_item_nbt,
- il.old_item_amount,
- il.new_item_id,
- il.new_item_meta,
- il.new_item_nbt,
- il.new_item_amount,
+SELECT il.old_id,
+ il.old_meta,
+ il.old_nbt,
+ il.old_amount,
+ il.new_id,
+ il.new_meta,
+ il.new_nbt,
+ il.new_amount,
e.entity_name AS entity_from,
x,
y,
diff --git a/src/matcracker/BedcoreProtect/Inspector.php b/src/matcracker/BedcoreProtect/Inspector.php
index 7085f76b..7f52466f 100644
--- a/src/matcracker/BedcoreProtect/Inspector.php
+++ b/src/matcracker/BedcoreProtect/Inspector.php
@@ -21,7 +21,7 @@
namespace matcracker\BedcoreProtect;
-use matcracker\BedcoreProtect\utils\Action;
+use matcracker\BedcoreProtect\enums\Action;
use matcracker\BedcoreProtect\utils\Utils;
use pocketmine\block\BlockFactory;
use pocketmine\command\CommandSender;
@@ -77,12 +77,12 @@ public static function removeInspector(CommandSender $inspector): bool
*/
public static function isInspector(CommandSender $inspector): bool
{
- return self::$inspectors[self::getSenderUUID($inspector)]["enabled"] ?? false;
+ return self::$inspectors[self::getSenderUUID($inspector)]['enabled'] ?? false;
}
public static function cacheLogs(CommandSender $inspector, array $logs = []): void
{
- self::$inspectors[self::getSenderUUID($inspector)]["logs"] = $logs;
+ self::$inspectors[self::getSenderUUID($inspector)]['logs'] = $logs;
}
/**
@@ -92,7 +92,7 @@ public static function cacheLogs(CommandSender $inspector, array $logs = []): vo
*/
public static function getCachedLogs(CommandSender $inspector): array
{
- return self::$inspectors[self::getSenderUUID($inspector)]["logs"] ?? [];
+ return self::$inspectors[self::getSenderUUID($inspector)]['logs'] ?? [];
}
public static function clearCache(): void
@@ -110,14 +110,15 @@ public static function clearCache(): void
*/
public static function parseLogs(CommandSender $inspector, array $logs, int $page = 0, int $lines = 4): void
{
+ $lang = Main::getInstance()->getLanguage();
if (empty($logs)) {
- $inspector->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cNo block data found for this location."));
+ $inspector->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . '&c' . $lang->translateString('inspector.no-data')));
return;
}
if ($lines < 1) {
- $inspector->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cThe lines number must be greater than 1."));
+ $inspector->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . '&c' . $lang->translateString('inspector.more-lines')));
return;
}
@@ -126,12 +127,12 @@ public static function parseLogs(CommandSender $inspector, array $logs, int $pag
$maxPages = count($chunkLogs);
$fakePage = $page + 1;
if (!isset($chunkLogs[$page])) {
- $inspector->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cThe page &6{$fakePage}&c does not exist!"));
+ $inspector->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . '&c' . $lang->translateString('inspector.page-not-exist', [$fakePage])));
return;
}
- $inspector->sendMessage(Utils::translateColors("&f-----&3 " . Main::PLUGIN_NAME . " &7(Page {$fakePage}/{$maxPages}) &f-----"));
+ $inspector->sendMessage(Utils::translateColors('&f-----&3 ' . Main::PLUGIN_NAME . ' &7(' . $lang->translateString('inspector.page', [$fakePage, $maxPages]) . ') &f-----'));
foreach ($chunkLogs[$page] as $log) {
//Default
$from = (string)$log['entity_from'];
@@ -144,30 +145,30 @@ public static function parseLogs(CommandSender $inspector, array $logs, int $pag
$timeStamp = (is_int($log['time']) ? (int)$log['time'] : strtotime($log['time']));
- $typeColumn = ($action->equals(Action::BREAK()) || $action->equals(Action::REMOVE())) ? "old" : "new";
- if (isset($log["{$typeColumn}_block_id"], $log["{$typeColumn}_block_meta"])) {
- $id = (int)$log["{$typeColumn}_block_id"];
- $meta = (int)$log["{$typeColumn}_block_meta"];
- $blockName = BlockFactory::get($id, $meta)->getName();
-
- $to = "#{$id}:{$meta} ({$blockName})";
+ $typeColumn = ($action->equals(Action::BREAK()) || $action->equals(Action::REMOVE())) ? 'old' : 'new';
+ if (isset($log["{$typeColumn}_id"], $log["{$typeColumn}_meta"])) {
+ $id = (int)$log["{$typeColumn}_id"];
+ $meta = (int)$log["{$typeColumn}_meta"];
+ if (isset($log["{$typeColumn}_amount"])) {
+ $amount = (int)$log["{$typeColumn}_amount"];
+
+ $itemName = ItemFactory::get($id, $meta)->getName();
+ $to = "{$amount} x #{$id}:{$meta} ({$itemName})";
+ } else {
+ $blockName = BlockFactory::get($id, $meta)->getName();
+ $to = "#{$id}:{$meta} ({$blockName})";
+ }
} elseif (isset($log['entity_to'])) {
$to = "#{$log['entity_to']}";
- } elseif (isset($log["{$typeColumn}_item_meta"], $log["{$typeColumn}_item_amount"])) {
- $id = (int)$log["{$typeColumn}_item_id"];
- $meta = (int)$log["{$typeColumn}_item_meta"];
- $amount = (int)$log["{$typeColumn}_item_amount"];
- $itemName = ItemFactory::get($id, $meta)->getName();
- $to = "{$amount} x #{$id}:{$meta} ({$itemName})";
} else {
- throw new UnexpectedValueException("Invalid action parsed: {$action->name()}");
+ throw new UnexpectedValueException('Unexpected log parsed. Is your database up to date?');
}
//TODO: Use strikethrough (&m) when MC fix it.
- $inspector->sendMessage(Utils::translateColors(($rollback ? "&o" : "") . "&7" . Utils::timeAgo($timeStamp)
+ $inspector->sendMessage(Utils::translateColors(($rollback ? '&o' : '') . '&7' . Utils::timeAgo($timeStamp)
. "&f - &3{$from} &f{$action->getMessage()} &3{$to} &f - &7(x{$x}/y{$y}/z{$z}/{$worldName})&f."));
}
- $inspector->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "View older data by typing /bcp l :."));
+ $inspector->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . $lang->translateString('inspector.view-old-data') . ' /bcp l :.'));
}
diff --git a/src/matcracker/BedcoreProtect/Main.php b/src/matcracker/BedcoreProtect/Main.php
index 00d47b13..b2fd326b 100644
--- a/src/matcracker/BedcoreProtect/Main.php
+++ b/src/matcracker/BedcoreProtect/Main.php
@@ -24,12 +24,14 @@
use JackMD\UpdateNotifier\UpdateNotifier;
use matcracker\BedcoreProtect\commands\BCPCommand;
use matcracker\BedcoreProtect\listeners\BlockListener;
+use matcracker\BedcoreProtect\listeners\BlockSniperListener;
use matcracker\BedcoreProtect\listeners\EntityListener;
use matcracker\BedcoreProtect\listeners\PlayerListener;
use matcracker\BedcoreProtect\listeners\WorldListener;
use matcracker\BedcoreProtect\storage\Database;
use matcracker\BedcoreProtect\tasks\SQLiteTransactionTask;
use matcracker\BedcoreProtect\utils\ConfigParser;
+use pocketmine\lang\BaseLang;
use pocketmine\plugin\PluginBase;
final class Main extends PluginBase
@@ -38,6 +40,9 @@ final class Main extends PluginBase
public const PLUGIN_TAG = "[" . self::PLUGIN_NAME . "]";
public const MESSAGE_PREFIX = "&3" . self::PLUGIN_NAME . " &f- ";
+ /**@var Main $instance */
+ private static $instance;
+
/**@var Database $database */
private $database;
@@ -45,6 +50,10 @@ final class Main extends PluginBase
private $configParser;
/**@var ConfigParser $oldConfigParser */
private $oldConfigParser;
+ /**@var BaseLang $baseLang */
+ private $baseLang;
+ /**@var boolean $bsHooked */
+ private $bsHooked = false;
/**
* @return Database
@@ -73,40 +82,83 @@ public function restoreParsedConfig(): void
*/
public function reloadPlugin(): bool
{
- $this->oldConfigParser = clone $this->configParser;
+ $this->oldConfigParser = $this->configParser;
$this->reloadConfig();
+ $this->configParser = (new ConfigParser($this->getConfig()))->validate();
+
+ if ($this->configParser->isValidConfig()) {
+ $this->baseLang = new BaseLang($this->configParser->getLanguage(), $this->getFile() . 'resources/languages/');
+ return true;
+ }
- return $this->configParser->validate()->isValidConfig();
+ return false;
}
- public function onEnable(): void
+ public static function getInstance(): Main
{
- $this->database = new Database($this);
-
- @mkdir($this->getDataFolder());
- $this->saveResource("bedcore_database.db");
+ return self::$instance;
+ }
- $this->configParser = (new ConfigParser($this))->validate();
+ public function onLoad(): void
+ {
+ $this->configParser = (new ConfigParser($this->getConfig()))->validate();
if (!$this->configParser->isValidConfig()) {
$this->getServer()->getPluginManager()->disablePlugin($this);
return;
}
+ $this->baseLang = new BaseLang($this->configParser->getLanguage(), $this->getFile() . 'resources/languages/');
+
+ if ($this->configParser->getBlockSniperHook()) {
+ $bsPlugin = $this->getServer()->getPluginManager()->getPlugin('BlockSniper');
+ if ($bsPlugin !== null) {
+ $this->getLogger()->info($this->baseLang->translateString('blocksniper.hook.success'));
+ $this->bsHooked = true;
+ } else {
+ $this->getLogger()->warning($this->baseLang->translateString('blocksniper.hook.no-hook'));
+ }
+ }
+
+ if ($this->configParser->getCheckUpdates()) {
+ UpdateNotifier::checkUpdate($this, $this->getName(), $this->getDescription()->getVersion());
+ }
+ }
+
+ public function onEnable(): void
+ {
+ self::$instance = $this;
+ $this->database = new Database($this);
+
+ @mkdir($this->getDataFolder());
+ $this->saveResource('bedcore_database.db');
+
//Database connection
if (!$this->database->connect()) {
$this->getServer()->getPluginManager()->disablePlugin($this);
return;
}
+ $version = $this->getVersion();
+ $this->database->getQueries()->init($version);
+ $dbVersion = $this->database->getVersion();
+ if (version_compare($version, $dbVersion) < 0) {
+ $this->getLogger()->warning($this->baseLang->translateString('database.version.higher'));
+ $this->getServer()->getPluginManager()->disablePlugin($this);
+
+ return;
+ }
- $this->database->getQueries()->init();
+ if ($this->database->getPatchManager()->patch()) {
+ $this->getLogger()->info($this->baseLang->translateString('database.version.updated', [$dbVersion, $version]));
+ }
if ($this->configParser->isSQLite()) {
+ $this->database->getQueries()->beginTransaction();
$this->getScheduler()->scheduleDelayedRepeatingTask(new SQLiteTransactionTask($this->database), SQLiteTransactionTask::getTicks(), SQLiteTransactionTask::getTicks());
}
- $this->getServer()->getCommandMap()->register("bedcoreprotect", new BCPCommand($this));
+ $this->getServer()->getCommandMap()->register('bedcoreprotect', new BCPCommand($this));
//Registering events
$events = [
@@ -116,13 +168,32 @@ public function onEnable(): void
new WorldListener($this)
];
+ if ($this->bsHooked) {
+ $events[] = new BlockSniperListener($this);
+ }
+
foreach ($events as $event) {
$this->getServer()->getPluginManager()->registerEvents($event, $this);
}
+ }
- if ($this->configParser->getCheckUpdates()) {
- UpdateNotifier::checkUpdate($this, $this->getName(), $this->getDescription()->getVersion());
- }
+ public function isBlockSniperHooked(): bool
+ {
+ return $this->bsHooked;
+ }
+
+ public function getLanguage(): BaseLang
+ {
+ return $this->baseLang;
+ }
+
+ /**
+ * Returns the plugin version.
+ * @return string
+ */
+ public function getVersion(): string
+ {
+ return $this->getDescription()->getVersion();
}
public function onDisable(): void
@@ -131,5 +202,8 @@ public function onDisable(): void
$this->database->disconnect();
Inspector::clearCache();
+ self::$instance = null;
+ $this->bsHooked = false;
+ unset($this->database, $this->baseLang, $this->configParser, $this->oldConfigParser);
}
-}
+}
\ No newline at end of file
diff --git a/src/matcracker/BedcoreProtect/commands/BCPCommand.php b/src/matcracker/BedcoreProtect/commands/BCPCommand.php
index a65a1559..e0fe9da0 100644
--- a/src/matcracker/BedcoreProtect/commands/BCPCommand.php
+++ b/src/matcracker/BedcoreProtect/commands/BCPCommand.php
@@ -21,13 +21,18 @@
namespace matcracker\BedcoreProtect\commands;
+use BlockHorizons\BlockSniper\sessions\SessionManager;
use matcracker\BedcoreProtect\Inspector;
use matcracker\BedcoreProtect\Main;
+use matcracker\BedcoreProtect\math\Area;
+use matcracker\BedcoreProtect\math\MathUtils;
+use matcracker\BedcoreProtect\ui\Forms;
use matcracker\BedcoreProtect\utils\Utils;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
+use pocketmine\math\AxisAlignedBB;
use pocketmine\Player;
-use poggit\libasynql\SqlError;
+use SOFe\AwaitGenerator\Await;
final class BCPCommand extends Command
{
@@ -38,10 +43,10 @@ final class BCPCommand extends Command
public function __construct(Main $plugin)
{
parent::__construct(
- "bedcoreprotect",
- "It runs the BedcoreProtect commands.",
- "Usage: /bcp help to display commands list",
- ["core", "co", "bcp"]
+ 'bedcoreprotect',
+ $plugin->getLanguage()->translateString('command.description'),
+ $plugin->getLanguage()->translateString('command.usage'),
+ ['core', 'co', 'bcp']
);
$this->plugin = $plugin;
$this->queries = $plugin->getDatabase()->getQueries();
@@ -56,8 +61,8 @@ public function execute(CommandSender $sender, string $commandLabel, array $args
}
$subCmd = $this->removeAbbreviation(strtolower($args[0]));
- if (!$sender->hasPermission("bcp.command.bedcoreprotect") || !$sender->hasPermission("bcp.subcommand.{$subCmd}")) {
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cYou don't have permission to run this command."));
+ if (!$sender->hasPermission('bcp.command.bedcoreprotect') || !$sender->hasPermission("bcp.subcommand.{$subCmd}")) {
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . '&c' . $this->plugin->getLanguage()->translateString('command.no-permission')));
return false;
}
@@ -68,28 +73,34 @@ public function execute(CommandSender $sender, string $commandLabel, array $args
isset($args[1]) ? BCPHelpCommand::showSpecificHelp($sender, $args[1]) : BCPHelpCommand::showGenericHelp($sender);
return true;
- case "reload":
+ case 'reload':
if ($this->plugin->reloadPlugin()) {
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Plugin configuration reloaded."));
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . $this->plugin->getLanguage()->translateString('command.reload.success')));
} else {
$this->plugin->restoreParsedConfig();
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cPlugin configuration not reloaded due to some errors. Check your console to see the errors."));
- $sender->sendMessage(Utils::translateColors("&cUntil you fix them, it will be used the old configuration."));
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . '&c' . $this->plugin->getLanguage()->translateString('command.reload.no-success')));
}
return true;
- case "status":
- $description = $this->plugin->getDescription();
- $sender->sendMessage(Utils::translateColors("&f----- &3" . Main::PLUGIN_NAME . " &f-----"));
- $sender->sendMessage(Utils::translateColors("&3Version:&f " . $description->getVersion()));
- $sender->sendMessage(Utils::translateColors("&3Database connection:&f " . $this->plugin->getParsedConfig()->getPrintableDatabaseType()));
- $sender->sendMessage(Utils::translateColors("&3Author:&f " . implode(",", $description->getAuthors())));
- $sender->sendMessage(Utils::translateColors("&3Website:&f " . $description->getWebsite()));
-
+ case 'status':
+ Await::f2c(function () use ($sender) {
+ $description = $this->plugin->getDescription();
+ $lang = $this->plugin->getLanguage();
+ $dbVersion = (string)yield $this->plugin->getDatabase()->getStatus()[0]["version"];
+ $sender->sendMessage(Utils::translateColors('&f----- &3' . Main::PLUGIN_NAME . ' &f-----'));
+ $sender->sendMessage(Utils::translateColors('&3' . $lang->translateString('command.status.version', [$this->plugin->getVersion()])));
+ $sender->sendMessage(Utils::translateColors('&3' . $lang->translateString('command.status.database-connection', [$this->plugin->getParsedConfig()->getPrintableDatabaseType()])));
+ $sender->sendMessage(Utils::translateColors('&3' . $lang->translateString('command.status.database-version', [$dbVersion])));
+ $sender->sendMessage(Utils::translateColors('&3' . $lang->translateString('command.status.blocksniper-hook', [$this->plugin->isBlockSniperHooked() ? $lang->translateString("generic.yes") : $lang->translateString("generic.no")])));
+ $sender->sendMessage(Utils::translateColors('&3' . $lang->translateString('command.status.author', [implode(', ', $description->getAuthors())])));
+ $sender->sendMessage(Utils::translateColors('&3' . $lang->translateString('command.status.website', [$description->getWebsite()])));
+ }, function () {
+ //NOOP
+ });
return true;
- case "lookup":
+ case 'lookup':
if (isset($args[1])) {
- $parser = new CommandParser($this->plugin->getParsedConfig(), $args, ["time"], true);
+ $parser = new CommandParser($sender->getName(), $this->plugin->getParsedConfig(), $args, ['time'], true);
if ($parser->parse()) {
$this->queries->requestLookup($sender, $parser);
} else {
@@ -107,7 +118,7 @@ public function execute(CommandSender $sender, string $commandLabel, array $args
}
if (!$ctype) {
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cWrong page/line value inserted!"));
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . '&c' . $this->plugin->getLanguage()->translateString('command.error.no-numeric-value')));
return true;
}
@@ -118,19 +129,19 @@ public function execute(CommandSender $sender, string $commandLabel, array $args
}
}
} else {
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cYou must add at least one parameter."));
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . '&c' . $this->plugin->getLanguage()->translateString('command.error.one-parameter')));
}
return true;
- case "purge":
+ case 'purge':
if (isset($args[1])) {
- $parser = new CommandParser($this->plugin->getParsedConfig(), $args, ["time"], true);
+ $parser = new CommandParser($sender->getName(), $this->plugin->getParsedConfig(), $args, ['time'], true);
if ($parser->parse()) {
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Data purge started. This may take some time."));
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Do not restart your server until completed."));
- $this->queries->purge($parser->getTime(), static function (int $affectedRows) use ($sender) {
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Data purge successful."));
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "{$affectedRows} rows of data deleted."));
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . $this->plugin->getLanguage()->translateString('command.purge.started')));
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . $this->plugin->getLanguage()->translateString('command.purge.no-restart')));
+ $this->queries->purge($parser->getTime(), function (int $affectedRows) use ($sender): void {
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . $this->plugin->getLanguage()->translateString('command.purge.success')));
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . $this->plugin->getLanguage()->translateString('command.purge.deleted-rows', [$affectedRows])));
});
return true;
@@ -138,39 +149,46 @@ public function execute(CommandSender $sender, string $commandLabel, array $args
$sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&c{$parser->getErrorMessage()}"));
}
} else {
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cYou must add at least one parameter."));
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . '&c' . $this->plugin->getLanguage()->translateString('command.error.one-parameter')));
}
return true;
}
if (!($sender instanceof Player)) {
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cYou can't run this command from console."));
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . '&c' . $this->plugin->getLanguage()->translateString('command.error.no-console')));
return false;
}
//Only players commands.
switch ($subCmd) {
- case "inspect":
- $b = Inspector::isInspector($sender);
- $b ? Inspector::removeInspector($sender) : Inspector::addInspector($sender);
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . ($b ? "Disabled" : "Enabled") . " inspector mode."));
-
+ case 'menu':
+ case 'ui':
+ $sender->sendForm((new Forms($this->plugin->getParsedConfig()))->getMainMenu());
+ return true;
+ case 'inspect':
+ if (Inspector::isInspector($sender)) {
+ Inspector::removeInspector($sender);
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . $this->plugin->getLanguage()->translateString('command.inspect.disabled')));
+ } else {
+ Inspector::addInspector($sender);
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . $this->plugin->getLanguage()->translateString('command.inspect.enabled')));
+ }
return true;
- case "near":
+ case 'near':
$near = 5;
if (isset($args[1])) {
if (!ctype_digit($args[1])) {
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cThe near value must be numeric!"));
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . '&c' . $this->plugin->getLanguage()->translateString('command.error.no-numeric-value')));
return true;
}
$near = (int)$args[1];
$maxRadius = $this->plugin->getParsedConfig()->getMaxRadius();
if ($near < 1 || $near > $maxRadius) {
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cThe near value must be between 1 and {$maxRadius}!"));
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . '&c' . $this->plugin->getLanguage()->translateString('command.near.range-value')));
return true;
}
@@ -179,112 +197,73 @@ public function execute(CommandSender $sender, string $commandLabel, array $args
$this->queries->requestNearLog($sender, $sender, $near);
return true;
- case "rollback":
+ case 'rollback':
if (isset($args[1])) {
- $parser = new CommandParser($this->plugin->getParsedConfig(), $args, ["time", "radius"], true);
+ $parser = new CommandParser($sender->getName(), $this->plugin->getParsedConfig(), $args, ['time', 'radius'], true);
if ($parser->parse()) {
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Starting rollback on \"{$sender->getLevel()->getFolderName()}\"."));
- $sender->sendMessage(Utils::translateColors("&f------"));
- $start = microtime(true);
-
- $this->queries->rollback($sender->asPosition(), $parser,
- static function (int $blocks, int $items, int $entities) use ($sender, $start, $parser) { //onSuccess
- if (($blocks + $items + $entities) > 0) {
- $diff = microtime(true) - $start;
- $time = time() - $parser->getTime();
- $radius = $parser->getRadius();
- $date = Utils::timeAgo($time);
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Rollback completed for \"{$sender->getLevel()->getFolderName()}\"."));
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Rolled back {$date}."));
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Radius: {$radius} block(s)."));
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Approx. {$blocks} block(s) changed."));
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Approx. {$items} item(s) changed."));
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Approx. {$entities} entity(ies) changed."));
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Time taken: " . round($diff, 1) . " second(s)."));
- $sender->sendMessage(Utils::translateColors("&f------"));
- $y = $sender->getLevel()->getHighestBlockAt((int)$sender->getX(), (int)$sender->getZ()) + 1;
- if ((int)$sender->getY() < $y) {
- $sender->teleport($sender->setComponents($sender->getX(), $y, $sender->getZ()), $sender->getYaw(), $sender->getPitch());
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Teleported to the top."));
- }
- } else {
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cNo data to rollback."));
- }
- },
- static function (SqlError $error) use ($sender) { //onError
- $this->plugin->getLogger()->alert($error->getErrorMessage());
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cAn error occurred while restoring. Check the console."));
- $sender->sendMessage(Utils::translateColors("&f------"));
- }
- );
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . $this->plugin->getLanguage()->translateString('command.rollback.started', [$sender->getLevel()->getName()])));
+
+ $bb = $this->getSelectionArea($sender) ?? MathUtils::getRangedVector($sender->asVector3(), $parser->getRadius());
+ $this->queries->rollback(new Area($sender->getLevel(), $bb), $parser);
} else {
$sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&c{$parser->getErrorMessage()}"));
}
} else {
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cYou must add at least one parameter."));
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . '&c' . $this->plugin->getLanguage()->translateString('command.error.one-parameter')));
}
return true;
- case "restore":
+ case 'restore':
if (isset($args[1])) {
- $parser = new CommandParser($this->plugin->getParsedConfig(), $args, ["time", "radius"], true);
+ $parser = new CommandParser($sender->getName(), $this->plugin->getParsedConfig(), $args, ['time', 'radius'], true);
if ($parser->parse()) {
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Restore started on \"{$sender->getLevel()->getFolderName()}\"."));
- $sender->sendMessage(Utils::translateColors("&f------"));
- $start = microtime(true);
-
- $this->queries->restore($sender->asPosition(), $parser,
- static function (int $blocks, int $items, int $entities) use ($sender, $start, $parser) { //onSuccess
- if (($blocks + $items + $entities) > 0) {
- $diff = microtime(true) - $start;
- $time = time() - $parser->getTime();
- $radius = $parser->getRadius();
- $date = Utils::timeAgo($time);
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Restore completed for \"{$sender->getLevel()->getFolderName()}\"."));
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Restored {$date}."));
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Radius: {$radius} block(s)."));
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Approx. {$blocks} block(s) changed."));
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Approx. {$items} item(s) changed."));
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Approx. {$entities} entity(ies) changed."));
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "Time taken: " . round($diff, 1) . " second(s)."));
- $sender->sendMessage(Utils::translateColors("&f------"));
- } else {
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cNo data to restore."));
- }
- },
- static function (SqlError $error) use ($sender) { //onError
- $this->plugin->getLogger()->alert($error->getErrorMessage());
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cAn error occurred while restoring. Check the console."));
- $sender->sendMessage(Utils::translateColors("&f------"));
- }
- );
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . $this->plugin->getLanguage()->translateString('command.restore.started', [$sender->getLevel()->getName()])));
+
+ $bb = $this->getSelectionArea($sender) ?? MathUtils::getRangedVector($sender->asVector3(), $parser->getRadius());
+ $this->queries->restore(new Area($sender->getLevel(), $bb), $parser);
} else {
$sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&c{$parser->getErrorMessage()}"));
}
} else {
- $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&cYou must add at least one parameter."));
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . '&c' . $this->plugin->getLanguage()->translateString('command.error.one-parameter')));
}
return true;
+ default:
+ $sender->sendMessage(Utils::translateColors(Main::MESSAGE_PREFIX . "&c{$this->getUsage()}"));
+ return false;
}
-
- return false;
}
private function removeAbbreviation(string $subCmd): string
{
- if ($subCmd === "l") {
- $subCmd = "lookup";
- } else if ($subCmd === "i") {
- $subCmd = "inspect";
- } else if ($subCmd === "rb") {
- $subCmd = "rollback";
- } else if ($subCmd === "rs") {
- $subCmd = "restore";
+ if ($subCmd === 'l') {
+ $subCmd = 'lookup';
+ } else if ($subCmd === 'i') {
+ $subCmd = 'inspect';
+ } else if ($subCmd === 'rb') {
+ $subCmd = 'rollback';
+ } else if ($subCmd === 'rs') {
+ $subCmd = 'restore';
+ } else if ($subCmd === 'ui') {
+ $subCmd = 'menu';
}
return $subCmd;
}
+ private function getSelectionArea(Player $player): ?AxisAlignedBB
+ {
+ if ($this->plugin->isBlockSniperHooked()) {
+ $session = SessionManager::getPlayerSession($player);
+ if ($session !== null) {
+ $selection = $session->getSelection();
+ if ($selection->ready()) {
+ return $selection->box();
+ }
+ }
+ }
+ return null;
+ }
}
\ No newline at end of file
diff --git a/src/matcracker/BedcoreProtect/commands/BCPHelpCommand.php b/src/matcracker/BedcoreProtect/commands/BCPHelpCommand.php
index f8092a4e..7b45fd28 100644
--- a/src/matcracker/BedcoreProtect/commands/BCPHelpCommand.php
+++ b/src/matcracker/BedcoreProtect/commands/BCPHelpCommand.php
@@ -34,35 +34,42 @@ private function __construct()
public static function showGenericHelp(CommandSender $sender): void
{
- $sender->sendMessage(Utils::translateColors("&f----- &3" . Main::PLUGIN_NAME . " &3Help Page &f-----"));
- $sender->sendMessage(Utils::translateColors("&3/bcp help &7 &f- Display more info for that command."));
- $sender->sendMessage(Utils::translateColors("&3/bcp &7inspect &f- Turns the blocks inspector on or off."));
- $sender->sendMessage(Utils::translateColors("&3/bcp &7rollback &3 &f- Rollback block data."));
- $sender->sendMessage(Utils::translateColors("&3/bcp &7restore &3 &f- Restore block data."));
- $sender->sendMessage(Utils::translateColors("&3/bcp &7lookup &3 &f- Advanced block data lookup."));
- $sender->sendMessage(Utils::translateColors("&3/bcp &7purge &3 &f- Delete old block data."));
- $sender->sendMessage(Utils::translateColors("&3/bcp &7reload &f- Reloads the configuration file."));
- $sender->sendMessage(Utils::translateColors("&3/bcp &7status &f- Displays the plugin status"));
+ $lang = Main::getInstance()->getLanguage();
+ $sender->sendMessage(Utils::translateColors("&f----- &3" . Main::PLUGIN_NAME . " &3" . $lang->translateString("command.help.title") . " &f-----"));
+ $sender->sendMessage(Utils::translateColors("&3/bcp help &7 &f- " . $lang->translateString("command.help.help")));
+ $sender->sendMessage(Utils::translateColors("&3/bcp &7menu &f- " . $lang->translateString("command.help.menu")));
+ $sender->sendMessage(Utils::translateColors("&3/bcp &7inspect &f- " . $lang->translateString("command.help.inspect")));
+ $sender->sendMessage(Utils::translateColors("&3/bcp &7rollback &3 &f- " . $lang->translateString("command.help.rollback")));
+ $sender->sendMessage(Utils::translateColors("&3/bcp &7restore &3 &f- " . $lang->translateString("command.help.restore")));
+ $sender->sendMessage(Utils::translateColors("&3/bcp &7lookup &3 &f- " . $lang->translateString("command.help.lookup")));
+ $sender->sendMessage(Utils::translateColors("&3/bcp &7purge &3 &f- " . $lang->translateString("command.help.purge")));
+ $sender->sendMessage(Utils::translateColors("&3/bcp &7reload &f- " . $lang->translateString("command.help.reload")));
+ $sender->sendMessage(Utils::translateColors("&3/bcp &7status &f- " . $lang->translateString("command.help.status")));
$sender->sendMessage(Utils::translateColors("&f------"));
}
public static function showSpecificHelp(CommandSender $sender, string $subCmd): void
{
+ $lang = Main::getInstance()->getLanguage();
$subCmd = strtolower($subCmd);
- $sender->sendMessage(Utils::translateColors("&f----- &3" . Main::PLUGIN_NAME . " &3Help Page &f-----"));
+ $sender->sendMessage(Utils::translateColors("&f----- &3" . Main::PLUGIN_NAME . " &3" . $lang->translateString("command.help.title") . "&f-----"));
switch ($subCmd) {
case "help":
- $sender->sendMessage(Utils::translateColors("&3/bcp help &f- Displays a list of all commands."));
+ $sender->sendMessage(Utils::translateColors("&3/bcp help &f- " . $lang->translateString("command.help.help2")));
+ break;
+ case "menu":
+ case "ui":
+ $sender->sendMessage(Utils::translateColors("&3/bcp menu &f- " . $lang->translateString("command.help.menu")));
break;
case "inspect":
case "i":
- $sender->sendMessage(Utils::translateColors("&3With the inspector enabled, you can do the following:"));
- $sender->sendMessage(Utils::translateColors("&7* Left-click a block to see who placed that block."));
- $sender->sendMessage(Utils::translateColors("&7* Right-click a block to see what adjacent block was removed."));
- $sender->sendMessage(Utils::translateColors("&7* Place a block to see what block was removed at the location."));
- $sender->sendMessage(Utils::translateColors("&7* Place a block in liquid (etc) to see who placed it."));
- $sender->sendMessage(Utils::translateColors("&7* Right-click on a door, chest, etc, to see who last used it."));
- $sender->sendMessage(Utils::translateColors("&7Tip: You can use just &3\"/bcp i\"&7 for quicker access."));
+ $sender->sendMessage(Utils::translateColors("&3" . $lang->translateString("command.help.inspect1")));
+ $sender->sendMessage(Utils::translateColors("&7* " . $lang->translateString("command.help.inspect2")));
+ $sender->sendMessage(Utils::translateColors("&7* " . $lang->translateString("command.help.inspect3")));
+ $sender->sendMessage(Utils::translateColors("&7* " . $lang->translateString("command.help.inspect4")));
+ $sender->sendMessage(Utils::translateColors("&7* " . $lang->translateString("command.help.inspect5")));
+ $sender->sendMessage(Utils::translateColors("&7* " . $lang->translateString("command.help.inspect6")));
+ $sender->sendMessage(Utils::translateColors("&7" . $lang->translateString("command.help.inspect7")));
break;
case "rollback":
case "rb":
@@ -76,61 +83,61 @@ public static function showSpecificHelp(CommandSender $sender, string $subCmd):
} elseif ($subCmd === "rb") {
$subCmd = "rollback";
}
- $sender->sendMessage(Utils::translateColors("&3/bcp {$subCmd} &7 &f- Perform the {$subCmd}."));
- $sender->sendMessage(Utils::translateColors("&3| &7u= &f- Specify the user(s) to {$subCmd}."));
- $sender->sendMessage(Utils::translateColors("&3| &7t=