Add files via upload

This commit is contained in:
Lawin0129
2022-10-14 21:24:53 +01:00
committed by GitHub
parent 498c1a769d
commit 42d5bbd462
59 changed files with 88937 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
[OnlineSubsystemMcp.Xmpp]
bUseSSL=false
ServerAddr="ws://127.0.0.1:80"
ServerPort=80
[OnlineSubsystemMcp.Xmpp Prod]
bUseSSL=false
ServerAddr="ws://127.0.0.1:80"
ServerPort=80
[OnlineSubsystemMcp]
bUsePartySystemV2=false
[OnlineSubsystemMcp.OnlinePartySystemMcpAdapter]
bUsePartySystemV2=false
+8
View File
@@ -0,0 +1,8 @@
[/Script/FortniteGame.FortGlobals]
bAllowLogout=true
[/Script/FortniteGame.FortChatManager]
bShouldRequestGeneralChatRooms=true
bShouldJoinGlobalChat=true
bShouldJoinFounderChat=true
bIsAthenaGlobalChatEnabled=true
+3
View File
@@ -0,0 +1,3 @@
[/Script/Engine.InputSettings]
+ConsoleKeys=Tilde
+ConsoleKeys=F8
+2
View File
@@ -0,0 +1,2 @@
[/Script/FortniteGame.FortRuntimeOptions]
bEnableGlobalChat=true
File diff suppressed because it is too large Load Diff
+24
View File
@@ -0,0 +1,24 @@
{
"created": "",
"updated": "",
"rvn": 0,
"wipeNumber": 1,
"accountId": "",
"profileId": "campaign",
"version": "no_version",
"items": {
"Token:lawinserver": {
"templateId": "Token:lawinserver",
"attributes": {
"item_seen": true
},
"quantity": 1
}
},
"stats": {
"attributes": {
"inventory_limit_bonus": 0
}
},
"commandRevision": 0
}
@@ -0,0 +1,24 @@
{
"created": "",
"updated": "",
"rvn": 0,
"wipeNumber": 1,
"accountId": "",
"profileId": "collection_book_people0",
"version": "no_version",
"items": {
"Token:lawinserver": {
"templateId": "Token:lawinserver",
"attributes": {
"item_seen": true
},
"quantity": 1
}
},
"stats": {
"attributes": {
"inventory_limit_bonus": 0
}
},
"commandRevision": 0
}
@@ -0,0 +1,24 @@
{
"created": "",
"updated": "",
"rvn": 0,
"wipeNumber": 1,
"accountId": "",
"profileId": "collection_book_schematics0",
"version": "no_version",
"items": {
"Token:lawinserver": {
"templateId": "Token:lawinserver",
"attributes": {
"item_seen": true
},
"quantity": 1
}
},
"stats": {
"attributes": {
"inventory_limit_bonus": 0
}
},
"commandRevision": 0
}
+24
View File
@@ -0,0 +1,24 @@
{
"created": "",
"updated": "",
"rvn": 0,
"wipeNumber": 1,
"accountId": "",
"profileId": "collections",
"version": "no_version",
"items": {
"Token:lawinserver": {
"templateId": "Token:lawinserver",
"attributes": {
"item_seen": true
},
"quantity": 1
}
},
"stats": {
"attributes": {
"inventory_limit_bonus": 0
}
},
"commandRevision": 0
}
File diff suppressed because it is too large Load Diff
+24
View File
@@ -0,0 +1,24 @@
{
"created": "",
"updated": "",
"rvn": 0,
"wipeNumber": 1,
"accountId": "",
"profileId": "common_public",
"version": "no_version",
"items": {
"Token:lawinserver": {
"templateId": "Token:lawinserver",
"attributes": {
"item_seen": true
},
"quantity": 1
}
},
"stats": {
"attributes": {
"inventory_limit_bonus": 0
}
},
"commandRevision": 0
}
+24
View File
@@ -0,0 +1,24 @@
{
"created": "",
"updated": "",
"rvn": 0,
"wipeNumber": 1,
"accountId": "",
"profileId": "creative",
"version": "no_version",
"items": {
"Token:lawinserver": {
"templateId": "Token:lawinserver",
"attributes": {
"item_seen": true
},
"quantity": 1
}
},
"stats": {
"attributes": {
"inventory_limit_bonus": 0
}
},
"commandRevision": 0
}
+24
View File
@@ -0,0 +1,24 @@
{
"created": "",
"updated": "",
"rvn": 0,
"wipeNumber": 1,
"accountId": "",
"profileId": "metadata",
"version": "no_version",
"items": {
"Token:lawinserver": {
"templateId": "Token:lawinserver",
"attributes": {
"item_seen": true
},
"quantity": 1
}
},
"stats": {
"attributes": {
"inventory_limit_bonus": 0
}
},
"commandRevision": 0
}
+24
View File
@@ -0,0 +1,24 @@
{
"created": "",
"updated": "",
"rvn": 0,
"wipeNumber": 1,
"accountId": "",
"profileId": "outpost0",
"version": "no_version",
"items": {
"Token:lawinserver": {
"templateId": "Token:lawinserver",
"attributes": {
"item_seen": true
},
"quantity": 1
}
},
"stats": {
"attributes": {
"inventory_limit_bonus": 0
}
},
"commandRevision": 0
}
File diff suppressed because it is too large Load Diff
+24
View File
@@ -0,0 +1,24 @@
{
"created": "",
"updated": "",
"rvn": 0,
"wipeNumber": 1,
"accountId": "",
"profileId": "recycle_bin",
"version": "no_version",
"items": {
"Token:lawinserver": {
"templateId": "Token:lawinserver",
"attributes": {
"item_seen": true
},
"quantity": 1
}
},
"stats": {
"attributes": {
"inventory_limit_bonus": 0
}
},
"commandRevision": 0
}
+24
View File
@@ -0,0 +1,24 @@
{
"created": "",
"updated": "",
"rvn": 0,
"wipeNumber": 1,
"accountId": "",
"profileId": "theater0",
"version": "no_version",
"items": {
"Token:lawinserver": {
"templateId": "Token:lawinserver",
"attributes": {
"item_seen": true
},
"quantity": 1
}
},
"stats": {
"attributes": {
"inventory_limit_bonus": 0
}
},
"commandRevision": 0
}
+24
View File
@@ -0,0 +1,24 @@
{
"created": "",
"updated": "",
"rvn": 0,
"wipeNumber": 1,
"accountId": "",
"profileId": "theater1",
"version": "no_version",
"items": {
"Token:lawinserver": {
"templateId": "Token:lawinserver",
"attributes": {
"item_seen": true
},
"quantity": 1
}
},
"stats": {
"attributes": {
"inventory_limit_bonus": 0
}
},
"commandRevision": 0
}
+24
View File
@@ -0,0 +1,24 @@
{
"created": "",
"updated": "",
"rvn": 0,
"wipeNumber": 1,
"accountId": "",
"profileId": "theater2",
"version": "no_version",
"items": {
"Token:lawinserver": {
"templateId": "Token:lawinserver",
"attributes": {
"item_seen": true
},
"quantity": 1
}
},
"stats": {
"attributes": {
"inventory_limit_bonus": 0
}
},
"commandRevision": 0
}
+9
View File
@@ -0,0 +1,9 @@
{
"moderators": ["discordId"],
"discord": {
"bot_token": ""
},
"mongodb": {
"database": "mongodb://127.0.0.1/lawindb"
}
}
+55
View File
@@ -0,0 +1,55 @@
const { MessageEmbed } = require("discord.js");
const User = require("../../model/user.js");
const config = require("../../Config/config.json");
module.exports = {
commandInfo: {
name: "ban",
description: "Ban a user from the backend by their username.",
options: [
{
name: "username",
description: "Target username.",
required: true,
type: 3 // string
}
]
},
execute: async (interaction) => {
let msg = "";
if (!config.moderators.includes(interaction.user.id)) return interaction.reply({ content: "You do not have moderator permissions.", ephemeral: true });
const { options } = interaction;
const targetUser = await User.findOne({ username_lower: (options.get("username").value).toLowerCase() });
if (!targetUser) msg = "The account username you entered does not exist.";
else if (targetUser.banned == true) msg = "This account is already banned.";
if (targetUser && targetUser.banned != true) {
await targetUser.updateOne({ $set: { banned: true } });
if (global.accessTokens.find(i => i.accountId == targetUser.accountId)) {
global.accessTokens.splice(global.accessTokens.findIndex(i => i.accountId == targetUser.accountId), 1);
global.refreshTokens.splice(global.refreshTokens.findIndex(i => i.accountId == targetUser.accountId), 1);
}
if (global.Clients.find(client => client.accountId == targetUser.accountId)) {
var ClientData = global.Clients.find(client => client.accountId == targetUser.accountId);
ClientData.client.close();
}
msg = `Successfully banned ${targetUser.username}`;
}
let embed = new MessageEmbed()
.setAuthor({ name: "Moderation", iconURL: "https://cdn.discordapp.com/attachments/927739901540188200/1020458073019666492/unknown.png" })
.setFields(
{ name: "Message", value: msg },
)
.setTimestamp()
interaction.reply({ embeds: [embed], ephemeral: true });
}
}
+35
View File
@@ -0,0 +1,35 @@
const { MessageEmbed } = require("discord.js");
const User = require("../../model/user.js");
const bcrypt = require("bcrypt");
module.exports = {
commandInfo: {
name: "change-password",
description: "Change your password.",
options: [
{
name: "password",
description: "Your new password.",
required: true,
type: 3 // string
}
]
},
execute: async (interaction) => {
const user = await User.findOne({ discordId: interaction.user.id });
if (!user) return interaction.reply({ content: "You do not have a registered account!", ephemeral: true });
const { options } = interaction;
let plainPassword = options.get("password").value;
if (plainPassword.length >= 128) return interaction.reply({ content: "Your password must be less than 128 characters long.", ephemeral: true });
if (plainPassword.length < 8) return interaction.reply({ content: "Your password must be atleast 8 characters long.", ephemeral: true });
let hashedPassword = await bcrypt.hash(plainPassword, 10);
await user.updateOne({ $set: { password: hashedPassword } });
interaction.reply({ content: `Successfully changed your password.`, ephemeral: true });
}
}
+36
View File
@@ -0,0 +1,36 @@
const { MessageEmbed } = require("discord.js");
const User = require("../../model/user.js");
module.exports = {
commandInfo: {
name: "change-username",
description: "Change your username.",
options: [
{
name: "username",
description: "Your new username.",
required: true,
type: 3 // string
}
]
},
execute: async (interaction) => {
const user = await User.findOne({ discordId: interaction.user.id });
if (!user) return interaction.reply({ content: "You do not have a registered account!", ephemeral: true });
const { options } = interaction;
let username = options.get("username").value;
if (username.length >= 25) return interaction.reply({ content: "Your username must be less than 25 characters long.", ephemeral: true });
if (username.length < 3) return interaction.reply({ content: "Your username must be atleast 3 characters long.", ephemeral: true });
try {
await user.updateOne({ $set: { username: username, username_lower: username.toLowerCase() } });
} catch (err) {
return interaction.reply({ content: "This username is already in use!", ephemeral: true });
}
interaction.reply({ content: `Successfully changed your username to ${username}`, ephemeral: true });
}
}
+62
View File
@@ -0,0 +1,62 @@
const { MessageEmbed } = require("discord.js");
const functions = require("../../structs/functions.js");
module.exports = {
commandInfo: {
name: "create",
description: "Creates an account on Lawin.",
options: [
{
name: "email",
description: "Your email.",
required: true,
type: 3 // string
},
{
name: "username",
description: "Your username.",
required: true,
type: 3
},
{
name: "password",
description: "Your password.",
required: true,
type: 3
}
],
},
execute: async (interaction) => {
const { options } = interaction;
const discordId = interaction.user.id;
const email = options.get("email").value;
const username = options.get("username").value;
const password = options.get("password").value;
await functions.registerUser(discordId, username, email, password).then(resp => {
if (resp.status >= 400) {
let embed = new MessageEmbed()
.setColor("#ff0000")
.setAuthor({ name: interaction.user.tag, iconURL: interaction.user.avatarURL() })
.setFields(
{ name: 'Message', value: resp.message }
)
.setTimestamp()
return interaction.reply({ embeds: [embed], ephemeral: true })
}
let embed = new MessageEmbed()
.setColor("#56ff00")
.setAuthor({ name: interaction.user.tag, iconURL: interaction.user.avatarURL() })
.setFields(
{ name: 'Message', value: resp.message },
)
.setTimestamp()
interaction.channel.send({ embeds: [embed] });
interaction.reply({ content: "You successfully created an account!", ephemeral: true })
})
}
}
+26
View File
@@ -0,0 +1,26 @@
const { MessageEmbed } = require("discord.js");
const User = require("../../model/user.js");
module.exports = {
commandInfo: {
name: "details",
description: "Retrieves your account info."
},
execute: async (interaction) => {
const user = await User.findOne({ discordId: interaction.user.id }).lean();
if (!user) return interaction.reply({ content: "You do not have a registered account!", ephemeral: true });
let embed = new MessageEmbed()
.setColor("#56ff00")
.setAuthor({ name: interaction.user.tag, iconURL: interaction.user.avatarURL() })
.setFields(
{ name: "Banned?", value: `${user.banned}` },
{ name: "Account ID", value: user.accountId },
{ name: 'Username', value: user.username },
{ name: 'Email', value: user.email }
)
.setTimestamp()
interaction.reply({ embeds: [embed], ephemeral: true });
}
}
+38
View File
@@ -0,0 +1,38 @@
const { MessageEmbed } = require("discord.js");
const User = require("../../model/user.js");
const functions = require("../../structs/functions.js");
module.exports = {
commandInfo: {
name: "exchange-code",
description: "Generates an exchange code for login. (One time use and expires after 5 mins)."
},
execute: async (interaction) => {
const user = await User.findOne({ discordId: interaction.user.id }).lean();
if (!user) return interaction.reply({ content: "You do not have a registered account!", ephemeral: true });
let exchange_code = functions.MakeID().replace(/-/ig, "");
global.exchangeCodes.push({
accountId: user.accountId,
exchange_code: exchange_code,
creatingClientId: ""
});
setTimeout(() => {
if (global.exchangeCodes.find(i => i.exchange_code == exchange_code)) {
global.exchangeCodes.splice(global.exchangeCodes.findIndex(i => i.exchange_code == exchange_code), 1)
}
}, 300000)
let embed = new MessageEmbed()
.setColor("#56ff00")
.setAuthor({ name: interaction.user.tag, iconURL: interaction.user.avatarURL() })
.setFields(
{ name: "Exchange Code", value: exchange_code }
)
.setTimestamp()
interaction.reply({ content: "Successfully generated an exchange code.", embeds: [embed], ephemeral: true });
}
}
+57
View File
@@ -0,0 +1,57 @@
const { MessageEmbed } = require("discord.js");
const User = require("../../model/user.js");
const config = require("../../Config/config.json");
module.exports = {
commandInfo: {
name: "kick",
description: "Kick someone out of their current session by their username.",
options: [
{
name: "username",
description: "Target username.",
required: true,
type: 3 // string
}
]
},
execute: async (interaction) => {
let msg = "";
if (!config.moderators.includes(interaction.user.id)) return interaction.reply({ content: "You do not have moderator permissions.", ephemeral: true });
const { options } = interaction;
const targetUser = await User.findOne({ username_lower: (options.get("username").value).toLowerCase() });
if (!targetUser) msg = "The account username you entered does not exist.";
if (targetUser) {
let removed = false;
if (global.accessTokens.find(i => i.accountId == targetUser.accountId)) {
global.accessTokens.splice(global.accessTokens.findIndex(i => i.accountId == targetUser.accountId), 1);
global.refreshTokens.splice(global.refreshTokens.findIndex(i => i.accountId == targetUser.accountId), 1);
removed = true;
}
if (global.Clients.find(client => client.accountId == targetUser.accountId)) {
var ClientData = global.Clients.find(client => client.accountId == targetUser.accountId);
ClientData.client.close();
}
if (removed) msg = `Successfully kicked ${targetUser.username}`;
else msg = `There are no current active sessions by ${targetUser.username}`;
}
let embed = new MessageEmbed()
.setAuthor({ name: "Moderation", iconURL: "https://cdn.discordapp.com/attachments/927739901540188200/1020458073019666492/unknown.png" })
.setFields(
{ name: "Message", value: msg },
)
.setTimestamp()
interaction.reply({ embeds: [embed], ephemeral: true });
}
}
+43
View File
@@ -0,0 +1,43 @@
const { MessageEmbed } = require("discord.js");
const User = require("../../model/user.js");
const config = require("../../Config/config.json");
module.exports = {
commandInfo: {
name: "unban",
description: "Unban a user from the backend by their username.",
options: [
{
name: "username",
description: "Target username.",
required: true,
type: 3 // string
}
]
},
execute: async (interaction) => {
let msg = "";
if (!config.moderators.includes(interaction.user.id)) return interaction.reply({ content: "You do not have moderator permissions.", ephemeral: true });
const { options } = interaction;
const targetUser = await User.findOne({ username_lower: (options.get("username").value).toLowerCase() });
if (!targetUser) msg = "The account username you entered does not exist.";
else if (targetUser.banned == false) msg = "This account is already unbanned.";
if (targetUser && targetUser.banned == true) {
await targetUser.updateOne({ $set: { banned: false } });
msg = `Successfully unbanned ${targetUser.username}`;
}
let embed = new MessageEmbed()
.setAuthor({ name: "Moderation", iconURL: "https://cdn.discordapp.com/attachments/927739901540188200/1020458073019666492/unknown.png" })
.setFields(
{ name: "Message", value: msg },
)
.setTimestamp()
interaction.reply({ embeds: [embed], ephemeral: true });
}
}
+28
View File
@@ -0,0 +1,28 @@
const { Client, Intents } = require("discord.js");
const client = new Client({ intents: [ Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES ] });
const fs = require("fs");
const config = require("../Config/config.json");
const log = require("../structs/log.js");
client.once("ready", () => {
log.bot("Bot is up and running!");
let commands = client.application.commands;
fs.readdirSync("./DiscordBot/commands").forEach(fileName => {
const command = require(`./commands/${fileName}`);
commands.create(command.commandInfo);
});
});
client.on("interactionCreate", interaction => {
if (!interaction.isApplicationCommand()) return;
if (fs.existsSync(`./DiscordBot/commands/${interaction.commandName}.js`)) {
require(`./commands/${interaction.commandName}.js`).execute(interaction);
}
});
client.login(config.discord.bot_token);
+57
View File
@@ -0,0 +1,57 @@
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const fs = require("fs");
const cookieParser = require("cookie-parser");
const config = require("./Config/config.json");
const log = require("./structs/log.js");
const error = require("./structs/error.js");
const functions = require("./structs/functions.js");
global.JWT_SECRET = "LAWIN_BACKEND";
const PORT = 8080;
global.accessTokens = [];
global.refreshTokens = [];
global.clientTokens = [];
global.exchangeCodes = [];
mongoose.connect(config.mongodb.database, () => {
log.backend("App successfully connected to MongoDB!");
});
mongoose.connection.on("error", err => {
log.error("MongoDB failed to connect, please make sure you have MongoDB installed and running.");
throw err;
});
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
fs.readdirSync("./routes").forEach(fileName => {
app.use(require(`./routes/${fileName}`));
});
app.listen(PORT, () => {
log.backend(`App started listening on port ${PORT}`);
require("./xmpp/xmpp.js");
require("./DiscordBot");
}).on("error", async (err) => {
if (err.code == "EADDRINUSE") {
log.error(`Port ${PORT} is already in use!\nClosing in 3 seconds...`);
await functions.sleep(3000)
process.exit(0);
} else throw err;
});
// if endpoint not found, return this error
app.use((req, res, next) => {
error.createError(
"errors.com.epicgames.common.not_found",
"Sorry the resource you were trying to find could not be found",
undefined, 1004, undefined, 404, res
);
});
+2
View File
@@ -0,0 +1,2 @@
npm i
pause
+16
View File
@@ -0,0 +1,16 @@
const mongoose = require("mongoose");
const FriendsSchema = new mongoose.Schema(
{
created: { type: Date, required: true },
accountId: { type: String, required: true, unique: true },
list: { type: Object, default: { accepted: [], incoming: [], outgoing: [], blocked: [] } }
},
{
collection: "friends"
}
)
const model = mongoose.model('FriendsSchema', FriendsSchema);
module.exports = model;
+16
View File
@@ -0,0 +1,16 @@
const mongoose = require("mongoose");
const ProfilesSchema = new mongoose.Schema(
{
created: { type: Date, required: true },
accountId: { type: String, required: true, unique: true },
profiles: { type: Object, required: true }
},
{
collection: "profiles"
}
)
const model = mongoose.model('ProfilesSchema', ProfilesSchema);
module.exports = model;
+21
View File
@@ -0,0 +1,21 @@
const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema(
{
created: { type: Date, required: true },
banned: { type: Boolean, default: false },
discordId: { type: String, required: true, unique: true },
accountId: { type: String, required: true, unique: true },
username: { type: String, required: true, unique: true },
username_lower: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true }
},
{
collection: "users"
}
)
const model = mongoose.model('UserSchema', UserSchema);
module.exports = model;
+3178
View File
File diff suppressed because it is too large Load Diff
+40
View File
@@ -0,0 +1,40 @@
{
"name": "lawinserverv2",
"version": "1.0.0",
"description": "LawinServer V2 is a fortnite backend that features an account system and xmpp.",
"main": "index.js",
"dependencies": {
"bcrypt": "^5.1.0",
"cookie-parser": "^1.4.6",
"discord.js": "^13.7.0",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"jsonwebtoken": "^8.5.1",
"mongoose": "^6.6.5",
"path": "^0.12.7",
"uuid": "^9.0.0",
"ws": "^8.9.0",
"xml-parser": "^1.2.1",
"xmlbuilder": "^15.1.1"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Lawin0129/LawinServerV2.git"
},
"keywords": [
"fortnite",
"backend",
"node",
"server",
"v2"
],
"author": "Lawin0129",
"license": "GPL-3.0",
"bugs": {
"url": "https://github.com/Lawin0129/LawinServerV2/issues"
},
"homepage": "https://github.com/Lawin0129/LawinServerV2#readme"
}
File diff suppressed because it is too large Load Diff
+802
View File
@@ -0,0 +1,802 @@
[
"46159C748694298198A52DC07476FDA3:4CLHOBqSrmS1RkG/SxZYi8Rc0zCmAKxXIBMMUHDl2ag=",
"8DA867A3B1F0E3A0985B0AB812C3582A:vS8S10ETj2TxdtD57p/iNINbMj4mfumCT6q3eV/jhdU=",
"D938886074C83017118B4484AECE11AB:wjHAHm00Vg6n2x5LU91ap0+SFX5ZXXBmax1LyX8Aips=:BID_737_Alchemy_1WW0D",
"024641850664615E97BE1533A4F3365E:Ut4/ICU0gseFN8MGgYyUTmWidRtj9yeo/NNBp4y/7hs=",
"688022C4193EA6D9DF1EDC7F6CF826DA:lOR338TzQ75G7R81RCKTdjYmYCjhSKJIB+ScPYanNow=",
"46FC5EBAD39CE53EFB215A2E05A915FC:H3gtdkEzT3Dk8vkwTTZE9oUDoJEy6vmfQj1jDo453gY=:Glider_ID_140_ShatterFly",
"5776BD1A9BFC4EEEB7DD1FCA71B9C39C:jkYOI3VSLqXBCMYyxpfl/soGCBdplmqs8C2AOg1pcGU=",
"8F6ACF5D43BC4BC272D72EBC072BDB4F:rsT5K8O82gjB/BWAR7zl6cBstk0xxiu/E0AK/RQNUjE=:CID_246_Athena_Commando_F_Grave",
"4A8216304A1A18CB9583BC8CFF99EE26:QF3nHCFt1vhELoU4q1VKTmpxnk20c2iAiBEBzlbzQAY=:CID_184_Athena_Commando_M_DurrburgerWorker",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_949_Athena_Commando_M_Football20Referee_C_SMMEY",
"30A11EE8EB62BEFD4E9B09611DB13857:YVeVPXcP7UoJTp71ZXpGNdPVzmjnRyymcUpsNWYXfRs=:BID_508_DonutDish",
"D85DFC0115FC3C75A6AD9C5D15B0DBF4:KFp5kuqdJIex+SS95mCy4nETnpzlaY8UHe8X7BSjGxY=:Wrap_080_Blackout1",
"7A59383C41DD998408A74BC37C7D6887:nSrruhpHV3ZEPPECeqWkMh/6mBFzQD8yEFKZS6oJeu8=:EID_BasketballDribble_E6OJV",
"010E6ACF85E4A58BF6F551EFE7B85F61:DwCIH5Dw/1wdiS6gFGmWe4HUgD9kMOEzjbzM/1QshM4=:Pickaxe_ID_178_SpeedyMidnight",
"A92DE306E5174C82739D774151D7B661:RF9sTh7l2tp+ypCb/Lp3WeMfBExvk2LSUbim04xsCJo=",
"8335E3DF8B0DFBCB0C05EFB5FF1B8A81:shx/UPd2PJpGZtpddRmoS7RosbEO0MlsaNb+9aaQR9g=:Pickaxe_ID_204_Miner",
"DC487286E8C1CD5FE18AC3FE76034EF2:3h9IwK2qQP8PHVuO1aZI1C34JrJxKBnXJOFcSDSj99M=:CID_478_Athena_Commando_F_WorldCup",
"8A6DABC9AF8B5FE521D365DB605D0AE0:T721SqBTncYsd8Gej01RnLX6sEaCgJoILnRauHaJz+g=:BID_284_NeonLines",
"5E15C5486CE8E539552D4D3E7682F9E2:+L/tTz+woDFZJEvtxfq8m8tNI1R72sYK7rnYr7sHTis=:EID_TeamRobot",
"E47EFA3166A5D7B35CEC27B19AC66AE5:JURSqAHhHK6YqLP5rKhCO+SQ2oql4NqJaoaeNGtsrM8=:LSID_325_RiftTourMKTG1_18M49",
"5A33986E8C23E664BD8A70D41697A93F:nFqFG2z7mnQhf4Q3iR6zQ2eWykiuwy0af+ga9QWnU6o=",
"0FA46244428655D55790A980B59745AD:fEzJj2anX6D4HyOhaXyNar9oFa+L2/ob/RIXLnxWc7Y=:CID_328_Athena_Commando_F_Tennis",
"BA6DF4F82C5CAB3CE1C51156BFCACE71:SDOlhnlP1SENGT+SrYUqeGIz0TkgoM7dQjfmfxegb1o=:MusicPack_030_BlackMonday_X91ZH",
"4009CB877085F3B3B0D76A686465A140:gMLJXUbFcIrqqUlAuoMI1b27KdWHBVJJeJWdYV1Iiro=:EID_KeplerFemale_C98JD",
"6DD6F574BA76BD6B68E14FF19181F2B6:Z/OnCtvolWJSaChHeIIVFXB8fptk8QBW8JQD1Gk2w+Y=:EID_Shaka",
"F60CFFFA32CF6A877B50DA7F0A88326E:OWIopbB4fxaobofPI9lF9hn6BPG9NVLp4Od61uQppfo=:CID_392_Athena_Commando_F_BountyBunny",
"6CED8B5F648ED1ACCC8F1194901775AF:qjfCT39FVniEjPj+CvZu5Qz8XHHtdnH8kCsV3P1OaJw=:BID_252_EvilBunny",
"216D955070ADAF10973BD156897472C3:MjQh55OvnJCoVMQzMU4C/1NF3FWiXDXnJ6G/EcHfUzo=:EID_AshtonBoardwalk",
"7A59383C41DD998408A74BC37C7D6887:nSrruhpHV3ZEPPECeqWkMh/6mBFzQD8yEFKZS6oJeu8=:CID_A_081_Athena_Commando_M_Hardwood_B_JRP29",
"FD0C3696948675DC3C2CBF5098D57D0D:rBWyTh/AVyZxi2oiQxM/OeD/HYZOSdVidEQeKoowV6U=:BID_744_CavernMale_CF6JE",
"25E4BA752FB1328DA3E5EDB5FFAA47C3:Mrh9sFIpmcD6xhM2zQjHjqzV5QuJBXS29x0fS5IFcFk=:BID_789_CavernArmored",
"57EC154062C75464BD8A087D89732317:5AEwoCp79njYci8QYF+sLMkGpjDnFCYLSCtz4LD9D78=:EID_Galileo4_PXPE0",
"C779C5126616BE8EA5FF851D2FF1FF34:uK97yLbZmBvrWhlMlQmYfVWq2l4mRy/CEm5H/zczFDI=",
"7313591AB9F0A7E46AB016065DE8F65A:NAL0bLW1p+ceLF4lhxfm1vQPaMlv8eNPP6tTizTZEN0=:CID_398_Athena_Commando_M_TreasureHunterFashion",
"929B82B3454DF80CC45B11A55400B6E7:jl/KsmshfBxKKnPDHyHNTHOzTE3buCIrBpSUpXJQdL4=:BID_180_IceMaiden",
"6BE73A630C01192C39807CEDA006C77C:3MYDxjacnNgSQwxc68DknO3e6TKXSw4tG5TVdSxGdFE=:Pickaxe_ID_327_GalileoKayak_50NFG",
"AFCCB7C08EC6957EEDDAAD676C3D3513:MuovEXob241ie6/RP76ImUk+MExLdl+bszvxCHNtg0U=",
"9261CD0F921EAA3CD6AA8C0716FB042B:W+yzeWWxWnA530lwV8nLi2BE+TD5MCXS11th7UphmPQ=:Pickaxe_ID_542_TyphoonFemale1H_CTEVQ",
"22AB4BDC10065AA49B38DE88522DF836:1L8L+oKtSOtIxbm1x0HbDtzquIH6CH8vu1PF4i8jU+w=:Glider_ID_153_Banner",
"FD0C3696948675DC3C2CBF5098D57D0D:rBWyTh/AVyZxi2oiQxM/OeD/HYZOSdVidEQeKoowV6U=:Pickaxe_ID_589_CavernMale_9U0A8",
"001B8CDAE8386ACB5DFE26FA59C10B40:XA9kqeHyWLK/xsRzYLCkooN/dBRNTyjy5sw9Jv+8nRs=",
"8AE56A5795250C959CD4357AF32DA563:GL9+gTLkh5vnyzImLDdxGYFksrHsmmJSUfZB9mP9fdM=",
"E4D8D083C49828F6BF310ECA74A84F98:NxjtZXHe49xC1zUVs+XKjHbeic3prkFOWmwkaQ1vOFw=:Wrap_395_TextileBlack_DBVU2",
"4C8D53A32D85124D08A3DCE6D3474A30:gam5sVciLPzKr+wmWOoctLo5HFqBvBLKKcxh6ZV1kn0=:Pickaxe_ID_532_WombatFemale_CWE2D",
"AC22C5B2B654FE15BDCC8B664D033140:zE2ddgoXrJ7X0UEkphUtys0CeoTzIDpAZ58beqOkx4M=:CID_A_232_Athena_Commando_F_CritterStreak_YILHR",
"010E6ACF85E4A58BF6F551EFE7B85F61:DwCIH5Dw/1wdiS6gFGmWe4HUgD9kMOEzjbzM/1QshM4=:Glider_ID_131_SpeedyMidnight",
"A0926AD8C6EDE29250AC4A0A93156E7B:keN/yZ7qnvcPZeIflsked9TAT867gbPgmnG1QdlSn3E=:Pickaxe_ID_382_Donut1H",
"C2216794035D5FC95DCC07FA72E1EC86:4CS9WyhB+tpbl/w4bd+9cnjWZTf0NCO8zl1/6TmIQeM=:EID_HNYGoodRiddance",
"8AB2A1D47937F30D49879F4043164045:Mwur5341qGGuZkJb6aGqo7oPYGS5RIaLu3lgf5n6eRg=",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:EID_FootballTD_U2HZI",
"D49757E2D55451A0D5B341906FE2ABE4:PWMwnjgi/wUDV+yxg02QsU33jA529fxVTRHyqnkv21c=:Glider_ID_142_AshtonSaltLake",
"0C2DFF3432352A23684E05B0794DFFC7:FG55cmgdBnszsr5pS0aBC44NVl7OyI+AuOXxALyaNKA=",
"2D24182706636A7BD3E96AD37605BAD6:jEZJE+EAU7VDo6p6Y84e4+p3AHxYBWin144H4MhzaSQ=:Pickaxe_ID_427_Seaweed1H_CZ9HA",
"4E7938F1FAC98BDF378823116712AC7A:jbZVgprILTQomUdGeJF0PsAFAJxsSCs5cKcXweZMAg0=:EID_Tar_S9YVE",
"2FE8DBD09F14AAF7D195AA73B9613792:KwIehLEKaCSJb5X/WcQ9IULKkz3G3M9f9Z5Jgi9hYUU=:Pickaxe_ID_297_FlowerSkeletonFemale1H",
"8B9DC1A32A4081596F0AE60926CF6846:4O/n/4TAJpnQ3BvcadiKLHRNSmZQQbr+15RSrDHnrQ4=",
"F395571A36D2BD888861E61EEBD45AF8:D/35GPTIOKbdfmpxRJmHTkjNXcWv+XdSmTxQt6z1hvI=:Pickaxe_ID_554_SkirmishMale_ML78Q",
"21D9E3FA446D32EE85025841557C1E4C:KBL9ZqzocmLvcq5k3mwTCeoeeVfJdw9wjuQacUrg50w=:EID_Grasshopper_8D51K",
"ED088B11311A599D6225CE85545F019A:1NMRh4JMXRL9XW8Kb6zo4/F10dwLJC1+kPm6D6DudCE=:Pickaxe_ID_653_LavishMale1H_SWKJB",
"A0926AD8C6EDE29250AC4A0A93156E7B:keN/yZ7qnvcPZeIflsked9TAT867gbPgmnG1QdlSn3E=:Glider_ID_206_Donut",
"566C4D92AF66F45DF5E2D7EB43CC27AE:EuAYwU5tQBXzGoSj5BMc7S5yFfe9wZ2qrzx/hIHpnqw=",
"163D68B009421CA82956BDD63659F7C0:SAE6Yruow/8IPkoOuzYEnjJFyvBuwLNI11z9/5EfyL0=:EID_TwistWasp_T2I4J",
"74AF07F9A2908BB2C32C9B07BC998560:V0Oqo/JGdPq3K1fX3JQRzwjCQMK7bV4QoyqQQFsIf0k=:BID_302_Hairy",
"BA6DF4F82C5CAB3CE1C51156BFCACE71:SDOlhnlP1SENGT+SrYUqeGIz0TkgoM7dQjfmfxegb1o=:BID_361_BlackMondayFemale_R0P2N",
"5869B4D27CF6766E4047DB0636CB6D72:bFnq5n5S+PRZZFp/dGhAmy63liDVz7wufMqMm65B0FE=",
"D8FDE5644FE474C7C3D476AA18426FEB:orzs/Wp9XxE5vpybtd0tOxX6hrMyZZheFZusAw1c+6A=:BID_126_DarkBomber",
"828B24CF7786DF74D8511CA89DEED8CF:nCahv7mQhidmYXSmKif6z7d6bQ60mdPQ7SrdZ7a3GaE=:BID_635_York_Male",
"E36F7DC3B2ECE987FC956C3CF7E71F21:+Y1iPDRR7adeEjebuo6DzBiHkgK0c4ZOwgmrnYYx43w=",
"28CBBF705C9DB5A88BEC70DAA005E02E:FvtzBBvDkyj8PRLW76169bMFvg65VojYrSmkjUAi4Bc=:Pickaxe_ID_259_CupidFemale1H",
"210726DF9DCD78AD95B4D407D5D9157B:cXzvTrgNBBmsa8jR8E4q9NFBasv/zdQSSPQmnKznkJE=:EID_SecurityGuard",
"21D9E3FA446D32EE85025841557C1E4C:KBL9ZqzocmLvcq5k3mwTCeoeeVfJdw9wjuQacUrg50w=:CID_A_236_Athena_Commando_M_Grasshopper_C_47TZ8",
"87F01091E4DA4FE3FFC9AD92A20A8DCE:p+5QvlQEV5QW2QQrIWrDnnthhNN9V0wXK+Zdmiw71u0=",
"98BCB8B7136162178BF364D6105BB9B7:c1dhB+vWHWRw3YvWpsHRj9Ayj8JjdqYOLnyr0YImxVo=:CID_A_001_Athena_Commando_F_GlobalFB_HDL2W",
"88FA70760D757D80F661FA53B4762EC2:7OtV76cpyOq9dNeM5PVD8TOdRcPx1K3weEPXzlCugu0=:BID_877_BistroAstronaut_LWL45",
"4009CB877085F3B3B0D76A686465A140:gMLJXUbFcIrqqUlAuoMI1b27KdWHBVJJeJWdYV1Iiro=:BID_704_KeplerFemale_C0L25",
"F6838AF4144E8386A184FBB0823C15D0:IjzqnnHjZ+r6WC4He/JawOyR7LxeMbm5880cDGDr2eU=:BID_229_LuckyRiderMale",
"80FC6D214CD513415CB0A54044683293:fXY1Xojrg1HpH6ZF0xNrhF9XZKS15GmaBidF9kSAbME=",
"22AB4BDC10065AA49B38DE88522DF836:1L8L+oKtSOtIxbm1x0HbDtzquIH6CH8vu1PF4i8jU+w=:BID_289_Banner",
"98BCB8B7136162178BF364D6105BB9B7:c1dhB+vWHWRw3YvWpsHRj9Ayj8JjdqYOLnyr0YImxVo=:CID_996_Athena_Commando_M_GlobalFB_B_RVED4",
"EBA3BC7F0023BE91CE5EFB7E1BC001A8:MdKbawNIe4qCuGaB4q7+4cy8keyDnJnxZLa7HLC0W4A=:EID_Feral",
"C5188047D9661347FC4483CCB04ACD4C:TlesZ5LgoEoJqkJaz7N2QB43zNWIJdOpx8rOpsbGC48=",
"C76299772B1BE272260BF3396F83FC1E:uiBDMtwYhdxktbqTrhYkzEZErlBp5gBtkLM+QFDouT4=:Pickaxe_ID_668_ClashVMale1H_5TA18",
"C76299772B1BE272260BF3396F83FC1E:uiBDMtwYhdxktbqTrhYkzEZErlBp5gBtkLM+QFDouT4=:Glider_ID_317_VertigoMale_E3F81",
"E0FB7B394449CE6450EA90C93D710EB8:NrXwNX6lKuu/kyQuvE74+6Uo04FODoV4ZqxToj/jS6I=:Pickaxe_ID_230_Drift1H",
"9078B5331B187C32C649D4B1E5530EEC:l1U0jw2fdShRIHGNl1NYmG8YDAJEUSIfhI46nJgSt30=",
"828B24CF7786DF74D8511CA89DEED8CF:nCahv7mQhidmYXSmKif6z7d6bQ60mdPQ7SrdZ7a3GaE=:CID_911_Athena_Commando_F_York_B",
"1655272875DB718493BB6B09032657D7:xQLpNTDeYJCcQOUQS2ICyfByvhPU3nC5cfJRbPSugdY=:EID_Survivorsault_NJ7WC",
"E4D8D083C49828F6BF310ECA74A84F98:NxjtZXHe49xC1zUVs+XKjHbeic3prkFOWmwkaQ1vOFw=:Pickaxe_ID_675_TextilePupMale_96JZF",
"545B9777127F4BE242F802C627356B7E:RNI/KvLEXcGoGnk3/AKaYbyJmXMtQl9Zmvl8ErePB4g=:Pickaxe_ID_691_RelishMale_FVCA7",
"C7623A35411F3D5FBDE2688C7E4A69EB:qAi49mUKsB2dbfbtJWDf3yO2DfRStA+Ed9XgDjC8Zaw=:Glider_ID_109_StreetGoth",
"4755D9C0E2D1DE1C09B77DEA8B830471:9tUO5yVhvp+/sp7icZaEDw05nMAdS6bYAWYyfQNsxBc=:Pickaxe_ID_387_DonutCup",
"D938886074C83017118B4484AECE11AB:wjHAHm00Vg6n2x5LU91ap0+SFX5ZXXBmax1LyX8Aips=:LSID_294_Alchemy_09U3R",
"545B9777127F4BE242F802C627356B7E:RNI/KvLEXcGoGnk3/AKaYbyJmXMtQl9Zmvl8ErePB4g=:Pickaxe_ID_690_RelishFemale_DC74M",
"7F0F5EB44D49E7563DD5A196121D49E1:CBIvm8gTJLCz6sD05GKbQo6u/Nk4Poni/7wlp724KWc=:BID_146_AnimalJacketsFemale",
"D14FDB2BB2FB7746797F25470913BFF1:CQDgIxcNnAoUboQnjafZAYvV7UqX+NefGTXFd3m+oFc=:Glider_ID_327_NucleusMale_55HFK",
"D83FAFF508200C47DF03BDFF2F801FEC:s9P7AOkoCuPm/506hyAKzuRaIh0xzV9YZON4oDs7GoY=:BID_665_Jupiter_XD7AK",
"EB16EA013B751792698E05435797C1ED:y9JgD812Io4mbaJ5i533Ts5SSfyXaGM4JyoimjP+i4M=:Pickaxe_ID_183_BaseballBat2018",
"98BCB8B7136162178BF364D6105BB9B7:c1dhB+vWHWRw3YvWpsHRj9Ayj8JjdqYOLnyr0YImxVo=:CID_A_003_Athena_Commando_F_GlobalFB_C_J4H5J",
"21D9E3FA446D32EE85025841557C1E4C:KBL9ZqzocmLvcq5k3mwTCeoeeVfJdw9wjuQacUrg50w=:Pickaxe_ID_696_Grasshopper_Male_24OGH",
"8566FD040AC2B245597E11D1F85DB4E5:SEoqoweofxmXfxu848wKn1UJhwU7oQ2w2F0lBst+FnU=:Pickaxe_ID_508_HistorianMale_6BQSW",
"738C0E8B5DAB633906DC77FE4C4E48F9:qr1ZfbWRp+uqwBMvEhY1XBj7Sr7SxRsWHN7jqYPaZfU=",
"A92DE306E5174C82739D774151D7B661:RF9sTh7l2tp+ypCb/Lp3WeMfBExvk2LSUbim04xsCJo=:LSID_374_GuavaKey_IY0H9",
"3E89561331A72D226FBF962DA29DBB82:qzWv2zubDSSrpTt3tKc4ZsReqR3QBKjhU1cGzVe7KH4=:CID_387_Athena_Commando_F_Golf",
"78FA1DF9C04F25EC129AA57492626563:AZT1/Asa4CuxdTtvLrw9nlEcxfOuoTnLbSLztfs7QQ4=",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:BID_653_Football20_1BS75",
"276E65E4041C467319534B14EAEA338A:Ib7KJMP8Q9if+P6x2bYZ0dC538B4LL3J1TcIy3rBlHk=",
"21D9E3FA446D32EE85025841557C1E4C:KBL9ZqzocmLvcq5k3mwTCeoeeVfJdw9wjuQacUrg50w=:CID_A_242_Athena_Commando_F_Grasshopper_D_EIQ7X",
"96FD474CBA52137DC5ABF658BE17C792:ZLWvbUR7Xow1GUNjC9Mxg7DHVoJAnBr4b9gSzmyFcxU=:BID_862_BigBucksBattleship_1JA5G",
"BB26302A83A2B42228EF6A731E598360:q6GH+OJutjEXL5wKuJnbLKAan9V/AXRxIkqg6WgSzUU=:Wrap_084_4thofJuly",
"21D9E3FA446D32EE85025841557C1E4C:KBL9ZqzocmLvcq5k3mwTCeoeeVfJdw9wjuQacUrg50w=:CID_A_239_Athena_Commando_F_Grasshopper_H6LB7",
"204D49F063979C3AF87EF896D074D1CF:SaYFk+GEE7mL4dsgs0v0VGR5ER4TwH8uTNX5XqSglu8=",
"7F0F5EB44D49E7563DD5A196121D49E1:CBIvm8gTJLCz6sD05GKbQo6u/Nk4Poni/7wlp724KWc=:CID_265_Athena_Commando_F_AnimalJackets",
"545BD59335CA43AC4481A621226B4E81:4lYAxO0wSzKarpiMl4b+bWQOjDkXdJKactoCetH65WY=",
"91C415954BF27B6E43970FB8A75FE8BB:YhHyxIA+Ru33r3pThiWqKNYdvDbL05yXSxKarRuMSxw=:BID_176_NautilusMale",
"8566FD040AC2B245597E11D1F85DB4E5:SEoqoweofxmXfxu848wKn1UJhwU7oQ2w2F0lBst+FnU=:Glider_ID_257_Historian_VS0BJ",
"22B8405FC3BE153C8148422C3F2D3A8A:d/ATMDztVZxwHLUCwOcJWP1/7oPKKGqbBWUBRNZ6dnM=:BID_837_Dragonfruit_0IZM3",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_942_Athena_Commando_F_Football20_YQUPK",
"32F8552040D83320E998654666873931:izPPgPIvrxfBXPaI/LJzO5lxOZtzjOXQJBuk9kPdKe0=:BID_338_StarWalker",
"7F863227B67DD0D99A7A4BBEE0682666:29bfvaQcZUswF3vrHMntLKfmknWKDf65FCbxbJghisg=",
"57D2C065461284F546C48C971A44C6D0:EOfb/g0hZdMhd5biYOZR69B/mqPU7X+sgQQrp2gQ/s0=:BID_178_Angel",
"A9AFB4A346420DB1399A2FB2065528F5:Zjzo+CaLNmCygplzQo2wUL4LT33DEiL6qZWE2R0EYMg=",
"0882DAEC4F7823551C4955BA25B8AAC4:kGljCDpbMnCIfeo0YBLpBKDhX6nLlCaZRe62mSYSPTs=:Pickaxe_ID_720_RustyBoltMale_UZ5E5",
"919FDAB2FDB531820404333B27DC7B06:W9Csp0y6agsgcQXlRGvYUpPGPImNdFfBsZ8yQoUEdGg=:BID_296_Sarong",
"A7D34E80FA70CDD2F367DBEF93B98467:KVErbMXsQqx7dxrZp5Ara4OVlA17pc29E2SZlFNipPU=:BID_283_StormSoldier",
"6D85E82539341B90944E84FFAAD872FB:mAiBk7KbE2Dnr+yVFyJK1yAwv2eWb+yANFH0z2krQkw=:BID_299_BriteBomberSummer",
"2FF619685EC983B800018ECBFF377ABB:Dn5ZlXEhBAhXP0RbkDskEQwOK4RUKTwAIls6cvVOr0g=:EID_SpeedRun",
"22AB4BDC10065AA49B38DE88522DF836:1L8L+oKtSOtIxbm1x0HbDtzquIH6CH8vu1PF4i8jU+w=:CID_446_Athena_Commando_M_BannerA",
"54FD9ABD65879452DCB8CE11C1D7F1AF:nV0Vm4NCBl+MkGX8wiqfFrg0viDriL3I2xc4KS7n7fg=:CID_421_Athena_Commando_M_MaskedWarrior",
"3E89561331A72D226FBF962DA29DBB82:qzWv2zubDSSrpTt3tKc4ZsReqR3QBKjhU1cGzVe7KH4=:Pickaxe_ID_190_GolfClub",
"726DD9BDA97CE92DFF162668027518BE:/QdzaWcoVhInSz0Oa0qk+NV3XxRt9WlXwcAu766Y6aY=",
"AF3080C00CB8CB301C167B00E9671CD4:wLmQDoGeYBN8Og/IMDoGxuuQNy7M+RQkKtajSZiOebE=:Pickaxe_ID_558_SmallFryMale_YBD34",
"AF3080C00CB8CB301C167B00E9671CD4:wLmQDoGeYBN8Og/IMDoGxuuQNy7M+RQkKtajSZiOebE=:BID_710_SmallFry_GDE1J",
"59AF6C46ABB214024067564F69D6EA37:NtUgzeFVvkbyZQGRVdteWV61HjED9MXquqlVKHo3c/M=:Glider_ID_238_Soy_RWO5D",
"4009CB877085F3B3B0D76A686465A140:gMLJXUbFcIrqqUlAuoMI1b27KdWHBVJJeJWdYV1Iiro=:Glider_ID_276_Kepler_BEUUP",
"B229884F839295B4B9EDC380B045C64B:SVmPvZenzQ5Si17i8daUFyKoOGDtaH4YZtsF1s2XkxE=:BID_745_BuffCatComic_AB1AX",
"713D64294CD1C40F60DEEB805E3A2D87:CJOOHtEX7q4CELcZ96oZjrmSZd7pyJ2fMaFX912GDl8=:BID_193_TeriyakiFishMale",
"7A59383C41DD998408A74BC37C7D6887:nSrruhpHV3ZEPPECeqWkMh/6mBFzQD8yEFKZS6oJeu8=:CID_A_085_Athena_Commando_F_Hardwood_K7ZZ1",
"599668A98461E4D89196E0189C32C4D2:8MqQjC52vWK/VwX4SfYC1wu9eiUTXdqq/xWODcW9dQ4=:CID_468_Athena_Commando_F_TennisWhite",
"7A59383C41DD998408A74BC37C7D6887:nSrruhpHV3ZEPPECeqWkMh/6mBFzQD8yEFKZS6oJeu8=:CID_A_088_Athena_Commando_F_Hardwood_D_WPHX2",
"44DB36B2D2B3854669780458D2FE48C4:gtl0smAMRKg8d9TdDH47lUOYCygKzbAPA6/HaXLWy94=:Season17_Magesty_Backbling_Schedule",
"F533FEDB46B06F324383349BDBC825D1:Z7b6780R78xFbYRbQehW/VZVDftI02RqvKe7XIYiOBc=:BID_184_SnowFairyFemale",
"B66EED5CA4F4ED75170872E30B9B0E23:rHT8/uzcZZ0ENxU9dxKpr+cdAajZ5L5U0geHt6NoZhI=:Pickaxe_ID_420_CandyAppleSour_JXBZA",
"5B26536B2ACB973C651C0D1A285C0E37:n4j7xWZ1HfwSGb9ixE7YMFyRsTjl3gjJVDZJj7Wy4rs=:CID_397_Athena_Commando_F_TreasureHunterFashion",
"7A59383C41DD998408A74BC37C7D6887:nSrruhpHV3ZEPPECeqWkMh/6mBFzQD8yEFKZS6oJeu8=:CID_A_083_Athena_Commando_M_Hardwood_D_7S0PN",
"7A59383C41DD998408A74BC37C7D6887:nSrruhpHV3ZEPPECeqWkMh/6mBFzQD8yEFKZS6oJeu8=:CID_A_084_Athena_Commando_M_Hardwood_E_II9YS",
"A7D34E80FA70CDD2F367DBEF93B98467:KVErbMXsQqx7dxrZp5Ara4OVlA17pc29E2SZlFNipPU=:Glider_ID_151_StormSoldier",
"E4D8D083C49828F6BF310ECA74A84F98:NxjtZXHe49xC1zUVs+XKjHbeic3prkFOWmwkaQ1vOFw=:EID_Textile_3O8QG",
"95EE98AB79EAA4E2871EFA0E4BA9CD7E:LJCJ2kW7AQoni1spB+sLcir3NXBEE7zOC0JGKKhn0ZY=:EID_Butter_1R26Q",
"B0ACC6254D42350D124727B035C9CE55:ZDFVEa7yau61hc1ba5xNGtYdZ+yif7XgE79BBWIlPJ0=:CID_299_Athena_Commando_M_SnowNinja",
"B229884F839295B4B9EDC380B045C64B:SVmPvZenzQ5Si17i8daUFyKoOGDtaH4YZtsF1s2XkxE=:LSID_287_BuffCatComic_JBE9O",
"F71D60AE5231E90CEA7F53D90DC4F007:ver8B06IS0up7tNYy03zkhCl+CrTl3czgmXPYYONcM8=",
"8DCAE39C7D9690E19F52655F02C613B2:ZZHbiVsbXquLlrtNVHtryLS3Vd1Ego8/8tlDpeUCgfc=:Pickaxe_ID_252_MascotMilitiaTomato",
"59AF6C46ABB214024067564F69D6EA37:NtUgzeFVvkbyZQGRVdteWV61HjED9MXquqlVKHo3c/M=",
"9261CD0F921EAA3CD6AA8C0716FB042B:W+yzeWWxWnA530lwV8nLi2BE+TD5MCXS11th7UphmPQ=:BID_689_TyphoonRobot_SMLZ7",
"91C415954BF27B6E43970FB8A75FE8BB:YhHyxIA+Ru33r3pThiWqKNYdvDbL05yXSxKarRuMSxw=:Pickaxe_ID_131_Nautilus",
"BA490514EFDA436A2679E381BD558AA3:3KBKxBOi/52H0feJ/ijKxRHk+lF1zID0uIpjd0T7/Bc=:EID_Haste1_T98Z9",
"32F8552040D83320E998654666873931:izPPgPIvrxfBXPaI/LJzO5lxOZtzjOXQJBuk9kPdKe0=:Pickaxe_ID_253_StarWalker",
"5581F333809DD14FA591F17B6C071687:/gEEJhUVQMVyFP7JR0jT4RM99Wj7hnIp2ZitAVdwAYc=",
"A7FAF0883F9147F93079F3A40413A83C:+wNde9ex5o3zvdjqgJUGhqcxmecYiQW3W1QuO00NUbc=",
"5A1170F589134C4D68AAA2B5AA6EDA69:bfro7s6Qtde/H7C4zc6MJdpua1mhem8HywLluxBLDrg=",
"E4C183B0EF31ADF061F175068046568E:AF+fNwseLnjCsPKzbFkYDkZE4gyYfGEaifyJjdsMjp0=",
"65000C27C3BC5B9B904A0D20050D6B36:JFwQi7tWgJDr+E4GzYU/rgasjjk+1BKRB/N88e7rVvI=",
"99B0F5AFB03FFA1BC3B8AFF75267CAD2:d4GffGn7ENqL9SpO5wnhKZzqzpr8S/4LQS2P+QD2wy4=",
"63722D44ECCA0F4178B85F5A6BC4C31B:j42UL0bmfBkli6Aj92wWABwFby5rAplP/Ac6nh9kRvA=:EID_Vivid_I434X",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_938_Athena_Commando_M_Football20_B_I18W6",
"44DB36B2D2B3854669780458D2FE48C4:gtl0smAMRKg8d9TdDH47lUOYCygKzbAPA6/HaXLWy94=:EID_Majesty_49JWY",
"17F31F416B1B0A73F14F0A7973DDBD76:+hUk8/wD736u5sylQPXcKKREoo5vSPaWPG+3xxT5nFM=:Pickaxe_ID_157_Dumpling",
"59AF6C46ABB214024067564F69D6EA37:NtUgzeFVvkbyZQGRVdteWV61HjED9MXquqlVKHo3c/M=:Pickaxe_ID_462_Soy_4CW52",
"F3A99CD0D4F58EECEEB0D112506AD846:ZZtCRPcKk6itVryDavp7uZFIXiZF5CW0O9b+8Zt2Oag=:LSID_328_Quarrel_K4C12",
"E4D8D083C49828F6BF310ECA74A84F98:NxjtZXHe49xC1zUVs+XKjHbeic3prkFOWmwkaQ1vOFw=:Glider_ID_316_TextileMale_3S90R",
"02421097082555483CA9524F79EF7687:e9wZT5/2KHmpbw6KjR8u4uo3iG00O92+PAZMbk09a3w=:BID_545_RenegadeRaiderFire",
"D49757E2D55451A0D5B341906FE2ABE4:PWMwnjgi/wUDV+yxg02QsU33jA529fxVTRHyqnkv21c=:EID_AshtonSaltLake",
"B1B800E199A6D4649287C11AE89F67CA:3udFXffIw3c7eM5hljF5mJQA36FbW2PeF8Gx1TcD1vc=:Pickaxe_ID_201_Swashbuckler",
"F2E3A44428F24B0E4F481938A8E3D8EE:Vgb58eI7kGPp+Ecr8lhE2RMoKeCLFG0sWAEugWV295A=:LSID_305_Downpour_CHB8O",
"23280A6FC0902B6420BB82522AE16D2C:C7o6m2vJJY+XWKd0t1YLBPVLYCMgNbt10d/itx5Wjnc=",
"8AE930B0D623C1C2B3926C52ECF6250B:uwtZv87e9DU/Z1ZvYB7Pv4TdRQ4/ZRT9nYJCwYSmlbI=",
"CBFF239A1792F25920D863F223368B54:J3N3cUH3M0R3uyzkE0qVK/SouxC/X6VEswcoWb6ViL8=:Pickaxe_ID_215_Pug",
"21D9E3FA446D32EE85025841557C1E4C:KBL9ZqzocmLvcq5k3mwTCeoeeVfJdw9wjuQacUrg50w=:CID_A_235_Athena_Commando_M_Grasshopper_B_RHQUY",
"6838E4BB35C0449D4F66F7E92A960D1F:KOKH3JA+OMliB+f17Pd8OFEtooaCZjehz3CvfqaSbtU=",
"CCFB247DE6ED8DB4856E039A5AE681B8:Z8ixoqcCEiFqUH1qec+yUNQTP1+D1xQjYw6FDpUQa9c=:EID_RhymeLock_5B2Y3",
"82669F5A2F9B703D1A6BEA3BCB922D7D:Leu9rrDPaqZd3izIU+IKpFcP/NNcqSncLkV2lapQL6k=",
"566C4D92AF66F45DF5E2D7EB43CC27AE:EuAYwU5tQBXzGoSj5BMc7S5yFfe9wZ2qrzx/hIHpnqw=:Pickaxe_ID_479_LunchBox1H",
"EBFE6788D367D741AF0A4FD098CDFD39:FAeJTGyT49P+dQOmKx+lMYVAxu7qtIPlqSaLAR85zqI=:EID_AssassinVest",
"57EC154062C75464BD8A087D89732317:5AEwoCp79njYci8QYF+sLMkGpjDnFCYLSCtz4LD9D78=:BID_428_GalileoFerry_28UZ3",
"FA393ED7DFD20657B9C8659CB0295F64:G5wmtVhL0E8/+gpxHPK3HGJJ5RvfoWyeYrLJ3Awm9f4=",
"3DFEA395156D835B86EB22801411ED08:cG8Q2VOqa9d+9J4QEvdBWe5hjbIayC4HtRp7svIWZ9g=",
"4F365EB12B55EB9A6BDD99DFC3D02E61:JFApzAook6DV1rLMngEwoo0pprP17X6gjpNc79NQ43A=",
"6A2047910081947B9A5DCF542A9AEBE5:V/jMTWL+zbqeIlKCE9+SM3+X69aYbt/cN0+G1D0GBQU=",
"E3D0A604B93651DDC6779B14F21D0FDA:8gPR3gZwEJxfkZBkXk0QAlpnJ7q5mXzVc0DN3lzpJ5k=:Pickaxe_ID_114_BadassCowboyCowSkull",
"A6130F4077B928D41D298463C61C0F34:oW3GkVlIb8uiNl0CzqrwVZeGfnEujp2O3O3tnw2zFOs=:Wrap_094_Watermelon",
"91C415954BF27B6E43970FB8A75FE8BB:YhHyxIA+Ru33r3pThiWqKNYdvDbL05yXSxKarRuMSxw=:BID_177_NautilusFemale",
"4E7938F1FAC98BDF378823116712AC7A:jbZVgprILTQomUdGeJF0PsAFAJxsSCs5cKcXweZMAg0=:LSID_273_Tar_ITJ9S",
"44DB36B2D2B3854669780458D2FE48C4:gtl0smAMRKg8d9TdDH47lUOYCygKzbAPA6/HaXLWy94=",
"D49757E2D55451A0D5B341906FE2ABE4:PWMwnjgi/wUDV+yxg02QsU33jA529fxVTRHyqnkv21c=:Pickaxe_ID_203_AshtonSaltLake",
"57EC154062C75464BD8A087D89732317:5AEwoCp79njYci8QYF+sLMkGpjDnFCYLSCtz4LD9D78=:Glider_ID_186_GalileoFerry_48L4V",
"57EC154062C75464BD8A087D89732317:5AEwoCp79njYci8QYF+sLMkGpjDnFCYLSCtz4LD9D78=:BID_429_GalileoRocket_ZD0AF",
"F3A99CD0D4F58EECEEB0D112506AD846:ZZtCRPcKk6itVryDavp7uZFIXiZF5CW0O9b+8Zt2Oag=:Glider_ID_305_QuarrelMale_ZTHTQ",
"828B24CF7786DF74D8511CA89DEED8CF:nCahv7mQhidmYXSmKif6z7d6bQ60mdPQ7SrdZ7a3GaE=:CID_909_Athena_Commando_M_York_E",
"510BE1093533EDED92752C0B90A80895:vaI8rYMUPwx+M61tvfJ0pf+dMK/96pnzKOQluAPmjU0=:CID_424_Athena_Commando_M_Vigilante",
"F60CFFFA32CF6A877B50DA7F0A88326E:OWIopbB4fxaobofPI9lF9hn6BPG9NVLp4Od61uQppfo=:Pickaxe_ID_198_BountyBunny",
"B4BE2A5487426AFF06CB7089EA9B75BE:w7Hbt5PsQ4MDg9EjvOU8WdtL/BrWxZNp9NM2UrHSjRg=",
"E3D0A604B93651DDC6779B14F21D0FDA:8gPR3gZwEJxfkZBkXk0QAlpnJ7q5mXzVc0DN3lzpJ5k=:BID_329_WildWestFemale",
"6EA156BE3D18E1D649D7D4B3F8C0FACA:qAKD9oM8u4IvUcKbReHTMaLg7GtHLBcnmz8++vwwB6o=",
"98BCB8B7136162178BF364D6105BB9B7:c1dhB+vWHWRw3YvWpsHRj9Ayj8JjdqYOLnyr0YImxVo=",
"63516700C5CFA6F1BE71B29214957E33:eR9Otw83jJyrj808CkqElVYzlXztuc14/u2pDtPtooQ=:Glider_ID_155_Jellyfish",
"44DB36B2D2B3854669780458D2FE48C4:gtl0smAMRKg8d9TdDH47lUOYCygKzbAPA6/HaXLWy94=:BID_801_MajestyTaco_FFH31",
"5E15C5486CE8E539552D4D3E7682F9E2:+L/tTz+woDFZJEvtxfq8m8tNI1R72sYK7rnYr7sHTis=:BID_311_Multibot",
"2A12750AF48FB5468105F255DC537CC1:lKjAansupIjoXjT3/0vH9XeOzVp9S+fBGtyP90Gve60=",
"591DF838AC4B3A6350E40E026B26D5C0:MBvGoHxJQBTxCm2V82s2yHqRWPsYdFyj8xKUhFsUkyE=:CID_745_Athena_Commando_M_RavenQuill",
"7E9FAC0F2BFC4AE3A2ED4C87D1A57DBF:xaR/8qp7kFAbILx9i6ANnoam0rZ/tP8Xy3yysuqt8BA=:Pickaxe_ID_231_Flamingo2",
"1D02A6E14FDF53655E818CEF9E57B1BF:ekG/6DFEYOaCYi5hruGoY/o1KzC/O5+9hJbdMyti8Gk=",
"E0FB7B394449CE6450EA90C93D710EB8:NrXwNX6lKuu/kyQuvE74+6Uo04FODoV4ZqxToj/jS6I=:Glider_ID_157_Drift",
"1234642F4676A00CE54CA7B32D78AF0C:Nd8vhYp296C+C0TqSIGxu0nBYOFGQ5xBNK5MFjHS8IA=:Glider_ID_115_SnowNinja",
"E48EFA857D8E6914B2505B05AADFB193:4AUdytefPzWNT8c11iGtU4xcGNWEgzpMJbxTjUq3NS0=:Pickaxe_ID_465_BackspinMale1H_R40E7",
"A31042B93988941EE77BC1E2DA6AA05E:pDUufUGsOVTv3LuXoq56xwz8HRnzlrHTvTLWbzBaPcU=",
"715D5B8D89F01C804C2ED33648157A6C:GbMcQmdpv3ju/P36UQIlDFZ0Q5jr0he7O2oTJ702McY=:BID_446_Barefoot",
"286270CA017B478C6FF6B5B815428F93:OUbNW00OmQLCd9iLA13soMU4wYtd0RTc+lEkoPdvF4U=",
"053E7EE2FE8B6EB117A01D1E0AF82AD1:SDqBD0e/4fAyf3WCPqwUQD/gDhMWPtbdTZt5j/p3M2A=",
"91BEC79063CD316E69E79215E0CE6437:uE56sTOQozw4kZfj70CQIEFqQOFORE1+mZhMhccG1z4=:EID_ModerateAmount_9LUN1",
"71BEC74046C6920A467E57B69FA3835A:q6m1xB4+mCmXL3g7eRGykDO6ZKrXS8M7m8SqbqIKzkI=:BID_201_WavyManMale",
"72CC2893A6B672F3854F36629B770774:0BgQgKZRRuPFEoqn7CxZVhLBOfpCE3qLKGQlZc+SA80=",
"22B8405FC3BE153C8148422C3F2D3A8A:d/ATMDztVZxwHLUCwOcJWP1/7oPKKGqbBWUBRNZ6dnM=:Pickaxe_ID_664_DragonfruitMale1H_4BIXL",
"23280A6FC0902B6420BB82522AE16D2C:C7o6m2vJJY+XWKd0t1YLBPVLYCMgNbt10d/itx5Wjnc=:LSID_367_Paperbag_3WGO8",
"E59B013651F078E718F08ECF9E1559EE:rTGy9at5kTfQtu8EwVrUihfzuN8vkFPl3XNyGvqbZX4=:Pickaxe_ID_194_TheBomb",
"D2FAE1D098B2B4695EB59FAAD504798D:ZUDIqDvGVcpCVuA3h67vdkVbZwLuC0Z1zX33JLyi5xE=:Pickaxe_ID_727_LateralFemale_D9XJG",
"8D578CF915DB851F9BE73C937D3565E4:Xk8kUK9cut4tXr0VQjufZdoepp+TzGmlDA7fzYA1rAc=",
"17F31F416B1B0A73F14F0A7973DDBD76:+hUk8/wD736u5sylQPXcKKREoo5vSPaWPG+3xxT5nFM=:BID_207_DumplingMan",
"682BB8BC5B0BBE6318CF2164E074E7E8:NA4nCwFqo95pvsqkLXWO2WDdLY+MQGcj97N6t881BQE=:EID_Socks_XA9HM",
"22AB4BDC10065AA49B38DE88522DF836:1L8L+oKtSOtIxbm1x0HbDtzquIH6CH8vu1PF4i8jU+w=:CID_447_Athena_Commando_M_BannerB",
"B3A4B83DA3274522D4B9F117DCF9A0B3:y5n7vfr0uucr+psZzb2F3g45pWUsv3i3j/M6bl78Z9A=",
"010E6ACF85E4A58BF6F551EFE7B85F61:DwCIH5Dw/1wdiS6gFGmWe4HUgD9kMOEzjbzM/1QshM4=:CID_371_Athena_Commando_M_SpeedyMidnight",
"488F01C34A9A24115776EA801A6E7E1B:WB1TFXsB2Cywzb16hZ2HdBc8X1FsTVqzlDwhyJO8Pcc=",
"B1EB196DD39D0736E7E08F99B07D8B9A:1fDhBY8uhi++l6QQPL2YtxZgUv04OZoMGBrH+yN8yKM=:EID_JanuaryBop",
"6B0D17A04F83AAF1E4EC1D0D481D7B03:fgSAnECppKmZD1eolFEZOuOpUDPbt1MmvGroMQ0sPFU=:EID_CrabDance",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_941_Athena_Commando_M_Football20_E_KNWUY",
"BE2C3EF59AB81D812AF5B8153325998F:W7NoICLZt9L2d7XZ5dT9gtI80MyOizk7uA9LtwA/Edw=:Pickaxe_ID_687_GiggleMale_YCQ4S",
"B4585A36D49CF15E1E236775B8C659C1:Ced0+UTeTBbDhnHM9mLTk5qxlz3YZK6dEn1U+NTxOko=",
"98BCB8B7136162178BF364D6105BB9B7:c1dhB+vWHWRw3YvWpsHRj9Ayj8JjdqYOLnyr0YImxVo=:CID_997_Athena_Commando_M_GlobalFB_C_N6I4H",
"7A59383C41DD998408A74BC37C7D6887:nSrruhpHV3ZEPPECeqWkMh/6mBFzQD8yEFKZS6oJeu8=:CID_A_087_Athena_Commando_F_Hardwood_C_AOU16",
"280F643808DE5EAB39E77B23E2193CE9:lYbsbCLMwjFvdalNxsBUj+PZiJmtoa/wclz2sAOQxuM=",
"49034BA1606B1672C8B634D2C6186807:5ujMnF4IKuvumpfNcUA1yi1mXjy5zBGPg00TJkHlG04=",
"58388BA7BD1643A85EFD49BF26EF5912:Aru327JJHsGKCD2YlQT+Ejy63//vly9ChTdKsfgL75o=",
"BA490514EFDA436A2679E381BD558AA3:3KBKxBOi/52H0feJ/ijKxRHk+lF1zID0uIpjd0T7/Bc=",
"1A10A7700C3780E2B1A03037D64E1EE5:IvQikWqraVuMzt8eP1B0cxW5Dcaiv7njo2QHFfZFmY8=:Trails_ID_081_MissingLink",
"E4D8D083C49828F6BF310ECA74A84F98:NxjtZXHe49xC1zUVs+XKjHbeic3prkFOWmwkaQ1vOFw=:BID_850_TextileRamFemale_2R9WR",
"AE9F7B3419C7FBD2414D72E2E1C8A7BA:kpIotniLp60tWfbBitDUrjw6gmJ2Swl+YT3QAkecpRA=:EID_ProVisitorProtest",
"F395571A36D2BD888861E61EEBD45AF8:D/35GPTIOKbdfmpxRJmHTkjNXcWv+XdSmTxQt6z1hvI=:BID_701_SkirmishMale_5LH4I",
"91181AD6BCB9443F7F6479DA8BA9B7A4:ckv0KEQuDpca5cP5JLUH8K1f+tVYvZptoMsGYR7fxDU=",
"828B24CF7786DF74D8511CA89DEED8CF:nCahv7mQhidmYXSmKif6z7d6bQ60mdPQ7SrdZ7a3GaE=:CID_906_Athena_Commando_M_York_B",
"0F810ABB0DB8672A438B14169C048145:9vfFUEaEveznaEvyq+mhGagh3w98fRdZ5BpwQgNzMzg=:Glider_ID_133_BandageNinja",
"EBFE6788D367D741AF0A4FD098CDFD39:FAeJTGyT49P+dQOmKx+lMYVAxu7qtIPlqSaLAR85zqI=:BID_271_AssassinSuitMale",
"A25DFB2C9EBAECE22F893DAA48A7138F:d5KZse0g/v9xySiDWLhNw3kCvlWXZKWMKUjDzW8/SIg=:Pickaxe_ID_435_TeriyakiAtlantisMale1H",
"4009CB877085F3B3B0D76A686465A140:gMLJXUbFcIrqqUlAuoMI1b27KdWHBVJJeJWdYV1Iiro=:BID_703_KeplerMale_ZTFJU",
"7ADE21079D27D9CA3931F676358A0F72:jWtbxcYHNph24P0SKVvPEuGDIdFpq+wZAEIlGXhSpj4=",
"488F01C34A9A24115776EA801A6E7E1B:WB1TFXsB2Cywzb16hZ2HdBc8X1FsTVqzlDwhyJO8Pcc=:Pickaxe_ID_538_GrilledCheeseMale_Z7YMW",
"F60CFFFA32CF6A877B50DA7F0A88326E:OWIopbB4fxaobofPI9lF9hn6BPG9NVLp4Od61uQppfo=:Wrap_048_Bunny2",
"F044853E82632E827ED91FB4AFBD28DF:LH1pXQ13KEoYfxxylALn8jaS0t/7IrVRVmO8UXieaVU=:Pickaxe_ID_693_SunriseCastle1H_5XE1U",
"EBB742679C34C9D4E056A5EAADF325B9:ousld0RIkeu9L9aTDwr9aNCIt+wOwB7KxGPY9BTfQ7s=",
"6ED300E6401C02B19FDF5F82D945C661:OVr0GWPGv86nzWikKzrw2SC4aS+4ApgKKLvQ7d0Nkn0=:CID_336_Athena_Commando_M_DragonMask",
"5D6562F1EAD89513C82C2F37A24E7F82:I2c+SQCdDvJpC6z1xniRT+k41KAp0pla+o/H68oXFLQ=:Wrap_179_HolidayPJs",
"9E9072AA036FB1FF6B2AAD7BEFE7BF17:ORHgZOt4Zrtc8dLSx6jCsWZ3Z6AwPJiSiFAkZRMK3kM=:Pickaxe_ID_649_AntiquePalMale1H_GBT24",
"63B2E664F9DEE5B42299191174C3B3C3:U1GOSBqPUDAFq3pjEdJg8nHb321IH6571dkhF0nEMss=",
"4C8D53A32D85124D08A3DCE6D3474A30:gam5sVciLPzKr+wmWOoctLo5HFqBvBLKKcxh6ZV1kn0=:Pickaxe_ID_533_WombatMale_L7QPQ",
"C7623A35411F3D5FBDE2688C7E4A69EB:qAi49mUKsB2dbfbtJWDf3yO2DfRStA+Ed9XgDjC8Zaw=:BID_189_StreetGothMale",
"21D9E3FA446D32EE85025841557C1E4C:KBL9ZqzocmLvcq5k3mwTCeoeeVfJdw9wjuQacUrg50w=:CID_A_240_Athena_Commando_F_Grasshopper_B_9RSI1",
"0882DAEC4F7823551C4955BA25B8AAC4:kGljCDpbMnCIfeo0YBLpBKDhX6nLlCaZRe62mSYSPTs=:BID_917_RustyBoltMale_1DGTV",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_953_Athena_Commando_F_Football20Referee_B_5SV7Q",
"F6E92DDBC70C8184E837D31905B2F2A7:UCSPatT+yv3YH2x0Ks+2GSXhSSu+3ZvZs6Lai3oOi0Y=:BID_826_RuckusMini_4EP8L",
"FBAC0AD8C03AAB2DC3BC077597517179:5oj8B4R53plPxRictMN6QkQ741CibMbmzRJYIDIQ5iM=",
"A10B1E27AF53CDC331BF4797C97B6B9B:fy5fTzL7HXpOBRg49CHm/E8Iptd4X12eYNBAeSa5CY4=",
"BAEF248980269F569C6E1FFF2B885DF6:2b6DQGIcab1r7zsw5j3MR84iDmt0g1XBquxJVR/8GxM=:EID_TourBus",
"0882DAEC4F7823551C4955BA25B8AAC4:kGljCDpbMnCIfeo0YBLpBKDhX6nLlCaZRe62mSYSPTs=:EID_RustyBolt_ZMR13",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_945_Athena_Commando_F_Football20_D_G1UYT",
"0882DAEC4F7823551C4955BA25B8AAC4:kGljCDpbMnCIfeo0YBLpBKDhX6nLlCaZRe62mSYSPTs=:Glider_ID_333_RustyBolt_13IXR",
"BAEF248980269F569C6E1FFF2B885DF6:2b6DQGIcab1r7zsw5j3MR84iDmt0g1XBquxJVR/8GxM=",
"22AB4BDC10065AA49B38DE88522DF836:1L8L+oKtSOtIxbm1x0HbDtzquIH6CH8vu1PF4i8jU+w=:CID_443_Athena_Commando_F_BannerB",
"7A59383C41DD998408A74BC37C7D6887:nSrruhpHV3ZEPPECeqWkMh/6mBFzQD8yEFKZS6oJeu8=:CID_A_089_Athena_Commando_F_Hardwood_E_4TDWH",
"7A8E25F664219ED6CCF3AB1658D0E557:TV+yyWpI3iHJoaK3o1t6+/uhN/sFZ1OixoAx0n7MtjM=:Wrap_118_AstronautEvil",
"A6855B699FE10FE50301AFE1A4FA74CB:fKXFbKW6dUWHLSC8M4KLAg1elVXH+wYouFbpvvtiIcY=",
"E4143E437DE7481237AFAB40C59D96E6:a35NCp3zTY2AhSsZWy09BJaXJDU0LMJbiiP1u0dOl0Q=",
"4755D9C0E2D1DE1C09B77DEA8B830471:9tUO5yVhvp+/sp7icZaEDw05nMAdS6bYAWYyfQNsxBc=:Pickaxe_ID_388_DonutDish1H",
"099F6A310406E06EEE5B011F57E8ADC5:eN0n2GvhVfW8LKPVA+LvlegACOXLQLyOxt24wFERaio=:EID_OverUnder_K3T0G",
"21D9E3FA446D32EE85025841557C1E4C:KBL9ZqzocmLvcq5k3mwTCeoeeVfJdw9wjuQacUrg50w=:CID_A_238_Athena_Commando_M_Grasshopper_E_Q14K1",
"1C8FA86241B2E4D084F7548529629CF6:pmXOfd+NEXcLhZX5YqDLjHu8/yzZoo4dWPcCM8ccXoI=:Glider_ID_118_Squishy",
"22AB4BDC10065AA49B38DE88522DF836:1L8L+oKtSOtIxbm1x0HbDtzquIH6CH8vu1PF4i8jU+w=:CID_442_Athena_Commando_F_BannerA",
"B7D9219AF6290146AAFF711E464C5849:iwGv47bJtl/Tm8oJGdnta9aDA86nY0IyjDmJWjQYdQo=:EID_TrophyCelebration",
"0882DAEC4F7823551C4955BA25B8AAC4:kGljCDpbMnCIfeo0YBLpBKDhX6nLlCaZRe62mSYSPTs=:Pickaxe_ID_721_RustyBoltSliceMale_V3A4N",
"828B24CF7786DF74D8511CA89DEED8CF:nCahv7mQhidmYXSmKif6z7d6bQ60mdPQ7SrdZ7a3GaE=:CID_908_Athena_Commando_M_York_D",
"CCFB247DE6ED8DB4856E039A5AE681B8:Z8ixoqcCEiFqUH1qec+yUNQTP1+D1xQjYw6FDpUQa9c=",
"9E9072AA036FB1FF6B2AAD7BEFE7BF17:ORHgZOt4Zrtc8dLSx6jCsWZ3Z6AwPJiSiFAkZRMK3kM=:BID_827_AntiquePal_BL5ER",
"F7CAA8D040108722FFA35FAA63DFD63E:WNwYWakPoe/BGxI8+xsB446zHv4R9A1krz8SK2y8Pmc=:BID_164_SnowmanMale",
"D938886074C83017118B4484AECE11AB:wjHAHm00Vg6n2x5LU91ap0+SFX5ZXXBmax1LyX8Aips=",
"E45BD1CD4B6669367E57AFB5DC2B4478:EXfrtfslMES/Z2M/wWCEYeQoWzI1GTRaElXhaHBw8YM=:CID_229_Athena_Commando_F_DarkBomber",
"204D49F063979C3AF87EF896D074D1CF:SaYFk+GEE7mL4dsgs0v0VGR5ER4TwH8uTNX5XqSglu8=:BID_643_Tapdance",
"D938886074C83017118B4484AECE11AB:wjHAHm00Vg6n2x5LU91ap0+SFX5ZXXBmax1LyX8Aips=:Pickaxe_ID_581_Alchemy_HKAS0",
"0882DAEC4F7823551C4955BA25B8AAC4:kGljCDpbMnCIfeo0YBLpBKDhX6nLlCaZRe62mSYSPTs=:Pickaxe_ID_719_RustyBoltFemale_0VJ7J",
"27D6556F776B2BDA97B480C1141DDDCA:uvUqb5LuwRFWQnA4oCRW3LNdorYcGtOmJ8PvBeCwBKg=:CID_467_Athena_Commando_M_WeirdObjectsPolice",
"A93064DA8BDA456CADD2CD316BE64EE5:nziBPQTfuEl4IRK6pOaovQpqQC6nsMQZFTx+DEg62q4=:EID_Bunnyhop",
"3AC8A6B5089F55E17E00AAD8AC3C6406:TlUSkJe3y85fW83rHMy+XuqcZxQduXcB8yftpPoiDvo=:EID_Loofah",
"6EA156BE3D18E1D649D7D4B3F8C0FACA:qAKD9oM8u4IvUcKbReHTMaLg7GtHLBcnmz8++vwwB6o=:BID_906_GrandeurMale_4JIZO",
"E47EFA3166A5D7B35CEC27B19AC66AE5:JURSqAHhHK6YqLP5rKhCO+SQ2oql4NqJaoaeNGtsrM8=:Glider_ID_304_BuffetFemale_AOF61",
"A25DFB2C9EBAECE22F893DAA48A7138F:d5KZse0g/v9xySiDWLhNw3kCvlWXZKWMKUjDzW8/SIg=:BID_566_TeriyakiAtlantis",
"B0030ECDA329A8B589D249F794EA90B3:BfF0FYJQJ71DMUBmClT0DppsOy+1Syn8fGu6qNtTgXE=:CID_A_094_Athena_Commando_F_Cavern_33LMC",
"110D116208C62834812C2EDF2F305E49:MwuF5zX7GpQCGL2w+CwkPmGzH3q05YUoLo5udhVMNPg=:BID_488_LuckyHero",
"40E9F547033360DFC0DD09743229B87C:x0/WK54ohwsadmVGHIisJNyHC8MqlU8bg2H+BsaEBtc=:EID_Kilo_VD0PK",
"2E539CD42E0594ED4D217ABE4E2B616F:9zdoLMrIZomTGmvDId1RMEGSfktV9gBGgcD2diSSMw4=:EID_NeverGonna",
"EB16EA013B751792698E05435797C1ED:y9JgD812Io4mbaJ5i533Ts5SSfyXaGM4JyoimjP+i4M=:Glider_ID_135_Baseball",
"E4D8D083C49828F6BF310ECA74A84F98:NxjtZXHe49xC1zUVs+XKjHbeic3prkFOWmwkaQ1vOFw=:Wrap_394_TextileSilver_ZUH63",
"488F01C34A9A24115776EA801A6E7E1B:WB1TFXsB2Cywzb16hZ2HdBc8X1FsTVqzlDwhyJO8Pcc=:EID_GrilledCheese_N31C9",
"21D9E3FA446D32EE85025841557C1E4C:KBL9ZqzocmLvcq5k3mwTCeoeeVfJdw9wjuQacUrg50w=:CID_A_237_Athena_Commando_M_Grasshopper_D_5OEIK",
"47668DCAEC0AE101E0402B6105A6DDF5:rSOpMue5liEBVSvy/0JZZGTPsP2QeA7Yw9GdicJHs7Y=:EID_Macaroon_45LHE",
"13F1DD5EC796B357B6085D50BBDA3C18:7NRW9FQONfoNEwOJARayC1upKkjg3obxAWICvcXfUWs=:BID_426_GalileoKayak_NS67T",
"E7C565B86445735863B8080B9BE651F7:7M3P/+is0y8muF7/0N2dJo96J3P/k991Vast/lb7Xec=",
"6DEBEC4266A3BC248F8A8FD4B76878BF:wjCAJ9VaThgTfbvUetCEWQFii5GmdfPwFCvxLv5ip/g=:EID_Eerie_8WGYK",
"2E5F91AEF58F310AE2044EA39C43BB81:pNy1GtfVzymqacOqXRY14EZEvI5ZSVD5AFxlhxXC5qk=:BID_870_CritterManiac_8Y8KK",
"6CED8B5F648ED1ACCC8F1194901775AF:qjfCT39FVniEjPj+CvZu5Qz8XHHtdnH8kCsV3P1OaJw=:Pickaxe_ID_196_EvilBunny",
"488F01C34A9A24115776EA801A6E7E1B:WB1TFXsB2Cywzb16hZ2HdBc8X1FsTVqzlDwhyJO8Pcc=:BID_687_GrilledCheese_C9FB6",
"BFE1F518C16A9F061B140D829ADDB0ED:bHkPYjXd71vacoJ4IisL//zEyVLFh+Di8MUqV9KkpFU=:CID_A_138_Athena_Commando_F_Foray_YQPB0",
"F395571A36D2BD888861E61EEBD45AF8:D/35GPTIOKbdfmpxRJmHTkjNXcWv+XdSmTxQt6z1hvI=:Pickaxe_ID_553_SkirmishFemale_J2JXX",
"CB3D84444FF0E551D18939AA7226B17F:U4GIAd4fGYWy9tySw3iVb92+6ZX3rQ3FsiBCXMT4TSo=:Glider_ID_108_Krampus",
"2DCD2E2A9A816AA9035999F8E6F85F6E:6xM4ZYt0UAylyuIgFrmOgq4fYVH2ChEzQNcl8KGQF0o=:Pickaxe_ID_406_HardcoreSportzFemale",
"6EA156BE3D18E1D649D7D4B3F8C0FACA:qAKD9oM8u4IvUcKbReHTMaLg7GtHLBcnmz8++vwwB6o=:LSID_372_Grandeur_UOK4E",
"975414A2AAC78A3710C3A47A8E3B7A57:LQWa9K05LB13Fn7Brzi8R3vsMRmFcNyJaoAcmBFZNjg=",
"57EC154062C75464BD8A087D89732317:5AEwoCp79njYci8QYF+sLMkGpjDnFCYLSCtz4LD9D78=:Pickaxe_ID_328_GalileoRocket_SNC0L",
"4C838738CDC4946786DD7BE341AB05DD:eyjCm9OcFQSvVRVBZizNVyF+8kb9OlNFrvDy8d1QDfo=:Pickaxe_ID_197_HoppityHeist",
"98BCB8B7136162178BF364D6105BB9B7:c1dhB+vWHWRw3YvWpsHRj9Ayj8JjdqYOLnyr0YImxVo=:CID_995_Athena_Commando_M_GlobalFB_H5OIJ",
"B66EED5CA4F4ED75170872E30B9B0E23:rHT8/uzcZZ0ENxU9dxKpr+cdAajZ5L5U0geHt6NoZhI=:EID_Fireworks_WKX2W",
"6A3F6093DECACCD1F78CF802DE7AFF84:Skd0CfmqkmJAUqDFE6Qy/adL2MSN4IuAndXZ0SepEXw=",
"7E9FAC0F2BFC4AE3A2ED4C87D1A57DBF:xaR/8qp7kFAbILx9i6ANnoam0rZ/tP8Xy3yysuqt8BA=:CID_464_Athena_Commando_M_Flamingo",
"4E7938F1FAC98BDF378823116712AC7A:jbZVgprILTQomUdGeJF0PsAFAJxsSCs5cKcXweZMAg0=:Pickaxe_ID_548_TarMale_8X3BY",
"63516700C5CFA6F1BE71B29214957E33:eR9Otw83jJyrj808CkqElVYzlXztuc14/u2pDtPtooQ=:BID_295_Jellyfish",
"1CE4B8636E40B4AF8858511CE01A98E3:+vewfAbMTec/enBaWVzzCxiHw8WLTJvfAWzFmcOJT4Y=:EID_TheShow",
"7A59383C41DD998408A74BC37C7D6887:nSrruhpHV3ZEPPECeqWkMh/6mBFzQD8yEFKZS6oJeu8=:CID_A_086_Athena_Commando_F_Hardwood_B_B7ZQA",
"2CB7CC414F921DD774957AAF4AD5F8FE:vi2xluuUw+pFj/tqqfvh7cS9Qnr8gQPEGX0IHyjZVp4=:BID_185_GnomeMale",
"B229884F839295B4B9EDC380B045C64B:SVmPvZenzQ5Si17i8daUFyKoOGDtaH4YZtsF1s2XkxE=:MusicPack_084_BuffCatComic_5JC9Y",
"5950552B5A52A97A433715A1FF107BC4:p9RBdPmk5295pRSg0+Ybfwy/kqY6HBYiJEAkvy650O4=:BID_171_Rhino",
"7AEE99564551FF8EE98E6887410AE8E2:Cumd3/0knsdwt4bl7zNQw8MKmmIuC/4wYVfVtQq5d2o=",
"E48EFA857D8E6914B2505B05AADFB193:4AUdytefPzWNT8c11iGtU4xcGNWEgzpMJbxTjUq3NS0=:Glider_ID_241_BackspinMale_97LM4",
"E47EFA3166A5D7B35CEC27B19AC66AE5:JURSqAHhHK6YqLP5rKhCO+SQ2oql4NqJaoaeNGtsrM8=:Pickaxe_ID_644_BuffetFemale_TOH8A",
"F395571A36D2BD888861E61EEBD45AF8:D/35GPTIOKbdfmpxRJmHTkjNXcWv+XdSmTxQt6z1hvI=:LSID_274_Skirmish_PJ9TZ",
"0EC19805A48534C8892FA21C75024971:WcebSI5r6bMgSAbNd8Ob187rYmIJFJciobdyQciRiSc=:Pickaxe_ID_268_ToxicKitty1H",
"F044853E82632E827ED91FB4AFBD28DF:LH1pXQ13KEoYfxxylALn8jaS0t/7IrVRVmO8UXieaVU=:BID_876_SunrisePalace_7JPK6",
"BA6DF4F82C5CAB3CE1C51156BFCACE71:SDOlhnlP1SENGT+SrYUqeGIz0TkgoM7dQjfmfxegb1o=:Glider_ID_176_BlackMondayCape_4P79K",
"F6838AF4144E8386A184FBB0823C15D0:IjzqnnHjZ+r6WC4He/JawOyR7LxeMbm5880cDGDr2eU=:Pickaxe_ID_174_LuckyRider",
"B8F307A56B6EEFACD6250B2E60A24A4C:ayYSM667dKzMIvm8ZUY0F+FNlvNsg4G2RMIgi2fPf8k=",
"09D84C411F2EFF940F5D462000CA5BE0:6Djlf6/XCCTMpI4KbNEHN4X6prgcnfQtru+z+RTHs2s=:BID_736_DayTrader_QS4PD",
"C6F7AEC922E28FB25AFBC50442F57877:qJNZNWzxSxvlrklYDsNkZek9OD8kGV6lI+Hfmm+k0gE=:EID_BluePhoto_JSG4D",
"552DB214510DE1E24F08920F80B0AEC5:GP2CYv9xYYDf6bOnpgm0fnOXa3iI0acXH02ZIaHAElg=:Glider_ID_306_StereoFemale_0ZZCF",
"57EC154062C75464BD8A087D89732317:5AEwoCp79njYci8QYF+sLMkGpjDnFCYLSCtz4LD9D78=:Pickaxe_ID_326_GalileoFerry1H_F5IUA",
"16FC688AE41A3E3C518F4DD9F9612EE7:Jd7nRLx/FoonA2dUjtbvJVk3nJoNq9LTedk3u4EdFS8=:Wrap_044_BattlePlane",
"D517F2A448CCB9B47E5004894BC62ACF:qOdQUR91sysqDRELOgz/YVZ7Piae8hqcrnYW90fXtvU=:Pickaxe_ID_680_TomcatMale_LOSMX",
"7B1151E3094646DFFD37B6492B117FDB:4WxNHdTgHDEpGjzIV2XIjGO41kyiwggFQpdq8y+o1jY=:Pickaxe_ID_577_TheGoldenSkeletonFemale1H_Y6VJG",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_950_Athena_Commando_M_Football20Referee_D_MIHME",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_944_Athena_Commando_F_Football20_C_FO6IY",
"5738A14C7E45E1B405CEF920829CB255:xZHlPTz/dxNahrp9IqTZ+tjOZSYMxQb9KZFXlg9N638=:Pickaxe_ID_330_HolidayTimeMale",
"4C546A04EB0E91B7EB4449B672B63900:RhtdrUqq3N21E77X7YatI4oX3wLYyvFH5Wm+eaUX8+w=",
"A0926AD8C6EDE29250AC4A0A93156E7B:keN/yZ7qnvcPZeIflsked9TAT867gbPgmnG1QdlSn3E=:EID_Donut1",
"A0926AD8C6EDE29250AC4A0A93156E7B:keN/yZ7qnvcPZeIflsked9TAT867gbPgmnG1QdlSn3E=:EID_Donut2",
"F4729DF9DB149229267F9389E3C95851:DCXGOUUTWG8jFuEryO+32mXKJsQgQe+Fp82u7mHiYFU=",
"36126C339CEBD31F23562CDCC5DFDD4D:cuLUN7oD/p5BSxuk6pKGY6KtlhGInVti36sV6zSv1n4=",
"0882DAEC4F7823551C4955BA25B8AAC4:kGljCDpbMnCIfeo0YBLpBKDhX6nLlCaZRe62mSYSPTs=",
"566C4D92AF66F45DF5E2D7EB43CC27AE:EuAYwU5tQBXzGoSj5BMc7S5yFfe9wZ2qrzx/hIHpnqw=:BID_629_LunchBox",
"57EC154062C75464BD8A087D89732317:5AEwoCp79njYci8QYF+sLMkGpjDnFCYLSCtz4LD9D78=:BID_427_GalileoSled_ZDWOV",
"F6E92DDBC70C8184E837D31905B2F2A7:UCSPatT+yv3YH2x0Ks+2GSXhSSu+3ZvZs6Lai3oOi0Y=:EID_RuckusMini_HW9YF",
"21D9E3FA446D32EE85025841557C1E4C:KBL9ZqzocmLvcq5k3mwTCeoeeVfJdw9wjuQacUrg50w=:CID_A_234_Athena_Commando_M_Grasshopper_A_57ARK",
"5A1170F589134C4D68AAA2B5AA6EDA69:bfro7s6Qtde/H7C4zc6MJdpua1mhem8HywLluxBLDrg=:Wrap_298_Embers",
"BE2C3EF59AB81D812AF5B8153325998F:W7NoICLZt9L2d7XZ5dT9gtI80MyOizk7uA9LtwA/Edw=",
"919FDAB2FDB531820404333B27DC7B06:W9Csp0y6agsgcQXlRGvYUpPGPImNdFfBsZ8yQoUEdGg=:Wrap_092_Sarong",
"28C5CD0467F2271365DA8AC4DE122672:I1ujTTKWOz0A5LcFiCwKJXQl9bnMpW9yhvY13UaWo1Y=",
"BFE1F518C16A9F061B140D829ADDB0ED:bHkPYjXd71vacoJ4IisL//zEyVLFh+Di8MUqV9KkpFU=:CID_A_139_Athena_Commando_M_Foray_SD8AA",
"C348806ECD35F176A5C50306B0A07DB9:x8+m/v+Cn55R+CIZrsqqSKxa5JpkQyQGeLVTJ8evrpw=",
"0DD695EB05DDF1067D46B2F758160F3E:H8eacvW3rgmZFvWGGwXfojcIBMrQUL+FJQ1x3dzzVm0=",
"BAEF248980269F569C6E1FFF2B885DF6:2b6DQGIcab1r7zsw5j3MR84iDmt0g1XBquxJVR/8GxM=:Pickaxe_ID_302_TourBus1H",
"D47DF51158673BE6CD4D32E84C91DF7F:+EzQK4ojNk1DqxceQeArAGZhQPQyuQBKX4gVuGEqSxM=:CID_632_Athena_Commando_F_GalileoZeppelin_SJKPW",
"6537263AA4E53B6A7B7D4AE3DE12826C:6WOQR0kXJWBJ4miykyUSj/hcH4u5JTSFpBTwaIeIFxQ=",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_955_Athena_Commando_F_Football20Referee_D_OFZIL",
"172B237342C2165A212FEEAC80584DD5:7bGmK+J89yojl49SMoQKA+Zf7ZZ0W3OatE6KZYlGPnU=:CID_254_Athena_Commando_M_Zombie",
"504BC0A80EE72DFEEF9CB7EE3FFCE163:eToIGihi0lTVTcHietksl1e6cHBf5h30aYO5YXpWXY4=",
"CBFF239A1792F25920D863F223368B54:J3N3cUH3M0R3uyzkE0qVK/SouxC/X6VEswcoWb6ViL8=:Wrap_071_Pug",
"ED088B11311A599D6225CE85545F019A:1NMRh4JMXRL9XW8Kb6zo4/F10dwLJC1+kPm6D6DudCE=:BID_832_Lavish_TV630",
"7A59383C41DD998408A74BC37C7D6887:nSrruhpHV3ZEPPECeqWkMh/6mBFzQD8yEFKZS6oJeu8=",
"D47DF51158673BE6CD4D32E84C91DF7F:+EzQK4ojNk1DqxceQeArAGZhQPQyuQBKX4gVuGEqSxM=:Glider_ID_189_GalileoZeppelinFemale_353IC",
"5D6562F1EAD89513C82C2F37A24E7F82:I2c+SQCdDvJpC6z1xniRT+k41KAp0pla+o/H68oXFLQ=:CID_649_Athena_Commando_F_HolidayPJ",
"5950552B5A52A97A433715A1FF107BC4:p9RBdPmk5295pRSg0+Ybfwy/kqY6HBYiJEAkvy650O4=:Glider_ID_102_Rhino",
"F395571A36D2BD888861E61EEBD45AF8:D/35GPTIOKbdfmpxRJmHTkjNXcWv+XdSmTxQt6z1hvI=:BID_702_SkirmishFemale_P9FE3",
"7F5ACEFE3F67BC0CCEB59A4E8EB82BAF:iDG2HB2LypEtzw5/EjKVpJmQ1o30BE3nVv01rOTyq64=",
"63722D44ECCA0F4178B85F5A6BC4C31B:j42UL0bmfBkli6Aj92wWABwFby5rAplP/Ac6nh9kRvA=:Pickaxe_ID_661_VividMale1H_ZN6Q0",
"EBFE6788D367D741AF0A4FD098CDFD39:FAeJTGyT49P+dQOmKx+lMYVAxu7qtIPlqSaLAR85zqI=:EID_AssassinSalute",
"3AC8A6B5089F55E17E00AAD8AC3C6406:TlUSkJe3y85fW83rHMy+XuqcZxQduXcB8yftpPoiDvo=:Pickaxe_ID_399_LoofahFemale1H",
"ECE91B4E506E33C16FA440F4B4313824:dGr4XbhLD3sf28Y3Tawke4Gr/TpwEA5xPOjhgi+ZAKk=",
"8DCAE39C7D9690E19F52655F02C613B2:ZZHbiVsbXquLlrtNVHtryLS3Vd1Ego8/8tlDpeUCgfc=:BID_336_MascotMilitiaBurger",
"06B9F77E165673FD1C5FF5099F43D1F3:Bvw6h4GKOLjC/wFgHQsiLePbBZhtPiNhtr5keDBse70=:BID_421_TeriyakiWarrior",
"FF5A507BCC4519B928075C3DF4603E8E:EVv5b8WFOYZlDUGRqb8YUS1WbIbbT8TjgoBWEQr65zs=",
"09BC93B3441ECBAC30FA23BBEF59CF89:3CHInj+JfLspiVCNDY/GTZ4Pn52nWFeA4qYI0SJv2dM=:CID_302_Athena_Commando_F_Nutcracker",
"CB34283BE466D2421549051C400A9E52:rTmyRzx7oSiBWRv52itbCbAFlLIy7W6dZoDcfyTMmyo=",
"74AF07F9A2908BB2C32C9B07BC998560:V0Oqo/JGdPq3K1fX3JQRzwjCQMK7bV4QoyqQQFsIf0k=:Glider_ID_158_Hairy",
"464F39FB64FAF4AB6843449EDD0BE3BE:0yYMEXLHteghUwUW+SThzKXltdNzvA42CssFpAXgxFA=",
"ECC9E1F04B18E523B2681C2037A17B56:AoeVhWzK5zFpeJ2yqYKkTaRw4vo9162/EuipYvC+jxA=:CID_602_Athena_Commando_M_NanaSplit",
"32E8846645441197B80CF8B1C86B01A1:cwJgOQhsrscdiFfLHzS9WudnE9mBMH/C/SAyX81B2fM=:CID_311_Athena_Commando_M_Reindeer",
"B9E5ABB4D4F783F13E7A32B971597F03:HGWfy8LBJu12s5HZeYTZDqP2EI3dJqPXupxd2AzYdUI=",
"C7623A35411F3D5FBDE2688C7E4A69EB:qAi49mUKsB2dbfbtJWDf3yO2DfRStA+Ed9XgDjC8Zaw=:BID_190_StreetGothFemale",
"234D1D3D37EFF3322E44B31200C1ACEA:T3lGoZ3JIVg7vasMQCr3hjyRo8x+HS1Arh43XvdUKss=",
"CBAC886CCED55EEAEDC0D4BED9588035:+5bLkb9JJIJBPrVxzvfhb0CkKU4ITf8SJRRG14UzyfI=",
"BA490514EFDA436A2679E381BD558AA3:3KBKxBOi/52H0feJ/ijKxRHk+lF1zID0uIpjd0T7/Bc=:Season18_Haste_TrickShotStyle1_Schedule",
"D14FDB2BB2FB7746797F25470913BFF1:CQDgIxcNnAoUboQnjafZAYvV7UqX+NefGTXFd3m+oFc=:BID_907_Nucleus_J147F",
"98BCB8B7136162178BF364D6105BB9B7:c1dhB+vWHWRw3YvWpsHRj9Ayj8JjdqYOLnyr0YImxVo=:CID_A_004_Athena_Commando_F_GlobalFB_D_62OZ5",
"D82BF0194AE18598B8B08491E2256E16:3ENJiAAhBVgbroE9WbkjWK5YqL8vzJ0sFKhadRKcQjk=:CID_255_Athena_Commando_F_HalloweenBunny",
"E46E6578D28965DB74B642E1CB239A5D:Dg3Oqkcno7QuLDGdi4N4VWSMSAd8bILyJT8Gh0PYjj8=:BID_758_Broccoli_TK4HH",
"F3A99CD0D4F58EECEEB0D112506AD846:ZZtCRPcKk6itVryDavp7uZFIXiZF5CW0O9b+8Zt2Oag=:BID_820_QuarrelFemale_7CW31",
"0CAB99F6E84D4E4C616B895E243F3B67:DWU31IKjnLsEt8sBBDfWQ3DPbZzpJ2JmfbxYdQ8QPZI=",
"FC4FC301558D3E9321A55180263EB17B:OXujupiNRNT6+b1g1dg2IXPtdQyfoNPUuvtgqfXnlEY=",
"22AB4BDC10065AA49B38DE88522DF836:1L8L+oKtSOtIxbm1x0HbDtzquIH6CH8vu1PF4i8jU+w=:CID_445_Athena_Commando_F_BannerD",
"C23FA9BDE9342B508B8AABBEEA6699A2:3mRtSSu9PTBlC3NpGAQcFent660Ptni4HbGX+Zj1KIA=:Wrap_404_CritterFrenzy_SNXC0",
"72CC2893A6B672F3854F36629B770774:0BgQgKZRRuPFEoqn7CxZVhLBOfpCE3qLKGQlZc+SA80=:MusicPack_112_Uproar_59WME",
"63516700C5CFA6F1BE71B29214957E33:eR9Otw83jJyrj808CkqElVYzlXztuc14/u2pDtPtooQ=:Pickaxe_ID_223_Jellyfish",
"5C0BC5E8819B8968CF25C60885F0CB5E:E52Ld2gtMzMFUMkdMpjNWmEHEgr1qnH+iliH2ha27dQ=:Pickaxe_ID_275_Traveler",
"258AB620A71C14508FB6614003DCD34E:fjPUuwSZbKfHlvSh8RMyVjR2SVTcVrGNpWvyjNVQ8Xw=",
"C66F354B49A4389E7636C1BF53CE8D97:BisMzLIPd3AuIv431ryh7DE1h1HYe/NdhBC0wkLq/zQ=:BID_204_TennisFemale",
"1162D72490AB6D040106B276D14B20D2:UoybfdmMPLyXmLpTKBZB0sqSOvXnKHabF/nv5olkuoQ=",
"6EDDE286471D1369B09E65A6B02686CF:2MDxhxeBxx/dN+Q/lwCG+poxzpStEQLDM0L80CoaEG8=:Pickaxe_ID_152_DragonMask",
"5D6562F1EAD89513C82C2F37A24E7F82:I2c+SQCdDvJpC6z1xniRT+k41KAp0pla+o/H68oXFLQ=:CID_650_Athena_Commando_F_HolidayPJ_B",
"E66DF3CF1BFE84F0B1966967210DD6D9:DGLD/iFbdLvaiZnAfWrHIW5yJ5SfsQQyjeW2IBQe+zw=",
"6B91F0DFD2780364EC6FC5E531665208:sBhYta4JrxcssCLVBkFXeJpKa7gQKHepqu9840vo6h4=",
"5332028CC33C98BF747EEF82B0384D8C:QxdEIZba2DLRx0jYKm8UpIk/K6eKuclfvDSTllMLLrk=",
"57EC154062C75464BD8A087D89732317:5AEwoCp79njYci8QYF+sLMkGpjDnFCYLSCtz4LD9D78=:EID_Galileo1_B3EX6",
"BA6DF4F82C5CAB3CE1C51156BFCACE71:SDOlhnlP1SENGT+SrYUqeGIz0TkgoM7dQjfmfxegb1o=:EID_BlackMondayMale_E0VSB",
"57EC154062C75464BD8A087D89732317:5AEwoCp79njYci8QYF+sLMkGpjDnFCYLSCtz4LD9D78=:BannerToken_015_GalileoA_0W6VH",
"72FCE9EE6B90885970CBD74AA2992B68:UvFcOwG78Bx6kVWWHd3NsSarAeWZAht32WLeqs0Opoo=:BannerToken_003_2019WorldCup",
"82669F5A2F9B703D1A6BEA3BCB922D7D:Leu9rrDPaqZd3izIU+IKpFcP/NNcqSncLkV2lapQL6k=:Pickaxe_ID_221_SkullBriteEclipse",
"08788A9DA34F4164ADA4F09FBF698CC3:DlhRrdBGDNADUAMRj4oAUwwR2j33Nr2ZNg2CU3i1/Pg=:EID_Quantity_39X5D",
"BE2C3EF59AB81D812AF5B8153325998F:W7NoICLZt9L2d7XZ5dT9gtI80MyOizk7uA9LtwA/Edw=:BID_872_Giggle_LN5LR",
"9944BE1C4E9D73E4FA195380EF0B7BBB:LQxoRi0ktKvKMLk6hauL2Gzs6zf5bcEk3mgfX0We/uc=:Glider_ID_122_Valentines",
"340C0957F37B985956E74242A9487B5A:CiISJuNPymcbI3tJAxIaNfGCcHBr1ttSFr++4c5DQx0=",
"7A59383C41DD998408A74BC37C7D6887:nSrruhpHV3ZEPPECeqWkMh/6mBFzQD8yEFKZS6oJeu8=:TOY_Basketball_Hookshot_LUWQ6",
"88FA70760D757D80F661FA53B4762EC2:7OtV76cpyOq9dNeM5PVD8TOdRcPx1K3weEPXzlCugu0=:MusicPack_106_Bistro_DQZH0",
"30A11EE8EB62BEFD4E9B09611DB13857:YVeVPXcP7UoJTp71ZXpGNdPVzmjnRyymcUpsNWYXfRs=:BID_506_DonutCup",
"30B53CD6A14D4EE40C71C60E9EE0DD93:RFvcbS74Q3YPnQpxUbhafzeiqVYKv6Fxukfi77h2TdI=",
"29DCC9CAE821CAF43197545BAFB9CDE1:i9A5h7EdSe56nquoLOHdmUB6HKB50OzHpQMLXDjSQkM=",
"E4D8D083C49828F6BF310ECA74A84F98:NxjtZXHe49xC1zUVs+XKjHbeic3prkFOWmwkaQ1vOFw=:BID_851_TextileKnightMale_MIPJ6",
"604C6242EB2BF301BB5D4BC6E3AC5A8C:Y7c2+dviThEDuVsG9kIOjMfnLdJUnPMbdaY5gKiVki0=",
"1050DE04C393D98D22D50388175B4834:aFzCQrL5V9QxBU7hrblnr3x8oWjKs7MjQrua/tyBEQI=",
"FD0C3696948675DC3C2CBF5098D57D0D:rBWyTh/AVyZxi2oiQxM/OeD/HYZOSdVidEQeKoowV6U=",
"545B9777127F4BE242F802C627356B7E:RNI/KvLEXcGoGnk3/AKaYbyJmXMtQl9Zmvl8ErePB4g=:LSID_360_Relish_FRX3N",
"4F53A11AB9CD08FA18D603BF29415366:mq1giTyk7GAqrpXphg9STetDQnhFBS5M1SYEHM7uYqk=:BID_251_SpaceBunny",
"B229884F839295B4B9EDC380B045C64B:SVmPvZenzQ5Si17i8daUFyKoOGDtaH4YZtsF1s2XkxE=:Pickaxe_ID_588_BuffCatComicMale_12ZAD",
"828B24CF7786DF74D8511CA89DEED8CF:nCahv7mQhidmYXSmKif6z7d6bQ60mdPQ7SrdZ7a3GaE=:Pickaxe_ID_491_YorkMale",
"545B9777127F4BE242F802C627356B7E:RNI/KvLEXcGoGnk3/AKaYbyJmXMtQl9Zmvl8ErePB4g=:BID_873_RelishMale_0Q8D9",
"F044853E82632E827ED91FB4AFBD28DF:LH1pXQ13KEoYfxxylALn8jaS0t/7IrVRVmO8UXieaVU=:Glider_ID_324_SunriseCastleMale_2R4Q3",
"768A95DE7B657B7B23D5A0DE283EB49F:JLLAz46a7wo2rADQvCkbp4IbKexr7J5bBr6d6toSn50=:Wrap_049_PajamaPartyGreen",
"F07BE27DCEFDF52818EE7BA2CD9CA504:lc47A/VahaBWJLQY4V1YyjzJPI5xVErInDaqdwPjv2g=:BID_255_MoonlightAssassin",
"2CEE3C1783B9E41EB66238BAD32EFF23:udlTL9abg8LIGytWpERMGVEpPrj9io23R2HbINHtF3o=",
"86588ED13DD870C5FDBF91B3C739D156:HFqg2udb5qqasLf+D2jzfRahu3HgBZWZN2AvnSUIIzs=:BannerToken_002_Doggus",
"CBFF239A1792F25920D863F223368B54:J3N3cUH3M0R3uyzkE0qVK/SouxC/X6VEswcoWb6ViL8=:BID_276_Pug",
"E46E6578D28965DB74B642E1CB239A5D:Dg3Oqkcno7QuLDGdi4N4VWSMSAd8bILyJT8Gh0PYjj8=:Pickaxe_ID_597_BroccoliMale_GMZ6W",
"16FC688AE41A3E3C518F4DD9F9612EE7:Jd7nRLx/FoonA2dUjtbvJVk3nJoNq9LTedk3u4EdFS8=:Wrap_024_StealthBlack",
"A2A3968C8EF4EA9F7979BC1FC57B871D:xVURN9OBgLtbyK0ZR4bqMgsZpL/SJjlIXf1WGEpfd6I=:Glider_ID_139_EarthDay",
"545B9777127F4BE242F802C627356B7E:RNI/KvLEXcGoGnk3/AKaYbyJmXMtQl9Zmvl8ErePB4g=:EID_Relish_TNPZI",
"604C6242EB2BF301BB5D4BC6E3AC5A8C:Y7c2+dviThEDuVsG9kIOjMfnLdJUnPMbdaY5gKiVki0=:BID_772_Lasso_Polo_BL4WE",
"22AB4BDC10065AA49B38DE88522DF836:1L8L+oKtSOtIxbm1x0HbDtzquIH6CH8vu1PF4i8jU+w=:CID_444_Athena_Commando_F_BannerC",
"C1C31115267D6802AD699472D2621F25:zAyelFy6RcyGIW/9z9IvgEbmRW9pdAytvgBIPb1/kdk=",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_951_Athena_Commando_M_Football20Referee_E_QBIBA",
"C76299772B1BE272260BF3396F83FC1E:uiBDMtwYhdxktbqTrhYkzEZErlBp5gBtkLM+QFDouT4=:Trails_ID_102_HightowerVertigo_G63FW",
"F044853E82632E827ED91FB4AFBD28DF:LH1pXQ13KEoYfxxylALn8jaS0t/7IrVRVmO8UXieaVU=:Pickaxe_ID_694_SunrisePalace1H_SDI6M",
"63722D44ECCA0F4178B85F5A6BC4C31B:j42UL0bmfBkli6Aj92wWABwFby5rAplP/Ac6nh9kRvA=:Glider_ID_308_VividMale_H8JAS",
"0DE6839DE97A78F987D7A34D644BB3AD:ZKZ1+Eb+7CpzfLHMqihYVN9+gVQobqBYQW5mh8I1KpA=",
"AAB934D179F489B8084EB057031AB845:oJF2EGCXkWP7B1BVK8i4yJzvNtkwXozjZJZv7ZznEEA=",
"35DDA69DABF1DE5826348A3CCD0DFE5E:CfhL+/n+phBF7TV4Qpw4Qhqrd6g3S/Gq2sU5n0FiH6A=:Trails_ID_059_Sony2",
"854D0D9F4EF33FB4410CB98340952245:wYzInzYpL5IB6dN+rCo6196KgGGo3E/rNeOf7Paizz4=:CID_304_Athena_Commando_M_Gnome",
"E50209164841E1829F672AB1B33D069F:1EMTmCTA4cO1QMoLu+RWAGd8Rw4FQdAONKvDwfQeNV8=:CID_333_Athena_Commando_M_Squishy",
"552DB214510DE1E24F08920F80B0AEC5:GP2CYv9xYYDf6bOnpgm0fnOXa3iI0acXH02ZIaHAElg=:BID_819_Stereo_TE8RC",
"216D955070ADAF10973BD156897472C3:MjQh55OvnJCoVMQzMU4C/1NF3FWiXDXnJ6G/EcHfUzo=:Pickaxe_ID_202_AshtonBoardwalk",
"B1B800E199A6D4649287C11AE89F67CA:3udFXffIw3c7eM5hljF5mJQA36FbW2PeF8Gx1TcD1vc=:BID_257_Swashbuckler",
"41BDA9510489C841C335EBFA5E233CF0:NceSf4zJLAR1Clh17nKGtBrw62kDRE7tJrodbJYMbU0=:Pickaxe_ID_193_HotDog",
"DC912741D5C6F75E4B0FEE33D7E3ECB5:0J6tWhEx0Nxw49VokIyykSs5sL5aFPgk2QJn9b5bAi8=:EID_LetsBegin",
"06B9F77E165673FD1C5FF5099F43D1F3:Bvw6h4GKOLjC/wFgHQsiLePbBZhtPiNhtr5keDBse70=:Wrap_176_TeriyakiWarrior",
"AC44D9C67B1FB24E70D94C827FC465AE:VrHcqJ9hMMqZicx3kS+qFfNXexXR/QA1/1bM+DwgqMw=",
"CD6B95C728B11810F8EE4C396D02EFCA:Fulo/BAgbJwmOju1xu/05XnxLDbenI4bDEb2rUyf5hw=:EID_Psychic_7SO2Z",
"8A6DABC9AF8B5FE521D365DB605D0AE0:T721SqBTncYsd8Gej01RnLX6sEaCgJoILnRauHaJz+g=:CID_429_Athena_Commando_F_NeonLines",
"1DF43E667862B117F72B5F39E750853A:Bhjx3mmVxhvadK5bkT+W9RJ0XAaMHawCnf8MfXIpABw=:Glider_ID_150_TechOpsBlue",
"6D85E82539341B90944E84FFAAD872FB:mAiBk7KbE2Dnr+yVFyJK1yAwv2eWb+yANFH0z2krQkw=:Glider_ID_156_SummerBomber",
"AFCCB7C08EC6957EEDDAAD676C3D3513:MuovEXob241ie6/RP76ImUk+MExLdl+bszvxCHNtg0U=:EID_TwistDaytona",
"7E9E6546A8C7109E9966F9C010D794A7:/hJU9SIxIewJ7taimArAwTbbuGG/4THrKvMElcTMzI0=:EID_BurgerFlipping",
"AE9F7B3419C7FBD2414D72E2E1C8A7BA:kpIotniLp60tWfbBitDUrjw6gmJ2Swl+YT3QAkecpRA=:EID_AntiVisitorProtest",
"5D6562F1EAD89513C82C2F37A24E7F82:I2c+SQCdDvJpC6z1xniRT+k41KAp0pla+o/H68oXFLQ=:BID_441_HolidayPJ",
"F6E92DDBC70C8184E837D31905B2F2A7:UCSPatT+yv3YH2x0Ks+2GSXhSSu+3ZvZs6Lai3oOi0Y=:Wrap_387_RuckusMini_6I5DM",
"0EC19805A48534C8892FA21C75024971:WcebSI5r6bMgSAbNd8Ob187rYmIJFJciobdyQciRiSc=:BID_345_ToxicKitty",
"828B24CF7786DF74D8511CA89DEED8CF:nCahv7mQhidmYXSmKif6z7d6bQ60mdPQ7SrdZ7a3GaE=:CID_913_Athena_Commando_F_York_D",
"1AFD764881D1E33FDAA65707010712AD:cbKyY3ux6wrdiWz2dXJq18KJaAYmUgBZ2aZsfz1UE3M=",
"7B1151E3094646DFFD37B6492B117FDB:4WxNHdTgHDEpGjzIV2XIjGO41kyiwggFQpdq8y+o1jY=:Wrap_356_GoldenSkeletonF_FT0B3",
"5E2A3EE7CE3884E31F58D83485D8B122:U++ePc5N62iMtEbjrJGSwNCaWeR6UoNMtWS85zJHwns=",
"21D9E3FA446D32EE85025841557C1E4C:KBL9ZqzocmLvcq5k3mwTCeoeeVfJdw9wjuQacUrg50w=:CID_A_241_Athena_Commando_F_Grasshopper_C_QGV1I",
"00EEB0CEB7585E8C69F90EF8534CA428:gSddavzl1D9mSi3KgCoXjX3eb5Dg9Rqh2C1pt6rD5rk=:EID_MyEffort_BT5Z0",
"98BCB8B7136162178BF364D6105BB9B7:c1dhB+vWHWRw3YvWpsHRj9Ayj8JjdqYOLnyr0YImxVo=:CID_A_005_Athena_Commando_F_GlobalFB_E_GTH5I",
"0882DAEC4F7823551C4955BA25B8AAC4:kGljCDpbMnCIfeo0YBLpBKDhX6nLlCaZRe62mSYSPTs=:SPID_333_RustyBoltCreature_ZGF9S",
"77B485EBF8E72CC8CD19F8646A6D0491:SXUHJQDuxBGv0PzDtuVsDxNyubG/pgH9s9FMvimS0YQ=:EID_Noodles_X6R9E",
"EB16EA013B751792698E05435797C1ED:y9JgD812Io4mbaJ5i533Ts5SSfyXaGM4JyoimjP+i4M=:BID_246_BaseballKitbashMale",
"97D5F3D0A78B050F427B5B300FC03EB5:Be+eZS6KqUc5Lc2iF4YAcLEe+S78nuLCK45HF/dDGDU=",
"5C0BC5E8819B8968CF25C60885F0CB5E:E52Ld2gtMzMFUMkdMpjNWmEHEgr1qnH+iliH2ha27dQ=:EID_AlienSupport",
"000A05AF03AE10ABB2059F29ACBF7D4B:3KrmPu2Ha/X0oy/MWd0a4O8JhJWli5MdtfG4XzeB248=",
"5950552B5A52A97A433715A1FF107BC4:p9RBdPmk5295pRSg0+Ybfwy/kqY6HBYiJEAkvy650O4=:Pickaxe_ID_127_Rhino",
"88FA70760D757D80F661FA53B4762EC2:7OtV76cpyOq9dNeM5PVD8TOdRcPx1K3weEPXzlCugu0=:Glider_ID_319_BistroAstronautFemale_A4839",
"A3254C97AE656A9B7301225E06E6B58F:tnv0g+8KyEy6IGYAl1ssmNI0uYT2fEP2twZkRnbIhbY=",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_940_Athena_Commando_M_Football20_D_ZID7Q",
"F6838AF4144E8386A184FBB0823C15D0:IjzqnnHjZ+r6WC4He/JawOyR7LxeMbm5880cDGDr2eU=:BID_232_Leprechaun",
"2FE8DBD09F14AAF7D195AA73B9613792:KwIehLEKaCSJb5X/WcQ9IULKkz3G3M9f9Z5Jgi9hYUU=",
"2B245B0F4DDB6AE9929DEDA081BEA512:lVz6HM71lNhCrT167xXv2wjekx+NqrJcy15i2+w3FdE=:Pickaxe_ID_152_DragonMask",
"A7D34E80FA70CDD2F367DBEF93B98467:KVErbMXsQqx7dxrZp5Ara4OVlA17pc29E2SZlFNipPU=:Pickaxe_ID_218_StormSoldier",
"315315A3A02AD685390B8D5878BE527B:Te5Ku+QdVzpXNd0B8XN7T/e1YaV5PyR04Z9yhfMFatc=:CID_465_Athena_Commando_M_PuffyVest",
"D50ABA0F48BD66E4044616BDC40F4AD6:GNzmjA0ytPrD6J//HSbVF0qypflabpJ3guKTdX4ZStE=:BID_115_DieselpunkMale",
"0690C12E471B0A42CD02549ADA662D64:Ntgy1QBz7O7CswgzsqOYwoMahjG3hGmk6/Qh4/rs+dM=:CID_273_Athena_Commando_F_HornedMask",
"EE0C67580F774526D46A64757F5DE77E:qRq1DPp8GnsFZSUYR1PJKeKm5YXAg3Kyd5Y+pjtXZyU=",
"2301C91045828DBFCDD966BE1AFE22F7:zS44RFNKoS6+WDSfin7CebOMjLH763+OGG5wjTrCosc=:Glider_ID_097_Feathers",
"9944BE1C4E9D73E4FA195380EF0B7BBB:LQxoRi0ktKvKMLk6hauL2Gzs6zf5bcEk3mgfX0We/uc=:BID_214_LoveLlama",
"D24B0606E503B97BFEB8EF12C6F1340B:wCF6GzuxQSxUX9I6eFwGJL34gU7YEPTKrZOOL3sPL3o=",
"5E15C5486CE8E539552D4D3E7682F9E2:+L/tTz+woDFZJEvtxfq8m8tNI1R72sYK7rnYr7sHTis=:EID_TeamMonster",
"E582349045884D5CD6A5518608336738:EuwTH/5P/6QUfbA3n5kc0wUYy+sI56+mNDYhIqheL4E=:BID_142_SamuraiUltra",
"F6E92DDBC70C8184E837D31905B2F2A7:UCSPatT+yv3YH2x0Ks+2GSXhSSu+3ZvZs6Lai3oOi0Y=:Pickaxe_ID_659_RuckusMini_O051M",
"D517F2A448CCB9B47E5004894BC62ACF:qOdQUR91sysqDRELOgz/YVZ7Piae8hqcrnYW90fXtvU=:BID_863_Tomcat_5V2TZ",
"BA6DF4F82C5CAB3CE1C51156BFCACE71:SDOlhnlP1SENGT+SrYUqeGIz0TkgoM7dQjfmfxegb1o=:EID_BlackMondayFemale_6HO4L",
"0882DAEC4F7823551C4955BA25B8AAC4:kGljCDpbMnCIfeo0YBLpBKDhX6nLlCaZRe62mSYSPTs=:BID_918_RustyBoltFemale_J4JW1",
"E47EFA3166A5D7B35CEC27B19AC66AE5:JURSqAHhHK6YqLP5rKhCO+SQ2oql4NqJaoaeNGtsrM8=:Wrap_383_Buffet_KGN3R",
"8566FD040AC2B245597E11D1F85DB4E5:SEoqoweofxmXfxu848wKn1UJhwU7oQ2w2F0lBst+FnU=:BID_658_Historian_4RCG3",
"A34195EF9068F0DD323EA0B07305EA47:eYcw2YEjssIAsJMgaWYPQQCBFcRvvkj9WoRVV+P3cBo=:EID_DontSneeze",
"BA6DF4F82C5CAB3CE1C51156BFCACE71:SDOlhnlP1SENGT+SrYUqeGIz0TkgoM7dQjfmfxegb1o=:Pickaxe_ID_276_BlackMondayFemale1H_1V4HE",
"46FC5EBAD39CE53EFB215A2E05A915FC:H3gtdkEzT3Dk8vkwTTZE9oUDoJEy6vmfQj1jDo453gY=:Wrap_051_ShatterFly",
"8AE930B0D623C1C2B3926C52ECF6250B:uwtZv87e9DU/Z1ZvYB7Pv4TdRQ4/ZRT9nYJCwYSmlbI=:Pickaxe_ID_605_GrimMale_8GT61",
"D938886074C83017118B4484AECE11AB:wjHAHm00Vg6n2x5LU91ap0+SFX5ZXXBmax1LyX8Aips=:Glider_ID_287_Alchemy_W87KL",
"2301C91045828DBFCDD966BE1AFE22F7:zS44RFNKoS6+WDSfin7CebOMjLH763+OGG5wjTrCosc=:BID_154_Feathers",
"828B24CF7786DF74D8511CA89DEED8CF:nCahv7mQhidmYXSmKif6z7d6bQ60mdPQ7SrdZ7a3GaE=:BID_634_York_Female",
"1609BAEA4AD6B664847EB5AACEAAD2AF:m2Yg+p6NDPR/POAPoG7bUCPabLTxGc/h8nrOEIwDx7k=:BID_130_VampireMale02",
"B77D921A94CDDAA841609065AE4C7BC0:SLDMLjxWpK+h1P4WNnqlixpWwujuV8OUZw+NoufV7sA=",
"CD6B95C728B11810F8EE4C396D02EFCA:Fulo/BAgbJwmOju1xu/05XnxLDbenI4bDEb2rUyf5hw=",
"59AF6C46ABB214024067564F69D6EA37:NtUgzeFVvkbyZQGRVdteWV61HjED9MXquqlVKHo3c/M=:BID_605_Soy_Y0DW7",
"8A154454D5B98503B341742F927C2457:grJh5qYNlPy1eMO4+to3Moy+a6NCMnXyGSAFUKKWY5E=:EID_Downward_8GZUA",
"F395571A36D2BD888861E61EEBD45AF8:D/35GPTIOKbdfmpxRJmHTkjNXcWv+XdSmTxQt6z1hvI=:Glider_ID_277_Skirmish_9KK2W",
"BA6DF4F82C5CAB3CE1C51156BFCACE71:SDOlhnlP1SENGT+SrYUqeGIz0TkgoM7dQjfmfxegb1o=",
"A5A71DA2F913ED0FD001BBCEC58F97FF:gFC4LJXINTgSLc8Gd6tYuSmuLHP+4AthS6eF52C93M0=:EID_GasStation_104FQ",
"03FBE2522823B14E3BD161BBCDAE4A85:kvHfxKURiw97DzzEt5xAUxVMFfxGya3Xw3kI7ORGEgM=",
"2BFECCEDD463D908C63438FD751529BE:u3hXyyjFecUwcUQIugiOjqwSJhnhy/cluvLBwlUhSC4=:CID_401_Athena_Commando_M_Miner",
"22AB4BDC10065AA49B38DE88522DF836:1L8L+oKtSOtIxbm1x0HbDtzquIH6CH8vu1PF4i8jU+w=:Pickaxe_ID_222_Banner",
"A062151202F2D5FCAD103D17B9300CE2:JiiR0xFNh20CRLDWN/tfjaeoo2ybApd1hQB364/iuTc=",
"D14FDB2BB2FB7746797F25470913BFF1:CQDgIxcNnAoUboQnjafZAYvV7UqX+NefGTXFd3m+oFc=:LSID_373_Nucleus_TZ5C1",
"9481CF79929F97F77D8F7D2607B42A6C:E28flW2DKtXyXBh2I7qs7VFKBFSkpgjkEDWIruQfVL8=:BannerToken_001_Cattus",
"BB59BEF60B72A241855EEC0FD63154D9:ZAQI6o6tkjRB6mh7VwOsf0x9DGyEAbGZ8qlUxS1fVm4=",
"FD0C3696948675DC3C2CBF5098D57D0D:rBWyTh/AVyZxi2oiQxM/OeD/HYZOSdVidEQeKoowV6U=:LSID_296_Cavern_60EXF",
"134343D31031634B122471F73F611CBC:zqtMGKxH4+Ydcx+1mHOb5DIMYxctpm2nKqXp8c5hH/0=:Wrap_076_CyberRunner",
"8DCAE39C7D9690E19F52655F02C613B2:ZZHbiVsbXquLlrtNVHtryLS3Vd1Ego8/8tlDpeUCgfc=:Pickaxe_ID_251_MascotMilitiaBurger",
"F3A99CD0D4F58EECEEB0D112506AD846:ZZtCRPcKk6itVryDavp7uZFIXiZF5CW0O9b+8Zt2Oag=",
"E04FBD38CB934DB1363EF57C85E48F9F:E+/j7zhGIdHODfCdH2vh4rgGRYSssFpT/s6dlus9Csc=",
"57EC154062C75464BD8A087D89732317:5AEwoCp79njYci8QYF+sLMkGpjDnFCYLSCtz4LD9D78=:EID_Galileo2_2VYEJ",
"E4D8D083C49828F6BF310ECA74A84F98:NxjtZXHe49xC1zUVs+XKjHbeic3prkFOWmwkaQ1vOFw=:BID_852_TextileSparkleFemale_X8KOH",
"F044853E82632E827ED91FB4AFBD28DF:LH1pXQ13KEoYfxxylALn8jaS0t/7IrVRVmO8UXieaVU=:LSID_358_Sunrise_1Q2KG",
"0E32ED911D1D1D67115812FB22317555:4qQbE3qtFL+oTEzvxYIwl2H6AsG7z1/3zNO9JEdHOd8=",
"687E53607C7004988B05C9EE1BA99AFD:jYmAGdz5vAvDRIhrcVdrcCNIPEmkJg8L1vWs/HZ5Kr0=:EID_SmallFry_KFFA1",
"498A4AB4BC3BFA9B055CDBE833C51670:67ndB88hm7gomLYiklekB5rGWrcr8RJ6K+no9DTP87M=:Pickaxe_ID_372_StreetFashionEmeraldFemale1H",
"CDCC968B6DEB5D05990F5D530A4B19D0:gAiLmJxr4FbEf/L10sgHjOLE8DEy7kYdtk7DJcgjPRM=",
"FF5A507BCC4519B928075C3DF4603E8E:EVv5b8WFOYZlDUGRqb8YUS1WbIbbT8TjgoBWEQr65zs=:EID_IndigoApple",
"AB10C0F1C99E5A6E4E477300FBD5D170:tLrb56vTjn3uiZIRhHU+RYygmirLzGglmEdI4DqfK4M=",
"21D9E3FA446D32EE85025841557C1E4C:KBL9ZqzocmLvcq5k3mwTCeoeeVfJdw9wjuQacUrg50w=",
"2E1C06DB5781755F3F06D95B6612BB3E:aTN33nTPI+qQ+osYxcMa4FjlyajAzhIxRzEcoAr8iAI=:Pickaxe_ID_546_MainframeMale_XW9S6",
"B0030ECDA329A8B589D249F794EA90B3:BfF0FYJQJ71DMUBmClT0DppsOy+1Syn8fGu6qNtTgXE=",
"F51F080981F8DC32B09FC3C62A977363:NqX2i8P3ayVe/mUk8aAqzUg5tvMEDWt1URv6xc4fUkY=",
"28CBBF705C9DB5A88BEC70DAA005E02E:FvtzBBvDkyj8PRLW76169bMFvg65VojYrSmkjUAi4Bc=:BID_352_CupidFemale",
"B16BF216C9085E63B70056FF0459F87A:xKQqQkkw6VWwT0pk7eKzepG9HM9kzi2ZPwSbdLWtpwI=",
"AC424209DFAB55305097B2050E16E2E9:efXu+MoloNbSOOHz8X4ipvD2MhSMWpRCaEOVNcdLPrY=",
"44DB36B2D2B3854669780458D2FE48C4:gtl0smAMRKg8d9TdDH47lUOYCygKzbAPA6/HaXLWy94=:LSID_323_Majesty_0P2RG",
"3CE25AC56856D0E10426276F61265547:NEtVDXR0qoOfW9lgdS4AuA8dkfd/1I9degcRI9UnvUo=",
"54FD9ABD65879452DCB8CE11C1D7F1AF:nV0Vm4NCBl+MkGX8wiqfFrg0viDriL3I2xc4KS7n7fg=:Wrap_070_MaskedWarrior",
"7A8E25F664219ED6CCF3AB1658D0E557:TV+yyWpI3iHJoaK3o1t6+/uhN/sFZ1OixoAx0n7MtjM=:BID_330_AstronautEvilUpgrade",
"F60CFFFA32CF6A877B50DA7F0A88326E:OWIopbB4fxaobofPI9lF9hn6BPG9NVLp4Od61uQppfo=:Wrap_047_Bunny",
"71BEC74046C6920A467E57B69FA3835A:q6m1xB4+mCmXL3g7eRGykDO6ZKrXS8M7m8SqbqIKzkI=:BID_202_WavyManFemale",
"3AC281E7A5EAA2765CFE02AC98B04FC8:R/hWNn8BcRRovJE/L7h15VDrJ0H4VqBBVt6XVvq2Ebw=",
"D2FAE1D098B2B4695EB59FAAD504798D:ZUDIqDvGVcpCVuA3h67vdkVbZwLuC0Z1zX33JLyi5xE=",
"204D49F063979C3AF87EF896D074D1CF:SaYFk+GEE7mL4dsgs0v0VGR5ER4TwH8uTNX5XqSglu8=:Glider_ID_251_TapDanceFemale",
"BE6386E7E95BB83F727A5282D4E1FF37:FsEC/J/Y3POX7wa0/+SonLUCp+u+MH7dktA25PEYLns=",
"419567181C57991B12DA9A9AEADAE6DB:nWZ+G2GG0PvarQUg/U/kRpWaJkA2YmmCgixEy4No+7Q=:CID_706_Athena_Commando_M_HenchmanBad_34LVU",
"37B3D2284CB3924E6592C2D1D11451E4:CMJclyQ1I9iY+VkDiajhGxxYQmZGHrTAlEl/wtlT+pk=",
"D938886074C83017118B4484AECE11AB:wjHAHm00Vg6n2x5LU91ap0+SFX5ZXXBmax1LyX8Aips=:Wrap_348_Alchemy_FYA4I",
"D14FDB2BB2FB7746797F25470913BFF1:CQDgIxcNnAoUboQnjafZAYvV7UqX+NefGTXFd3m+oFc=:Pickaxe_ID_708_NucleusMale_72W2J",
"216D955070ADAF10973BD156897472C3:MjQh55OvnJCoVMQzMU4C/1NF3FWiXDXnJ6G/EcHfUzo=:BID_258_AshtonBoardwalk",
"768A95DE7B657B7B23D5A0DE283EB49F:JLLAz46a7wo2rADQvCkbp4IbKexr7J5bBr6d6toSn50=:Wrap_050_PajamaPartyRed",
"8CB3CD29BF1611B7CA90D1C635859415:s7gVGQuQz2CDwqNda6dXQRqH9mpV6NUFu1zaoDihQYU=:EID_ChickenLeg_TDJ0O",
"419567181C57991B12DA9A9AEADAE6DB:nWZ+G2GG0PvarQUg/U/kRpWaJkA2YmmCgixEy4No+7Q=:CID_707_Athena_Commando_M_HenchmanGood_9OBH6",
"F044853E82632E827ED91FB4AFBD28DF:LH1pXQ13KEoYfxxylALn8jaS0t/7IrVRVmO8UXieaVU=:EID_Sunrise_RPZ6M",
"8022BB6AFCA2733E261C32590EA86E9B:HzKZXV9sQfjsDuGuGRfpabHawomJhu82FeOaEQDg1lM=",
"AC6F67B037F362174DD4DCEF7522D107:s4kP8pRC49WsLsc5Nlh7se3l3x57R3KrldkoTK2L8PU=:BID_301_HeistSummer",
"D49757E2D55451A0D5B341906FE2ABE4:PWMwnjgi/wUDV+yxg02QsU33jA529fxVTRHyqnkv21c=:BID_259_Ashton_SaltLake",
"591DF838AC4B3A6350E40E026B26D5C0:MBvGoHxJQBTxCm2V82s2yHqRWPsYdFyj8xKUhFsUkyE=:CID_746_Athena_Commando_F_FuzzyBear",
"72CC2893A6B672F3854F36629B770774:0BgQgKZRRuPFEoqn7CxZVhLBOfpCE3qLKGQlZc+SA80=:SPID_325_UproarGraffiti_QFE4O",
"4E7938F1FAC98BDF378823116712AC7A:jbZVgprILTQomUdGeJF0PsAFAJxsSCs5cKcXweZMAg0=",
"452BEE39B4C18C93D6B185B565ACA1CA:Be2Oll2p0qIXmiJMi4Y/wyePY+WefMmJyCzjgjrzkhc=:BID_233_DevilRock",
"72CC2893A6B672F3854F36629B770774:0BgQgKZRRuPFEoqn7CxZVhLBOfpCE3qLKGQlZc+SA80=:Pickaxe_ID_699_UproarBraidsFemale_LY5GM",
"2DCD2E2A9A816AA9035999F8E6F85F6E:6xM4ZYt0UAylyuIgFrmOgq4fYVH2ChEzQNcl8KGQF0o=:BID_532_HardcoreSportzMale",
"310CAA852300A8ED2B74754EF027C823:CbrsdQ2vpkgVe0Oc5HlGFLVkV9arQn928vHSnPpSxbk=:EID_MakeItPlantain",
"AE04BC41397F3D492390E60E59B39CAC:xC3e/4BfPQ5/xQqEKnB+EgmzrOcLiOCqiQCuZB6V9Ac=",
"A02E08C8CE48D4D8676358FF7BE55533:d9wA4snpl4I4B4zZFxWyu9cL9zSkXqy9+vTw9PUhHlw=",
"498A4AB4BC3BFA9B055CDBE833C51670:67ndB88hm7gomLYiklekB5rGWrcr8RJ6K+no9DTP87M=:BID_494_StreetFashionEmerald",
"F707FA321C9644351C5F87893C16580F:bOW0W1Al3NZZGbPupvIlLl7wWgBA2jPtH6SZO/fjdy0=",
"828B24CF7786DF74D8511CA89DEED8CF:nCahv7mQhidmYXSmKif6z7d6bQ60mdPQ7SrdZ7a3GaE=:CID_905_Athena_Commando_M_York",
"E4D8D083C49828F6BF310ECA74A84F98:NxjtZXHe49xC1zUVs+XKjHbeic3prkFOWmwkaQ1vOFw=:Wrap_396_TextileGold_GC2TL",
"5D6562F1EAD89513C82C2F37A24E7F82:I2c+SQCdDvJpC6z1xniRT+k41KAp0pla+o/H68oXFLQ=:CID_652_Athena_Commando_F_HolidayPJ_D",
"828B24CF7786DF74D8511CA89DEED8CF:nCahv7mQhidmYXSmKif6z7d6bQ60mdPQ7SrdZ7a3GaE=:CID_914_Athena_Commando_F_York_E",
"97E91E4F436B598D654592793B595536:Pj0lxheibz4Db/C4ehhHGlOalLQAxFCS+2NYkHRbjyQ=",
"F9AF8CDE150D2D1E65B64710D70C23A7:3SpHToTu2E//Qe8Dhu4I3kG5fLqEemMiL+2NxRVKdOc=:EID_DuckTeacher_9IPLU",
"552DB214510DE1E24F08920F80B0AEC5:GP2CYv9xYYDf6bOnpgm0fnOXa3iI0acXH02ZIaHAElg=:Pickaxe_ID_648_StereoFemale_0DTZ9",
"E0FB7B394449CE6450EA90C93D710EB8:NrXwNX6lKuu/kyQuvE74+6Uo04FODoV4ZqxToj/jS6I=:BID_300_DriftSummer",
"828B24CF7786DF74D8511CA89DEED8CF:nCahv7mQhidmYXSmKif6z7d6bQ60mdPQ7SrdZ7a3GaE=:CID_912_Athena_Commando_F_York_C",
"74245D2573276B4C9ECCF61B23367A72:I5LtJ72UAlZ9XIupxkzRJKiRnSEkEvEc5D8+Ss4u2Ik=",
"2301C91045828DBFCDD966BE1AFE22F7:zS44RFNKoS6+WDSfin7CebOMjLH763+OGG5wjTrCosc=:CID_274_Athena_Commando_M_Feathers",
"3ECF85734CD277EE10524DA249C5D0D8:4NtGfZpXGCuoEqpaN7C2kInVtLVwQ9Zp3zj4vtwxtv8=:BID_211_SkullBrite",
"E47EFA3166A5D7B35CEC27B19AC66AE5:JURSqAHhHK6YqLP5rKhCO+SQ2oql4NqJaoaeNGtsrM8=:CID_A_173_Athena_Commando_F_PartyTrooperBuffet_55Z8G",
"925BD833E71FF05FB73136BF57189C5C:WsXZpM/1+PT+xzorL685J5XB1dpvv8IOpOeeA2Rl1zE=",
"D24667CC40ED6564CE26A31E63E327BA:OnghWyLG/IQEx45PtmEcmqAHuViWUsTSDQ31EgRhyZM=",
"2E5F91AEF58F310AE2044EA39C43BB81:pNy1GtfVzymqacOqXRY14EZEvI5ZSVD5AFxlhxXC5qk=:Pickaxe_ID_683_CritterManiacMale_S4I63",
"54FD9ABD65879452DCB8CE11C1D7F1AF:nV0Vm4NCBl+MkGX8wiqfFrg0viDriL3I2xc4KS7n7fg=:Trails_ID_027_Sands",
"98BCB8B7136162178BF364D6105BB9B7:c1dhB+vWHWRw3YvWpsHRj9Ayj8JjdqYOLnyr0YImxVo=:CID_A_002_Athena_Commando_F_GlobalFB_B_0CH64",
"46FC5EBAD39CE53EFB215A2E05A915FC:H3gtdkEzT3Dk8vkwTTZE9oUDoJEy6vmfQj1jDo453gY=:BID_256_ShatterFly",
"258D945630DF6E1016889F47B16EED80:zQ/4osJ36W0V1DFXswf8JSStDMBTZPQ8oFcMrDqS7BM=",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_947_Athena_Commando_M_Football20Referee_IN7EY",
"D83FAFF508200C47DF03BDFF2F801FEC:s9P7AOkoCuPm/506hyAKzuRaIh0xzV9YZON4oDs7GoY=:EID_Jupiter_7JZ9R",
"0CD312F730BA9C3FD6CD67420EDDACF7:nXBDxcWYx2VtjMeRCDfSak9+f9aSOgrcxp8GKeUiId4=",
"BE20AAF89FE897368E52AAA193DEEB53:jHRZho9v4IKzFzk51RD0nAVFCZ27vIwcstPkdQeSupc=",
"91C415954BF27B6E43970FB8A75FE8BB:YhHyxIA+Ru33r3pThiWqKNYdvDbL05yXSxKarRuMSxw=:Glider_ID_103_Nautilus",
"C015FB76A9E7912825A5F9CA69671961:4zfC1uF8ll4CkTBctitVmwjHsazAiz2LXPHIPj4ef98=",
"819F658DBDBB5D333430800891F28361:u/+kuv6DsiUouUOusRRfC8Ti5rCKhsgIyxyOnLH3Mh0=:CID_719_Athena_Commando_F_Blonde",
"3DB93E023E700ACD0C78072ED4787D37:aePdzcjsQvnpefA3P/cKfnZrVspZ5QVSsAc+Rui20pM=",
"E50209164841E1829F672AB1B33D069F:1EMTmCTA4cO1QMoLu+RWAGd8Rw4FQdAONKvDwfQeNV8=:Glider_ID_118_Squishy",
"360CD59F6F7B68A441DDED9DB5FD13D7:G6pVAf/ul1HPYh6s2M1l8G4hn62jdwkcbegeLoxL7Y0=:LSID_364_Ashes_0XBPK",
"2DCD2E2A9A816AA9035999F8E6F85F6E:6xM4ZYt0UAylyuIgFrmOgq4fYVH2ChEzQNcl8KGQF0o=:BID_531_HardcoreSportzFemale",
"06E3CB03E94C4D850CE185166706E868:jDuRIbxnZBnAH/hUrfRX3qnGyIogSWUHrK6nq7Et3pk=",
"2E1C06DB5781755F3F06D95B6612BB3E:aTN33nTPI+qQ+osYxcMa4FjlyajAzhIxRzEcoAr8iAI=:Glider_ID_273_MainframeMale_P06W7",
"89D641BBEFFD9A227200861A01807ECF:rXDTm9JS6HhLBHIDXPRRF/eERp1DkUhV46QPxevqMWA=:EID_Comrade_6O5AK",
"3AC8A6B5089F55E17E00AAD8AC3C6406:TlUSkJe3y85fW83rHMy+XuqcZxQduXcB8yftpPoiDvo=",
"44DB36B2D2B3854669780458D2FE48C4:gtl0smAMRKg8d9TdDH47lUOYCygKzbAPA6/HaXLWy94=:Season17_Magesty_Glider_Schedule",
"71C3BFE2AF0BC8DE7BC3735614CE6263:hNLsvUTUw0cw1WrfOEjm7oSGPfpEZer6R0G7F2El6Q0=",
"01BCAD21B42507D45972A0E634D3BF68:LFzYKDNwUHYxLThhPKfnzmnADCwCZFjZybIL9TaGBkw=:EID_Deflated_6POAZ",
"96FD474CBA52137DC5ABF658BE17C792:ZLWvbUR7Xow1GUNjC9Mxg7DHVoJAnBr4b9gSzmyFcxU=",
"552DB214510DE1E24F08920F80B0AEC5:GP2CYv9xYYDf6bOnpgm0fnOXa3iI0acXH02ZIaHAElg=",
"7A59383C41DD998408A74BC37C7D6887:nSrruhpHV3ZEPPECeqWkMh/6mBFzQD8yEFKZS6oJeu8=:CID_A_082_Athena_Commando_M_Hardwood_C_YS5XC",
"EBFE6788D367D741AF0A4FD098CDFD39:FAeJTGyT49P+dQOmKx+lMYVAxu7qtIPlqSaLAR85zqI=:Pickaxe_ID_213_AssassinSuitSledgehammer",
"922A62BF1FB397B890EADCC9ED9E6F90:OvZzqErOUkh5FciEJD8JI+lu4X5NmK5TtzvCK6F5RM4=",
"99F8F15A893B9B4BAC2E12BFDCE251B9:1OMIfAluyzGr5kvv03niOQMXp/D+M1s/f/mHTv52Prk=",
"C17D1F224DBE7ACE1D1D998F9EC974B4:lKF1wmYGidWP6J4irSLvW13QbAIwHPOeO8b7LtP88t8=:CID_303_Athena_Commando_F_SnowFairy",
"22AB4BDC10065AA49B38DE88522DF836:1L8L+oKtSOtIxbm1x0HbDtzquIH6CH8vu1PF4i8jU+w=:CID_448_Athena_Commando_M_BannerC",
"C97FBD76436AD77913E727A0AD147FEB:NjQSZ0Lg9LaEhDjA3TeS1XUhN04KM2wQvR0j/YPmQu4=:BID_181_SnowNinjaMale",
"4755D9C0E2D1DE1C09B77DEA8B830471:9tUO5yVhvp+/sp7icZaEDw05nMAdS6bYAWYyfQNsxBc=:Pickaxe_ID_389_DonutPlate1H",
"27D6556F776B2BDA97B480C1141DDDCA:uvUqb5LuwRFWQnA4oCRW3LNdorYcGtOmJ8PvBeCwBKg=:CID_466_Athena_Commando_M_WeirdObjectsCreature",
"545B9777127F4BE242F802C627356B7E:RNI/KvLEXcGoGnk3/AKaYbyJmXMtQl9Zmvl8ErePB4g=:BID_874_RelishFemale_I7B41",
"452BEE39B4C18C93D6B185B565ACA1CA:Be2Oll2p0qIXmiJMi4Y/wyePY+WefMmJyCzjgjrzkhc=:Pickaxe_ID_176_DevilRock",
"204D49F063979C3AF87EF896D074D1CF:SaYFk+GEE7mL4dsgs0v0VGR5ER4TwH8uTNX5XqSglu8=:Pickaxe_ID_500_TapDanceFemale1H",
"793D221E5331282DD7F3681100944880:B5R64E9EZQD1lHmmyUV+9a1XUEOcYfdopJ3avEIcVxE=:EID_TwistFire_I2VTA",
"73FDB8F2BDCCF4518225CB3E28DD9C0A:MBo/DO8mLebMquZPCgeE/FgUdJOXASKVjIJ1H+IEPac=",
"00BD73648F7CD05EDE0B2D4C33B499BD:0D3XSX1KGIR/UWBELcxKxJp06xbU96TetFY2Rz9R614=",
"B9C9B09F29DF6BC9DA94C36184CECFFF:1/E0M5TV90UjL3PR+sqOzaRiMRpF8ByTmfVayVEL/Ig=",
"1CFA91F4317CA2724E2AD9A098B2888B:op+720ix4L4JmxKqwXbOt+T5Xwqhcva7c6lETmEVCbY=:EID_Shindig_8W1AW",
"4D896B93DC5B2D18AA2949EA7B67B4EA:0V70x6p0zRRV9bV6P+sq62lM0CdW4rvUgip6/65GWzc=",
"2648ACDF6B7E55495928F2319101BB8A:tKha+iiFKUamRIWCxq0gOtbN/G1B5J5eOIElAx9T3rc=",
"4C838738CDC4946786DD7BE341AB05DD:eyjCm9OcFQSvVRVBZizNVyF+8kb9OlNFrvDy8d1QDfo=:BID_253_HoppityHeist",
"8680408E4982495D8EC65D930CE902F3:ZIoca9gNSMll2u3zmmEsMFSAp2pTmsvWIPWwz2b0FsE=:BID_188_FortniteDJFemale",
"3D8D56FDB72DACCA7E656FBC0F125916:gMX76nmLV2caz28Ro/i3FatCU4tdi1jHgJSPbdnLTUc=",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_937_Athena_Commando_M_Football20_UIC2Q",
"2D24182706636A7BD3E96AD37605BAD6:jEZJE+EAU7VDo6p6Y84e4+p3AHxYBWin144H4MhzaSQ=:BID_553_Seaweed_NIS9V",
"91DE2263000EF60E067F04C5505104C0:J72L3sJQnakH4GQrYgBz7QIAmI4aC1sde+iB7zErKG4=",
"DD07D332EE51C9C9585F5249FD62A45A:8Fv7jA8ISZ3iOlNCeaeeGh9rmRV6QvL7sbsx5wYTvnc=:CID_A_223_Athena_Commando_M_Glitz_MJ5WQ",
"19CAB803EB00118FB3E6B3E5ABA7B234:tRM77TfQWWJ38hNsFLjt7jMNoSOozxqi9PF9/9H3rmU=:BID_373_HauntLensFlare",
"5A03216B7495CB52261D6E0D74DC62CB:tYFoxNFq/lu5imPTcSk5vAX7ZfPNBwi8INXf2hU+YyU=:CID_A_159_Athena_Commando_M_Cashier_7K3F0",
"B8C17AF9BC0DF3113AC6C498DF3325C2:iElxozD4UvK0+tPt0pPLg0gBoSkwLwByJiE4ucKHU7U=:Wrap_085_Beach",
"7A59383C41DD998408A74BC37C7D6887:nSrruhpHV3ZEPPECeqWkMh/6mBFzQD8yEFKZS6oJeu8=:CID_A_080_Athena_Commando_M_Hardwood_I15AL",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_956_Athena_Commando_F_Football20Referee_E_DQTP6",
"D83FAFF508200C47DF03BDFF2F801FEC:s9P7AOkoCuPm/506hyAKzuRaIh0xzV9YZON4oDs7GoY=:Glider_ID_258_JupiterMale_LB0TE",
"2DCD2E2A9A816AA9035999F8E6F85F6E:6xM4ZYt0UAylyuIgFrmOgq4fYVH2ChEzQNcl8KGQF0o=:Glider_ID_216_HardcoreSportz",
"1609BAEA4AD6B664847EB5AACEAAD2AF:m2Yg+p6NDPR/POAPoG7bUCPabLTxGc/h8nrOEIwDx7k=:CID_228_Athena_Commando_M_Vampire",
"134343D31031634B122471F73F611CBC:zqtMGKxH4+Ydcx+1mHOb5DIMYxctpm2nKqXp8c5hH/0=:BID_279_CyberRunner",
"2E5F91AEF58F310AE2044EA39C43BB81:pNy1GtfVzymqacOqXRY14EZEvI5ZSVD5AFxlhxXC5qk=",
"D517F2A448CCB9B47E5004894BC62ACF:qOdQUR91sysqDRELOgz/YVZ7Piae8hqcrnYW90fXtvU=:Glider_ID_318_Wombat_1MQMN",
"F8D604C6FA9156F47356B54E1E442A97:EcmOKEqNv/9U+rw3oLZb7e+z4gaKWlfRIpdQwODvOKw=",
"72CC2893A6B672F3854F36629B770774:0BgQgKZRRuPFEoqn7CxZVhLBOfpCE3qLKGQlZc+SA80=:BID_890_UproarBraids_EF68P",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_943_Athena_Commando_F_Football20_B_GR3WN",
"F32262244DE021E18BF22F9BF7594474:08HErdKvBV58StDIjB9wvtY67peu7ZK3BsMpBMKvSrM=:CID_280_Athena_Commando_M_Snowman",
"30B98E694C38C868A4EDB892F3FF1940:3biPX66md7tSkYYCBkYrshj9OJIo1B4CWV33LnL1kds=:BID_195_FunkOpsFemale",
"F3A99CD0D4F58EECEEB0D112506AD846:ZZtCRPcKk6itVryDavp7uZFIXiZF5CW0O9b+8Zt2Oag=:BID_821_QuarrelMale_IKIS8",
"71BEC74046C6920A467E57B69FA3835A:q6m1xB4+mCmXL3g7eRGykDO6ZKrXS8M7m8SqbqIKzkI=:EID_WackyWavy",
"E47EFA3166A5D7B35CEC27B19AC66AE5:JURSqAHhHK6YqLP5rKhCO+SQ2oql4NqJaoaeNGtsrM8=:BID_818_Buffet_XRF7H",
"09BC93B3441ECBAC30FA23BBEF59CF89:3CHInj+JfLspiVCNDY/GTZ4Pn52nWFeA4qYI0SJv2dM=:BID_183_NutcrackerFemale",
"27D6556F776B2BDA97B480C1141DDDCA:uvUqb5LuwRFWQnA4oCRW3LNdorYcGtOmJ8PvBeCwBKg=:Wrap_095_WeirdObjects",
"E3D0A604B93651DDC6779B14F21D0FDA:8gPR3gZwEJxfkZBkXk0QAlpnJ7q5mXzVc0DN3lzpJ5k=:BID_328_WildWest",
"C76299772B1BE272260BF3396F83FC1E:uiBDMtwYhdxktbqTrhYkzEZErlBp5gBtkLM+QFDouT4=:Emoji_S18_ClashV_I1DF9",
"5738A14C7E45E1B405CEF920829CB255:xZHlPTz/dxNahrp9IqTZ+tjOZSYMxQb9KZFXlg9N638=:BID_423_HolidayTime",
"A08F80FECB766B071C66017C5902DBD1:Q4sRGzjjbRTMZ3HwAmiC6a6+017KgXUsLapzs71OWEs=",
"713D64294CD1C40F60DEEB805E3A2D87:CJOOHtEX7q4CELcZ96oZjrmSZd7pyJ2fMaFX912GDl8=:Glider_ID_110_TeriyakiFish",
"9261CD0F921EAA3CD6AA8C0716FB042B:W+yzeWWxWnA530lwV8nLi2BE+TD5MCXS11th7UphmPQ=:Pickaxe_ID_543_TyphoonRobotMale_S4B4M",
"E48EFA857D8E6914B2505B05AADFB193:4AUdytefPzWNT8c11iGtU4xcGNWEgzpMJbxTjUq3NS0=:EID_Backspin_R3NAI",
"4F463077C4B0260225A47547ABFDDEE3:jvXG7IisBPOlXz80kl6hZdn+jb6TV0Bvq1WafaHji44=",
"E59B013651F078E718F08ECF9E1559EE:rTGy9at5kTfQtu8EwVrUihfzuN8vkFPl3XNyGvqbZX4=:BID_250_TheBomb",
"5A1170F589134C4D68AAA2B5AA6EDA69:bfro7s6Qtde/H7C4zc6MJdpua1mhem8HywLluxBLDrg=:BID_642_Embers",
"21D9E3FA446D32EE85025841557C1E4C:KBL9ZqzocmLvcq5k3mwTCeoeeVfJdw9wjuQacUrg50w=:BID_896_GrasshopperMale_BRT10",
"16FC688AE41A3E3C518F4DD9F9612EE7:Jd7nRLx/FoonA2dUjtbvJVk3nJoNq9LTedk3u4EdFS8=:BID_248_Pilots",
"21D9E3FA446D32EE85025841557C1E4C:KBL9ZqzocmLvcq5k3mwTCeoeeVfJdw9wjuQacUrg50w=:CID_A_243_Athena_Commando_F_Grasshopper_E_L6I24",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_946_Athena_Commando_F_Football20_E_EFKP3",
"98BCB8B7136162178BF364D6105BB9B7:c1dhB+vWHWRw3YvWpsHRj9Ayj8JjdqYOLnyr0YImxVo=:CID_998_Athena_Commando_M_GlobalFB_D_UTIB8",
"E4D8D083C49828F6BF310ECA74A84F98:NxjtZXHe49xC1zUVs+XKjHbeic3prkFOWmwkaQ1vOFw=:BID_853_TextilePupMale_LFOE4",
"0690C12E471B0A42CD02549ADA662D64:Ntgy1QBz7O7CswgzsqOYwoMahjG3hGmk6/Qh4/rs+dM=:BID_153_HornedMaskFemale",
"BE2C3EF59AB81D812AF5B8153325998F:W7NoICLZt9L2d7XZ5dT9gtI80MyOizk7uA9LtwA/Edw=:Glider_ID_323_GiggleMale_XADT7",
"D83FAFF508200C47DF03BDFF2F801FEC:s9P7AOkoCuPm/506hyAKzuRaIh0xzV9YZON4oDs7GoY=:Pickaxe_ID_510_JupiterMale_G035V",
"1234642F4676A00CE54CA7B32D78AF0C:Nd8vhYp296C+C0TqSIGxu0nBYOFGQ5xBNK5MFjHS8IA=:BID_200_SnowNinjaFemale",
"987329E3B70FEAD522EBF7435E5CA6DD:j4zyQQh25LYcjUO0HYDsBzmqLSXR5r98UKdC0xeTyHI=:EID_Boomer_N2RQT",
"30A11EE8EB62BEFD4E9B09611DB13857:YVeVPXcP7UoJTp71ZXpGNdPVzmjnRyymcUpsNWYXfRs=:BID_507_DonutPlate",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:EID_Football20Flag_C3QEE",
"22B8405FC3BE153C8148422C3F2D3A8A:d/ATMDztVZxwHLUCwOcJWP1/7oPKKGqbBWUBRNZ6dnM=:Wrap_391_Dragonfruit_YVN1M",
"CB3D84444FF0E551D18939AA7226B17F:U4GIAd4fGYWy9tySw3iVb92+6ZX3rQ3FsiBCXMT4TSo=:BID_194_Krampus",
"E47EFA3166A5D7B35CEC27B19AC66AE5:JURSqAHhHK6YqLP5rKhCO+SQ2oql4NqJaoaeNGtsrM8=",
"C23FA9BDE9342B508B8AABBEEA6699A2:3mRtSSu9PTBlC3NpGAQcFent660Ptni4HbGX+Zj1KIA=:BID_867_CritterFrenzy_3VYKQ",
"4009CB877085F3B3B0D76A686465A140:gMLJXUbFcIrqqUlAuoMI1b27KdWHBVJJeJWdYV1Iiro=:Pickaxe_ID_551_KeplerFemale_AOYI5",
"308F587F46CB50450DCA9B9CFD50E120:2nvyeGrxnqL5SJjMPag1d9YiiXfdGYVkL/WJqWYnC2A=:BID_157_MothMale",
"60CE6E28E6993C1DC1C58E839E7A7284:ZlOTwn6YbAK9HetjsiQo0AS1jwJQnLJY7NkR5i7o2/g=",
"1C8FA86241B2E4D084F7548529629CF6:pmXOfd+NEXcLhZX5YqDLjHu8/yzZoo4dWPcCM8ccXoI=:CID_333_Athena_Commando_M_Squishy",
"D2FAE1D098B2B4695EB59FAAD504798D:ZUDIqDvGVcpCVuA3h67vdkVbZwLuC0Z1zX33JLyi5xE=:BID_925_LateralFemale_7RK0Z",
"88FA70760D757D80F661FA53B4762EC2:7OtV76cpyOq9dNeM5PVD8TOdRcPx1K3weEPXzlCugu0=:BID_878_BistroSpooky_VPF4T",
"57EC154062C75464BD8A087D89732317:5AEwoCp79njYci8QYF+sLMkGpjDnFCYLSCtz4LD9D78=:BannerToken_018_GalileoD_5XXFQ",
"2F2804FC81CA638FC3DFEE5FB922987B:vz4MvtMQubNdmH1BO2E2FnNT3/vSvjbIn7HWNcWIYl8=:BID_272_AssassinSuitFemale",
"F044853E82632E827ED91FB4AFBD28DF:LH1pXQ13KEoYfxxylALn8jaS0t/7IrVRVmO8UXieaVU=:BID_875_SunriseCastle_91J3L",
"D1EBFA5EEFFAFC07E39EE2D9986CF8FB:jdM2xx6liOm1miOSVC7txNj6HvWF7/zCq4zxMYFYxug=",
"5D6562F1EAD89513C82C2F37A24E7F82:I2c+SQCdDvJpC6z1xniRT+k41KAp0pla+o/H68oXFLQ=:CID_651_Athena_Commando_F_HolidayPJ_C",
"BA4D882E7B09657A5E05773F702103CF:PjieN4lF3tRBNjQmWWUAyvZUaV0OrPGPYwrqNT8ZSus=:Wrap_045_Angel",
"EBFE6788D367D741AF0A4FD098CDFD39:FAeJTGyT49P+dQOmKx+lMYVAxu7qtIPlqSaLAR85zqI=:Wrap_066_AssassinSuit02",
"E0FB7B394449CE6450EA90C93D710EB8:NrXwNX6lKuu/kyQuvE74+6Uo04FODoV4ZqxToj/jS6I=:Wrap_088_DriftSummer",
"7FA4F2374FFE075000BC209360056A5A:nywIiZlIL8AIMkwCZfrYoAkpHM3zCwddhfszh++6ejI=:CID_223_Athena_Commando_M_Dieselpunk",
"5A1170F589134C4D68AAA2B5AA6EDA69:bfro7s6Qtde/H7C4zc6MJdpua1mhem8HywLluxBLDrg=:Pickaxe_ID_492_EmbersMale",
"C23FA9BDE9342B508B8AABBEEA6699A2:3mRtSSu9PTBlC3NpGAQcFent660Ptni4HbGX+Zj1KIA=:Pickaxe_ID_676_CritterFrenzyMale_B21OE",
"F3A99CD0D4F58EECEEB0D112506AD846:ZZtCRPcKk6itVryDavp7uZFIXiZF5CW0O9b+8Zt2Oag=:Pickaxe_ID_646_QuarrelMale_PTOBI",
"BAEF248980269F569C6E1FFF2B885DF6:2b6DQGIcab1r7zsw5j3MR84iDmt0g1XBquxJVR/8GxM=:BID_402_TourBus",
"BFE1F518C16A9F061B140D829ADDB0ED:bHkPYjXd71vacoJ4IisL//zEyVLFh+Di8MUqV9KkpFU=:BID_806_Foray_WG30D",
"BF953D81273D8772F12F57646A49430E:JP2vQQulX3OGMjglMYW7PT3KMCMbia3rtHnuEsuEVxA=",
"566C4D92AF66F45DF5E2D7EB43CC27AE:EuAYwU5tQBXzGoSj5BMc7S5yFfe9wZ2qrzx/hIHpnqw=:EID_LunchBox",
"9B730D57F59135CF774023F0DC1A99E7:l2Jy2Q3X1MPar8qMDGSHWWhdsVsYQ7hsqEYFMA6D8fI=",
"44DB36B2D2B3854669780458D2FE48C4:gtl0smAMRKg8d9TdDH47lUOYCygKzbAPA6/HaXLWy94=:Season17_Magesty_Pickaxe_Schedule",
"828B24CF7786DF74D8511CA89DEED8CF:nCahv7mQhidmYXSmKif6z7d6bQ60mdPQ7SrdZ7a3GaE=:CID_910_Athena_Commando_F_York",
"9261CD0F921EAA3CD6AA8C0716FB042B:W+yzeWWxWnA530lwV8nLi2BE+TD5MCXS11th7UphmPQ=:EID_Typhoon_VO9OF",
"EB16EA013B751792698E05435797C1ED:y9JgD812Io4mbaJ5i533Ts5SSfyXaGM4JyoimjP+i4M=:BID_245_BaseballKitbashFemale",
"22AB4BDC10065AA49B38DE88522DF836:1L8L+oKtSOtIxbm1x0HbDtzquIH6CH8vu1PF4i8jU+w=:CID_449_Athena_Commando_M_BannerD",
"AE9F7B3419C7FBD2414D72E2E1C8A7BA:kpIotniLp60tWfbBitDUrjw6gmJ2Swl+YT3QAkecpRA=:CID_547_Athena_Commando_F_Meteorwoman",
"929B82B3454DF80CC45B11A55400B6E7:jl/KsmshfBxKKnPDHyHNTHOzTE3buCIrBpSUpXJQdL4=:Glider_ID_107_IceMaiden",
"5A1170F589134C4D68AAA2B5AA6EDA69:bfro7s6Qtde/H7C4zc6MJdpua1mhem8HywLluxBLDrg=:Glider_ID_250_EmbersMale",
"98CAB76B2CB8406085C8CDF566FFF5DD:cucOYeadgsZAhkdKC7Klc4/BhUe0SnQtF2cwEScRBxw=",
"F044853E82632E827ED91FB4AFBD28DF:LH1pXQ13KEoYfxxylALn8jaS0t/7IrVRVmO8UXieaVU=",
"BB09F8C7991800CA61A7144E3A6219FA:o+Hvu5rCygQz66xIyk0SANceWaptKHLEls3vZaMW9oc=",
"88FA70760D757D80F661FA53B4762EC2:7OtV76cpyOq9dNeM5PVD8TOdRcPx1K3weEPXzlCugu0=:Pickaxe_ID_682_BistroAstronautFemale_A3MD2",
"312398E80AB6209B22CAA2EBAB2DB35B:QZ5uhBnQSeK4b+u9E6PTfw7j2scPMTPX4fFTOJWIwEM=:EID_Shorts",
"63722D44ECCA0F4178B85F5A6BC4C31B:j42UL0bmfBkli6Aj92wWABwFby5rAplP/Ac6nh9kRvA=",
"79F7D9C856E8CF354109D3298F076C06:Ak3TOM0i0Mq/KYxd7SDlSuS7o55USaf+urL6WqnmalY=",
"4E7938F1FAC98BDF378823116712AC7A:jbZVgprILTQomUdGeJF0PsAFAJxsSCs5cKcXweZMAg0=:BID_586_Tar_DIJGH",
"308F587F46CB50450DCA9B9CFD50E120:2nvyeGrxnqL5SJjMPag1d9YiiXfdGYVkL/WJqWYnC2A=:Glider_ID_099_Moth",
"6D85E82539341B90944E84FFAAD872FB:mAiBk7KbE2Dnr+yVFyJK1yAwv2eWb+yANFH0z2krQkw=:Wrap_087_BriteBomberSummer",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_939_Athena_Commando_M_Football20_C_9OP0F",
"E4D8D083C49828F6BF310ECA74A84F98:NxjtZXHe49xC1zUVs+XKjHbeic3prkFOWmwkaQ1vOFw=",
"D2FAE1D098B2B4695EB59FAAD504798D:ZUDIqDvGVcpCVuA3h67vdkVbZwLuC0Z1zX33JLyi5xE=:BID_924_LateralMale_Y2INS",
"010E6ACF85E4A58BF6F551EFE7B85F61:DwCIH5Dw/1wdiS6gFGmWe4HUgD9kMOEzjbzM/1QshM4=:BID_234_SpeedyMidnight",
"54FD9ABD65879452DCB8CE11C1D7F1AF:nV0Vm4NCBl+MkGX8wiqfFrg0viDriL3I2xc4KS7n7fg=:CID_422_Athena_Commando_F_MaskedWarrior",
"929B82B3454DF80CC45B11A55400B6E7:jl/KsmshfBxKKnPDHyHNTHOzTE3buCIrBpSUpXJQdL4=:CID_298_Athena_Commando_F_IceMaiden",
"F07BE27DCEFDF52818EE7BA2CD9CA504:lc47A/VahaBWJLQY4V1YyjzJPI5xVErInDaqdwPjv2g=:Pickaxe_ID_200_MoonlightAssassin",
"8DCAE39C7D9690E19F52655F02C613B2:ZZHbiVsbXquLlrtNVHtryLS3Vd1Ego8/8tlDpeUCgfc=:EID_ScoreCardBurger",
"FCD2F65146D53215F92F558CBA418191:3cp//Ss4zbgQ6tnnNLBcaTy9fsz3IM6ddZmiQSkX43c=:CID_336_Athena_Commando_M_DragonMask",
"06E3CB03E94C4D850CE185166706E868:jDuRIbxnZBnAH/hUrfRX3qnGyIogSWUHrK6nq7Et3pk=:BID_771_Lasso_ZN4VA",
"19CAB803EB00118FB3E6B3E5ABA7B234:tRM77TfQWWJ38hNsFLjt7jMNoSOozxqi9PF9/9H3rmU=:Wrap_154_Haunt",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=",
"C5C1E0742C0BFE4264242F3774C13B41:BO5aZnDZhvHsUFLsJD2vtYCQ6iYpX7Lhl565nDsBhaE=",
"B3BE1C036099F140800BB7D5FF1D9C49:bLt9+35t2O26OTgiEMuUCvH1kn+lGjTjhaEEoiz4CtE=:Pickaxe_ID_535_ConvoyTarantulaMale_GQ82N",
"40E9F547033360DFC0DD09743229B87C:x0/WK54ohwsadmVGHIisJNyHC8MqlU8bg2H+BsaEBtc=",
"56812D9CB607F72A9BDBADEE44ECCD21:pj9dMhJSaj6V2HsA0VWABE7Cs4+eEBz1Kex340gafK8=:Pickaxe_ID_199_ShinyHammer",
"42FEDE262B530BFDC25D9E6B8684D1B7:bXloLJVoSi2uTe72cpdsB8pAmUPKzmxwPC2GPhHFVhk=:EID_Layers_BBZ49",
"98BCB8B7136162178BF364D6105BB9B7:c1dhB+vWHWRw3YvWpsHRj9Ayj8JjdqYOLnyr0YImxVo=:CID_999_Athena_Commando_M_GlobalFB_E_OISU6",
"AEC9FD29ACF48B274A1A573C9ECF4B06:7OT+zOUDq1RjYJKp8gQhbUnYz/qJ19It2X4HduP5y/g=:Pickaxe_ID_249_Squishy1H",
"110D116208C62834812C2EDF2F305E49:MwuF5zX7GpQCGL2w+CwkPmGzH3q05YUoLo5udhVMNPg=:CID_718_Athena_Commando_F_LuckyHero",
"EF7C5225BD60644B313ABEE69182A302:ITNJPJyUEyMw8YrBk89HfKwHTFV6jGJJHt4D8UmpaxI=",
"8C623F6A49CFF9ADC7895A466CA1C896:kLmYdLi+jOBs2k+B/UxrCcPSdvuNYTha0xl9+SvUzJU=",
"56812D9CB607F72A9BDBADEE44ECCD21:pj9dMhJSaj6V2HsA0VWABE7Cs4+eEBz1Kex340gafK8=:BID_254_ShinyMale",
"828B24CF7786DF74D8511CA89DEED8CF:nCahv7mQhidmYXSmKif6z7d6bQ60mdPQ7SrdZ7a3GaE=:Glider_ID_248_York",
"D938886074C83017118B4484AECE11AB:wjHAHm00Vg6n2x5LU91ap0+SFX5ZXXBmax1LyX8Aips=:EID_Alchemy_BZWS8",
"3AC8A6B5089F55E17E00AAD8AC3C6406:TlUSkJe3y85fW83rHMy+XuqcZxQduXcB8yftpPoiDvo=:BID_527_Loofah",
"4755D9C0E2D1DE1C09B77DEA8B830471:9tUO5yVhvp+/sp7icZaEDw05nMAdS6bYAWYyfQNsxBc=:Glider_ID_209_DonutPlate",
"DC487286E8C1CD5FE18AC3FE76034EF2:3h9IwK2qQP8PHVuO1aZI1C34JrJxKBnXJOFcSDSj99M=:Wrap_102_WorldCup2019",
"C5C1E0742C0BFE4264242F3774C13B41:BO5aZnDZhvHsUFLsJD2vtYCQ6iYpX7Lhl565nDsBhaE=:EID_Martian_SK4J6",
"FE0FA56F4B280D2F0CB2AB899C645F3E:hYi0DrAf6wtw7Zi+PlUi7/vIlIB3psBzEb5piGLEW6s=:CID_220_Athena_Commando_F_Clown",
"8DCAE39C7D9690E19F52655F02C613B2:ZZHbiVsbXquLlrtNVHtryLS3Vd1Ego8/8tlDpeUCgfc=:BID_337_MascotMilitiaTomato",
"5738A14C7E45E1B405CEF920829CB255:xZHlPTz/dxNahrp9IqTZ+tjOZSYMxQb9KZFXlg9N638=:Wrap_180_HolidayTime",
"7B1151E3094646DFFD37B6492B117FDB:4WxNHdTgHDEpGjzIV2XIjGO41kyiwggFQpdq8y+o1jY=:BID_733_TheGoldenSkeletonFemale_SG4HF",
"B1EB196DD39D0736E7E08F99B07D8B9A:1fDhBY8uhi++l6QQPL2YtxZgUv04OZoMGBrH+yN8yKM=:EID_SandwichBop",
"2E5F91AEF58F310AE2044EA39C43BB81:pNy1GtfVzymqacOqXRY14EZEvI5ZSVD5AFxlhxXC5qk=:Wrap_409_CritterManiac_1B4II",
"F78569F2AD7950F870965BC647904647:e3+Nhzk8SBfmZWoQThFsZmnyJs2AoJ+LQDgMz45YAUE=:CID_952_Athena_Commando_F_Football20Referee_ZX4IC",
"360CD59F6F7B68A441DDED9DB5FD13D7:G6pVAf/ul1HPYh6s2M1l8G4hn62jdwkcbegeLoxL7Y0=:EID_Ashes_MYQ8O",
"2F1A5AFD22512A8B16494629CCA065B2:Un44BCuGtirrKab0E9TeOyDRnWC/Jh1h48+FOn4UrtA=",
"195439D6DD0FE44ADAE6BF7A44436519:kRCw7VFSPCYqhu7lJlA4kO4YmsqZUzxM6ARm7Ti8ntQ=",
"8675F0B46A008B0B6C0ABDD41A619443:9JYZhRB5Kld9h7zVQTbfSyNJvhz9UaJ17HIAPZH8TwQ=",
"22B8405FC3BE153C8148422C3F2D3A8A:d/ATMDztVZxwHLUCwOcJWP1/7oPKKGqbBWUBRNZ6dnM=",
"F3A99CD0D4F58EECEEB0D112506AD846:ZZtCRPcKk6itVryDavp7uZFIXiZF5CW0O9b+8Zt2Oag=:Pickaxe_ID_645_QuarrelFemale_W3B7A",
"5AEDD4DB5DA39071FCFC2404EEB3D02D:qaoe5DQrf1+HPEQRW5zls4KSe7DHbrxXO8OZMsFeo8Y=",
"828B24CF7786DF74D8511CA89DEED8CF:nCahv7mQhidmYXSmKif6z7d6bQ60mdPQ7SrdZ7a3GaE=:CID_907_Athena_Commando_M_York_C",
"8033BA4F3E1FB68ABADE271C9BE4EE42:XGwA8RWdavpeScQpqM/aFod3SGTB3PibdGE7iGKR4jg=",
"D776CA2A40FD9EC1F8522E9E13E99031:uRYulzQ2zdGG9UisQw2wM9OOM/9JsSWFwFt5d/3okng=:Glider_ID_121_BriteBomberDeluxe",
"D7727B4696A62373E9EBD9803F705B3C:XEbXIzCpOuA88jMBtt+XuMt+NaOIWlvfpW9h7i/dFlM=:Wrap_036_EvilSuit"
]
+318
View File
@@ -0,0 +1,318 @@
const express = require("express");
const app = express.Router();
const jwt = require("jsonwebtoken");
const bcrypt = require("bcrypt");
const error = require("../structs/error.js");
const functions = require("../structs/functions.js");
const tokenCreation = require("../tokenManager/tokenCreation.js");
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
const User = require("../model/user.js");
app.post("/account/api/oauth/token", async (req, res) => {
try {
var clientId = Buffer.from(req.headers["authorization"].split(" ")[1], "base64").toString().split(":")[0]
if (!clientId) throw new Error("client id is empty");
} catch (err) {
return error.createError(
"errors.com.epicgames.common.oauth.invalid_client",
"It appears that your Authorization header may be invalid or not present, please verify that you are sending the correct headers.",
[], 1011, "invalid_client", 400, res
);
}
switch (req.body.grant_type) {
case "client_credentials":
var ip = req.ip;
if (global.clientTokens.find(i => i.ip == ip)) global.clientTokens.splice(global.clientTokens.findIndex(i => i.ip == ip), 1);
const token = tokenCreation.createClient(clientId, req.body.grant_type, "4h")
global.clientTokens.push({ token: `eg1~${token}`, ip: ip });
res.json({
access_token: `eg1~${token}`,
expires_in: 14400,
expires_at: GetDateAddHours(4),
token_type: "bearer",
client_id: clientId,
internal_client: true,
client_service: "fortnite"
});
return;
break;
case "password":
if (!req.body.username || !req.body.password) return error.createError(
"errors.com.epicgames.common.oauth.invalid_request",
"Username/password is required.",
[], 1013, "invalid_request", 400, res
);
const { username: email, password: password } = req.body;
req.user = await User.findOne({ email: email }).lean();
if (!req.user) {
return error.createError(
"errors.com.epicgames.account.invalid_account_credentials",
"Your e-mail and/or password are incorrect. Please check them and try again.",
[], 18031, "invalid_grant", 400, res
);
} else {
if (!await bcrypt.compare(password, req.user.password)) {
return error.createError(
"errors.com.epicgames.account.invalid_account_credentials",
"Your e-mail and/or password are incorrect. Please check them and try again.",
[], 18031, "invalid_grant", 400, res
);
}
}
break;
case "refresh_token":
if (!req.body.refresh_token) return error.createError(
"errors.com.epicgames.common.oauth.invalid_request",
"Refresh token is required.",
[], 1013, "invalid_request", 400, res
);
const refresh_token = req.body.refresh_token;
try {
jwt.verify(refresh_token.replace("eg1~", ""), global.JWT_SECRET);
if (!global.refreshTokens.find(i => i.token == refresh_token)) throw new Error("Refresh token invalid.");
} catch (err) {
if (global.refreshTokens.find(i => i.token == refresh_token)) global.refreshTokens.splice(global.refreshTokens.findIndex(i => i.token == refresh_token), 1);
error.createError(
"errors.com.epicgames.account.auth_token.invalid_refresh_token",
`Sorry the refresh token '${refresh_token}' is invalid`,
[refresh_token], 18036, "invalid_grant", 400, res
);
return;
}
var object = global.refreshTokens.find(i => i.token == refresh_token);
req.user = await User.findOne({ accountId: object.accountId }).lean();
break;
case "exchange_code":
if (!req.body.exchange_code) return error.createError(
"errors.com.epicgames.common.oauth.invalid_request",
"Exchange code is required.",
[], 1013, "invalid_request", 400, res
);
const { exchange_code: exchange_code } = req.body;
if (!global.exchangeCodes.find(i => i.exchange_code == exchange_code)) return error.createError(
"errors.com.epicgames.account.oauth.exchange_code_not_found",
"Sorry the exchange code you supplied was not found. It is possible that it was no longer valid",
[], 18057, "invalid_grant", 400, res
);
var object = global.exchangeCodes.find(i => i.exchange_code == exchange_code);
req.user = await User.findOne({ accountId: object.accountId }).lean();
global.exchangeCodes.splice(global.exchangeCodes.findIndex(i => i.exchange_code == exchange_code), 1)
break;
default:
error.createError(
"errors.com.epicgames.common.oauth.unsupported_grant_type",
`Unsupported grant type: ${req.body.grant_type}`,
[], 1016, "unsupported_grant_type", 400, res
);
return;
}
if (global.refreshTokens.find(i => i.accountId == req.user.accountId)) global.refreshTokens.splice(global.refreshTokens.findIndex(i => i.accountId == req.user.accountId), 1);
const deviceId = functions.MakeID().replace(/-/ig, "");
const accessToken = tokenCreation.createAccess(req.user, clientId, req.body.grant_type, deviceId, "8h");
const refreshToken = tokenCreation.createRefresh(req.user, clientId, req.body.grant_type, deviceId, "24h");
global.accessTokens.push({ accountId: req.user.accountId, token: `eg1~${accessToken}` });
global.refreshTokens.push({ accountId: req.user.accountId, token: `eg1~${refreshToken}` });
res.json({
access_token: `eg1~${accessToken}`,
expires_in: 28800,
expires_at: GetDateAddHours(8),
token_type: "bearer",
refresh_token: `eg1~${refreshToken}`,
refresh_expires: 86400,
refresh_expires_at: GetDateAddHours(24),
account_id: req.user.accountId,
client_id: clientId,
internal_client: true,
client_service: "fortnite",
displayName: req.user.username,
app: "fortnite",
in_app_id: req.user.accountId,
device_id: deviceId
})
});
app.get("/account/api/oauth/verify", verifyToken, async (req, res) => {
var token = req.headers["authorization"].split("bearer ")[1];
const decodedToken = jwt.decode(token.replace("eg1~", ""));
res.json({
token: token,
session_id: decodedToken.jti,
token_type: "bearer",
client_id: decodedToken.clid,
internal_client: true,
client_service: "fortnite",
account_id: req.user.accountId,
expires_in: 28800,
expires_at: GetDateAddHours(8),
auth_method: decodedToken.am,
display_name: req.user.username,
app: "fortnite",
in_app_id: req.user.accountId,
device_id: decodedToken.dvid
})
})
app.get("/account/api/oauth/exchange", verifyToken, async (req, res) => {
var token = req.headers["authorization"].split("bearer ")[1];
const exchange_code = functions.MakeID().replace(/-/ig, "");
const decodedToken = jwt.decode(token.replace("eg1~", ""));
global.exchangeCodes.push({
accountId: req.user.accountId,
exchange_code: exchange_code,
creatingClientId: decodedToken.clid
});
setTimeout(() => {
if (global.exchangeCodes.find(i => i.exchange_code == exchange_code)) {
global.exchangeCodes.splice(global.exchangeCodes.findIndex(i => i.exchange_code == exchange_code), 1)
}
}, 300000) // remove exchange code in 5 minutes if unused
res.json({
expiresInSeconds: 300,
code: exchange_code,
creatingClientId: decodedToken.clid
})
});
app.delete("/account/api/oauth/sessions/kill", verifyToken, async (req, res) => {
var token = req.headers["authorization"].split("bearer ")[1];
switch (req.query.killType) {
case "ALL":
for (var i in global.accessTokens) {
if (global.accessTokens[i].accountId == req.user.accountId) {
global.accessTokens.splice(Number(i), 1);
var client = global.Clients.find(x => x.accountId == req.user.accountId);
if (client) client.client.close();
}
}
res.status(204).end();
break;
case "OTHERS":
for (var i in global.accessTokens) {
if (global.accessTokens[i].accountId == req.user.accountId) {
if (global.accessTokens[i].token != token) {
var client = global.Clients.find(x => x.token == global.accessTokens[i].token);
if (client) client.client.close();
global.accessTokens.splice(Number(i), 1);
}
}
}
res.status(204).end();
break;
case "ALL_ACCOUNT_CLIENT":
for (var i in global.accessTokens) {
if (global.accessTokens[i].accountId == req.user.accountId) {
global.accessTokens.splice(Number(i), 1);
var client = global.Clients.find(x => x.accountId == req.user.accountId);
if (client) client.client.close();
}
}
res.status(204).end();
break;
case "OTHERS_ACCOUNT_CLIENT":
for (var i in global.accessTokens) {
if (global.accessTokens[i].accountId == req.user.accountId) {
if (global.accessTokens[i].token != token) {
var client = global.Clients.find(x => x.token == global.accessTokens[i].token);
if (client) client.client.close();
global.accessTokens.splice(Number(i), 1);
}
}
}
res.status(204).end();
break;
case "OTHERS_ACCOUNT_CLIENT_SERVICE":
for (var i in global.accessTokens) {
if (global.accessTokens[i].accountId == req.user.accountId) {
if (global.accessTokens[i].token != token) {
var client = global.Clients.find(x => x.token == global.accessTokens[i].token);
if (client) client.client.close();
global.accessTokens.splice(Number(i), 1);
}
}
}
res.status(204).end();
break;
default:
error.createError(
"errors.com.epicgames.common.oauth.invalid_request",
"A valid killType is required.",
[], 1013, "invalid_request", 400, res
);
return;
}
});
app.delete("/account/api/oauth/sessions/kill/:token", verifyClient, async (req, res) => {
var token = req.headers["authorization"].split("bearer ")[1];
if (global.accessTokens.find(i => i.token == token)) {
var object = global.accessTokens.find(i => i.token == token);
var client = global.Clients.find(i => i.token == object.token);
if (client) client.client.close();
global.accessTokens.splice(global.accessTokens.findIndex(i => i.token == token), 1);
global.refreshTokens.splice(global.refreshTokens.findIndex(i => i.accountId == object.accountId), 1);
}
if (global.clientTokens.find(i => i.token == token)) global.clientTokens.splice(global.clientTokens.findIndex(i => i.token == token), 1);
res.status(204).end();
});
function GetDateAddHours(number) {
var date = new Date();
date.setHours(date.getHours() + number);
return date.toISOString();
}
module.exports = app;
+68
View File
@@ -0,0 +1,68 @@
const express = require("express");
const app = express.Router();
const fs = require("fs");
const crypto = require("crypto");
const path = require("path");
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
const functions = require("../structs/functions.js");
app.get("/fortnite/api/cloudstorage/system", verifyClient, async (req, res) => {
const memory = functions.GetVersionInfo(req);
if (memory.build >= 9.40 && memory.build <= 10.40) {
return res.status(404).end();
}
const dir = path.join(__dirname, "..", "CloudStorage")
var CloudFiles = [];
fs.readdirSync(dir).forEach(name => {
if (name.toLowerCase().endsWith(".ini")) {
const ParsedFile = fs.readFileSync(path.join(dir, name), 'utf-8');
const ParsedStats = fs.statSync(path.join(dir, name));
CloudFiles.push({
"uniqueFilename": name,
"filename": name,
"hash": crypto.createHash('sha1').update(ParsedFile).digest('hex'),
"hash256": crypto.createHash('sha256').update(ParsedFile).digest('hex'),
"length": ParsedFile.length,
"contentType": "application/octet-stream",
"uploaded": ParsedStats.mtime,
"storageType": "S3",
"storageIds": {},
"doNotCache": true
})
}
});
res.json(CloudFiles)
})
app.get("/fortnite/api/cloudstorage/system/:file", verifyClient, async (req, res) => {
const file = path.join(__dirname, "..", "CloudStorage", req.params.file);
if (fs.existsSync(file)) {
const ParsedFile = fs.readFileSync(file);
return res.status(200).send(ParsedFile).end();
} else {
res.status(200);
res.end();
}
})
app.get("/fortnite/api/cloudstorage/user/*/*", verifyToken, async (req, res) => {
res.status(200).end();
})
app.get("/fortnite/api/cloudstorage/user/*", verifyToken, async (req, res) => {
res.json([]);
})
app.put("/fortnite/api/cloudstorage/user/*/*", verifyToken, async (req, res) => {
res.status(204).end();
})
module.exports = app;
+11
View File
@@ -0,0 +1,11 @@
const express = require("express");
const app = express.Router();
const functions = require("../structs/functions.js");
app.get("/content/api/pages/*", async (req, res) => {
const contentpages = functions.getContentPages(req);
res.json(contentpages)
})
module.exports = app;
+221
View File
@@ -0,0 +1,221 @@
const express = require("express");
const app = express.Router();
const functions = require("../structs/functions.js");
const Friends = require("../model/friends.js");
const friendManager = require("../structs/friend.js");
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
app.get("/friends/api/v1/*/settings", verifyToken, async (req, res) => {
res.json({})
});
app.get("/friends/api/v1/*/blocklist", verifyToken, async (req, res) => {
res.json([])
});
app.get("/friends/api/public/friends/:accountId", verifyToken, async (req, res) => {
let response = [];
const friends = await Friends.findOne({ accountId: req.user.accountId }).lean();
friends.list.accepted.forEach(friend => {
response.push({
"accountId": friend.accountId,
"status": "ACCEPTED",
"direction": "OUTBOUND",
"created": friend.created,
"favorite": false
})
})
friends.list.incoming.forEach(friend => {
response.push({
"accountId": friend.accountId,
"status": "PENDING",
"direction": "INBOUND",
"created": friend.created,
"favorite": false
})
})
friends.list.outgoing.forEach(friend => {
response.push({
"accountId": friend.accountId,
"status": "PENDING",
"direction": "OUTBOUND",
"created": friend.created,
"favorite": false
})
})
res.json(response);
});
app.post("/friends/api/public/friends/*/:receiverId", verifyToken, async (req, res) => {
let sender = await Friends.findOne({ accountId: req.user.accountId });
let receiver = await Friends.findOne({ accountId: req.params.receiverId });
if (!sender || !receiver) return res.status(403).end();
if (sender.list.incoming.find(i => i.accountId == receiver.accountId)) {
if (!await friendManager.acceptFriendReq(sender.accountId, receiver.accountId)) return res.status(403).end();
functions.getPresenceFromUser(sender.accountId, receiver.accountId, false);
functions.getPresenceFromUser(receiver.accountId, sender.accountId, false);
} else if (!sender.list.outgoing.find(i => i.accountId == receiver.accountId)) {
if (!await friendManager.sendFriendReq(sender.accountId, receiver.accountId)) return res.status(403).end();
}
res.status(204).end();
});
app.post("/friends/api/v1/*/friends/:receiverId", verifyToken, async (req, res) => {
let sender = await Friends.findOne({ accountId: req.user.accountId });
let receiver = await Friends.findOne({ accountId: req.params.receiverId });
if (!sender || !receiver) return res.status(403).end();
if (sender.list.incoming.find(i => i.accountId == receiver.accountId)) {
if (!await friendManager.acceptFriendReq(sender.accountId, receiver.accountId)) return res.status(403).end();
functions.getPresenceFromUser(sender.accountId, receiver.accountId, false);
functions.getPresenceFromUser(receiver.accountId, sender.accountId, false);
} else if (!sender.list.outgoing.find(i => i.accountId == receiver.accountId)) {
if (!await friendManager.sendFriendReq(sender.accountId, receiver.accountId)) return res.status(403).end();
}
res.status(204).end();
});
app.delete("/friends/api/public/friends/*/:receiverId", verifyToken, async (req, res) => {
let sender = await Friends.findOne({ accountId: req.user.accountId });
let receiver = await Friends.findOne({ accountId: req.params.receiverId });
if (!sender || !receiver) return res.status(403).end();
if (!await friendManager.deleteFriend(sender.accountId, receiver.accountId)) return res.status(403).end();
functions.getPresenceFromUser(sender.accountId, receiver.accountId, true);
functions.getPresenceFromUser(receiver.accountId, sender.accountId, true);
res.status(204).end();
});
app.delete("/friends/api/v1/*/friends/:receiverId", verifyToken, async (req, res) => {
let sender = await Friends.findOne({ accountId: req.user.accountId });
let receiver = await Friends.findOne({ accountId: req.params.receiverId });
if (!sender || !receiver) return res.status(403).end();
if (!await friendManager.deleteFriend(sender.accountId, receiver.accountId)) return res.status(403).end();
functions.getPresenceFromUser(sender.accountId, receiver.accountId, true);
functions.getPresenceFromUser(receiver.accountId, sender.accountId, true);
res.status(204).end();
});
app.post("/friends/api/public/blocklist/*/:receiverId", verifyToken, async (req, res) => {
let sender = await Friends.findOne({ accountId: req.user.accountId });
let receiver = await Friends.findOne({ accountId: req.params.receiverId });
if (!sender || !receiver) return res.status(403).end();
if (!await friendManager.blockFriend(sender.accountId, receiver.accountId)) return res.status(403).end();
functions.getPresenceFromUser(sender.accountId, receiver.accountId, true);
functions.getPresenceFromUser(receiver.accountId, sender.accountId, true);
res.status(204).end();
});
app.post("/friends/api/v1/*/blocklist/:receiverId", verifyToken, async (req, res) => {
let sender = await Friends.findOne({ accountId: req.user.accountId });
let receiver = await Friends.findOne({ accountId: req.params.receiverId });
if (!sender || !receiver) return res.status(403).end();
if (!await friendManager.blockFriend(sender.accountId, receiver.accountId)) return res.status(403).end();
functions.getPresenceFromUser(sender.accountId, receiver.accountId, true);
functions.getPresenceFromUser(receiver.accountId, sender.accountId, true);
res.status(204).end();
});
app.delete("/friends/api/public/blocklist/*/:receiverId", verifyToken, async (req, res) => {
let sender = await Friends.findOne({ accountId: req.user.accountId });
let receiver = await Friends.findOne({ accountId: req.params.receiverId });
if (!sender || !receiver) return res.status(403).end();
if (!await friendManager.deleteFriend(sender.accountId, receiver.accountId)) return res.status(403).end();
res.status(204).end();
});
app.delete("/friends/api/v1/*/blocklist/:receiverId", verifyToken, async (req, res) => {
let sender = await Friends.findOne({ accountId: req.user.accountId });
let receiver = await Friends.findOne({ accountId: req.params.receiverId });
if (!sender || !receiver) return res.status(403).end();
if (!await friendManager.deleteFriend(sender.accountId, receiver.accountId)) return res.status(403).end();
res.status(204).end();
});
app.get("/friends/api/v1/:accountId/summary", verifyToken, async (req, res) => {
var response = {
"friends": [],
"incoming": [],
"outgoing": [],
"suggested": [],
"blocklist": [],
"settings": {
"acceptInvites": "public"
}
}
const friends = await Friends.findOne({ accountId: req.user.accountId }).lean();
friends.list.accepted.forEach(friend => {
response.friends.push({
"accountId": friend.accountId,
"groups": [],
"mutual": 0,
"alias": "",
"note": "",
"favorite": false,
"created": friend.created
})
})
friends.list.incoming.forEach(friend => {
response.incoming.push({
"accountId": friend.accountId,
"mutual": 0,
"favorite": false,
"created": friend.created
})
})
friends.list.outgoing.forEach(friend => {
response.outgoing.push({
"accountId": friend.accountId,
"favorite": false
})
})
friends.list.blocked.forEach(friend => {
response.blocklist.push({
"accountId": friend.accountId
})
})
res.json(response);
});
app.get("/friends/api/public/list/fortnite/*/recentPlayers", verifyToken, async (req, res) => {
res.json([])
});
app.get("/friends/api/public/blocklist/*", verifyToken, async (req, res) => {
var friends = await Friends.findOne({ accountId: req.user.accountId }).lean();
res.json({
"blockedUsers": friends.list.blocked.map(i => i.accountId)
})
});
module.exports = app;
+57
View File
@@ -0,0 +1,57 @@
const express = require("express");
const app = express.Router();
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
app.get("/lightswitch/api/service/Fortnite/status", verifyClient, async (req, res) => {
var banned = false;
if (req.user) banned = req.user.banned;
res.json({
"serviceInstanceId": "fortnite",
"status": "UP",
"message": "Fortnite is online",
"maintenanceUri": null,
"overrideCatalogIds": [
"a7f138b2e51945ffbfdacc1af0541053"
],
"allowedActions": [],
"banned": banned,
"launcherInfoDTO": {
"appName": "Fortnite",
"catalogItemId": "4fe75bbc5a674f4f9b356b5c90567da5",
"namespace": "fn"
}
});
})
app.get("/lightswitch/api/service/bulk/status", verifyClient, async (req, res) => {
var banned = false;
if (req.user) banned = req.user.banned;
res.json(
[{
"serviceInstanceId": "fortnite",
"status": "UP",
"message": "fortnite is up.",
"maintenanceUri": null,
"overrideCatalogIds": [
"a7f138b2e51945ffbfdacc1af0541053"
],
"allowedActions": [
"PLAY",
"DOWNLOAD"
],
"banned": banned,
"launcherInfoDTO": {
"appName": "Fortnite",
"catalogItemId": "4fe75bbc5a674f4f9b356b5c90567da5",
"namespace": "fn"
}
}]
)
})
module.exports = app;
+122
View File
@@ -0,0 +1,122 @@
const express = require("express");
const app = express.Router();
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
app.post("/fortnite/api/game/v2/tryPlayOnPlatform/account/*", verifyToken, (req, res) => {
res.setHeader("Content-Type", "text/plain");
res.send(true);
})
app.get("/launcher/api/public/distributionpoints/", (req, res) => {
res.json({
"distributions": [
"https://download.epicgames.com/",
"https://download2.epicgames.com/",
"https://download3.epicgames.com/",
"https://download4.epicgames.com/",
"https://epicgames-download1.akamaized.net/"
]
});
})
app.get("/waitingroom/api/waitingroom", (req, res) => {
res.status(204);
res.end();
})
app.get("/socialban/api/public/v1/*", verifyToken, (req, res) => {
res.json({
"bans": [],
"warnings": []
});
})
app.get("/fortnite/api/game/v2/events/tournamentandhistory/*/EU/WindowsClient", verifyToken, (req, res) => {
res.json({});
})
app.get("/fortnite/api/statsv2/account/:accountId", verifyToken, (req, res) => {
res.json({
"startTime": 0,
"endTime": 0,
"stats": {},
"accountId": req.user.accountId
});
})
app.get("/statsproxy/api/statsv2/account/:accountId", verifyToken, (req, res) => {
res.json({
"startTime": 0,
"endTime": 0,
"stats": {},
"accountId": req.user.accountId
});
})
app.get("/fortnite/api/stats/accountId/:accountId/bulk/window/alltime", verifyToken, (req, res) => {
res.json({
"startTime": 0,
"endTime": 0,
"stats": {},
"accountId": req.user.accountId
})
})
app.post("/fortnite/api/feedback/*", verifyToken, (req, res) => {
res.status(200);
res.end();
})
app.post("/fortnite/api/statsv2/query", verifyToken, (req, res) => {
res.json([]);
})
app.post("/statsproxy/api/statsv2/query", verifyToken, (req, res) => {
res.json([]);
})
app.post("/fortnite/api/game/v2/events/v2/setSubgroup/*", verifyToken, (req, res) => {
res.status(204);
res.end();
})
app.get("/fortnite/api/game/v2/enabled_features", verifyToken, (req, res) => {
res.json([])
})
app.get("/api/v1/events/Fortnite/download/*", verifyToken, (req, res) => {
res.json({})
})
app.get("/fortnite/api/game/v2/twitch/*", verifyToken, (req, res) => {
res.status(200);
res.end();
})
app.get("/fortnite/api/game/v2/world/info", verifyToken, (req, res) => {
res.json({});
})
app.post("/fortnite/api/game/v2/chat/*/*/*/pc", verifyToken, (req, res) => {
res.json({ "GlobalChatRooms": [{ "roomName": "lawinserverglobal" }] })
})
app.post("/fortnite/api/game/v2/chat/*/recommendGeneralChatRooms/pc", verifyToken, (req, res) => {
res.json({});
})
app.get("/fortnite/api/receipts/v1/account/*/receipts", verifyToken, (req, res) => {
res.json([])
})
app.get("/fortnite/api/game/v2/leaderboards/cohort/*", verifyToken, (req, res) => {
res.json([])
})
app.post("/datarouter/api/v1/public/data", (req, res) => {
res.status(204);
res.end();
})
module.exports = app;
+85
View File
@@ -0,0 +1,85 @@
const express = require("express");
const app = express.Router();
const functions = require("../structs/functions.js");
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
app.get("/fortnite/api/matchmaking/session/findPlayer/*", verifyToken, async (req, res) => {
res.status(200);
res.end();
})
app.get("/fortnite/api/game/v2/matchmakingservice/ticket/player/*", verifyToken, async (req, res) => {
res.cookie("buildUniqueId", req.query.bucketId.split(":")[0]);
res.json({
"serviceUrl": "ws://lawinservermatchmaker.herokuapp.com",
"ticketType": "mms-player",
"payload": "69=",
"signature": "420="
})
res.end();
})
app.get("/fortnite/api/game/v2/matchmaking/account/:accountId/session/:sessionId", verifyToken, async (req, res) => {
res.json({
"accountId": req.params.accountId,
"sessionId": req.params.sessionId,
"key": "AOJEv8uTFmUh7XM2328kq9rlAzeQ5xzWzPIiyKn2s7s="
})
})
app.get("/fortnite/api/matchmaking/session/:session_id", verifyToken, async (req, res) => {
res.json({
"id": req.params.session_id,
"ownerId": functions.MakeID().replace(/-/ig, "").toUpperCase(),
"ownerName": "[DS]fortnite-liveeugcec1c2e30ubrcore0a-z8hj-1968",
"serverName": "[DS]fortnite-liveeugcec1c2e30ubrcore0a-z8hj-1968",
"serverAddress": "164.92.177.128",
"serverPort": 7777,
"maxPublicPlayers": 220,
"openPublicPlayers": 175,
"maxPrivatePlayers": 0,
"openPrivatePlayers": 0,
"attributes": {
"REGION_s": "EU",
"GAMEMODE_s": "FORTATHENA",
"ALLOWBROADCASTING_b": true,
"SUBREGION_s": "GB",
"DCID_s": "FORTNITE-LIVEEUGCEC1C2E30UBRCORE0A-14840880",
"tenant_s": "Fortnite",
"MATCHMAKINGPOOL_s": "Any",
"STORMSHIELDDEFENSETYPE_i": 0,
"HOTFIXVERSION_i": 0,
"PLAYLISTNAME_s": "Playlist_DefaultSolo",
"SESSIONKEY_s": functions.MakeID().replace(/-/ig, "").toUpperCase(),
"TENANT_s": "Fortnite",
"BEACONPORT_i": 15009
},
"publicPlayers": [],
"privatePlayers": [],
"totalPlayers": 45,
"allowJoinInProgress": false,
"shouldAdvertise": false,
"isDedicated": false,
"usesStats": false,
"allowInvites": false,
"usesPresence": false,
"allowJoinViaPresence": true,
"allowJoinViaPresenceFriendsOnly": false,
"buildUniqueId": req.cookies.buildUniqueId || "0",
"lastUpdated": new Date().toISOString(),
"started": false
})
})
app.post("/fortnite/api/matchmaking/session/*/join", verifyToken, async (req, res) => {
res.status(204);
res.end();
})
app.post("/fortnite/api/matchmaking/session/matchMakingRequest", verifyToken, async (req, res) => {
res.json([])
})
module.exports = app;
+560
View File
@@ -0,0 +1,560 @@
const express = require("express");
const app = express.Router();
const Profile = require("../model/profiles.js");
const profileManager = require("../structs/profile.js");
const error = require("../structs/error.js");
const functions = require("../structs/functions.js");
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
app.post("/fortnite/api/game/v2/profile/*/client/MarkItemSeen", verifyToken, async (req, res) => {
if (!await profileManager.validateProfile(req.user.accountId, req.query.profileId)) return error.createError(
"errors.com.epicgames.modules.profiles.operation_forbidden",
`Unable to find template configuration for profile ${req.query.profileId}`,
[req.query.profileId], 12813, undefined, 403, res
);
if (req.query.profileId != "athena") return error.createError(
"errors.com.epicgames.modules.profiles.invalid_command",
`SetItemFavoriteStatusBatch is not valid on ${req.query.profileId} profile`,
["SetItemFavoriteStatusBatch",req.query.profileId], 12801, undefined, 400, res
);
const profiles = await Profile.findOne({ accountId: req.user.accountId });
let profile = profiles.profiles[req.query.profileId];
if (profile.profileId == "athena") {
const memory = functions.GetVersionInfo(req);
profile.stats.attributes.season_num = memory.season;
if (memory.season == 2) {
profile.stats.attributes.book_level = 70;
profile.stats.attributes.season_match_boost = 110;
} else {
profile.stats.attributes.book_level = 100;
profile.stats.attributes.season_match_boost = 120;
}
}
let ApplyProfileChanges = [];
let BaseRevision = profile.rvn || 0;
let QueryRevision = req.query.rvn || -1;
let StatChanged = false;
var missingFields = [];
if (!req.body.itemIds) missingFields.push("itemIds");
if (missingFields.length > 0) {
return error.createError(
"errors.com.epicgames.validation.validation_failed",
`Validation Failed. [${missingFields.join(", ")}] field(s) is missing.`,
[`[${missingFields.join(", ")}]`], 1040, undefined, 400, res
);
}
if (Array.isArray(req.body.itemIds)) {
for (var i in req.body.itemIds) {
if (!profile.items[req.body.itemIds[i]]) {
return error.createError(
"errors.com.epicgames.fortnite.id_invalid",
`Item (id: "${req.body.itemIds[i]}") not found`,
[req.body.itemIds[i]], 16027, undefined, 400, res
);
}
profile.items[req.body.itemIds[i]].attributes.item_seen = true;
ApplyProfileChanges.push({
"changeType": "itemAttrChanged",
"itemId": req.body.itemIds[i],
"attributeName": "item_seen",
"attributeValue": profile.items[req.body.itemIds[i]].attributes.item_seen
})
StatChanged = true;
}
}
if (StatChanged == true) {
profile.rvn += 1;
profile.commandRevision += 1;
profile.updated = new Date().toISOString();
await profiles.updateOne({ $set: { [`profiles.${req.query.profileId}`]: profile } });
}
if (QueryRevision != BaseRevision) {
ApplyProfileChanges = [{
"changeType": "fullProfileUpdate",
"profile": profile
}];
}
res.json({
profileRevision: profile.rvn || 0,
profileId: req.query.profileId,
profileChangesBaseRevision: BaseRevision,
profileChanges: ApplyProfileChanges,
profileCommandRevision: profile.commandRevision || 0,
serverTime: new Date().toISOString(),
responseVersion: 1
});
});
app.post("/fortnite/api/game/v2/profile/*/client/SetItemFavoriteStatusBatch", verifyToken, async (req, res) => {
if (!await profileManager.validateProfile(req.user.accountId, req.query.profileId)) return error.createError(
"errors.com.epicgames.modules.profiles.operation_forbidden",
`Unable to find template configuration for profile ${req.query.profileId}`,
[req.query.profileId], 12813, undefined, 403, res
);
if (req.query.profileId != "athena") return error.createError(
"errors.com.epicgames.modules.profiles.invalid_command",
`SetItemFavoriteStatusBatch is not valid on ${req.query.profileId} profile`,
["SetItemFavoriteStatusBatch",req.query.profileId], 12801, undefined, 400, res
);
const profiles = await Profile.findOne({ accountId: req.user.accountId });
let profile = profiles.profiles[req.query.profileId];
if (profile.profileId == "athena") {
const memory = functions.GetVersionInfo(req);
profile.stats.attributes.season_num = memory.season;
if (memory.season == 2) {
profile.stats.attributes.book_level = 70;
profile.stats.attributes.season_match_boost = 110;
} else {
profile.stats.attributes.book_level = 100;
profile.stats.attributes.season_match_boost = 120;
}
}
let ApplyProfileChanges = [];
let BaseRevision = profile.rvn || 0;
let QueryRevision = req.query.rvn || -1;
let StatChanged = false;
var missingFields = [];
if (!req.body.itemIds) missingFields.push("itemIds");
if (!req.body.itemFavStatus) missingFields.push("itemFavStatus");
if (missingFields.length > 0) {
return error.createError(
"errors.com.epicgames.validation.validation_failed",
`Validation Failed. [${missingFields.join(", ")}] field(s) is missing.`,
[`[${missingFields.join(", ")}]`], 1040, undefined, 400, res
);
}
if (Array.isArray(req.body.itemIds) && Array.isArray(req.body.itemFavStatus)) {
for (var i in req.body.itemIds) {
if (!profile.items[req.body.itemIds[i]]) {
return error.createError(
"errors.com.epicgames.fortnite.id_invalid",
`Item (id: "${req.body.itemIds[i]}") not found`,
[req.body.itemIds[i]], 16027, undefined, 400, res
);
}
if (typeof req.body.itemFavStatus[i] == "boolean") {
profile.items[req.body.itemIds[i]].attributes.favorite = req.body.itemFavStatus[i];
ApplyProfileChanges.push({
"changeType": "itemAttrChanged",
"itemId": req.body.itemIds[i],
"attributeName": "favorite",
"attributeValue": profile.items[req.body.itemIds[i]].attributes.favorite
})
StatChanged = true;
}
}
}
if (StatChanged == true) {
profile.rvn += 1;
profile.commandRevision += 1;
profile.updated = new Date().toISOString();
await profiles.updateOne({ $set: { [`profiles.${req.query.profileId}`]: profile } });
}
if (QueryRevision != BaseRevision) {
ApplyProfileChanges = [{
"changeType": "fullProfileUpdate",
"profile": profile
}];
}
res.json({
profileRevision: profile.rvn || 0,
profileId: req.query.profileId,
profileChangesBaseRevision: BaseRevision,
profileChanges: ApplyProfileChanges,
profileCommandRevision: profile.commandRevision || 0,
serverTime: new Date().toISOString(),
responseVersion: 1
});
});
app.post("/fortnite/api/game/v2/profile/*/client/SetBattleRoyaleBanner", verifyToken, async (req, res) => {
if (!await profileManager.validateProfile(req.user.accountId, req.query.profileId)) return error.createError(
"errors.com.epicgames.modules.profiles.operation_forbidden",
`Unable to find template configuration for profile ${req.query.profileId}`,
[req.query.profileId], 12813, undefined, 403, res
);
if (req.query.profileId != "athena") return error.createError(
"errors.com.epicgames.modules.profiles.invalid_command",
`SetBattleRoyaleBanner is not valid on ${req.query.profileId} profile`,
["SetBattleRoyaleBanner",req.query.profileId], 12801, undefined, 400, res
);
const profiles = await Profile.findOne({ accountId: req.user.accountId });
let profile = profiles.profiles[req.query.profileId];
if (profile.profileId == "athena") {
const memory = functions.GetVersionInfo(req);
profile.stats.attributes.season_num = memory.season;
if (memory.season == 2) {
profile.stats.attributes.book_level = 70;
profile.stats.attributes.season_match_boost = 110;
} else {
profile.stats.attributes.book_level = 100;
profile.stats.attributes.season_match_boost = 120;
}
}
let ApplyProfileChanges = [];
let BaseRevision = profile.rvn || 0;
let QueryRevision = req.query.rvn || -1;
let StatChanged = false;
var missingFields = [];
if (!req.body.homebaseBannerIconId) missingFields.push("homebaseBannerIconId");
if (!req.body.homebaseBannerColorId) missingFields.push("homebaseBannerColorId");
if (missingFields.length > 0) {
return error.createError(
"errors.com.epicgames.validation.validation_failed",
`Validation Failed. [${missingFields.join(", ")}] field(s) is missing.`,
[`[${missingFields.join(", ")}]`], 1040, undefined, 400, res
);
}
var returnError = true;
for (var itemId in profiles.profiles["common_core"].items) {
if (profiles.profiles["common_core"].items[itemId].templateId.startsWith(`HomebaseBannerIcon:${req.body.homebaseBannerIconId}`)) returnError = false;
}
if (returnError == true) return error.createError(
"errors.com.epicgames.fortnite.item_not_found",
`Banner template 'HomebaseBannerIcon:${req.body.homebaseBannerIconId}' not found in profile`,
[`HomebaseBannerIcon:${req.body.homebaseBannerIconId}`], 16006, undefined, 400, res
);
returnError = true;
for (var itemId in profiles.profiles["common_core"].items) {
if (profiles.profiles["common_core"].items[itemId].templateId.startsWith(`HomebaseBannerColor:${req.body.homebaseBannerColorId}`)) returnError = false;
}
if (returnError == true) return error.createError(
"errors.com.epicgames.fortnite.item_not_found",
`Banner template 'HomebaseBannerColor:${req.body.homebaseBannerColorId}' not found in profile`,
[`HomebaseBannerColor:${req.body.homebaseBannerColorId}`], 16006, undefined, 400, res
);
if (req.body.homebaseBannerIconId && req.body.homebaseBannerColorId) {
if (typeof req.body.homebaseBannerIconId == "string" && typeof req.body.homebaseBannerColorId == "string") {
profile.stats.attributes.banner_icon = req.body.homebaseBannerIconId;
profile.stats.attributes.banner_color = req.body.homebaseBannerColorId;
ApplyProfileChanges.push({
"changeType": "statModified",
"name": "banner_icon",
"value": profile.stats.attributes.banner_icon
})
ApplyProfileChanges.push({
"changeType": "statModified",
"name": "banner_color",
"value": profile.stats.attributes.banner_color
})
StatChanged = true;
}
}
if (StatChanged == true) {
profile.rvn += 1;
profile.commandRevision += 1;
profile.updated = new Date().toISOString();
await profiles.updateOne({ $set: { [`profiles.${req.query.profileId}`]: profile } });
}
if (QueryRevision != BaseRevision) {
ApplyProfileChanges = [{
"changeType": "fullProfileUpdate",
"profile": profile
}];
}
res.json({
profileRevision: profile.rvn || 0,
profileId: req.query.profileId,
profileChangesBaseRevision: BaseRevision,
profileChanges: ApplyProfileChanges,
profileCommandRevision: profile.commandRevision || 0,
serverTime: new Date().toISOString(),
responseVersion: 1
});
});
app.post("/fortnite/api/game/v2/profile/*/client/EquipBattleRoyaleCustomization", verifyToken, async (req, res) => {
if (!await profileManager.validateProfile(req.user.accountId, req.query.profileId)) return error.createError(
"errors.com.epicgames.modules.profiles.operation_forbidden",
`Unable to find template configuration for profile ${req.query.profileId}`,
[req.query.profileId], 12813, undefined, 403, res
);
if (req.query.profileId != "athena") return error.createError(
"errors.com.epicgames.modules.profiles.invalid_command",
`EquipBattleRoyaleCustomization is not valid on ${req.query.profileId} profile`,
["EquipBattleRoyaleCustomization",req.query.profileId], 12801, undefined, 400, res
);
const profiles = await Profile.findOne({ accountId: req.user.accountId });
let profile = profiles.profiles[req.query.profileId];
if (profile.profileId == "athena") {
const memory = functions.GetVersionInfo(req);
profile.stats.attributes.season_num = memory.season;
if (memory.season == 2) {
profile.stats.attributes.book_level = 70;
profile.stats.attributes.season_match_boost = 110;
} else {
profile.stats.attributes.book_level = 100;
profile.stats.attributes.season_match_boost = 120;
}
}
let ApplyProfileChanges = [];
let BaseRevision = profile.rvn || 0;
let QueryRevision = req.query.rvn || -1;
let StatChanged = false;
let specialCosmetics = [
"athenacharacter:cid_random",
"athenabackpack:bid_random",
"athenapickaxe:pickaxe_random",
"athenaglider:glider_random",
"athenaskydivecontrail:trails_random",
"athenaitemwrap:wrap_random",
"athenamusicpack:musicpack_random",
"athenaloadingscreen:lsid_random"
];
var missingFields = [];
if (!req.body.slotName) missingFields.push("slotName");
if (missingFields.length > 0) {
return error.createError(
"errors.com.epicgames.validation.validation_failed",
`Validation Failed. [${missingFields.join(", ")}] field(s) is missing.`,
[`[${missingFields.join(", ")}]`], 1040, undefined, 400, res
);
}
if (!profile.items[req.body.itemToSlot] && req.body.itemToSlot) {
let item = req.body.itemToSlot
if (typeof item == "string") item = item.toLowerCase()
if (!specialCosmetics.includes(item)) {
return error.createError(
"errors.com.epicgames.fortnite.id_invalid",
`Item (id: "${req.body.itemToSlot}") not found`,
[req.body.itemToSlot], 16027, undefined, 400, res
);
}
}
if (profile.items[req.body.itemToSlot]) {
if (!profile.items[req.body.itemToSlot].templateId.startsWith(`Athena${req.body.slotName}:`)) return error.createError(
"errors.com.epicgames.fortnite.id_invalid",
`Cannot slot item of type ${profile.items[req.body.itemToSlot].templateId.split(":")[0]} in slot of category ${req.body.slotName}`,
[profile.items[req.body.itemToSlot].templateId.split(":")[0],req.body.slotName], 16027, undefined, 400, res
);
let Variants = req.body.variantUpdates;
let item = req.body.itemToSlot
if (typeof item == "string") item = item.toLowerCase()
if (Variants && !specialCosmetics.includes(item)) {
for (var i in Variants) {
if (!Variants[i].channel) break;
if (!Variants[i].active) break;
if (!profile.items[req.body.itemToSlot].attributes.variants.find(x => x.channel == Variants[i].channel)) break;
if (!profile.items[req.body.itemToSlot].attributes.variants.find(x => x.channel == Variants[i].channel).owned.includes(Variants[i].active)) break;
let index = profile.items[req.body.itemToSlot].attributes.variants.findIndex(x => x.channel == Variants[i].channel);
profile.items[req.body.itemToSlot].attributes.variants[index].active = Variants[i].active;
}
ApplyProfileChanges.push({
"changeType": "itemAttrChanged",
"itemId": req.body.itemToSlot,
"attributeName": "variants",
"attributeValue": profile.items[req.body.itemToSlot].attributes.variants
})
}
}
let slotNames = ["Character","Backpack","Pickaxe","Glider","SkyDiveContrail","MusicPack","LoadingScreen"];
switch (req.body.slotName) {
case "Dance":
var indexwithinslot = req.body.indexWithinSlot || 0;
if (indexwithinslot >= 0 && indexwithinslot <= 5) {
profile.stats.attributes.favorite_dance[indexwithinslot] = req.body.itemToSlot || "";
StatChanged = true;
}
break;
case "ItemWrap":
var indexwithinslot = req.body.indexWithinSlot || 0;
switch (true) {
case indexwithinslot >= 0 && indexwithinslot <= 7:
profile.stats.attributes.favorite_itemwraps[indexwithinslot] = req.body.itemToSlot || "";
StatChanged = true;
break;
case indexwithinslot == -1:
for (var i = 0; i < 7; i++) {
profile.stats.attributes.favorite_itemwraps[i] = req.body.itemToSlot || "";
}
StatChanged = true;
break;
}
break;
default:
if (!slotNames.includes(req.body.slotName)) break;
let Category = (`favorite_${req.body.slotName}`).toLowerCase()
profile.stats.attributes[Category] = req.body.itemToSlot || "";
StatChanged = true;
break;
}
if (StatChanged == true) {
let Category = (`favorite_${req.body.slotName}`).toLowerCase()
if (Category == "favorite_itemwrap") Category += "s";
profile.rvn += 1;
profile.commandRevision += 1;
profile.updated = new Date().toISOString();
ApplyProfileChanges.push({
"changeType": "statModified",
"name": Category,
"value": profile.stats.attributes[Category]
})
await profiles.updateOne({ $set: { [`profiles.${req.query.profileId}`]: profile } });
}
if (QueryRevision != BaseRevision) {
ApplyProfileChanges = [{
"changeType": "fullProfileUpdate",
"profile": profile
}];
}
res.json({
profileRevision: profile.rvn || 0,
profileId: req.query.profileId,
profileChangesBaseRevision: BaseRevision,
profileChanges: ApplyProfileChanges,
profileCommandRevision: profile.commandRevision || 0,
serverTime: new Date().toISOString(),
responseVersion: 1
});
});
app.post("/fortnite/api/game/v2/profile/*/client/:operation", verifyToken, async (req, res) => {
if (!await profileManager.validateProfile(req.user.accountId, req.query.profileId)) return error.createError(
"errors.com.epicgames.modules.profiles.operation_forbidden",
`Unable to find template configuration for profile ${req.query.profileId}`,
[req.query.profileId], 12813, undefined, 403, res
);
const profiles = await Profile.findOne({ accountId: req.user.accountId }).lean();
let profile = profiles.profiles[req.query.profileId];
if (profile.profileId == "athena") {
const memory = functions.GetVersionInfo(req);
profile.stats.attributes.season_num = memory.season;
if (memory.season == 2) {
profile.stats.attributes.book_level = 70;
profile.stats.attributes.season_match_boost = 110;
} else {
profile.stats.attributes.book_level = 100;
profile.stats.attributes.season_match_boost = 120;
}
}
let ApplyProfileChanges = [];
let BaseRevision = profile.rvn || 0;
let QueryRevision = req.query.rvn || -1;
switch (req.params.operation) {
case "QueryProfile": break;
case "ClientQuestLogin": break;
case "RefreshExpeditions": break;
case "GetMcpTimeForLogin": break;
case "IncrementNamedCounterStat": break;
case "SetHardcoreModifier": break;
default:
error.createError(
"errors.com.epicgames.fortnite.operation_not_found",
`Operation ${req.params.operation} not valid`,
[req.params.operation], 16035, undefined, 404, res
);
return;
}
if (QueryRevision != BaseRevision) {
ApplyProfileChanges = [{
"changeType": "fullProfileUpdate",
"profile": profile
}];
}
res.json({
profileRevision: profile.rvn || 0,
profileId: req.query.profileId,
profileChangesBaseRevision: BaseRevision,
profileChanges: ApplyProfileChanges,
profileCommandRevision: profile.commandRevision || 0,
serverTime: new Date().toISOString(),
responseVersion: 1
});
});
module.exports = app;
+26
View File
@@ -0,0 +1,26 @@
const express = require("express");
const app = express.Router();
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
const keychain = require("../responses/keychain.json");
app.get("/fortnite/api/storefront/v2/catalog", verifyToken, async (req, res) => {
if (req.headers["user-agent"].includes("2870186")) return res.status(404).end();
res.json({
refreshIntervalHrs: 24,
dailyPurchaseHrs: 24,
expiration: "9999-12-31T00:00:00.000Z",
storefronts: []
});
});
app.get("/fortnite/api/storefront/v2/keychain", verifyToken, async (req, res) => {
res.json(keychain);
});
app.get("/catalog/api/shared/bulk/offers", verifyToken, async (req, res) => {
res.json({});
});
module.exports = app;
+57
View File
@@ -0,0 +1,57 @@
const express = require("express");
const app = express.Router();
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
const functions = require("../structs/functions.js");
app.get("/fortnite/api/calendar/v1/timeline", verifyClient, async (req, res) => {
const memory = functions.GetVersionInfo(req);
var activeEvents = [
{
"eventType": `EventFlag.Season${memory.season}`,
"activeUntil": "9999-01-01T00:00:00.000Z",
"activeSince": "2020-01-01T00:00:00.000Z"
},
{
"eventType": `EventFlag.${memory.lobby}`,
"activeUntil": "9999-01-01T00:00:00.000Z",
"activeSince": "2020-01-01T00:00:00.000Z"
}
];
res.json({
channels: {
"client-matchmaking": {
states: [],
cacheExpire: "9999-01-01T00:00:00.000Z"
},
"client-events": {
states: [{
validFrom: "0001-01-01T00:00:00.000Z",
activeEvents: activeEvents,
state: {
activeStorefronts: [],
eventNamedWeights: {},
seasonNumber: memory.season,
seasonTemplateId: `AthenaSeason:athenaseason${memory.season}`,
matchXpBonusPoints: 0,
seasonBegin: "2020-01-01T00:00:00Z",
seasonEnd: "9999-01-01T00:00:00Z",
seasonDisplayedEnd: "9999-01-01T00:00:00Z",
weeklyStoreEnd: "9999-01-01T00:00:00Z",
stwEventStoreEnd: "9999-01-01T00:00:00.000Z",
stwWeeklyStoreEnd: "9999-01-01T00:00:00.000Z",
dailyStoreEnd: "9999-01-01T00:00:00Z"
}
}],
cacheExpire: "9999-01-01T00:00:00.000Z"
}
},
eventsTimeOffsetHrs: 0,
cacheIntervalMins: 10,
currentTime: new Date().toISOString()
})
})
module.exports = app;
+83
View File
@@ -0,0 +1,83 @@
const express = require("express");
const app = express.Router();
const error = require("../structs/error.js");
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
const User = require("../model/user.js");
app.get("/account/api/public/account", verifyToken, async (req, res) => {
var response = [];
if (typeof req.query.accountId == "string") {
var user = await User.findOne({ accountId: req.query.accountId, banned: false }).lean();
if (user) {
response.push({
id: user.accountId,
displayName: user.username,
externalAuths: {}
})
}
}
if (Array.isArray(req.query.accountId)) {
for (var x in req.query.accountId) {
var user = await User.findOne({ accountId: req.query.accountId[x], banned: false }).lean();
if (user) {
response.push({
id: user.accountId,
displayName: user.username,
externalAuths: {}
})
}
}
}
res.json(response)
});
app.get("/account/api/public/account/displayName/:displayName", verifyToken, async (req, res) => {
var user = await User.findOne({ username_lower: req.params.displayName.toLowerCase(), banned: false }).lean();
if (!user) return error.createError(
"errors.com.epicgames.account.account_not_found",
`Sorry, we couldn't find an account for ${req.params.displayName}`,
[req.params.displayName], 18007, undefined, 404, res
);
res.json({
id: user.accountId,
displayName: user.username,
externalAuths: {}
});
});
app.get("/account/api/public/account/:accountId", verifyToken, async (req, res) => {
res.json({
id: req.user.accountId,
displayName: req.user.username,
name: "Lawin",
email: req.user.email,
failedLoginAttempts: 0,
lastLogin: new Date().toISOString(),
numberOfDisplayNameChanges: 0,
ageGroup: "UNKNOWN",
headless: false,
country: "US",
lastName: "Server",
preferredLanguage: "en",
canUpdateDisplayName: false,
tfaEnabled: false,
emailVerified: true,
minorVerified: false,
minorExpected: false,
minorStatus: "UNKNOWN"
})
});
app.get("/account/api/public/account/*/externalAuths", verifyToken, async (req, res) => {
res.json([])
});
module.exports = app;
+61
View File
@@ -0,0 +1,61 @@
const express = require("express");
const app = express.Router();
const { verifyToken, verifyClient } = require("../tokenManager/tokenVerify.js");
app.get("/fortnite/api/version", async (req, res) => {
res.json({
"app": "fortnite",
"serverDate": new Date().toISOString(),
"overridePropertiesVersion": "unknown",
"cln": "17951730",
"build": "444",
"moduleName": "Fortnite-Core",
"buildDate": "2021-10-27T21:00:51.697Z",
"version": "18.30",
"branch": "Release-18.30",
"modules": {
"Epic-LightSwitch-AccessControlCore": {
"cln": "17237679",
"build": "b2130",
"buildDate": "2021-08-19T18:56:08.144Z",
"version": "1.0.0",
"branch": "trunk"
},
"epic-xmpp-api-v1-base": {
"cln": "5131a23c1470acbd9c94fae695ef7d899c1a41d6",
"build": "b3595",
"buildDate": "2019-07-30T09:11:06.587Z",
"version": "0.0.1",
"branch": "master"
},
"epic-common-core": {
"cln": "17909521",
"build": "3217",
"buildDate": "2021-10-25T18:41:12.486Z",
"version": "3.0",
"branch": "TRUNK"
}
}
});
});
app.get("/fortnite/api/v2/versioncheck/*", async (req, res) => {
res.json({
"type": "NO_UPDATE"
});
});
app.get("/fortnite/api/v2/versioncheck*", async (req, res) => {
res.json({
"type": "NO_UPDATE"
});
});
app.get("/fortnite/api/versioncheck*", async (req, res) => {
res.json({
"type": "NO_UPDATE"
});
});
module.exports = app;
+2
View File
@@ -0,0 +1,2 @@
node index.js
pause
+21
View File
@@ -0,0 +1,21 @@
function createError(errorCode, errorMessage, messageVars, numericErrorCode, error, statusCode, res) {
res.set({
'X-Epic-Error-Name': errorCode,
'X-Epic-Error-Code': numericErrorCode
});
res.status(statusCode).json({
errorCode: errorCode,
errorMessage: errorMessage,
messageVars: messageVars,
numericErrorCode: numericErrorCode,
originatingService: "any",
intent: "prod",
error_description: errorMessage,
error: error
});
}
module.exports = {
createError
}
+197
View File
@@ -0,0 +1,197 @@
const Friends = require("../model/friends.js");
const functions = require("../structs/functions.js");
async function validateFriendAdd(accountId, friendId) {
let sender = await Friends.findOne({ accountId: accountId }).lean();
let receiver = await Friends.findOne({ accountId: friendId }).lean();
if (!sender || !receiver) return false;
if (sender.list.accepted.find(i => i.accountId == receiver.accountId) || receiver.list.accepted.find(i => i.accountId == sender.accountId)) return false;
if (sender.list.blocked.find(i => i.accountId == receiver.accountId) || receiver.list.blocked.find(i => i.accountId == sender.accountId)) return false;
return true;
}
async function validateFriendDelete(accountId, friendId) {
let sender = await Friends.findOne({ accountId: accountId }).lean();
let receiver = await Friends.findOne({ accountId: friendId }).lean();
if (!sender || !receiver) return false;
return true;
}
async function validateFriendBlock(accountId, friendId) {
let sender = await Friends.findOne({ accountId: accountId }).lean();
let receiver = await Friends.findOne({ accountId: friendId }).lean();
if (!sender || !receiver) return false;
if (sender.list.blocked.find(i => i.accountId == receiver.accountId)) return false;
return true;
}
async function sendFriendReq(fromId, toId) {
if (!await validateFriendAdd(fromId, toId)) return false;
let from = await Friends.findOne({ accountId: fromId });
let fromFriends = from.list;
let to = await Friends.findOne({ accountId: toId });
let toFriends = to.list;
if (fromFriends.blocked.find(i => i.accountId == to.accountId)) return;
if (toFriends.blocked.find(i => i.accountId == from.accountId)) return;
fromFriends.outgoing.push({ accountId: to.accountId, created: new Date().toISOString() });
functions.sendXmppMessageToId({
"payload": {
"accountId": to.accountId,
"status": "PENDING",
"direction": "OUTBOUND",
"created": new Date().toISOString(),
"favorite": false
},
"type": "com.epicgames.friends.core.apiobjects.Friend",
"timestamp": new Date().toISOString()
}, from.accountId);
toFriends.incoming.push({ accountId: from.accountId, created: new Date().toISOString() });
functions.sendXmppMessageToId({
"payload": {
"accountId": from.accountId,
"status": "PENDING",
"direction": "INBOUND",
"created": new Date().toISOString(),
"favorite": false
},
"type": "com.epicgames.friends.core.apiobjects.Friend",
"timestamp": new Date().toISOString()
}, to.accountId);
await from.updateOne({ $set: { list: fromFriends } });
await to.updateOne({ $set: { list: toFriends } });
return true;
}
async function acceptFriendReq(fromId, toId) {
if (!await validateFriendAdd(fromId, toId)) return false;
let from = await Friends.findOne({ accountId: fromId });
let fromFriends = from.list;
let to = await Friends.findOne({ accountId: toId });
let toFriends = to.list;
if (fromFriends.incoming.find(i => i.accountId == to.accountId)) {
fromFriends.incoming.splice(fromFriends.incoming.findIndex(i => i.accountId == to.accountId), 1);
fromFriends.accepted.push({ accountId: to.accountId, created: new Date().toISOString() });
functions.sendXmppMessageToId({
"payload": {
"accountId": to.accountId,
"status": "ACCEPTED",
"direction": "OUTBOUND",
"created": new Date().toISOString(),
"favorite": false
},
"type": "com.epicgames.friends.core.apiobjects.Friend",
"timestamp": new Date().toISOString()
}, from.accountId);
toFriends.outgoing.splice(toFriends.outgoing.findIndex(i => i.accountId == from.accountId), 1);
toFriends.accepted.push({ accountId: from.accountId, created: new Date().toISOString() });
functions.sendXmppMessageToId({
"payload": {
"accountId": from.accountId,
"status": "ACCEPTED",
"direction": "OUTBOUND",
"created": new Date().toISOString(),
"favorite": false
},
"type": "com.epicgames.friends.core.apiobjects.Friend",
"timestamp": new Date().toISOString()
}, to.accountId);
await from.updateOne({ $set: { list: fromFriends } });
await to.updateOne({ $set: { list: toFriends } });
}
return true;
}
async function deleteFriend(fromId, toId) {
if (!await validateFriendDelete(fromId, toId)) return false;
let from = await Friends.findOne({ accountId: fromId });
let fromFriends = from.list;
let to = await Friends.findOne({ accountId: toId });
let toFriends = to.list;
var removed = false;
for (var listType in fromFriends) {
if (fromFriends[listType].find(i => i.accountId == to.accountId)) {
fromFriends[listType].splice(fromFriends[listType].findIndex(i => i.accountId == to.accountId), 1);
removed = true;
}
if (listType == "blocked") break;
if (toFriends[listType].find(i => i.accountId == from.accountId)) toFriends[listType].splice(toFriends[listType].findIndex(i => i.accountId == from.accountId), 1);
}
if (removed == true) {
functions.sendXmppMessageToId({
"payload": {
"accountId": to.accountId,
"reason": "DELETED"
},
"type": "com.epicgames.friends.core.apiobjects.FriendRemoval",
"timestamp": new Date().toISOString()
}, from.accountId);
functions.sendXmppMessageToId({
"payload": {
"accountId": from.accountId,
"reason": "DELETED"
},
"type": "com.epicgames.friends.core.apiobjects.FriendRemoval",
"timestamp": new Date().toISOString()
}, to.accountId);
await from.updateOne({ $set: { list: fromFriends } });
await to.updateOne({ $set: { list: toFriends } });
}
return true;
}
async function blockFriend(fromId, toId) {
if (!await validateFriendDelete(fromId, toId)) return false;
if (!await validateFriendBlock(fromId, toId)) return false;
await deleteFriend(fromId, toId);
let from = await Friends.findOne({ accountId: fromId });
let fromFriends = from.list;
let to = await Friends.findOne({ accountId: toId });
fromFriends.blocked.push({ accountId: to.accountId, created: new Date().toISOString() });
await from.updateOne({ $set: { list: fromFriends } });
return true;
}
module.exports = {
validateFriendAdd,
validateFriendDelete,
sendFriendReq,
acceptFriendReq,
blockFriend,
deleteFriend
}
+261
View File
@@ -0,0 +1,261 @@
const XMLBuilder = require("xmlbuilder");
const uuid = require("uuid");
const bcrypt = require("bcrypt");
const User = require("../model/user.js");
const Profile = require("../model/profiles.js");
const profileManager = require("../structs/profile.js");
const Friends = require("../model/friends.js");
async function sleep(ms) {
await new Promise((resolve, reject) => {
setTimeout(resolve, ms);
})
}
function GetVersionInfo(req) {
var memory = {
season: 0,
build: 0.0,
CL: "",
lobby: ""
}
if (req.headers["user-agent"]) {
var CL = "";
try {
var BuildID = req.headers["user-agent"].split("-")[3].split(",")[0]
if (!Number.isNaN(Number(BuildID))) {
CL = BuildID;
}
if (Number.isNaN(Number(BuildID))) {
var BuildID = req.headers["user-agent"].split("-")[3].split(" ")[0]
if (!Number.isNaN(Number(BuildID))) {
CL = BuildID;
}
}
} catch (err) {
try {
var BuildID = req.headers["user-agent"].split("-")[1].split("+")[0]
if (!Number.isNaN(Number(BuildID))) {
CL = BuildID;
}
} catch (err) {}
}
try {
var Build = req.headers["user-agent"].split("Release-")[1].split("-")[0];
if (Build.split(".").length == 3) {
Value = Build.split(".");
Build = Value[0] + "." + Value[1] + Value[2];
}
memory.season = Number(Build.split(".")[0]);
memory.build = Number(Build);
memory.CL = CL;
memory.lobby = `LobbySeason${memory.season}`;
if (Number.isNaN(memory.season)) {
throw new Error();
}
} catch (err) {
memory.season = 2;
memory.build = 2.0;
memory.CL = CL;
memory.lobby = "LobbyWinterDecor";
}
}
return memory;
}
function getContentPages(req) {
const memory = GetVersionInfo(req);
const contentpages = JSON.parse(JSON.stringify(require("../responses/contentpages.json")));
var Language = "en";
try {
if (req.headers["accept-language"]) {
if (req.headers["accept-language"].includes("-") && req.headers["accept-language"] != "es-419") {
Language = req.headers["accept-language"].split("-")[0];
} else {
Language = req.headers["accept-language"];
}
}
} catch {}
const modes = ["saveTheWorldUnowned", "battleRoyale", "creative", "saveTheWorld"];
const news = ["savetheworldnews", "battleroyalenews"]
try {
modes.forEach(mode => {
contentpages.subgameselectdata[mode].message.title = contentpages.subgameselectdata[mode].message.title[Language]
contentpages.subgameselectdata[mode].message.body = contentpages.subgameselectdata[mode].message.body[Language]
})
} catch (err) {}
try {
if (memory.build < 5.30) {
news.forEach(mode => {
contentpages[mode].news.messages[0].image = "https://cdn.discordapp.com/attachments/927739901540188200/930879507496308736/discord.png";
contentpages[mode].news.messages[1].image = "https://cdn.discordapp.com/attachments/927739901540188200/930879519882088508/lawin.png";
})
}
} catch (err) {}
try {
contentpages.dynamicbackgrounds.backgrounds.backgrounds[0].stage = `season${memory.season}`;
contentpages.dynamicbackgrounds.backgrounds.backgrounds[1].stage = `season${memory.season}`;
if (memory.season == 10) {
contentpages.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "seasonx";
contentpages.dynamicbackgrounds.backgrounds.backgrounds[1].stage = "seasonx";
}
if (memory.build == 11.31 || memory.build == 11.40) {
contentpages.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "Winter19";
contentpages.dynamicbackgrounds.backgrounds.backgrounds[1].stage = "Winter19";
}
if (memory.build == 19.01) {
contentpages.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "winter2021";
contentpages.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = "https://cdn.discordapp.com/attachments/927739901540188200/930880158167085116/t-bp19-lobby-xmas-2048x1024-f85d2684b4af.png";
contentpages.subgameinfo.battleroyale.image = "https://cdn.discordapp.com/attachments/927739901540188200/930880421514846268/19br-wf-subgame-select-512x1024-16d8bb0f218f.jpg";
contentpages.specialoffervideo.bSpecialOfferEnabled = "true";
}
if (memory.season == 20) {
if (memory.build == 20.40) {
contentpages.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = "https://cdn2.unrealengine.com/t-bp20-40-armadillo-glowup-lobby-2048x2048-2048x2048-3b83b887cc7f.jpg"
} else {
contentpages.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = "https://cdn2.unrealengine.com/t-bp20-lobby-2048x1024-d89eb522746c.png";
}
}
if (memory.season == 21) {
contentpages.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = "https://cdn2.unrealengine.com/s21-lobby-background-2048x1024-2e7112b25dc3.jpg"
}
} catch (err) {}
return contentpages;
}
function MakeID() {
return uuid.v4();
}
function sendXmppMessageToAll(body) {
if (!global.Clients) return;
if (typeof body == "object") body = JSON.stringify(body);
global.Clients.forEach(ClientData => {
ClientData.client.send(XMLBuilder.create("message")
.attribute("from", "[email protected]")
.attribute("xmlns", "jabber:client")
.attribute("to", ClientData.jid)
.element("body", `${body}`).up().toString());
});
}
function sendXmppMessageToClient(ws, msg, body) {
if (!global.Clients) return;
if (typeof body == "object") body = JSON.stringify(body);
var sender = global.Clients.find(i => i.client == ws);
var receiver = global.Clients.find(i => i.jid.split("/")[0] == msg.root.attributes.to || i.jid == msg.root.attributes.to);
if (!receiver || !sender) return;
receiver.client.send(XMLBuilder.create("message")
.attribute("from", sender.jid)
.attribute("id", msg.root.attributes.id)
.attribute("to", receiver.jid)
.attribute("xmlns", "jabber:client")
.element("body", body).up().toString());
}
function sendXmppMessageToId(body, toAccountId) {
if (!global.Clients) return;
if (typeof body == "object") body = JSON.stringify(body);
var receiver = global.Clients.find(i => i.accountId == toAccountId);
if (!receiver) return;
receiver.client.send(XMLBuilder.create("message")
.attribute("from", "[email protected]")
.attribute("to", receiver.jid)
.attribute("xmlns", "jabber:client")
.element("body", body).up().toString());
}
function getPresenceFromUser(fromId, toId, unavailable) {
if (!global.Clients) return;
var SenderData = global.Clients.find(i => i.accountId == fromId);
var ClientData = global.Clients.find(i => i.accountId == toId);
var availability = unavailable == true ? "unavailable" : "available";
if (!SenderData || !ClientData) return;
var xml = XMLBuilder.create("presence")
.attribute("to", ClientData.jid)
.attribute("xmlns", "jabber:client")
.attribute("from", SenderData.jid)
if (SenderData.lastPresenceUpdate.away == true) xml = xml.attribute("type", availability).element("show", "away").up().element("status", SenderData.lastPresenceUpdate.status).up();
else xml = xml.attribute("type", availability).element("status", SenderData.lastPresenceUpdate.status).up();
ClientData.client.send(xml.toString())
}
async function registerUser(discordId, username, email, plainPassword) {
email = email.toLowerCase();
if (!discordId || !username || !email || !plainPassword) return { message: "Username/email/password is required.", status: 400 };
if (await User.findOne({ discordId })) return { message: "You already created an account!", status: 400 };
const accountId = MakeID().replace(/-/ig, "");
// filters
const emailFilter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
if (!emailFilter.test(email)) return { message: "You did not provide a valid email address!", status: 400 };
if (username.length >= 25) return { message: "Your username must be less than 25 characters long.", status: 400 };
if (username.length < 3) return { message: "Your username must be atleast 3 characters long.", status: 400 };
if (plainPassword.length >= 128) return { message: "Your password must be less than 128 characters long.", status: 400 };
if (plainPassword.length < 8) return { message: "Your password must be atleast 8 characters long.", status: 400 };
const hashedPassword = await bcrypt.hash(plainPassword, 10);
try {
await User.create({ created: new Date().toISOString(), discordId, accountId, username, username_lower: username.toLowerCase(), email, password: hashedPassword }).then(async (i) => {
await Profile.create({ created: i.created, accountId: i.accountId, profiles: profileManager.createProfiles(i.accountId) });
await Friends.create({ created: i.created, accountId: i.accountId });
});
} catch (err) {
if (err.code == 11000) return { message: `Username or email is already in use.`, status: 400 };
return { message: "An unknown error has occured, please try again later.", status: 400 };
};
return { message: `Successfully created an account with the username ${username}`, status: 200 };
}
function DecodeBase64(str) {
return Buffer.from(str, 'base64').toString()
}
module.exports = {
sleep,
GetVersionInfo,
getContentPages,
MakeID,
sendXmppMessageToAll,
sendXmppMessageToClient,
sendXmppMessageToId,
getPresenceFromUser,
registerUser,
DecodeBase64
}
+46
View File
@@ -0,0 +1,46 @@
function backend() {
let msg = "";
for (let i in backend.arguments) {
msg += `${i == "0" ? "" : " "}${backend.arguments[i]}`;
}
console.log(`\x1b[32mBACKEND\x1b[0m: ${msg}`);
}
function bot() {
let msg = "";
for (let i in bot.arguments) {
msg += `${i == "0" ? "" : " "}${bot.arguments[i]}`;
}
console.log(`\x1b[33mBOT\x1b[0m: ${msg}`);
}
function xmpp() {
let msg = "";
for (let i in xmpp.arguments) {
msg += `${i == "0" ? "" : " "}${xmpp.arguments[i]}`;
}
console.log(`\x1b[34mXMPP\x1b[0m: ${msg}`)
}
function error() {
let msg = "";
for (let i in error.arguments) {
msg += `${i == "0" ? "" : " "}${error.arguments[i]}`;
}
console.log(`\x1b[31mERROR\x1b[0m: ${msg}`);
}
module.exports = {
backend,
bot,
xmpp,
error
}
+35
View File
@@ -0,0 +1,35 @@
const fs = require("fs");
const Profile = require("../model/profiles.js");
function createProfiles(accountId) {
var profiles = {};
fs.readdirSync("./Config/DefaultProfiles").forEach(fileName => {
const profile = require(`../Config/DefaultProfiles/${fileName}`);
profile.accountId = accountId;
profile.created = new Date().toISOString();
profiles[profile.profileId] = profile;
})
return profiles;
}
async function validateProfile(accountId, profileId) {
try {
var profiles = await Profile.findOne({ accountId: accountId }).lean();
var profile = profiles.profiles[profileId];
if (!profile || !profileId) throw new Error("Invalid profile/profileId");
} catch (err) {
return false;
}
return true;
}
module.exports = {
createProfiles,
validateProfile
}
+51
View File
@@ -0,0 +1,51 @@
const functions = require("../structs/functions.js");
const jwt = require("jsonwebtoken");
function createClient(clientId, grant_type, expiresIn) {
return jwt.sign({
"p": Buffer.from(functions.MakeID()).toString("base64"),
"clsvc": "fortnite",
"t": "s",
"mver": false,
"clid": clientId,
"ic": true,
"am": grant_type,
"jti": functions.MakeID().replace(/-/ig, "")
}, global.JWT_SECRET, { expiresIn: expiresIn })
}
function createAccess(user, clientId, grant_type, deviceId, expiresIn) {
return jwt.sign({
"app": "fortnite",
"sub": user.accountId,
"dvid": deviceId,
"mver": false,
"clid": clientId,
"dn": user.username,
"am": grant_type,
"p": Buffer.from(functions.MakeID()).toString("base64"),
"iai": user.accountId,
"sec": 1,
"clsvc": "fortnite",
"t": "s",
"ic": true,
"jti": functions.MakeID().replace(/-/ig, "")
}, global.JWT_SECRET, { expiresIn: expiresIn })
}
function createRefresh(user, clientId, grant_type, deviceId, expiresIn) {
return jwt.sign({
"sub": user.accountId,
"dvid": deviceId,
"t": "r",
"clid": clientId,
"am": grant_type,
"jti": functions.MakeID().replace(/-/ig, "")
}, global.JWT_SECRET, { expiresIn: expiresIn })
}
module.exports = {
createClient,
createAccess,
createRefresh
}
+80
View File
@@ -0,0 +1,80 @@
const jwt = require("jsonwebtoken");
const User = require("../model/user.js");
const error = require("../structs/error.js");
async function verifyToken(req, res, next) {
if (!req.headers["authorization"] || !req.headers["authorization"].startsWith("bearer eg1~")) return error.createError(
"errors.com.epicgames.common.authorization.authorization_failed",
`Authorization failed for ${req.originalUrl}`,
[req.originalUrl], 1032, undefined, 401, res
);
const token = req.headers["authorization"].split("bearer eg1~")[1];
try {
const decodedToken = jwt.verify(token, global.JWT_SECRET);
if (!global.accessTokens.find(i => i.token == `eg1~${token}`)) throw new Error("Invalid token.");
req.user = await User.findOne({ accountId: decodedToken.sub }).lean();
if (req.user.banned == true) return error.createError(
"errors.com.epicgames.account.account_not_active",
"Sorry, your account is inactive and may not login.",
[], -1, undefined, 400, res
);
next();
} catch (err) {
if (global.accessTokens.find(i => i.token == `eg1~${token}`)) global.accessTokens.splice(global.accessTokens.findIndex(i => i.token == `eg1~${token}`), 1);
return error.createError(
"errors.com.epicgames.common.authorization.authorization_failed",
`Authorization failed for ${req.originalUrl}`,
[req.originalUrl], 1032, undefined, 401, res
);
}
}
async function verifyClient(req, res, next) {
if (!req.headers["authorization"] || !req.headers["authorization"].startsWith("bearer eg1~")) return error.createError(
"errors.com.epicgames.common.authorization.authorization_failed",
`Authorization failed for ${req.originalUrl}`,
[req.originalUrl], 1032, undefined, 401, res
);
const token = req.headers["authorization"].split("bearer eg1~")[1];
try {
const decodedToken = jwt.verify(token, global.JWT_SECRET);
if (!global.accessTokens.find(i => i.token == `eg1~${token}`) && !global.clientTokens.find(i => i.token == `eg1~${token}`)) throw new Error("Invalid token.");
if (global.accessTokens.find(i => i.token == `eg1~${token}`)) {
req.user = await User.findOne({ accountId: decodedToken.sub }).lean();
if (req.user.banned == true) return error.createError(
"errors.com.epicgames.account.account_not_active",
"Sorry, your account is inactive and may not login.",
[], -1, undefined, 400, res
);
}
next();
} catch (err) {
if (global.accessTokens.find(i => i.token == `eg1~${token}`)) global.accessTokens.splice(global.accessTokens.findIndex(i => i.token == `eg1~${token}`), 1);
if (global.clientTokens.find(i => i.token == `eg1~${token}`)) global.clientTokens.splice(global.clientTokens.findIndex(i => i.token == `eg1~${token}`), 1);
return error.createError(
"errors.com.epicgames.common.authorization.authorization_failed",
`Authorization failed for ${req.originalUrl}`,
[req.originalUrl], 1032, undefined, 401, res
);
}
}
module.exports = {
verifyToken,
verifyClient
}
+479
View File
@@ -0,0 +1,479 @@
const WebSocket = require("ws").Server;
const XMLBuilder = require("xmlbuilder");
const XMLParser = require("xml-parser");
const express = require("express");
const app = express();
const log = require("../structs/log.js");
const functions = require("../structs/functions.js");
const User = require("../model/user.js");
const Friends = require("../model/friends.js");
const port = 80;
const wss = new WebSocket({ server: app.listen(port, () => log.xmpp(`XMPP started listening on port ${port}`)) });
global.Clients = [];
// multi user chat rooms (global chat/party chat)
global.MUCs = [];
app.get("/", (req, res) => {
res.set("Content-Type", "text/plain");
var data = JSON.stringify({
"Clients": {
"amount": global.Clients.length,
"clients": global.Clients.map(i => i.displayName)
}
}, null, 2);
res.send(data);
})
app.get("/clients", (req, res) => {
res.set("Content-Type", "text/plain");
var data = JSON.stringify({
"amount": global.Clients.length,
"clients": global.Clients.map(i => i.displayName)
}, null, 2);
res.send(data);
})
wss.on('connection', async (ws) => {
var accountId = "";
var displayName = "";
var token = "";
var jid = "";
var resource = "";
var ID = functions.MakeID();
var Authenticated = false;
ws.on('message', async (message) => {
if (Buffer.isBuffer(message)) message = message.toString();
const msg = XMLParser(message);
if (!msg || !msg.root || !msg.root.name) return Error(ws);
switch (msg.root.name) {
case "open":
ws.send(XMLBuilder.create("open")
.attribute("xmlns", "urn:ietf:params:xml:ns:xmpp-framing")
.attribute("from", "prod.ol.epicgames.com")
.attribute("id", ID)
.attribute("version", "1.0")
.attribute("xml:lang", "en").toString())
if (Authenticated == true) {
ws.send(XMLBuilder.create("stream:features").attribute("xmlns:stream", "http://etherx.jabber.org/streams")
.element("ver").attribute("xmlns", "urn:xmpp:features:rosterver").up()
.element("starttls").attribute("xmlns", "urn:ietf:params:xml:ns:xmpp-tls").up()
.element("bind").attribute("xmlns", "urn:ietf:params:xml:ns:xmpp-bind").up()
.element("compression").attribute("xmlns", "http://jabber.org/features/compress")
.element("method", "zlib").up().up()
.element("session").attribute("xmlns", "urn:ietf:params:xml:ns:xmpp-session").up().toString())
} else {
ws.send(XMLBuilder.create("stream:features").attribute("xmlns:stream", "http://etherx.jabber.org/streams")
.element("mechanisms").attribute("xmlns", "urn:ietf:params:xml:ns:xmpp-sasl")
.element("mechanism", "PLAIN").up().up()
.element("ver").attribute("xmlns", "urn:xmpp:features:rosterver").up()
.element("starttls").attribute("xmlns", "urn:ietf:params:xml:ns:xmpp-tls").up()
.element("compression").attribute("xmlns", "http://jabber.org/features/compress")
.element("method", "zlib").up().up()
.element("auth").attribute("xmlns", "http://jabber.org/features/iq-auth").up().toString())
}
break;
case "auth":
if (global.Clients.find(i => i.client == ws) || accountId) return;
if (!msg.root.content) return Error(ws);
if (!functions.DecodeBase64(msg.root.content)) return Error(ws);
if (!functions.DecodeBase64(msg.root.content).includes("\u0000")) return Error(ws);
var decodedBase64 = functions.DecodeBase64(msg.root.content).split("\u0000");
var object = global.accessTokens.find(i => i.token == decodedBase64[2]);
if (!object) return Error(ws);
var user = await User.findOne({ accountId: object.accountId });
if (global.Clients.find(i => i.accountId == user.accountId)) return Error(ws);
accountId = user.accountId;
displayName = user.username;
token = object.token;
if (decodedBase64 && accountId && displayName && token && decodedBase64.length == 3) {
Authenticated = true;
log.xmpp(`An xmpp client with the displayName ${displayName} has logged in.`);
ws.send(XMLBuilder.create("success").attribute("xmlns", "urn:ietf:params:xml:ns:xmpp-sasl").toString());
} else {
return Error(ws);
}
break;
case "iq":
switch (msg.root.attributes.id) {
case "_xmpp_bind1":
if (global.Clients.find(i => i.client == ws) || resource || !accountId) return;
if (!msg.root.children.find(i => i.name == "bind")) return;
if (!msg.root.children.find(i => i.name == "bind").children.find(i => i.name == "resource")) return;
if (!msg.root.children.find(i => i.name == "bind").children.find(i => i.name == "resource").content) return;
resource = msg.root.children.find(i => i.name == "bind").children.find(i => i.name == "resource").content;
jid = `${accountId}@prod.ol.epicgames.com/${resource}`;
ws.send(XMLBuilder.create("iq")
.attribute("to", jid)
.attribute("id", "_xmpp_bind1")
.attribute("xmlns", "jabber:client")
.attribute("type", "result")
.element("bind")
.attribute("xmlns", "urn:ietf:params:xml:ns:xmpp-bind")
.element("jid", jid).up().up().toString())
break;
case "_xmpp_session1":
if (!global.Clients.find(i => i.client == ws)) return Error(ws);
var xml = XMLBuilder.create("iq")
.attribute("to", jid)
.attribute("from", "prod.ol.epicgames.com")
.attribute("id", "_xmpp_session1")
.attribute("xmlns", "jabber:client")
.attribute("type", "result");
ws.send(xml.toString());
await getPresenceFromFriends(ws);
break;
default:
if (!global.Clients.find(i => i.client == ws)) return Error(ws);
var xml = XMLBuilder.create("iq")
.attribute("to", jid)
.attribute("from", "prod.ol.epicgames.com")
.attribute("id", msg.root.attributes.id)
.attribute("xmlns", "jabber:client")
.attribute("type", "result");
ws.send(xml.toString());
}
break;
case "message":
if (!global.Clients.find(i => i.client == ws)) return Error(ws);
if (!msg.root.children.find(i => i.name == "body") || !msg.root.children.find(i => i.name == "body").content) return;
var body = msg.root.children.find(i => i.name == "body").content;
switch (msg.root.attributes.type) {
case "chat":
if (!msg.root.attributes.to) return;
var receiver = global.Clients.find(i => i.jid.split("/")[0] == msg.root.attributes.to);
var sender = global.Clients.find(i => i.client == ws);
if (!receiver || !sender) return;
if (receiver == sender) return;
receiver.client.send(XMLBuilder.create("message")
.attribute("to", receiver.jid)
.attribute("from", sender.jid)
.attribute("xmlns", "jabber:client")
.attribute("type", "chat")
.element("body", body).up().toString())
return;
break;
case "groupchat":
if (!msg.root.attributes.to) return;
var sender = global.Clients.find(i => i.client == ws);
if (!sender) return;
var MUC = global.MUCs.find(i => i.roomName == msg.root.attributes.to.split("@")[0]);
if (!MUC) return;
MUC.members.forEach(member => {
var ClientData = global.Clients.find(i => i.accountId == member.accountId);
if (!ClientData) return;
ClientData.client.send(XMLBuilder.create("message")
.attribute("to", ClientData.jid)
.attribute("from", getMUCmember(MUC.roomName, sender.accountId))
.attribute("xmlns", "jabber:client")
.attribute("type", "groupchat")
.element("body", body).up().toString())
})
return;
break;
}
if (isJSON(body)) {
var object = JSON.parse(body);
if (!object.hasOwnProperty("type") || typeof object.type != "string") return;
if (!msg.root.attributes.to) return;
if (!msg.root.attributes.id) return;
functions.sendXmppMessageToClient(ws, msg, body);
}
break;
case "presence":
if (!global.Clients.find(i => i.client == ws)) return Error(ws);
if (msg.root.attributes.type == "unavailable") {
if (!msg.root.attributes.to) return;
if (msg.root.attributes.to.endsWith("@muc.prod.ol.epicgames.com") || msg.root.attributes.to.split("/")[0].endsWith("@muc.prod.ol.epicgames.com")) {
if (msg.root.attributes.to.toLowerCase().startsWith("party-")) {
var MUC = global.MUCs.find(i => i.roomName == msg.root.attributes.to.split("@")[0]);
if (!MUC) return;
var MUCIndex = global.MUCs.findIndex(i => i.roomName == msg.root.attributes.to.split("@")[0]);
const client = global.Clients.find(i => i.client == ws);
if (global.MUCs[MUCIndex].members.find(i => i.accountId == client.accountId)) {
global.MUCs[MUCIndex].members.splice(global.MUCs[MUCIndex].members.findIndex(i => i.accountId == client.accountId), 1);
}
ws.send(XMLBuilder.create("presence")
.attribute("to", client.jid)
.attribute("from", getMUCmember(global.MUCs[MUCIndex].roomName, client.accountId))
.attribute("xmlns", "jabber:client")
.attribute("type", "unavailable")
.element("x").attribute("xmlns", "http://jabber.org/protocol/muc#user")
.element("item")
.attribute("nick", getMUCmember(global.MUCs[MUCIndex].roomName, client.accountId).replace(`${global.MUCs[MUCIndex].roomName}@muc.prod.ol.epicgames.com/`, ""))
.attribute("jid", client.jid)
.attribute("role", "none").up()
.element("status").attribute("code", "110").up()
.element("status").attribute("code", "100").up()
.element("status").attribute("code", "170").up().up().toString())
return;
}
}
}
if (msg.root.children.find(i => i.name == "x")) {
if (msg.root.children.find(i => i.name == "x").children.find(i => i.name == "history")) {
if (!msg.root.attributes.to) return;
var MUC = global.MUCs.find(i => i.roomName == msg.root.attributes.to.split("@")[0]);
if (!MUC) global.MUCs.push({
"roomName": msg.root.attributes.to.split("@")[0],
"members": [],
});
var MUCIndex = global.MUCs.findIndex(i => i.roomName == msg.root.attributes.to.split("@")[0]);
const client = global.Clients.find(i => i.client == ws);
global.MUCs[MUCIndex].members.push({ accountId: client.accountId });
ws.send(XMLBuilder.create("presence")
.attribute("to", client.jid)
.attribute("from", getMUCmember(global.MUCs[MUCIndex].roomName, client.accountId))
.attribute("xmlns", "jabber:client")
.element("x").attribute("xmlns", "http://jabber.org/protocol/muc#user")
.element("item")
.attribute("nick", getMUCmember(global.MUCs[MUCIndex].roomName, client.accountId).replace(`${global.MUCs[MUCIndex].roomName}@muc.prod.ol.epicgames.com/`, ""))
.attribute("jid", client.jid)
.attribute("role", "participant")
.attribute("affiliation", "none").up()
.element("status").attribute("code", "110").up()
.element("status").attribute("code", "100").up()
.element("status").attribute("code", "170").up()
.element("status").attribute("code", "201").up().up().toString())
global.MUCs[MUCIndex].members.forEach(member => {
var ClientData = global.Clients.find(i => i.accountId == member.accountId);
if (!ClientData) return;
ws.send(XMLBuilder.create("presence")
.attribute("from", getMUCmember(global.MUCs[MUCIndex].roomName, ClientData.accountId))
.attribute("to", client.jid)
.attribute("xmlns", "jabber:client")
.element("x")
.attribute("xmlns", "http://jabber.org/protocol/muc#user")
.element("item")
.attribute("nick", getMUCmember(global.MUCs[MUCIndex].roomName, ClientData.accountId).replace(`${global.MUCs[MUCIndex].roomName}@muc.prod.ol.epicgames.com/`, ""))
.attribute("jid", ClientData.jid)
.attribute("role", "participant")
.attribute("affiliation", "none").up().up().toString())
})
global.MUCs[MUCIndex].members.forEach(member => {
var ClientData = global.Clients.find(i => i.accountId == member.accountId);
if (!ClientData) return;
if (client.accountId.toLowerCase() != ClientData.accountId.toLowerCase()) {
ClientData.client.send(XMLBuilder.create("presence")
.attribute("from", getMUCmember(global.MUCs[MUCIndex].roomName, client.accountId))
.attribute("to", ClientData.jid)
.attribute("xmlns", "jabber:client")
.element("x")
.attribute("xmlns", "http://jabber.org/protocol/muc#user")
.element("item")
.attribute("nick", getMUCmember(global.MUCs[MUCIndex].roomName, client.accountId).replace(`${global.MUCs[MUCIndex].roomName}@muc.prod.ol.epicgames.com/`, ""))
.attribute("jid", client.jid)
.attribute("role", "participant")
.attribute("affiliation", "none").up().up().toString())
}
})
return;
}
}
if (!msg.root.children.find(i => i.name == "status") || !msg.root.children.find(i => i.name == "status").content) return;
if (!isJSON(msg.root.children.find(i => i.name == "status").content)) return;
if (Array.isArray(JSON.parse(msg.root.children.find(i => i.name == "status").content))) return;
var body = msg.root.children.find(i => i.name == "status").content;
var away = false;
if (msg.root.children.find(i => i.name == "show")) away = true;
await updatePresenceForFriends(ws, body, away, false);
functions.getPresenceFromUser(accountId, accountId, false);
break;
}
if (!global.Clients.find(i => i.client == ws)) {
if (accountId && displayName && token && jid && ID && resource && Authenticated == true) {
global.Clients.push({
client: ws,
accountId: accountId,
displayName: displayName,
token: token,
jid: jid,
resource: resource,
lastPresenceUpdate: {
away: false,
status: "{}"
}
});
}
}
})
ws.on('close', () => RemoveClient(ws))
})
function Error(ws) {
ws.send(XMLBuilder.create("close").attribute("xmlns", "urn:ietf:params:xml:ns:xmpp-framing").toString());
ws.close();
}
function RemoveClient(ws) {
var client = global.Clients.find(i => i.client == ws);
if (!client) return;
var ClientStatus = JSON.parse(client.lastPresenceUpdate.status);
var partyId = "";
switch (true) {
case (!ClientStatus.Properties): break;
case (isObject(ClientStatus.Properties)): {
for (var key in ClientStatus.Properties) {
if (key.toLowerCase().startsWith("party")) {
if (ClientStatus.Properties[key] && isObject(ClientStatus.Properties[key])) partyId = ClientStatus.Properties[key].partyId;
}
}
}
}
global.Clients.forEach(ClientData => {
if (client.accountId.toLowerCase() != ClientData.accountId.toLowerCase()) {
ClientData.client.send(XMLBuilder.create("message")
.attribute("id", functions.MakeID().replace(/-/ig, "").toUpperCase())
.attribute("from", client.jid)
.attribute("xmlns", "jabber:client")
.attribute("to", ClientData.jid)
.element("body", JSON.stringify({
"type": "com.epicgames.party.memberexited",
"payload": {
"partyId": partyId,
"memberId": client.accountId,
"wasKicked": false
},
"timestamp": new Date().toISOString()
})).up().toString());
}
});
updatePresenceForFriends(ws, "{}", false, true);
log.xmpp(`An xmpp client with the displayName ${global.Clients.find(i => i.client == ws).displayName} has logged out.`);
global.Clients.splice(global.Clients.findIndex(i => i.client == ws), 1);
}
async function getPresenceFromFriends(ws) {
var SenderData = global.Clients.find(i => i.client == ws);
if (!SenderData) return;
var friends = await Friends.findOne({ accountId: SenderData.accountId });
var accepted = friends.list.accepted;
accepted.forEach(friend => {
var ClientData = global.Clients.find(i => i.accountId == friend.accountId);
if (!ClientData) return;
var xml = XMLBuilder.create("presence")
.attribute("to", SenderData.jid)
.attribute("xmlns", "jabber:client")
.attribute("from", ClientData.jid)
if (ClientData.lastPresenceUpdate.away == true) xml = xml.attribute("type", "available").element("show", "away").up().element("status", ClientData.lastPresenceUpdate.status).up();
else xml = xml.attribute("type", "available").element("status", ClientData.lastPresenceUpdate.status).up();
SenderData.client.send(xml.toString())
})
}
async function updatePresenceForFriends(ws, body, away, offline) {
var SenderData = global.Clients.find(i => i.client == ws);
if (!SenderData) return;
var SenderIndex = global.Clients.findIndex(i => i.client == ws);
global.Clients[SenderIndex].lastPresenceUpdate.away = away;
global.Clients[SenderIndex].lastPresenceUpdate.status = body;
var friends = await Friends.findOne({ accountId: SenderData.accountId });
var accepted = friends.list.accepted;
accepted.forEach(friend => {
var ClientData = global.Clients.find(i => i.accountId == friend.accountId);
if (!ClientData) return;
var xml = XMLBuilder.create("presence")
.attribute("to", ClientData.jid)
.attribute("xmlns", "jabber:client")
.attribute("from", SenderData.jid)
if (offline == true) xml = xml.attribute("type", "unavailable");
else xml = xml.attribute("type", "available")
if (away == true) xml = xml.element("show", "away").up().element("status", body).up();
else xml = xml.element("status", body).up();
ClientData.client.send(xml.toString())
})
}
function getMUCmember(roomName, accountId) {
let client = global.Clients.find(i => i.accountId == accountId);
if (!client) return `${roomName}@muc.prod.ol.epicgames.com`;
return `${roomName}@muc.prod.ol.epicgames.com/${encodeURI(client.displayName)}:${client.accountId}:${client.resource}`
}
function isObject(value) {
if (typeof value == "object" && !Array.isArray(value)) return true;
else return false;
}
function isJSON(str) {
try {
JSON.parse(str)
} catch (err) {
return false;
}
return true;
}