GenerateChestJsonCommand.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <?php
  2. namespace App\Module\GameItems\Commands;
  3. use App\Module\Game\DCache\ChestJsonConfig;
  4. use App\Module\GameItems\Config\NumericAttributesWhitelist;
  5. use App\Module\GameItems\Enums\ITEM_TYPE;
  6. use App\Module\GameItems\Models\ItemChestConfig;
  7. use Illuminate\Console\Command;
  8. use App\Module\GameItems\Models\Item;
  9. use UCore\Helper\Logger;
  10. /**
  11. * 生成宝箱JSON数据命令
  12. *
  13. * 该命令用于从数据库中的宝箱相关表生成宝箱JSON数据文件,供客户端使用。
  14. * 生成的JSON文件包含宝箱的基本信息和内容配置,如宝箱ID、可能获得的物品及其概率等。
  15. * 该命令通常在宝箱配置更新后运行,以确保客户端获取最新的宝箱数据。
  16. */
  17. class GenerateChestJsonCommand extends Command
  18. {
  19. /**
  20. * 命令名称和签名
  21. *
  22. * @var string
  23. */
  24. protected $signature = 'gameitems:generate-chest-json';
  25. /**
  26. * 命令描述
  27. *
  28. * @var string
  29. */
  30. protected $description = 'Generate chest.json from Item-chest table';
  31. /**
  32. * 执行命令
  33. */
  34. /**
  35. * 生成宝箱JSON数据
  36. *
  37. * @param bool $saveToFile 是否保存到文件
  38. * @return array|bool 生成的数据或失败标志
  39. */
  40. public static function generateJson()
  41. {
  42. try {
  43. // 查询Item表中的宝箱数据,使用新的组系统
  44. $chests = Item::query()
  45. ->where('type', ITEM_TYPE::CHEST)
  46. ->with([
  47. 'chestConfig' => function ($query) {
  48. $query->where('is_active', true)
  49. ->with([
  50. 'consumeGroup.consumeItems',
  51. 'rewardGroup.rewardItems',
  52. 'conditionGroup'
  53. ]);
  54. }
  55. ])
  56. ->select(['id', 'name', 'numeric_attributes'])
  57. ->get();
  58. // 处理数据,去除不必要的字段
  59. $processedChests = $chests->map(function (Item $chest) {
  60. // 检查宝箱是否有配置数据
  61. if (!$chest->chestConfig) {
  62. Logger::error("跳过物品 {$chest->id} ,没有宝箱配置");
  63. return null; // 跳过没有配置的宝箱
  64. }
  65. // 获取激活的配置(应该只有一个)
  66. $config = $chest->chestConfig;
  67. if (!$config || !$config->rewardGroup) {
  68. Logger::error("跳过宝箱 {$chest->id} ,没有奖励组");
  69. return null; // 跳过没有奖励组的宝箱
  70. }
  71. $chestData = [
  72. 'id' => $chest->id,
  73. 'name' => $chest->name,
  74. 'desc' => $chest->description,
  75. ];
  76. // 处理宝箱内容(从奖励组获取)
  77. $contents = [];
  78. if ($config->rewardGroup && $config->rewardGroup->rewardItems) {
  79. foreach ($config->rewardGroup->rewardItems as $rewardItem) {
  80. // 转换为 Proto 对象
  81. $rewardProtoObject = $rewardItem->toRewardObject();
  82. $contentData= json_decode($rewardProtoObject->serializeToJsonString(),true);
  83. $contents[] = $contentData;
  84. }
  85. }
  86. // 检查处理后的内容是否为空
  87. if (empty($contents)) {
  88. Logger::error("跳过宝箱 {$chest->id} ,没有奖励内容");
  89. return null; // 如果没有有效的内容,跳过这个宝箱
  90. }
  91. $chestData['contents'] = $contents;
  92. // 处理宝箱开启消耗(从消耗组获取)
  93. $costs = [];
  94. if ($config->consumeGroup && $config->consumeGroup->consumeItems) {
  95. foreach ($config->consumeGroup->consumeItems as $consumeItem) {
  96. // 转换为 Proto 对象
  97. $consumeProtoObject = $consumeItem->toDeductObject();
  98. $costData= json_decode($consumeProtoObject->serializeToJsonString(),true);
  99. $costs[] = $costData;
  100. }
  101. }
  102. $chestData['costs'] = $costs;
  103. return $chestData;
  104. })
  105. ->filter() // 过滤掉返回值为null的宝箱
  106. ->toArray();
  107. // 准备完整数据,包含生成时间
  108. $data = [
  109. 'generated_ts' => time(),
  110. 'chests' => $processedChests
  111. ];
  112. return $data;
  113. } catch (\Exception $e) {
  114. // 不使用Log,直接输出到控制台
  115. echo 'Generate chest.json failed: ' . $e->getMessage() . "\n";
  116. echo $e->getTraceAsString() . "\n";
  117. return false;
  118. }
  119. }
  120. /**
  121. * 执行命令
  122. *
  123. * @return int
  124. */
  125. public function handle()
  126. {
  127. $this->info('Generating chest JSON data...');
  128. $result = ChestJsonConfig::getData([], true);
  129. if ($result && isset($result['chests'])) {
  130. $chestCount = count($result['chests']);
  131. $contentCount = 0;
  132. $costCount = 0;
  133. foreach ($result['chests'] as $chest) {
  134. $contentCount += count($chest['contents'] ?? []);
  135. $costCount += count($chest['costs'] ?? []);
  136. }
  137. $this->info('Successfully generated chest.json with timestamp');
  138. $this->info("Processed {$chestCount} chests with {$contentCount} content items and {$costCount} cost items");
  139. return 0; // 成功
  140. } else {
  141. $this->error('Failed to generate chest.json');
  142. return 1; // 失败
  143. }
  144. }
  145. }