forked from OpenWF/SpaceNinjaServer
		
	feat(webui): add "add missing warframes" & "add missing weapons" (#775)
This commit is contained in:
		
							parent
							
								
									eab4eb2e5b
								
							
						
					
					
						commit
						215b83974c
					
				@ -1,33 +0,0 @@
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { ItemType, toAddItemRequest } from "@/src/helpers/customHelpers/addItemHelpers";
 | 
			
		||||
import { getWeaponType } from "@/src/services/itemDataService";
 | 
			
		||||
import { addPowerSuit, addEquipment, getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
 | 
			
		||||
const addItemController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
    const request = toAddItemRequest(req.body);
 | 
			
		||||
 | 
			
		||||
    switch (request.type) {
 | 
			
		||||
        case ItemType.Powersuit: {
 | 
			
		||||
            const inventory = await getInventory(accountId);
 | 
			
		||||
            const inventoryChanges = addPowerSuit(inventory, request.InternalName);
 | 
			
		||||
            await inventory.save();
 | 
			
		||||
            res.json(inventoryChanges);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        case ItemType.Weapon: {
 | 
			
		||||
            const inventory = await getInventory(accountId);
 | 
			
		||||
            const weaponType = getWeaponType(request.InternalName);
 | 
			
		||||
            const inventoryChanges = addEquipment(inventory, weaponType, request.InternalName);
 | 
			
		||||
            await inventory.save();
 | 
			
		||||
            res.json(inventoryChanges);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        default:
 | 
			
		||||
            res.status(400).json({ error: "something went wrong" });
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export { addItemController };
 | 
			
		||||
							
								
								
									
										33
									
								
								src/controllers/custom/addItemsController.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/controllers/custom/addItemsController.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { getWeaponType } from "@/src/services/itemDataService";
 | 
			
		||||
import { addPowerSuit, addEquipment, getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
 | 
			
		||||
export const addItemsController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
    const requests = req.body as IAddItemRequest[];
 | 
			
		||||
    const inventory = await getInventory(accountId);
 | 
			
		||||
    for (const request of requests) {
 | 
			
		||||
        switch (request.type) {
 | 
			
		||||
            case ItemType.Powersuit:
 | 
			
		||||
                addPowerSuit(inventory, request.internalName);
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case ItemType.Weapon:
 | 
			
		||||
                addEquipment(inventory, getWeaponType(request.internalName), request.internalName);
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    await inventory.save();
 | 
			
		||||
    res.end();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum ItemType {
 | 
			
		||||
    Powersuit = "Powersuit",
 | 
			
		||||
    Weapon = "Weapon"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface IAddItemRequest {
 | 
			
		||||
    type: ItemType;
 | 
			
		||||
    internalName: string;
 | 
			
		||||
}
 | 
			
		||||
@ -1,46 +0,0 @@
 | 
			
		||||
import { isString } from "@/src/helpers/general";
 | 
			
		||||
 | 
			
		||||
export enum ItemType {
 | 
			
		||||
    Powersuit = "Powersuit",
 | 
			
		||||
    Weapon = "Weapon"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const isItemType = (itemType: string): itemType is ItemType => {
 | 
			
		||||
    return Object.keys(ItemType).includes(itemType);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const parseItemType = (itemType: unknown): ItemType => {
 | 
			
		||||
    if (!itemType || !isString(itemType) || !isItemType(itemType)) {
 | 
			
		||||
        throw new Error("incorrect item type");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return itemType;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface IAddItemRequest {
 | 
			
		||||
    type: ItemType;
 | 
			
		||||
    InternalName: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const parseInternalItemName = (internalName: unknown): string => {
 | 
			
		||||
    if (!isString(internalName)) {
 | 
			
		||||
        throw new Error("incorrect internal name");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return internalName;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const toAddItemRequest = (body: unknown): IAddItemRequest => {
 | 
			
		||||
    if (!body || typeof body !== "object") {
 | 
			
		||||
        throw new Error("incorrect or missing add item request data");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ("type" in body && "internalName" in body) {
 | 
			
		||||
        return {
 | 
			
		||||
            type: parseItemType(body.type),
 | 
			
		||||
            InternalName: parseInternalItemName(body.internalName)
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    throw new Error("malformed add item request");
 | 
			
		||||
};
 | 
			
		||||
@ -8,7 +8,7 @@ import { deleteAccountController } from "@/src/controllers/custom/deleteAccountC
 | 
			
		||||
import { renameAccountController } from "@/src/controllers/custom/renameAccountController";
 | 
			
		||||
 | 
			
		||||
import { createAccountController } from "@/src/controllers/custom/createAccountController";
 | 
			
		||||
import { addItemController } from "@/src/controllers/custom/addItemController";
 | 
			
		||||
import { addItemsController } from "@/src/controllers/custom/addItemsController";
 | 
			
		||||
 | 
			
		||||
import { getConfigDataController } from "@/src/controllers/custom/getConfigDataController";
 | 
			
		||||
import { updateConfigDataController } from "@/src/controllers/custom/updateConfigDataController";
 | 
			
		||||
@ -23,7 +23,7 @@ customRouter.get("/deleteAccount", deleteAccountController);
 | 
			
		||||
customRouter.get("/renameAccount", renameAccountController);
 | 
			
		||||
 | 
			
		||||
customRouter.post("/createAccount", createAccountController);
 | 
			
		||||
customRouter.post("/addItem", addItemController);
 | 
			
		||||
customRouter.post("/addItems", addItemsController);
 | 
			
		||||
 | 
			
		||||
customRouter.get("/config", getConfigDataController);
 | 
			
		||||
customRouter.post("/config", updateConfigDataController);
 | 
			
		||||
 | 
			
		||||
@ -82,11 +82,11 @@
 | 
			
		||||
                </form>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div data-route="/webui/inventory" data-title="Inventory | OpenWF WebUI">
 | 
			
		||||
                <p class="mb-4">
 | 
			
		||||
                <p class="mb-3">
 | 
			
		||||
                    Note: Changes made here will only be reflected in-game when the game re-downloads your
 | 
			
		||||
                    inventory. Visiting the navigation should be the easiest way to trigger that.
 | 
			
		||||
                </p>
 | 
			
		||||
                <div class="card mb-4">
 | 
			
		||||
                <div class="card mb-3">
 | 
			
		||||
                    <h5 class="card-header">Add Items</h5>
 | 
			
		||||
                    <form class="card-body input-group" onsubmit="doAcquireMiscItems();return false;">
 | 
			
		||||
                        <input class="form-control" id="miscitem-count" type="number" min="1" value="1" />
 | 
			
		||||
@ -94,9 +94,9 @@
 | 
			
		||||
                        <button class="btn btn-primary" type="submit">Add</button>
 | 
			
		||||
                    </form>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row">
 | 
			
		||||
                <div class="row g-3">
 | 
			
		||||
                    <div class="col-lg-6">
 | 
			
		||||
                        <div class="card mb-4">
 | 
			
		||||
                        <div class="card mb-3">
 | 
			
		||||
                            <h5 class="card-header">Warframes</h5>
 | 
			
		||||
                            <div class="card-body">
 | 
			
		||||
                                <form class="input-group mb-3" onsubmit="doAcquireWarframe();return false;">
 | 
			
		||||
@ -108,9 +108,16 @@
 | 
			
		||||
                                </table>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="card mb-3">
 | 
			
		||||
                            <h5 class="card-header">Bulk Actions</h5>
 | 
			
		||||
                            <div class="card-body">
 | 
			
		||||
                                <button class="btn btn-primary" onclick="addMissingWarframes();">Add Missing Warframes</button>
 | 
			
		||||
                                <button class="btn btn-primary" onclick="addMissingWeapons();">Add Missing Weapons</button>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="col-lg-6">
 | 
			
		||||
                        <div class="card mb-4">
 | 
			
		||||
                        <div class="card mb-3">
 | 
			
		||||
                            <h5 class="card-header">Weapons</h5>
 | 
			
		||||
                            <div class="card-body">
 | 
			
		||||
                                <form class="input-group mb-3" onsubmit="doAcquireWeapon();return false;">
 | 
			
		||||
@ -128,7 +135,7 @@
 | 
			
		||||
            <div id="powersuit-route" data-route="~ /webui/powersuit/(.+)" data-title="Inventory | OpenWF WebUI">
 | 
			
		||||
                <h3 class="mb-0"></h3>
 | 
			
		||||
                <p class="text-body-secondary"></p>
 | 
			
		||||
                <div class="card mb-4">
 | 
			
		||||
                <div class="card mb-3">
 | 
			
		||||
                    <h5 class="card-header">Archon Shard Slots</h5>
 | 
			
		||||
                    <div class="card-body">
 | 
			
		||||
                        <p>You can use these unlimited slots to apply a wide range of upgrades.</p>
 | 
			
		||||
@ -145,13 +152,13 @@
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div data-route="/webui/mods" data-title="Mods | OpenWF WebUI">
 | 
			
		||||
                <p class="mb-4">
 | 
			
		||||
                <p class="mb-3">
 | 
			
		||||
                    Note: Changes made here will only be reflected in-game when the game re-downloads your
 | 
			
		||||
                    inventory. Visiting the navigation should be the easiest way to trigger that.
 | 
			
		||||
                </p>
 | 
			
		||||
                <div class="row">
 | 
			
		||||
                <div class="row g-3">
 | 
			
		||||
                    <div class="col-xxl-6">
 | 
			
		||||
                        <div class="card mb-4">
 | 
			
		||||
                        <div class="card mb-3">
 | 
			
		||||
                            <h5 class="card-header">Add Riven</h5>
 | 
			
		||||
                            <form class="card-body" onsubmit="doAcquireRiven();return false;">
 | 
			
		||||
                                <select class="form-control mb-3" id="addriven-type">
 | 
			
		||||
@ -168,7 +175,7 @@
 | 
			
		||||
                                <a href="riven-tool/" target="_blank">Need help with the fingerprint?</a>
 | 
			
		||||
                            </form>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="card mb-4">
 | 
			
		||||
                        <div class="card mb-3">
 | 
			
		||||
                            <h5 class="card-header">Rivens</h5>
 | 
			
		||||
                            <div class="card-body">
 | 
			
		||||
                                <table class="table table-hover w-100">
 | 
			
		||||
@ -178,7 +185,7 @@
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="col-xxl-6">
 | 
			
		||||
                        <div class="card mb-4">
 | 
			
		||||
                        <div class="card mb-3">
 | 
			
		||||
                            <h5 class="card-header">Mods</h5>
 | 
			
		||||
                            <div class="card-body">
 | 
			
		||||
                                <form class="input-group mb-3" onsubmit="doAcquireMod();return false;">
 | 
			
		||||
@ -194,9 +201,9 @@
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div data-route="/webui/cheats, /webui/settings" data-title="Cheats | OpenWF WebUI">
 | 
			
		||||
                <div class="row">
 | 
			
		||||
                <div class="row g-3">
 | 
			
		||||
                    <div class="col-lg-4">
 | 
			
		||||
                        <div class="card mb-4">
 | 
			
		||||
                        <div class="card mb-3">
 | 
			
		||||
                            <h5 class="card-header">Server</h5>
 | 
			
		||||
                            <div class="card-body">
 | 
			
		||||
                                <div id="server-settings-no-perms" class="d-none">
 | 
			
		||||
@ -283,7 +290,7 @@
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="col-lg-4">
 | 
			
		||||
                        <div class="card mb-4">
 | 
			
		||||
                        <div class="card mb-3">
 | 
			
		||||
                            <h5 class="card-header">Account</h5>
 | 
			
		||||
                            <div class="card-body">
 | 
			
		||||
                                <p><button class="btn btn-primary" onclick="doUnlockAllFocusSchools();">Unlock All Focus Schools</button></p>
 | 
			
		||||
@ -292,7 +299,7 @@
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="col-lg-4">
 | 
			
		||||
                        <div class="card mb-4">
 | 
			
		||||
                        <div class="card mb-3">
 | 
			
		||||
                            <h5 class="card-header">Client</h5>
 | 
			
		||||
                            <div id="client-cheats-nok" class="card-body">
 | 
			
		||||
                                Client cheats are currently unavailable. This could be because your client is not running or using a DLL without an HTTP interface.
 | 
			
		||||
 | 
			
		||||
@ -190,6 +190,7 @@ function updateInventory() {
 | 
			
		||||
            document.getElementById("warframe-list").innerHTML = "";
 | 
			
		||||
            data.Suits.forEach(item => {
 | 
			
		||||
                const tr = document.createElement("tr");
 | 
			
		||||
                tr.setAttribute("data-item-type", item.ItemType);
 | 
			
		||||
                {
 | 
			
		||||
                    const td = document.createElement("td");
 | 
			
		||||
                    td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType;
 | 
			
		||||
@ -267,6 +268,7 @@ function updateInventory() {
 | 
			
		||||
            ["LongGuns", "Pistols", "Melee"].forEach(category => {
 | 
			
		||||
                data[category].forEach(item => {
 | 
			
		||||
                    const tr = document.createElement("tr");
 | 
			
		||||
                    tr.setAttribute("data-item-type", item.ItemType);
 | 
			
		||||
                    {
 | 
			
		||||
                        const td = document.createElement("td");
 | 
			
		||||
                        td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType;
 | 
			
		||||
@ -527,12 +529,14 @@ function doAcquireWarframe() {
 | 
			
		||||
    }
 | 
			
		||||
    revalidateAuthz(() => {
 | 
			
		||||
        const req = $.post({
 | 
			
		||||
            url: "/custom/addItem?" + window.authz,
 | 
			
		||||
            url: "/custom/addItems?" + window.authz,
 | 
			
		||||
            contentType: "application/json",
 | 
			
		||||
            data: JSON.stringify({
 | 
			
		||||
            data: JSON.stringify([
 | 
			
		||||
                {
 | 
			
		||||
                    type: "Powersuit",
 | 
			
		||||
                    internalName: uniqueName
 | 
			
		||||
            })
 | 
			
		||||
                }
 | 
			
		||||
            ])
 | 
			
		||||
        });
 | 
			
		||||
        req.done(() => {
 | 
			
		||||
            document.getElementById("warframe-to-acquire").value = "";
 | 
			
		||||
@ -553,12 +557,14 @@ function doAcquireWeapon() {
 | 
			
		||||
    }
 | 
			
		||||
    revalidateAuthz(() => {
 | 
			
		||||
        const req = $.post({
 | 
			
		||||
            url: "/custom/addItem?" + window.authz,
 | 
			
		||||
            url: "/custom/addItems?" + window.authz,
 | 
			
		||||
            contentType: "application/json",
 | 
			
		||||
            data: JSON.stringify({
 | 
			
		||||
            data: JSON.stringify([
 | 
			
		||||
                {
 | 
			
		||||
                    type: "Weapon",
 | 
			
		||||
                    internalName: uniqueName
 | 
			
		||||
            })
 | 
			
		||||
                }
 | 
			
		||||
            ])
 | 
			
		||||
        });
 | 
			
		||||
        req.done(() => {
 | 
			
		||||
            document.getElementById("weapon-to-acquire").value = "";
 | 
			
		||||
@ -571,6 +577,49 @@ $("#weapon-to-acquire").on("input", () => {
 | 
			
		||||
    $("#weapon-to-acquire").removeClass("is-invalid");
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function dispatchAddItemsRequestsBatch(requests) {
 | 
			
		||||
    revalidateAuthz(() => {
 | 
			
		||||
        const req = $.post({
 | 
			
		||||
            url: "/custom/addItems?" + window.authz,
 | 
			
		||||
            contentType: "application/json",
 | 
			
		||||
            data: JSON.stringify(requests)
 | 
			
		||||
        });
 | 
			
		||||
        req.done(() => {
 | 
			
		||||
            updateInventory();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function addMissingWarframes() {
 | 
			
		||||
    const requests = [];
 | 
			
		||||
    document.querySelectorAll("#datalist-warframes option").forEach(elm => {
 | 
			
		||||
        if (!document.querySelector("#warframe-list [data-item-type='" + elm.getAttribute("data-key") + "']")) {
 | 
			
		||||
            requests.push({ type: "Powersuit", internalName: elm.getAttribute("data-key") });
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
    if (
 | 
			
		||||
        requests.length != 0 &&
 | 
			
		||||
        window.confirm("Are you sure you want to add " + requests.length + " items to your account?")
 | 
			
		||||
    ) {
 | 
			
		||||
        dispatchAddItemsRequestsBatch(requests);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function addMissingWeapons() {
 | 
			
		||||
    const requests = [];
 | 
			
		||||
    document.querySelectorAll("#datalist-weapons option").forEach(elm => {
 | 
			
		||||
        if (!document.querySelector("#weapon-list [data-item-type='" + elm.getAttribute("data-key") + "']")) {
 | 
			
		||||
            requests.push({ type: "Weapon", internalName: elm.getAttribute("data-key") });
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
    if (
 | 
			
		||||
        requests.length != 0 &&
 | 
			
		||||
        window.confirm("Are you sure you want to add " + requests.length + " items to your account?")
 | 
			
		||||
    ) {
 | 
			
		||||
        dispatchAddItemsRequestsBatch(requests);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function addGearExp(category, oid, xp) {
 | 
			
		||||
    const data = {};
 | 
			
		||||
    data[category] = [
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user