diff --git a/plugin.yml b/plugin.yml index 64c3188..1666513 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,5 +1,5 @@ name: BedrockEconomy -version: 4.0.3 +version: 4.0.4 api: [ 5.0.0 ] author: cooldogedev main: cooldogedev\BedrockEconomy\BedrockEconomy diff --git a/resources/config.yml b/resources/config.yml index 160ed91..aa625e9 100644 --- a/resources/config.yml +++ b/resources/config.yml @@ -1,5 +1,5 @@ --- -config-version: 4.0.2 +config-version: 4.0.4 language: en-US @@ -12,11 +12,11 @@ currency: name: United States Dollar code: USD symbol: $ - formatter: "compact" # The currency formatter, compact or commadot + formatter: compact # The currency formatter, compact or commadot default: amount: 0 decimals: 00 - decimals: true + decimals: false database: # The database provider, mysql or sqlite diff --git a/src/cooldogedev/BedrockEconomy/BedrockEconomy.php b/src/cooldogedev/BedrockEconomy/BedrockEconomy.php index a1c1b7d..de473a9 100644 --- a/src/cooldogedev/BedrockEconomy/BedrockEconomy.php +++ b/src/cooldogedev/BedrockEconomy/BedrockEconomy.php @@ -48,10 +48,14 @@ use CortexPE\Commando\PacketHooker; use JsonException; use pocketmine\plugin\PluginBase; +use pocketmine\promise\Promise; use pocketmine\scheduler\ClosureTask; use pocketmine\utils\SingletonTrait; use pocketmine\utils\TextFormat; use RuntimeException; +use function class_alias; +use function count; +use function rename; final class BedrockEconomy extends PluginBase { @@ -66,6 +70,8 @@ final class BedrockEconomy extends PluginBase */ private ?array $migrationInfo; + private bool $ready = false; + protected function onLoad(): void { foreach ($this->getResources() as $resource) { @@ -105,7 +111,6 @@ protected function onEnable(): void $this->currencyManager = new CurrencyManager($this->currency); GlobalCache::init(); - QueryManager::init($this->currency->code, $this->getConfig()->getNested("database.provider") === "mysql"); QueryManager::TABLE()->execute(); @@ -113,16 +118,22 @@ protected function onEnable(): void task: new ClosureTask( function (): void { [$oldVersion, $oldProvider] = $this->migrationInfo; + $promises = []; foreach (MigrationRegistry::get($oldVersion) as $migrationClass) { $migration = new $migrationClass($this); - - if ($migration->run($oldProvider)) { - $this->getLogger()->debug($migration->getName() . " migration ran successfully"); - } else { - $this->getLogger()->debug($migration->getName() . " migration failed to run"); + $promise = $migration->run($oldProvider); + if ($promise !== null) { + $promises[] = $promise; } } + + if (count($promises) === 0) { + $this->ready = true; + return; + } + + Promise::all($promises)->onCompletion(fn () => $this->ready = true, fn () => $this->ready = true); } ), delay: 0 @@ -136,7 +147,13 @@ function (): void { } $this->getScheduler()->scheduleRepeatingTask( - task: new ClosureTask(static fn() => GlobalCache::invalidate()), + task: new ClosureTask(function (): void { + if (!$this->ready) { + return; + } + + GlobalCache::invalidate(); + }), period: $this->getConfig()->getNested("cache.invalidation") * 20 ); } @@ -211,4 +228,9 @@ public function getCurrencyManager(): CurrencyManager { return $this->currencyManager; } + + public function isReady(): bool + { + return $this->ready; + } } diff --git a/src/cooldogedev/BedrockEconomy/EventListener.php b/src/cooldogedev/BedrockEconomy/EventListener.php index d79d68e..c9b9fe1 100644 --- a/src/cooldogedev/BedrockEconomy/EventListener.php +++ b/src/cooldogedev/BedrockEconomy/EventListener.php @@ -56,13 +56,26 @@ public function __construct(private readonly BedrockEconomy $plugin) {} private function handleAddTransaction(UpdateTransaction $transaction): void { + $fetcher = static function (CacheEntry $entry) use ($transaction) { + $amount = $entry->amount + $transaction->amount; + $decimals = $entry->decimals + $transaction->decimals; + + if ($decimals >= 100) { + $amount += 1; + $decimals -= 100; + } + + return [$amount, $decimals]; + }; + $online = GlobalCache::ONLINE()->get($transaction->username); $top = GlobalCache::TOP()->get($transaction->username); if ($top !== null) { + [$amount, $decimals] = $fetcher($top); GlobalCache::TOP()->set($transaction->username, new CacheEntry( - amount: $top->amount + $transaction->amount, - decimals: $top->decimals + $transaction->decimals, + amount: $amount, + decimals: $decimals, position: $top->position, )); @@ -70,9 +83,10 @@ private function handleAddTransaction(UpdateTransaction $transaction): void } if ($online !== null) { + [$amount, $decimals] = $fetcher($online); GlobalCache::ONLINE()->set($transaction->username, new CacheEntry( - amount: $online->amount + $transaction->amount, - decimals: $online->decimals + $transaction->decimals, + amount: $amount, + decimals: $decimals, position: GlobalCache::TOP()->get($transaction->username)?->position ?? $online->position, )); } @@ -80,13 +94,26 @@ private function handleAddTransaction(UpdateTransaction $transaction): void private function handleSubtractTransaction(UpdateTransaction $transaction): void { + $fetcher = static function (CacheEntry $entry) use ($transaction) { + $amount = $entry->amount - $transaction->amount; + $decimals = $entry->decimals - $transaction->decimals; + + if ($decimals < 0) { + $amount -= 1; + $decimals += 100; + } + + return [$amount, $decimals]; + }; + $online = GlobalCache::ONLINE()->get($transaction->username); $top = GlobalCache::TOP()->get($transaction->username); if ($top !== null) { + [$amount, $decimals] = $fetcher($top); GlobalCache::TOP()->set($transaction->username, new CacheEntry( - amount: $top->amount - $transaction->amount, - decimals: $top->decimals - $transaction->decimals, + amount: $amount, + decimals: $decimals, position: $top->position, )); @@ -94,9 +121,10 @@ private function handleSubtractTransaction(UpdateTransaction $transaction): void } if ($online !== null) { + [$amount, $decimals] = $fetcher($online); GlobalCache::ONLINE()->set($transaction->username, new CacheEntry( - amount: $online->amount - $transaction->amount, - decimals: $online->decimals - $transaction->decimals, + amount: $amount, + decimals: $decimals, position: GlobalCache::TOP()->get($transaction->username)?->position ?? $online->position, )); } @@ -171,6 +199,11 @@ public function onPlayerCreation(PlayerCreationEvent $event): void $networkSession = $event->getNetworkSession(); $playerInfo = $networkSession->getPlayerInfo(); + if (!$this->plugin->isReady()) { + $networkSession->disconnect("An error occurred while loading the plugin. Please try again later."); + return; + } + if (!$playerInfo instanceof XboxLivePlayerInfo) { throw new RuntimeException("BedrockEconomy requires xbox authentication."); } diff --git a/src/cooldogedev/BedrockEconomy/api/type/ClosureAPI.php b/src/cooldogedev/BedrockEconomy/api/type/ClosureAPI.php index 17efa2b..75ec32a 100644 --- a/src/cooldogedev/BedrockEconomy/api/type/ClosureAPI.php +++ b/src/cooldogedev/BedrockEconomy/api/type/ClosureAPI.php @@ -39,6 +39,9 @@ use cooldogedev\BedrockEconomy\event\transaction\TransactionFailEvent; use cooldogedev\BedrockEconomy\event\transaction\TransactionSubmitEvent; use cooldogedev\BedrockEconomy\event\transaction\TransactionSuccessEvent; +use function array_map; +use function explode; +use function number_format; final class ClosureAPI extends BaseAPI { @@ -54,7 +57,13 @@ public function getVersion(): string public function bulk(array $list, Closure $onSuccess, Closure $onError): void { - QueryManager::BULK($list)->execute($onSuccess, $onError); + QueryManager::BULK($list)->execute( + onSuccess: fn (array $rows) => $onSuccess(array_map(fn (array $row) => [ + ...$row, + ... $this->transformAmount($row["amount"]), + ], $rows)), + onFail: $onError, + ); } public function insert(string $xuid, string $username, int $balance, int $decimals, Closure $onSuccess, Closure $onError): void @@ -76,12 +85,25 @@ public function migrate(string $xuid, string $username, string $newXuid, string */ public function get(string $xuid, string $username, Closure $onSuccess, Closure $onError): void { - QueryManager::RETRIEVE($xuid, $username)->execute($onSuccess, $onError); + QueryManager::RETRIEVE($xuid, $username) + ->execute( + onSuccess: fn (array $result) => $onSuccess([ + ... $result, + ... $this->transformAmount($result["amount"]), + ]), + onFail: $onError, + ); } public function top(int $limit, int $offset, bool $ascending, Closure $onSuccess, Closure $onError): void { - QueryManager::TOP($limit, $offset, $ascending)->execute($onSuccess, $onError); + QueryManager::TOP($limit, $offset, $ascending)->execute( + onSuccess: fn (array $rows) => $onSuccess(array_map(fn (array $row) => [ + ...$row, + ... $this->transformAmount($row["amount"]), + ], $rows)), + onFail: $onError, + ); } public function transfer(array $source, array $target, int $amount, int $decimals, Closure $onSuccess, Closure $onError): void @@ -151,4 +173,14 @@ public function set(string $xuid, string $username, int $amount, int $decimals, onFail: ClosureWrapper::combine($onError, static fn() => (new TransactionFailEvent($transaction))->call()), ); } + + private function transformAmount(float $amount): array + { + $amount = number_format($amount, 2, ".", ""); + $amount = explode(".", $amount); + return [ + "amount" => (int) $amount[0], + "decimals" => (int) $amount[1], + ]; + } } diff --git a/src/cooldogedev/BedrockEconomy/command/BalanceCommand.php b/src/cooldogedev/BedrockEconomy/command/BalanceCommand.php index a576aeb..61909e9 100644 --- a/src/cooldogedev/BedrockEconomy/command/BalanceCommand.php +++ b/src/cooldogedev/BedrockEconomy/command/BalanceCommand.php @@ -59,6 +59,10 @@ protected function prepare(): void public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { + if (!$this->getOwningPlugin()->isReady()) { + return; + } + $player = $args[BalanceCommand::ARGUMENT_PLAYER] ?? null; if (!$sender instanceof Player && $player === null) { diff --git a/src/cooldogedev/BedrockEconomy/command/PayCommand.php b/src/cooldogedev/BedrockEconomy/command/PayCommand.php index ad74e15..9064f65 100644 --- a/src/cooldogedev/BedrockEconomy/command/PayCommand.php +++ b/src/cooldogedev/BedrockEconomy/command/PayCommand.php @@ -75,6 +75,10 @@ protected function prepare(): void */ public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { + if (!$this->getOwningPlugin()->isReady()) { + return; + } + $player = $args[PayCommand::ARGUMENT_TARGET]; $amount = $args[PayCommand::ARGUMENT_AMOUNT]; @@ -108,6 +112,9 @@ public function onRun(CommandSender $sender, string $aliasUsed, array $args): vo $balance = (int)$amount[0]; $decimals = (int)($amount[1] ?? 0); + if ($decimals >= 100) { + $decimals = 99; + } Await::f2c( function () use ($sender, $player, $balance, $decimals): Generator { diff --git a/src/cooldogedev/BedrockEconomy/command/RichCommand.php b/src/cooldogedev/BedrockEconomy/command/RichCommand.php index d6b0d61..8e19a97 100644 --- a/src/cooldogedev/BedrockEconomy/command/RichCommand.php +++ b/src/cooldogedev/BedrockEconomy/command/RichCommand.php @@ -54,6 +54,10 @@ protected function prepare(): void public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { + if (!$this->getOwningPlugin()->isReady()) { + return; + } + if (count(GlobalCache::TOP()->getAll()) === 0) { GlobalCache::invalidate(); $sender->sendMessage(LanguageManager::getString(KnownMessages::ERROR_RICH_NO_RECORDS)); diff --git a/src/cooldogedev/BedrockEconomy/command/admin/AddBalanceCommand.php b/src/cooldogedev/BedrockEconomy/command/admin/AddBalanceCommand.php index 4723514..d185e86 100644 --- a/src/cooldogedev/BedrockEconomy/command/admin/AddBalanceCommand.php +++ b/src/cooldogedev/BedrockEconomy/command/admin/AddBalanceCommand.php @@ -68,6 +68,10 @@ protected function prepare(): void public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { + if (!$this->getOwningPlugin()->isReady()) { + return; + } + $player = $args[AddBalanceCommand::ARGUMENT_PLAYER]; $amount = $args[AddBalanceCommand::ARGUMENT_AMOUNT]; @@ -96,6 +100,9 @@ public function onRun(CommandSender $sender, string $aliasUsed, array $args): vo $balance = (int)$amount[0]; $decimals = (int)($amount[1] ?? 0); + if ($decimals >= 100) { + $decimals = 99; + } Await::f2c( function () use ($sender, $player, $balance, $decimals): Generator { diff --git a/src/cooldogedev/BedrockEconomy/command/admin/RemoveBalanceCommand.php b/src/cooldogedev/BedrockEconomy/command/admin/RemoveBalanceCommand.php index d0bb99b..a8c7af1 100644 --- a/src/cooldogedev/BedrockEconomy/command/admin/RemoveBalanceCommand.php +++ b/src/cooldogedev/BedrockEconomy/command/admin/RemoveBalanceCommand.php @@ -69,6 +69,10 @@ protected function prepare(): void public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { + if (!$this->getOwningPlugin()->isReady()) { + return; + } + $player = $args[RemoveBalanceCommand::ARGUMENT_PLAYER]; $amount = $args[RemoveBalanceCommand::ARGUMENT_AMOUNT]; @@ -97,6 +101,9 @@ public function onRun(CommandSender $sender, string $aliasUsed, array $args): vo $balance = (int)$amount[0]; $decimals = (int)($amount[1] ?? 0); + if ($decimals >= 100) { + $decimals = 99; + } Await::f2c( function () use ($sender, $player, $balance, $decimals): Generator { diff --git a/src/cooldogedev/BedrockEconomy/command/admin/SetBalanceCommand.php b/src/cooldogedev/BedrockEconomy/command/admin/SetBalanceCommand.php index b75dfd0..c209fa1 100644 --- a/src/cooldogedev/BedrockEconomy/command/admin/SetBalanceCommand.php +++ b/src/cooldogedev/BedrockEconomy/command/admin/SetBalanceCommand.php @@ -68,6 +68,10 @@ protected function prepare(): void public function onRun(CommandSender $sender, string $aliasUsed, array $args): void { + if (!$this->getOwningPlugin()->isReady()) { + return; + } + $player = $args[SetBalanceCommand::ARGUMENT_PLAYER]; $amount = $args[SetBalanceCommand::ARGUMENT_AMOUNT]; @@ -96,6 +100,9 @@ public function onRun(CommandSender $sender, string $aliasUsed, array $args): vo $balance = (int)$amount[0]; $decimals = (int)($amount[1] ?? 0); + if ($decimals >= 100) { + $decimals = 99; + } Await::f2c( function () use ($sender, $player, $balance, $decimals): Generator { diff --git a/src/cooldogedev/BedrockEconomy/currency/CurrencyFormatter.php b/src/cooldogedev/BedrockEconomy/currency/CurrencyFormatter.php index 17bac25..25aa152 100644 --- a/src/cooldogedev/BedrockEconomy/currency/CurrencyFormatter.php +++ b/src/cooldogedev/BedrockEconomy/currency/CurrencyFormatter.php @@ -92,10 +92,6 @@ public function commadot(int $number, ?int $decimals): string $decimals = "0" . $decimals; } - if ($decimals === "00") { - $decimals = null; - } - return $this->currency->symbol . $formatted . ($decimals !== null ? "." . $decimals : ""); } } diff --git a/src/cooldogedev/BedrockEconomy/database/helper/TableHolder.php b/src/cooldogedev/BedrockEconomy/database/helper/TableHolder.php index 8ff2056..3a6aff4 100644 --- a/src/cooldogedev/BedrockEconomy/database/helper/TableHolder.php +++ b/src/cooldogedev/BedrockEconomy/database/helper/TableHolder.php @@ -31,6 +31,8 @@ namespace cooldogedev\BedrockEconomy\database\helper; use cooldogedev\BedrockEconomy\database\constant\TablePrefix; +use function strtolower; +use function str_replace; trait TableHolder { @@ -38,6 +40,6 @@ trait TableHolder public function setTable(string $table): void { - $this->table = strtolower(TablePrefix::PREFIX . $table);; + $this->table = strtolower(TablePrefix::PREFIX . str_replace(" ", "_", $table)); } } diff --git a/src/cooldogedev/BedrockEconomy/database/migration/BaseMigration.php b/src/cooldogedev/BedrockEconomy/database/migration/BaseMigration.php index 5fe5ab4..1a5243e 100644 --- a/src/cooldogedev/BedrockEconomy/database/migration/BaseMigration.php +++ b/src/cooldogedev/BedrockEconomy/database/migration/BaseMigration.php @@ -31,6 +31,7 @@ namespace cooldogedev\BedrockEconomy\database\migration; use cooldogedev\BedrockEconomy\BedrockEconomy; +use pocketmine\promise\Promise; use PrefixedLogger; abstract class BaseMigration @@ -46,5 +47,5 @@ abstract static public function getName(): string; abstract static public function getMin(): string; abstract static public function getMax(): string; - abstract public function run(string $mode): bool; + abstract public function run(string $mode): ?Promise; } diff --git a/src/cooldogedev/BedrockEconomy/database/migration/MigrationRegistry.php b/src/cooldogedev/BedrockEconomy/database/migration/MigrationRegistry.php index 0634a5b..9a1e230 100644 --- a/src/cooldogedev/BedrockEconomy/database/migration/MigrationRegistry.php +++ b/src/cooldogedev/BedrockEconomy/database/migration/MigrationRegistry.php @@ -33,6 +33,7 @@ use cooldogedev\BedrockEconomy\database\constant\MigrationVersion; use cooldogedev\BedrockEconomy\database\migration\economyapi\Migration as EconomyAPI; use cooldogedev\BedrockEconomy\database\migration\v2_1_2\Migration as v2_1_2; +use cooldogedev\BedrockEconomy\database\migration\v4_0_3\Migration as v_4_0_3; final class MigrationRegistry { @@ -42,6 +43,7 @@ public static function init(): void { MigrationRegistry::register(EconomyAPI::class); MigrationRegistry::register(v2_1_2::class); + MigrationRegistry::register(v_4_0_3::class); } /** diff --git a/src/cooldogedev/BedrockEconomy/database/migration/economyapi/Migration.php b/src/cooldogedev/BedrockEconomy/database/migration/economyapi/Migration.php index ec940ce..e991f26 100644 --- a/src/cooldogedev/BedrockEconomy/database/migration/economyapi/Migration.php +++ b/src/cooldogedev/BedrockEconomy/database/migration/economyapi/Migration.php @@ -36,6 +36,7 @@ use cooldogedev\BedrockEconomy\database\migration\BaseMigration; use cooldogedev\libSQL\exception\SQLException; use Generator; +use pocketmine\promise\Promise; use SOFe\AwaitGenerator\Await; final class Migration extends BaseMigration @@ -55,33 +56,28 @@ public static function getMax(): string return MigrationVersion::VERSION_ANY; } - public function run(string $mode): bool + public function run(string $mode): ?Promise { $economyAPI = $this->plugin->getServer()->getPluginManager()->getPlugin("EconomyAPI"); - - if ($economyAPI === null) { - return false; - } - - Await::f2c( - function () use ($economyAPI): Generator { - foreach ($economyAPI->getAllMoney() as $username => $money) { - $money = explode(".", (string)$money); - $amount = (int)($money[0] ?? 0); - $decimals = (int)($money[1] ?? 0); - - try { - yield from BedrockEconomyAPI::ASYNC()->insert($username, $username, $amount, $decimals); - $this->logger->info("Migrated data for player " . $username); - } catch (RecordAlreadyExistsException) { - $this->logger->warning("Attempted to migrate data for player " . $username . " but they already exist"); - } catch (SQLException) { - $this->logger->warning("Failed to migrate data for player " . $username); + if ($economyAPI !== null) { + Await::f2c( + function () use ($economyAPI): Generator { + foreach ($economyAPI->getAllMoney() as $username => $money) { + $money = explode(".", (string)$money); + $amount = (int)($money[0] ?? 0); + $decimals = (int)($money[1] ?? 0); + try { + yield from BedrockEconomyAPI::ASYNC()->insert($username, $username, $amount, $decimals); + $this->logger->debug("Migrated data for player " . $username); + } catch (RecordAlreadyExistsException) { + $this->logger->warning("Attempted to migrate data for player " . $username . " but they already exist"); + } catch (SQLException) { + $this->logger->warning("Failed to migrate data for player " . $username); + } } } - } - ); - - return true; + ); + } + return null; } } diff --git a/src/cooldogedev/BedrockEconomy/database/migration/v2_1_2/Migration.php b/src/cooldogedev/BedrockEconomy/database/migration/v2_1_2/Migration.php index 5dc4699..99c3be4 100644 --- a/src/cooldogedev/BedrockEconomy/database/migration/v2_1_2/Migration.php +++ b/src/cooldogedev/BedrockEconomy/database/migration/v2_1_2/Migration.php @@ -35,6 +35,7 @@ use cooldogedev\BedrockEconomy\database\migration\BaseMigration; use cooldogedev\libSQL\exception\SQLException; use Generator; +use pocketmine\promise\Promise; use SOFe\AwaitGenerator\Await; final class Migration extends BaseMigration @@ -54,7 +55,7 @@ public static function getMax(): string return "2.1.2"; } - public function run(string $mode): bool + public function run(string $mode): ?Promise { $query = $mode === "mysql" ? new MySQLHandler() : new SQLiteHandler(); $query->execute( @@ -63,7 +64,7 @@ function () use ($records): Generator { foreach ($records as $record) { try { yield from BedrockEconomyAPI::ASYNC()->insert($record["username"], $record["username"], (int)$record["balance"], 0); - $this->logger->info("Migrated data for player " . $record["username"]); + $this->logger->debug("Migrated data for player " . $record["username"]); } catch (RecordAlreadyExistsException) { $this->logger->warning("Attempted to migrate data for player " . $record["username"] . " but they already exist"); } catch (SQLException) { @@ -72,11 +73,8 @@ function () use ($records): Generator { } } ), - onFail: function (): void { - $this->logger->warning("Failed to migrate data from old database"); - } + onFail: fn (SQLException $exception) => $this->logger->logException($exception) ); - - return true; + return null; } } diff --git a/src/cooldogedev/BedrockEconomy/database/migration/v4_0_3/Migration.php b/src/cooldogedev/BedrockEconomy/database/migration/v4_0_3/Migration.php new file mode 100644 index 0000000..632f79e --- /dev/null +++ b/src/cooldogedev/BedrockEconomy/database/migration/v4_0_3/Migration.php @@ -0,0 +1,93 @@ +setTable(BedrockEconomy::getInstance()->getCurrency()->code); + $query->execute( + onSuccess: fn(array $result) => QueryManager::TABLE()->execute( + onSuccess: fn() => Await::f2c(function () use ($resolver, $result): Generator { + foreach ($result as $record) { + try { + yield from BedrockEconomyAPI::ASYNC()->insert( + xuid: $record["xuid"], + username: $record["username"], + balance: $record["amount"], + decimals: $record["decimals"], + ); + $this->logger->debug("Migrated data for player " . $record["username"]); + } catch (RecordAlreadyExistsException) { + $this->logger->warning("Attempted to migrate data for player " . $record["username"] . " but they already exist"); + } catch (SQLException) { + $this->logger->warning("Failed to migrate data for player " . $record["username"]); + } + $resolver->resolve(null); + } + }), + onFail: fn(SQLException $exception) => $this->logger->logException($exception), + ), + onFail: fn(SQLException $exception) => $this->logger->logException($exception), + ); + return $resolver->getPromise(); + } +} diff --git a/src/cooldogedev/BedrockEconomy/database/migration/v4_0_3/MySQLHandler.php b/src/cooldogedev/BedrockEconomy/database/migration/v4_0_3/MySQLHandler.php new file mode 100644 index 0000000..959a339 --- /dev/null +++ b/src/cooldogedev/BedrockEconomy/database/migration/v4_0_3/MySQLHandler.php @@ -0,0 +1,50 @@ +query("SELECT * FROM " . $this->table); + $result = $query?->fetch_all(MYSQLI_ASSOC) ?? []; + $query->close(); + $connection->query("DROP TABLE IF EXISTS " . $this->table); + + $this->setResult($result); + } +} diff --git a/src/cooldogedev/BedrockEconomy/database/migration/v4_0_3/SQLiteHandler.php b/src/cooldogedev/BedrockEconomy/database/migration/v4_0_3/SQLiteHandler.php new file mode 100644 index 0000000..11d13c4 --- /dev/null +++ b/src/cooldogedev/BedrockEconomy/database/migration/v4_0_3/SQLiteHandler.php @@ -0,0 +1,54 @@ +query("SELECT * FROM " . $this->table); + $result = []; + while ($row = $query->fetchArray(SQLITE3_ASSOC)) { + $result[] = $row; + } + $query->finalize(); + $connection->query("DROP TABLE IF EXISTS " . $this->table); + + $this->setResult($result); + } +} diff --git a/src/cooldogedev/BedrockEconomy/database/mysql/BulkQuery.php b/src/cooldogedev/BedrockEconomy/database/mysql/BulkQuery.php index 532c531..c97fdc5 100644 --- a/src/cooldogedev/BedrockEconomy/database/mysql/BulkQuery.php +++ b/src/cooldogedev/BedrockEconomy/database/mysql/BulkQuery.php @@ -54,7 +54,7 @@ public function onRun(mysqli $connection): void $list = igbinary_unserialize($this->list); $params = implode(", ", array_fill(0, count($list), "?")); - $statement = $connection->prepare("SELECT *, COUNT(*) as position FROM " . $this->table . " WHERE xuid IN (" . $params . ") GROUP BY xuid, username, amount, decimals ORDER BY amount, decimals DESC"); + $statement = $connection->prepare("SELECT *, COUNT(*) as position FROM " . $this->table . " WHERE xuid IN (" . $params . ") GROUP BY xuid, username, amount ORDER BY amount"); $statement->bind_param(str_repeat("s", count($list)), ...$list); $statement->execute(); diff --git a/src/cooldogedev/BedrockEconomy/database/mysql/InsertionQuery.php b/src/cooldogedev/BedrockEconomy/database/mysql/InsertionQuery.php index 569015d..dfa11c6 100644 --- a/src/cooldogedev/BedrockEconomy/database/mysql/InsertionQuery.php +++ b/src/cooldogedev/BedrockEconomy/database/mysql/InsertionQuery.php @@ -50,6 +50,7 @@ public function __construct(private readonly int $amount, private readonly int $ */ public function onRun(mysqli $connection): void { + $amount = $this->amount . "." . $this->decimals; // start transaction $connection->begin_transaction(); @@ -68,8 +69,8 @@ public function onRun(mysqli $connection): void } // insert account - $insertionQuery = $connection->prepare("INSERT IGNORE INTO " . $this->table . " (xuid, username, amount, decimals) VALUES (?, ?, ?, ?)"); - $insertionQuery->bind_param("ssii", $this->getRef($this->xuid), $this->getRef($this->username), $this->getRef($this->amount), $this->getRef($this->decimals)); + $insertionQuery = $connection->prepare("INSERT IGNORE INTO " . $this->table . " (xuid, username, amount) VALUES (?, ?, ?)"); + $insertionQuery->bind_param("ssii", $this->getRef($this->xuid), $this->getRef($this->username), $amount); $insertionQuery->execute(); if ($insertionQuery->affected_rows === 0) { diff --git a/src/cooldogedev/BedrockEconomy/database/mysql/RetrieveQuery.php b/src/cooldogedev/BedrockEconomy/database/mysql/RetrieveQuery.php index e4fe0c9..41ea7ce 100644 --- a/src/cooldogedev/BedrockEconomy/database/mysql/RetrieveQuery.php +++ b/src/cooldogedev/BedrockEconomy/database/mysql/RetrieveQuery.php @@ -48,7 +48,7 @@ final class RetrieveQuery extends MySQLQuery */ public function onRun(mysqli $connection): void { - $statement = $connection->prepare("SELECT *, (SELECT COUNT(*) FROM " . $this->table . " WHERE amount > t.amount AND decimals > t.decimals) + 1 AS position FROM " . $this->table . " t WHERE xuid = ? OR username = ?"); + $statement = $connection->prepare("SELECT *, (SELECT COUNT(*) FROM " . $this->table . " WHERE amount > t.amount) + 1 AS position FROM " . $this->table . " t WHERE xuid = ? OR username = ?"); $statement->bind_param("ss", $this->getRef($this->xuid), $this->getRef($this->username)); $statement->execute(); diff --git a/src/cooldogedev/BedrockEconomy/database/mysql/TableQuery.php b/src/cooldogedev/BedrockEconomy/database/mysql/TableQuery.php index 13abda2..df936f1 100644 --- a/src/cooldogedev/BedrockEconomy/database/mysql/TableQuery.php +++ b/src/cooldogedev/BedrockEconomy/database/mysql/TableQuery.php @@ -40,6 +40,6 @@ final class TableQuery extends MySQLQuery public function onRun(mysqli $connection): void { - $connection->query("CREATE TABLE IF NOT EXISTS " . $this->table . " (xuid VARCHAR(32) PRIMARY KEY, username VARCHAR(32), amount BIGINT, decimals TINYINT)"); + $connection->query("CREATE TABLE IF NOT EXISTS " . $this->table . " (xuid VARCHAR(32) PRIMARY KEY, username VARCHAR(32), amount DECIMAL(64, 2))"); } } diff --git a/src/cooldogedev/BedrockEconomy/database/mysql/TopQuery.php b/src/cooldogedev/BedrockEconomy/database/mysql/TopQuery.php index f66766e..feaae14 100644 --- a/src/cooldogedev/BedrockEconomy/database/mysql/TopQuery.php +++ b/src/cooldogedev/BedrockEconomy/database/mysql/TopQuery.php @@ -49,8 +49,8 @@ public function __construct(private readonly int $limit, private readonly int $o public function onRun(mysqli $connection): void { $query = match ($this->ascending) { - true => "SELECT * FROM " . $this->table . " ORDER BY amount ASC, decimals ASC LIMIT ? OFFSET ?", - false => "SELECT * FROM " . $this->table . " ORDER BY amount DESC, decimals DESC LIMIT ? OFFSET ?" + true => "SELECT * FROM " . $this->table . " ORDER BY amount LIMIT ? OFFSET ?", + false => "SELECT * FROM " . $this->table . " ORDER BY amount DESC LIMIT ? OFFSET ?" }; $statement = $connection->prepare($query); diff --git a/src/cooldogedev/BedrockEconomy/database/mysql/TransferQuery.php b/src/cooldogedev/BedrockEconomy/database/mysql/TransferQuery.php index e720f85..9393134 100644 --- a/src/cooldogedev/BedrockEconomy/database/mysql/TransferQuery.php +++ b/src/cooldogedev/BedrockEconomy/database/mysql/TransferQuery.php @@ -58,6 +58,7 @@ public function __construct( */ public function onRun(mysqli $connection): void { + $amount = $this->amount . "." . $this->decimals; $connection->begin_transaction(); // check if the source account exists @@ -89,8 +90,8 @@ public function onRun(mysqli $connection): void } // subtract the money from the source account - $sourceUpdateQuery = $connection->prepare("UPDATE " . $this->table . " SET amount = amount - ?, decimals = ? WHERE (xuid = ? OR username = ?) AND amount >= ? AND decimals >= ?"); - $sourceUpdateQuery->bind_param("iissii", $this->getRef($this->amount), $this->getRef($this->decimals), $this->getRef($this->xuid), $this->getRef($this->username), $this->getRef($this->amount), $this->getRef($this->decimals)); + $sourceUpdateQuery = $connection->prepare("UPDATE " . $this->table . " SET amount = amount - ? WHERE (xuid = ? OR username = ?) AND amount >= ?"); + $sourceUpdateQuery->bind_param("issi", $amount, $this->getRef($this->xuid), $this->getRef($this->username), $amount); $sourceUpdateQuery->execute(); if ($sourceUpdateQuery->affected_rows === 0) { @@ -101,8 +102,8 @@ public function onRun(mysqli $connection): void } // add the money to the target account - $targetUpdateQuery = $connection->prepare("UPDATE " . $this->table . " SET amount = amount + ?, decimals = ? WHERE xuid = ? OR username = ?"); - $targetUpdateQuery->bind_param("iiss", $this->getRef($this->amount), $this->getRef($this->decimals), $this->getRef($this->targetXuid), $this->getRef($this->targetUsername)); + $targetUpdateQuery = $connection->prepare("UPDATE " . $this->table . " SET amount = amount + ? WHERE xuid = ? OR username = ?"); + $targetUpdateQuery->bind_param("iss", $amount, $this->getRef($this->targetXuid), $this->getRef($this->targetUsername)); $targetUpdateQuery->execute(); if ($targetUpdateQuery->affected_rows === 0) { diff --git a/src/cooldogedev/BedrockEconomy/database/mysql/UpdateQuery.php b/src/cooldogedev/BedrockEconomy/database/mysql/UpdateQuery.php index 71a5dbf..7379a5c 100644 --- a/src/cooldogedev/BedrockEconomy/database/mysql/UpdateQuery.php +++ b/src/cooldogedev/BedrockEconomy/database/mysql/UpdateQuery.php @@ -54,6 +54,7 @@ public function __construct(private readonly int $mode, private readonly int $am */ public function onRun(mysqli $connection): void { + $amount = $this->amount . "." . $this->decimals; $connection->begin_transaction(); // check if account exists @@ -71,9 +72,9 @@ public function onRun(mysqli $connection): void } $updateQuery = match ($this->mode) { - UpdateMode::ADD => "UPDATE " . $this->table . " SET amount = amount + ?, decimals = decimals + ? WHERE xuid = ? OR username = ?", - UpdateMode::SUBTRACT => "UPDATE " . $this->table . " SET amount = amount - ?, decimals = decimals - ? WHERE (xuid = ? OR username = ?) AND amount >= ? AND decimals >= ?", - UpdateMode::SET => "UPDATE " . $this->table . " SET amount = ?, decimals = ? WHERE xuid = ? OR username = ?", + UpdateMode::ADD => "UPDATE " . $this->table . " SET amount = amount + ? WHERE xuid = ? OR username = ?", + UpdateMode::SUBTRACT => "UPDATE " . $this->table . " SET amount = amount - ? WHERE (xuid = ? OR username = ?) AND amount >= ?", + UpdateMode::SET => "UPDATE " . $this->table . " SET amount = ? WHERE xuid = ? OR username = ?", default => throw new InvalidArgumentException("Invalid mode " . $this->mode) }; @@ -82,9 +83,9 @@ public function onRun(mysqli $connection): void $updateQuery = $connection->prepare($updateQuery); if ($this->mode === UpdateMode::SUBTRACT) { - $updateQuery->bind_param("iissii", $this->getRef($this->amount), $this->getRef($this->decimals), $this->getRef($this->xuid), $this->getRef($this->username), $this->getRef($this->amount), $this->getRef($this->decimals)); + $updateQuery->bind_param("issi", $amount, $this->getRef($this->xuid), $this->getRef($this->username), $amount); } else { - $updateQuery->bind_param("iiss", $this->getRef($this->amount), $this->getRef($this->decimals), $this->getRef($this->xuid), $this->getRef($this->username)); + $updateQuery->bind_param("iss", $amount, $this->getRef($this->xuid), $this->getRef($this->username)); } $updateQuery->execute(); diff --git a/src/cooldogedev/BedrockEconomy/database/sqlite/BulkQuery.php b/src/cooldogedev/BedrockEconomy/database/sqlite/BulkQuery.php index 8b340a8..3550348 100644 --- a/src/cooldogedev/BedrockEconomy/database/sqlite/BulkQuery.php +++ b/src/cooldogedev/BedrockEconomy/database/sqlite/BulkQuery.php @@ -54,7 +54,7 @@ public function onRun(SQLite3 $connection): void $list = igbinary_unserialize($this->list); $params = implode(", ", array_fill(0, count($list), "?")); - $statement = $connection->prepare("SELECT *, ROW_NUMBER() OVER (ORDER BY amount, decimals DESC) as position FROM " . $this->table . " WHERE xuid IN (" . $params . ")"); + $statement = $connection->prepare("SELECT *, ROW_NUMBER() OVER (ORDER BY amount DESC) as position FROM " . $this->table . " WHERE xuid IN (" . $params . ")"); for ($i = 0; $i < count($list); $i++) { $statement->bindValue($i + 1, $list[$i]); diff --git a/src/cooldogedev/BedrockEconomy/database/sqlite/InsertionQuery.php b/src/cooldogedev/BedrockEconomy/database/sqlite/InsertionQuery.php index 3263b7a..bb0b870 100644 --- a/src/cooldogedev/BedrockEconomy/database/sqlite/InsertionQuery.php +++ b/src/cooldogedev/BedrockEconomy/database/sqlite/InsertionQuery.php @@ -48,6 +48,7 @@ public function __construct(private readonly int $amount, private readonly int $ */ public function onRun(SQLite3 $connection): void { + $amount = $this->amount . "." . $this->decimals; $connection->exec("BEGIN TRANSACTION"); // check if account exists @@ -63,11 +64,10 @@ public function onRun(SQLite3 $connection): void ); } - $insertionQuery = $connection->prepare("INSERT OR IGNORE INTO " . $this->table . " (xuid, username, amount, decimals) VALUES (?, ?, ?, ?)"); + $insertionQuery = $connection->prepare("INSERT OR IGNORE INTO " . $this->table . " (xuid, username, amount) VALUES (?, ?, ?)"); $insertionQuery->bindValue(1, $this->xuid); $insertionQuery->bindValue(2, $this->username); - $insertionQuery->bindValue(3, $this->amount, SQLITE3_INTEGER); - $insertionQuery->bindValue(4, $this->decimals, SQLITE3_INTEGER); + $insertionQuery->bindValue(3, $amount); $insertionQuery->execute(); if ($connection->changes() === 0) { diff --git a/src/cooldogedev/BedrockEconomy/database/sqlite/RetrieveQuery.php b/src/cooldogedev/BedrockEconomy/database/sqlite/RetrieveQuery.php index 362c94a..039729d 100644 --- a/src/cooldogedev/BedrockEconomy/database/sqlite/RetrieveQuery.php +++ b/src/cooldogedev/BedrockEconomy/database/sqlite/RetrieveQuery.php @@ -46,7 +46,7 @@ final class RetrieveQuery extends SQLiteQuery */ public function onRun(SQLite3 $connection): void { - $statement = $connection->prepare("SELECT *, ROW_NUMBER() OVER (ORDER BY amount, decimals DESC) as position FROM " . $this->table . " WHERE xuid = ? OR username = ?"); + $statement = $connection->prepare("SELECT *, ROW_NUMBER() OVER (ORDER BY amount) as position FROM " . $this->table . " WHERE xuid = ? OR username = ?"); $statement->bindValue(1, $this->xuid); $statement->bindValue(2, $this->username); diff --git a/src/cooldogedev/BedrockEconomy/database/sqlite/TableQuery.php b/src/cooldogedev/BedrockEconomy/database/sqlite/TableQuery.php index 3692411..0aa2ccd 100644 --- a/src/cooldogedev/BedrockEconomy/database/sqlite/TableQuery.php +++ b/src/cooldogedev/BedrockEconomy/database/sqlite/TableQuery.php @@ -40,6 +40,6 @@ final class TableQuery extends SQLiteQuery public function onRun(SQLite3 $connection): void { - $connection->exec("CREATE TABLE IF NOT EXISTS " . $this->table . " (xuid VARCHAR(32) PRIMARY KEY, username VARCHAR(32) COLLATE NOCASE, amount BIGINT, decimals TINYINT)"); + $connection->exec("CREATE TABLE IF NOT EXISTS " . $this->table . " (xuid VARCHAR(32) PRIMARY KEY, username VARCHAR(32) COLLATE NOCASE, amount NUMERIC(64, 2))"); } } diff --git a/src/cooldogedev/BedrockEconomy/database/sqlite/TopQuery.php b/src/cooldogedev/BedrockEconomy/database/sqlite/TopQuery.php index 1e25da7..3f73ce7 100644 --- a/src/cooldogedev/BedrockEconomy/database/sqlite/TopQuery.php +++ b/src/cooldogedev/BedrockEconomy/database/sqlite/TopQuery.php @@ -47,8 +47,8 @@ public function __construct(private readonly int $limit, private readonly int $o public function onRun(SQLite3 $connection): void { $query = match ($this->ascending) { - true => "SELECT * FROM " . $this->table . " ORDER BY amount ASC, decimals ASC LIMIT ? OFFSET ?", - false => "SELECT * FROM " . $this->table . " ORDER BY amount DESC, decimals DESC LIMIT ? OFFSET ?" + true => "SELECT * FROM " . $this->table . " ORDER BY amount LIMIT ? OFFSET ?", + false => "SELECT * FROM " . $this->table . " ORDER BY amount DESC LIMIT ? OFFSET ?" }; $statement = $connection->prepare($query); diff --git a/src/cooldogedev/BedrockEconomy/database/sqlite/TransferQuery.php b/src/cooldogedev/BedrockEconomy/database/sqlite/TransferQuery.php index 3fdd6a2..67c8cf5 100644 --- a/src/cooldogedev/BedrockEconomy/database/sqlite/TransferQuery.php +++ b/src/cooldogedev/BedrockEconomy/database/sqlite/TransferQuery.php @@ -56,6 +56,7 @@ public function __construct( */ public function onRun(SQLite3 $connection): void { + $amount = $this->amount . "." . $this->decimals; $connection->exec("BEGIN TRANSACTION"); // check if the source account exists @@ -87,13 +88,11 @@ public function onRun(SQLite3 $connection): void } // subtract the money from the source account - $sourceUpdateQuery = $connection->prepare("UPDATE " . $this->table . " SET amount = amount - ?, decimals = decimals - ? WHERE (xuid = ? OR username = ?) AND amount >= ? AND decimals >= ?"); - $sourceUpdateQuery->bindValue(1, $this->amount, SQLITE3_INTEGER); - $sourceUpdateQuery->bindValue(2, $this->decimals, SQLITE3_INTEGER); - $sourceUpdateQuery->bindValue(3, $this->xuid); - $sourceUpdateQuery->bindValue(4, $this->username); - $sourceUpdateQuery->bindValue(5, $this->amount, SQLITE3_INTEGER); - $sourceUpdateQuery->bindValue(6, $this->decimals, SQLITE3_INTEGER); + $sourceUpdateQuery = $connection->prepare("UPDATE " . $this->table . " SET amount = amount - ? WHERE (xuid = ? OR username = ?) AND amount >= ?"); + $sourceUpdateQuery->bindValue(1, $amount); + $sourceUpdateQuery->bindValue(2, $this->xuid); + $sourceUpdateQuery->bindValue(3, $this->username); + $sourceUpdateQuery->bindValue(4, $amount); $sourceUpdateResult = $sourceUpdateQuery->execute(); @@ -105,11 +104,10 @@ public function onRun(SQLite3 $connection): void } // add the money to the target account - $targetUpdateQuery = $connection->prepare("UPDATE " . $this->table . " SET amount = amount + ?, decimals = decimals + ? WHERE xuid = ? OR username = ?"); - $targetUpdateQuery->bindValue(1, $this->amount, SQLITE3_INTEGER); - $targetUpdateQuery->bindValue(2, $this->decimals, SQLITE3_INTEGER); - $targetUpdateQuery->bindValue(3, $this->targetXuid); - $targetUpdateQuery->bindValue(4, $this->targetUsername); + $targetUpdateQuery = $connection->prepare("UPDATE " . $this->table . " SET amount = amount + ? WHERE xuid = ? OR username = ?"); + $targetUpdateQuery->bindValue(1, $amount); + $targetUpdateQuery->bindValue(2, $this->targetXuid); + $targetUpdateQuery->bindValue(3, $this->targetUsername); $targetUpdateResult = $targetUpdateQuery->execute(); diff --git a/src/cooldogedev/BedrockEconomy/database/sqlite/UpdateQuery.php b/src/cooldogedev/BedrockEconomy/database/sqlite/UpdateQuery.php index 30f46d5..fb71f99 100644 --- a/src/cooldogedev/BedrockEconomy/database/sqlite/UpdateQuery.php +++ b/src/cooldogedev/BedrockEconomy/database/sqlite/UpdateQuery.php @@ -52,6 +52,7 @@ public function __construct(private readonly int $mode, private readonly int $am */ public function onRun(SQLite3 $connection): void { + $amount = $this->amount . "." . $this->decimals; $connection->exec("BEGIN TRANSACTION"); // check if account exists @@ -69,23 +70,21 @@ public function onRun(SQLite3 $connection): void } $updateQuery = match ($this->mode) { - UpdateMode::ADD => "UPDATE " . $this->table . " SET amount = amount + ?, decimals = decimals + ? WHERE xuid = ? OR username = ?", - UpdateMode::SUBTRACT => "UPDATE " . $this->table . " SET amount = amount - ?, decimals = decimals - ? WHERE (xuid = ? OR username = ?) AND amount >= ? AND decimals >= ?", - UpdateMode::SET => "UPDATE " . $this->table . " SET amount = ?, decimals = ? WHERE xuid = ? OR username = ?", + UpdateMode::ADD => "UPDATE " . $this->table . " SET amount = amount + ? WHERE xuid = ? OR username = ?", + UpdateMode::SUBTRACT => "UPDATE " . $this->table . " SET amount = amount - ? WHERE (xuid = ? OR username = ?) AND amount >= ?", + UpdateMode::SET => "UPDATE " . $this->table . " SET amount = ? WHERE xuid = ? OR username = ?", default => throw new InvalidArgumentException("Invalid mode " . $this->mode) }; // update account $updateQuery = $connection->prepare($updateQuery); - $updateQuery->bindValue(1, $this->amount, SQLITE3_INTEGER); - $updateQuery->bindValue(2, $this->decimals, SQLITE3_INTEGER); - $updateQuery->bindValue(3, $this->xuid); - $updateQuery->bindValue(4, $this->username); + $updateQuery->bindValue(1, $amount); + $updateQuery->bindValue(2, $this->xuid); + $updateQuery->bindValue(3, $this->username); if ($this->mode === UpdateMode::SUBTRACT) { - $updateQuery->bindValue(5, $this->amount, SQLITE3_INTEGER); - $updateQuery->bindValue(6, $this->decimals, SQLITE3_INTEGER); + $updateQuery->bindValue(4, $amount); } $updateResult = $updateQuery->execute();