From d3e8098b26c48568c2318990413c3535883e4c4a Mon Sep 17 00:00:00 2001 From: Rage Date: Tue, 7 Jan 2025 06:56:55 -0500 Subject: [PATCH] Updated Weapon Customizer --- .../plugins/Tyfon.WeaponCustomizer.dll | Bin 19968 -> 21504 bytes mods/Weapon Customizer/meta.ini | 4 +- .../mods/tyfon-weaponcustomizer/package.json | 2 +- .../mods/tyfon-weaponcustomizer/src/mod.ts | 45 +++++++- .../plugins/Tyfon.WeaponCustomizer.dll | Bin 0 -> 19968 bytes mods/Weapon Customizer_backup/meta.ini | 28 +++++ .../mods/tyfon-weaponcustomizer/package.json | 33 ++++++ .../mods/tyfon-weaponcustomizer/src/mod.ts | 100 ++++++++++++++++++ profiles/Multiplayer/modlist.txt | 1 - 9 files changed, 208 insertions(+), 5 deletions(-) create mode 100644 mods/Weapon Customizer_backup/BepInEx/plugins/Tyfon.WeaponCustomizer.dll create mode 100644 mods/Weapon Customizer_backup/meta.ini create mode 100644 mods/Weapon Customizer_backup/user/mods/tyfon-weaponcustomizer/package.json create mode 100644 mods/Weapon Customizer_backup/user/mods/tyfon-weaponcustomizer/src/mod.ts diff --git a/mods/Weapon Customizer/BepInEx/plugins/Tyfon.WeaponCustomizer.dll b/mods/Weapon Customizer/BepInEx/plugins/Tyfon.WeaponCustomizer.dll index 53b0bb26ce3caf7969ceeb4b92608f413193de13..a68b30f4b4670db49358c0142ee998cf290542a0 100644 GIT binary patch delta 10490 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 VenA8;^8TITzsv;tiP%%;|NqemK;{4d delta 9070 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 -class WeaponCustomizer implements IPreSptLoadMod { +class WeaponCustomizer implements IPreSptLoadMod, IPostSptLoadMod { private logger: ILogger; private vfs: VFS; + private profileHelper: ProfileHelper; private customizations: Customizations = null; private filepath: string; public preSptLoad(container: DependencyContainer): void { this.logger = container.resolve("PrimaryLogger"); this.vfs = container.resolve("VFS"); + const staticRouterModService = container.resolve("StaticRouterModService"); this.filepath = path.resolve(__dirname, "../customizations.json"); @@ -56,6 +60,11 @@ class WeaponCustomizer implements IPreSptLoadMod { ); } + public postSptLoad(container: DependencyContainer): void { + this.profileHelper = container.resolve("ProfileHelper"); + this.clean(); + } + private async saveCustomization(payload: CustomizePayload): Promise { //this.logger.info(`WeaponCustomizer: Saving customization for weapon ${payload.weaponId}`); if (Object.keys(payload.slots).length === 0) { @@ -64,6 +73,7 @@ class WeaponCustomizer implements IPreSptLoadMod { this.customizations[payload.weaponId] = payload.slots; } await this.save(); + return JSON.stringify({ success: true }); } @@ -88,6 +98,39 @@ class WeaponCustomizer implements IPreSptLoadMod { } } + // Remove any customizations for items that no longer exist + private async clean() { + const map = new Map(); + for (const weaponId of Object.keys(this.customizations)) { + map.set(weaponId, false); + } + + for (const profile of Object.values(this.profileHelper.getProfiles())) { + for (const item of profile.characters.pmc.Inventory.items) { + if (map.has(item._id)) { + map.set(item._id, true); + } + } + } + + let dirtyCount = 0; + for (const [weaponId, found] of Object.entries(map)) { + if (!found) { + delete this.customizations[weaponId]; + dirtyCount++; + } + } + + if (dirtyCount > 0) { + this.logger.logWithColor( + `WeaponCustomizer: Cleaned up ${dirtyCount} customizations for weapons that no longer exist`, + LogTextColor.CYAN + ); + + await this.save(); + } + } + private async save() { try { await this.vfs.writeFileAsync(this.filepath, JSON.stringify(this.customizations, null, 2)); diff --git a/mods/Weapon Customizer_backup/BepInEx/plugins/Tyfon.WeaponCustomizer.dll b/mods/Weapon Customizer_backup/BepInEx/plugins/Tyfon.WeaponCustomizer.dll new file mode 100644 index 0000000000000000000000000000000000000000..53b0bb26ce3caf7969ceeb4b92608f413193de13 GIT binary patch literal 19968 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 rEI$gl6f7HoFQZ{a1=e_#LqS>XQwN%5ps literal 0 HcmV?d00001 diff --git a/mods/Weapon Customizer_backup/meta.ini b/mods/Weapon Customizer_backup/meta.ini new file mode 100644 index 0000000..0ca81db --- /dev/null +++ b/mods/Weapon Customizer_backup/meta.ini @@ -0,0 +1,28 @@ +[General] +gameName=spt +modid=0 +version=d2025.1.6.0 +newestVersion= +category="2," +nexusFileStatus=1 +installationFile=Tyfon-WeaponCustomizer-1.0.0.zip +repository=Nexus +ignoredVersion= +comments= +notes= +nexusDescription= +url= +hasCustomURL=false +lastNexusQuery= +lastNexusUpdate= +nexusLastModified=2025-01-07T00:12:11Z +nexusCategory=0 +converted=false +validated=false +color=@Variant(\0\0\0\x43\0\xff\xff\0\0\0\0\0\0\0\0) +tracked=0 + +[installedFiles] +1\modid=0 +1\fileid=0 +size=1 diff --git a/mods/Weapon Customizer_backup/user/mods/tyfon-weaponcustomizer/package.json b/mods/Weapon Customizer_backup/user/mods/tyfon-weaponcustomizer/package.json new file mode 100644 index 0000000..ea0ce22 --- /dev/null +++ b/mods/Weapon Customizer_backup/user/mods/tyfon-weaponcustomizer/package.json @@ -0,0 +1,33 @@ +{ + "name": "weapon-customizer", + "version": "1.0.0", + "main": "src/mod.js", + "license": "MIT", + "author": "Tyfon", + "sptVersion": "~3.10", + "loadBefore": [], + "loadAfter": [], + "incompatibilities": [], + "contributors": [], + "isBundleMod": false, + "scripts": { + "setup": "npm i", + "build": "node ./build.mjs", + "buildinfo": "node ./build.mjs --verbose" + }, + "devDependencies": { + "@types/node": "20.11", + "@typescript-eslint/eslint-plugin": "7.2", + "@typescript-eslint/parser": "7.2", + "archiver": "^6.0", + "eslint": "8.57", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.1.3", + "fs-extra": "11.2", + "ignore": "^5.2", + "os": "^0.1", + "tsyringe": "4.8.0", + "typescript": "5.4", + "winston": "3.12" + } +} diff --git a/mods/Weapon Customizer_backup/user/mods/tyfon-weaponcustomizer/src/mod.ts b/mods/Weapon Customizer_backup/user/mods/tyfon-weaponcustomizer/src/mod.ts new file mode 100644 index 0000000..4c996e0 --- /dev/null +++ b/mods/Weapon Customizer_backup/user/mods/tyfon-weaponcustomizer/src/mod.ts @@ -0,0 +1,100 @@ +import type { DependencyContainer } from "tsyringe"; + +import type { IPreSptLoadMod } from "@spt/models/external/IPreSptLoadMod"; +import { LogTextColor } from "@spt/models/spt/logging/LogTextColor"; +import type { ILogger } from "@spt/models/spt/utils/ILogger"; +import type { StaticRouterModService } from "@spt/services/mod/staticRouter/StaticRouterModService"; +import { VFS } from "@spt/utils/VFS"; +import fs from "node:fs"; +import path from "node:path"; + +type Vector3 = { + x: number; + y: number; + z: number; +}; + +type CustomPosition = { + original: Vector3; + modified: Vector3; +}; + +type CustomizePayload = { + weaponId: string; + slots: Record; +}; + +type Customizations = Record>; + +class WeaponCustomizer implements IPreSptLoadMod { + private logger: ILogger; + private vfs: VFS; + private customizations: Customizations = null; + private filepath: string; + + public preSptLoad(container: DependencyContainer): void { + this.logger = container.resolve("PrimaryLogger"); + this.vfs = container.resolve("VFS"); + const staticRouterModService = container.resolve("StaticRouterModService"); + + this.filepath = path.resolve(__dirname, "../customizations.json"); + this.load(); + + staticRouterModService.registerStaticRouter( + "WeaponCustomizerRoutes", + [ + { + url: "/weaponcustomizer/save", + action: async (url, info: CustomizePayload, sessionId, output) => this.saveCustomization(info) + }, + { + url: "/weaponcustomizer/load", + action: async (url, info, sessionId, output) => JSON.stringify(this.customizations) + } + ], + "custom-static-weapon-customizer" + ); + } + + private async saveCustomization(payload: CustomizePayload): Promise { + //this.logger.info(`WeaponCustomizer: Saving customization for weapon ${payload.weaponId}`); + if (Object.keys(payload.slots).length === 0) { + delete this.customizations[payload.weaponId]; + } else { + this.customizations[payload.weaponId] = payload.slots; + } + await this.save(); + return JSON.stringify({ success: true }); + } + + private load() { + try { + if (this.vfs.exists(this.filepath)) { + this.customizations = JSON.parse(this.vfs.readFile(this.filepath)); + } else { + this.customizations = {}; + + // Create the file with fs - vfs.writeFile pukes on windows paths if it needs to create the file + fs.writeFileSync(this.filepath, JSON.stringify(this.customizations)); + } + + const count = Object.keys(this.customizations).length; + if (count > 0) { + this.logger.logWithColor(`WeaponCustomizer: ${count} weapon customizations loaded.`, LogTextColor.CYAN); + } + } catch (error) { + this.logger.error("WeaponCustomizer: Failed to load weapon customization! " + error); + this.customizations = {}; + } + } + + private async save() { + try { + await this.vfs.writeFileAsync(this.filepath, JSON.stringify(this.customizations, null, 2)); + } catch (error) { + this.logger.error("WeaponCustomizer: Failed to save weapon customization! " + error); + } + } +} + +export const mod = new WeaponCustomizer(); diff --git a/profiles/Multiplayer/modlist.txt b/profiles/Multiplayer/modlist.txt index 70744e5..6163cc2 100644 --- a/profiles/Multiplayer/modlist.txt +++ b/profiles/Multiplayer/modlist.txt @@ -1,4 +1,3 @@ -# This file was automatically generated by Mod Organizer. -Unsorted_separator -Visceral Combat -SWAG + DONUTS