| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- <?php
- namespace App\Module\GameItems\Commands;
- use App\Module\Game\DCache\ChestJsonConfig;
- use App\Module\Game\DCache\ItemJsonConfig;
- use App\Module\GameItems\Enums\CHEST_COST_TYPE;
- use App\Module\GameItems\Enums\ITEM_TYPE;
- use Illuminate\Console\Command;
- use App\Module\GameItems\Models\Item;
- use Illuminate\Support\Facades\File;
- use Illuminate\Support\Facades\Log;
- /**
- * 生成宝箱JSON数据命令
- *
- * 该命令用于从数据库中的宝箱相关表生成宝箱JSON数据文件,供客户端使用。
- * 生成的JSON文件包含宝箱的基本信息和内容配置,如宝箱ID、可能获得的物品及其概率等。
- * 该命令通常在宝箱配置更新后运行,以确保客户端获取最新的宝箱数据。
- */
- class GenerateChestJsonCommand extends Command
- {
- /**
- * 命令名称和签名
- *
- * @var string
- */
- protected $signature = 'gameitems:generate-chest-json';
- /**
- * 命令描述
- *
- * @var string
- */
- protected $description = 'Generate chest.json from Item-chest table';
- /**
- * 执行命令
- */
- /**
- * 生成宝箱JSON数据
- *
- * @param bool $saveToFile 是否保存到文件
- * @return array|bool 生成的数据或失败标志
- */
- public static function generateJson(bool $saveToFile = true)
- {
- try {
- // 查询Item表中的宝箱数据
- $chests = Item::query()
- ->where('type', ITEM_TYPE::CHEST)
- ->with([
- 'chest_contents' => function ($query) {
- $query->select([
- 'id', 'chest_id', 'item_id', 'group_id',
- 'min_quantity', 'max_quantity', 'weight'
- ])
- ->where('weight', '>', 0)
- ->with([
- 'item' => function ($query) {
- $query->select(['id', 'name']);
- },
- 'group' => function ($query) {
- $query->select(['id', 'name']);
- }
- ]);
- },
- 'chest_costs' => function ($query) {
- $query->select([
- 'id', 'chest_id', 'cost_type', 'cost_id', 'cost_quantity'
- ])
- ->where('is_active', true)
- ->with([
- 'costItem' => function ($query) {
- $query->select(['id', 'name']);
- }
- ]);
- }
- ])
- ->select(['id', 'name', 'item_id','numeric_attributes'])
- ->get();
- // 处理数据,去除不必要的字段
- $processedChests = $chests->map(function ($chest) {
- $chestData = [
- 'id' => $chest->id,
- 'name' => $chest->name,
- ];
- // 添加宝箱数值属性中的必要字段
- if (!empty($chest->numeric_attributes)) {
- $numericAttrs = $chest->numeric_attributes;
- if (isset($numericAttrs->min_drop_count)) {
- $chestData['min_drop_count'] = $numericAttrs->min_drop_count;
- }
- if (isset($numericAttrs->max_drop_count)) {
- $chestData['max_drop_count'] = $numericAttrs->max_drop_count;
- }
- }
- // 处理宝箱内容
- $chestData['contents'] = $chest->chest_contents->map(function ($content) {
- $contentData = [
- 'id' => $content->id,
- 'weight' => $content->weight,
- 'min_quantity' => $content->min_quantity,
- 'max_quantity' => $content->max_quantity,
- ];
- // 根据是物品还是物品组添加不同的字段
- if ($content->item_id && $content->item) {
- $contentData['item_id'] = $content->item_id;
- $contentData['item_name'] = $content->item->name;
- $contentData['type'] = 'item';
- } elseif ($content->group_id && $content->group) {
- $contentData['group_id'] = $content->group_id;
- $contentData['group_name'] = $content->group->name;
- $contentData['type'] = 'group';
- }
- return $contentData;
- })->toArray();
- // 处理宝箱开启消耗
- $chestData['costs'] = $chest->chest_costs->map(function ($cost) {
- $costData = [
- 'cost_type' => $cost->cost_type,
- 'cost_id' => $cost->cost_id,
- 'cost_quantity' => $cost->cost_quantity,
- ];
- // 如果是物品消耗,添加物品名称
- if ($cost->cost_type == CHEST_COST_TYPE::ITEM->value && $cost->costItem) {
- $costData['item_name'] = $cost->costItem->name;
- }
- return $costData;
- })->toArray();
- return $chestData;
- })->toArray();
- // 准备完整数据,包含生成时间
- $data = [
- 'generated_at' => now()->toDateTimeString(),
- 'chests' => $processedChests
- ];
- // 如果需要保存到文件
- if ($saveToFile) {
- self::saveJsonToFile($data);
- }
- return $data;
- } catch (\Exception $e) {
- // 不使用Log,直接输出到控制台
- echo 'Generate chest.json failed: ' . $e->getMessage() . "\n";
- echo $e->getTraceAsString() . "\n";
- return false;
- }
- }
- /**
- * 将JSON数据保存到文件
- *
- * @param array $data 要保存的数据
- * @return bool 是否保存成功
- */
- protected static function saveJsonToFile(array $data): bool
- {
- try {
- // 确保目录存在
- $directory = 'public/json';
- if (!File::exists($directory)) {
- File::makeDirectory($directory, 0755, true);
- }
- // 将数据保存为JSON文件
- $jsonContent = json_encode($data, JSON_UNESCAPED_UNICODE);
- $filePath = $directory . '/chest.json';
- File::put($filePath, $jsonContent);
- // 同时生成一个格式化的版本供开发者查看
- $prettyJsonContent = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
- $prettyFilePath = $directory . '/chest_pretty.json';
- File::put($prettyFilePath, $prettyJsonContent);
- // 不使用Log,直接输出到控制台
- echo 'Chest JSON files saved to: ' . $filePath . ' and ' . $prettyFilePath . "\n";
- return true;
- } catch (\Exception $e) {
- // 不使用Log,直接输出到控制台
- echo 'Save chest.json to file failed: ' . $e->getMessage() . "\n";
- echo $e->getTraceAsString() . "\n";
- return false;
- }
- }
- /**
- * 执行命令
- *
- * @return int
- */
- public function handle()
- {
- $this->info('Generating chest JSON data...');
- $result = ChestJsonConfig::getData([], true);
- if ($result && isset($result['chests'])) {
- $chestCount = count($result['chests']);
- $contentCount = 0;
- $costCount = 0;
- foreach ($result['chests'] as $chest) {
- $contentCount += count($chest['contents'] ?? []);
- $costCount += count($chest['costs'] ?? []);
- }
- $this->info('Successfully generated chest.json with timestamp');
- $this->info("Processed {$chestCount} chests with {$contentCount} content items and {$costCount} cost items");
- $this->info('JSON files saved to:');
- $this->info('- public/json/chest.json (compact version)');
- $this->info('- public/json/chest_pretty.json (formatted version for development)');
- return 0; // 成功
- } else {
- $this->error('Failed to generate chest.json');
- return 1; // 失败
- }
- }
- }
|