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")
|
ASSISTS: Symbol("assists")
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const KILLACTIVITY = Object.freeze({
|
||||||
|
THIS: Symbol("kill"),
|
||||||
|
ID: Symbol("killer_id"),
|
||||||
|
});
|
||||||
|
|
||||||
export const LOGIN = Object.freeze({
|
export const LOGIN = Object.freeze({
|
||||||
THIS: Symbol("login"),
|
THIS: Symbol("login"),
|
||||||
ID: Symbol("id"),
|
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) {
|
export async function get_characters_by_account(account_id) {
|
||||||
try {
|
try {
|
||||||
const characters = await pool.query('SELECT * FROM avatar WHERE account_id=$1 AND deleted=false', [account_id])
|
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;
|
export default api;
|
||||||
|
|
@ -6,12 +6,13 @@
|
||||||
import { selectedPlayer } from '../player';
|
import { selectedPlayer } from '../player';
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
get_weaponStats();
|
get_iWeaponStats();
|
||||||
});
|
});
|
||||||
|
|
||||||
let player; // Define player variable to hold player data
|
let player; // Define player variable to hold player data
|
||||||
let weapons = [];
|
let iWeapons = [];
|
||||||
let alert;
|
let alert;
|
||||||
|
let iWeaponsKillsSum
|
||||||
|
|
||||||
// Subscribe to the selectedPlayer store to get the selected player data
|
// Subscribe to the selectedPlayer store to get the selected player data
|
||||||
selectedPlayer.subscribe(value => {
|
selectedPlayer.subscribe(value => {
|
||||||
|
|
@ -20,11 +21,42 @@
|
||||||
|
|
||||||
const url = "/api/avatar/"+$selectedPlayer.id+"/weaponstats"
|
const url = "/api/avatar/"+$selectedPlayer.id+"/weaponstats"
|
||||||
|
|
||||||
async function get_weaponStats() {
|
async function get_iWeaponStats() {
|
||||||
try {
|
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 resp = await axios.get(url);
|
||||||
const stats = resp.data;
|
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
|
// Reset alert message if needed
|
||||||
alert.message("");
|
alert.message("");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -249,8 +281,8 @@ const weaponNames = [
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</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;">Battle Rank:</span> {$selectedPlayer.br}<br>
|
||||||
|
<span style="color:lightgrey;">Command Rank:</span> {$selectedPlayer.cr}<br>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
@ -266,9 +298,9 @@ const weaponNames = [
|
||||||
<th>Accuracy</th>
|
<th>Accuracy</th>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{#each weapons as weapon}
|
{#each iWeapons as weapon}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{getWeaponName(weapon.weapon_id)} {weapon.weapon_id}</td>
|
<td>{getWeaponName(weapon.weapon_id)}</td>
|
||||||
<td>{weapon.kills}</td>
|
<td>{weapon.kills}</td>
|
||||||
<td>{weapon.assists}</td>
|
<td>{weapon.assists}</td>
|
||||||
<td>{weapon.shots_fired}</td>
|
<td>{weapon.shots_fired}</td>
|
||||||
|
|
@ -278,3 +310,4 @@ const weaponNames = [
|
||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<span style="color:lightgrey;">Total Kills: </span>{iWeaponsKillsSum}
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,12 @@
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
get_BEPleaderboard();
|
get_BEPleaderboard();
|
||||||
get_CEPleaderboard();
|
get_CEPleaderboard();
|
||||||
|
get_kills();
|
||||||
});
|
});
|
||||||
|
|
||||||
let bepPlayers = [];
|
let bepPlayers = [];
|
||||||
let cepPlayers = [];
|
let cepPlayers = [];
|
||||||
|
let kills = [];
|
||||||
let alert;
|
let alert;
|
||||||
|
|
||||||
async function get_BEPleaderboard() {
|
async function get_BEPleaderboard() {
|
||||||
|
|
@ -27,18 +29,31 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function get_CEPleaderboard() {
|
async function get_CEPleaderboard() {
|
||||||
try {
|
try {
|
||||||
const resp = await axios.get("/api/char_stats_cep/0");
|
const resp = await axios.get("/api/char_stats_cep/0");
|
||||||
const stats = resp.data;
|
const stats = resp.data;
|
||||||
cepPlayers = stats.players;
|
cepPlayers = stats.players;
|
||||||
// Reset alert message if needed
|
// Reset alert message if needed
|
||||||
alert.message("");
|
alert.message("");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
alert.message("Failed to fetch stats from server");
|
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
|
// Define battle rank ranges
|
||||||
const rankRanges = [
|
const rankRanges = [
|
||||||
|
|
@ -115,22 +130,26 @@
|
||||||
return 40;
|
return 40;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to calculate rank based on CEP
|
// Function to calculate rank based on CEP
|
||||||
function calculateCrRank(cep) {
|
function calculateCrRank(cep) {
|
||||||
// Iterate through rank ranges to find the appropriate rank
|
// Iterate through rank ranges to find the appropriate rank
|
||||||
for (const range of crRankRanges) {
|
for (const range of crRankRanges) {
|
||||||
if (cep >= range.minCEP && cep <= range.maxCEP) {
|
if (cep >= range.minCEP && cep <= range.maxCEP) {
|
||||||
return range.rank;
|
return range.rank;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Default rank if CEP doesn't match any range
|
// Default rank if CEP doesn't match any range
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleClick = (clickedPlayer) => {
|
const handleClick = (clickedPlayer) => {
|
||||||
selectedPlayer.set({id: clickedPlayer.id, name: clickedPlayer.name, faction_id: clickedPlayer.faction_id, br: calculateRank(clickedPlayer.bep), cr: calculateCrRank(clickedPlayer.cep)});
|
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>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
|
@ -140,18 +159,18 @@
|
||||||
|
|
||||||
<ul class="nav nav-tabs mb-3" id="nav-tab" role="tablist">
|
<ul class="nav nav-tabs mb-3" id="nav-tab" role="tablist">
|
||||||
<li class="nav-item">
|
<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>
|
||||||
<li class="nav-item">
|
<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>
|
<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>
|
||||||
<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>
|
</ul>
|
||||||
|
|
||||||
<div class="tab-content" id="tabs-tabContent">
|
<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">
|
<table class="table table-sm table-dark table-responsive-md table-striped table-hover">
|
||||||
<thead class="thead-light">
|
<thead class="thead-light">
|
||||||
<th>#</th>
|
<th>#</th>
|
||||||
|
|
@ -174,7 +193,8 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</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">
|
<table class="table table-sm table-dark table-responsive-md table-striped table-hover">
|
||||||
<thead class="thead-light">
|
<thead class="thead-light">
|
||||||
<th>#</th>
|
<th>#</th>
|
||||||
|
|
@ -194,10 +214,33 @@
|
||||||
<td>{calculateCrRank(player.cep)}</td>
|
<td>{calculateCrRank(player.cep)}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane" id="kills" role="tabpanel" aria-labelledby="kills-tab">
|
|
||||||
|
|
||||||
</div>
|
<div class="tab-pane show active" id="kills" role="tabpanel" aria-labelledby="kills-tab">
|
||||||
</div>
|
<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