diff --git a/Adventures in Lestoria/InventoryConsumableWindow.cpp b/Adventures in Lestoria/InventoryConsumableWindow.cpp index 264d270b..ddd5dce6 100644 --- a/Adventures in Lestoria/InventoryConsumableWindow.cpp +++ b/Adventures in Lestoria/InventoryConsumableWindow.cpp @@ -92,7 +92,7 @@ void Menu::InitializeConsumableInventoryWindow(){ std::vector>&components=Component(INVENTORY_CONSUMABLES,"inventory")->GetComponents(); auto inventory=Component(INVENTORY_CONSUMABLES,"inventory"); auto foundComponent=std::find_if(components.begin(),components.end(),[&](auto&component){ - if(!ISBLANK(DYNAMIC_POINTER_CAST(component)->GetItem().lock())&&DYNAMIC_POINTER_CAST(component)->GetItem().lock()->ActualName()==game->GetLoadoutItem(Menu::menus[type]->I(A::LOADOUT_SLOT)).lock()->ActualName()){ + if(!ISBLANK(DYNAMIC_POINTER_CAST(component)->GetItem().lock())&&!ISBLANK(game->GetLoadoutItem(Menu::menus[type]->I(A::LOADOUT_SLOT)))&&DYNAMIC_POINTER_CAST(component)->GetItem().lock()->ActualName()==game->GetLoadoutItem(Menu::menus[type]->I(A::LOADOUT_SLOT)).lock()->ActualName()){ return true; } return false; diff --git a/Adventures in Lestoria/LoadGameWindow.cpp b/Adventures in Lestoria/LoadGameWindow.cpp index 861ee849..d5f8d9f3 100644 --- a/Adventures in Lestoria/LoadGameWindow.cpp +++ b/Adventures in Lestoria/LoadGameWindow.cpp @@ -52,8 +52,8 @@ void Menu::InitializeLoadGameWindow(){ loadGameWindow->ADD("Go Back Button",MenuComponent)(geom2d::rect{{72,148},{48,12}},"Back",[](MenuFuncData menu){Menu::CloseMenu();return true;})END; #ifdef __EMSCRIPTEN__ auto offlineCharacterTab = loadGameWindow->ADD("Offline Character Tab",MenuComponent)(geom2d::rect{{-8,4},{102,16}},"Offline Characters",[](MenuFuncData data){ - Component(data.menu.GetType(),"Game Files List")->Enable(true); - Component(data.menu.GetType(),"Online Game Files List")->Enable(false); + Component(data.menu.GetType(),"Game Files List")->Enable(); + Component(data.menu.GetType(),"Online Game Files List")->Disable(); Component(data.menu.GetType(),"Online Character Tab")->SetSelected(false); data.component.lock()->SetSelected(true); SoundEffect::PlaySFX("Button Click",SoundEffect::CENTERED); @@ -63,8 +63,8 @@ void Menu::InitializeLoadGameWindow(){ offlineCharacterTab->SetSelectionType(HIGHLIGHT); offlineCharacterTab->SetSelected(true); auto onlineCharacterTab = loadGameWindow->ADD("Online Character Tab",MenuComponent)(geom2d::rect{{96,4},{102,16}},"Online Characters",[](MenuFuncData data){ - Component(data.menu.GetType(),"Game Files List")->Enable(false); - Component(data.menu.GetType(),"Online Game Files List")->Enable(true); + Component(data.menu.GetType(),"Game Files List")->Disable(); + Component(data.menu.GetType(),"Online Game Files List")->Enable(); Component(data.menu.GetType(),"Offline Character Tab")->SetSelected(false); SoundEffect::PlaySFX("Button Click",SoundEffect::CENTERED); data.component.lock()->SetSelected(true); diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index b40def4f..46946637 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 0 #define VERSION_MINOR 3 #define VERSION_PATCH 0 -#define VERSION_BUILD 7112 +#define VERSION_BUILD 7114 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/backend.js b/Adventures in Lestoria/backend.js index eed9181a..b76cf264 100644 --- a/Adventures in Lestoria/backend.js +++ b/Adventures in Lestoria/backend.js @@ -1,53 +1,568 @@ -app.post("/AiL",function (req, res) { - var username=decodeURI(req.body.username) - var operation=decodeURI(req.body.operation) - var checksum=decodeURI(req.body.checksum) - var data=decodeURI(req.body.data) - const saveDir="files/AiLsaves/"; - if(username&&operation&&checksum&&data){ - if(username.length<=24&& - (operation==="GET_LOAD_FILES"||operation==="GET_FILE"||operation==="SAVE_FILE"||operation==="SAVE_METADATA_FILE")&& - data.length<=1000000&& - Number(checksum)===username.length*8+data.length*2+operation.length){ - //Checksum: Length of username*8+Length of data*2+Length of operation - if(!fs.existsSync(`${saveDir+username}`)){ - fs.mkdirSync(`${saveDir+username}`); - } - switch(operation){ - case "GET_LOAD_FILES":{ - if(fs.existsSync(`${saveDir+username}/metadata.dat`)){ - res.status(200).send(fs.readFileSync(`${saveDir+username}/metadata.dat`)); - }else{ - res.status(404).send("Not Found!"); - } - }break; - case "GET_FILE":{ - if(fs.existsSync(`${saveDir+username}/save.${data.padStart(4,'0')}`)){ - res.status(200).send(fs.readFileSync(`${saveDir+username}/save.${data.padStart(4,'0')}`)); - }else{ - res.status(404).send("Not Found!"); - } - }break; - case "SAVE_FILE":{ - var fileData=data.split("|"); - var fileNumb=fileData[0]; - var saveFileData=fileData[1]; - - fs.writeFileSync(`${saveDir+username}/save.${fileNumb.padStart(4,'0')}`,saveFileData); - res.status(200).send("Saved!"); - }break; - case "SAVE_METADATA_FILE":{ - fs.writeFileSync(`${saveDir+username}/metadata.dat`,data); - res.status(200).send("Saved!"); - }break; - default:{ - res.status(418).send('I\'m definitely a teapot.'); - } - } - }else{ - res.status(418).send('I\'m definitely a teapot.'); - } - }else{ - res.status(400).send('Invalid input!'); - } - }); \ No newline at end of file +const express = require('express') +const axios = require('axios') +var http = require('http'); +var https = require('https'); +const fs = require('fs'); + +const sh = require('secrethash'); + +var key = fs.readFileSync('./projectdivar.com/privkey.pem'); +var cert = fs.readFileSync('./projectdivar.com/cert.pem'); +var options = { + key: key, + cert: cert +}; + +const app = express() + +var server = https.createServer(options, app); +const port = 4505 +server.listen(port, () => console.log(`Example app listening at http://localhost:${port}`)) +const bodyParser = require('body-parser') +const { json } = require('body-parser') +const moment = require('moment'); +const Pool = require('pg').Pool +app.use(bodyParser.json()) +app.use( + bodyParser.urlencoded({ + extended: true, + }) +) + + +let allowCrossDomain = function (req, res, next) { + res.header('Access-Control-Allow-Origin', "*"); + res.header('Access-Control-Allow-Headers', "*"); + res.header('Access-Control-Allow-Methods', "*"); + next(); +} +app.use(allowCrossDomain); + +var db = + new Pool({ + user: 'postgres', + password: '', + host: 'postgres', + database: 'sigcrafting', + port: 5432, + }) + +app.get('/', async (req, res) => { + res.status(200).send('BUN is love, BUN is life.') +}) + +app.get('/getData', (req, res) => { + db.query('select * from crafting_list order by id asc') + .then((data) => { + if (data.rows.length > 0) { + res.status(200).json(data.rows) + } else { + res.status(204).send("No data") + } + }) + .catch((err) => { + res.status(500).send(err.message) + }) +}) + +app.get('/getNotifications', (req, res) => { + db.query('select * from audit_log where date>$1 order by id asc limit 10', [req.query.date]) + .then((data) => { + res.status(200).json(data.rows) + }) + .catch((err) => { + console.log(err) + res.status(500).send(err.message) + }) +}) + +app.get('/lastUpdate', (req, res) => { + db.query("select * from site_data limit 1") + .then((data) => { + res.status(200).json(data.rows) + }) + .catch((err) => { + res.status(500).send(err.message) + }) +}) + +app.post("/updateItem", (req, res) => { + var itemIcon = "" + db.query("update crafting_list set obtained=$1 where id=$2 returning *", [req.body.obtained, req.body.id]) + .then((data) => { + itemIcon = "https://xivapi.com" + data.rows[0].icon + return db.query("update site_data set last_modified=$1", [req.body.last_modified]) + }) + .then((data) => { + return axios.post(process.env.DISCORD_WEBHOOK, { + embeds: [{ + author: { + name: req.body.item_name, + icon_url: itemIcon + }, + color: req.body.obtained == req.body.required ? 32768 : Number(req.body.obtained) > 0 ? 20680 : 2172201, + description: "**" + req.body.username + "** " + (req.body.operation === "FINISH" ? " has finished " + (req.body.finalcraft === true ? "crafting " : "collecting ") + req.body.required + " __" + req.body.item_name + "__!" : + req.body.operation === "INCREASE" ? " has collected " + req.body.obtained + " / " + req.body.required + " __" + req.body.item_name + "__ (+" + (req.body.obtained - req.body.previous_amt) + ")" + : " has set __" + req.body.item_name + "__ to " + req.body.obtained + " / " + req.body.required) + "\n\n[Sig Planner - Sig crafts all the things](http://projectdivar.com:3001)", + footer: { + "text": "Progress: " + ((req.body.itemCount + req.body.obtained - req.body.previous_amt) / req.body.totalItemCount * 100).toFixed(2) + "% (" + (req.body.itemCount + req.body.obtained - req.body.previous_amt) + "/" + req.body.totalItemCount + ")" + } + }] + }) + }) + .then((data) => { + return db.query("insert into audit_log(username,obtained,required,item_name,operation,date,previous_amt) values($1,$2,$3,$4,$5,$6,$7)", [req.body.username, req.body.obtained, req.body.required, req.body.item_name, req.body.operation === "FINISH" && req.body.finalcraft === true ? "FINISH_CRAFT" : req.body.operation, req.body.last_modified, req.body.previous_amt]) + }) + .then((data) => { + res.status(200).send("Yay!") + }) + .catch((err) => { + console.log(err.message) + res.status(500).send(err.message) + }) +}) + +app.post("/updateTimer", (req, res) => { + if (req.body.timer_start !== null && req.body.timer_end !== null && req.body.timer_start !== undefined && req.body.timer_end !== undefined) { + var splitter = req.body.timer_start.split(",") + var splitter2 = req.body.timer_end.split(",") + for (t of splitter) { + if (t == "") continue; + if (t.split(":").length != 2 || (t.split(":").length == 2 && (isNaN(t.split(":")[0]) || isNaN(t.split(":")[1])))) { + res.status(500).send("Invalid input!") + return + } + } + for (t of splitter2) { + if (t == "") continue; + if (t.split(":").length != 2 || (t.split(":").length == 2 && (isNaN(t.split(":")[0]) || isNaN(t.split(":")[1])))) { + console.log(t) + res.status(500).send("Invalid input!") + return + } + } + db.query("update crafting_list set timer_start=$1,timer_end=$2 where id=$3 returning *", [req.body.timer_start, req.body.timer_end, req.body.id]) + .then((data) => { + itemIcon = "https://xivapi.com" + data.rows[0].icon + return db.query("update site_data set last_modified=$1", [req.body.last_modified]) + }) + .then((data) => { + res.status(200).send("Yay!") + }) + .catch((err) => { + console.log(err.message) + res.status(500).send(err.message) + }) + } else { + res.status(500).send("Invalid input!") + } +}) + +app.post('/setItem', async (req, res) => { + await db.query('select * from crafting_list where itemid=$1', [req.body.itemid]) + .then((data) => { + if (data.rows.length == 0) { + db.query('insert into crafting_list(itemid,name,obtained,required,icon) values($1,$2,$3,$4,$5)', [req.body.itemid, req.body.name, req.body.obtained, req.body.required, req.body.icon]) + .then((data) => { + res.status(200).send("Yay!") + }) + .catch((err) => { + res.status(500).send(err.message) + }) + } else { + db.query('update crafting_list set required=$1 where itemid=$2', [Number(data.rows[0].required) + Number(req.body.required), req.body.itemid]) + .then((data) => { + res.status(200).send("Yayay!") + }) + .catch((err) => { + res.status(500).send(err.message) + }) + } + }) +}) + + +app.post('/addItem', async (req, res) => { + await db.query('select * from crafting_list where itemid=$1', [req.body.itemid]) + .then((data) => { + if (data.rows.length > 0) { + db.query('update crafting_list set obtained=$1 where itemid=$2', [Math.min(data.rows[0].required, Number(data.rows[0].obtained) + Number(req.body.obtained)), req.body.itemid]) + .then((data) => { + res.status(200).send("AYAYA") + }) + .catch((err) => { + res.status(500).send(err.message) + }) + } else { + res.status(200).send("Nothing to do!") + } + }) +}) + +function ConvertIssues(str, repoURL) { + str += ' ' //Hack to fix issues with not finding a space after links. + var split = str.split("Issue #"); + for (var i = 0; i < split.length - 1; i++) { + split[i] += "[Issue #" + var spaceLocation = split[i + 1].indexOf(' '); + var spaceSubStr = Number(split[i + 1].substr(0, spaceLocation)); + if (Number.isInteger(spaceSubStr)) { + split[i + 1] = spaceSubStr + "](" + repoURL + "/issues/" + spaceSubStr + ") " + split[i + 1].substr(spaceLocation + 1) + } + } + var split2 = split.join("").split("Issue#") + console.log(split2) + for (var i = 0; i < split2.length - 1; i++) { + split2[i] += "[Issue#" + var spaceLocation = split[i + 1].indexOf(' '); + var spaceSubStr = Number(split[i + 1].substr(0, spaceLocation)); + if (Number.isInteger(spaceSubStr)) { + split[i + 1] = spaceSubStr + "](" + repoURL + "/issues/" + spaceSubStr + ") " + split[i + 1].substr(spaceLocation + 1) + } + } + return split2.join(""); +} + +function ParseMentions(str) { + //@quapsel: 155789951571591168 + //@sigonasr2: 176012829076226048 + return str.replaceAll("@Quapsel", "<@155789951571591168>").replaceAll("@sigonasr2", "<@176012829076226048>") +} + +var embedItems = []; +function ParseAttachments(str) { + var stage = 0; + var backTickRepeatCount = 0; + var backTicksEnabled = false; + var isImage = false; + var accumulatedLink = ""; + for (var i = 0; i < str.length; i++) { + //If at any time we find ```, we continue until they close. + if (str[i] == '`') { + backTickRepeatCount++; + if (backTickRepeatCount == 3) { + backTickRepeatCount = 0; + backTicksEnabled = !backTicksEnabled; + } + continue; + } else { + backTickRepeatCount = 0; + } + if (backTicksEnabled) { + continue; //As long as we are in back tick mode, we don't care what is posted. + } + switch (stage) { + case 0: { + //In stage 0 we look for [. + if (str[i] == '[') { + if (i > 0 && str[i - 1] == '!') { + isImage = true; + } else { + isImage = false; + } + stage++; + } + } break; + case 1: { + //In stage 1 we look for ]. + if (str[i] == ']') { + stage++; + } + } break; + case 2: { + //In stage 2 the next character should be (. If it's not, reset. + if (str[i] == '(') { + stage++; + } else { + stage = 0; + } + } break; + case 3: { + //In stage 3, we accumulate what's inside and look for ). + if (str[i] == ')') { + //We're done! We have a new embed. + if (accumulatedLink.startsWith("http")) { + if (isImage) { + embedItems = [...embedItems, { image: { url: accumulatedLink } }] + } else { + embedItems = [...embedItems, { url: accumulatedLink }] + } + } else { + if (isImage) { + embedItems = [...embedItems, { image: { url: "http://sig.projectdivar.com/" + accumulatedLink } }] + } else { + embedItems = [...embedItems, { url: "http://sig.projectdivar.com/" + accumulatedLink }] + } + } + accumulatedLink = "" + isImage = false; + stage = 0; + break; + } else { + accumulatedLink += str[i]; + } + } break; + } + } + return str +} + +embeds = [] +setInterval(() => { + if (embeds.length > 0) { + axios.post(process.env.GITEA_WEBHOOK, embeds.shift()); + } +}, 1000); + +app.post("/postUpdate", (req, res) => { + res.status(200).send("Thank you!") + embedItems = [] + if (req.body.action) { + switch (req.body.action) { + case "opened": { + embedItems = [{ + author: { + name: "Issue #" + req.body.number + " opened by " + req.body?.issue?.user?.username, + icon_url: req.body.issue.user.avatar_url + }, + color: 11731199, + description: "**" + req.body.issue.title + ":**\n\n" + ConvertIssues(ParseAttachments(ParseMentions(req.body.issue.body)), req.body.repository?.html_url) + "\n\n[Link to Issue](" + req.body.issue?.html_url + ")", + }, ...embedItems]; + embeds.push({ embeds: embedItems }); + } break; + case "reopened": { + embeds.push({ + embeds: [{ + author: { + name: "Issue #" + req.body.number + " re-opened by " + req.body.issue.user.username, + icon_url: req.body.issue.user.avatar_url + }, + color: 13789695, + description: "**" + req.body.issue.title + ":**\n\n" + ConvertIssues(req.body.issue.body, req.body.repository?.html_url) + "\n\n[Link to Issue](" + req.body.issue?.html_url + ")", + }] + }); + } break; + case "assigned": { + var assignedList = "" + for (assignee of req.body.issue.assignees) { + if (assignedList.length == 0) { + assignedList += assignee.username + } else { + assignedList += "," + assignee.username + } + } + embeds.push({ + embeds: [{ + author: { + name: "Assigned users to Issue #" + req.body.number, + icon_url: req.body.issue.user.avatar_url + }, + color: 50363, + description: "Assigned **" + assignedList + "** to Issue **" + req.body.issue.title + "**\n\n[Link to Issue](" + req.body.issue.html_url + ")", + }] + }); + } break; + case "label_updated": { + var labelsList = "" + for (label of req.body.issue.labels) { + if (labelsList.length == 0) { + labelsList += "- **" + label.name + "**" + } else { + labelsList += "\n- **" + label.name + "**" + } + } + embeds.push({ + embeds: [{ + author: { + name: "Assigned labels to Issue #" + req.body.number, + icon_url: req.body.issue.user.avatar_url + }, + color: 365568, + description: "Labels set for Issue **" + req.body.issue.title + "**:\n" + labelsList + "\n\n[Link to Issue](" + req.body.issue.html_url + ")", + }] + }) + } break; + case "created": { + embeds.push({ + embeds: [{ + author: { + name: "Comment posted on Issue #" + req.body.issue.number, + icon_url: req.body.comment.user.avatar_url + }, + color: 11731199, + description: "__**" + req.body.issue.title + "**__\nCommented by **" + req.body.comment.user.username + ":**\n" + ConvertIssues(ParseAttachments(ParseMentions(req.body.comment.body)), req.body.repository.html_url) + "\n\n[Link to Comment](" + req.body.comment.html_url + ")", + }] + }) + } break; + case "edited": { + if (req.body.comment) { + embedItems = [{ + author: { + name: "Comment edited on Issue #" + req.body.issue.number, + icon_url: req.body.comment.user.avatar_url + }, + color: 11731199, + description: "__**" + req.body.issue.title + "**__\nCommented by **" + req.body.comment.user.username + ":**\n" + ConvertIssues(ParseAttachments(ParseMentions(req.body.comment.body)), req.body.repository.html_url) + "\n\n[Link to Comment](" + req.body.comment.html_url + ")", + }, ...embedItems] + embeds.push({ embeds: embedItems }) + } else { + embedItems = [{ + author: { + name: "Edit on Issue #" + req.body.issue.number, + icon_url: req.body.issue.user.avatar_url + }, + color: 11731199, + description: "__**" + req.body.issue.title + "**__\nEdited by **" + req.body.issue.user.username + ":**\n" + ConvertIssues(ParseAttachments(ParseMentions(req.body.issue.body)), req.body.repository.html_url) + "\n\n[Link to Issue](" + req.body.issue.html_url + ")", + }, ...embedItems] + embeds.push({ embeds: embedItems }); + } + } break; + case "deleted": { + embeds.push({ + embeds: [{ + author: { + name: "Comment deleted on Issue #" + req.body.issue.number, + icon_url: req.body.comment.user.avatar_url + }, + color: 11731199, + description: "__**" + req.body.issue.title + "**__\nCommented by **" + req.body.comment.user.username + ":**\n~~" + ConvertIssues(req.body.comment.body, req.body.repository.html_url) + "~~\n\n[Link to Comment](" + req.body.comment.html_url + ")", + }] + }) + } break; + case "closed": { + embeds.push({ + embeds: [{ + author: { + name: "Issue #" + req.body.number + " closed by " + req.body.issue.user.username, + icon_url: req.body.issue.user.avatar_url + }, + color: 9502805, + description: "**" + req.body.issue.title + ":**\n\n" + ConvertIssues(req.body.issue.body, req.body.repository.html_url) + "\n\n[Link to Issue](" + req.body.issue.html_url + ")", + }] + }) + } break; + default: { + console.log("Unknown action " + req.body.action + ". Ignoring.") + } + } + } else + if (req.body.ref) { + for (var commit of req.body.commits) { + var filesAdded = commit.added.length + var filesRemoved = commit.removed.length + var filesModified = commit.modified.length + axios.post(process.env.GITEA_WEBHOOK, { + embeds: [{ + author: { + name: commit.author.username + " has pushed a new commit", + icon_url: "http://sig.projectdivar.com/assets/update.png" + }, + color: 17663, + description: "**Commit ID " + commit.id + "**\n\n" + ConvertIssues(commit.message, req.body.repository.html_url) + "\n" + (filesAdded > 0 ? "\n" + filesAdded + " file" + (filesAdded == 1 ? "" : "s") + " added" : "") + (filesRemoved > 0 ? "\n" + filesRemoved + " file" + (filesRemoved == 1 ? "" : "s") + " removed" : "") + (filesModified > 0 ? "\n" + filesModified + " file" + (filesModified == 1 ? "" : "s") + " modified" : "") + "\n\n[Link to Commit](" + commit.url + ")", + }] + }) + } + } else { + console.log("Unknown webhook incoming. Ignoring.") + } + /* + return axios.post(process.env.DISCORD_WEBHOOK,{embeds:[{ + author:{ + name:req.body.item_name, + icon_url:itemIcon + }, + color:req.body.obtained==req.body.required?32768:Number(req.body.obtained)>0?20680:2172201, + description:"**"+req.body.username+"** "+(req.body.operation==="FINISH"?" has finished "+(req.body.finalcraft===true?"crafting ":"collecting ")+req.body.required+" __"+req.body.item_name+"__!": + req.body.operation==="INCREASE"?" has collected "+req.body.obtained+" / "+req.body.required+" __"+req.body.item_name+"__ (+"+(req.body.obtained-req.body.previous_amt)+")" + :" has set __"+req.body.item_name+"__ to "+req.body.obtained+" / "+req.body.required)+"\n\n[Sig Planner - Sig crafts all the things](http://projectdivar.com:3001)", + footer:{ + "text":"Progress: "+((req.body.itemCount+req.body.obtained-req.body.previous_amt)/req.body.totalItemCount*100).toFixed(2)+"% ("+(req.body.itemCount+req.body.obtained-req.body.previous_amt)+"/"+req.body.totalItemCount+")" + } + }] +})*/ +}) + +var runInventoryScan = async () => { + for (var item of myInv) { + const it = item + await db.query('select * from crafting_list where itemid=$1', [item.itemId]) + .then(async (data) => { + for (var row of data.rows) { + if (row.required - row.obtained <= it.quantity) { + await db.query('update crafting_list set obtained=$1 where itemid=$2', [row.required, it.itemId]) + .catch((err) => { + console.log(err.message) + }) + } else { + await db.query('update crafting_list set obtained=$1 where itemid=$2', [row.obtained + it.quantity, it.itemId]) + .catch((err) => { + console.log(err.message) + }) + break; + } + } + }) + .catch((err) => { + console.log(err.message) + }) + } +} + +app.post("/AiL", function (req, res) { + var username = decodeURI(req.body.username) + var operation = decodeURI(req.body.operation) + var checksum = decodeURI(req.body.checksum) + var data = decodeURI(req.body.data) + const saveDir = "files/AiLsaves/"; + if (username && operation && checksum && data) { + if (username.length <= 24 && + (operation === "GET_LOAD_FILES" || operation === "GET_FILE" || operation === "SAVE_FILE" || operation === "SAVE_METADATA_FILE") && + data.length <= 1000000 && + Number(checksum) === username.length * 8 + data.length * 2 + operation.length) { + //Checksum: Length of username*8+Length of data*2+Length of operation + if (!fs.existsSync(`${saveDir + username}`)) { + fs.mkdirSync(`${saveDir + username}`); + } + switch (operation) { + case "GET_LOAD_FILES": { + if (fs.existsSync(`${saveDir + username}/metadata.dat`)) { + res.status(200).send(fs.readFileSync(`${saveDir + username}/metadata.dat`)); + } else { + fs.writeFileSync(`${saveDir + username}/metadata.dat`, "\n"); + res.status(200).send(fs.readFileSync(`${saveDir + username}/metadata.dat`)); + } + } break; + case "GET_FILE": { + if (fs.existsSync(`${saveDir + username}/save.${data.padStart(4, '0')}`)) { + res.status(200).send(fs.readFileSync(`${saveDir + username}/save.${data.padStart(4, '0')}`)); + } else { + res.status(404).send("Not Found!"); + } + } break; + case "SAVE_FILE": { + var fileData = data.split("|"); + var fileNumb = fileData[0]; + var saveFileData = fileData[1]; + + fs.writeFileSync(`${saveDir + username}/save.${fileNumb.padStart(4, '0')}`, saveFileData); + res.status(200).send("Saved!"); + } break; + case "SAVE_METADATA_FILE": { + fs.writeFileSync(`${saveDir + username}/metadata.dat`, data); + res.status(200).send("Saved!"); + } break; + default: { + res.status(418).send('I\'m definitely a teapot.'); + } + } + } else { + res.status(418).send('I\'m definitely a teapot.'); + } + } else { + res.status(400).send('Invalid input!'); + } +}); + +//runInventoryScan() + +//console.log(process.env.DISCORD_WEBHOOK) \ No newline at end of file diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index b0d23bd4..1673b093 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ