140 lines
4.2 KiB
PHP
140 lines
4.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\User;
|
|
use App\Models\UserQuest;
|
|
use App\Traits\BaseApiResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Str;
|
|
|
|
class LeagueController extends Controller
|
|
{
|
|
use BaseApiResponse;
|
|
|
|
/**
|
|
* API 1: User League Stats
|
|
*/
|
|
public function stats(Request $request)
|
|
{
|
|
$user = $request->user();
|
|
|
|
// Dynamic Level Calculation (Every 500 XP = 1 Level)
|
|
$level = floor($user->xp / 500) + 1;
|
|
$xpToNext = 500 - ($user->xp % 500);
|
|
$progress = ($user->xp % 500) / 500;
|
|
|
|
$winRate = $user->duels_played > 0
|
|
? round(($user->duels_won / $user->duels_played) * 100)
|
|
: 0;
|
|
|
|
// Calculate Global Rank Position
|
|
$rankPosition = User::where('xp', '>', $user->xp)->count() + 1;
|
|
|
|
$data = [
|
|
'user_id' => $user->id,
|
|
'name' => $user->name ?? 'کاربر',
|
|
'current_level' => $level,
|
|
'rank_name' => $this->getRankName($level),
|
|
'total_xp' => $user->xp,
|
|
'xp_to_next_level' => $xpToNext,
|
|
'progress_percent' => round($progress, 2),
|
|
'win_rate_percent' => $winRate,
|
|
'total_duels' => $user->duels_played,
|
|
'global_rank_position' => $rankPosition
|
|
];
|
|
|
|
return $this->success($data, 'موفق', 'اطلاعات لیگ کاربر دریافت شد');
|
|
}
|
|
|
|
/**
|
|
* API 2: Daily Quests
|
|
*/
|
|
public function quests(Request $request)
|
|
{
|
|
$user = $request->user();
|
|
|
|
// Fetch active quests for today using the new relationship
|
|
$userQuests = $user->activeQuests()->with('quest')->get();
|
|
|
|
$formattedQuests = $userQuests->map(function ($uq) {
|
|
return [
|
|
'id' => $uq->id,
|
|
'title' => $uq->quest->title,
|
|
'current_progress' => $uq->current_progress,
|
|
'required_amount' => $uq->quest->required_amount,
|
|
'reward_text' => '+' . $uq->quest->reward_xp . ' XP',
|
|
'is_completed' => $uq->is_completed
|
|
];
|
|
});
|
|
|
|
$expiresIn = now()->endOfDay()->diffInSeconds(now());
|
|
|
|
return $this->success([
|
|
'expires_in_seconds' => $expiresIn,
|
|
'quests' => $formattedQuests
|
|
], 'موفق', 'چالشهای روزانه دریافت شد');
|
|
}
|
|
|
|
/**
|
|
* API 3: League Leaderboard
|
|
*/
|
|
public function leaderboard(Request $request)
|
|
{
|
|
$currentUser = $request->user();
|
|
|
|
// Get Top 50 Users
|
|
$topUsers = User::orderByDesc('xp')->limit(50)->get(['id', 'name', 'xp']);
|
|
|
|
$leaderboard = $topUsers->map(function ($u, $index) use ($currentUser) {
|
|
return [
|
|
'rank' => $index + 1,
|
|
'user_id' => $u->id,
|
|
'name' => $u->name ?? 'کاربر ناشناس',
|
|
'xp' => $u->xp,
|
|
'is_me' => $u->id === $currentUser->id
|
|
];
|
|
});
|
|
|
|
// Current User Data
|
|
$myRank = User::where('xp', '>', $currentUser->xp)->count() + 1;
|
|
|
|
$myStats = [
|
|
'rank' => $myRank,
|
|
'user_id' => $currentUser->id,
|
|
'name' => $currentUser->name ?? 'شما',
|
|
'xp' => $currentUser->xp,
|
|
'is_me' => true
|
|
];
|
|
|
|
return $this->success([
|
|
'leaderboard' => $leaderboard,
|
|
'current_user' => $myStats
|
|
], 'موفق', 'جدول ردهبندی دریافت شد');
|
|
}
|
|
|
|
/**
|
|
* API 4: PvP Matchmaking Entry
|
|
*/
|
|
public function matchmake(Request $request)
|
|
{
|
|
$ticketId = 'req_' . Str::random(12);
|
|
|
|
return $this->success([
|
|
'matchmaking_ticket_id' => $ticketId,
|
|
'status' => 'searching',
|
|
'websocket_channel' => 'private-matchmaking.' . $ticketId,
|
|
'estimated_wait_seconds' => 15
|
|
], 'در حال جستجو', 'به صف انتظار دوئل اضافه شدید');
|
|
}
|
|
|
|
private function getRankName($level)
|
|
{
|
|
if ($level >= 50) return 'الماس';
|
|
if ($level >= 30) return 'طلا';
|
|
if ($level >= 10) return 'نقرهای';
|
|
return 'برنز';
|
|
}
|
|
}
|