Dev Update
Build & Release VS Code Extension / release (push) Failing after 18s
Details
Build & Release VS Code Extension / release (push) Failing after 18s
Details
This commit is contained in:
parent
71c201ad5c
commit
c7c97e4ae5
|
|
@ -17,3 +17,7 @@ I will use this area to keep up with what i did last.
|
|||
## [Release 1.0.11]
|
||||
|
||||
- Removed Debug Data
|
||||
|
||||
## [Release 1.1.0]
|
||||
|
||||
- Combined the 2 dev tool resources togethter to make one total tool for easier maintaining
|
||||
26
README.md
26
README.md
|
|
@ -8,5 +8,29 @@ A collection of custom Lua snippets for FiveM development.
|
|||
- Thread templates
|
||||
- Common FiveM utilities
|
||||
|
||||
## Usage
|
||||
## 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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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"}
|
||||
{"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"}
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"resourceGenerator.js","sourceRoot":"","sources":["../src/resourceGenerator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,8DAWC;AAnDD,+CAAiC;AACjC,2BAAyE;AACzE,2CAA6B;AAE7B,IAAI,qBAAqB,GAAG,EAAE,CAAC;AAC/B,IAAI,cAAc,GAAG,KAAK,CAAC,CAAC,iBAAiB;AAW7C,MAAM,SAAS,GAA+B;IAC1C,YAAY,EAAE;QACV,KAAK,EAAE,eAAe;QACtB,WAAW,EAAE,iDAAiD;QAC9D,SAAS,EAAE,cAAc;QACzB,KAAK,EAAE,EAAE;KACZ;IACD,YAAY,EAAE;QACV,KAAK,EAAE,eAAe;QACtB,WAAW,EAAE,gCAAgC;QAC7C,SAAS,EAAE,aAAa;QACxB,KAAK,EAAE,EAAE;KACZ;IACD,WAAW,EAAE;QACT,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EAAE,sBAAsB;QACnC,SAAS,EAAE,EAAE;QACb,KAAK,EAAE,EAAE;KACZ;CACJ,CAAC;AAEF,MAAM,UAAU,GAAG,cAAc,CAAC;AAElC,qDAAqD;AACrD,SAAgB,yBAAyB,CAAC,OAAgC;IACtE,qBAAqB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IAErE,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,eAAe,CAC9C,gCAAgC,EAChC,CAAC,GAAe,EAAE,EAAE;QAChB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC5B,CAAC,CACJ,CAAC;IAEF,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAC3C,CAAC;AAED,iDAAiD;AACjD,SAAS,UAAU,CAAC,YAAqB;IACrC,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAE7B,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QAC7C,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QAChC,KAAK,CAAC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;QAE5C,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;YACzB,IAAI,KAAK,CAAC,KAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAM,CAAC,KAAK,CAAC;gBACjC,KAAK,CAAC,KAAM,CAAC,IAAI,EAAE,CAAC;gBAEpB,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;oBAClB,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,KAAM,CAAC,IAAI,EAAE,CAAC;gBAC7C,CAAC;qBAAM,CAAC;oBACJ,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa;gBAClD,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAC1B,oCAAoC,KAAK,CAAC,KAAK,IAAI,CACtD,CAAC;YACN,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;YACrB,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACvB,CAAC;IACL,CAAC;AACL,CAAC;AAED,qDAAqD;AACrD,KAAK,UAAU,iBAAiB,CAAC,YAAqB;IAClD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,aAAa,CAC5C,CAAC,KAAK,EAAE,IAAI,CAAC,EACb;QACI,WAAW,EAAE,sBAAsB;KACtC,CACJ,CAAC;IAEF,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,sBAAsB,CAAC,CAAC;QACzD,OAAO;IACX,CAAC;IAED,cAAc,GAAG,MAAM,KAAK,KAAK,CAAC;IAElC,eAAe,CAAC,YAAY,CAAC,CAAC;AAClC,CAAC;AAED,iDAAiD;AACjD,SAAS,eAAe,CAAC,QAAiB;IACtC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACZ,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;QACtD,OAAO;IACX,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC;IAEtC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAEvE,IAAA,cAAS,EAAC,YAAY,CAAC,CAAC;IACxB,WAAW,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAElC,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAChC,oDAAoD,SAAS,CAAC,YAAY,CAAC,KAAK,IAAI,CACvF,CAAC;AACN,CAAC;AASD,SAAS,MAAM,CAAC,GAAW;IACvB,OAAO;QACH,GAAG;QACH,KAAK,EAAE,EAAE;QACT,OAAO,EAAE,EAAE;KACd,CAAC;AACN,CAAC;AAED,sDAAsD;AACtD,SAAS,kBAAkB,CAAC,GAAW;IACnC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAE3B,qCAAqC;IACrC,MAAM,gBAAgB,GAAG,cAAc;QACnC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,aAAa,CAAC;QACjD,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAE/C,MAAM,KAAK,GAAG,IAAA,gBAAW,EAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,CAAC,EAAE;QACxD,aAAa,EAAE,IAAI;KACtB,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACrB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAC1C,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAC5B,CAAC;QACN,CAAC;aAAM,CAAC;YACJ,IAAI,OAAO,GAAG,IAAA,iBAAY,EACtB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,EAC3C,OAAO,CACV,CAAC;YAEF,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;gBAC1B,OAAO,GAAG,OAAO,CAAC,OAAO,CACrB,IAAI,MAAM,CAAC,SAAS,GAAG,KAAK,EAAE,GAAG,CAAC,EAClC,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,CACvB,CAAC;YACN,CAAC;YAED,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;QACtC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,kDAAkD;AAClD,SAAS,WAAW,CAAC,GAAW,EAAE,MAAkB;IAChD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAA,kBAAa,EAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC1C,IAAA,cAAS,EAAC,aAAa,CAAC,CAAC;QAEzB,WAAW,CAAC,aAAa,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD,CAAC;AACL,CAAC"}
|
||||
|
|
@ -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") {
|
||||
// ✅ 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);
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
37
package.json
37
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"
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
@ -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<string, InputField> = {
|
||||
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<string, string>;
|
||||
folders: Record<string, FolderType>;
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
|
@ -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") {
|
||||
// ✅ 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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
@ -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'
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
@ -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; }
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="reset.css" type="text/css">
|
||||
<link rel="stylesheet" href="loadsplash.css" type="text/css">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fjalla+One&family=Inconsolata:wght@300&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fjalla+One&family=Inconsolata:wght@300&family=Roboto+Condensed&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
|
||||
<script src="nui://game/ui/jquery.js" type="text/javascript"></script>
|
||||
<script src="nui://game/ui/jquery.js" type="text/javascript"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.1.1/howler.min.js" type="text/javascript"></script>
|
||||
<script>
|
||||
var audioPlayer = null;
|
||||
// Listen for NUI Messages.
|
||||
window.addEventListener('message', function(event) {
|
||||
// Check for playSound transaction
|
||||
if (event.data.transactionType == "playSound") {
|
||||
|
||||
if (audioPlayer != null) {
|
||||
audioPlayer.pause();
|
||||
}
|
||||
|
||||
audioPlayer = new Howl({src: ["./sounds/" + event.data.transactionFile + ".ogg"]});
|
||||
audioPlayer.volume(event.data.transactionVolume);
|
||||
audioPlayer.play();
|
||||
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body id="splashScreen" class="unselectable w3-display-container">
|
||||
<div class="w3-animate-opacity">
|
||||
<script src="./loadsplash.js" type="text/javascript"></script>
|
||||
<div id="loader" class="loader"></div>
|
||||
<div class="fade-in-image">
|
||||
<img id="bgIMG" src="https://images.cstm.games/imgstor/splashscreens/defaultsplash.png" alt="" style="width:100%;height:100%;">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -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)
|
||||
})
|
||||
|
|
@ -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;
|
||||
}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,38 @@
|
|||
local RESOURCE_CODE = GetResourceMetadata(GetCurrentResourceName(), "resource_code", 0)
|
||||
local SPLASH_IMG = GetResourceMetadata(GetCurrentResourceName(), "SPLASH_IMG", 0)
|
||||
|
||||
--Setup the splash image on script load
|
||||
Citizen.CreateThread(function()
|
||||
print("Setting Up LoadSplash")
|
||||
SendNUIMessage({
|
||||
type = "setIMG",
|
||||
value = SPLASH_IMG,
|
||||
})
|
||||
end)
|
||||
|
||||
-- Show and hide the splash without spinner
|
||||
function displaySplash(bool)
|
||||
SendNUIMessage({
|
||||
type = "showSplash",
|
||||
status = bool,
|
||||
})
|
||||
end
|
||||
|
||||
RegisterNetEvent(RESOURCE_CODE..':ShowStaticSplash')
|
||||
AddEventHandler(RESOURCE_CODE..':ShowStaticSplash', function(bool)
|
||||
displaySplash(bool)
|
||||
end)
|
||||
|
||||
-- Show and hide the splash with spinner
|
||||
function displayLoadSplash(bool)
|
||||
SendNUIMessage({
|
||||
type = "showLoadingSplash",
|
||||
status = bool,
|
||||
})
|
||||
end
|
||||
|
||||
RegisterNetEvent(RESOURCE_CODE..':ShowLoadingSplash')
|
||||
AddEventHandler(RESOURCE_CODE..':ShowLoadingSplash', function(bool)
|
||||
displayLoadSplash(bool)
|
||||
end)
|
||||
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
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'
|
||||
SPLASH_IMG 'https://images.cstm.games/imgstor/splashscreens/defaultsplash.png'
|
||||
|
||||
|
||||
dependencies {
|
||||
'SLF',
|
||||
'SCF'
|
||||
}
|
||||
|
||||
files {
|
||||
'client/html/index.html',
|
||||
'client/html/sounds/*.ogg',
|
||||
'client/config/*.json',
|
||||
'client/html/loadsplash.html',
|
||||
'client/html/loadsplash.js',
|
||||
'client/html/loadsplash.css',
|
||||
'client/html/reset.css'
|
||||
}
|
||||
|
||||
ui_page 'client/html/loadsplash.html'
|
||||
|
||||
-- shared_scripts {
|
||||
-- 'shared/*.lua'
|
||||
-- }
|
||||
|
||||
client_scripts {
|
||||
'@menuv/menuv.lua',
|
||||
'menus/*.lua',
|
||||
'client/*.lua'
|
||||
}
|
||||
|
||||
server_scripts {
|
||||
'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
|
||||
Loading…
Reference in New Issue