Thursday, September 19, 2024 11:46:46 PM
> settings

Customize


Authenticate

> ExileServer_marxet_system_network_tradeRequest.sqf
/*
    MarXet v2.0
    Written by WolfkillArcadia
    CC BY-NC-SA 4.0
*/
 
private["_sessionID", "_package", "_marxetID", "_pincode", "_containerType", "_containerNetID", "_vehicleNetIDs", "_position", "_sentToSafex", "_playerObject", "_entry", "_tradeClassname", "_isVehicle", "_index", "_vehicleCost", "_rekeyCost", "_amount", "_hasAllRequested", "_classname", "_quantity", "_hasItem", "_cargo", "_overallHealth", "_damaged", "_vehicleClass", "_helipad", "_vehiclesModified", "_money", "_respect", "_displayName", "_databaseID", "_vehicleObject", "_added", "_vehicle", "_requestorUID", "_requestorObject", "_vehicleInfo", "_locker", "_traderLog"];
_sessionID = _this select 0;
_package = _this select 1;
_marxetID = _package select 0;
_pincode = _package select 1;
_containerType = _package select 2;
_containerNetID = _package select 3;
_vehicleNetIDs = _package select 4;
_position = [];
_sentToSafex = false;
try
{
	_playerObject = _sessionID call ExileServer_system_session_getPlayerObject;
	if (isNull _playerObject) then 
	{
		throw "Player is Null";
	};
	if (_playerObject getVariable ["ExileMutex", false]) then 
	{
		throw "Player is Mutex";
	};
	_playerObject setVariable ["ExileMutex", true];
	_entry = MarXetTrading getVariable [_marxetID, []];
	if (_entry isEqualTo []) then 
	{
		throw "Invalid listing ID";
	};
	if (_marxetID call ExileServer_system_request_trading_isLocked) then 
	{
		throw "This item is currently locked. Please try again later";
	};
	_marxetID call ExileServer_marxet_system_request_trading_lock;
	_tradeClassname = (_entry select 3) select 0;
	_isVehicle = _tradeClassname isKindOf "AllVehicles";
	if (_isVehicle) then 
	{
		if (_pincode isEqualTo "") then 
		{
			throw "Empty Pin Code";
		};
		if !(([_pincode, "1234567890"] call ExileClient_util_string_containsForbiddenCharacter) isEqualTo -1) then 
		{
			throw "Pincode contains illegal character";
		};
		if (getNumber(missionConfigFile >> "CfgMarXet" >> "Settings" >> "Vehicles" >> "addRekeyFee") isEqualTo 1) then 
		{
			_index = -1;
			_vehicleCost = getNumber (missionConfigFile >> "CfgExileArsenal" >> _tradeClassname >> "price");
			_rekeyCost = floor(_vehicleCost * (getNumber (missionConfigFile >> "CfgTrading" >> "rekeyPriceFactor"))) max 1;
			{
				if ((_x select 0) isEqualTo "ExileMoney") exitWith 
				{
					_index = _forEachIndex;
				};
			}
			forEach (_entry select 4);
			if (_index isEqualTo -1) then 
			{
				(_entry select 4) pushBack ["ExileMoney", _rekeyCost];
			}
			else
			{
				_amount = ((_entry select 4) select _index) select 1;
				((_entry select 4) select _index) set [1, _amount + _rekeyCost];
			};
		};
	};
	_hasAllRequested = [];
	{
		_classname = _x select 0;
		_quantity = _x select 1;
		switch (_classname) do 
		{
			case "ExileMoney": 
			{
				_hasItem = (_playerObject getVariable ["ExileMoney", 0]) >= _quantity;
			};
			case "ExileScore": 
			{
				_hasItem = ExileClientPlayerScore >= _quantity;
			};
			default 
			{
				_cargo = (_playerObject call ExileClient_util_playerCargo_list) call ExileClient_util_array_toLower;
				{
					if ((owner _x) isEqualTo (owner _playerObject) && {alive _x}) then 
					{
						if (toLower(typeOf(_x)) isEqualTo toLower(_classname)) then 
						{
							_overallHealth = (getAllHitPointsDamage _x) call ExileClient_marxet_util_vehicle_getOverallDamage;
							_overallHealth = [(1 - _overallHealth) * 100, 2] call ExileClient_util_math_round;
							_damaged = _overallHealth < getNumber(missionConfigFile >> "CfgMarXet" >> "Settings" >> "Vehicles" >> "overallVehicleHealth");
						};
						_cargo pushBack toLower(typeOf(_x));
						_cargo append (_x call ExileClient_util_containerCargo_list) call ExileClient_util_array_toLower;
					};
				}
				forEach (nearestObjects [_playerObject, ["LandVehicle", "Air", "Ship"], 80]);
				_hasItem = ({ _x isEqualTo toLower(_classname) } count _cargo) >= _quantity;
			};
		};
		_hasAllRequested pushBack (_hasItem && !_damaged);
	}
	forEach (_entry select 4);
	if !(({_x} count _hasAllRequested) isEqualTo count(_hasAllRequested)) then 
	{
		throw "Missing one or more requested items/vehicles";
	};
	if (_isVehicle) then 
	{
		if (getNumber(missionConfigFile >> "CfgMarXet" >> "Settings" >> "Vehicles" >> "Static" >> "useStaticSpawning") isEqualTo 1) then 
		{
			if (_vehicleClass isKindOf "Ship") then
            {
                _helipad = nearestObject [(getPosATL _playerObject), getText(missionConfigFile >> "CfgMarXet" >> "Settings" >> "Vehicles" >> "Static" >> "boatSpawnClassname")];    
			}
            else
            {
                if (_vehicleClass isKindOf "Air") then
                {
                    _helipad = nearestObject [(getPosATL _playerObject), getText(missionConfigFile >> "CfgMarXet" >> "Settings" >> "Vehicles" >> "Static" >> "airSpawnClassname")];
                }
                else
                {
                    _helipad = nearestObject [(getPosATL _playerObject), getText(missionConfigFile >> "CfgMarXet" >> "Settings" >> "Vehicles" >> "Static" >> "landSpawnClassname")];
                };
            };
			if !(isNull _helipad) then
			{
				_position = (getPosATL _helipad);
				_position set [2,0];
			};
		}
		else
		{
			if (_vehicleClass isKindOf "Ship") then
            {
                _position = [(getPosATL _playerObject), 80, 10] call ExileClient_util_world_findWaterPosition;
            }
            else
            {
                _position = (getPos _playerObject) findEmptyPosition [10, 175, _vehicleClass];
            };
		};
		if (_position isEqualTo []) then 
		{
			throw "Unable to find suitable position for spawning";
		};
	};
	_vehiclesModified = [];
	{
		_classname = _x select 0;
		_quantity = _x select 1;
		switch (_classname) do 
		{
			case "ExileMoney": 
			{
				_money = _playerObject getVariable ["ExileMoney", 0];
				_money = _money - _quantity;
				_playerObject setVariable ["ExileMoney", _money, true];
				format["setPlayerMoney:%1:%2", _money, _playerObject getVariable ["ExileDatabaseID", 0]] call ExileServer_system_database_query_fireAndForget;
			};
			case "ExileScore": 
			{
				_respect = _playerObject getVariable ["ExileScore", 0];
				_respect = _respect - _quantity;
				_playerObject setVariable ["ExileScore", _respect];
				format["setAccountScore:%1:%2", _respect, getPlayerUID _playerObject] call ExileServer_system_database_query_fireAndForget;
				[_sessionID, "updateRespect", [_respect]] call ExileServer_system_network_send_to;
			};
			default 
			{
				try 
				{
					if ([_playerObject, _classname] call ExileClient_util_playerEquipment_contains) then 
					{
						throw [_playerObject, _classname] call ExileClient_util_playerEquipment_remove;
					};
					if (_classname in (_playerObject call ExileClient_util_playerCargo_list)) then 
					{
						throw [_playerObject, _classname] call ExileClient_util_playerCargo_remove;
					};
					{
						if ((owner _x) isEqualTo (owner _playerObject) && {alive _x}) then 
						{
							if (_classname in (_x call ExileClient_util_containerCargo_list)) then 
							{
								_vehiclesModified pushBack _x;
								throw [_x, _classname] call ExileClient_util_containerCargo_remove;
							};
						};
					}
					forEach (nearestObjects [_playerObject, ["LandVehicle", "Air", "Ship"], 80]);
				}
				catch {};
			};
		};
	}
	forEach (_entry select 4);
	_playerObject call ExileServer_object_player_database_update;
	{ _x call ExileServer_object_vehicle_database_update } forEach _vehiclesModified;
	_displayName = getText(configFile >> (_tradeClassname call ExileClient_util_gear_getConfigNameByClassName) >> _tradeClassname >> "displayName");
	if (_isVehicle) then 
	{
		_databaseID = _marxetID call ExileServer_marxet_object_vehicle_getID;
		_vehicleObject = _databaseID call ExileServer_object_vehicle_database_load;
		_vehicleObject setPosATL _position;
		_vehicleObject setVariable ["ExileAccessCode", _pincode];
		_vehicleObject setVariable ["ExileOwnerUID", getPlayerUID(_playerObject)];
		_vehicleObject call ExileServer_object_vehicle_database_update;
		format["marxetUpdateVehicle:%1:%2", _databaseID, getPlayerUID(_playerObject)] call ExileServer_system_database_query_fireAndForget;
	}
	else
	{
		_added = false;
		switch (_tradeClassname) do 
		{
			case "ExileMoney": 
			{
				_money = _playerObject getVariable ["ExileMoney", 0];
				_money = _money + (((_entry select 3) select 1) select 0);
				_playerObject setVariable ["ExileMoney", _money, true];
				format["setPlayerMoney:%1:%2", _money, _playerObject getVariable ["ExileDatabaseID", 0]] call ExileServer_system_database_query_fireAndForget;
				_added = true;
				_displayName = format["%1 Poptabs", (((_entry select 3) select 1) select 0)];
			};
			case "ExileScore": 
			{
				_respect = _playerObject getVariable ["ExileScore", 0];
				_respect = _respect + (((_entry select 3) select 1) select 0);
				_playerObject setVariable ["ExileScore", _respect];
				format["setAccountScore:%1:%2", _respect, getPlayerUID _playerObject] call ExileServer_system_database_query_fireAndForget;
				[_sessionID, "updateRespect", [_respect]] call ExileServer_system_network_send_to;
				_added = true;
				_displayName = format["%1 Respect", (((_entry select 3) select 1) select 0)];
			};
			default 
			{
				switch (_containerType) do
				{
					case 1:
					{
						_added = [_playerObject, _tradeClassname] call ExileClient_util_playerCargo_add;
					};
					case 2:
					{
						_added = [(uniformContainer _playerObject), _tradeClassname] call ExileClient_util_containerCargo_add;
					};
					case 3:
					{
						_added = [(vestContainer _playerObject), _tradeClassname] call ExileClient_util_containerCargo_add;
					};
					case 4:
					{
						_added = [(backpackContainer _playerObject), _tradeClassname] call ExileClient_util_containerCargo_add;
					};
					case 5:
					{
						_vehicle = objectFromNetId _containerNetID;
						_added = [_vehicle, _tradeClassname] call ExileClient_util_containerCargo_add;
					};
				};
			};
		};
		if !(_added) then 
		{
			format["%1. Unable to add to %2, sending to SafeX: %3", _marxetID, getPlayerUID(_playerObject), _tradeClassname] call ExileServer_marxet_util_log;
			[getPlayerUID(_playerObject), [_tradeClassname]] call ExileServer_system_safex_addItem;
			_sentToSafex = true;
		};
	};
	[_sessionID, "tradeResponse", [true, _tradeClassname, _sentToSafex, _pincode]] call ExileServer_system_network_send_to;
	_entry = MarXetTrading getVariable [_marxetID, []];
	_requestorUID = (_entry select 1) select 0;
	_requestorObject = _requestorUID call ExileClient_util_player_objectFromPlayerUID;
	{
		_classname = _x select 0;
		_quantity = _x select 1;
		if (_classname isKindOf "AllVehicles") then 
		{
			_vehicleInfo = { if (toLower(typeOf(objectFromNetID(_x))) isEqualTo toLower(_classname)) exitWith { [_x, _forEachIndex] } } forEach _vehicleNetIDs;
			_vehicle = objectFromNetID(_vehicleInfo select 0);
			[_requestorUID, [_classname, _vehicle getVariable ["ExileDatabaseID", -1]]] call ExileServer_system_safex_addVehicle;
			_vehicleNetIDs deleteAt (_vehicleInfo select 1);
		}
		else
		{
			switch (_classname) do 
			{
				case "ExileMoney": 
				{
					_locker = 0;
					if (isNull _requestorObject) then 
					{
						_locker = format["getLocker:%1", _requestorUID] call ExileServer_system_database_query_selectSingleField;
						_locker = _locker + _quantity;
					}
					else
					{
						_locker = _requestorObject getVariable ["ExileLocker", 0];
						_locker = _locker + _quantity;
						_requestorObject setVariable ["ExileLocker", _locker, true];
					};
					format["updateLocker:%1:%2", _locker, _requestorUID] call ExileServer_system_database_query_fireAndForget;
				};
				case "ExileScore": 
				{
					_respect = 0;
					if (isNull _requestorObject) then 
					{
						_respect = format["getAccountScore:%1", _requestorUID] call ExileServer_system_database_query_selectSingleField;
						_respect = _respect + _quantity;
					}
					else
					{
						_respect = _requestorObject getVariable ["ExileScore", 0];
						_respect = _respect + _quantity;
						_requestorObject setVariable ["ExileScore", _respect];
						[_requestorObject, "updateRespect", [_respect]] call ExileServer_system_network_send_to;
					};
					format["setAccountScore:%1:%2", _respect, _requestorUID] call ExileServer_system_database_query_fireAndForget;
				};
				default 
				{
					format["%1. Sending to %2's SafeX: %3", _marxetID, _requestorUID, [_classname, _quantity]] call ExileServer_marxet_util_log;
					[_requestorUID, [_classname, _quantity]] call ExileServer_system_safex_addItem;
				};
			};
		};
	}
	forEach (_entry select 4);
	if !(isNull _requestorObject) then 
	{
		[
			_requestorObject, 
			"toastRequest", 
			[
				"SuccessTitleAndText", 
				[
					"Trade Complete", 
					format[
						"Your trade of %1 has just been completed.<br/>The requested items have been deposited in your SafeX<br/>Thank you for using Mar<t font='PuristaBold' color='#C72651'>X</t>et, Exile's leading Player Marketplace and Auction House",
						_displayName
					]
				]
			] 
		]
		call ExileServer_system_network_send_to;
	}
	else
	{
		if (isClass(configFile >> "CfgPatches" >> "exile_server_xm8")) then 
		{
			[
				_requestorUID,
				"Trade Completed",
				format[
					"Greetings!\nYour trade of **%1** has just been completed.\nThe following item(s)/vehicle(s) have been deposited in your **SafeX**:\n%2\nThank you for using **MarXet**, Exile's leading Player Marketplace and Auction House",
					_displayName,
					(_entry select 4) call ExileClient_marxet_util_array_formatPretty
				]
			] 
			call ExileServer_system_xm8_sendCustom;
		};
	};
	if (getNumber(missionConfigFile >> "CfgMarXet" >> "Settings" >> "Logging" >> "logToFile") isEqualTo 1) then
	{
		_traderLog = format [
			"PLAYER %1 (%2) COMPLETED A TRADE REQUEST. ID: %3. REQUESTOR UID: %4. TRADE ITEM/VEHICLE: %5. REQUESTED ITEMS/VEHICLES: %6", 
			_playerObject, 
			getPlayerUID(_playerObject),
			_marxetID,
			_requestorUID,
			_tradeClassname,
			_entry select 4
		];
		"extDB3" callExtension format["1:TRADING:%1",_traderLog];
	};
	if (getNumber(missionConfigFile >> "CfgMarXet" >> "Settings" >> "Logging" >> "logToDiscord") isEqualTo 1) then
	{
		[
			"success", 
			"embed", 
			[
				"Trade Completed",
				"",
				[
					["Player Name (UID)", format["%1 (%2)", name _playerObject, getPlayerUID(_playerObject)], true],
					["MarXet ID", _marxetID, true],
					["Requestor's UID", _requestorUID, true],
					["Trading For", _tradeClassname, true],
					["Requested Items/Vehicles", format["```%1```", _entry select 4], true]
				]
			]
		]
		call ESM_fnc_logToDiscord;
	};
	[_marxetID, getPlayerUID(_playerObject)] call ExileServer_marxet_system_request_trading_complete;
}
catch
{
	_marxetID call ExileServer_marxet_system_request_trading_unlock;
	[_sessionID, "tradeResponse", [false, _exception, false, ""]] call ExileServer_system_network_send_to;
};
if (!isNil "_playerObject") then 
{
	_playerObject setVariable ["ExileMutex", false];
};
All opinions represented herein are my own
- © 2024 itsthedevman
- build 3c15a1b