From c7c97e4ae5ef931dc6bc439a9d0b4207bd2e62c2 Mon Sep 17 00:00:00 2001 From: Chase Eller Date: Tue, 24 Mar 2026 21:03:43 -0400 Subject: [PATCH] Dev Update --- CHANGELOG.md | 6 +- README.md | 28 ++- out/extension.js | 9 +- out/extension.js.map | 2 +- out/resourceGenerator.js | 164 +++++++++++++++ out/resourceGenerator.js.map | 1 + out/updater.js | 16 +- out/updater.js.map | 2 +- package.json | 39 +++- src/extension.ts | 10 +- src/resourceGenerator.ts | 189 ++++++++++++++++++ src/updater.ts | 21 +- template/base/Menus/readme.txt | 6 + template/base/client/client.lua | 49 +++++ template/base/fxmanifest.lua | 36 ++++ template/base/server/server.lua | 59 ++++++ template/base/shared/shared.lua | 0 template/withFeature/Menus/readme.txt | 6 + template/withFeature/client/client.lua | 49 +++++ .../withFeature/client/html/loadsplash.css | 57 ++++++ .../withFeature/client/html/loadsplash.html | 41 ++++ .../withFeature/client/html/loadsplash.js | 47 +++++ template/withFeature/client/html/reset.css | 48 +++++ .../client/html/sounds/warning.ogg | Bin 0 -> 13143 bytes template/withFeature/client/nui.lua | 38 ++++ template/withFeature/fxmanifest.lua | 44 ++++ template/withFeature/server/server.lua | 59 ++++++ template/withFeature/shared/shared.lua | 0 28 files changed, 983 insertions(+), 43 deletions(-) create mode 100644 out/resourceGenerator.js create mode 100644 out/resourceGenerator.js.map create mode 100644 src/resourceGenerator.ts create mode 100644 template/base/Menus/readme.txt create mode 100644 template/base/client/client.lua create mode 100644 template/base/fxmanifest.lua create mode 100644 template/base/server/server.lua create mode 100644 template/base/shared/shared.lua create mode 100644 template/withFeature/Menus/readme.txt create mode 100644 template/withFeature/client/client.lua create mode 100644 template/withFeature/client/html/loadsplash.css create mode 100644 template/withFeature/client/html/loadsplash.html create mode 100644 template/withFeature/client/html/loadsplash.js create mode 100644 template/withFeature/client/html/reset.css create mode 100644 template/withFeature/client/html/sounds/warning.ogg create mode 100644 template/withFeature/client/nui.lua create mode 100644 template/withFeature/fxmanifest.lua create mode 100644 template/withFeature/server/server.lua create mode 100644 template/withFeature/shared/shared.lua diff --git a/CHANGELOG.md b/CHANGELOG.md index beae625..9b4c4a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,4 +16,8 @@ I will use this area to keep up with what i did last. ## [Release 1.0.11] -- Removed Debug Data \ No newline at end of file +- Removed Debug Data + +## [Release 1.1.0] + +- Combined the 2 dev tool resources togethter to make one total tool for easier maintaining \ No newline at end of file diff --git a/README.md b/README.md index 76c39db..023e460 100644 --- a/README.md +++ b/README.md @@ -8,5 +8,29 @@ A collection of custom Lua snippets for FiveM development. - Thread templates - Common FiveM utilities -## Usage -Type a snippet prefix and press Ctrl+Space. \ No newline at end of file +## Snippet Usage +Type a snippet prefix and press Ctrl+Space. + +## Resource Generator Usage +This is an ***INTERNAL USE ONLY*** tool for generating a FiveM Resource using our structure that we have outlined during the GCONFIG update. This will produce you a folder with the correct naming schemes, folder structure, and settings to allow for a plug and play experience. Edit what you need to and remove/add anything you need to the provided files. If you have any updates/request for thing in the generator let Chase know so he can get it in a plugin update and get that uploaded to the repository. + +Right click on your resources folder in your explorer window on the left hand side of your screen and select "Generate FiveM Resource From Template" and follow the prompts on the screen and it will create the following folder structure and fill out the fxmanifest.lua with the info provided. + +```markdown +├── RESOURCE CODE +│ ├── fxmanifest.lua +│ ├── initConfig.json +│ ├── SERVER +│ │ ├── server.lua +│ ├── CLIENT +│ │ ├── client.lua +│ ├── MENUS +│ │ ├── readme.txt + +``` + + + +# Disclaimer +Yes you can indeed make a resource folder yourself. Yes this is a fair bit cheating, but this ensure that the files you are starting with are a good foundation to work from and you are less likely to trip and mess up. + diff --git a/out/extension.js b/out/extension.js index 2f506b7..f3faaa4 100644 --- a/out/extension.js +++ b/out/extension.js @@ -39,6 +39,7 @@ exports.activate = activate; exports.deactivate = deactivate; const vscode = __importStar(require("vscode")); const updater_1 = require("./updater"); +const resourceGenerator_1 = require("./resourceGenerator"); // ================= LOGGING SETUP ================= exports.updaterOutput = vscode.window.createOutputChannel("Updater Startup"); function logDebug(...args) { @@ -50,12 +51,14 @@ function logDebug(...args) { exports.updaterOutput.show(true); } function activate(context) { - logDebug("[Extension] Activating extension..."); // test log + logDebug("[Extension] Activating extension..."); // Run automatic updater (0, updater_1.runUpdater)(context); - // Register manual update check command - const disposable = vscode.commands.registerCommand("kj4lxc.cstmgames.fivem_snippets.checkUpdates", () => (0, updater_1.manualUpdateCheck)(context)); + // Register manual update command + const disposable = vscode.commands.registerCommand("kj4lxc.cstmgames.fivem_devtools.autoUpdate", () => (0, updater_1.manualUpdateCheck)(context)); context.subscriptions.push(disposable); + // Register resource generator + (0, resourceGenerator_1.registerResourceGenerator)(context); } function deactivate() { } //# sourceMappingURL=extension.js.map \ No newline at end of file diff --git a/out/extension.js.map b/out/extension.js.map index 1a72900..f969ca0 100644 --- a/out/extension.js.map +++ b/out/extension.js.map @@ -1 +1 @@ -{"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,4BAOC;AAED,4BAYC;AAED,gCAA+B;AA7B/B,+CAAiC;AACjC,uCAA0D;AAE1D,oDAAoD;AACvC,QAAA,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;AAElF,SAAgB,QAAQ,CAAC,GAAG,IAAW;IACnC,MAAM,OAAO,GAAG,IAAI;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SAClE,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,qBAAa,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,oCAAoC;IAC1D,qBAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,SAAgB,QAAQ,CAAC,OAAgC;IACrD,QAAQ,CAAC,qCAAqC,CAAC,CAAC,CAAC,WAAW;IAE5D,wBAAwB;IACxB,IAAA,oBAAU,EAAC,OAAO,CAAC,CAAC;IAEpB,uCAAuC;IACvC,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,eAAe,CAC9C,8CAA8C,EAC9C,GAAG,EAAE,CAAC,IAAA,2BAAiB,EAAC,OAAO,CAAC,CACnC,CAAC;IACF,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAC3C,CAAC;AAED,SAAgB,UAAU,KAAI,CAAC"} \ No newline at end of file +{"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,4BAOC;AAED,4BAeC;AAED,gCAA+B;AAjC/B,+CAAiC;AACjC,uCAA0D;AAC1D,2DAAgE;AAEhE,oDAAoD;AACvC,QAAA,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;AAElF,SAAgB,QAAQ,CAAC,GAAG,IAAW;IACnC,MAAM,OAAO,GAAG,IAAI;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SAClE,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,qBAAa,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,oCAAoC;IAC1D,qBAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,SAAgB,QAAQ,CAAC,OAAgC;IACrD,QAAQ,CAAC,qCAAqC,CAAC,CAAC;IAEhD,wBAAwB;IACxB,IAAA,oBAAU,EAAC,OAAO,CAAC,CAAC;IAEpB,iCAAiC;IACjC,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,eAAe,CAC9C,4CAA4C,EAC5C,GAAG,EAAE,CAAC,IAAA,2BAAiB,EAAC,OAAO,CAAC,CACnC,CAAC;IACF,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAEvC,8BAA8B;IAC9B,IAAA,6CAAyB,EAAC,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,SAAgB,UAAU,KAAI,CAAC"} \ No newline at end of file diff --git a/out/resourceGenerator.js b/out/resourceGenerator.js new file mode 100644 index 0000000..3002557 --- /dev/null +++ b/out/resourceGenerator.js @@ -0,0 +1,164 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.registerResourceGenerator = registerResourceGenerator; +const vscode = __importStar(require("vscode")); +const fs_1 = require("fs"); +const path = __importStar(require("path")); +let extensionTemplatePath = ""; +let includeFeature = false; // ✅ boolean flag +const InputData = { + resourceCode: { + title: "Resource Code", + placeholder: "Used for the folder name: GOD, GSR, SELAPI, ...", + nextInput: "resourceName", + value: "" + }, + resourceName: { + title: "Resource name", + placeholder: "B_Jobs, Phone, esx_garage, ...", + nextInput: "description", + value: "" + }, + description: { + title: "Resource description", + placeholder: "This resource is ...", + nextInput: "", + value: "" + } +}; +const startInput = "resourceCode"; +// ================= ENTRY FUNCTION ================= +function registerResourceGenerator(context) { + extensionTemplatePath = path.join(context.extensionPath, "template"); + const disposable = vscode.commands.registerCommand("kj4lxc.fivem.generate-resource", (uri) => { + loadInputs(uri?.fsPath); + }); + context.subscriptions.push(disposable); +} +// ================= INPUT FLOW ================= +function loadInputs(resourcePath) { + for (const key in InputData) { + const field = InputData[key]; + field.input = vscode.window.createInputBox(); + field.input.title = field.title; + field.input.placeholder = field.placeholder; + field.input.onDidAccept(() => { + if (field.input.value.trim().length > 0) { + field.value = field.input.value; + field.input.hide(); + if (field.nextInput) { + InputData[field.nextInput].input.show(); + } + else { + askIncludeFeature(resourcePath); // ✅ NEW STEP + } + } + else { + vscode.window.showErrorMessage(`You need to complete this input (${field.title}).`); + } + }); + if (key === startInput) { + field.input.show(); + } + } +} +// ================= BOOLEAN PROMPT ================= +async function askIncludeFeature(resourcePath) { + const result = await vscode.window.showQuickPick(["Yes", "No"], { + placeHolder: "Include UI Elements?" + }); + if (!result) { + vscode.window.showWarningMessage("Operation cancelled."); + return; + } + includeFeature = result === "Yes"; + startProcessing(resourcePath); +} +// ================= PROCESSING ================= +function startProcessing(basePath) { + if (!basePath) { + vscode.window.showErrorMessage("No folder selected."); + return; + } + const folder = getGeneratedFolder(""); + const resourcePath = path.join(basePath, InputData.resourceCode.value); + (0, fs_1.mkdirSync)(resourcePath); + writeFolder(resourcePath, folder); + vscode.window.showInformationMessage(`You just created a new FiveM Lua Resource named '${InputData.resourceName.value}'.`); +} +function Folder(url) { + return { + url, + files: {}, + folders: {} + }; +} +// ================= TEMPLATE PARSER ================= +function getGeneratedFolder(url) { + const folder = Folder(url); + // ✅ SWITCH TEMPLATE BASED ON BOOLEAN + const baseTemplatePath = includeFeature + ? path.join(extensionTemplatePath, "withFeature") + : path.join(extensionTemplatePath, "base"); + const files = (0, fs_1.readdirSync)(path.join(baseTemplatePath, url), { + withFileTypes: true + }); + for (const file of files) { + if (file.isDirectory()) { + folder.folders[file.name] = getGeneratedFolder(path.join(url, file.name)); + } + else { + let content = (0, fs_1.readFileSync)(path.join(baseTemplatePath, url, file.name), "utf-8"); + for (const key in InputData) { + content = content.replace(new RegExp(`\\$\\{${key}\\}`, "g"), InputData[key].value); + } + folder.files[file.name] = content; + } + } + return folder; +} +// ================= FILE WRITER ================= +function writeFolder(url, folder) { + for (const key in folder.files) { + (0, fs_1.writeFileSync)(path.join(url, key), folder.files[key], "utf-8"); + } + for (const key in folder.folders) { + const subFolderPath = path.join(url, key); + (0, fs_1.mkdirSync)(subFolderPath); + writeFolder(subFolderPath, folder.folders[key]); + } +} +//# sourceMappingURL=resourceGenerator.js.map \ No newline at end of file diff --git a/out/resourceGenerator.js.map b/out/resourceGenerator.js.map new file mode 100644 index 0000000..5ce359b --- /dev/null +++ b/out/resourceGenerator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"resourceGenerator.js","sourceRoot":"","sources":["../src/resourceGenerator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/out/updater.js b/out/updater.js index dcb5f52..549d884 100644 --- a/out/updater.js +++ b/out/updater.js @@ -46,7 +46,7 @@ const os = __importStar(require("os")); const path = __importStar(require("path")); const node_fetch_1 = __importDefault(require("node-fetch")); // ================= LOGGING SETUP ================= -exports.updaterOutput = vscode.window.createOutputChannel("Updater"); +exports.updaterOutput = vscode.window.createOutputChannel("CSTMGames Updater"); function logDebug(...args) { const message = args .map(a => (typeof a === "object" ? JSON.stringify(a, null, 2) : a)) @@ -156,29 +156,25 @@ async function installVsix(url) { const tmpFile = path.join(os.tmpdir(), "update.vsix"); try { logDebug("[Updater] Downloading VSIX from:", url); - // Fetch the VSIX const res = await (0, node_fetch_1.default)(url); if (!res.ok) throw new Error(`HTTP ${res.status}`); const buffer = Buffer.from(await res.arrayBuffer()); - // Save to temp file fs.writeFileSync(tmpFile, buffer); logDebug("[Updater] VSIX saved to temp file:", tmpFile); - // Install extension from local file await vscode.commands.executeCommand("workbench.extensions.installExtension", vscode.Uri.file(tmpFile)); logDebug("[Updater] Installed VSIX from temp file"); - // Ask user to reload - const reload = await vscode.window.showInformationMessage("Extension updated successfully.", "Reload Now"); - if (reload === "Reload Now") { - await vscode.commands.executeCommand("workbench.action.reloadWindow"); - } + // ✅ Optional short delay (prevents race conditions) + await new Promise(resolve => setTimeout(resolve, 1500)); + vscode.window.showInformationMessage("Extension updated successfully. Reloading..."); + // ✅ AUTO reload VS Code (this restarts extensions) + await vscode.commands.executeCommand("workbench.action.reloadWindow"); } catch (err) { logDebug("[Updater] Install failed:", err); vscode.window.showErrorMessage("Failed to install update."); } finally { - // Clean up temp file try { if (fs.existsSync(tmpFile)) { fs.unlinkSync(tmpFile); diff --git a/out/updater.js.map b/out/updater.js.map index 715ed50..3ec6114 100644 --- a/out/updater.js.map +++ b/out/updater.js.map @@ -1 +1 @@ -{"version":3,"file":"updater.js","sourceRoot":"","sources":["../src/updater.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"updater.js","sourceRoot":"","sources":["../src/updater.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package.json b/package.json index cc533dd..294c88b 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,24 @@ { "name": "cstmgames-fivem-snippets", - "displayName": "CSTMGames FiveM Snippets", - "description": "Snippets for FiveM", - "version": "1.0.11", + "displayName": "CSTMGames FiveM Dev Tools", + "description": "Development tools for FiveM", + "version": "1.1.0", + "author": { + "name": "Chase Eller", + "email": "chase@cstmgames.com", + "url": "https://cstmgames.com" + }, "engines": { "vscode": "^1.110.0" }, "main": "./out/extension.js", "activationEvents": [ - "onStartupFinished", - "onCommand:cstmgames.fivem_snippets.checkUpdates" + "onStartupFinished" ], "icon": "pridelogo.png", + "files": [ + "template/fxmanifest.lua" + ], "repository": { "type": "git", "url": "https://git.cstmgames.dev/CSTMGames/FiveM_Snippets.git" @@ -29,14 +36,26 @@ ], "commands": [ { - "command": "kj4lxc.cstmgames.fivem_snippets.checkUpdates", - "title": "Check for Snippet Updates" + "command": "kj4lxc.cstmgames.fivem_devtools.autoUpdate", + "title": "Check for CSTMDev Tools Updates" + }, + { + "command": "kj4lxc.fivem.generate-resource", + "title": "Generate FiveM Resource" } ], + "menus": { + "explorer/context": [ + { + "when": "explorerResourceIsFolder", + "command": "kj4lxc.fivem.generate-resource" + } + ] + }, "configuration": { - "title": "Snippets Updater", + "title": "CSTMGames FiveM Dev Tools Updater", "properties": { - "cstmgames.fivem_snippets.autoUpdate": { + "cstmgames.fivem_devtools.autoUpdate": { "type": "boolean", "default": true, "description": "Automatically install updates" @@ -53,4 +72,4 @@ "@types/vscode": "^1.110.0", "vscode": "^1.1.37" } -} +} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index c252432..3526b33 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,5 +1,6 @@ import * as vscode from "vscode"; import { runUpdater, manualUpdateCheck } from "./updater"; +import { registerResourceGenerator } from "./resourceGenerator"; // ================= LOGGING SETUP ================= export const updaterOutput = vscode.window.createOutputChannel("Updater Startup"); @@ -14,17 +15,20 @@ export function logDebug(...args: any[]) { } export function activate(context: vscode.ExtensionContext) { - logDebug("[Extension] Activating extension..."); // test log + logDebug("[Extension] Activating extension..."); // Run automatic updater runUpdater(context); - // Register manual update check command + // Register manual update command const disposable = vscode.commands.registerCommand( - "kj4lxc.cstmgames.fivem_snippets.checkUpdates", + "kj4lxc.cstmgames.fivem_devtools.autoUpdate", () => manualUpdateCheck(context) ); context.subscriptions.push(disposable); + + // Register resource generator + registerResourceGenerator(context); } export function deactivate() {} \ No newline at end of file diff --git a/src/resourceGenerator.ts b/src/resourceGenerator.ts new file mode 100644 index 0000000..cc483ad --- /dev/null +++ b/src/resourceGenerator.ts @@ -0,0 +1,189 @@ +import * as vscode from "vscode"; +import { readFileSync, readdirSync, mkdirSync, writeFileSync } from "fs"; +import * as path from "path"; + +let extensionTemplatePath = ""; +let includeFeature = false; // ✅ boolean flag + +// ================= INPUT STRUCTURE ================= +interface InputField { + title: string; + placeholder: string; + nextInput: string; + value: string; + input?: vscode.InputBox; +} + +const InputData: Record = { + resourceCode: { + title: "Resource Code", + placeholder: "Used for the folder name: GOD, GSR, SELAPI, ...", + nextInput: "resourceName", + value: "" + }, + resourceName: { + title: "Resource name", + placeholder: "B_Jobs, Phone, esx_garage, ...", + nextInput: "description", + value: "" + }, + description: { + title: "Resource description", + placeholder: "This resource is ...", + nextInput: "", + value: "" + } +}; + +const startInput = "resourceCode"; + +// ================= ENTRY FUNCTION ================= +export function registerResourceGenerator(context: vscode.ExtensionContext) { + extensionTemplatePath = path.join(context.extensionPath, "template"); + + const disposable = vscode.commands.registerCommand( + "kj4lxc.fivem.generate-resource", + (uri: vscode.Uri) => { + loadInputs(uri?.fsPath); + } + ); + + context.subscriptions.push(disposable); +} + +// ================= INPUT FLOW ================= +function loadInputs(resourcePath?: string) { + for (const key in InputData) { + const field = InputData[key]; + + field.input = vscode.window.createInputBox(); + field.input.title = field.title; + field.input.placeholder = field.placeholder; + + field.input.onDidAccept(() => { + if (field.input!.value.trim().length > 0) { + field.value = field.input!.value; + field.input!.hide(); + + if (field.nextInput) { + InputData[field.nextInput].input!.show(); + } else { + askIncludeFeature(resourcePath); // ✅ NEW STEP + } + } else { + vscode.window.showErrorMessage( + `You need to complete this input (${field.title}).` + ); + } + }); + + if (key === startInput) { + field.input.show(); + } + } +} + +// ================= BOOLEAN PROMPT ================= +async function askIncludeFeature(resourcePath?: string) { + const result = await vscode.window.showQuickPick( + ["Yes", "No"], + { + placeHolder: "Include UI Elements?" + } + ); + + if (!result) { + vscode.window.showWarningMessage("Operation cancelled."); + return; + } + + includeFeature = result === "Yes"; + + startProcessing(resourcePath); +} + +// ================= PROCESSING ================= +function startProcessing(basePath?: string) { + if (!basePath) { + vscode.window.showErrorMessage("No folder selected."); + return; + } + + const folder = getGeneratedFolder(""); + + const resourcePath = path.join(basePath, InputData.resourceCode.value); + + mkdirSync(resourcePath); + writeFolder(resourcePath, folder); + + vscode.window.showInformationMessage( + `You just created a new FiveM Lua Resource named '${InputData.resourceName.value}'.` + ); +} + +// ================= FOLDER STRUCT ================= +interface FolderType { + url: string; + files: Record; + folders: Record; +} + +function Folder(url: string): FolderType { + return { + url, + files: {}, + folders: {} + }; +} + +// ================= TEMPLATE PARSER ================= +function getGeneratedFolder(url: string): FolderType { + const folder = Folder(url); + + // ✅ SWITCH TEMPLATE BASED ON BOOLEAN + const baseTemplatePath = includeFeature + ? path.join(extensionTemplatePath, "withFeature") + : path.join(extensionTemplatePath, "base"); + + const files = readdirSync(path.join(baseTemplatePath, url), { + withFileTypes: true + }); + + for (const file of files) { + if (file.isDirectory()) { + folder.folders[file.name] = getGeneratedFolder( + path.join(url, file.name) + ); + } else { + let content = readFileSync( + path.join(baseTemplatePath, url, file.name), + "utf-8" + ); + + for (const key in InputData) { + content = content.replace( + new RegExp(`\\$\\{${key}\\}`, "g"), + InputData[key].value + ); + } + + folder.files[file.name] = content; + } + } + + return folder; +} + +// ================= FILE WRITER ================= +function writeFolder(url: string, folder: FolderType) { + for (const key in folder.files) { + writeFileSync(path.join(url, key), folder.files[key], "utf-8"); + } + + for (const key in folder.folders) { + const subFolderPath = path.join(url, key); + mkdirSync(subFolderPath); + + writeFolder(subFolderPath, folder.folders[key]); + } +} \ No newline at end of file diff --git a/src/updater.ts b/src/updater.ts index 8dab39b..f4abea1 100644 --- a/src/updater.ts +++ b/src/updater.ts @@ -7,7 +7,7 @@ import fetch from "node-fetch"; // ================= LOGGING SETUP ================= -export const updaterOutput = vscode.window.createOutputChannel("Updater"); +export const updaterOutput = vscode.window.createOutputChannel("CSTMGames Updater"); export function logDebug(...args: any[]) { const message = args @@ -152,38 +152,35 @@ async function installVsix(url: string) { try { logDebug("[Updater] Downloading VSIX from:", url); - // Fetch the VSIX const res = await fetch(url); if (!res.ok) throw new Error(`HTTP ${res.status}`); const buffer = Buffer.from(await res.arrayBuffer()); - // Save to temp file fs.writeFileSync(tmpFile, buffer); logDebug("[Updater] VSIX saved to temp file:", tmpFile); - // Install extension from local file await vscode.commands.executeCommand( "workbench.extensions.installExtension", vscode.Uri.file(tmpFile) ); + logDebug("[Updater] Installed VSIX from temp file"); - // Ask user to reload - const reload = await vscode.window.showInformationMessage( - "Extension updated successfully.", - "Reload Now" + // ✅ Optional short delay (prevents race conditions) + await new Promise(resolve => setTimeout(resolve, 1500)); + + vscode.window.showInformationMessage( + "Extension updated successfully. Reloading..." ); - if (reload === "Reload Now") { - await vscode.commands.executeCommand("workbench.action.reloadWindow"); - } + // ✅ AUTO reload VS Code (this restarts extensions) + await vscode.commands.executeCommand("workbench.action.reloadWindow"); } catch (err) { logDebug("[Updater] Install failed:", err); vscode.window.showErrorMessage("Failed to install update."); } finally { - // Clean up temp file try { if (fs.existsSync(tmpFile)) { fs.unlinkSync(tmpFile); diff --git a/template/base/Menus/readme.txt b/template/base/Menus/readme.txt new file mode 100644 index 0000000..2514bbe --- /dev/null +++ b/template/base/Menus/readme.txt @@ -0,0 +1,6 @@ +If you need to create a menu please add it here in this folder then declare it properly in the fxmanifest. + + +add "menuv" to your dependencies + +add '@menuv/menuv.lua' and 'menu/*.lua' to your client_scripts declaration. \ No newline at end of file diff --git a/template/base/client/client.lua b/template/base/client/client.lua new file mode 100644 index 0000000..3cfa987 --- /dev/null +++ b/template/base/client/client.lua @@ -0,0 +1,49 @@ +--GLOBAL CONSTANTS +local CLASS = "CHANGEME"--This is the name that the logging framework will use to display your logs in the correct manner +local LOG_LEVEL = GetResourceMetadata(GetCurrentResourceName(), "log_level", 0) +local RESOURCE_CODE = GetResourceMetadata(GetCurrentResourceName(), "resource_code", 0) +--LOCAL VARIABLES + + + +--END CONFIG +----------------------------------------------------------------------------------------------- + + + +------------------- +--YOUR CODE HERE--- +--HAPPY CODING!---- +------------------- + + + +------------------------------------------------------------------------------------------------ +--SLF Server Logging Function DO NOT TOUCH unless you know what you are doing + +---Used to send logs to the client console +---@param message any Preformatted message or VARIABLES to be sent to log +---@param logLevel integer Level of log, 1-Error, 2-Warn, 3-Info, 4-Debug +function Log(message, logLevel) + local line = debug.getinfo(2, "l").currentline + local name = debug.getinfo(2, "n").name + if name == "fn" then + name = "Thread" + end + local value = "{"..CLASS.."."..name.."("..line..")} "..message + if logLevel then + if tonumber(LOG_LEVEL) >= logLevel then + exports.SLF:LogToClient(RESOURCE_CODE, logLevel, value) + end + else + exports.SLF:LogToClient(RESOURCE_CODE, 4, value) + Log("Warning line was logged without a level value... Logged it as debug as that is the safest route.", 1) + end +end + +function GetSID(UUID) + Log("Requesting SID for UUID: "..UUID, 4) + local SID = exports.SPH:GetSID(UUID) + Log("Retreived SID: "..SID.." for UUID: "..UUID, 4) + return SID +end diff --git a/template/base/fxmanifest.lua b/template/base/fxmanifest.lua new file mode 100644 index 0000000..c77ae77 --- /dev/null +++ b/template/base/fxmanifest.lua @@ -0,0 +1,36 @@ +fx_version 'adamant' +game 'gta5' +name '${resourceName}' +description '${description}' +author 'CSTMChristina & KJ4LXC' +version '0.0.1' +--this is a working script +resource_code '${resourceCode}' +log_level '4' +bucket_prefix '9' + + +dependencies { + 'SLF', + 'SCF' +} + +files { + 'client/config/*.json' +} + + +-- shared_scripts { +-- 'shared/*.lua' +-- } + +client_scripts { + '@menuv/menuv.lua', + 'menus/*.lua', + 'client/*.lua' +} + +server_scripts { + 'server/*.lua' +} + diff --git a/template/base/server/server.lua b/template/base/server/server.lua new file mode 100644 index 0000000..1b91213 --- /dev/null +++ b/template/base/server/server.lua @@ -0,0 +1,59 @@ +--GLOBAL CONSTANTS +local CLASS = "CHANGEME"--This is the name that the logging framework will use to display your logs in the correct manner +local LOG_LEVEL = GetResourceMetadata(GetCurrentResourceName(), "log_level", 0) +local RESOURCE_CODE = GetResourceMetadata(GetCurrentResourceName(), "resource_code", 0) +--Global Variables +--LOCAL VARIABLES + + +--END CONFIG +----------------------------------------------------------------------------------------------- + + + +------------------- +--YOUR CODE HERE--- +--HAPPY CODING!---- +------------------- + + + +------------------------------------------------------------------------------------------------ +--SLF Server Logging Function DO NOT TOUCH unless you know what you are doing. + +---Used to send logs to the server console +---@param message any Preformatted message or VARIABLES to be sent to log +---@param logLevel integer Level of log, 1-Error, 2-Warn, 3-Info, 4-Debug +function Log(message, logLevel) + local line = debug.getinfo(2, "l").currentline + local name = debug.getinfo(2, "n").name + if name == "fn" then + name = "Thread" + end + local value = "{"..CLASS.."."..name.."("..line..")} "..message + if logLevel then + if tonumber(LOG_LEVEL) >= logLevel then + exports.SLF:LogToServer(RESOURCE_CODE, logLevel, value) + end + else + exports.SLF:LogToServer(RESOURCE_CODE, 4, value) + Log("Warning line was logged without a level value... Logged it as debug as that is the safest route.", 1) + end +end + +function DisLog(message) + local line = debug.getinfo(2, "l").currentline + local name = debug.getinfo(2, "n").name + if name == "fn" then + name = "Thread" + end + local value = "{"..CLASS.."."..name.."("..line..")} "..message + exports.SLF:LogServerToDiscord(RESOURCE_CODE, message) +end + +function GetSID(UUID) + Log("Requesting SID for UUID: "..UUID, 4) + local SID = exports.SPH:GetSID(UUID) + Log("Retreived SID: "..SID.." for UUID: "..UUID, 4) + return SID +end \ No newline at end of file diff --git a/template/base/shared/shared.lua b/template/base/shared/shared.lua new file mode 100644 index 0000000..e69de29 diff --git a/template/withFeature/Menus/readme.txt b/template/withFeature/Menus/readme.txt new file mode 100644 index 0000000..2514bbe --- /dev/null +++ b/template/withFeature/Menus/readme.txt @@ -0,0 +1,6 @@ +If you need to create a menu please add it here in this folder then declare it properly in the fxmanifest. + + +add "menuv" to your dependencies + +add '@menuv/menuv.lua' and 'menu/*.lua' to your client_scripts declaration. \ No newline at end of file diff --git a/template/withFeature/client/client.lua b/template/withFeature/client/client.lua new file mode 100644 index 0000000..3cfa987 --- /dev/null +++ b/template/withFeature/client/client.lua @@ -0,0 +1,49 @@ +--GLOBAL CONSTANTS +local CLASS = "CHANGEME"--This is the name that the logging framework will use to display your logs in the correct manner +local LOG_LEVEL = GetResourceMetadata(GetCurrentResourceName(), "log_level", 0) +local RESOURCE_CODE = GetResourceMetadata(GetCurrentResourceName(), "resource_code", 0) +--LOCAL VARIABLES + + + +--END CONFIG +----------------------------------------------------------------------------------------------- + + + +------------------- +--YOUR CODE HERE--- +--HAPPY CODING!---- +------------------- + + + +------------------------------------------------------------------------------------------------ +--SLF Server Logging Function DO NOT TOUCH unless you know what you are doing + +---Used to send logs to the client console +---@param message any Preformatted message or VARIABLES to be sent to log +---@param logLevel integer Level of log, 1-Error, 2-Warn, 3-Info, 4-Debug +function Log(message, logLevel) + local line = debug.getinfo(2, "l").currentline + local name = debug.getinfo(2, "n").name + if name == "fn" then + name = "Thread" + end + local value = "{"..CLASS.."."..name.."("..line..")} "..message + if logLevel then + if tonumber(LOG_LEVEL) >= logLevel then + exports.SLF:LogToClient(RESOURCE_CODE, logLevel, value) + end + else + exports.SLF:LogToClient(RESOURCE_CODE, 4, value) + Log("Warning line was logged without a level value... Logged it as debug as that is the safest route.", 1) + end +end + +function GetSID(UUID) + Log("Requesting SID for UUID: "..UUID, 4) + local SID = exports.SPH:GetSID(UUID) + Log("Retreived SID: "..SID.." for UUID: "..UUID, 4) + return SID +end diff --git a/template/withFeature/client/html/loadsplash.css b/template/withFeature/client/html/loadsplash.css new file mode 100644 index 0000000..7fc54eb --- /dev/null +++ b/template/withFeature/client/html/loadsplash.css @@ -0,0 +1,57 @@ +body { + font-size: 20px; + text-align: center; +} + +.unselectable { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} + +.loader { + border: 16px solid #6d6d6dc4; /* Light grey */ + border-top: 16px solid #4f2580; /* purple */ + border-radius: 50%; + width: 120px; + height: 120px; + animation: spin 2s linear infinite; + right: 1%; + bottom: 1%; + position: fixed; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.fade-in-image { + animation: fadeIn 1.5S; + -webkit-animation: fadeIn 1.5S; + -moz-animation: fadeIn 1.5S; + -o-animation: fadeIn 1.5S; + -ms-animation: fadeIn 1.5S; +} + +@keyframes fadeIn { + 0% { opacity: 0; } + 100% { opacity: 1; } +} + +.fade-out-image { + animation: fadeOut 1.5S; + -webkit-animation: fadeOut 1.5S; + -moz-animation: fadeOut 1.5S; + -o-animation: fadeOut 1.5S; + -ms-animation: fadeOut 1.5S; +} + +@keyframes fadeOut { + 0% { opacity: 1; } + 100% { opacity: 0; } +} \ No newline at end of file diff --git a/template/withFeature/client/html/loadsplash.html b/template/withFeature/client/html/loadsplash.html new file mode 100644 index 0000000..354ad73 --- /dev/null +++ b/template/withFeature/client/html/loadsplash.html @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + +
+ +
+
+ +
+
+ + \ No newline at end of file diff --git a/template/withFeature/client/html/loadsplash.js b/template/withFeature/client/html/loadsplash.js new file mode 100644 index 0000000..11d978c --- /dev/null +++ b/template/withFeature/client/html/loadsplash.js @@ -0,0 +1,47 @@ +$(function () { + function showSplash(bool) { + if (bool) { + $("#splashScreen").show(); + } else { + $("#splashScreen").hide(); + } + } + + function showLoadingSplash(bool) { + if (bool) { + $("#splashScreen").show(); + $("#loader").show(); + } else { + $("#splashScreen").hide(); + $("#loader").hide(); + } + } + + window.addEventListener('message', function(event) { + var item = event.data; + + // Show or hide the splash screen without loading spinner + if (item.type === "showSplash") { + if (item.status == true) { + showSplash(true) + } else { + showSplash(false) + } + } + + // Show or hide the loading splash screen + if (item.type === "showLoadingSplash") { + if (item.status == true) { + showLoadingSplash(true) + } else { + showLoadingSplash(false) + } + } + + if (item.type === "setIMG") { + document.getElementById("bgIMG").src = item.value; + } + }) + + showLoadingSplash(false) +}) \ No newline at end of file diff --git a/template/withFeature/client/html/reset.css b/template/withFeature/client/html/reset.css new file mode 100644 index 0000000..af94440 --- /dev/null +++ b/template/withFeature/client/html/reset.css @@ -0,0 +1,48 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} \ No newline at end of file diff --git a/template/withFeature/client/html/sounds/warning.ogg b/template/withFeature/client/html/sounds/warning.ogg new file mode 100644 index 0000000000000000000000000000000000000000..555b207846f58ce746aab53922408eb802cb5622 GIT binary patch literal 13143 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 logLevel then + exports.SLF:LogToServer(RESOURCE_CODE, logLevel, value) + end + else + exports.SLF:LogToServer(RESOURCE_CODE, 4, value) + Log("Warning line was logged without a level value... Logged it as debug as that is the safest route.", 1) + end +end + +function DisLog(message) + local line = debug.getinfo(2, "l").currentline + local name = debug.getinfo(2, "n").name + if name == "fn" then + name = "Thread" + end + local value = "{"..CLASS.."."..name.."("..line..")} "..message + exports.SLF:LogServerToDiscord(RESOURCE_CODE, message) +end + +function GetSID(UUID) + Log("Requesting SID for UUID: "..UUID, 4) + local SID = exports.SPH:GetSID(UUID) + Log("Retreived SID: "..SID.." for UUID: "..UUID, 4) + return SID +end \ No newline at end of file diff --git a/template/withFeature/shared/shared.lua b/template/withFeature/shared/shared.lua new file mode 100644 index 0000000..e69de29