ter = array_value($config, 'filter'); $arr = array_value($filter, $type); $enable = array_value($arr, 'enable'); $wordarr = array_value($arr, 'keyword'); if (0 == $enable || empty($wordarr)) return FALSE; foreach ($wordarr as $_keyword) { if (!$_keyword) continue; $r = strpos(strtolower($keyword), strtolower($_keyword)); if (FALSE !== $r) { $error = $_keyword; return TRUE; } } return FALSE; } // return http://domain.com OR https://domain.com function url_prefix() { $http = ((isset($_SERVER['HTTPS']) && 'on' == $_SERVER['HTTPS']) || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://'; return $http . $_SERVER['HTTP_HOST']; } // 唯一身份ID function uniq_id() { return uniqid(substr(md5(microtime(true) . mt_rand(1000, 9999)), 8, 8)); } // 生成订单号 14位 function trade_no() { $trade_no = str_replace('.', '', microtime(1)); $strlen = mb_strlen($trade_no, 'UTF-8'); $strlen = 14 - $strlen; $str = ''; if ($strlen) { for ($i = 0; $i <= $strlen; $i++) { if ($i < $strlen) $str .= '0'; } } return $trade_no . $str; } // 生成订单号 16位 function trade_no_16() { $explode = explode(' ', microtime()); $trade_no = $explode[1] . mb_substr($explode[0], 2, 6, 'UTF-8'); return $trade_no; } // 当前年的天数 function date_year($time = NULL) { $time = intval($time) ? $time : time(); return date('L', $time) + 365; } // 当前年份中的第几天 function date_z($time = NULL) { $time = intval($time) ? $time : time(); return date('z', $time); } // 当前月份中的第几天,没有前导零 1 到 31 function date_j($time = NULL) { $time = intval($time) ? $time : time(); return date('j', $time); } // 当前月份中的第几天,有前导零的2位数字 01 到 31 function date_d($time = NULL) { $time = intval($time) ? $time : time(); return date('d', $time); } // 当前时间为星期中的第几天 数字表示 1表示星期一 到 7表示星期天 function date_w_n($time = NULL) { $time = intval($time) ? $time : time(); return date('N', $time); } // 当前日第几周 function date_d_w($time = NULL) { $time = intval($time) ? $time : time(); return date('W', $time); } // 当前几月 没有前导零1-12 function date_n($time = NULL) { $time = intval($time) ? $time : time(); return date('n', $time); } // 当前月的天数 function date_t($time = NULL) { $time = intval($time) ? $time : time(); return date('t', $time); } // 0 o'clock on the day function clock_zero() { return strtotime(date('Ymd')); } // 24 o'clock on the day function clock_twenty_four() { return strtotime(date('Ymd')) + 86400; } // 8点过期 / expired at 8 a.m. function eight_expired($time = NULL) { $time = intval($time) ? $time : time(); // 当前时间大于8点则改为第二天8点过期 $life = date('G') <= 8 ? (strtotime(date('Ymd')) + 28800 - $time) : clock_twenty_four() - $time + 28800; return $life; } // 24点过期 / expired at 24 a.m. function twenty_four_expired($time = NULL) { $time = intval($time) ? $time : time(); $twenty_four = clock_twenty_four(); $life = $twenty_four - $time; return $life; } /** * @param $url 提交地址 * @param string $post POST数组 / 空为GET获取数据 / $post='GET'获取连续跳转最终URL * @param string $cookie cookie * @param int $timeout 超时 * @param int $ms 设为1是毫秒 * @return mixed 返回数据 */ function https_request($url, $post = '', $cookie = '', $timeout = 30, $ms = 0) { if (empty($url)) return FALSE; if (version_compare(PHP_VERSION, '5.2.3', '<')) { $ms = 0; $timeout = 30; } is_array($post) and $post = http_build_query($post); // 没有安装curl 使用http的形式,支持post if (!extension_loaded('curl')) { //throw new Exception('server not install CURL'); if ($post) { return https_post($url, $post, $cookie, $timeout); } else { return http_get($url, $cookie, $timeout); } } is_array($cookie) and $cookie = http_build_query($cookie); $curl = curl_init(); // 返回执行结果,不输出 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); //php5.5跟php5.6中的CURLOPT_SAFE_UPLOAD的默认值不同 if (class_exists('\CURLFile')) { curl_setopt($curl, CURLOPT_SAFE_UPLOAD, true); } else { defined('CURLOPT_SAFE_UPLOAD') and curl_setopt($curl, CURLOPT_SAFE_UPLOAD, false); } // 设定请求的RUL curl_setopt($curl, CURLOPT_URL, $url); // 设定返回信息中包含响应信息头 if (ini_get('safe_mode') && ini_get('open_basedir')) { // $post参数必须为GET if ('GET' == $post) { // 安全模式时将头文件的信息作为数据流输出 curl_setopt($curl, CURLOPT_HEADER, true); // 安全模式采用连续抓取 curl_setopt($curl, CURLOPT_NOBODY, true); } } else { curl_setopt($curl, CURLOPT_HEADER, false); // 允许跳转10次 curl_setopt($curl, CURLOPT_MAXREDIRS, 10); // 使用自动跳转,返回最后的Location curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); } $ua1 = 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'; $ua = empty($_SERVER["HTTP_USER_AGENT"]) ? $ua1 : $_SERVER["HTTP_USER_AGENT"]; curl_setopt($curl, CURLOPT_USERAGENT, $ua); // 兼容HTTPS if (FALSE !== stripos($url, 'https://')) { curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); //ssl版本控制 //curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); curl_setopt($curl, CURLOPT_SSLVERSION, true); } $header = array('Content-type: application/x-www-form-urlencoded;charset=UTF-8', 'X-Requested-With: XMLHttpRequest'); $cookie and $header[] = "Cookie: $cookie"; curl_setopt($curl, CURLOPT_HTTPHEADER, $header); if ($post) { // POST curl_setopt($curl, CURLOPT_POST, true); // 自动设置Referer curl_setopt($curl, CURLOPT_AUTOREFERER, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $post); } if ($ms) { curl_setopt($curl, CURLOPT_NOSIGNAL, true); // 设置毫秒超时 curl_setopt($curl, CURLOPT_TIMEOUT_MS, intval($timeout)); // 超时毫秒 } else { curl_setopt($curl, CURLOPT_TIMEOUT, intval($timeout)); // 秒超时 } //优先解析 IPv6 超时后IPv4 //curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); curl_setopt($curl, CURLOPT_ENCODING, 'gzip'); // 返回执行结果 $output = curl_exec($curl); // 有效URL,输出URL非URL页面内容 CURLOPT_RETURNTRANSFER 必须为false 'GET' == $post and $output = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL); curl_close($curl); return $output; } function save_image($img) { $ch = curl_init(); // 设定请求的RUL curl_setopt($ch, CURLOPT_URL, $img); // 设定返回信息中包含响应信息头 启用时会将头文件的信息作为数据流输出 //curl_setopt($ch, CURLOPT_HEADER, false); //curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER["HTTP_USER_AGENT"]); // true表示$html,false表示echo $html curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); //curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); curl_setopt($ch, CURLOPT_ENCODING, 'gzip'); $output = curl_exec($ch); curl_close($ch); return $output; } // 计算字串宽度:剧中对齐(字体大小/字串内容/字体链接/背景宽度/倍数) function calculate_str_width($size, $str, $font, $width, $multiple = 2) { $box = imagettfbbox($size, 0, $font, $str); return ($width - $box[4] - $box[6]) / $multiple; } // 搜索目录下的文件 比对文件后缀 function search_directory($path) { if (is_dir($path)) { $paths = scandir($path); foreach ($paths as $val) { $sub_path = $path . '/' . $val; if ('.' == $val || '..' == $val) { continue; } else if (is_dir($sub_path)) { //echo '目录名:' . $val . '
'; search_directory($sub_path); } else { //echo ' 最底层文件: ' . $path . '/' . $val . '
'; $ext = strtolower(file_ext($sub_path)); if (in_array($ext, array('php', 'asp', 'jsp', 'cgi', 'exe', 'dll'), TRUE)) { echo '异常文件:' . $sub_path . '
'; } } } } } // 一维数组转字符串 $sign待签名字符串 $url为urlencode转码GET参数字符串 function array_to_string($arr, &$sign = '', &$url = '') { if (count($arr) != count($arr, 1)) throw new Exception('Does not support multi-dimensional array to string'); // 注销签名 unset($arr['sign']); // 排序 ksort($arr); reset($arr); // 转字符串做签名 $url = ''; $sign = ''; foreach ($arr as $key => $val) { if (empty($val) || is_array($val)) continue; $url .= $key . '=' . urlencode($val) . '&'; $sign .= $key . '=' . $val . '&'; } $url = substr($url, 0, -1); $url = htmlspecialchars($url); $sign = substr($sign, 0, -1); } // 私钥生成签名 function rsa_create_sign($data, $key, $sign_type = 'RSA') { if (!function_exists('openssl_sign')) throw new Exception('OpenSSL extension is not enabled'); if (!defined('OPENSSL_ALGO_SHA256')) throw new Exception('Only versions above PHP 5.4.8 support SHA256'); $key = wordwrap($key, 64, "\n", true); if (FALSE === $key) throw new Exception('Private Key Error'); $key = "-----BEGIN RSA PRIVATE KEY-----\n$key\n-----END RSA PRIVATE KEY-----"; if ('RSA2' == $sign_type) { openssl_sign($data, $sign, $key, OPENSSL_ALGO_SHA256); } else { openssl_sign($data, $sign, $key, OPENSSL_ALGO_SHA1); } // 加密 return base64_encode($sign); } // 公钥验证签名 function rsa_verify_sign($data, $sign, $key, $sign_type = 'RSA') { $key = wordwrap($key, 64, "\n", true); if (FALSE === $key) throw new Exception('Public Key Error'); $key = "-----BEGIN PUBLIC KEY-----\n$key\n-----END PUBLIC KEY-----"; // 签名正确返回1 签名不正确返回0 错误-1 if ('RSA2' == $sign_type) { $result = openssl_verify($data, base64_decode($sign), $key, OPENSSL_ALGO_SHA256); } else { $result = openssl_verify($data, base64_decode($sign), $key, OPENSSL_ALGO_SHA1); } return $result === 1; } // Array to xml array('appid' => 'appid', 'code' => 'success') function array_to_xml($arr) { if (!is_array($arr) || empty($arr)) throw new Exception('Array Error'); $xml = ""; foreach ($arr as $key => $val) { if (is_numeric($val)) { $xml .= "<" . $key . ">" . $val . ""; } else { $xml .= "<" . $key . ">"; } } $xml .= ""; return $xml; } // Xml to array function xml_to_array($xml) { if (!$xml) throw new Exception('XML error'); $old = libxml_disable_entity_loader(true); // xml解析 $result = (array)simplexml_load_string($xml, null, LIBXML_NOCDATA | LIBXML_COMPACT); // 恢复旧值 if (FALSE === $old) libxml_disable_entity_loader(false); return $result; } // 逐行读取 function well_import($file) { if ($handle = fopen($file, 'r')) { while (!feof($handle)) { yield trim(fgets($handle)); } fclose($handle); } } // 计算总行数 function well_import_total($file, $key = 'well_import_total') { static $cache = array(); if (isset($cache[$key])) return $cache[$key]; $count = cache_get($key); if (NULL === $count) { $count = 0; $globs = well_import($file); while ($globs->valid()) { ++$count; $globs->next(); // 指向下一个 } $count and cache_set($key, $count, 300); } return $cache[$key] = $count; } $g_dir_file = FALSE; function well_search_dir($path) { global $g_dir_file; FALSE === $g_dir_file and $g_dir_file = array(); if (is_dir($path)) { $paths = scandir($path); foreach ($paths as $val) { $sub_path = $path . '/' . $val; if ('.' == $val || '..' == $val) { continue; } else if (is_dir($sub_path)) { well_search_dir($sub_path); } else { $g_dir_file[] = $sub_path; } } } return $g_dir_file; } ?>php - Keep track of statistic periods (display stats in app from last 7 days, last month, etc.) - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - Keep track of statistic periods (display stats in app from last 7 days, last month, etc.) - Stack Overflow

programmeradmin17浏览0评论

I'm working on a Laravel project where I need to display player statistics for different periods (last day, last week, last month, and overall). The statistics are stored in a PlayerShip model, and I need to calculate the difference in statistics over these periods, as I have tables that will show stats for every individual player, it is basically the same 10-12 stats but the stats differ in periods when they were calculated, and that will of course always change but in my tables all the stats are the same. So, to sum: my tables have to show stats a player had: past week, past month, past day and overall.

The code is configured this way: I had migrations that formed a database structure for the table where this data is stored and where it is pulled from, there's an "updated_at" field which is a timestamp that gets renewed each time the method from the service code gets triggered.

The method fetches the data from the Wargaming's API and calculates the stats in the format I need. So that part is sorted, everything is okay, I just need to find a way as to how to differentiate between the periods.

How do I fetch actual stats that were in last week, last month, for last day and overall?

I tried using the "updated_at" but realised that will change literally everyday and refresh to a date which is newer than last 24 hours because there is a cron-job that runs this service code each day

Here's my service code,as I believe this is the only code you need.. the controller only forwards this to the view. The methods that I'm concerned about are:

  • getPlayerStatsLastDay
  • getPlayerStatsLastWeek
  • getPlayerStatsLastMonth
  • getPlayerStatsOverall
  • getTopPlayersLastDay
  • getTopPlayersLastWeek
  • getTopPlayersLastMonth
  • getTopPlayersOverall

Service code

<?php

namespace App\Services;

use App\Models\ClanMember;
use App\Models\Player;
use App\Models\PlayerShip;
use App\Models\Ship;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;


class PlayerShipService
{
    protected $apiKey;
    protected $apiUrl = "/";

    protected $expectedValues;
    public function __construct()
    {
        $this->apiKey = config('services.wargaming.api_key');
    }

    public function loadExpectedValues()
    {
        $path = resource_path('expected_values.json');
        if (!File::exists($path)) {
            Log::error("Expected values file not found at: $path");
            throw new \Exception("Expected values file not found");
        }

        $jsonContent = File::get($path);
        $decodedData = json_decode($jsonContent, true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            Log::error("Invalid JSON in expected values file", [
                'error' => json_last_error_msg(),
                'path' => $path
            ]);
            throw new \Exception("Invalid JSON in expected values file");
        }

        $this->expectedValues = $decodedData;
    }

    private function calculateWN8($ship, $totalBattles, $totalFrags, $totalWins, $totalDamageDealt)
    {
        $shipId = $ship->ship_id; // Extract the ship_id from the model

        //check if it's missing or empty
        if (
            !isset($this->expectedValues['data'][$shipId]) ||
            empty($this->expectedValues['data'][$shipId])
        ) {
            Log::warning("Expected values not found or empty for ship_id: $shipId");
            return null;
        }

        //store expected values for each ship in a variable
        $expected = $this->expectedValues['data'][$shipId];

        //get final expected values by multiplying expected values with number of battles
        $expectedDamage = $expected['average_damage_dealt'] * $totalBattles;
        $expectedFrags = $expected['average_frags'] * $totalBattles;
        $expectedWins = ($expected['win_rate'] / 100) * $totalBattles;

        // Ratios
        $rDmg = $expectedDamage > 0 ? $totalDamageDealt / $expectedDamage : 0;
        $rFrags = $expectedFrags > 0 ? $totalFrags / $expectedFrags : 0;
        $rWins = $expectedWins > 0 ? $totalWins / $expectedWins : 0;

        // Normalize
        $nDmg = max(0, ($rDmg - 0.4) / (1 - 0.4));
        $nFrags = max(0, ($rFrags - 0.1) / (1 - 0.1));
        $nWins = max(0, ($rWins - 0.7) / (1 - 0.7));


        // WN8 formula
        $wn8 = (700 * $nDmg) + (300 * $nFrags) + (150 * $nWins);


        return $wn8;
    }

    public function totalPlayerWN8($playerId)
    {
        $playerShips = PlayerShip::where('account_id', $playerId)->get();


        $total_weighted_wn8 = 0;
        $total_battles = 0;

        foreach ($playerShips as $playerShip) {
            //condition: if there's battles played at all for that player 
            //and corresponding wn8 for the ship played
            if ($playerShip->battles_played > 0 && $playerShip->wn8 !== null) {
                //weighted by total battles to get the total
                $total_weighted_wn8 += $playerShip->wn8 * $playerShip->battles_played;
                $total_battles += $playerShip->battles_played;
            }
        }

        $player_total_wn8 = $total_battles > 0 ? $total_weighted_wn8 / $total_battles : 0;



        return $player_total_wn8;
    }


    private function determineCategoryWN8($wn8)
    {
        //simple if statement, if "value" eq "num" then return "x->value"
        if ($wn8 == null) {
            return 'Null';
        }

        if ($wn8 < 750) {
            return 'Bad';
        } elseif ($wn8 >= 750 && $wn8 < 1100) {
            return 'Below Average';
        } elseif ($wn8 >= 1100 && $wn8 < 1350) {
            return 'Average';
        } elseif ($wn8 >= 1350 && $wn8 < 1550) {
            return 'Good';
        } elseif ($wn8 >= 1550 && $wn8 < 1750) {
            return 'Very Good';
        } elseif ($wn8 >= 1750 && $wn8 < 2100) {
            return 'Great';
        } elseif ($wn8 >= 2100 && $wn8 < 2450) {
            return 'Unicum';
        } elseif ($wn8 >= 2450 && $wn8 < 9999) {
            return 'Super Unicum';
        }
    }


    private function extractBattleStats($stats, $battleType)
    {
        return [
            'battles' => $stats[$battleType]['battles'] ?? 0,
            'wins' => $stats[$battleType]['wins'] ?? 0,
            'damage_dealt' => $stats[$battleType]['damage_dealt'] ?? 0,
            'frags' => $stats[$battleType]['frags'] ?? 0,
            'xp' => $stats[$battleType]['xp'] ?? 0,
            'survived_battles' => $stats[$battleType]['survived_battles'] ?? 0,
            'distance' => $stats[$battleType]['distance'] ?? 0,
        ];
    }




    public function getTopPlayersLast24Hours()
    {
        $last24Hours = now()->subDays(1);

        return PlayerShip::select('account_id', DB::raw('MAX(player_name) as player_name'), DB::raw('MAX(total_player_wn8) as total_player_wn8'))
            ->where('ship_tier', '>', 5)
            ->where('battles_played', '>', 5)
            ->where('updated_at', '<=', $last24Hours)
            ->groupBy('account_id')
            ->orderByDesc('total_player_wn8')
            ->limit(10)
            ->get()
            ->map(function ($player) {
                return [
                    'name' => $player->player_name,
                    'wid' => $player->account_id,
                    'wn8' => $player->total_player_wn8,
                ];
            })
            ->toArray();
    }

    public function getTopPlayersLast7Days()
    {

        $last7days = now()->subDays(7);

        return PlayerShip::select('account_id', DB::raw('MAX(player_name) as player_name'), DB::raw('MAX(total_player_wn8) as total_player_wn8'))
            ->where('ship_tier', '>', 5)
            ->where('battles_played', '>', 30)
            ->where('updated_at', '<=', $last7days)
            ->groupBy('account_id')
            ->orderByDesc('total_player_wn8')
            ->limit(10)
            ->get()
            ->map(function ($player) {
                return [
                    'name' => $player->player_name,
                    'wid' => $player->account_id,
                    'wn8' => $player->total_player_wn8,
                ];
            })
            ->toArray();
    }

    public function getTopPlayersLastMonth()
    {

        $lastMonth = now()->subDays(25);

        return PlayerShip::select('account_id', DB::raw('MAX(player_name) as player_name'), DB::raw('MAX(total_player_wn8) as total_player_wn8'))
            ->where('ship_tier', '>', 5)
            ->where('battles_played', '>', 120)
            ->where('updated_at', '>=', $lastMonth)
            ->groupBy('account_id')
            ->orderByDesc('total_player_wn8')
            ->limit(10)
            ->get()
            ->map(function ($player) {
                return [
                    'name' => $player->player_name,
                    'wid' => $player->account_id,
                    'wn8' => $player->total_player_wn8,
                ];
            })
            ->toArray();
    }

    public function getTopPlayersOverall()
    {

        $overall = now()->subDays(29);

        return PlayerShip::select('account_id', DB::raw('MAX(player_name) as player_name'), DB::raw('MAX(total_player_wn8) as total_player_wn8'))
            ->where('ship_tier', '>', 5)
            ->where('battles_played', '>', 500)
            ->where('updated_at', '>=', $overall)
            ->groupBy('account_id')
            ->orderByDesc('total_player_wn8')
            ->limit(10)
            ->get()
            ->map(function ($player) {
                return [
                    'name' => $player->player_name,
                    'wid' => $player->account_id,
                    'wn8' => $player->total_player_wn8,
                ];
            })
            ->toArray();
    }

 

    public function fetchAndStorePlayerShips()
    {
        $this->loadExpectedValues();

        Log::info('Starting fetchAndStorePlayerShips');

        try {
            $playerIds = ClanMember::pluck('account_id')->all();
            Log::info("Data loaded", ['players_count' => count($playerIds)]);

            foreach ($playerIds as $playerId) {
                $response = Http::get($this->apiUrl, [
                    'application_id' => $this->apiKey,
                    'account_id' => $playerId,
                    'extra' => 'pve,club,pve_div2,pve_div3,pve_solo,pvp_solo,pvp_div2,pvp_div3,rank_solo,rank_div2,rank_div3'
                ]);

                if ($response->successful()) {
                    $data = $response->json();

                    $playerName = ClanMember::where('account_id', $playerId)->value('account_name');



                    if (isset($data['data'][$playerId])) {
                        foreach ($data['data'][$playerId] as $shipStats) {
                            // Find the ship using ship_id from the API
                            $ship = Ship::where('ship_id', $shipStats['ship_id'])->first();


                            if (!$ship) {
                                Log::warning("Ship not found in database", [
                                    'api_ship_id' => $shipStats['ship_id'],
                                    'player_id' => $playerId
                                ]);
                                continue;
                            }

                            //extract stats from ships table 
                            $shipName = $ship->name;
                            $shipType = $ship->type;
                            $shipTier = $ship->tier;
                            $shipNation = $ship->nation;

                            // Extract statistics for different battle types
                            $pvpStats = [];
                            $pveStats = [];
                            $clubStats = [];
                            $rankStats = [];

                            if (isset($shipStats['pvp'])) {
                                $pvpStats = $this->extractBattleStats($shipStats, 'pvp');
                            }

                            if (isset($shipStats['pvp_div2'])) {
                                $pvp2Stats = $this->extractBattleStats($shipStats, 'pvp_div2');
                            }

                            if (isset($shipStats['pvp_div3'])) {
                                $pvp3Stats = $this->extractBattleStats($shipStats, 'pvp_div3');
                            }

                            if (isset($shipStats['pve'])) {
                                $pveStats = $this->extractBattleStats($shipStats, 'pve');
                            }

                            if (isset($shipStats['pve_solo'])) {
                                $pve_soloStats = $this->extractBattleStats($shipStats, 'pve_solo');
                            }

                            if (isset($shipStats['pve_div2'])) {
                                $pve2Stats = $this->extractBattleStats($shipStats, 'pve_div2');
                            }

                            if (isset($shipStats['pve_div3'])) {
                                $pve3Stats = $this->extractBattleStats($shipStats, 'pve_div3');
                            }

                            if (isset($shipStats['club'])) {
                                $clubStats = $this->extractBattleStats($shipStats, 'club');
                            }

                            if (isset($shipStats['rank_solo'])) {
                                $rankStats = $this->extractBattleStats($shipStats, 'rank_solo');
                            }

                            if (isset($shipStats['rank_div2'])) {
                                $rank_div2Stats = $this->extractBattleStats($shipStats, 'rank_solo');
                            }

                            if (isset($shipStats['rank_div3'])) {
                                $rank_div3Stats = $this->extractBattleStats($shipStats, 'rank_solo');
                            }

                            // Calculate total battles
                            $totalBattles = ($pvpStats['battles'] ?? 0) + ($pveStats['battles'] ?? 0)
                                + ($clubStats['battles'] ?? 0) + ($rankStats['battles'] ?? 0)
                                + ($rank_div2Stats['battles'] ?? 0) + ($rank_div3Stats['battles'] ?? 0)
                                + ($pve_soloStats['battles'] ?? 0) + ($pve2Stats['battles'] ?? 0)
                                + ($pve3Stats['battles'] ?? 0) + ($pvp2Stats['battles'] ?? 0)
                                + ($pvp3Stats['battles'] ?? 0);

                            // Calculate total damage
                            $totalDamageDealt = ($pvpStats['damage_dealt'] ?? 0) + ($pveStats['damage_dealt'] ?? 0)
                                + ($clubStats['damage_dealt'] ?? 0) + ($rankStats['damage_dealt'] ?? 0)
                                + ($rank_div2Stats['damage_dealt'] ?? 0) + ($rank_div3Stats['damage_dealt'] ?? 0)
                                + ($pve_soloStats['damage_dealt'] ?? 0) + ($pve2Stats['damage_dealt'] ?? 0)
                                + ($pve3Stats['damage_dealt'] ?? 0) + ($pvp2Stats['damage_dealt'] ?? 0)
                                + ($pvp3Stats['damage_dealt'] ?? 0);


                            $averageDamage = $totalBattles > 0 ? $totalDamageDealt / $totalBattles : 0;

                            //calculate total wins
                            $totalWins = ($pvpStats['wins'] ?? 0) + ($pveStats['wins'] ?? 0)
                                + ($clubStats['wins'] ?? 0) + ($rankStats['wins'] ?? 0)
                                + ($rank_div2Stats['wins'] ?? 0) + ($rank_div3Stats['wins'] ?? 0)
                                + ($pve_soloStats['wins'] ?? 0) + ($pve2Stats['wins'] ?? 0)
                                + ($pve3Stats['wins'] ?? 0) + ($pvp2Stats['wins'] ?? 0)
                                + ($pvp3Stats['wins'] ?? 0);

                            //calculate total frags
                            $totalFrags = ($pvpStats['frags'] ?? 0) + ($pveStats['frags'] ?? 0)
                                + ($clubStats['frags'] ?? 0) + ($rankStats['frags'] ?? 0)
                                + ($rank_div2Stats['frags'] ?? 0) + ($rank_div3Stats['frags'] ?? 0)
                                + ($pve_soloStats['frags'] ?? 0) + ($pve2Stats['frags'] ?? 0)
                                + ($pve3Stats['frags'] ?? 0) + ($pvp2Stats['frags'] ?? 0)
                                + ($pvp3Stats['frags'] ?? 0);

                            $totalXp = ($pvpStats['xp'] ?? 0) + ($pveStats['xp'] ?? 0)
                                + ($clubStats['xp'] ?? 0) + ($rankStats['xp'] ?? 0)
                                + ($rank_div2Stats['xp'] ?? 0) + ($rank_div3Stats['xp'] ?? 0)
                                + ($pve_soloStats['xp'] ?? 0) + ($pve2Stats['xp'] ?? 0)
                                + ($pve3Stats['xp'] ?? 0) + ($pvp2Stats['xp'] ?? 0)
                                + ($pvp3Stats['xp'] ?? 0);


                            $totalCapture = ($pvpStats['capture_points'] ?? 0) + ($pveStats['capture_points'] ?? 0)
                                + ($clubStats['capture_points'] ?? 0) + ($rankStats['capture_points'] ?? 0)
                                + ($rank_div2Stats['capture_points'] ?? 0) + ($rank_div3Stats['capture_points'] ?? 0)
                                + ($pve_soloStats['capture_points'] ?? 0) + ($pve2Stats['capture_points'] ?? 0)
                                + ($pve3Stats['capture_points'] ?? 0) + ($pvp2Stats['capture_points'] ?? 0)
                                + ($pvp3Stats['capture_points'] ?? 0);

                            $totalDefend = ($pvpStats['dropped_capture_points'] ?? 0) + ($pveStats['dropped_capture_points'] ?? 0)
                                + ($clubStats['dropped_capture_points'] ?? 0) + ($rankStats['dropped_capture_points'] ?? 0)
                                + ($rank_div2Stats['dropped_capture_points'] ?? 0) + ($rank_div3Stats['dropped_capture_points'] ?? 0)
                                + ($pve_soloStats['dropped_capture_points'] ?? 0) + ($pve2Stats['dropped_capture_points'] ?? 0)
                                + ($pve3Stats['dropped_capture_points'] ?? 0) + ($pvp2Stats['dropped_capture_points'] ?? 0)
                                + ($pvp3Stats['dropped_capture_points'] ?? 0);

                            $totalSpotted = ($pvpStats['ships_spotted'] ?? 0) + ($pveStats['ships_spotted'] ?? 0)
                                + ($clubStats['ships_spotted'] ?? 0) + ($rankStats['ships_spotted'] ?? 0)
                                + ($rank_div2Stats['ships_spotted'] ?? 0) + ($rank_div3Stats['ships_spotted'] ?? 0)
                                + ($pve_soloStats['ships_spotted'] ?? 0) + ($pve2Stats['ships_spotted'] ?? 0)
                                + ($pve3Stats['ships_spotted'] ?? 0) + ($pvp2Stats['ships_spotted'] ?? 0)
                                + ($pvp3Stats['ships_spotted'] ?? 0);

                            // Calculate survival rate
                            $totalSurvivedBattles = ($pvpStats['survived_battles'] ?? 0) + ($pveStats['survived_battles'] ?? 0) + ($clubStats['survived_battles'] ?? 0) + ($rankStats['survived_battles'] ?? 0);
                            $survivalRate = $totalBattles > 0 ? ($totalSurvivedBattles / $totalBattles) * 100 : 0;


                            //wn8
                            $wn8 =  $this->calculateWN8($ship, $totalBattles, $totalFrags, $totalWins, $totalDamageDealt);

                            //total_player_wn8
                            $total_player_wn8 = $this->totalPlayerWN8($playerId);
                            //wn8 per type / category of a ship 
                            $wn8_category = $this->determineCategoryWN8($wn8);


                            Log::info("Processing ship for player", [
                                'player_id' => $playerId,
                                'ship_id' => $ship->ship_id,
                                'ship_name' => $ship->name,
                                'ship_nation' => $ship->nation
                            ]);

                            PlayerShip::updateOrCreate(
                                [
                                    'account_id' => $playerId,
                                    'ship_id' => $shipStats['ship_id']
                                ],
                                [
                                    'player_name' => $playerName,
                                    'battles_played' => $totalBattles,
                                    'last_battle_time' => $shipStats['last_battle_time'],
                                    'wins_count' => $totalWins,
                                    'damage_dealt' => $totalDamageDealt,
                                    'average_damage' => $averageDamage,
                                    'frags' => $totalFrags,
                                    'survival_rate' => $survivalRate,
                                    'xp' => $totalXp,
                                    'ship_name' => $shipName,
                                    'ship_type' => $shipType,
                                    'ship_tier' => $shipTier,
                                    'ship_nation' => $shipNation,
                                    'distance' => $shipStats['distance'],
                                    'wn8' => $wn8,
                                    'total_player_wn8' => $total_player_wn8,
                                    'capture' => $totalCapture,
                                    'defend' => $totalDefend,
                                    'spotted' => $totalSpotted,
                                    // PVE stats
                                    'pve_battles' => $pveStats['battles'] ?? 0,
                                    'pve_wins' => $pveStats['wins'] ?? 0,
                                    'pve_frags' => $pveStats['frags'] ?? 0,
                                    'pve_xp' => $pveStats['xp'] ?? 0,
                                    'pve_survived_battles' => $pveStats['survived_battles'] ?? 0,
                                    // PVP stats
                                    'pvp_battles' => $pvpStats['battles'] ?? 0,
                                    'pvp_wins' => $pvpStats['wins'] ?? 0,
                                    'pvp_frags' => $pvpStats['frags'] ?? 0,
                                    'pvp_xp' => $pvpStats['xp'] ?? 0,
                                    'pvp_survived_battles' => $pvpStats['survived_battles'] ?? 0,
                                    // Club stats
                                    'club_battles' => $clubStats['battles'] ?? 0,
                                    'club_wins' => $clubStats['wins'] ?? 0,
                                    'club_frags' => $clubStats['frags'] ?? 0,
                                    'club_xp' => $clubStats['xp'] ?? 0,
                                    'club_survived_battles' => $clubStats['survived_battles'] ?? 0,
                                    //Rank stats
                                    'rank_battles' => $rankStats['battles'] ?? 0,
                                    'rank_wins' => $rankStats['wins'] ?? 0,
                                    'rank_frags' => $rankStats['frags'] ?? 0,
                                    'rank_xp' => $rankStats['xp'] ?? 0,
                                    'rank_survived_battles' => $rankStats['survived_battles'] ?? 0,
                                ]
                            );
                        }
                        Log::info("Successfully updated/created player ship record", [
                            'player_id' => $playerId,
                            'ship_id' => $shipStats['ship_id'],
                            'nation' => $ship->nation
                        ]);
                        $this->totalPlayerWN8($playerId);
                    }
                } else {
                    Log::error("Failed to fetch player ships", [
                        'account_id' => $playerId,
                        'status' => $response->status(),
                        'response' => $response->body()
                    ]);
                }
            }

            return true;
        } catch (\Exception $e) {
            Log::error("Error in fetchAndStorePlayerShips", [
                'message' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            throw $e;
        }
    }

    //get stats for each player, based on a period: 24, 7, 30, overall


    public function getPlayerStatsLastDay($account_id)
    {
        $playerStatistics = PlayerShip::select(
            'battles_played as battles',
            'wins_count as wins',
            'ship_tier as tier',
            'survival_rate as survived',
            'damage_dealt as damage',
            'frags as frags',
            'xp as xp',
            'spotted as spotted',
            'capture as capture',
            'defend as defend',
            'wn8 as wn8'
        )
            ->where('account_id', $account_id)
            ->where('updated_at', '>=', now()->subDay())
            ->first();
        Log::info($playerStatistics);

        return $playerStatistics ? $playerStatistics->toArray() : [];
    }
    public function getPlayerStatsLastWeek($account_id)
    {
        $playerStatistics = PlayerShip::select(
            'battles_played as battles',
            'wins_count as wins',
            'ship_tier as tier',
            'survival_rate as survived',
            'damage_dealt as damage',
            'frags as frags',
            'xp as xp',
            'spotted as spotted',
            'capture as capture',
            'defend as defend',
            'wn8 as wn8'
        )
            ->where('account_id', $account_id)
            ->where('updated_at', '>=', now()->subWeek())
            ->first();

        Log::info($playerStatistics);
        return $playerStatistics ? $playerStatistics->toArray() : [];
    }

    public function getPlayerStatsLastMonth($account_id)
    {
        $playerStatistics = PlayerShip::select(
            'battles_played as battles',
            'wins_count as wins',
            'ship_tier as tier',
            'survival_rate as survived',
            'damage_dealt as damage',
            'frags as frags',
            'xp as xp',
            'spotted as spotted',
            'capture as capture',
            'defend as defend',
            'wn8 as wn8'
        )
            ->where('account_id', $account_id)
            ->where('updated_at', '>=', now()->subMonth())
            ->first();
        Log::info($playerStatistics);

        return $playerStatistics ? $playerStatistics->toArray() : [];
    }


    public function getPlayerStatsOverall($account_id)
    {
        $playerStatistics = PlayerShip::select(
            'battles_played as battles',
            'wins_count as wins',
            'ship_tier as tier',
            'survival_rate as survived',
            'damage_dealt as damage',
            'frags as frags',
            'xp as xp',
            'spotted as spotted',
            'capture as capture',
            'defend as defend',
            'wn8 as wn8'
        )
            ->where('account_id', $account_id)
            ->first();
        Log::info($playerStatistics);

        return $playerStatistics ? $playerStatistics->toArray() : [];
    }

    public function getPlayerVehicleData($account_id, $name)
    {
        $playerVehicles = PlayerShip::select(
            'ship_nation as nation',
            'ship_name as name',
            'ship_tier as tier',
            'battles_played as battles',
            'frags as frags',
            'damage_dealt as damage',
            'wins_count as wins',
            'wn8 as wn8'
        )
            ->where('account_id', $account_id)
            ->where('player_name', $name)
            ->get()
            ->map(function ($vehicle) {
                return [
                    'nation' => $vehicle->nation,
                    'name' => $vehicle->name,
                    'tier' => $vehicle->tier,
                    'battles' => $vehicle->battles,
                    'frags' => $vehicle->frags,
                    'damage' => $vehicle->damage,
                    'wins' => $vehicle->wins,
                    'wn8' => $vehicle->wn8,
                ];
            })
            ->toArray();
        if (!$playerVehicles) {
            Log::warning("Player vehicle info not found", ['account_id' => $account_id, 'name' => $name]);
            return [];
        }

        Log::info("Fetched vehicle for player $account_id", ['player vehicle data: ' => $playerVehicles]);

        return $playerVehicles;
    }
}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论