Compare commits

...

8 Commits

Author SHA1 Message Date
github-actions
016a204499 v1.0.0 Build 11 2025-05-11 06:20:45 +00:00
Jacob Schmidt
461a678f8b feat: Implement timesheet submission and rating system in bank addon
All checks were successful
Build / Build (push) Successful in 25s
This commit introduces the ability for players to submit timesheets and receive payment based on their rating. It also includes updates to player data handling to incorporate the new rating system.

Key changes include:

- Added `getPlayer` PREP.
- Implemented `BANK::SUBMIT::TIMESHEET` case in `XEH_preInit_server.sqf` to handle timesheet submissions.
- Modified `fnc_initBankStore.sqf` to include rating in player data and update account information.
- Added `submitTimesheet` function to `fnc_initBankStore.sqf` to process timesheet submissions and pay players based on rating.
- Updated `handlePlayerLoad` and `updateAccount` functions in `fnc_initBankStore.sqf` to include rating.
- Added `getRating` function to `fnc_initBankStore.sqf` to retrieve player rating.
- Updated `BANK::HANDLE::PLAYER::LOAD` case in `XEH_preInit_server.sqf` to include rating value.
- Added database saving for reputation.

These changes introduce a new gameplay mechanic and provide a way for players to earn money based on their performance.
2025-05-11 01:19:58 -05:00
github-actions
fb7c198e56 v1.0.0 Build 10 2025-05-10 22:50:38 +00:00
Jacob Schmidt
2ff4a37677 Merge branch 'master' of https://gitea.innovativedevsolutions.org/IDSolutions/server
All checks were successful
Build / Build (push) Successful in 38s
2025-05-10 17:50:25 -05:00
Jacob Schmidt
991ee5019a feat: Enhance admin and bank event handling with improved logging
This commit refines the event handling for both admin and bank functionalities, ensuring better clarity and consistency in logging.

Key changes include:

- Updated event names in admin handling to follow a consistent naming convention.
- Improved parameter handling in admin event functions, ensuring validation checks are in place.
- Enhanced logging messages to provide clearer context regarding the source of events and actions taken.
- Introduced bank event handling for deposit, transfer, withdrawal, and balance inquiries, with appropriate validation and logging.

These changes aim to improve the maintainability and readability of the codebase while ensuring robust event management.
2025-05-10 17:50:21 -05:00
github-actions
17d5942de4 v1.0.0 Build 9 2025-05-05 01:03:33 +00:00
Jacob Schmidt
74b9f78141 Merge branch 'master' of https://gitea.innovativedevsolutions.org/IDSolutions/server
All checks were successful
Build / Build (push) Successful in 25s
2025-05-04 20:03:03 -05:00
Jacob Schmidt
db238970f7 feat: Update server mod icons and properties
This commit updates the server mod with new icons and properties.

The following changes were made:

- Updated `picture` to `title_ca.paa` in `mod.cpp`.
- Updated `logoSmall` to `icon_64_ca.paa` in `mod.cpp`.
- Updated `logo` to `icon_128_ca.paa` in `mod.cpp`.
- Updated `logoOver` to `icon_128_highlight_ca.paa` in `mod.cpp`.
- Added `dlcColor` to `mod.cpp`.
- Updated binary files for `icon_128_highlight_ca.paa`, `icon_64_ca.paa`, and `icon_128_ca.paa`.
2025-05-04 20:02:30 -05:00
17 changed files with 390 additions and 24 deletions

View File

@ -4,53 +4,53 @@ call FUNC(initAdmin);
call FUNC(initAdminStore);
[QGVAR(handleEvents), {
params ["_event", "_params"];
params ["_event", "_data"];
diag_log format ["[FORGE: Admin] Received event: %1 with params: %2", _event, _params];
diag_log format ["[FORGE::Server::Admin::XEH_preInit] Received event: %1 with data: %2", _event, _data];
switch (_event) do {
case "advanceAll": {
case "ADMIN::ADVANCE::ALL": {
private _adminStore = call FUNC(verifyAdminStore);
_params params ["_amount"];
_data params [["_amount", 0, [0]]];
if (isNil "_amount") exitWith { diag_log "Amount cannot be empty!"; };
if (_amount isEqualTo 0) exitWith { diag_log "[FORGE::Server::Admin::XEH_preInit::advanceAll] Invalid amount!"; };
_adminStore call ["handleTransfer", ["advanceAll", _amount]];
};
case "handlePayday": {
case "ADMIN::PAYDAY": {
private _adminStore = call FUNC(verifyAdminStore);
_adminStore call ["handleTransfer", ["payday"]];
};
case "handleTransfer": {
case "ADMIN::TRANSFER": {
private _adminStore = call FUNC(verifyAdminStore);
_params params ["_condition", "_amount", "_uid"];
_data params [["_condition", "", [""]], ["_amount", 0, [0]], ["_uid", "", [""]]];
if (isNil "_condition") exitWith { diag_log "Condition cannot be empty!"; };
if (_condition isEqualTo "" || _amount isEqualTo 0 || _uid isEqualTo "") exitWith { diag_log "[FORGE::Server::Admin::XEH_preInit::handleTransfer] Invalid condition, amount, or UID!"; };
_adminStore call ["handleTransfer", [_condition, _amount, _uid]];
};
case "sendMessage": {
case "ADMIN::SEND::MESSAGE": {
private _adminStore = call FUNC(verifyAdminStore);
_params params ["_uid", "_message"];
_data params [["_uid", "", [""]], ["_message", "", [""]]];
if (isNil "_message") exitWith { diag_log "Message cannot be empty!"; };
if (_message isEqualTo "") exitWith { diag_log "[FORGE::Server::Admin::XEH_preInit::sendMessage] Invalid message!"; };
if (_uid isEqualTo "") then {
_adminStore call ["broadcastMessage", [_message]];
} else {
_adminStore call ["sendMessage", [_uid, _message]];
};
};
case "updatePaygrade": {
case "ADMIN::UPDATE::PAYGRADE": {
private _adminStore = call FUNC(verifyAdminStore);
_params params ["_uid", "_paygrade"];
_data params [["_uid", "", [""]], ["_paygrade", "", [""]]];
if (_uid isEqualTo "" && _paygrade isEqualTo "") exitWith { diag_log "UID or Paygrade cannot be empty!"; };
if (_uid isEqualTo "" || _paygrade isEqualTo "") exitWith { diag_log "[FORGE::Server::Admin::XEH_preInit::updatePaygrade] Invalid UID or paygrade!"; };
_adminStore call ["updatePaygrade", [_uid, _paygrade]];
};
default {
diag_log format ["Unknown event: %1 with params: %2", _event, _params];
diag_log format ["[FORGE::Server::Admin::XEH_preInit] Unknown event: %1 with data: %2", _event, _data];
};
};
}] call CFUNC(addEventHandler);

View File

@ -13,6 +13,6 @@
_cpof allowDamage false;
_cpof setVariable ["isCPOF", true, true];
diag_log text format ["[FORGE Admin] ClassName: '%1' Pos: '%2' Dir: '%3'", _className, _pos, _dir];
diag_log text format ["[FORGE::Server::Admin::initAdmin] ClassName: '%1' Pos: '%2' Dir: '%3'", _className, _pos, _dir];
} forEach ("true" configClasses (missionConfigFile >> "CfgCpofs" >> "cpofs"));

View File

@ -26,7 +26,7 @@ private _store = GETMVAR(FORGE_ADMIN_STORE_REG,nil);
if (isNil "_store") then {
_store = call FUNC(initAdminStore);
diag_log text "[FORGE Admin] Admin store initialized";
diag_log text "[FORGE::Server::Admin::verifyAdminStore] Admin store initialized";
};
_store

View File

@ -1 +1,3 @@
PREP(initBank);
PREP(initBankStore);
PREP(verifyBankStore);

View File

@ -1,3 +1,78 @@
#include "script_component.hpp"
call FUNC(initBank);
call FUNC(initBankStore);
[QGVAR(handleEvents), {
params ["_event", "_data"];
diag_log text format ["[FORGE::Server::Bank::XEH_preInit] Received event: '%1' with data: '%2'", _event, _data];
switch (_event) do {
case "BANK::DEPOSIT": {
private _bankStore = call FUNC(verifyBankStore);
_data params [["_uid", "", [""]], ["_amount", 0, [0]]];
if (_uid isEqualTo "" || _amount isEqualTo 0) exitWith { diag_log "[FORGE::Server::Bank::XEH_preInit::handleDeposit] Invalid UID and amount, UID cannot be empty and amount must be greater than 0!"; };
_bankStore call ["deposit", [_uid, _amount]];
};
case "BANK::SUBMIT::TIMESHEET": {
private _bankStore = call FUNC(verifyBankStore);
_data params [["_uid", "", [""]], ["_rating", 0, [0]]];
if (_uid isEqualTo "" || _rating <= 0) exitWith { diag_log "[FORGE::Server::Bank::XEH_preInit::handleSubmitTimesheet] Invalid UID, UID cannot be empty!"; };
_bankStore call ["submitTimesheet", [_uid, _rating]];
};
case "BANK::TRANSFER": {
private _bankStore = call FUNC(verifyBankStore);
_data params [["_fromUid", "", [""]], ["_toUid", "", [""]], ["_amount", 0, [0]]];
if (_fromUid isEqualTo "" || _toUid isEqualTo "" || _amount isEqualTo 0) exitWith { diag_log "[FORGE::Server::Bank::XEH_preInit::handleTransfer] Invalid UIDs and amount, UID cannot be empty and amount must be greater than 0!"; };
_bankStore call ["transfer", [_fromUid, _toUid, _amount]];
};
case "BANK::WITHDRAW": {
private _bankStore = call FUNC(verifyBankStore);
_data params [["_uid", "", [""]], ["_amount", 0, [0]]];
if (_uid isEqualTo "" || _amount isEqualTo 0) exitWith { diag_log "[FORGE::Server::Bank::XEH_preInit::handleWithdraw] Invalid UID and amount!"; };
_bankStore call ["withdraw", [_uid, _amount]];
};
case "BANK::GET::BALANCE": {
private _bankStore = call FUNC(verifyBankStore);
_data params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE::Server::Bank::XEH_preInit::handleGetBalance] Invalid UID, UID cannot be empty!"; };
_bankStore call ["getBalance", [_uid]];
};
case "BANK::GET::CASH": {
private _bankStore = call FUNC(verifyBankStore);
_data params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE::Server::Bank::XEH_preInit::handleGetCash] Invalid UID, UID cannot be empty!"; };
_bankStore call ["getCash", [_uid]];
};
case "BANK::HANDLE::PLAYER::LOAD": {
private _bankStore = call FUNC(verifyBankStore);
_data params [["_uid", "", [""]], ["_bankValue", 0, [0]], ["_cashValue", 0, [0]], ["_ratingValue", 0, [0]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE::Server::Bank::XEH_preInit::handlePlayerLoad] Invalid UID, UID cannot be empty!"; };
_bankStore call ["handlePlayerLoad", [_uid, _bankValue, _cashValue, _ratingValue]];
};
case "BANK::GET::TRANSACTION::HISTORY": {
private _bankStore = call FUNC(verifyBankStore);
_data params [["_uid", "", [""]], ["_limit", 10, [0]]];
_bankStore call ["getTransactionHistory", [_uid, _limit]];
};
default {
diag_log format ["[FORGE::Server::Bank::XEH_preInit] Unknown event: %1 with data: %2", _event, _data];
};
};
}] call CFUNC(addEventHandler);

View File

@ -26,5 +26,5 @@
_bank setVariable ["BIS_enableRandomization", false];
};
diag_log text format ["[FORGE Bank] ClassName: '%1' Pos: '%2' Dir: '%3'", _className, _pos, _dir];
diag_log text format ["[FORGE::Server::Bank::initBank] ClassName: '%1' Pos: '%2' Dir: '%3'", _className, _pos, _dir];
} forEach ("true" configClasses (missionConfigFile >> "CfgBanks" >> "banks"));

View File

@ -0,0 +1,227 @@
#include "..\script_component.hpp"
/*
* Author: IDSolutions
* Initializes a server-side bank store interface for managing banking operations.
* Provides CRUD operations for bank data, including database persistence.
*
* Arguments:
* None
*
* Return Value:
* <HASHMAP> Bank store object
*
* Example:
* private _bankStore = call forge_server_bank_fnc_initBank;
* _bankStore call ["deposit", [getPlayerUID player, 1000]];
*
* Public: Yes
*/
private _bankStore = createHashMapObject [[
["#type", "IBankStore"],
["#create", {
_self set ["accounts", createHashMap];
_self set ["transactions", []];
_self set ["isLoaded", true];
true
}],
["handlePlayerLoad", {
params [["_uid", "", [""]], ["_bankValue", 0, [0]], ["_cashValue", 0, [0]], ["_ratingValue", 0, [0]]];
if (_uid isEqualTo "") exitWith { false };
_self call ["updateAccount", [_uid, _bankValue, _cashValue, _ratingValue]];
diag_log text format ["[FORGE::Server::Bank::Store::handlePlayerLoad] Loaded player data for '%1' - Bank: '%2', Cash: '%3', Rating: '%4'", _uid, _bankValue, _cashValue, _ratingValue];
true
}],
["updateAccount", {
params [["_uid", "", [""]], ["_bankValue", 0, [0]], ["_cashValue", 0, [0]], ["_ratingValue", 0, [0]], ["_isSave", false, [false]]];
if (_uid isEqualTo "") exitWith { false };
private _accounts = _self get "accounts";
private _account = _accounts getOrDefault [_uid, createHashMap];
private _player = [_uid] call EFUNC(misc,getPlayer);
_account set ["bank", _bankValue];
_account set ["cash", _cashValue];
_account set ["rating", _ratingValue];
_accounts set [_uid, _account];
_self set ["accounts", _accounts];
private _balance = _account getOrDefault ["bank", 0];
private _cash = _account getOrDefault ["cash", 0];
SETPVAR(_player,FORGE_Bank,_balance);
SETPVAR(_player,FORGE_Cash,_cash);
SETPVAR(_player,FORGE_Rating,_ratingValue);
if (_isSave) then {
["hsetid", _uid, "bank", -1, [_bankValue]] call dragonfly_db_fnc_addTask;
["hsetid", _uid, "cash", -1, [_cashValue]] call dragonfly_db_fnc_addTask;
["hsetid", _uid, "reputation", -1, [_ratingValue]] call dragonfly_db_fnc_addTask;
};
diag_log text format ["[FORGE::Server::Bank::Store::updateAccount] Updated player data for '%1' - Bank: '%2', Cash: '%3', Rating: '%4'", _uid, _bankValue, _cashValue, _ratingValue];
true
}],
["getBalance", {
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { 0 };
private _accounts = _self get "accounts";
private _account = _accounts getOrDefault [_uid, createHashMap];
_account getOrDefault ["bank", 0]
}],
["getCash", {
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { 0 };
private _accounts = _self get "accounts";
private _account = _accounts getOrDefault [_uid, createHashMap];
_account getOrDefault ["cash", 0]
}],
["getRating", {
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { 0 };
private _accounts = _self get "accounts";
private _account = _accounts getOrDefault [_uid, createHashMap];
_account getOrDefault ["rating", 0]
}],
["deposit", {
params [["_uid", "", [""]], ["_amount", 0, [0]]];
if (_uid isEqualTo "" || _amount <= 0) exitWith { false };
private _accounts = _self get "accounts";
private _account = _accounts getOrDefault [_uid, createHashMap];
private _currentCash = _account getOrDefault ["cash", 0];
private _currentBalance = _account getOrDefault ["bank", 0];
private _currentRating = _account getOrDefault ["rating", 0];
if (_currentCash < _amount) exitWith { false };
private _newBalance = _currentBalance + _amount;
private _newCash = _currentCash - _amount;
_self call ["updateAccount", [_uid, _newBalance, _newCash, _currentRating, true]];
private _transactions = _self get "transactions";
_transactions pushBack [_uid, "deposit", _amount, time];
_self set ["transactions", _transactions];
true
}],
["submitTimesheet", {
params [["_uid", "", [""]], ["_rating", 0, [0]]];
if (_uid isEqualTo "" || _rating <= 0) exitWith { false };
private _accounts = _self get "accounts";
private _account = _accounts getOrDefault [_uid, createHashMap];
private _currentBalance = _account getOrDefault ["bank", 0];
private _currentCash = _account getOrDefault ["cash", 0];
private _payMultiplyer = "MULTIPLYR" call BFUNC(getParamValue);
private _multiplyer = _rating * _payMultiplyer;
private _newBalance = _currentBalance + _multiplyer;
_self call ["updateAccount", [_uid, _newBalance, _currentCash, 0, true]];
private _transactions = _self get "transactions";
_transactions pushBack [_uid, "timesheet", _multiplyer, time];
_self set ["transactions", _transactions];
true
}],
["transfer", {
params [["_fromUid", "", [""]], ["_toUid", "", [""]], ["_amount", 0, [0]]];
if (_fromUid isEqualTo "" || _toUid isEqualTo "" || _amount <= 0) exitWith { false };
private _accounts = _self get "accounts";
private _fromAccount = _accounts getOrDefault [_fromUid, createHashMap];
private _toAccount = _accounts getOrDefault [_toUid, createHashMap];
private _fromBalance = _fromAccount getOrDefault ["bank", 0];
private _toBalance = _toAccount getOrDefault ["bank", 0];
private _fromCash = _fromAccount getOrDefault ["cash", 0];
private _toCash = _toAccount getOrDefault ["cash", 0];
private _fromRating = _fromAccount getOrDefault ["rating", 0];
private _toRating = _toAccount getOrDefault ["rating", 0];
if (_fromBalance < _amount) exitWith { false };
_self call ["updateAccount", [_fromUid, _fromBalance - _amount, _fromCash, _fromRating, true]];
_self call ["updateAccount", [_toUid, _toBalance + _amount, _toCash, _toRating, true]];
private _transactions = _self get "transactions";
_transactions pushBack [_fromUid, "transfer_out", _amount, time, _toUid];
_transactions pushBack [_toUid, "transfer_in", _amount, time, _fromUid];
_self set ["transactions", _transactions];
true
}],
["withdraw", {
params [["_uid", "", [""]], ["_amount", 0, [0]]];
if (_uid isEqualTo "" || _amount <= 0) exitWith { false };
private _accounts = _self get "accounts";
private _account = _accounts getOrDefault [_uid, createHashMap];
private _currentBalance = _account getOrDefault ["bank", 0];
private _currentCash = _account getOrDefault ["cash", 0];
private _currentRating = _account getOrDefault ["rating", 0];
if (_currentBalance < _amount) exitWith { false };
private _newBalance = _currentBalance - _amount;
private _newCash = _currentCash + _amount;
_self call ["updateAccount", [_uid, _newBalance, _newCash, _currentRating, true]];
private _transactions = _self get "transactions";
_transactions pushBack [_uid, "withdraw", _amount, time];
_self set ["transactions", _transactions];
true
}],
["getTransactionHistory", {
params [["_uid", "", [""]], ["_limit", 10, [0]]];
private _transactions = _self get "transactions";
private _filteredTransactions = [];
if (_uid isEqualTo "") then {
_filteredTransactions = _transactions;
} else {
{
if ((_x select 0) == _uid) then { _filteredTransactions pushBack _x; };
} forEach _transactions;
};
_filteredTransactions sort false;
_filteredTransactions resize (_limit min (count _filteredTransactions));
_filteredTransactions
}]
]];
SETMVAR(FORGE_BANK_STORE_REG,_bankStore);
GETMVAR(FORGE_BANK_STORE_REG,_bankStore);

View File

@ -0,0 +1,32 @@
#include "..\script_component.hpp"
/*
* Function: forge_server_bank_fnc_verifyBankStore
* Author: IDSolutions
*
* [Description]
* Ensures the bank store is initialized and returns the store object.
* Acts as a singleton accessor for the bank store interface.
* If the store doesn't exist yet, it initializes it first.
*
* Arguments:
* None
*
* Return Value:
* Bank Store <OBJECT> - The bank store interface object
*
* Example:
* private _bankStore = call forge_server_bank_fnc_verifyBankStore
*
* Public: No
*/
private _store = GETMVAR(FORGE_BANK_STORE_REG,nil);
if (isNil "_store") then {
_store = call FUNC(initBankStore);
diag_log text "[FORGE::Server::Bank::verifyBankStore] Bank store initialized";
};
_store

View File

@ -1,4 +1,4 @@
#define MAJOR 1
#define MINOR 0
#define PATCH 0
#define BUILD 8
#define BUILD 11

View File

@ -1,4 +1,5 @@
PREP(cargoToPairs);
PREP(getPlayer);
PREP(playSound);
PREP(playerGroup2Server);
PREP(redirectClient2Server);

View File

@ -0,0 +1,27 @@
#include "..\script_component.hpp"
/*
* Author: IDSolutions
* Gets a player object by UID.
*
* Arguments:
* 0: Player UID <STRING>
*
* Return Value:
* Player object or objNull if not found <OBJECT>
*
* Example:
* ["76561198012345678"] call forge_crate_common_fnc_getPlayer
*
* Public: Yes
*/
params ["_uid"];
private _player = objNull;
{
if ((getPlayerUID _x) isEqualTo _uid) exitWith { _player = _x; };
} forEach allPlayers;
_player

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,7 @@
dir = "@forge_server";
name = "FORGE Server";
author = "IDSolutions";
picture = "title_co.paa";
picture = "title_ca.paa";
logoSmall = "icon_64_ca.paa";
logo = "icon_128_ca.paa";
logoOver = "icon_128_highlight_ca.paa";
@ -10,3 +11,4 @@ overview = "FORGE Server - Official Modification";
description = "FORGE Server - Version 1.0.0";
action = "https://innovativedevsolutions.org";
actionName = "Website";
dlcColor[] = {0.45, 0.47, 0.41, 1};

BIN
title_ca.paa Normal file

Binary file not shown.

Binary file not shown.