diff --git a/config.json b/config.json index dff7961..e8445eb 100644 --- a/config.json +++ b/config.json @@ -27,6 +27,10 @@ "oxInventoryEvents": { "enabled": true, "dataset": "default" + }, + "esxWorldEvents": { + "enabled": false, + "dataset": "default" } } } \ No newline at end of file diff --git a/config.schema.json b/config.schema.json index 654eedb..3bd22ba 100644 --- a/config.schema.json +++ b/config.schema.json @@ -132,6 +132,23 @@ } }, "default": { "enabled": false, "dataset": "default" } + }, + "esxWorldEvents": { + "description": "ESX world events configuration (garage, property, drugs, license, identity, ambulance).", + "type": "object", + "properties": { + "enabled": { + "description": "Enable ESX world events to be logged.", + "type": "boolean", + "default": false + }, + "dataset": { + "description": "Dataset to use for ESX world events.", + "type": "string", + "default": "default" + } + }, + "default": { "enabled": false, "dataset": "default" } } }, "required": [ @@ -144,7 +161,8 @@ "playerEvents", "chatEvents", "txAdminEvents", - "oxInventoryEvents" + "oxInventoryEvents", + "esxWorldEvents" ] } }, diff --git a/features/logs/server/logger.ts b/features/logs/server/logger.ts index e8fa588..e150479 100644 --- a/features/logs/server/logger.ts +++ b/features/logs/server/logger.ts @@ -20,6 +20,7 @@ import './chat'; import './txadmin' import './baseevents' import './third-party/ox-inventory' +import './third-party/esx-world' const levels = config.logs.levels.reduce>( (acc, curr, idx) => { diff --git a/features/logs/server/third-party/esx-world.ts b/features/logs/server/third-party/esx-world.ts new file mode 100644 index 0000000..6da9c78 --- /dev/null +++ b/features/logs/server/third-party/esx-world.ts @@ -0,0 +1,149 @@ +import { config } from "~/utils/common/config"; +import { ingest } from "../logger"; + +if (config.logs.esxWorldEvents?.enabled) { + const dataset = config.logs.esxWorldEvents.dataset; + + // esx_garage + onNet("esx_garage:takeOutVehicle", (playerId: number, plate: string, model: string) => { + const playerName = GetPlayerName(playerId.toString()); + const playerSource = playerId; + ingest(dataset, "info", `player ${playerName} took out vehicle ${model} (${plate}) from garage`, { + playerSource, + playerName, + vehiclePlate: plate, + vehicleModel: model, + action: "takeOut", + }, { _internal_RESOURCE: "esx_garage" }); + }); + + onNet("esx_garage:storeVehicle", (playerId: number, plate: string, model: string) => { + const playerName = GetPlayerName(playerId.toString()); + const playerSource = playerId; + ingest(dataset, "info", `player ${playerName} stored vehicle ${model} (${plate}) in garage`, { + playerSource, + playerName, + vehiclePlate: plate, + vehicleModel: model, + action: "store", + }, { _internal_RESOURCE: "esx_garage" }); + }); + + // esx_property + onNet("esx_property:buy", (playerId: number, propertyName: string, price: number) => { + const playerName = GetPlayerName(playerId.toString()); + const playerSource = playerId; + ingest(dataset, "info", `player ${playerName} bought property ${propertyName} for $${price}`, { + playerSource, + playerName, + propertyName, + price, + }, { _internal_RESOURCE: "esx_property" }); + }); + + onNet("esx_property:enter", (playerId: number, propertyName: string) => { + const playerName = GetPlayerName(playerId.toString()); + const playerSource = playerId; + ingest(dataset, "info", `player ${playerName} entered property ${propertyName}`, { + playerSource, + playerName, + propertyName, + action: "enter", + }, { _internal_RESOURCE: "esx_property" }); + }); + + onNet("esx_property:exit", (playerId: number, propertyName: string) => { + const playerName = GetPlayerName(playerId.toString()); + const playerSource = playerId; + ingest(dataset, "info", `player ${playerName} exited property ${propertyName}`, { + playerSource, + playerName, + propertyName, + action: "exit", + }, { _internal_RESOURCE: "esx_property" }); + }); + + // esx_drugs + onNet("esx_drugs:harvestPlants", (playerId: number, plantType: string, amount: number) => { + const playerName = GetPlayerName(playerId.toString()); + const playerSource = playerId; + ingest(dataset, "info", `player ${playerName} harvested ${amount}x ${plantType}`, { + playerSource, + playerName, + plantType, + amount, + action: "harvest", + }, { _internal_RESOURCE: "esx_drugs" }); + }); + + onNet("esx_drugs:processDrugs", (playerId: number, drugType: string, amount: number) => { + const playerName = GetPlayerName(playerId.toString()); + const playerSource = playerId; + ingest(dataset, "info", `player ${playerName} processed ${amount}x ${drugType}`, { + playerSource, + playerName, + drugType, + amount, + action: "process", + }, { _internal_RESOURCE: "esx_drugs" }); + }); + + // esx_license + onNet("esx_license:addLicense", (playerId: number, licenseType: string) => { + const playerName = GetPlayerName(playerId.toString()); + const playerSource = playerId; + ingest(dataset, "info", `player ${playerName} granted license ${licenseType}`, { + playerSource, + playerName, + licenseType, + action: "add", + }, { _internal_RESOURCE: "esx_license" }); + }); + + onNet("esx_license:removeLicense", (playerId: number, licenseType: string) => { + const playerName = GetPlayerName(playerId.toString()); + const playerSource = playerId; + ingest(dataset, "info", `player ${playerName} had license ${licenseType} revoked`, { + playerSource, + playerName, + licenseType, + action: "remove", + }, { _internal_RESOURCE: "esx_license" }); + }); + + // esx_identity + onNet("esx_identity:registrationDone", (playerId: number, firstName: string, lastName: string, dateOfBirth: string, sex: string, height: number) => { + const playerName = GetPlayerName(playerId.toString()); + const playerSource = playerId; + ingest(dataset, "info", `player ${playerName} completed character registration`, { + playerSource, + playerName, + firstName, + lastName, + dateOfBirth, + sex, + height, + }, { _internal_RESOURCE: "esx_identity" }); + }); + + // esx_ambulancejob + onNet("esx_ambulancejob:revive", (targetId: number, medicId: number) => { + const targetName = GetPlayerName(targetId.toString()); + const medicName = GetPlayerName(medicId.toString()); + ingest(dataset, "info", `player ${targetName} revived by ${medicName}`, { + targetSource: targetId, + targetName, + playerSource: medicId, + playerName: medicName, + }, { _internal_RESOURCE: "esx_ambulancejob" }); + }); + + onNet("esx_ambulancejob:onPlayerDead", (playerId: number) => { + const playerName = GetPlayerName(playerId.toString()); + const playerSource = playerId; + ingest(dataset, "info", `player ${playerName} declared dead`, { + playerSource, + playerName, + }, { _internal_RESOURCE: "esx_ambulancejob" }); + }); +} diff --git a/features/utils/common/config.ts b/features/utils/common/config.ts index 2f2ceaf..50511b2 100644 --- a/features/utils/common/config.ts +++ b/features/utils/common/config.ts @@ -29,6 +29,7 @@ const ConfigSchema = object({ chatEvents: EventConfigSchema, txAdminEvents: EventConfigSchema, oxInventoryEvents: EventConfigSchema, + esxWorldEvents: EventConfigSchema, }), });