mirror of
https://github.com/psforever/PSFPortal.git
synced 2026-01-19 18:14:45 +00:00
Merge pull request #44 from ScrawnyRonnie/master
Add Kills Leaderboard and Tidy Up
This commit is contained in:
commit
4fbdd3ade2
20
api/db.js
20
api/db.js
|
|
@ -80,6 +80,11 @@ export const WEAPONSTAT = Object.freeze({
|
|||
ASSISTS: Symbol("assists")
|
||||
});
|
||||
|
||||
export const KILLACTIVITY = Object.freeze({
|
||||
THIS: Symbol("kill"),
|
||||
ID: Symbol("killer_id"),
|
||||
});
|
||||
|
||||
export const LOGIN = Object.freeze({
|
||||
THIS: Symbol("login"),
|
||||
ID: Symbol("id"),
|
||||
|
|
@ -343,6 +348,21 @@ export async function get_weaponstats_by_avatar(id) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function get_killstats() {
|
||||
try {
|
||||
const kills = await pool.query('SELECT count(killactivity.killer_id), killactivity.killer_id, avatar.name, avatar.bep, avatar.cep, avatar.faction_id' +
|
||||
' FROM killactivity' +
|
||||
' INNER JOIN avatar ON killactivity.killer_id = avatar.id' +
|
||||
' GROUP BY killactivity.killer_id, avatar.name, avatar.bep, avatar.cep, avatar.faction_id' +
|
||||
' ORDER BY count(killer_id) DESC')
|
||||
return kills.rows;
|
||||
} catch (e) {
|
||||
if (e.code)
|
||||
e.code = pg_error_inv[e.code]
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
export async function get_characters_by_account(account_id) {
|
||||
try {
|
||||
const characters = await pool.query('SELECT * FROM avatar WHERE account_id=$1 AND deleted=false', [account_id])
|
||||
|
|
|
|||
10
api/stats.js
10
api/stats.js
|
|
@ -58,4 +58,14 @@ api.get('/char_stats_cep/:batch', async (req, res, next) => {
|
|||
}
|
||||
});
|
||||
|
||||
api.get('/char_stats_kills', async (req, res, next) => {
|
||||
try {
|
||||
const kills = await db.get_killstats();
|
||||
res.status(200).json({ kills: kills });
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
res.status(500).json({ message: 'error' });
|
||||
}
|
||||
});
|
||||
|
||||
export default api;
|
||||
|
|
@ -6,12 +6,13 @@
|
|||
import { selectedPlayer } from '../player';
|
||||
|
||||
onMount(() => {
|
||||
get_weaponStats();
|
||||
get_iWeaponStats();
|
||||
});
|
||||
|
||||
let player; // Define player variable to hold player data
|
||||
let weapons = [];
|
||||
let iWeapons = [];
|
||||
let alert;
|
||||
let iWeaponsKillsSum
|
||||
|
||||
// Subscribe to the selectedPlayer store to get the selected player data
|
||||
selectedPlayer.subscribe(value => {
|
||||
|
|
@ -20,11 +21,42 @@
|
|||
|
||||
const url = "/api/avatar/"+$selectedPlayer.id+"/weaponstats"
|
||||
|
||||
async function get_weaponStats() {
|
||||
async function get_iWeaponStats() {
|
||||
try {
|
||||
const ids = [55, 56, 57, 140, 146, 175, 233, 299, 304, 324, 334, 345, 396, 406,
|
||||
407, 411, 425, 429, 462, 468, 556, 587, 588, 589, 599, 673, 680, 701, 706, 714,
|
||||
716, 730, 737, 817, 838, 845, 864, 888, 889, 890, 968, 969, 970];
|
||||
const resp = await axios.get(url);
|
||||
const stats = resp.data;
|
||||
weapons = stats.weapons;
|
||||
const filteredWeapons = stats.weapons.filter(weapon => {
|
||||
return ids.includes(weapon.weapon_id);
|
||||
});
|
||||
|
||||
filteredWeapons.forEach(weapon => {
|
||||
switch (weapon.weapon_id) {
|
||||
case 304:
|
||||
weapon.shots_fired = Math.ceil(weapon.shots_fired / 36);
|
||||
weapon.shots_landed = Math.ceil(weapon.shots_landed / 8);
|
||||
break;
|
||||
case 411:
|
||||
weapon.shots_fired = Math.ceil(weapon.shots_fired / 21);
|
||||
weapon.shots_landed = Math.ceil(weapon.shots_landed / 6);
|
||||
break;
|
||||
case 588:
|
||||
weapon.shots_fired = Math.ceil(weapon.shots_fired / 55);
|
||||
weapon.shots_landed = Math.ceil(weapon.shots_landed / 10);
|
||||
break;
|
||||
case 714:
|
||||
weapon.shots_fired = Math.ceil(weapon.shots_fired / 36);
|
||||
weapon.shots_landed = Math.ceil(weapon.shots_landed / 8);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
iWeapons = filteredWeapons;
|
||||
iWeaponsKillsSum = iWeapons.reduce((total, weapon) => total + weapon.kills, 0);
|
||||
// Reset alert message if needed
|
||||
alert.message("");
|
||||
} catch (e) {
|
||||
|
|
@ -249,8 +281,8 @@ const weaponNames = [
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<span style="color:lightgrey;">Command Rank:</span> {$selectedPlayer.cr}<br>
|
||||
<span style="color:lightgrey;">Battle Rank:</span> {$selectedPlayer.br}<br>
|
||||
<span style="color:lightgrey;">Command Rank:</span> {$selectedPlayer.cr}<br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
@ -266,9 +298,9 @@ const weaponNames = [
|
|||
<th>Accuracy</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each weapons as weapon}
|
||||
{#each iWeapons as weapon}
|
||||
<tr>
|
||||
<td>{getWeaponName(weapon.weapon_id)} {weapon.weapon_id}</td>
|
||||
<td>{getWeaponName(weapon.weapon_id)}</td>
|
||||
<td>{weapon.kills}</td>
|
||||
<td>{weapon.assists}</td>
|
||||
<td>{weapon.shots_fired}</td>
|
||||
|
|
@ -278,3 +310,4 @@ const weaponNames = [
|
|||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
<span style="color:lightgrey;">Total Kills: </span>{iWeaponsKillsSum}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@
|
|||
onMount(() => {
|
||||
get_BEPleaderboard();
|
||||
get_CEPleaderboard();
|
||||
get_kills();
|
||||
});
|
||||
|
||||
let bepPlayers = [];
|
||||
let cepPlayers = [];
|
||||
let kills = [];
|
||||
let alert;
|
||||
|
||||
async function get_BEPleaderboard() {
|
||||
|
|
@ -27,18 +29,31 @@
|
|||
}
|
||||
}
|
||||
|
||||
async function get_CEPleaderboard() {
|
||||
try {
|
||||
const resp = await axios.get("/api/char_stats_cep/0");
|
||||
const stats = resp.data;
|
||||
cepPlayers = stats.players;
|
||||
// Reset alert message if needed
|
||||
alert.message("");
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
alert.message("Failed to fetch stats from server");
|
||||
}
|
||||
async function get_CEPleaderboard() {
|
||||
try {
|
||||
const resp = await axios.get("/api/char_stats_cep/0");
|
||||
const stats = resp.data;
|
||||
cepPlayers = stats.players;
|
||||
// Reset alert message if needed
|
||||
alert.message("");
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
alert.message("Failed to fetch stats from server");
|
||||
}
|
||||
}
|
||||
|
||||
async function get_kills() {
|
||||
try {
|
||||
const resp = await axios.get("/api/char_stats_kills");
|
||||
const stats = resp.data;
|
||||
kills = stats.kills;
|
||||
// Reset alert message if needed
|
||||
alert.message("");
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
alert.message("Failed to fetch stats from server");
|
||||
}
|
||||
}
|
||||
|
||||
// Define battle rank ranges
|
||||
const rankRanges = [
|
||||
|
|
@ -115,22 +130,26 @@
|
|||
return 40;
|
||||
}
|
||||
|
||||
// Function to calculate rank based on CEP
|
||||
function calculateCrRank(cep) {
|
||||
// Iterate through rank ranges to find the appropriate rank
|
||||
for (const range of crRankRanges) {
|
||||
if (cep >= range.minCEP && cep <= range.maxCEP) {
|
||||
return range.rank;
|
||||
}
|
||||
}
|
||||
// Default rank if CEP doesn't match any range
|
||||
return 5;
|
||||
}
|
||||
// Function to calculate rank based on CEP
|
||||
function calculateCrRank(cep) {
|
||||
// Iterate through rank ranges to find the appropriate rank
|
||||
for (const range of crRankRanges) {
|
||||
if (cep >= range.minCEP && cep <= range.maxCEP) {
|
||||
return range.rank;
|
||||
}
|
||||
}
|
||||
// Default rank if CEP doesn't match any range
|
||||
return 5;
|
||||
}
|
||||
|
||||
const handleClick = (clickedPlayer) => {
|
||||
selectedPlayer.set({id: clickedPlayer.id, name: clickedPlayer.name, faction_id: clickedPlayer.faction_id, br: calculateRank(clickedPlayer.bep), cr: calculateCrRank(clickedPlayer.cep)});
|
||||
};
|
||||
|
||||
const handleKillClick = (clickedPlayer) => {
|
||||
selectedPlayer.set({id: clickedPlayer.killer_id, name: clickedPlayer.name, faction_id: clickedPlayer.faction_id, br: calculateRank(clickedPlayer.bep), cr: calculateCrRank(clickedPlayer.cep)});
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
|
@ -140,18 +159,18 @@
|
|||
|
||||
<ul class="nav nav-tabs mb-3" id="nav-tab" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" id="br-tab" data-toggle="tab" href="#br" role="tab" aria-controls="br" aria-selected="true">Battle Rank</a>
|
||||
<a class="nav-link active" id="kills-tab" data-toggle="tab" href="#kills" role="tab" aria-controls="kills" aria-selected="true">Kills</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="br-tab" data-toggle="tab" href="#br" role="tab" aria-controls="br" aria-selected="false">Battle Rank</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="cr-tab" data-toggle="tab" href="#cr" role="tab" aria-controls="cr" aria-selected="false">Command Rank</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="kills-tab" data-toggle="tab" href="#kills" role="tab" aria-controls="kills" aria-selected="false">Kills</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content" id="tabs-tabContent">
|
||||
<div class="tab-pane show active" id="br" role="tabpanel" aria-labelledby="br-tab">
|
||||
<div class="tab-pane" id="br" role="tabpanel" aria-labelledby="br-tab">
|
||||
<table class="table table-sm table-dark table-responsive-md table-striped table-hover">
|
||||
<thead class="thead-light">
|
||||
<th>#</th>
|
||||
|
|
@ -174,7 +193,8 @@
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-pane" id="cr" role="tabpanel" aria-labelledby="cr-tab">
|
||||
|
||||
<div class="tab-pane" id="cr" role="tabpanel" aria-labelledby="cr-tab">
|
||||
<table class="table table-sm table-dark table-responsive-md table-striped table-hover">
|
||||
<thead class="thead-light">
|
||||
<th>#</th>
|
||||
|
|
@ -194,10 +214,33 @@
|
|||
<td>{calculateCrRank(player.cep)}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-pane" id="kills" role="tabpanel" aria-labelledby="kills-tab">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane show active" id="kills" role="tabpanel" aria-labelledby="kills-tab">
|
||||
<table class="table table-sm table-dark table-responsive-md table-striped table-hover">
|
||||
<thead class="thead-light">
|
||||
<th>#</th>
|
||||
<th>Name</th>
|
||||
<th>Kills</th>
|
||||
<th>BR</th>
|
||||
<th>CR</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each kills as killer, $index}
|
||||
<tr>
|
||||
<td>{$index + 1}</td>
|
||||
<td>
|
||||
<img height="24" src={getFactionIcon(killer.faction_id)} alt={killer.faction_id} />
|
||||
<a href="/avatar/{killer.killer_id}" on:click={() => handleKillClick(killer)}>{killer.name}</a>
|
||||
</td>
|
||||
<td>{killer.count}</td>
|
||||
<td>{calculateRank(killer.bep)}</td>
|
||||
<td>{calculateCrRank(killer.cep)}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
Loading…
Reference in a new issue