예제 #1
0
 public function get_player_pve_stats($name, $time)
 {
     //searching by name, null name = no buenos
     if ($name == NULL) {
         return Response::error('404');
     } else {
         $input_name = urldecode($name);
     }
     //Look up the player, latest to account for deletes with the same name
     $player = Player::where('name', '=', $input_name)->order_by('created_at', 'DESC')->first();
     //no player found, why not search?
     if (!$player) {
         return Response::error('404');
     }
     //Player website preferences
     $web_prefs = WebsitePref::where('db_id', '=', $player->db_id)->first();
     if (isset($web_prefs->attributes)) {
         $web_prefs = $web_prefs->attributes;
     }
     function stats_number_formatting($n)
     {
         if ($n > 1000000000000) {
             return round($n / 1000000000000, 1) . ' T';
         } else {
             if ($n > 1000000000) {
                 return round($n / 1000000000, 1) . ' B';
             } else {
                 if ($n > 1000000) {
                     return round($n / 1000000, 1) . ' M';
                 } else {
                     if ($n > 1000) {
                         return round($n / 1000, 1) . ' K';
                     }
                 }
             }
         }
         return number_format($n);
     }
     //Global (technically) default for pve stats data, dont worry about setting it to null depending on webprefs, simply skip the logic.
     $pve_stats_data = "";
     $player_db_id = $player->db_id;
     $todays_date = gmdate("Y-m-d");
     //I worked hard once; it was awful.
     if (urldecode($time) == 'all') {
         //Check the cache all date to see if it's out of date
         if (Cache::has($player_db_id . '_pve_stats_all')) {
             $pve_stats_data = Cache::get($player_db_id . '_pve_stats_all');
         } else {
             //no cache, time to make some money, make mysql do work.  uh. gettin in shape.
             //Stats
             $pve_stats_bindings = array($player_db_id, $todays_date);
             $pve_stats_sql = "SELECT \n                    SUM(`accuracy`) AS 'accuracy', SUM(`damage_done`) AS 'damage_done', SUM(`damage_taken`) AS 'damage_taken', \n                    SUM(`deaths`) AS 'deaths', SUM(`drowned`) AS 'drowned', SUM(`headshots`) AS 'headshots', SUM(`healed`) AS 'healed', \n                    SUM(`incapacitated`) AS 'incapacitated', SUM(`primary_reloads`) AS 'primary_reloads', \n                    SUM(`primary_weapon_shots_fired`) AS 'primary_weapon_shots_fired', SUM(`revived`) AS 'revived', SUM(`revives`) AS 'revives', \n                    SUM(`scanhammer_kills`) AS 'scanhammer_kills', SUM(`secondary_reloads`) AS 'secondary_reloads', \n                    SUM(`secondary_weapon_shots_fired`) AS 'secondary_weapon_shots_fired', SUM(`suicides`) AS 'suicides'\n                    FROM `pvestats` WHERE ( `db_id` = ? AND DATE(`created_at`) < DATE(?) )";
             $pve_stats_query = DB::query($pve_stats_sql, $pve_stats_bindings);
             $pve_events_sql = "SELECT\n                    SUM(ares_missions_0) AS 'ares_missions_0', SUM(ares_missions_1) AS 'ares_missions_1', SUM(crashed_lgvs) AS 'crashed_lgvs',\n                    SUM(crashed_thumpers) AS 'crashed_thumpers', SUM(holmgang_tech_completed) AS 'holmgang_tech_completed', SUM(lgv_races) AS 'lgv_races',\n                    MIN(lgv_fastest_time_sunken_copa) AS 'lgv_fastest_time_sunken_copa', MIN(lgv_fastest_time_thump_copa) AS 'lgv_fastest_time_thump_copa',\n                    MIN(lgv_fastest_time_copa_trans) AS 'lgv_fastest_time_copa_trans', MIN(lgv_fastest_time_copa_thump) AS 'lgv_fastest_time_copa_thump',\n                    MIN(lgv_fastest_time_trans_sunken) AS 'lgv_fastest_time_trans_sunken', SUM(outposts_defended) AS 'outposts_defended',\n                    SUM(strike_teams_0) AS 'strike_teams_0', SUM(strike_teams_1) AS 'strike_teams_1', SUM(strike_teams_2) AS 'strike_teams_2',\n                    SUM(strike_teams_3) AS 'strike_teams_3', SUM(sunken_harbor_invasions_completed) AS 'sunken_harbor_invasions_completed',\n                    SUM(thump_dump_invasions_completed) AS 'thump_dump_invasions_completed', SUM(tornados_3) AS 'tornados_3', SUM(tornados_4) AS 'tornados_4',\n                    SUM(warbringers_3) AS 'warbringers_3', SUM(warbringers_4) AS 'warbringers_4', SUM(watchtowers_defended) AS 'watchtowers_defended',\n                    SUM(watchtowers_retaken) AS 'watchtowers_retaken', SUM(raider_squads_defeated) AS 'raider_squads_defeated', SUM(chosen_death_squads) as 'chosen_death_squads'\n                    FROM `pveevents` WHERE ( `db_id` = ? AND DATE(`created_at`) < DATE(?) )";
             $pve_events_query = DB::query($pve_events_sql, $pve_stats_bindings);
             $pve_kills_sql = "SELECT t1,t2,t3,t4 FROM `pvekills` WHERE ( `db_id` = ? AND DATE(`created_at`) < DATE(?) )";
             $pve_kills_query = DB::query($pve_kills_sql, $pve_stats_bindings);
             //PVE KILLS IS SPECIAL.  So let's sum up what we have to do.
             $pve_kills_datas = array('t1' => array(), 't2' => array(), 't3' => array(), 't4' => array());
             foreach ($pve_kills_query as $kills) {
                 //each t1,t2,t3,t4
                 foreach ($kills as $key => $value) {
                     $kill = unserialize($value);
                     if (!empty($kill)) {
                         foreach ($kill as $k => $v) {
                             if (array_key_exists($k, $pve_kills_datas[$key])) {
                                 $temp = $pve_kills_datas[$key][$k] + $v;
                                 $pve_kills_datas[$key][$k] = $temp;
                             } else {
                                 $pve_kills_datas[$key][$k] = $v;
                             }
                             unset($kill);
                         }
                     }
                     unset($kills);
                 }
             }
             //Can has data?  For real?
             $pve_stats_data = array('stats' => '', 'events' => '', 'kills' => '');
             if (!empty($pve_stats_query) && !is_null($pve_stats_query[0]->accuracy)) {
                 $pve_stats_data['stats'] = $pve_stats_query[0];
             }
             if (!empty($pve_events_query) && !is_null($pve_events_query[0]->ares_missions_0)) {
                 $pve_stats_data['events'] = $pve_events_query[0];
             }
             if (!empty($pve_kills_datas)) {
                 $pve_stats_data['kills'] = $pve_kills_datas;
             }
             //set cache to expire "tomorrow"
             $now = strtotime('now');
             $tomorrow = strtotime('tomorrow');
             $caches_expires = round(($tomorrow - $now) / 60);
             $cache_expires_minutes = $caches_expires > 0 ? $caches_expires : 1;
             Cache::put($player_db_id . '_pve_stats_all', $pve_stats_data, $cache_expires_minutes);
         }
         //no all cache exists
     }
     //all
     //X5s did all that hard work... hard work is not Xtops approved.  We must slack off!
     //Your hard work is not recognized in Fort Kick Ass.
     if (urldecode($time) == 'today') {
         if (Cache::has($player_db_id . '_pve_stats_' . $todays_date)) {
             $pve_stats_data = Cache::get($player_db_id . '_pve_stats_' . $todays_date);
         } else {
             //Stats
             $pve_stats_query = PvEStat::where(function ($query) use($player_db_id, $todays_date) {
                 $query->where('db_id', '=', $player_db_id);
                 $query->where(DB::raw('DATE(created_at)'), '=', $todays_date);
             })->first();
             //Events
             $pve_events_query = PvEEvent::where(function ($query) use($player_db_id, $todays_date) {
                 $query->where('db_id', '=', $player_db_id);
                 $query->where(DB::raw('DATE(created_at)'), '=', $todays_date);
             })->first();
             //Kills
             $pve_kills_query = PvEKill::where(function ($query) use($player_db_id, $todays_date) {
                 $query->where('db_id', '=', $player_db_id);
                 $query->where(DB::raw('DATE(created_at)'), '=', $todays_date);
             })->first();
             //Format the data, we don't want square pegs in round holes... but maybe round pegs in square holes?
             $pve_stats = new stdClass();
             $pve_stats_allowed_keys = array('accuracy', 'damage_done', 'damage_taken', 'deaths', 'drowned', 'headshots', 'healed', 'incapacitated', 'primary_reloads', 'primary_weapon_shots_fired', 'revived', 'revives', 'scanhammer_kills', 'secondary_reloads', 'secondary_weapon_shots_fired', 'suicides');
             if ($pve_stats_query) {
                 foreach ($pve_stats_query->original as $key => $value) {
                     if (in_array($key, $pve_stats_allowed_keys)) {
                         $pve_stats->{$key} = $value;
                     }
                 }
             }
             $pve_events = new stdClass();
             $pve_events_allowed_keys = array('ares_missions_0', 'ares_missions_1', 'crashed_lgvs', 'crashed_thumpers', 'holmgang_tech_completed', 'lgv_races', 'lgv_fastest_time_sunken_copa', 'lgv_fastest_time_thump_copa', 'lgv_fastest_time_copa_trans', 'lgv_fastest_time_copa_thump', 'lgv_fastest_time_trans_sunken', 'outposts_defended', 'strike_teams_0', 'strike_teams_1', 'strike_teams_2', 'strike_teams_3', 'sunken_harbor_invasions_completed', 'thump_dump_invasions_completed', 'tornados_3', 'tornados_4', 'warbringers_3', 'warbringers_4', 'watchtowers_defended', 'watchtowers_retaken', 'raider_squads_defeated', 'chosen_death_squads');
             if ($pve_events_query) {
                 foreach ($pve_events_query->original as $key => $value) {
                     if (in_array($key, $pve_events_allowed_keys)) {
                         $pve_events->{$key} = $value;
                     }
                 }
             }
             $pve_kills = new stdClass();
             $pve_kills_allowed_keys = array('t1', 't2', 't3', 't4');
             if ($pve_kills_query) {
                 foreach ($pve_kills_query->original as $key => $value) {
                     if (in_array($key, $pve_kills_allowed_keys)) {
                         $pve_kills->{$key} = unserialize($value);
                     }
                 }
             }
             //Can has data?  For real?
             $pve_stats_data = array('stats' => '', 'events' => '', 'kills' => '');
             if (!empty($pve_stats)) {
                 $pve_stats_data['stats'] = $pve_stats;
             }
             if (!empty($pve_events)) {
                 $pve_stats_data['events'] = $pve_events;
             }
             if (!empty($pve_kills)) {
                 $pve_stats_data['kills'] = $pve_kills;
             }
             Cache::put($player_db_id . '_pve_stats_' . $todays_date, $pve_stats_data, 5);
         }
         //no today cache exists
     }
     //today onry
     return View::make('player.player_profile_pve_stats')->with(compact('pve_stats_data'))->with(compact('web_prefs'));
 }
예제 #2
0
 public function post_pve_stats()
 {
     $log_header = "addon_v2.php@pve [" . $this->user_ip . "] - ({$this->logdate}): ";
     $line = Input::json();
     if ($this->savedata) {
         file_put_contents($this->logpath . $this->logdate . '_pve.json', serialize($line));
     }
     $datlog = new DatLog();
     $datlog->ip = ip2long($this->user_ip);
     $datlog->db_id = isset($line->Player_ID) ? $line->Player_ID : NULL;
     $datlog->name = isset($line->Player_Name) ? $line->Player_Name : NULL;
     $datlog->category = 'pve';
     $datlog->save();
     try {
         /*
          ********************************
          ** Validate Minimum Keys Exist**
          ********************************
          *  # Fail if invalid
          */
         //Minimum keys
         if (!isset($line->Player_Instance) || !isset($line->PvE_Events) || !isset($line->Player_EID) || !isset($line->PvE_Stats) || !isset($line->PvE_Kills) || !isset($line->Player_ID) || !isset($line->Player_Name)) {
             throw new Exception('Player did not send all keys.');
         }
         /*
          ********************************
          ** Validate Player ID (db_id) **
          ********************************
          *  # Fail if invalid
          *  @ sets $player_db_id
          *
          *  -check digits only
          *  -19 characters long
          *  -Begins with a 9
          */
         //Digits only?
         if (preg_match('/[^0-9]/', $line->Player_ID)) {
             throw new Exception("Player ID was more than just numbers: " . $line->Player_ID);
         }
         //19 Characters long?
         if (strlen($line->Player_ID) !== 19) {
             throw new Exception("Player ID was not 19 characters: " . $line->Player_ID);
         }
         //Starts with a 9?
         if (substr($line->Player_ID, 0, 1) !== '9') {
             throw new Exception("Player ID did not start with a 9: " . $line->Player_ID);
         }
         $player_db_id = $line->Player_ID;
         /*
          **********************************
          ** Validate Player EID          **
          **********************************
          *  # Fail is non numeric, NULL otherwise
          *  @ sets $player_eid
          *
          *  -Greater than 0
          *  -Expected length 9 or 10, but others possible
          */
         //Sent only numbers
         if (preg_match('/[^0-9]/', $line->Player_EID)) {
             throw new Exception("Player ({$player_db_id}) EID contained something other than a number: " . $line->Player_EID);
         }
         //EID should be as long as a db_id
         if (strlen($line->Player_EID) !== 19) {
             Log::warn("Player ({$player_db_id}) EID was not the expected 19 digits long: " . $line->Player_EID);
             $line->Player_EID = NULL;
         }
         $player_eid = $line->Player_EID;
         /*
          **********************************
          ** Validate Player Name/Army Tag**
          **********************************
          *  # Warn if invalid
          *  @ sets $player_name
          *  @ sets $player_army_tag
          *
          *  -15 + 6 characters or less ~23 to be safe
          *  -We don't care about character content as much as FF does
          */
         //Check if name is way too long, or too short
         if (strlen($line->Player_Name) > 30 || trim(strlen($line->Player_Name)) < 3) {
             throw new Exception("Player ({$player_db_id}) name was longer than 30 characters, should be <= 23: " . $line->Player_Name);
         }
         //Warn if longer than expected (that's what she said)
         //But allow for armytag length too
         if (strlen($line->Player_Name) > 27) {
             Log::warn("Player ({$player_db_id}) sent a character name longer than max expected length of 27: " . $line->Player_Name);
         }
         //Name is ok, but does it have an army tag?  Does it blend?
         if (strpos($line->Player_Name, ']')) {
             $last = strripos($line->Player_Name, ']') + 1;
             $player_army_tag = substr($line->Player_Name, 0, $last);
             $player_name = trim(substr($line->Player_Name, $last));
         } else {
             $player_army_tag = NULL;
             $player_name = $line->Player_Name;
         }
         /*
          ***********************************
          ** Check existing name/db_id/eid **
          ***********************************
          *  Does the db_id exist?
          *  Does the submitted name match existing?
          *  Does the submitted eid match existing?
          */
         $check_existing_sql = Player::where('db_id', '=', $player_db_id)->order_by('created_at', 'DESC')->first();
         if ($check_existing_sql) {
             if ($check_existing_sql->name != $player_name) {
                 throw new Exception("Existing db_id does not match existing name: (player sent:{$player_db_id}|{$player_name};existing:{$check_existing_sql->db_id}|{$check_existing_sql->name};)");
                 Log::warn("Existing db_id does not match existing name({$player_db_id}|in:{$player_name}|existing:{$check_existing_sql->name})");
             }
             if ($check_existing_sql->e_id != $player_eid) {
                 throw new Exception("Existing db_id does not match existing name({$player_db_id}|in:{$player_eid}|existing:{$check_existing_sql->e_id})");
                 Log::warn("Existing db_id does not match existing eid({$player_db_id}|in:{$player_eid}|existing:{$check_existing_sql->e_id})");
             }
         }
         //Let's store some data
         //First up, PVE STATS
         /*
          ***********************************
          ** CHECK FOR CRAZY IN PVE STATS  **
          ***********************************
          *  Integer
          *  Greater than 0
          */
         $pve_stats_data = $line->PvE_Stats;
         foreach ($pve_stats_data as $key => $value) {
             //I can't add letters
             if (!is_numeric($value)) {
                 throw new Exception("PvEStats->{$key} was not numeric");
             }
             //All positive thinking here, except for accuracy
             if ($value < 0 && $key != 'Accuracy') {
                 throw new Exception("PvEStats->{$key} was less than zero");
             }
             //check suspect values, over 9000 is so web2.0
             if ($key != 'Primary_Weapon_Shots_Fired' && $key != 'Secondary_Weapon_Shots_Fired' && $key != 'Healed' && $key != 'Damage_Done') {
                 if ($value > 99999) {
                     Log::warn("Player ({$player_db_id}) sent value > 99999: {$key}={$value}");
                 }
             }
         }
         //check shots_fired, but not fire shtos
         if (!$pve_stats_data->Primary_Weapon_Shots_Fired > 100000 || !$pve_stats_data->Secondary_Weapon_Shots_Fired > 100000 || !$pve_stats_data->Healed > 100000 || !$pve_stats_data->Damage_Done > 100000) {
             Log::warn("Player ({$player_db_id}) sent value > 100000 for shots fired/healed.");
         }
         //Check for duplicate date entry, add to existing data if so
         $last_pve_stats_update = PvEStat::where(function ($query) use($player_db_id) {
             $query->where('db_id', '=', $player_db_id);
             $query->where(DB::raw('DATE(updated_at)'), '=', $this->date_only);
         })->order_by('id', 'desc')->first('id');
         if ($last_pve_stats_update) {
             $query_update_pvestats = "UPDATE `pvestats` SET ";
             $query_update_pvestats .= "`accuracy` = `accuracy` + ?, ";
             $query_update_pvestats .= "`damage_done` = `damage_done` + ?, ";
             $query_update_pvestats .= "`damage_taken` = `damage_taken` + ?, ";
             $query_update_pvestats .= "`deaths` = `deaths` + ?, ";
             $query_update_pvestats .= "`drowned` = `drowned` + ?, ";
             $query_update_pvestats .= "`headshots` = `headshots` + ?, ";
             $query_update_pvestats .= "`healed` = `healed` + ?, ";
             $query_update_pvestats .= "`incapacitated` = `incapacitated` + ?, ";
             $query_update_pvestats .= "`primary_reloads` = `primary_reloads` + ?, ";
             $query_update_pvestats .= "`primary_weapon_shots_fired` = `primary_weapon_shots_fired` + ?, ";
             $query_update_pvestats .= "`revived` = `revived` + ?, ";
             $query_update_pvestats .= "`revives` = `revives` + ?, ";
             $query_update_pvestats .= "`scanhammer_kills` = `scanhammer_kills` + ?, ";
             $query_update_pvestats .= "`secondary_reloads` = `secondary_reloads` + ?, ";
             $query_update_pvestats .= "`secondary_weapon_shots_fired` = `secondary_weapon_shots_fired` + ?, ";
             $query_update_pvestats .= "`suicides` = `suicides` + ?, ";
             $query_update_pvestats .= "`updated_at` = ? WHERE `id` = ?";
             $bindings_update_pvestats = array($pve_stats_data->Accuracy, $pve_stats_data->Damage_Done, $pve_stats_data->Damage_Taken, $pve_stats_data->Deaths, $pve_stats_data->Drowned, $pve_stats_data->Headshots, $pve_stats_data->Healed, $pve_stats_data->Incapacitated, $pve_stats_data->Primary_Reloads, $pve_stats_data->Primary_Weapon_Shots_Fired, $pve_stats_data->Revived, $pve_stats_data->Revives, $pve_stats_data->Scanhammer_Kills, $pve_stats_data->Secondary_Reloads, $pve_stats_data->Secondary_Weapon_Shots_Fired, $pve_stats_data->Suicides, $this->date, $last_pve_stats_update->id);
             if (DB::query($query_update_pvestats, $bindings_update_pvestats) === false) {
                 throw new Exception('Error updating pve stats.');
             }
         } else {
             $pvestat = new PvEStat();
             $pvestat->db_id = $player_db_id;
             $pvestat->Accuracy = $pve_stats_data->Accuracy;
             $pvestat->Damage_Done = $pve_stats_data->Damage_Done;
             $pvestat->Damage_Taken = $pve_stats_data->Damage_Taken;
             $pvestat->Deaths = $pve_stats_data->Deaths;
             $pvestat->Drowned = $pve_stats_data->Drowned;
             $pvestat->Headshots = $pve_stats_data->Headshots;
             $pvestat->Healed = $pve_stats_data->Healed;
             $pvestat->Incapacitated = $pve_stats_data->Incapacitated;
             $pvestat->Primary_Reloads = $pve_stats_data->Primary_Reloads;
             $pvestat->Primary_Weapon_Shots_Fired = $pve_stats_data->Primary_Weapon_Shots_Fired;
             $pvestat->Revived = $pve_stats_data->Revived;
             $pvestat->Revives = $pve_stats_data->Revives;
             $pvestat->Scanhammer_Kills = $pve_stats_data->Scanhammer_Kills;
             $pvestat->Secondary_Reloads = $pve_stats_data->Secondary_Reloads;
             $pvestat->Secondary_Weapon_Shots_Fired = $pve_stats_data->Secondary_Weapon_Shots_Fired;
             $pvestat->Suicides = $pve_stats_data->Suicides;
             if (!$pvestat->save()) {
                 throw new Exception('Add PvEStat query failed:');
             }
         }
         /*
          ***********************************
          ** CHECK FOR CRAZY IN PVE EVENTS **
          ***********************************
          *  Integer
          *  Greater than 0
          */
         $pve_events_data = $line->PvE_Events;
         foreach ($pve_events_data as $key => $value) {
             if (is_object($value) || is_array($value)) {
                 foreach ($value as $k => $v) {
                     if (!is_numeric($v) || $v < 0) {
                         throw new Exception("PvEEvent was not numeric, or less than zero: ({$key})");
                     }
                 }
             } else {
                 if (!is_numeric($value) || $value < 0) {
                     throw new Exception("PvEEvent was not numeric, or less than zero: ({$key})");
                 }
             }
         }
         //Check for duplicate date entry, add to existing data if so
         $last_pve_events_update = PvEEvent::where(function ($query) use($player_db_id) {
             $query->where('db_id', '=', $player_db_id);
             $query->where(DB::raw('DATE(updated_at)'), '=', $this->date_only);
         })->order_by('id', 'desc')->first('id');
         if ($last_pve_events_update) {
             $query_update_pveevents = "UPDATE `pveevents` SET ";
             $query_update_pveevents .= "`ares_missions_0` = `ares_missions_0` + ?, ";
             $query_update_pveevents .= "`ares_missions_1` = `ares_missions_1` + ?, ";
             $query_update_pveevents .= "`crashed_lgvs` = `crashed_lgvs` + ?, ";
             $query_update_pveevents .= "`raider_squads_defeated` = `raider_squads_defeated` + ?, ";
             $query_update_pveevents .= "`crashed_thumpers` = `crashed_thumpers` + ?, ";
             $query_update_pveevents .= "`holmgang_tech_completed` = `holmgang_tech_completed` + ?, ";
             $query_update_pveevents .= "`lgv_races` = `lgv_races` + ?, ";
             $query_update_pveevents .= "`lgv_fastest_time_sunken_copa` = LEAST(`lgv_fastest_time_sunken_copa`, ?), ";
             $query_update_pveevents .= "`lgv_fastest_time_thump_copa` = LEAST(`lgv_fastest_time_thump_copa`, ?), ";
             $query_update_pveevents .= "`lgv_fastest_time_copa_trans` = LEAST(`lgv_fastest_time_copa_trans`, ?), ";
             $query_update_pveevents .= "`lgv_fastest_time_copa_thump` = LEAST(`lgv_fastest_time_copa_thump`, ?), ";
             $query_update_pveevents .= "`lgv_fastest_time_trans_sunken` = LEAST(`lgv_fastest_time_trans_sunken`, ?), ";
             $query_update_pveevents .= "`outposts_defended` = `outposts_defended` + ?, ";
             $query_update_pveevents .= "`strike_teams_0` = `strike_teams_0` + ?, ";
             $query_update_pveevents .= "`strike_teams_1` = `strike_teams_1` + ?, ";
             $query_update_pveevents .= "`strike_teams_2` = `strike_teams_2` + ?, ";
             $query_update_pveevents .= "`strike_teams_3` = `strike_teams_3` + ?, ";
             $query_update_pveevents .= "`sunken_harbor_invasions_completed` = `sunken_harbor_invasions_completed` + ?, ";
             $query_update_pveevents .= "`thump_dump_invasions_completed` = `thump_dump_invasions_completed` + ?, ";
             $query_update_pveevents .= "`tornados_3` = `tornados_3` + ?, ";
             $query_update_pveevents .= "`tornados_4` = `tornados_4` + ?, ";
             $query_update_pveevents .= "`warbringers_3` = `warbringers_3` + ?, ";
             $query_update_pveevents .= "`warbringers_4` = `warbringers_4` + ?, ";
             $query_update_pveevents .= "`watchtowers_defended` = `watchtowers_defended` + ?, ";
             $query_update_pveevents .= "`watchtowers_retaken` = `watchtowers_retaken` + ?, ";
             $query_update_pveevents .= "`chosen_death_squads` = `chosen_death_squads` + ?, ";
             $query_update_pveevents .= "updated_at = ? WHERE `id` = ?";
             //pesky race values
             $pve_events_data_lgv_sunken_copa = isset($pve_events_data->LGV_Race_Fastest_Time->{'Sunken-Copa'}) ? $pve_events_data->LGV_Race_Fastest_Time->{'Sunken-Copa'} : 999.0;
             $pve_events_data_lgv_thump_copa = isset($pve_events_data->LGV_Race_Fastest_Time->{'Thump-Copa'}) ? $pve_events_data->LGV_Race_Fastest_Time->{'Thump-Copa'} : 999.0;
             $pve_events_data_lgv_copa_trans = isset($pve_events_data->LGV_Race_Fastest_Time->{'Copa-Trans'}) ? $pve_events_data->LGV_Race_Fastest_Time->{'Copa-Trans'} : 999.0;
             $pve_events_data_lgv_copa_thump = isset($pve_events_data->LGV_Race_Fastest_Time->{'Copa-Thump'}) ? $pve_events_data->LGV_Race_Fastest_Time->{'Copa-Thump'} : 999.0;
             $pve_events_data_lgv_trans_sunken = isset($pve_events_data->LGV_Race_Fastest_Time->{'Trans-Sunken'}) ? $pve_events_data->LGV_Race_Fastest_Time->{'Trans-Sunken'} : 999.0;
             if (isset($pve_events_data->Raider_Squads_Defeated)) {
                 $raider_squads_defeated = $pve_events_data->Raider_Squads_Defeated;
             } else {
                 $raider_squads_defeated = 0;
             }
             if (isset($pve_events_data->Chosen_Death_Squads_Defeated)) {
                 $chosen_death_squads = $pve_events_data->Chosen_Death_Squads_Defeated;
             } else {
                 $chosen_death_squads = 0;
             }
             $bindings_update_pveevents = array($pve_events_data->ARES_Missions[0], $pve_events_data->ARES_Missions[1], $pve_events_data->Crashed_LGVs, $raider_squads_defeated, $pve_events_data->Crashed_Thumpers, $pve_events_data->Holmgang_Tech_Completed, $pve_events_data->LGV_Races, $pve_events_data_lgv_sunken_copa, $pve_events_data_lgv_thump_copa, $pve_events_data_lgv_copa_trans, $pve_events_data_lgv_copa_thump, $pve_events_data_lgv_trans_sunken, $pve_events_data->Outposts_Defended, $pve_events_data->Strike_Teams[0], $pve_events_data->Strike_Teams[1], $pve_events_data->Strike_Teams[2], $pve_events_data->Strike_Teams[3], $pve_events_data->Sunken_Harbor_Invasions_Completed, $pve_events_data->Thump_Dump_Invasions_Completed, $pve_events_data->Tornados->{3}, $pve_events_data->Tornados->{4}, $pve_events_data->Warbringers->{3}, $pve_events_data->Warbringers->{4}, $pve_events_data->Watchtowers_Defended, $pve_events_data->Watchtowers_Retaken, $chosen_death_squads, $this->date, $last_pve_events_update->id);
             if (DB::query($query_update_pveevents, $bindings_update_pveevents) === false) {
                 throw new Exception('Error updating pve events.');
             }
         } else {
             $pveevent = new PvEEvent();
             $pveevent->db_id = $player_db_id;
             $pveevent->ares_missions_0 = $pve_events_data->ARES_Missions[0];
             $pveevent->ares_missions_1 = $pve_events_data->ARES_Missions[1];
             $pveevent->crashed_lgvs = $pve_events_data->Crashed_LGVs;
             if (isset($pve_events_data->Raider_Squads_Defeated)) {
                 $pveevent->raider_squads_defeated = $pve_events_data->Raider_Squads_Defeated;
             }
             $pveevent->crashed_thumpers = $pve_events_data->Crashed_Thumpers;
             $pveevent->holmgang_tech_completed = $pve_events_data->Holmgang_Tech_Completed;
             $pveevent->lgv_races = $pve_events_data->LGV_Races;
             //check if any race times have been sent, default, high impossible value
             $pveevent->lgv_fastest_time_sunken_copa = 999.0;
             $pveevent->lgv_fastest_time_thump_copa = 999.0;
             $pveevent->lgv_fastest_time_copa_trans = 999.0;
             $pveevent->lgv_fastest_time_copa_thump = 999.0;
             $pveevent->lgv_fastest_time_trans_sunken = 999.0;
             if (count($pve_events_data->LGV_Race_Fastest_Time) > 0) {
                 foreach ($pve_events_data->LGV_Race_Fastest_Time as $key => $value) {
                     switch (strtolower($key)) {
                         case 'sunken-copa':
                             $pveevent->lgv_fastest_time_sunken_copa = $value;
                             break;
                         case 'thump-copa':
                             $pveevent->lgv_fastest_time_thump_copa = $value;
                             break;
                         case 'copa-trans':
                             $pveevent->lgv_fastest_time_copa_trans = $value;
                             break;
                         case 'copa-thump':
                             $pveevent->lgv_fastest_time_copa_thump = $value;
                             break;
                         case 'trans-sunken':
                             $pveevent->lgv_fastest_time_trans_sunken = $value;
                             break;
                         default:
                             break;
                     }
                 }
             }
             $pveevent->outposts_defended = $pve_events_data->Outposts_Defended;
             $pveevent->strike_teams_0 = $pve_events_data->Strike_Teams[0];
             $pveevent->strike_teams_1 = $pve_events_data->Strike_Teams[1];
             $pveevent->strike_teams_2 = $pve_events_data->Strike_Teams[2];
             $pveevent->strike_teams_3 = $pve_events_data->Strike_Teams[3];
             $pveevent->sunken_harbor_invasions_completed = $pve_events_data->Sunken_Harbor_Invasions_Completed;
             $pveevent->thump_dump_invasions_completed = $pve_events_data->Thump_Dump_Invasions_Completed;
             $pveevent->tornados_3 = $pve_events_data->Tornados->{3};
             $pveevent->tornados_4 = $pve_events_data->Tornados->{4};
             $pveevent->warbringers_3 = $pve_events_data->Warbringers->{3};
             $pveevent->warbringers_4 = $pve_events_data->Warbringers->{4};
             $pveevent->watchtowers_defended = $pve_events_data->Watchtowers_Defended;
             $pveevent->watchtowers_retaken = $pve_events_data->Watchtowers_Retaken;
             if (isset($pve_events_data->Chosen_Death_Squads_Defeated)) {
                 $pveevent->chosen_death_squads = $pve_events_data->Chosen_Death_Squads_Defeated;
             }
             if (!$pveevent->save()) {
                 throw new Exception('Add PvEEvent query failed:');
             }
         }
         /*
          ***********************************
          ** CHECK FOR CRAZY IN PVE KILLS  **
          ***********************************
          *  Integer
          *  Greater than 0
          */
         $pve_kills_data = $line->PvE_Kills;
         foreach ($pve_kills_data as $key => $value) {
             if ($key == 'T1' || $key == 'T2' || $key == 'T3' || $key == 'T4') {
                 foreach ($value as $k => $v) {
                     //keys must be numeric
                     if (!is_numeric($k)) {
                         throw new Exception("PvE Kills sent non numeric mob id");
                     }
                     if (!is_numeric($v) || $v > 10000) {
                         Log::warn($log_header . $logdate . ": PvE Kills sent non numeric value, or val greater than 10000");
                     }
                 }
             } else {
                 throw new Exception("PvE Kills sent unexpected key");
             }
         }
         //Check for duplicate date entry, add to existing data if so
         $last_pve_kills_update = PvEKill::where(function ($query) use($player_db_id) {
             $query->where('db_id', '=', $player_db_id);
             $query->where(DB::raw('DATE(updated_at)'), '=', $this->date_only);
         })->order_by('id', 'desc')->first();
         //do this one backwards
         if (!$last_pve_kills_update) {
             //no data, so we add data
             $pvekill = new PvEKill();
             $pvekill->db_id = $player_db_id;
             $pvekill->t1 = serialize($pve_kills_data->T1);
             $pvekill->t2 = serialize($pve_kills_data->T2);
             $pvekill->t3 = serialize($pve_kills_data->T3);
             $pvekill->t4 = serialize($pve_kills_data->T4);
             if (!$pvekill->save()) {
                 throw new Exception('Add PvEKill query failed:');
             }
         } else {
             // JUSTICE FRIENDS, ASSEMBLE
             $new_t1 = $new_t2 = $new_t3 = $new_t4 = '';
             //EXISTING T1 , ASSIMILATE
             $current_t1 = unserialize($last_pve_kills_update->t1);
             if (count($current_t1) > 0) {
                 //We have existing data.  By our keys combined, we are captain planet!
                 $temp = array();
                 //Add existing data to temp
                 foreach ($current_t1 as $key => $value) {
                     $temp[$key] = $value;
                 }
                 //Add new data to temp, if exists
                 if (count($pve_kills_data->T1) > 0) {
                     foreach ($pve_kills_data->T1 as $key => $value) {
                         //if they key exists, add to it
                         if (array_key_exists($key, $temp)) {
                             $temp_val = $temp[$key];
                             $temp[$key] = $temp_val + $value;
                         } else {
                             $temp[$key] = $value;
                         }
                     }
                 }
                 $new_t1 = serialize((object) $temp);
             } else {
                 //No existing data... so use the input one
                 $new_t1 = serialize($pve_kills_data->T1);
             }
             //EXISTING T2 , ASSIMILATE
             $current_t2 = unserialize($last_pve_kills_update->t2);
             if (count($current_t2) > 0) {
                 //We have existing data.  By our keys combined, we are captain planet!
                 $temp = array();
                 //Add existing data to temp
                 foreach ($current_t2 as $key => $value) {
                     $temp[$key] = $value;
                 }
                 //Add new data to temp, if exists
                 if (count($pve_kills_data->T2) > 0) {
                     foreach ($pve_kills_data->T2 as $key => $value) {
                         //if they key exists, add to it
                         if (array_key_exists($key, $temp)) {
                             $temp_val = $temp[$key];
                             $temp[$key] = $temp_val + $value;
                         } else {
                             $temp[$key] = $value;
                         }
                     }
                 }
                 $new_t2 = serialize((object) $temp);
             } else {
                 //No existing data... so use the input one
                 $new_t2 = serialize($pve_kills_data->T2);
             }
             //EXISTING T3 , ASSIMILATE
             $current_t3 = unserialize($last_pve_kills_update->t3);
             if (count($current_t3) > 0) {
                 //We have existing data.  By our keys combined, we are captain planet!
                 $temp = array();
                 //Add existing data to temp
                 foreach ($current_t3 as $key => $value) {
                     $temp[$key] = $value;
                 }
                 //Add new data to temp, if exists
                 if (count($pve_kills_data->T3) > 0) {
                     foreach ($pve_kills_data->T3 as $key => $value) {
                         //if they key exists, add to it
                         if (array_key_exists($key, $temp)) {
                             $temp_val = $temp[$key];
                             $temp[$key] = $temp_val + $value;
                         } else {
                             $temp[$key] = $value;
                         }
                     }
                 }
                 $new_t3 = serialize((object) $temp);
             } else {
                 //No existing data... so use the input one
                 $new_t3 = serialize($pve_kills_data->T3);
             }
             //EXISTING T4 , ASSIMILATE
             $current_t4 = unserialize($last_pve_kills_update->t4);
             if (count($current_t4) > 0) {
                 //We have existing data.  By our keys combined, we are captain planet!
                 $temp = array();
                 //Add existing data to temp
                 foreach ($current_t4 as $key => $value) {
                     $temp[$key] = $value;
                 }
                 //Add new data to temp, if exists
                 if (count($pve_kills_data->T4) > 0) {
                     foreach ($pve_kills_data->T4 as $key => $value) {
                         //if they key exists, add to it
                         if (array_key_exists($key, $temp)) {
                             $temp_val = $temp[$key];
                             $temp[$key] = $temp_val + $value;
                         } else {
                             $temp[$key] = $value;
                         }
                     }
                 }
                 $new_t4 = serialize((object) $temp);
             } else {
                 //No existing data... so use the input one
                 $new_t4 = serialize($pve_kills_data->T4);
             }
             $query_update_pvekills = "UPDATE `pvekills` SET ";
             $query_update_pvekills .= "`t1` = ?, `t2` = ?, `t3` = ?, `t4` = ?, ";
             $query_update_pvekills .= "updated_at = ? WHERE `id` = ?";
             $bindings_update_pvekills = array($new_t1, $new_t2, $new_t3, $new_t4, $this->date, $last_pve_kills_update->id);
             if (DB::query($query_update_pvekills, $bindings_update_pvekills) === false) {
                 throw new Exception('Error updating pve kills.');
             }
         }
     } catch (Exception $e) {
         Log::info($log_header . $e->getMessage());
         file_put_contents($this->logpath . $this->logdate . '_pve.json', serialize($line));
     }
     return Response::json(array('ThumpDumpDB' => '(PVE) Thanks'));
 }