Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions data/achievements.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

103 changes: 100 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const express = require("express");
const compression = require("compression");
const helmet = require("helmet");
const achievements = require('./data/achievements');
const m = require("./lib/functions");
const db = require("./lib/db");
let types = {
Expand Down Expand Up @@ -111,6 +112,52 @@ app.post('/api/searchVillages', async (req, res) => {
}
})

// search nations
app.post('/api/searchNations', async (req, res) => {
if(req.body['nation']) {
let nations = await m.getNations();

if(nations) {
let regex = new RegExp(req.body['nation'], 'i');
let filtered = nations.filter(e => regex.test(e.name));

if(filtered.length != 0) {
let n = [];
const promises = filtered.map(async (element) => {
let username = await m.searchUser(db, element.owner);
n.push({
owner: username ? username.username : 'Unknown',
owner_uuid: element.owner,
name: element.name,
uuid: element.uuid,
villages: element.villages
});
});

await Promise.all(promises);

res.json({
data: n,
status: true
});
}
else {
res.json({
status: false, code: 2, msg: "no nations found"
})
}
}
else {
res.json({
status: false, code: 2, msg: "no nations found"
})
}
}
else {
res.status(500).json({status: false, message: "invalid params"});
}
})

// online status
app.get('/api/online', async (req, res) => {
if(req.query['username']) {
Expand Down Expand Up @@ -203,6 +250,10 @@ app.get('/villages', (req, res) => {
res.render('villages');
});

app.get('/nations', (req, res) => {
res.render('nations');
});

// get the user villages
app.get('/api/user_villages', async (req, res) => {
if(req.query['uuid']) {
Expand Down Expand Up @@ -294,8 +345,21 @@ app.get('/player/:player', async (req, res) => {
if(req.params.player) {
let player = await m.searchUser(db, req.params.player);
if(player) {
let user = await(m.getUser(player['uuid']));
!user ? res.status(404).render('error', {status: '404', msg: 'User not found.'}) : res.render('player', {data: user,m});
let user = await m.getUser(player['uuid']);
if(!user) return res.status(404).render('error', {status: '404', msg: 'User not found.'});

let earnedAchievements = await m.getPlayerAchievements(player['uuid']);
// API may return objects with an `id` field or bare numeric IDs
const earnedIds = new Set(earnedAchievements.map(e => {
const val = typeof e === 'object' ? e.id : e;
return typeof val === 'string' ? parseInt(val, 10) : val;
}));
user.badges = achievements
.filter(a => earnedIds.has(a.id) && a.icon && (a.server || a.special))
.sort((a, b) => (b.server ? 1 : 0) - (a.server ? 1 : 0))
.map(a => ({ name: a.name, icon: a.icon, special: a.special, server: a.server }));

res.render('player', { data: user, m });
}
else {
res.status(404).render('error', {status: '500', msg: 'Oops! Minecraft user does not exist.'});
Expand Down Expand Up @@ -351,8 +415,41 @@ app.get('/village/:village', async (req, res) => {
});


app.get('/nation/:nation', async (req, res) => {
if(req.params.nation) {
let uuid = req.params.nation;

if(!m.isUUID(uuid)) {
let nations = await m.getNations();
if(nations) {
let found = nations.find(n => n.name.toLowerCase() === uuid.toLowerCase());
if(found) uuid = found.uuid;
else return res.status(404).render('error', {status: '404', msg: 'Oops! Nation does not exist.'});
}
else {
return res.status(404).render('error', {status: '404', msg: 'Oops! Nation does not exist.'});
}
}

let nation = await m.getNation(uuid);
if(nation && nation.found) {
let username = await m.searchUser(db, nation.owner);
nation.username = username ? username.username : 'Unknown';
nation.villageList = nation.villages || [];

res.render('nation', {data: nation, m});
}
else {
res.status(404).render('error', {status: '404', msg: 'Oops! Nation does not exist.'});
}
}
else {
res.status(500).render('error', {status: '500', msg: 'Oops! Invalid parameters.'});
}
});

app.get('*', (req, res) => {
res.status(404).render('error', {status: '404', msg: 'Page not found.'});
res.status(404).render('error', {status: '404', msg: 'Page not found.'});
});


Expand Down
43 changes: 38 additions & 5 deletions lib/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,30 @@ async function getVillages() {
return villages['villages'] && !villages['error'] ? villages['villages'] : false;
}

// get all nations
async function getNations() {
let nations = await request(process.env.nationsURL);
return nations['nations'] && !nations['error'] ? nations['nations'] : false;
}

// get a nation's information
async function getNation(uuid) {
let nation = await request(process.env.nationURL+uuid);
return nation && !nation['error'] ? nation : false;
}


// don't stress mojang api
async function searchUser(db, player) {
// check db first
let user = await db('player_data').where(!isUUID(player) ? {"username": player} : {"uuid": player}).select("username", "uuid");
let user = await db('player_data')
.whereRaw(
!isUUID(player)
? "LOWER(username) = LOWER(?)"
: "uuid = ?",
[player.trim()]
)
.select("username", "uuid");
if(user.length == 0) {

let p = await getMojangUser(player);
Expand Down Expand Up @@ -92,15 +111,25 @@ async function getUserVillage(uuid) {
// get user statistics
async function getUser(uuid) {
let u = await request(process.env.userURL+uuid);
return u && u['found'] ? u : false;
return u && u['found'] ? u : false;
}

// get player achievement completion from retromc api
async function getPlayerAchievements(uuid) {
let data = await request(`${process.env.achievementURL}?uuid=${uuid}`);
if (!data) return [];
// API may return an array directly or an object with an achievements property
if (Array.isArray(data)) return data;
if (Array.isArray(data.achievements)) return data.achievements;
return [];
}


// is this user online?

async function isPlayerOnline(username) {
let server = await getServer();
let r = [];
if(!server || !server['players']) return { online: false };
const userObject = server['players'].find(item => item.name === username);

return userObject ? {
Expand Down Expand Up @@ -281,6 +310,7 @@ async function getVillageName(db, uuid) {
}



async function updatePlayer(db, uuid, data) {
await db('player_data').where("uuid", uuid).update({
playerDeaths: data.playerDeaths,
Expand Down Expand Up @@ -334,7 +364,7 @@ function getRankColor(rank) {
case 'helper':
return '<span class="minecraft-dark-aqua minecraft-bold">Helper</span>';
case 'trooper':
return '<span class="minecraft-light-purple minecraft-bold">trooper</span>';
return '<span class="minecraft-light-purple minecraft-bold">Trooper</span>';
case 'donator':
return '<span class="minecraft-red">Donator</span>';
case 'donator+':
Expand Down Expand Up @@ -370,6 +400,8 @@ module.exports = {
getUserCape,
getServer,
getVillages,
getNations,
getNation,
getMojangUser,
getUserVillage,
getUser,
Expand All @@ -394,5 +426,6 @@ module.exports = {
isPlayerOnline,
getUsername,
getVillageName,
searchUser
searchUser,
getPlayerAchievements
}
Loading