first(); if (! $user) { return Command::SUCCESS; } // 3. 常规心跳经验与金币发放 // (模拟前端每30-60秒发一次心跳的过程,此处每分钟跑一次,发放单人心跳奖励) $expGain = $this->parseRewardValue(Sysparam::getValue('exp_per_heartbeat', '1')); if ($expGain > 0) { $expMultiplier = $this->vipService->getExpMultiplier($user); $actualExpGain = (int) round($expGain * $expMultiplier); $user->exp_num += $actualExpGain; } $jjbGain = $this->parseRewardValue(Sysparam::getValue('jjb_per_heartbeat', '0')); if ($jjbGain > 0) { $jjbMultiplier = $this->vipService->getJjbMultiplier($user); $actualJjbGain = (int) round($jjbGain * $jjbMultiplier); $user->jjb = ($user->jjb ?? 0) + $actualJjbGain; } $user->save(); $user->refresh(); // 4. 重算等级(基础心跳升级) $superLevel = (int) Sysparam::getValue('superlevel', '100'); $leveledUp = $this->calculateNewLevel($user, $superLevel); // 5. 随机事件触发 $eventChance = (int) Sysparam::getValue('auto_event_chance', '10'); if ($eventChance > 0 && rand(1, 100) <= $eventChance) { $autoEvent = Autoact::randomEvent(); if ($autoEvent) { // 执行随机事件的金钱经验惩奖 if ($autoEvent->exp_change !== 0) { $this->currencyService->change( $user, 'exp', $autoEvent->exp_change, CurrencySource::AUTO_EVENT, "随机事件:{$autoEvent->text_body}", 1 ); } if ($autoEvent->jjb_change !== 0) { $this->currencyService->change( $user, 'gold', $autoEvent->jjb_change, CurrencySource::AUTO_EVENT, "随机事件:{$autoEvent->text_body}", 1 ); } $user->refresh(); // 重新计算等级 if ($this->calculateNewLevel($user, $superLevel)) { $leveledUp = true; } // 广播随机事件 $this->broadcastSystemMessage( '星海小博士', $autoEvent->renderText($user->username), match ($autoEvent->event_type) { 'good' => '#16a34a', 'bad' => '#dc2626', default => '#7c3aed', } ); } } // 6. 如果由于心跳或事件导致了升级,广播升级消息 if ($leveledUp) { $this->broadcastSystemMessage( '系统传音', "🌟 天道酬勤!恭喜侠客【{$user->username}】挂机苦修,境界突破至 LV.{$user->user_level}!", '#d97706', '大声宣告' ); } return Command::SUCCESS; } /** * 计算并更新用户等级 */ private function calculateNewLevel(User $user, int $superLevel): bool { $oldLevel = $user->user_level; if ($oldLevel >= $superLevel) { return false; // 管理员不自动升降级 } $newLevel = Sysparam::calculateLevel($user->exp_num); if ($newLevel !== $oldLevel && $newLevel < $superLevel) { $user->user_level = $newLevel; $user->save(); return $newLevel > $oldLevel; } return false; } /** * 解析配置的奖励范围,如 "1" 或 "1-5" */ private function parseRewardValue(string $raw): int { $raw = trim($raw); if (str_contains($raw, '-')) { [$min, $max] = explode('-', $raw, 2); return rand((int) $min, (int) $max); } return (int) $raw; } /** * 往所有活跃房间发送系统广播消息 */ private function broadcastSystemMessage(string $fromUser, string $content, string $color, string $action = ''): void { $activeRoomIds = $this->chatState->getAllActiveRoomIds(); if (empty($activeRoomIds)) { $activeRoomIds = [1]; } foreach ($activeRoomIds as $roomId) { $sysMsg = [ 'id' => $this->chatState->nextMessageId($roomId), 'room_id' => $roomId, 'from_user' => $fromUser, 'to_user' => '大家', 'content' => $content, 'is_secret' => false, 'font_color' => $color, 'action' => $action, 'sent_at' => now()->toDateTimeString(), ]; $this->chatState->pushMessage($roomId, $sysMsg); broadcast(new MessageSent($roomId, $sysMsg)); SaveMessageJob::dispatch($sysMsg); } } }