|
|
|
@ -4,6 +4,7 @@ import {
|
|
|
|
|
getGuildVault,
|
|
|
|
|
hasAccessToDojo,
|
|
|
|
|
hasGuildPermission,
|
|
|
|
|
removePigmentsFromGuildMembers,
|
|
|
|
|
scaleRequiredCount
|
|
|
|
|
} from "@/src/services/guildService";
|
|
|
|
|
import { ExportDojoRecipes, IDojoResearch } from "warframe-public-export-plus";
|
|
|
|
@ -28,8 +29,7 @@ export const guildTechController: RequestHandler = async (req, res) => {
|
|
|
|
|
const inventory = await getInventory(accountId);
|
|
|
|
|
const guild = await getGuildForRequestEx(req, inventory);
|
|
|
|
|
const data = JSON.parse(String(req.body)) as TGuildTechRequest;
|
|
|
|
|
const action = data.Action.split(",")[0];
|
|
|
|
|
if (action == "Sync") {
|
|
|
|
|
if (data.Action == "Sync") {
|
|
|
|
|
let needSave = false;
|
|
|
|
|
const techProjects: ITechProjectClient[] = [];
|
|
|
|
|
if (guild.TechProjects) {
|
|
|
|
@ -53,18 +53,18 @@ export const guildTechController: RequestHandler = async (req, res) => {
|
|
|
|
|
await guild.save();
|
|
|
|
|
}
|
|
|
|
|
res.json({ TechProjects: techProjects });
|
|
|
|
|
} else if (action == "Start") {
|
|
|
|
|
} else if (data.Action == "Start") {
|
|
|
|
|
if (!hasAccessToDojo(inventory) || !(await hasGuildPermission(guild, accountId, GuildPermission.Fabricator))) {
|
|
|
|
|
res.status(400).send("-1").end();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const recipe = ExportDojoRecipes.research[data.RecipeType!];
|
|
|
|
|
const recipe = ExportDojoRecipes.research[data.RecipeType];
|
|
|
|
|
guild.TechProjects ??= [];
|
|
|
|
|
if (!guild.TechProjects.find(x => x.ItemType == data.RecipeType)) {
|
|
|
|
|
const techProject =
|
|
|
|
|
guild.TechProjects[
|
|
|
|
|
guild.TechProjects.push({
|
|
|
|
|
ItemType: data.RecipeType!,
|
|
|
|
|
ItemType: data.RecipeType,
|
|
|
|
|
ReqCredits: config.noDojoResearchCosts ? 0 : scaleRequiredCount(recipe.price),
|
|
|
|
|
ReqItems: recipe.ingredients.map(x => ({
|
|
|
|
|
ItemType: x.ItemType,
|
|
|
|
@ -78,14 +78,17 @@ export const guildTechController: RequestHandler = async (req, res) => {
|
|
|
|
|
processFundedProject(guild, techProject, recipe);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (data.RecipeType.substring(0, 39) == "/Lotus/Types/Items/Research/DojoColors/") {
|
|
|
|
|
guild.ActiveDojoColorResearch = data.RecipeType;
|
|
|
|
|
}
|
|
|
|
|
await guild.save();
|
|
|
|
|
res.end();
|
|
|
|
|
} else if (action == "Contribute") {
|
|
|
|
|
} else if (data.Action == "Contribute") {
|
|
|
|
|
if (!hasAccessToDojo(inventory)) {
|
|
|
|
|
res.status(400).send("-1").end();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const contributions = data as IGuildTechContributeFields;
|
|
|
|
|
const contributions = data;
|
|
|
|
|
const techProject = guild.TechProjects!.find(x => x.ItemType == contributions.RecipeType)!;
|
|
|
|
|
|
|
|
|
|
if (contributions.VaultCredits) {
|
|
|
|
@ -136,7 +139,7 @@ export const guildTechController: RequestHandler = async (req, res) => {
|
|
|
|
|
|
|
|
|
|
if (techProject.ReqCredits == 0 && !techProject.ReqItems.find(x => x.ItemCount > 0)) {
|
|
|
|
|
// This research is now fully funded.
|
|
|
|
|
const recipe = ExportDojoRecipes.research[data.RecipeType!];
|
|
|
|
|
const recipe = ExportDojoRecipes.research[data.RecipeType];
|
|
|
|
|
processFundedProject(guild, techProject, recipe);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -146,12 +149,12 @@ export const guildTechController: RequestHandler = async (req, res) => {
|
|
|
|
|
InventoryChanges: inventoryChanges,
|
|
|
|
|
Vault: getGuildVault(guild)
|
|
|
|
|
});
|
|
|
|
|
} else if (action == "Buy") {
|
|
|
|
|
} else if (data.Action.split(",")[0] == "Buy") {
|
|
|
|
|
if (!hasAccessToDojo(inventory) || !(await hasGuildPermission(guild, accountId, GuildPermission.Fabricator))) {
|
|
|
|
|
res.status(400).send("-1").end();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const purchase = data as IGuildTechBuyFields;
|
|
|
|
|
const purchase = data as IGuildTechBuyRequest;
|
|
|
|
|
const quantity = parseInt(data.Action.split(",")[1]);
|
|
|
|
|
const recipeChanges = [
|
|
|
|
|
{
|
|
|
|
@ -173,13 +176,12 @@ export const guildTechController: RequestHandler = async (req, res) => {
|
|
|
|
|
Recipes: recipeChanges
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
} else if (action == "Fabricate") {
|
|
|
|
|
} else if (data.Action == "Fabricate") {
|
|
|
|
|
if (!hasAccessToDojo(inventory) || !(await hasGuildPermission(guild, accountId, GuildPermission.Fabricator))) {
|
|
|
|
|
res.status(400).send("-1").end();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const payload = data as IGuildTechFabricateRequest;
|
|
|
|
|
const recipe = ExportDojoRecipes.fabrications[payload.RecipeType];
|
|
|
|
|
const recipe = ExportDojoRecipes.fabrications[data.RecipeType];
|
|
|
|
|
const inventoryChanges: IInventoryChanges = updateCurrency(inventory, recipe.price, false);
|
|
|
|
|
inventoryChanges.MiscItems = recipe.ingredients.map(x => ({
|
|
|
|
|
ItemType: x.ItemType,
|
|
|
|
@ -190,6 +192,23 @@ export const guildTechController: RequestHandler = async (req, res) => {
|
|
|
|
|
await inventory.save();
|
|
|
|
|
// Not a mistake: This response uses `inventoryChanges` instead of `InventoryChanges`.
|
|
|
|
|
res.json({ inventoryChanges: inventoryChanges });
|
|
|
|
|
} else if (data.Action == "Pause") {
|
|
|
|
|
const project = guild.TechProjects!.find(x => x.ItemType == data.RecipeType)!;
|
|
|
|
|
project.State = -2;
|
|
|
|
|
guild.ActiveDojoColorResearch = "";
|
|
|
|
|
await guild.save();
|
|
|
|
|
await removePigmentsFromGuildMembers(guild._id);
|
|
|
|
|
res.end();
|
|
|
|
|
} else if (data.Action == "Unpause") {
|
|
|
|
|
const project = guild.TechProjects!.find(x => x.ItemType == data.RecipeType)!;
|
|
|
|
|
project.State = 0;
|
|
|
|
|
guild.ActiveDojoColorResearch = data.RecipeType;
|
|
|
|
|
const entry = guild.TechChanges?.find(x => x.details == data.RecipeType);
|
|
|
|
|
if (entry) {
|
|
|
|
|
entry.dateTime = new Date();
|
|
|
|
|
}
|
|
|
|
|
await guild.save();
|
|
|
|
|
res.end();
|
|
|
|
|
} else {
|
|
|
|
|
throw new Error(`unknown guildTech action: ${data.Action}`);
|
|
|
|
|
}
|
|
|
|
@ -233,20 +252,24 @@ const setTechLogState = (
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
type TGuildTechRequest =
|
|
|
|
|
| ({
|
|
|
|
|
Action: string;
|
|
|
|
|
} & Partial<IGuildTechStartFields> &
|
|
|
|
|
Partial<IGuildTechContributeFields>)
|
|
|
|
|
| IGuildTechFabricateRequest;
|
|
|
|
|
| { Action: "Sync" | "SomethingElseThatWeMightNotKnowAbout" }
|
|
|
|
|
| IGuildTechBasicRequest
|
|
|
|
|
| IGuildTechContributeRequest;
|
|
|
|
|
|
|
|
|
|
interface IGuildTechStartFields {
|
|
|
|
|
interface IGuildTechBasicRequest {
|
|
|
|
|
Action: "Start" | "Fabricate" | "Pause" | "Unpause";
|
|
|
|
|
Mode: "Guild";
|
|
|
|
|
RecipeType: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type IGuildTechBuyFields = IGuildTechStartFields;
|
|
|
|
|
interface IGuildTechBuyRequest {
|
|
|
|
|
Action: string;
|
|
|
|
|
Mode: "Guild";
|
|
|
|
|
RecipeType: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface IGuildTechContributeFields {
|
|
|
|
|
interface IGuildTechContributeRequest {
|
|
|
|
|
Action: "Contribute";
|
|
|
|
|
ResearchId: "";
|
|
|
|
|
RecipeType: string;
|
|
|
|
|
RegularCredits: number;
|
|
|
|
@ -254,9 +277,3 @@ interface IGuildTechContributeFields {
|
|
|
|
|
VaultCredits: number;
|
|
|
|
|
VaultMiscItems: IMiscItem[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface IGuildTechFabricateRequest {
|
|
|
|
|
Action: "Fabricate";
|
|
|
|
|
Mode: "Guild";
|
|
|
|
|
RecipeType: string;
|
|
|
|
|
}
|
|
|
|
|