Skip to content

Commit

Permalink
Added Steam API download #8
Browse files Browse the repository at this point in the history
  • Loading branch information
EwanLyon committed Dec 23, 2020
1 parent 376e481 commit 2e0b6ad
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 5 deletions.
4 changes: 4 additions & 0 deletions configschema.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
"description": "Port to listen for HLAE game events",
"default": 31337
},
"steamApiKey": {
"type": "string",
"description": "Steam API key used to get steam profile pictures (https://steamcommunity.com/dev/apikey)"
},
"gameSettings": {
"type": "object",
"description": "Various server setting information to properly display data",
Expand Down
30 changes: 29 additions & 1 deletion package-lock.json

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

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nodecg-csgo-manager",
"version": "0.2.0",
"version": "0.3.0",
"description": "Layouts for CSGO spectating",
"homepage": "",
"author": {
Expand Down Expand Up @@ -111,6 +111,7 @@
"gsap": "^3.5.1",
"livesplit-core": "^0.10.2",
"lodash": "^4.17.20",
"node-fetch": "^2.6.1",
"nodecg": "^1.7.4",
"parcel": "^1.12.4",
"react": "^16.14.0",
Expand All @@ -128,6 +129,7 @@
"devDependencies": {
"@types/deep-equal": "^1.0.1",
"@types/lodash": "^4.14.165",
"@types/node-fetch": "^2.5.7",
"@types/react-beautiful-dnd": "^13.0.0",
"@types/react-dom": "^16.9.10",
"@types/styled-components": "^5.1.7",
Expand Down
9 changes: 8 additions & 1 deletion src/dashboard/setup/teams/teams.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,17 @@ export const Teams: React.FunctionComponent = () => {
<Button
variant="contained"
style={{ marginTop: 10 }}
onClick={(): void => setSwapTeamsRep(!swapTeamsRep)}
onClick={() => setSwapTeamsRep(!swapTeamsRep)}
>
Swap Teams
</Button>
<Button
variant="contained"
style={{ marginTop: 10 }}
onClick={() => nodecg.sendMessage('getAllProfileData')}
>
Download steam profiles
</Button>
</Grid>
<Grid
container
Expand Down
65 changes: 63 additions & 2 deletions src/extension/extraData.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import * as nodecgApiContext from './util/nodecg-api-context';
import * as SteamAPI from './util/steam-api';
import _ from 'lodash';

import { CSGOOutputAllplayer, CSGOOutputPhaseCountdowns, Map } from '../types/csgo-gsi';
import { PlayerDataAll, TeamData } from '../types/extra-data';
import { ExtraMapData } from '../types/map-data';
Expand Down Expand Up @@ -38,8 +41,6 @@ function currentTeamSide(round: number): boolean {

// SETTING TEAMONE AND TEAMTWO PLAYERS
function refreshTeamPlayers(): void {
nodecg.log.info(`Updating players list`);

const teamOneList: string[] = [];
const teamTwoList: string[] = [];
allPlayersRep.value.forEach(player => {
Expand Down Expand Up @@ -287,6 +288,62 @@ nodecg.listenFor('reorderMaps', newOrder => {
mapDataRep.value = newOrder;
});

// Steam Profile Pictures
nodecg.listenFor('getAllSteamProfilePictures', () => {
getAllPlayersProfilePictures();
});

nodecg.listenFor('getAllProfileData', () => {
getAllProfileData();
});

function getAllPlayersProfilePictures(overwrite = false) {
const playerData = _.cloneDeep(playerDataRep.value);

const steamIds = Object.keys(playerData);

SteamAPI.getProfilePictures(steamIds).then(pfps => {
pfps.forEach((pfp) => {
// Default question mark PFP
if (pfp.pfp !== 'https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/fe/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb_full.jpg') {
// Overwrite all player profile pictures else just do ones that dont have one
if (overwrite) {
playerData[pfp.id].image = pfp.pfp;
} else if (!playerData[pfp.id].image) {
playerData[pfp.id].image = pfp.pfp;
}
}
});
});

playerDataRep.value = playerData;
}

function getAllProfileData(overwrite = false) {
const playerData = _.cloneDeep(playerDataRep.value);

const steamIds = Object.keys(playerData);

SteamAPI.getProfileData(steamIds).then(pfps => {
pfps.forEach((profileData) => {
// Default question mark PFP
if (profileData.pfp !== 'https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/fe/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb_full.jpg') {
// Overwrite all player profile pictures else just do ones that dont have one
if (overwrite) {
playerData[profileData.steamid].image = profileData.pfp;
} else if (!playerData[profileData.steamid].image) {
playerData[profileData.steamid].image = profileData.pfp;
}
}

playerData[profileData.steamid].name = profileData.realname;
playerData[profileData.steamid].country = Array.from(profileData.country || '').map(letterToLetterEmoji).join('');
});
});

playerDataRep.value = playerData;
}

function sumGrenades(players: CSGOOutputAllplayer[]): TeamData['grenades'] {
const nades = {
he: 0,
Expand Down Expand Up @@ -324,3 +381,7 @@ function sumGrenades(players: CSGOOutputAllplayer[]): TeamData['grenades'] {

return nades;
}

function letterToLetterEmoji(letter: string) {
return String.fromCodePoint(letter.toLowerCase().charCodeAt(0) + 127365);
}
46 changes: 46 additions & 0 deletions src/extension/util/steam-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as nodecgApiContext from './nodecg-api-context';
import fetch from 'node-fetch';
const nodecg = nodecgApiContext.get();

interface SteamProfileData {
steamid: string;
pfp: string;
country?: string;
realname?: string;
}

export async function getProfilePicture(steamid: string): Promise<{ id: string, pfp: string }[]> {
if (nodecg.bundleConfig.steamApiKey) {
const json = await fetch(`http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=${nodecg.bundleConfig.steamApiKey}&steamids=${steamid}`).then(res => res.json());
return json.response.players.map((player: Record<string, any>) => {
return { id: player.steamid, pfp: player.avatarfull }
});
}

return [];
}

export async function getProfilePictures(steamids: string[]) {
if (steamids.length > 100) {
throw new Error("Cannot request over 100 steam ids");
}

const joinedSteamIds = steamids.join(',');
return await getProfilePicture(joinedSteamIds);
}

export async function getProfileData(steamids: string[]): Promise<SteamProfileData[]> {
if (steamids.length > 100) {
throw new Error("Cannot request over 100 steam ids");
}

const joinedSteamIds = steamids.join(',');
if (nodecg.bundleConfig.steamApiKey) {
const json = await fetch(`http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=${nodecg.bundleConfig.steamApiKey}&steamids=${joinedSteamIds}`).then(res => res.json());
return json.response.players.map((player: Record<string, any>) => {
return { steamid: player.steamid, pfp: player.avatarfull, country: player.loccountrycode, realname: player.realname } as SteamProfileData;
});
}

return [];
}

0 comments on commit 2e0b6ad

Please sign in to comment.