Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Jackzmc/l4d2-stats-plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
Jackzmc committed Nov 14, 2024
2 parents c181361 + d87f4fb commit 2d475f2
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 25 deletions.
9 changes: 8 additions & 1 deletion website-api/routes/campaigns.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ const router = Router()
import routeCache from 'route-cache'

export default function(pool) {
router.get('/values', routeCache.cacheSeconds(600), async(req, res) => {
const [gamemodes] = await pool.query("SELECT gamemode, COUNT(gamemode) count from stats_games GROUP BY gamemode ORDER BY count DESC")
res.json({
gamemodes
})
})
router.get('/:id', routeCache.cacheSeconds(120), async(req,res) => {
try {
const [rows] = await pool.query(
Expand All @@ -24,7 +30,8 @@ export default function(pool) {
const offset = pageNumber * perPage;

const difficulty = isNaN(req.query.difficulty) ? null : parseInt(req.query.difficulty)
let selectTag = req.query.tag || "prod"
let selectTag = req.query.tag
if(!selectTag || selectTag === "any") selectTag = "prod"
let gamemodeSearchString = req.query.gamemode && req.query.gamemode !== "all" ? `${req.query.gamemode}` : `%`
let mapSearchString = "" // RLIKE "^c[0-9]m"
if(req.query.type) {
Expand Down
31 changes: 30 additions & 1 deletion website-api/routes/top.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,38 @@ export default function(pool) {
const selectedPage = req.params.page || 0;
const pageNumber = (isNaN(selectedPage) || selectedPage <= 0) ? 0 : (parseInt(req.params.page) - 1);
const offset = pageNumber * MAX_RESULTS;
const [rows] = await pool.query("SELECT steamid,last_alias,minutes_played,last_join_date,points FROM `stats_users` ORDER BY `points` DESC, `minutes_played` DESC LIMIT ?,?", [offset, MAX_RESULTS])
let rows, version
if(req.query.version == "1") {
[rows] = await pool.query("SELECT steamid,last_alias,minutes_played,last_join_date,points FROM `stats_users` ORDER BY `points` DESC, `minutes_played` DESC LIMIT ?,?", [offset, MAX_RESULTS])
version = "v1"
} else {
[rows] = await pool.query(`select
steamid,last_alias,minutes_played,last_join_date,
points as points_old,
(
(common_kills / 1000 * 0.10) +
(kills_all_specials * 0.25) +
(revived_others * 0.05) +
(heal_others * 0.05) -
(survivor_incaps * 0.10) -
(survivor_deaths * 0.05) +
(survivor_ff * 0.03) +
(damage_to_tank*0.15/minutes_played) +
((kills_molotov+kills_pipe)*0.025) +
(witches_crowned*0.2) -
(rocks_hitby*0.2) +
(cleared_pinned*0.05)
) as points
from stats_users
order by points desc
limit ?,?`,
[offset, MAX_RESULTS]
)
version = "v2"
}
res.json({
users: rows,
version
});
}catch(err) {
console.error('[/api/top]',err.message);
Expand Down
2 changes: 2 additions & 0 deletions website-ui/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VUE_APP_SITE_NAME="L4D2 Stats"
VUE_APP_SHARE_URL="https://jackz.me/c/"
21 changes: 21 additions & 0 deletions website-ui/src/assets/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"selectableTags": [
{ "value": "main", "label": "Main (Private)" },
{ "value": "vanilla+", "label": "Reserved (Private)" },
{ "value": "public", "label": "Public" },
{
"label": "Regions",
"list": [
{"value": "tx", "label": "Texas"}
]
}
],
"gamemodeLabels": {
"coop": "Coop",
"versus": "Versus",
"survival": "Survival",
"tankrun": "Tank Run",
"rocketdude": "Rocket Dude",
"realism": "Realism"
}
}
2 changes: 1 addition & 1 deletion website-ui/src/components/ProfileList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</b-tooltip>
</b-table-column>
<b-table-column field="points" label="Points" v-slot="props">
<span style="color: blue">{{ props.row.points | formatNumber }}</span>
<span style="color: blue">{{ Math.round(props.row.points) | formatNumber }}</span>
<!-- <em> {{Math.round(props.row.points / (props.row.minutes_played / 60)) | formatNumber}} p/h</em> -->
</b-table-column>
<b-table-column label="Last Played" v-slot="props">
Expand Down
5 changes: 3 additions & 2 deletions website-ui/src/views/Leaderboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
<h6 class="title is-6">Random Player of the Day</h6>
<router-link :to="'/user/' + randomPlayer.steamid + '/overview'" class="title">{{randomPlayer.last_alias}}</router-link>
<br>
<p class="subtitle is-6"><em>{{randomPlayer.points | formatNumber}} points</em></p>
<p class="subtitle is-6"><em>{{Math.round(randomPlayer.points) | formatNumber}} points</em></p>
</div>
</div>
</div>
Expand Down Expand Up @@ -163,7 +163,8 @@ export default {
refreshTop() {
console.debug('Loading users for page' + this.top_page)
this.loading = true;
return this.$http.get(`/api/top/users/${this.top_page}`, { cache: true })
const params = this.$route.query.version ? `?version=${this.$route.query.version}` : ""
return this.$http.get(`/api/top/users/${this.top_page}${params}`, { cache: true })
.then((r) => {
this.top_today = r.data.users;
})
Expand Down
63 changes: 43 additions & 20 deletions website-ui/src/views/campaigns/List.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,15 @@
<b-field label="Tag Selection">
<!-- TODO: fetch from server -->
<b-select v-model="filtered.filters.tag" placeholder="Select a tag">
<option value="prod">All</option>
<!-- <option value="dev" v-if="process.env.NODE_ENV !== 'production'">Dev</option> -->
<option value="lgs">Main (Private)</option>
<option value="server-r">Vanilla (Reserved)</option>
<option value="public">Public</option>
<optgroup label="Regions">
<option value="tx">Texas</option>
</optgroup>
<optgroup label="Server">
<option v-for="i of 7" :key="i" :value="'server-' + i">Server TX-P{{i}}</option>
</optgroup>
<option value="any">Any</option>
<template v-for="entry in selectableTags">
<optgroup v-if="entry.list" :label="entry.label" :key="entry.label">
<option v-for="subentry in entry.list" :key="subentry.value" :value="subentry.value">
{{ subentry.label }}
</option>
</optgroup>
<option v-else :value="entry.value" :key="entry.value">{{ entry.label }}</option>
</template>
</b-select>
</b-field>
<b-field label="Map Type">
Expand All @@ -69,12 +67,9 @@
<b-field label="Gamemode">
<b-select v-model="filtered.filters.gamemode">
<option value="all">Any</option>
<option value="coop">Coop</option>
<option value="versus">Versus</option>
<option value="survival">Survival</option>
<option value="TankRun">Tank Run</option>
<option value="RocketDude">RocketDude</option>
<option value="Realism">Realism</option>
<option v-for="entry in selectableGamemodes" :key="entry.gamemode" :value="entry.gamemode">
{{ entry.label }} ({{entry.count.toLocaleString()}})
</option>
</b-select>
</b-field>
<b-field label="Difficulty">
Expand Down Expand Up @@ -124,6 +119,7 @@

<script>
import { getMapName, getMapImage } from '@/js/map'
import Settings from "@/assets/settings.json"
export default {
data() {
return {
Expand All @@ -133,7 +129,7 @@ export default {
selectedRecent: 0,
filtered: {
filters: {
tag: null,
tag: "any",
type: "all",
gamemode: 'all',
difficulty: 'all',
Expand All @@ -142,15 +138,17 @@ export default {
list: [],
loading: true,
}
},
gamemodes: []
}
},
mounted() {
/*let routerPage = parseInt(this.$route.params.page);
if(isNaN(routerPage) || routerPage <= 0) routerPage = 1;
this.current_page = routerPage;*/
this.fetchCampaigns()
document.title = `Campaigns - L4D2 Stats Plugin`
this.fetchGamemodes()
this.fetchCampaigns()
},
watch: {
"filtered.filters": {
Expand All @@ -160,9 +158,34 @@ export default {
deep: true
}
},
computed: {
selectableGamemodes() {
const arr = []
for(const entry of Object.values(this.gamemodes)) {
const label = Settings.gamemodeLabels ? Settings.gamemodeLabels[entry.gamemode] : undefined
arr.push({
gamemode: entry.gamemode,
count: entry.count,
label: label ?? entry.gamemode
})
}
return arr
},
selectableTags() {
return Settings.selectableTags || []
}
},
methods: {
getMapName,
getMapImage,
async fetchGamemodes() {
try {
const res = await this.$http.get('/api/campaigns/values', { cache: true })
this.gamemodes = res.data.gamemodes
} catch(err) {
console.error("Could not fetch values: ", err)
}
},
fetchFilteredCampaigns() {
this.filtered.loading = true;
const queryParams = `?page=${this.filtered.filters.page}&perPage=16&tag=${this.filtered.filters.tag}&gamemode=${this.filtered.filters.gamemode}&type=${this.filtered.filters.type}&difficulty=${this.filtered.filters.difficulty}
Expand Down

0 comments on commit 2d475f2

Please sign in to comment.