Skip to content

Commit

Permalink
Automate fetching riot headers
Browse files Browse the repository at this point in the history
  • Loading branch information
giorgi-o committed May 24, 2024
1 parent 6c050a0 commit 8711058
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 98 deletions.
27 changes: 14 additions & 13 deletions discord/bot.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import {
ButtonBuilder,
ButtonStyle,
ActivityType,
ModalBuilder,
TextInputBuilder,
ModalBuilder,
TextInputBuilder,
TextInputStyle
} from "discord.js";
import cron from "node-cron";
Expand All @@ -37,7 +37,7 @@ import {
renderProfile,
renderCompetitiveMatchHistory
} from "./embed.js";
import { authUser, fetchRiotClientVersion, getUser, getUserList, getRegion, getUserInfo } from "../valorant/auth.js";
import { authUser, getUser, getUserList, getRegion, getUserInfo } from "../valorant/auth.js";
import { getBalance } from "../valorant/shop.js";
import { getSkin, fetchData, searchSkin, searchBundle, getBundle, clearCache } from "../valorant/cache.js";
import {
Expand All @@ -61,10 +61,11 @@ import {
fetchChannel, fetchMaintenances, getProxyManager, initProxyManager,
removeAlertActionRow,
skinNameAndEmoji,
valNamesToDiscordNames, WeaponTypeUuid,
WeaponTypeUuid,
WeaponType,
fetch,
calcLength
calcLength,
fetchRiotVersionData,
} from "../misc/util.js";
import config, { loadConfig, saveConfig } from "../misc/config.js";
import { localError, localLog, sendConsoleOutput } from "../misc/logger.js";
Expand Down Expand Up @@ -104,7 +105,7 @@ client.on("ready", async () => {

console.log("Loading skins...");
fetchData().then(() => console.log("Skins loaded!"));
fetchRiotClientVersion().then(() => console.log("Fetched latest Riot user-agent!"));
fetchRiotVersionData().then(() => console.log("Fetched latest Riot user-agent!"));
initProxyManager().then(() => {
if (getProxyManager().enabled) {
console.log(`Proxy manager loaded ${getProxyManager().allProxies.length} proxies!`);
Expand Down Expand Up @@ -158,7 +159,7 @@ export const scheduleTasks = () => {
if (config.logToChannel && config.logFrequency) cronTasks.push(cron.schedule(config.logFrequency, sendConsoleOutput));

// check for a new riot client version (new user agent) every 15mins
if (config.updateUserAgent) cronTasks.push(cron.schedule(config.updateUserAgent, fetchRiotClientVersion));
if (config.updateUserAgent) cronTasks.push(cron.schedule(config.updateUserAgent, fetchRiotVersionData));
}

export const destroyTasks = () => {
Expand Down Expand Up @@ -905,7 +906,7 @@ client.on("interactionCreate", async (interaction) => {
embeds: [basicEmbed(s(interaction).info.ACCOUNT_UPDATED.f({ u: user.username }, interaction))],
});
break;
}
}
case "testalerts": {
if (!valorantUser) return await interaction.reply({
embeds: [basicEmbed(s(interaction).error.NOT_REGISTERED)],
Expand All @@ -925,7 +926,7 @@ client.on("interactionCreate", async (interaction) => {
}
case "login": {
await defer(interaction, true);

const json = readUserJson(interaction.user.id);
if (json && json.accounts.length >= config.maxAccountsPerUser) {
return await interaction.followUp({
Expand Down Expand Up @@ -979,7 +980,7 @@ client.on("interactionCreate", async (interaction) => {

break;
}
case "logout":
case "logout":
case "forget": {
const accountCount = getNumberOfAccounts(interaction.user.id);
if (accountCount === 0) return await interaction.reply({
Expand Down Expand Up @@ -1631,14 +1632,14 @@ client.on("interactionCreate", async (interaction) => {

async function clwpage() {
const weaponType = Object.values(WeaponTypeUuid)[parseInt(weaponTypeIndex)];

let user;
if (userId !== interaction.user.id) user = getUser(userId);
else user = valorantUser;

const skinsResponse = await getSkins(user);
if (!skinsResponse.success) return await interaction.reply(authFailureMessage(interaction, skinsResponse, s(interaction).error.AUTH_ERROR_COLLECTION, userId !== interaction.user.id));

await interaction.update(await collectionOfWeaponEmbed(interaction, userId, user, weaponType, skinsResponse.skins, parseInt(pageIndex-1)));
}
}
Expand Down
11 changes: 7 additions & 4 deletions misc/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,18 @@ export const loadConfig = (filename="config.json") => {
return console.error("You forgot to put your bot token in config.json!");

if(loadedConfig.HDevTokenAlert && !loadedConfig.HDevToken || loadedConfig.HDevToken === ""){
console.error("You forgot to put your HDevToken in config.json!");
console.error("The Profile command works without an HDEV token, but you can view up to 2 different accounts per hour.");
console.error("If you need more than 2 accounts per hour, see https://discord.gg/B7AarTMZMK");
console.error("If you don't want to see this notification again, set HDevTokenAlert to false in config.json file");
console.error("Looks like you didn't put a HDevToken in config.json!");
console.error("The /profile command won't work without one. To get a key, see https://discord.gg/B7AarTMZMK");
console.error("If you don't want to see this notification again, set HDevTokenAlert to false in config.json");
}

// backwards compatibility
loadedConfig.fetchSkinPrices = loadedConfig.showSkinPrices;
loadedConfig.fetchSkinRarities = loadedConfig.showSkinRarities;

// to see what these keys do, check here:
// https://github.com/giorgi-o/SkinPeek/wiki/SkinPeek-Admin-Guide#the-option-list

applyConfig(loadedConfig, "token", "token goes here");
applyConfig(loadedConfig, "HDevToken", "");
applyConfig(loadedConfig, "HDevTokenAlert", true);
Expand Down
59 changes: 59 additions & 0 deletions misc/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,65 @@ export const itemTypes = {
TITLE: "de7caa6b-adf7-4588-bbd1-143831e786c6"
}

// example riotVersionData: {
// "manifestId": "C330A20409C5FDF2",
// "branch": "release-08.09",
// "version": "08.09.00.2521387",
// "buildVersion": "57",
// "engineVersion": "4.27.2.0",
// "riotClientVersion": "release-08.09-shipping-57-2521387",
// "riotClientBuild": "86.0.3.1523.3366",
// "buildDate": "2024-05-13T00:00:00Z"
// }
let riotVersionData = null;

export const getRiotVersionData = () => {
if(riotVersionData === null) {
throw "Tried to get Riot version data before it was loaded! Might be a race condition.";
}

return riotVersionData;
}

export const fetchRiotVersionData = async () => {
console.log("Fetching latest Valorant version number...");

const req = await fetch("https://valorant-api.com/v1/version");
if(req.statusCode !== 200) {
console.log(`Riot version data status code is ${req.statusCode}!`);
console.log(req);

return null;
}

const json = JSON.parse(req.body);
riotVersionData = json.data;

return riotVersionData;
}

// TODO: find out what how to automatically get the latest one of these
const platformOsVersion = "10.0.19042.1.256.64bit";

export const riotClientHeaders = () => {
const clientPlatformData = {
platformType: "PC",
platformOS: "Windows",
platformOSVersion: platformOsVersion,
platformChipset: "Unknown",
}

// JSON stringify prettyfied with 1 tab and \r\n, then base64 encode
const clientPlatformDataJson = JSON.stringify(clientPlatformData, null, "\t");
const clientPlatformDataBuffer = Buffer.from(clientPlatformDataJson.replace(/\n/g, "\r\n"));
const clientPlatformDataBase64 = clientPlatformDataBuffer.toString("base64");

return {
"X-Riot-ClientPlatform": clientPlatformDataBase64,
"X-Riot-ClientVersion": getRiotVersionData().riotClientVersion,
}
}

export const parseSetCookie = (setCookie) => {
if(!setCookie) {
console.error("Riot didn't return any cookies during the auth request! Cloudflare might have something to do with it...");
Expand Down
62 changes: 1 addition & 61 deletions valorant/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -389,72 +389,12 @@ export const refreshToken = async (id, account=null) => {
return response;
}

let riotClientVersion;
let userAgentFetchPromise;
export const fetchRiotClientVersion = async (attempt=1) => {
if(userAgentFetchPromise) return userAgentFetchPromise;

let resolve;
if(!userAgentFetchPromise) {
console.log("Fetching latest Riot user-agent..."); // only log it the first time
userAgentFetchPromise = new Promise(r => resolve = r);
}

const headers = {
"User-Agent": "giorgi-o/skinpeek",
"X-GitHub-Api-Version": "2022-11-28",
};
if(config.githubToken) headers["Authorization"] = `Bearer ${config.githubToken}`;

const githubReq = await fetch("https://api.github.com/repos/Morilli/riot-manifests/contents/Riot%20Client/KeystoneFoundationLiveWin?ref=master", {
headers
});

let json, versions, error = false;
try {
if(githubReq.statusCode !== 200) error = true;
else {
json = JSON.parse(githubReq.body);
versions = json.map(file => file.name.split('_')[0]);
}
} catch(e) {
error = true
}

if(error) {
if(attempt === 3) {
console.error("Failed to fetch latest Riot user-agent! (tried 3 times)");

const fallbackVersion = "65.0.2.5073401";
console.error(`Using version number ${fallbackVersion} instead...`);
}

console.error(`Failed to fetch latest Riot user-agent! (try ${attempt}/3`);
console.error(githubReq);

await wait(1000);
return fetchRiotClientVersion(attempt + 1);
}

const compareVersions = (a, b) => {
const aSplit = a.split(".");
const bSplit = b.split(".");
for(let i = 0; i < aSplit.length; i++) {
if(aSplit[i] > bSplit[i]) return 1;
if(aSplit[i] < bSplit[i]) return -1;
}
return 0;
}
versions.sort((a, b) => compareVersions(b, a));

riotClientVersion = versions[0];
userAgentFetchPromise = null;
resolve?.();
}

const getUserAgent = async () => {
// temporary bypass for Riot adding hCaptcha (see github issue #93)
return "ShooterGame/11 Windows/10.0.22621.1.768.64bit";
return "ShooterGame/13 Windows/10.0.19043.1.256.64bit";

if(!riotClientVersion) await fetchRiotClientVersion();
return `RiotClient/${riotClientVersion}.1234567 rso-auth (Windows;10;;Professional, x64)`;
Expand Down
3 changes: 1 addition & 2 deletions valorant/battlepass.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@

import {authUser, deleteUserAuth, getUser} from "./auth.js";
import {fetch, isMaintenance, userRegion} from "../misc/util.js";
import {fetch, isMaintenance, riotClientHeaders, userRegion} from "../misc/util.js";
import {getBattlepassInfo, getBuddy, getCard, getSkin, getSpray, getValorantVersion} from "./cache.js";
import { RIOT_CLIENT_HEADERS } from "./shop.js";
import {renderBattlepass} from "../discord/embed.js";
import {getEntitlements} from "./inventory.js";
import {l, s} from "../misc/languages.js";
Expand Down
2 changes: 1 addition & 1 deletion valorant/cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import fs from "fs";
import { DEFAULT_VALORANT_LANG, discToValLang } from "../misc/languages.js";
import { client } from "../discord/bot.js";
import { sendShardMessage } from "../misc/shardMessage.js";
import { RIOT_CLIENT_HEADERS } from "./shop.js";
import { riotClientHeaders } from "../misc/util.js";

const formatVersion = 14;
let gameVersion;
Expand Down
8 changes: 4 additions & 4 deletions valorant/inventory.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {authUser, deleteUserAuth, getUser} from "./auth.js";
import {authFailureMessage, basicEmbed, skinCollectionSingleEmbed, collectionOfWeaponEmbed} from "../discord/embed.js";
import config from "../misc/config.js";
import {s} from "../misc/languages.js";
import { RIOT_CLIENT_HEADERS } from "./shop.js";
import {riotClientHeaders} from "../misc/util.js";


export const getEntitlements = async (user, itemTypeId, itemType="item") => {
Expand All @@ -12,7 +12,7 @@ export const getEntitlements = async (user, itemTypeId, itemType="item") => {
headers: {
"Authorization": "Bearer " + user.auth.rso,
"X-Riot-Entitlements-JWT": user.auth.ent,
...RIOT_CLIENT_HEADERS,
...riotClientHeaders(),
}
});

Expand Down Expand Up @@ -94,7 +94,7 @@ export const getLoadout = async (user, account) => {
headers: {
"Authorization": "Bearer " + user.auth.rso,
"X-Riot-Entitlements-JWT": user.auth.ent,
...RIOT_CLIENT_HEADERS,
...riotClientHeaders(),
}
});

Expand All @@ -111,7 +111,7 @@ export const getLoadout = async (user, account) => {
headers: {
"Authorization": "Bearer " + user.auth.rso,
"X-Riot-Entitlements-JWT": user.auth.ent,
...RIOT_CLIENT_HEADERS,
...riotClientHeaders(),
}
});

Expand Down
15 changes: 2 additions & 13 deletions valorant/shop.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,6 @@ import config from "../misc/config.js";
import { deleteUser, saveUser } from "./accountSwitcher.js";
import { mqGetShop, useMultiqueue } from "../misc/multiqueue.js";

export const RIOT_CLIENT_HEADERS = {
// fix for HTTP 400 (thx Zxc and Manuel_Hexe)
"X-Riot-ClientPlatform": "ew0KCSJwbGF0Zm9ybVR5cGUiOiAiUEMiLA0KCSJwbGF0Zm9ybU9TIjogIldpbmRvd3MiLA0KCSJwbGF0Zm9ybU9TVmVyc2lvbiI6ICIxMC4wLjE5MDQyLjEuMjU2LjY0Yml0IiwNCgkicGxhdGZvcm1DaGlwc2V0IjogIlVua25vd24iDQp9",
"X-Riot-ClientVersion": "release-08.09-shipping-57-2521387",
// todo: get ClientVersion from Valorant API to not have to automatically update it.
// before that, got to make a cache for it, so that we don't need to fetch it
// every time someone uses /shop, but make sure it doesn't interfere with all
// the other caches (skins, rarities, etc.) because those need the actual
// uncached client version.
}

export const getShop = async (id, account = null) => {
if (useMultiqueue()) return await mqGetShop(id, account);

Expand All @@ -40,7 +29,7 @@ export const getShop = async (id, account = null) => {
headers: {
"Authorization": "Bearer " + user.auth.rso,
"X-Riot-Entitlements-JWT": user.auth.ent,
...RIOT_CLIENT_HEADERS
...riotClientHeaders(),
}
});
console.assert(req.statusCode === 200, `Valorant skins offers code is ${req.statusCode}!`, req);
Expand Down Expand Up @@ -135,7 +124,7 @@ export const getBalance = async (id, account = null) => {
headers: {
"Authorization": "Bearer " + user.auth.rso,
"X-Riot-Entitlements-JWT": user.auth.ent,
...RIOT_CLIENT_HEADERS
...riotClientHeaders(),
}
});
console.assert(req.statusCode === 200, `Valorant balance code is ${req.statusCode}!`, req);
Expand Down

0 comments on commit 8711058

Please sign in to comment.