From 557b2f2581555fbf399ea5ef5978d916be4631ad Mon Sep 17 00:00:00 2001 From: vbawol Date: Thu, 17 Sep 2015 11:31:04 -0500 Subject: [PATCH] push server sources --- .../EPOCH_server_handle_sapperObjs.sqf | 23 + .../EPOCH_server_handle_say3D.sqf | 24 + .../EPOCH_server_handle_switchMove.sqf | 32 + .../EPOCH_server_triggerEvent.sqf | 28 + .../epoch_bases/EPOCH_server_changeOwner.sqf | 13 + .../EPOCH_server_loadBuildings.sqf | 134 + .../epoch_bases/EPOCH_server_maintBUILD.sqf | 69 + .../epoch_bases/EPOCH_server_paintBUILD.sqf | 43 + .../epoch_bases/EPOCH_server_removeBUILD.sqf | 164 ++ .../epoch_bases/EPOCH_server_saveBuilding.sqf | 145 + .../EPOCH_server_saveBuildingDamage.sqf | 51 + .../epoch_bases/EPOCH_server_simToStatic.sqf | 30 + .../epoch_bases/EPOCH_server_simulSwap.sqf | 54 + .../epoch_bases/EPOCH_server_unsuppported.sqf | 56 + .../epoch_bases/EPOCH_server_upgradeBUILD.sqf | 62 + .../compile/epoch_bases/fn_saveBuilding.sqf | 25 + .../epoch_group/EPOCH_server_createGroup.sqf | 62 + .../epoch_group/EPOCH_server_deleteGroup.sqf | 31 + .../epoch_group/EPOCH_server_invitePlayer.sqf | 9 + .../EPOCH_server_updatePlayerGroup.sqf | 108 + .../epoch_group/EPOCH_server_upgradeGroup.sqf | 57 + .../EPOCH_server_destroyTrash.sqf | 56 + .../EPOCH_server_knockDownTree.sqf | 35 + .../epoch_looting/EPOCH_server_lootAnimal.sqf | 24 + .../EPOCH_server_lootContainer.sqf | 58 + .../epoch_looting/EPOCH_server_mineRocks.sqf | 44 + .../EPOCH_server_spawnBoatLoot.sqf | 16 + .../EPOCH_Server_airDropCrate.sqf | 22 + .../EPOCH_Server_createAirDrop.sqf | 65 + .../EPOCH_Server_createObject.sqf | 79 + .../EPOCH_Server_fillContainer.sqf | 32 + .../epoch_player/EPOCH_server_checkPlayer.sqf | 54 + .../epoch_player/EPOCH_server_deadPlayer.sqf | 61 + .../EPOCH_server_equippedItem.sqf | 25 + .../epoch_player/EPOCH_server_loadPlayer.sqf | 329 +++ .../EPOCH_server_onPlayerDisconnect.sqf | 26 + .../EPOCH_server_respawnPlayer.sqf | 43 + .../EPOCH_server_revivePlayer.sqf | 250 ++ .../epoch_player/EPOCH_server_savePlayer.sqf | 104 + .../epoch_player/EPOCH_server_storeCrypto.sqf | 114 + .../epoch_server/EPOCH_localCleanup.sqf | 22 + .../epoch_server/EPOCH_serverLootObject.sqf | 114 + .../EPOCH_server_buildingInit.sqf | 2 + .../EPOCH_server_createTeleport.sqf | 76 + .../epoch_server/EPOCH_server_setWeather.sqf | 54 + .../epoch_server/EPOCH_server_storageInit.sqf | 2 + .../EPOCH_server_teleportPlayer.sqf | 13 + .../EPOCH_server_traderKilled.sqf | 16 + .../epoch_server/EPOCH_server_vehicleInit.sqf | 4 + .../epoch_server/EPOCH_test_damage.sqf | 1 + .../EPOCH_server_loadTraders.sqf | 162 ++ .../EPOCH_server_spawnTraders.sqf | 127 + .../EPOCH_server_makeNPCTrade.sqf | 255 ++ .../epoch_trading/EPOCH_server_makeTrade.sqf | 68 + .../epoch_trading/EPOCH_server_takeCrypto.sqf | 30 + .../EPOCH_server_tradeRequest.sqf | 14 + .../epoch_vehicle/EPOCH_fill_inventory.sqf | 13 + .../epoch_vehicle/EPOCH_load_storage.sqf | 202 ++ .../epoch_vehicle/EPOCH_load_vehicles.sqf | 254 ++ .../EPOCH_save_killedBuilding.sqf | 19 + .../EPOCH_save_killedStorage.sqf | 18 + .../EPOCH_save_killedVehicle.sqf | 17 + .../epoch_vehicle/EPOCH_save_storage.sqf | 76 + .../epoch_vehicle/EPOCH_save_vehicle.sqf | 49 + .../epoch_vehicle/EPOCH_save_vehicles.sqf | 15 + .../EPOCH_server_fillVehicle.sqf | 15 + .../EPOCH_server_lockStorage.sqf | 85 + .../EPOCH_server_lockVehicle.sqf | 51 + .../epoch_vehicle/EPOCH_server_packJack.sqf | 12 + .../EPOCH_server_packStorage.sqf | 127 + .../EPOCH_server_repairVehicle.sqf | 22 + .../epoch_vehicle/EPOCH_spawn_vehicle.sqf | 103 + .../epoch_vehicle/EPOCH_spawn_vehicles.sqf | 159 ++ .../compile/epoch_vehicle/test.sqf | 205 ++ Sources/epoch_server/config.cpp | 50 + Sources/epoch_server/init/fn_init.sqf | 8 + Sources/epoch_server/init/fn_postinit.sqf | 9 + Sources/epoch_server/init/server_compiles.sqf | 116 + Sources/epoch_server/init/server_init.sqf | 200 ++ Sources/epoch_server/init/server_publicEH.sqf | 44 + .../init/server_securityfunctions.sqf | 2346 +++++++++++++++++ .../epoch_server/init/server_variables.sqf | 124 + Sources/epoch_server/system/Trader_brain.fsm | 559 ++++ .../epoch_server/system/server_monitor.fsm | 463 ++++ 84 files changed, 8978 insertions(+) create mode 100644 Sources/epoch_server/compile/epoch_antagonists/EPOCH_server_handle_sapperObjs.sqf create mode 100644 Sources/epoch_server/compile/epoch_antagonists/EPOCH_server_handle_say3D.sqf create mode 100644 Sources/epoch_server/compile/epoch_antagonists/EPOCH_server_handle_switchMove.sqf create mode 100644 Sources/epoch_server/compile/epoch_antagonists/EPOCH_server_triggerEvent.sqf create mode 100644 Sources/epoch_server/compile/epoch_bases/EPOCH_server_changeOwner.sqf create mode 100644 Sources/epoch_server/compile/epoch_bases/EPOCH_server_loadBuildings.sqf create mode 100644 Sources/epoch_server/compile/epoch_bases/EPOCH_server_maintBUILD.sqf create mode 100644 Sources/epoch_server/compile/epoch_bases/EPOCH_server_paintBUILD.sqf create mode 100644 Sources/epoch_server/compile/epoch_bases/EPOCH_server_removeBUILD.sqf create mode 100644 Sources/epoch_server/compile/epoch_bases/EPOCH_server_saveBuilding.sqf create mode 100644 Sources/epoch_server/compile/epoch_bases/EPOCH_server_saveBuildingDamage.sqf create mode 100644 Sources/epoch_server/compile/epoch_bases/EPOCH_server_simToStatic.sqf create mode 100644 Sources/epoch_server/compile/epoch_bases/EPOCH_server_simulSwap.sqf create mode 100644 Sources/epoch_server/compile/epoch_bases/EPOCH_server_unsuppported.sqf create mode 100644 Sources/epoch_server/compile/epoch_bases/EPOCH_server_upgradeBUILD.sqf create mode 100644 Sources/epoch_server/compile/epoch_bases/fn_saveBuilding.sqf create mode 100644 Sources/epoch_server/compile/epoch_group/EPOCH_server_createGroup.sqf create mode 100644 Sources/epoch_server/compile/epoch_group/EPOCH_server_deleteGroup.sqf create mode 100644 Sources/epoch_server/compile/epoch_group/EPOCH_server_invitePlayer.sqf create mode 100644 Sources/epoch_server/compile/epoch_group/EPOCH_server_updatePlayerGroup.sqf create mode 100644 Sources/epoch_server/compile/epoch_group/EPOCH_server_upgradeGroup.sqf create mode 100644 Sources/epoch_server/compile/epoch_looting/EPOCH_server_destroyTrash.sqf create mode 100644 Sources/epoch_server/compile/epoch_looting/EPOCH_server_knockDownTree.sqf create mode 100644 Sources/epoch_server/compile/epoch_looting/EPOCH_server_lootAnimal.sqf create mode 100644 Sources/epoch_server/compile/epoch_looting/EPOCH_server_lootContainer.sqf create mode 100644 Sources/epoch_server/compile/epoch_looting/EPOCH_server_mineRocks.sqf create mode 100644 Sources/epoch_server/compile/epoch_looting/EPOCH_server_spawnBoatLoot.sqf create mode 100644 Sources/epoch_server/compile/epoch_missions/EPOCH_Server_airDropCrate.sqf create mode 100644 Sources/epoch_server/compile/epoch_missions/EPOCH_Server_createAirDrop.sqf create mode 100644 Sources/epoch_server/compile/epoch_missions/EPOCH_Server_createObject.sqf create mode 100644 Sources/epoch_server/compile/epoch_missions/EPOCH_Server_fillContainer.sqf create mode 100644 Sources/epoch_server/compile/epoch_player/EPOCH_server_checkPlayer.sqf create mode 100644 Sources/epoch_server/compile/epoch_player/EPOCH_server_deadPlayer.sqf create mode 100644 Sources/epoch_server/compile/epoch_player/EPOCH_server_equippedItem.sqf create mode 100644 Sources/epoch_server/compile/epoch_player/EPOCH_server_loadPlayer.sqf create mode 100644 Sources/epoch_server/compile/epoch_player/EPOCH_server_onPlayerDisconnect.sqf create mode 100644 Sources/epoch_server/compile/epoch_player/EPOCH_server_respawnPlayer.sqf create mode 100644 Sources/epoch_server/compile/epoch_player/EPOCH_server_revivePlayer.sqf create mode 100644 Sources/epoch_server/compile/epoch_player/EPOCH_server_savePlayer.sqf create mode 100644 Sources/epoch_server/compile/epoch_player/EPOCH_server_storeCrypto.sqf create mode 100644 Sources/epoch_server/compile/epoch_server/EPOCH_localCleanup.sqf create mode 100644 Sources/epoch_server/compile/epoch_server/EPOCH_serverLootObject.sqf create mode 100644 Sources/epoch_server/compile/epoch_server/EPOCH_server_buildingInit.sqf create mode 100644 Sources/epoch_server/compile/epoch_server/EPOCH_server_createTeleport.sqf create mode 100644 Sources/epoch_server/compile/epoch_server/EPOCH_server_setWeather.sqf create mode 100644 Sources/epoch_server/compile/epoch_server/EPOCH_server_storageInit.sqf create mode 100644 Sources/epoch_server/compile/epoch_server/EPOCH_server_teleportPlayer.sqf create mode 100644 Sources/epoch_server/compile/epoch_server/EPOCH_server_traderKilled.sqf create mode 100644 Sources/epoch_server/compile/epoch_server/EPOCH_server_vehicleInit.sqf create mode 100644 Sources/epoch_server/compile/epoch_server/EPOCH_test_damage.sqf create mode 100644 Sources/epoch_server/compile/epoch_traders/EPOCH_server_loadTraders.sqf create mode 100644 Sources/epoch_server/compile/epoch_traders/EPOCH_server_spawnTraders.sqf create mode 100644 Sources/epoch_server/compile/epoch_trading/EPOCH_server_makeNPCTrade.sqf create mode 100644 Sources/epoch_server/compile/epoch_trading/EPOCH_server_makeTrade.sqf create mode 100644 Sources/epoch_server/compile/epoch_trading/EPOCH_server_takeCrypto.sqf create mode 100644 Sources/epoch_server/compile/epoch_trading/EPOCH_server_tradeRequest.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_fill_inventory.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_load_storage.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_load_vehicles.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_killedBuilding.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_killedStorage.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_killedVehicle.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_storage.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_vehicle.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_vehicles.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_fillVehicle.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_lockStorage.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_lockVehicle.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_packJack.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_packStorage.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_repairVehicle.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_spawn_vehicle.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/EPOCH_spawn_vehicles.sqf create mode 100644 Sources/epoch_server/compile/epoch_vehicle/test.sqf create mode 100644 Sources/epoch_server/config.cpp create mode 100644 Sources/epoch_server/init/fn_init.sqf create mode 100644 Sources/epoch_server/init/fn_postinit.sqf create mode 100644 Sources/epoch_server/init/server_compiles.sqf create mode 100644 Sources/epoch_server/init/server_init.sqf create mode 100644 Sources/epoch_server/init/server_publicEH.sqf create mode 100644 Sources/epoch_server/init/server_securityfunctions.sqf create mode 100644 Sources/epoch_server/init/server_variables.sqf create mode 100644 Sources/epoch_server/system/Trader_brain.fsm create mode 100644 Sources/epoch_server/system/server_monitor.fsm diff --git a/Sources/epoch_server/compile/epoch_antagonists/EPOCH_server_handle_sapperObjs.sqf b/Sources/epoch_server/compile/epoch_antagonists/EPOCH_server_handle_sapperObjs.sqf new file mode 100644 index 00000000..ddf3361b --- /dev/null +++ b/Sources/epoch_server/compile/epoch_antagonists/EPOCH_server_handle_sapperObjs.sqf @@ -0,0 +1,23 @@ +private["_trgt","_obj","_unit","_safeUnits","_obj2"]; +_obj = _this select 0; +_trgt = _this select 1; + +if !([_trgt,_this select 2]call EPOCH_server_getPToken)exitWith{}; +diag_log format["DEBUG: Calling Sapper Detonate Player:%1 | Bomb: %2 | PToken: %3 ",_trgt,_obj,_this select 2]; + +_safeUnits = ["Epoch_Sapper_F","Epoch_SapperB_F"]; + +_unit = _this select 3; +//diag_log format ["DEBUG: Performing Sapper Detonate with %1 for %2",_unit,_trgt]; + +_obj2 = objNull; +if(count _this > 4)then{ + _obj2 = _this select 4; +}; + +if!(typeOf _unit in _safeUnits)exitWith{}; + +_obj setDamage 1; +if!(isNull _obj2)then{ + _obj2 setDamage 1; +}; diff --git a/Sources/epoch_server/compile/epoch_antagonists/EPOCH_server_handle_say3D.sqf b/Sources/epoch_server/compile/epoch_antagonists/EPOCH_server_handle_say3D.sqf new file mode 100644 index 00000000..a69a21b8 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_antagonists/EPOCH_server_handle_say3D.sqf @@ -0,0 +1,24 @@ +/* +3d sound system + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private["_range", "_nearBy", "_target", "_soundIndex", "_sound"]; + +if !([_this select 0, _this select 3] call EPOCH_server_getPToken) exitWith{}; + +_target = _this select 1; +if (isNull _target) exitWith {}; +_soundIndex = _this select 2; +_sound = EPOCH_sounds select _soundIndex; + +if (!isNil "_sound") then { + _range = getNumber(configFile >> "CfgSay3Dhandler" >> _sound >> "distance"); + _nearBy = _target nearEntities [["Epoch_Male_F","Epoch_Female_F","LandVehicle","Ship","Air","Tank"], _range]; + { + if (isPlayer _x) then { + [["say3D", [_target, _soundIndex]], owner _x] call EPOCH_sendPublicVariableClient + } + }forEach (_nearBy - [_this select 0]); //_this select 0 == the caller, play the sound already locally! +}; diff --git a/Sources/epoch_server/compile/epoch_antagonists/EPOCH_server_handle_switchMove.sqf b/Sources/epoch_server/compile/epoch_antagonists/EPOCH_server_handle_switchMove.sqf new file mode 100644 index 00000000..f04fc70e --- /dev/null +++ b/Sources/epoch_server/compile/epoch_antagonists/EPOCH_server_handle_switchMove.sqf @@ -0,0 +1,32 @@ +/* +Player Animations + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private["_range", "_move", "_nearBy", "_target"]; + +_target = _this select 0; + +if !([_target, _this select 2] call EPOCH_server_getPToken) exitWith{}; + +_range = 0; +_move = ""; + +switch (_this select 1) do { + case 1: { + _range = 1000; + _move = "AovrPercMrunSrasWrflDf"; + }; + case 2: { + _range = 1000; + _move = "epoch_unarmed_jump"; + }; +}; + +if (_range > 0 && _move != "") then { + _nearBy = _target nearEntities [["Epoch_Male_F","Epoch_Female_F"], _range]; + { + [["switchMove", [_target, _move]], (owner _x)] call EPOCH_sendPublicVariableClient; + }forEach (_nearBy - [_target]); //_target == the caller, already plays the animation locally! +}; diff --git a/Sources/epoch_server/compile/epoch_antagonists/EPOCH_server_triggerEvent.sqf b/Sources/epoch_server/compile/epoch_antagonists/EPOCH_server_triggerEvent.sqf new file mode 100644 index 00000000..01535b3c --- /dev/null +++ b/Sources/epoch_server/compile/epoch_antagonists/EPOCH_server_triggerEvent.sqf @@ -0,0 +1,28 @@ +private ["_target"]; +_target = _this select 0; +if (!isNull _target) then { + switch (_this select 1) do { + case "UAV": { + [["unitSpawn", "I_UAV_01_F"], (owner _target)] call EPOCH_sendPublicVariableClient; + }; + case "Cloak": { + if (sunOrMoon < 1) then { + [["unitSpawn", "Epoch_Cloak_F"], (owner _target)] call EPOCH_sendPublicVariableClient; + } else { + [["unitSpawn", "Epoch_Sapper_F"], (owner _target)] call EPOCH_sendPublicVariableClient; + }; + }; + case "Sapper": { + [["unitSpawn", "Epoch_Sapper_F"], (owner _target)] call EPOCH_sendPublicVariableClient; + }; + case "GreatWhite": { + [["unitSpawn", "GreatWhite_F"], (owner _target)] call EPOCH_sendPublicVariableClient; + }; + case "SapperB": { + [["unitSpawn", "Epoch_SapperB_F"], (owner _target)] call EPOCH_sendPublicVariableClient; + }; + case "PHANTOM": { + [["unitSpawn", "PHANTOM"], (owner _target)] call EPOCH_sendPublicVariableClient; + }; + }; +}; diff --git a/Sources/epoch_server/compile/epoch_bases/EPOCH_server_changeOwner.sqf b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_changeOwner.sqf new file mode 100644 index 00000000..73ee7a25 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_changeOwner.sqf @@ -0,0 +1,13 @@ +private ["_result","_object","_newOwner"]; +_object = _this select 0; +_newOwner = owner (_this select 1); +_result = false; +if (!isNull _object) then { + if (local _object) then { + if ((owner _object) != _newOwner) then { + _result = _object setOwner _newOwner; + diag_log format["DEBUG CHANGEOWNER: %1 OWNER: %2 PLAYER: %3 RESULT: %4", _object,owner(_object),_newOwner,_result]; + }; + }; +}; +_result \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_bases/EPOCH_server_loadBuildings.sqf b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_loadBuildings.sqf new file mode 100644 index 00000000..4c0d2d5e --- /dev/null +++ b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_loadBuildings.sqf @@ -0,0 +1,134 @@ +/* +Load Buildings + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ + +_maxTTL = parseNumber EPOCH_expiresBuilding; +_config = 'CfgEpochClient' call EPOCH_returnConfig; +_buildingJammerRange = getNumber(_config >> "buildingJammerRange"); +if (_buildingJammerRange == 0) then { _buildingJammerRange = 75; }; + +for "_i" from 0 to _this do { + _vehHiveKey = format ["%1:%2", (call EPOCH_fn_InstanceID),_i]; + _response = ["Building", _vehHiveKey] call EPOCH_fnc_server_hiveGETTTL; + + if ((_response select 0) == 1 && typeName (_response select 1) == "ARRAY" && !((_response select 1) isEqualTo [])) then { + _arr = _response select 1; + _ttl = _response select 2; + + _arrCount = count _arr; + + _class = _arr select 0; + _worldspace = _arr select 1; + + _storageSlot = "-1"; + if (_arrCount >= 3) then { + if ((typeName (_arr select 2)) == "SCALAR") then { + _storageSlot = str(_arr select 2); + } else { + _storageSlot = _arr select 2; + }; + // diag_log format ["DEBUG _class: %1 _worldspace: %2 _storageSlot: %3", _class, _worldspace, _storageSlot]; + }; + + _owner = "-1"; + if (_arrCount >= 4) then { + _owner = _arr select 3; + }; + + // load texture index + _textureSlot = 0; + if (_arrCount >= 5) then { + _textureSlot = _arr select 4; + }; + + + + + + // experiment with damage factor based on time only for now. + _damage = ((1 - (_ttl / _maxTTL)) min 1) max 0; + + _location = _worldspace deleteAt 0; + + // increased position precision + if (count _location == 2) then{ + _location = (_location select 0) vectorAdd (_location select 1); + }; + + if (isClass (configFile >> "CfgVehicles" >> _class) && (_damage < 1)) then { + _baseObj = createVehicle [_class, _location, [], 0, "CAN_COLLIDE"]; + + _baseObj setVectorDirAndUp _worldspace; + _baseObj setposATL _location; + + if (_arrCount >= 6) then{ + _anims = _arr param[5, [], [[]]]; + { + _baseObj animate [_x, _anims param [_forEachIndex,0], true] + } foreach(getArray(configFile >> "CfgVehicles" >> _class >> "persistAnimations")); + }; + + // TODO make config based + if (_class == "PlotPole_EPOCH") then { + if (EPOCH_SHOW_JAMMERS) then { + _marker = createMarker[str(_location), _location]; + _marker setMarkerShape "ICON"; + // TODO allow players to change this per base + _marker setMarkerType "mil_dot"; + // _marker setMarkerText _class; + _marker setMarkerColor "ColorBlue"; + }; + }; + if (_class == "LockBox_EPOCH") then { + if ((_location select 2) < 0) then { + _location set [2, 0]; + _baseObj setposATL _location; + }; + + if (_storageSlot != "-1") then { + _baseObj setVariable ["EPOCH_secureStorage", _storageSlot]; + _baseObj setVariable ["EPOCH_Locked", true, true]; + }; + }; + + _baseObj setDamage _damage; + _baseObj call EPOCH_server_buildingInit; + _baseObj setVariable ["BUILD_SLOT", _i, true]; + + if (_owner != "-1") then { + _baseObj setVariable ["BUILD_OWNER", _owner, true]; + }; + + if (_textureSlot != 0) then { + // get texture path from index + _color = getArray (configFile >> "CfgVehicles" >> _class >> "availableTextures"); + if !(_color isEqualTo []) then { + _baseObj setObjectTextureGlobal [0, (_color select _textureSlot)]; + _baseObj setVariable ["TEXTURE_SLOT", _textureSlot, true]; + }; + }; + + missionNamespace setVariable [format ["EPOCH_BUILD_%1",_i], _baseObj]; + + EPOCH_BuildingSlots set [_i,1]; + if (EPOCH_DEBUG_VEH) then { + _marker = createMarker [str(_location) , _location]; + _marker setMarkerShape "ICON"; + _marker setMarkerType "mil_dot"; + _marker setMarkerText _class; + _marker setMarkerColor "ColorRed"; + }; + } else { //Need Hivecall to delete the object out of the DB! + EPOCH_BuildingSlots set [_i,0]; + }; + } + else { + EPOCH_BuildingSlots set [_i,0]; + }; +}; +EPOCH_BuildingSlotCount = {_x == 0} count EPOCH_BuildingSlots; +publicVariable "EPOCH_BuildingSlotCount"; +true diff --git a/Sources/epoch_server/compile/epoch_bases/EPOCH_server_maintBUILD.sqf b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_maintBUILD.sqf new file mode 100644 index 00000000..d352303f --- /dev/null +++ b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_maintBUILD.sqf @@ -0,0 +1,69 @@ +/* +Building Maintain + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private["_object", "_plyr", "_maintCount", "_plyrUID", "_counter", "_objSlot", "_objHiveKey", "_buildingJammerRange", "_current_crypto", "_cIndex", "_vars"]; + +_object = _this select 0; +_plyr = _this select 1; +_maintCount = _this select 2; + +if !([_plyr, _this select 3] call EPOCH_server_getPToken) exitWith{}; +if (isNull _object) exitWith{}; +if (_plyr distance _object > 20) exitWith{}; +_config = 'CfgEpochClient' call EPOCH_returnConfig; +_buildingJammerRange = getNumber(_config >> "buildingJammerRange"); +if (_buildingJammerRange == 0) then { _buildingJammerRange = 75; }; + +_plyrUID = getPlayerUID _plyr; +_counter = 0; + +if (typeOf _object == "PlotPole_EPOCH") then { + // maintain pole + + _objSlot = _object getVariable["BUILD_SLOT", -1]; + if (_objSlot != -1) then { + + // get vars array and current Crypto value + _cIndex = EPOCH_customVars find "Crypto"; + _vars = _plyr getVariable["VARS", [] + EPOCH_defaultVars_SEPXVar]; + _current_crypto = _vars select _cIndex; + + if (_current_crypto >= _maintCount) then { + + // maintain jammer + _counter = _counter + 1; + _object call EPOCH_fnc_saveBuilding; + + if (_maintCount > 1) then { + // maintain all objects within range + { + _object = _x; + _objSlot = _object getVariable["BUILD_SLOT", -1]; + if (_objSlot != -1) then { + if ((damage _object) > 0) then { + _counter = _counter + 1; + _object call EPOCH_fnc_saveBuilding; + }; + }; + if (_counter >= _maintCount) exitWith{}; + } forEach nearestObjects[_object, ["Constructions_static_F","Constructions_foundation_F"], _buildingJammerRange]; + + // effect crypto + + _playerCryptoLimit = [(configFile >> "CfgSecConf" >> "limits"), "playerCrypto", 25000] call EPOCH_fnc_returnConfigEntry; + + _current_crypto = ((_current_crypto - _counter) min _playerCryptoLimit) max 0; + [["effectCrypto", _current_crypto], (owner _plyr)] call EPOCH_sendPublicVariableClient; + _vars set[_cIndex, _current_crypto]; + _plyr setVariable["VARS", _vars]; + + }; + diag_log format["ADMIN: %1 maintained %2 base objects at %3", _plyrUID, _counter, getPosATL(_this select 0)]; + }; + + }; + +}; diff --git a/Sources/epoch_server/compile/epoch_bases/EPOCH_server_paintBUILD.sqf b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_paintBUILD.sqf new file mode 100644 index 00000000..7698c9e3 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_paintBUILD.sqf @@ -0,0 +1,43 @@ +/* +Building Paint + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private["_color", "_class", "_object", "_textureSlot", "_currentTextureSlot", "_plyr", "_slot", "_worldspace", "_objHiveKey", "_VAL", "_return", "_plyrUID", "_objSlot"]; + +_object = _this select 0; +_textureSlot = _this select 1; +_plyr = _this select 2; + +if !([_plyr, _this select 3] call EPOCH_server_getPToken) exitWith{}; +if (isNull _object) exitWith{}; +if (_plyr distance _object > 20) exitWith{}; + +_plyrUID = getPlayerUID _plyr; + +_objSlot = _object getVariable["BUILD_SLOT", -1]; +if (_objSlot != -1) then { + + _currentTextureSlot = _object getVariable["TEXTURE_SLOT", 0]; + if (_textureSlot != _currentTextureSlot) then { + + // get texture path from index + _class = typeOf _object; + _color = getArray(configFile >> "CfgVehicles" >> _class >> "availableTextures"); + if !(_color isEqualTo[]) then { + _object setObjectTextureGlobal[0, (_color select _textureSlot)]; + _object setVariable["TEXTURE_SLOT", _textureSlot, true]; + + // save building with new color + // _slot = "-1"; + // _worldspace = [(getposATL _object call EPOCH_precisionPos), (vectordir _object), (vectorup _object)]; + // _objHiveKey = format["%1:%2", (call EPOCH_fn_InstanceID), _objSlot]; + + _object call EPOCH_fnc_saveBuilding; + + //_VAL = [_class, _worldspace, _slot, _plyrUID, _textureSlot, _animPhases]; + //_return = ["Building", _objHiveKey, EPOCH_expiresBuilding, _VAL] call EPOCH_fnc_server_hiveSETEX; + }; + }; +}; diff --git a/Sources/epoch_server/compile/epoch_bases/EPOCH_server_removeBUILD.sqf b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_removeBUILD.sqf new file mode 100644 index 00000000..7bb663fb --- /dev/null +++ b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_removeBUILD.sqf @@ -0,0 +1,164 @@ +/* +Building Remove + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private["_vehSlot", "_building", "_player", "_gwh", "_wepsItemsCargo", "_magsAmmoCargo", "_objTypes", "_objQty", "_magazine", "_weapon", "_suppressor", "_laser", "_optics", "_arrCount", "_magazineName", "_magazineSize", "_qty", "_objType", "_inventory", "_posWH", "_nearbyWH", "_removeParts", "_isTemporary", "_storageSlot"]; + +_building = _this select 0; +_player = _this select 1; + +if !([_player, _this select 2] call EPOCH_server_getPToken) exitWith{}; +if (isNull _building) exitWith{}; +if (_player distance _building > 20) exitWith{}; + +// TODO add group check here since this should only be removed by group or owner of pole +_objType = typeOf _building; + +_isTemporary = getNumber(configFile >> "CfgVehicles" >> _objType >> "isTemporary"); + +// check that object has building or storage slot +_vehSlot = _building getVariable["BUILD_SLOT", -1]; +_storageSlot = _building getVariable["STORAGE_SLOT", "ABORT"]; + +if (_vehSlot != -1 || _storageSlot != "ABORT" || _isTemporary == 1) then{ + + _removeParts = getArray(('CfgBaseBuilding' call EPOCH_returnConfig) >> _objType >> "removeParts"); + if !(_removeParts isEqualTo []) then { + + _posWH = getPosATL _player; + _gwh = objNull; + // give player a refund of parts + _nearbyWH = nearestObjects[_posWH, ["groundWeaponHolder"], 2]; + if !(_nearbyWH isEqualTo[]) then{ + _gwh = _nearbyWH select 0; + // _posWH = getPosATL _gwh; + } else { + _gwh = createVehicle["groundWeaponHolder", _posWH, [], 0, "CAN_COLLIDE"]; + _gwh setPosATL _posWH; + }; + + if !(isNull _gwh) then{ + + // if normal storage device dump items on ground. + if (_building isKindOf "Buildable_Storage") then { + + // may not be needed but should prevent in DB. + _wepsItemsCargo = weaponsItemsCargo _building; + if (isNil "_wepsItemsCargo") then{ + _wepsItemsCargo = []; + }; + _magsAmmoCargo = magazinesAmmoCargo _building; + if (isNil "_magsAmmoCargo") then{ + _magsAmmoCargo = []; + }; + + // dump items on ground + _inventory = [ + _wepsItemsCargo, + _magsAmmoCargo, + getBackpackCargo _building, + getItemCargo _building + ]; + + [_building, _player] call EPOCH_server_save_killedStorage; + deleteVehicle _building; + + { + _objType = _forEachIndex; + + _objTypes = _x; + _objQty = []; + + if (_objType in[2, 3]) then{ + _objTypes = _x select 0; + _objQty = _x select 1; + }; + + { + switch _objType do { + case 0: { + if (typeName _x == "ARRAY") then{ + _arrCount = count _x; + if (_arrCount >= 4) then{ + + _gwh addWeaponCargoGlobal[_x deleteAt 0, 1]; + + _attachments = []; + _wMags = false; + _wMagsArray = []; + // suppressor, laser, optics, magazines(array), bipods + { + // magazines + if (typeName(_x) == "ARRAY") then{ + _wMags = true; + _wMagsArray = _x; + } + else { + // attachments + if (_x != "") then{ + _attachments pushBack _x; + }; + }; + } forEach _x; + + // add all attachments to vehicle + // TODO replace with adding attachments directly to gun (Arma feature dependant) + { + _gwh addItemCargoGlobal[_x, 1]; + } forEach _attachments; + + if (_wMags) then{ + if (typeName _wMagsArray == "ARRAY" && (count _wMagsArray) >= 2) then{ + _gwh addMagazineAmmoCargo[_wMagsArray select 0, 1, _wMagsArray select 1]; + }; + }; + + }; + }; + }; + case 1: { + if (typeName _x == "ARRAY") then{ + if ((count _x) == 2) then{ + _magazineName = _x select 0; + _magazineSize = _x select 1; + + if ((typeName _magazineName == "STRING") && (typeName _magazineSize == "SCALAR")) then{ + _gwh addMagazineAmmoCargo[_magazineName, 1, _magazineSize]; + }; + }; + }; + }; + case 2: { + if (typeName _x == "STRING") then{ + _qty = _objQty select _forEachIndex; + _gwh addBackpackCargoGlobal[_x, _qty]; + }; + }; + case 3: { + if (typeName _x == "STRING") then{ + _qty = _objQty select _forEachIndex; + _gwh addItemCargoGlobal[_x, _qty]; + }; + }; + }; + }forEach _objTypes; + }forEach _inventory; + + } else { + + [_building, _player] call EPOCH_server_save_killedBuilding; + deleteVehicle _building; + }; + + + // Normal config based payout + { + _gwh addMagazineCargoGlobal[_x select 0, _x select 1]; + } forEach _removeParts; + }; + + }; + +}; diff --git a/Sources/epoch_server/compile/epoch_bases/EPOCH_server_saveBuilding.sqf b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_saveBuilding.sqf new file mode 100644 index 00000000..872806b2 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_saveBuilding.sqf @@ -0,0 +1,145 @@ +/* +Building Save + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private["_objSlot", "_findnextslot", "_worldspace", "_objHiveKey", "_VAL", "_config", "_slot", "_storageObj", "_pos", "_buildClass", "_newVehicle", "_textureSlot", "_staticClass", "_vehicle", "_plyr", "_plyrUID", "_oemType"]; + +_vehicle = _this select 0; +_plyr = _this select 1; + +if (isNull _vehicle || isNull _plyr) exitWith{}; +if !([_plyr,_this select 2] call EPOCH_server_getPToken) exitWith {}; + +_plyrUID = getPlayerUID _plyr; + +if (!isNull ropeAttachedTo _vehicle) exitWith{}; + +_oemType = typeOf _vehicle; +_config = (configFile >> "CfgVehicles" >> _oemType >> "staticClass"); +if (isText _config) then { + _staticClass = getText(_config); + + if (_staticClass isKindOf "Buildable_Storage") then { + + if !(EPOCH_StorageSlots isEqualTo[]) then { + + _config = (configFile >> "CfgVehicles" >> _oemType >> "staticClass"); + if (isText(_config)) then { + + _slot = EPOCH_StorageSlots select 0; + EPOCH_StorageSlots = EPOCH_StorageSlots - [_slot]; + + _vehiclePos = getposATL _vehicle; + _worldspace = [(_vehiclePos call EPOCH_precisionPos), vectordir _vehicle, vectorup _vehicle]; + deleteVehicle _vehicle; + + _storageObj = createVehicle[_staticClass, _vehiclePos, [], 0, "CAN_COLLIDE"]; + _storageObj setVariable["STORAGE_SLOT", _slot, true]; + + _storageObj setVectorDirAndUp[_worldspace select 1, _worldspace select 2]; + _storageObj setposATL _vehiclePos; + + _storageObj call EPOCH_server_save_storage; + _storageObj call EPOCH_server_storageInit; + + diag_log format["STORAGE: %1 created storage %2 at %3", getPlayerUID _plyr, _staticClass, _vehiclePos]; + + EPOCH_StorageSlotsCount = count EPOCH_StorageSlots; + publicVariable "EPOCH_StorageSlotsCount"; + }; + }; + + } else { + + // TODO: optimize by using config var + if (_vehicle isKindOf "ThingX" || _vehicle isKindOf "Const_Ghost_EPOCH" || _vehicle isKindOf "PlotPole_EPOCH") then { + + _objSlot = _vehicle getVariable["BUILD_SLOT", -1]; + if (_objSlot == -1) then { + _findnextslot = EPOCH_BuildingSlots find 0; + if (_findnextslot != -1) then { + _objSlot = _findnextslot; + EPOCH_BuildingSlots set [_findnextslot,1]; + _vehicle setVariable["BUILD_SLOT", _findnextslot, true]; + }; + }; + + // get texture slot index + _textureSlot = _vehicle getVariable["TEXTURE_SLOT", 0]; + + EPOCH_BuildingSlotCount = { _x == 0 } count EPOCH_BuildingSlots; + publicVariable "EPOCH_BuildingSlotCount"; + + + if (_objSlot != -1) then { + _vehiclePos = getposATL _vehicle; + // _worldspace = [(_vehiclePos call EPOCH_precisionPos), vectordir _vehicle, vectorup _vehicle]; + // _objHiveKey = format["%1:%2", (call EPOCH_fn_InstanceID), _objSlot]; + + _newVehicle = [_vehicle, false] call EPOCH_server_simulSwap; + + missionNamespace setVariable[format["EPOCH_BUILD_%1", _objSlot], _newVehicle]; + + _newVehicle setVariable["BUILD_OWNER", _plyrUID, true]; + + _slot = "-1"; + // TODO change to config based classes + if (_oemType == "LockBox_SIM_EPOCH") then { + + //diag_log format["building lockbox %1", _oemType]; + + _buildClass = "LockBoxProxy_EPOCH"; + + if (!isNull _newVehicle) then { + + diag_log format["building lockbox !isnull %1", _newVehicle]; + + if !(EPOCH_StorageSlots isEqualTo []) then { + + //diag_log format["building lockbox findslot %1", _newVehicle]; + + // TODO need some sanity checks here + _storageObj = createVehicle[_buildClass, _vehiclePos, [], 0.0, "CAN_COLLIDE"]; + + _slot = EPOCH_StorageSlots select 0; + EPOCH_StorageSlots = EPOCH_StorageSlots - [_slot]; + + //diag_log format["building lockbox found slot %1", _slot]; + + missionNamespace setVariable[format["EPOCH_STORAGE_%1", _slot], _storageObj]; + + _newVehicle setVariable["EPOCH_secureStorage", _slot]; + _newVehicle setVariable["EPOCH_Locked", false, true]; + + _storageObj setVariable["STORAGE_OWNERS", [_plyrUID]]; + _storageObj setVariable["EPOCH_secStorParent", _objSlot]; + _storageObj setVariable["STORAGE_SLOT", _slot, true]; + + _storageObj call EPOCH_server_save_storage; + + _storageObj call EPOCH_server_storageInit; + + diag_log format["STORAGE: %1 created storage %2 at %3", _plyrUID, _buildClass, _pos]; + + EPOCH_StorageSlotsCount = count EPOCH_StorageSlots; + publicVariable "EPOCH_StorageSlotsCount"; + }; + }; + }; + + _newVehicle call EPOCH_fnc_saveBuilding; + + // _VAL = [_staticClass, _worldspace, _slot, _plyrUID, _textureSlot, _animPhases]; + // ["Building", _objHiveKey, EPOCH_expiresBuilding, _VAL] call EPOCH_fnc_server_hiveSETEX; + //_return = ["Building", _objHiveKey, _VAL] call EPOCH_fnc_server_hiveSET; + }; + + } else { + diag_log format["DEBUG BUILD SAVE ABORT TYPE ERROR: %1", _this] + }; + + }; +}; +true diff --git a/Sources/epoch_server/compile/epoch_bases/EPOCH_server_saveBuildingDamage.sqf b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_saveBuildingDamage.sqf new file mode 100644 index 00000000..2fb7275f --- /dev/null +++ b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_saveBuildingDamage.sqf @@ -0,0 +1,51 @@ +/* +Building Save Damage + +Epoch Mod - EpochMod.com +All Rights Reserved. + +private["_class", "_worldspace", "_VAL", "_storageSlot", "_owner", "_textureSlot", "_arr", "_arrCount", "_bldHiveKey", "_response", "_vehicle", "_slot"]; + +_vehicle = _this; + +if (alive _vehicle) then { + _slot = _vehicle getVariable["BUILD_SLOT", -1]; + if (_slot != -1) then { + + _bldHiveKey = format["%1:%2", (call EPOCH_fn_InstanceID), _slot]; + _response = ["Building", _bldHiveKey] call EPOCH_fnc_server_hiveGETRANGE; + + if ((_response select 0) == 1 && typeName(_response select 1) == "ARRAY" && !((_response select 1) isEqualTo[])) then { + _arr = _response select 1; + _arrCount = count _arr; + + _class = _arr select 0; + _worldspace = _arr select 1; + + _storageSlot = "-1"; + if (_arrCount >= 3) then { + if ((typeName(_arr select 2)) == "SCALAR") then { + _storageSlot = str(_arr select 2); + } else { + _storageSlot = _arr select 2; + }; + }; + + _owner = "-1"; + if (_arrCount >= 4) then { + _owner = _arr select 3; + }; + + _textureSlot = 0; + if (_arrCount >= 5) then { + _textureSlot = _arr select 4; + }; + + _VAL = [_class, _worldspace, _storageSlot, _owner, _textureSlot, damage _vehicle]; + ["Building", _bldHiveKey, EPOCH_expiresBuilding, _VAL] call EPOCH_fnc_server_hiveSETEX; + + }; + }; +}; + +*/ \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_bases/EPOCH_server_simToStatic.sqf b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_simToStatic.sqf new file mode 100644 index 00000000..ec52a3f8 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_simToStatic.sqf @@ -0,0 +1,30 @@ +/* +Building - Converts to static all simulated objects that have not moved since last check + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private ["_worldspace","_newObj","_class","_objSlot","_config","_lastPosition","_currentPosition","_entities"]; +_entities = allMissionObjects "Constructions_modular_F"; +{ + _lastPosition = _x getVariable["LAST_POS", []]; + _currentPosition = getposATL _x; + if (_lastPosition isEqualTo _currentPosition) then { + _config = (configFile >> "CfgVehicles" >> (typeOf _x) >> "staticClass"); + if (isText(_config)) then { + _class = getText(_config); + _objSlot = _x getVariable["BUILD_SLOT", -1]; + if (_objSlot != -1) then { + _worldspace = [_currentPosition,(vectordir _x),(vectorup _x)]; + deleteVehicle _x; + _newObj = createVehicle [_class, (_worldspace select 0), [], 0, "CAN_COLLIDE"]; + _newObj setVariable ["BUILD_SLOT",_objSlot,true]; + _newObj call EPOCH_server_buildingInit; + _newObj setVectorDirAndUp [(_worldspace select 1),(_worldspace select 2)]; + _newObj setposATL (_worldspace select 0); + }; + }; + }; + _x setVariable ["LAST_POS",_currentPosition]; + uiSleep 1; +} forEach _entities; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_bases/EPOCH_server_simulSwap.sqf b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_simulSwap.sqf new file mode 100644 index 00000000..88f5883e --- /dev/null +++ b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_simulSwap.sqf @@ -0,0 +1,54 @@ +/* +Building - Sim to Static + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private["_cfgClass", "_worldspace", "_newObj", "_return", "_class", "_oemType", "_config", "_object", "_objSlot", "_damage", "_color", "_textureSlot"]; + +_object = _this select 0; +_return = _object; + +_objSlot = _object getVariable ["BUILD_SLOT", -1]; +if (_objSlot != -1) then { + + _cfgClass = "staticClass"; + if (_this select 1) then { + _cfgClass = "simulClass"; + }; + _oemType = typeOf _object; + + _config = (configFile >> "CfgVehicles" >> _oemType >> _cfgClass); + if (isText _config) then { + _class = getText(_config); + + if (_oemType != _class) then { + + _textureSlot = _object getVariable["TEXTURE_SLOT", 0]; + _damage = damage _object; + + _worldspace = [getposATL _object,vectordir _object,vectorup _object]; + deleteVehicle _object; + + _newObj = createVehicle [_class, _worldspace select 0, [], 0, "CAN_COLLIDE"]; + _newObj setVariable ["BUILD_SLOT",_objSlot,true]; + _newObj call EPOCH_server_buildingInit; + + if (_textureSlot != 0) then { + // get texture path from index + _color = getArray(configFile >> "CfgVehicles" >> _class >> "availableTextures"); + if !(_color isEqualTo[]) then { + _newObj setObjectTextureGlobal[0, (_color select _textureSlot)]; + _newObj setVariable["TEXTURE_SLOT", _textureSlot, true]; + }; + }; + + _newObj setVectorDirAndUp [(_worldspace select 1),(_worldspace select 2)]; + _newObj setposATL (_worldspace select 0); + _newObj setDamage _damage; + _return = _newObj; + + }; + }; +}; +_return \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_bases/EPOCH_server_unsuppported.sqf b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_unsuppported.sqf new file mode 100644 index 00000000..c788f977 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_unsuppported.sqf @@ -0,0 +1,56 @@ +/* +Building - Unsupported building check + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ + +private["_worldspace", "_newObj", "_class", "_objSlot", "_config", "_isSupported", "_lastPosition", "_currentPosition", "_objectPos"]; + +if !(isNil "EPOCH_unsupportedCheckRunning") exitWith{ diag_log "UnsupportedCheck: Already running aborted"}; +EPOCH_unsupportedCheckRunning = true; + +// Check unsupported +_start = diag_tickTime; +_simulatedCount = 0; +_stableCount = 0; +{ + if (!isNull _x) then { + + _config = (configFile >> "CfgVehicles" >> (typeOf _x) >> "simulClass"); + if (isText(_config)) then { + + _objectPos = getPosASL _x; + _isSupported = isTouchingGround _x; + if (!_isSupported) then { + _isSupported = if (terrainIntersectASL[_objectPos, [_objectPos select 0, _objectPos select 1, (_objectPos select 2) - 1]]) then { true } else { + lineIntersects[_objectPos, [_objectPos select 0, _objectPos select 1, (_objectPos select 2) - 5], _x, objNull] + }; + }; + if (!_isSupported) then { + _class = getText(_config); + _objSlot = _x getVariable["BUILD_SLOT", -1]; + if (_objSlot != -1) then { + _vDir = vectordir _x; + _vUP = vectorup _x; + _plyrUID = _x getVariable["BUILD_OWNER", "-1"]; + _slot = _x getVariable["EPOCH_secureStorage", "-1"]; + deleteVehicle _x; + _newObj = createVehicle[_class, _objectPos, [], 0, "CAN_COLLIDE"]; + _newObj setVariable["BUILD_SLOT", _objSlot, true]; + _newObj setVectorDirAndUp[_vDir, _vUP]; + _newObj setposASL _objectPos; + _newObj setVariable["BUILD_OWNER", _plyrUID, true]; + _newObj setVariable["EPOCH_secureStorage", _slot]; + _newObj setVelocity[0, 0, -1]; + _simulatedCount = _simulatedCount + 1; + uiSleep 1; + }; + } else { + _stableCount = _stableCount + 1; + }; + }; + }; +} forEach(allMissionObjects "Constructions_static_F"); +diag_log format["Speed %1 Count %2 Stable %3", (diag_tickTime - _start), _simulatedCount, _stableCount]; +EPOCH_unsupportedCheckRunning = nil; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_bases/EPOCH_server_upgradeBUILD.sqf b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_upgradeBUILD.sqf new file mode 100644 index 00000000..ee61d2f6 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_bases/EPOCH_server_upgradeBUILD.sqf @@ -0,0 +1,62 @@ +/* +Building Upgrades + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private["_worldspace", "_class", "_newObj", "_objHiveKey", "_VAL", "_return", "_upgrade", "_objSlot", "_objType", "_object", "_player"]; + +_object = _this select 0; +_player = _this select 1; +_index = param [2,0]; + +if (isNull _object) exitWith{}; +if !([_player, _this select 3] call EPOCH_server_getPToken) exitWith{}; + +_objSlot = _object getVariable["BUILD_SLOT", -1]; +if (_objSlot != -1) then { + _config = 'CfgBaseBuilding' call EPOCH_returnConfig; + + _upgrades = getArray(_config >> (typeOf _object) >> "upgradeBuilding"); + if !(_upgrades isEqualTo []) then { + + _upgrade = _upgrades param [_index,[]]; + + _objectPos = getposATL _object; + _worldspace = [(_objectPos call EPOCH_precisionPos), vectordir _object, vectorup _object]; + + deleteVehicle _object; + _class = _upgrade select 0; + + _newObj = createVehicle [_class, _objectPos, [], 0, "CAN_COLLIDE"]; + _newObj setVariable ["BUILD_SLOT",_objSlot,true]; + _newObj call EPOCH_server_buildingInit; + _newObj setVectorDirAndUp [(_worldspace select 1),(_worldspace select 2)]; + _newObj setposATL _objectPos; + + _newObj call EPOCH_fnc_saveBuilding; + + diag_log format["DEBUG upgrade BUILD : %1 slot %2", _object, _objSlot]; + }; +} else { + _objType = typeOf _object; + if (getNumber(configFile >> "CfgVehicles" >> _objType >> "isTemporary") == 1) then{ + _config = 'CfgBaseBuilding' call EPOCH_returnConfig; + + _upgrades = getArray(_config >> (typeOf _object) >> "upgradeBuilding"); + if !(_upgrades isEqualTo []) then { + + _upgrade = _upgrades param [_index,[]]; + + _worldspace = [getposATL _object, vectordir _object, vectorup _object]; + deleteVehicle _object; + _class = _upgrade select 0; + + _newObj = createVehicle[_class, (_worldspace select 0), [], 0, "CAN_COLLIDE"]; + _newObj setVectorDirAndUp[(_worldspace select 1), (_worldspace select 2)]; + _newObj setposATL(_worldspace select 0); + + diag_log format["DEBUG upgrade BUILD : %1 slot %2", _object, _objSlot]; + }; + }; +}; diff --git a/Sources/epoch_server/compile/epoch_bases/fn_saveBuilding.sqf b/Sources/epoch_server/compile/epoch_bases/fn_saveBuilding.sqf new file mode 100644 index 00000000..b3168a1d --- /dev/null +++ b/Sources/epoch_server/compile/epoch_bases/fn_saveBuilding.sqf @@ -0,0 +1,25 @@ +/* +Building Save function + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private ["_class","_worldspace","_objHiveKey","_animPhases","_VAL","_return","_objSlot"]; +_return = false; +if !(isNull _this) then { + _objSlot = _this getVariable["BUILD_SLOT", -1]; + if (_objSlot != -1) then{ + _this setDamage 0; + _class = typeOf _this; + _worldspace = [(getposATL _this call EPOCH_precisionPos), vectordir _this, vectorup _this]; + _objHiveKey = format["%1:%2", (call EPOCH_fn_InstanceID), _objSlot]; + _animPhases = []; + { + _animPhases pushBack (_this animationPhase _x) + } foreach (getArray(configFile >> "CfgVehicles" >> _class >> "persistAnimations")); + _VAL = [_class, _worldspace, _this getVariable["EPOCH_secureStorage", "-1"], _this getVariable["BUILD_OWNER", "-1"], _this getVariable["TEXTURE_SLOT", 0], _animPhases]; + ["Building", _objHiveKey, EPOCH_expiresBuilding, _VAL] call EPOCH_fnc_server_hiveSETEX; + _return = true; + }; +}; +_return diff --git a/Sources/epoch_server/compile/epoch_group/EPOCH_server_createGroup.sqf b/Sources/epoch_server/compile/epoch_group/EPOCH_server_createGroup.sqf new file mode 100644 index 00000000..4390d7aa --- /dev/null +++ b/Sources/epoch_server/compile/epoch_group/EPOCH_server_createGroup.sqf @@ -0,0 +1,62 @@ +/* +Add HiveFunction: Create Group / Set Data +Return: + +true = group has been created and / or successfully saved! +false = group exist already and hasn't been saved! +*/ +_return = false; +diag_log format["GROUP: Create %1", _this]; +_leader = _this select 0; +_groupName = _this select 1; + +_textArr = toArray(_groupName); + +// exit if greater than 24 chars +if (count _textArr > 24) exitWith{}; + +// remove any disallowed chars in group name "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 -_" +{ + if !(_x in [97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,49,50,51,52,53,54,55,56,57,48,32,45,95]) then { + _textArr = _textArr - [_x]; + }; +} forEach _textArr; +_groupName = toString _textArr; + +if !([_leader, _this select 2] call EPOCH_server_getPToken) exitWith{}; + +// get vars array and current Crypto value +_cIndex = EPOCH_customVars find "Crypto"; +_vars = _leader getVariable["VARS", [] + EPOCH_defaultVars_SEPXVar]; +_current_crypto = _vars select _cIndex; + +_upgradePrice = parseNumber (EPOCH_group_upgrade_lvl_SEPXVar select 1); + +if (_current_crypto >= _upgradePrice) then { + if (_groupName != "") then { + + _playerCryptoLimit = [(configFile >> "CfgSecConf" >> "limits"), "playerCrypto", 25000] call EPOCH_fnc_returnConfigEntry; + _current_crypto = ((_current_crypto - _upgradePrice) min _playerCryptoLimit) max 0; + [["effectCrypto", _current_crypto], (owner _leader)] call EPOCH_sendPublicVariableClient; + _vars set[_cIndex, _current_crypto]; + _leader setVariable["VARS", _vars]; + + _groupID = getPlayerUID _leader; + //diag_log format["GROUP: Created _groupID %1", _groupID]; + + _leaderName = if (alive _leader) then {name _leader} else {"Dead Player"}; + + _contentArray = [_groupName, _leaderName, EPOCH_group_upgrade_lvl_SEPXVar select 0, [], []]; + + [["groupUpdate", _contentArray], (owner _leader)] call EPOCH_sendPublicVariableClient; + [["groupUidUpdate", _groupID], (owner _leader)] call EPOCH_sendPublicVariableClient; + + _leader setVariable ["GROUP", _groupID]; + + // Save Group Data + ["Group", _groupID, _contentArray] call EPOCH_fnc_server_hiveSET; + _return = true; + + }; +}; +_return diff --git a/Sources/epoch_server/compile/epoch_group/EPOCH_server_deleteGroup.sqf b/Sources/epoch_server/compile/epoch_group/EPOCH_server_deleteGroup.sqf new file mode 100644 index 00000000..7c97165c --- /dev/null +++ b/Sources/epoch_server/compile/epoch_group/EPOCH_server_deleteGroup.sqf @@ -0,0 +1,31 @@ +private [ + "_player","_token" + ,"_groupID" + ,"_response" +]; + +_player = _this select 0; + +if !([_player, _this select 1] call EPOCH_server_getPToken) exitWith{}; + +_groupID = getPlayerUID _player; + +diag_log format ["GROUP: Delete %1",_this]; + +_response = ["Group", _groupID] call EPOCH_fnc_server_hiveGETRANGE; +if ((_response select 0) == 1 && typeName (_response select 1) == "ARRAY") then { + { + if ((_x getVariable["GROUP", ""]) == _groupID) exitWith { + { + _x setVariable ["GROUP", nil]; + [["resetGroup", true], (owner _x)] call EPOCH_sendPublicVariableClient; + [_x] joinSilent (createGroup west); + } forEach (units group _x); + }; + } forEach playableUnits; + + // Remove Key + ["Group", _groupID] call EPOCH_fnc_server_hiveDEL; +}; + +true diff --git a/Sources/epoch_server/compile/epoch_group/EPOCH_server_invitePlayer.sqf b/Sources/epoch_server/compile/epoch_group/EPOCH_server_invitePlayer.sqf new file mode 100644 index 00000000..5310b568 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_group/EPOCH_server_invitePlayer.sqf @@ -0,0 +1,9 @@ +if !([_this select 3, _this select 4] call EPOCH_server_getPToken) exitWith{}; + +_playerUID = _this select 0; +{ + if (getPlayerUID _x == _playerUID) exitWith { + diag_log format ["DEBUG GROUP %1 - %2",_this,_x]; + [["groupInvitePlayer", [_this select 1, _this select 2]], (owner _x)] call EPOCH_sendPublicVariableClient; + }; +} forEach playableUnits; diff --git a/Sources/epoch_server/compile/epoch_group/EPOCH_server_updatePlayerGroup.sqf b/Sources/epoch_server/compile/epoch_group/EPOCH_server_updatePlayerGroup.sqf new file mode 100644 index 00000000..e3bccb6a --- /dev/null +++ b/Sources/epoch_server/compile/epoch_group/EPOCH_server_updatePlayerGroup.sqf @@ -0,0 +1,108 @@ +private ["_groupID","_selectedPlayerUID","_addOrRemove","_modOrMember","_modOrMemberRevert","_response","_contentArray","_modArray","_memberArray","_selectedPlayerName","_group","_removePlayerArray","_modOrMemberArray","_found"]; + +if !([_this select 4, _this select 5] call EPOCH_server_getPToken) exitWith {}; + +_groupID = _this select 0; +if (_groupID == "") exitWith{ diag_log format["GROUP: No Group Selected %1", _this]; }; + +diag_log format["GROUP: Update %1", _this]; + +_selectedPlayerUID = _this select 1; +_addOrRemove = _this select 2; //add = true +_modOrMember = if (_this select 3) then [{3},{4}]; +_modOrMemberRevert = if (_this select 3) then [{4},{3}]; + +// [_groupName, _leaderName, _groupSize, _modArray, _memberArray] +_response = ["Group", _groupID] call EPOCH_fnc_server_hiveGETRANGE; +if ((_response select 0) == 1 && typeName (_response select 1) == "ARRAY") then { + _contentArray = _response select 1; + + //_groupName = _contentArray select 0; + //_leaderName = _contentArray select 1; + //_groupSize = _contentArray select 2; + _modArray = _contentArray select 3; + _memberArray = _contentArray select 4; + + if (_addOrRemove) then { //Add + _selectedPlayerName = "Dead Player"; + + { + if (getPlayerUID _x == _selectedPlayerUID) exitWith { + _selectedPlayerName = if (alive _x) then {name _x}; + if ((_x getVariable ["GROUP",""]) != _groupID) then { + _x setVariable ["GROUP", _groupID]; + _group = grpNull; + { + if ((_x getVariable["GROUP",""]) == _groupID) exitWith { + _group = group _x; + }; + }count playableUnits; + + if (isNull _group) then { + _group = createGroup west; + }; + [_x] joinSilent _group; + }; + }; + }count playableUnits; + + _removePlayerArray = _contentArray select _modOrMemberRevert; + + { + if (_x select 0 == _selectedPlayerUID) exitWith { + _removePlayerArray deleteAt _forEachIndex; + _contentArray set [_modOrMemberRevert, _removePlayerArray]; + }; + } forEach _removePlayerArray; + + _modOrMemberArray = _contentArray select _modOrMember; + _modOrMemberArray pushBack [_selectedPlayerUID, _selectedPlayerName]; + + _contentArray set [_modOrMember, _modOrMemberArray]; + } + else { //Remove + _found = false; + + { + if (getPlayerUID _x == _selectedPlayerUID) exitWith { + _x setVariable ["GROUP", nil]; + [_x] joinSilent (createGroup west); + [["resetGroup", true], (owner _x)] call EPOCH_sendPublicVariableClient; + }; + } count playableUnits; + + { + if (_x select 0 == _selectedPlayerUID) exitWith { + _memberArray deleteAt _forEachIndex; + _found = true; + }; + } forEach _memberArray; + + if (_found) then { + _contentArray set [4, _memberArray]; + } else { + { + if (_x select 0 == _selectedPlayerUID) exitWith { + _modArray deleteAt _forEachIndex; + _found = true; + }; + } forEach _modArray; + _contentArray set [3, _modArray]; + }; + + if (!_found) then { + diag_log format ["%1 cannot remove Player! (%1)", __FILE__, _this] + }; + }; + + { + if ((_x getVariable["GROUP", ""]) == _groupID) exitWith { + { + [["groupUpdate", _contentArray], (owner _x)] call EPOCH_sendPublicVariableClient; + } count (units group _x); + }; + } count playableUnits; + + // Save Group Data + ["Group", _groupID, _contentArray] call EPOCH_fnc_server_hiveSET; +}; diff --git a/Sources/epoch_server/compile/epoch_group/EPOCH_server_upgradeGroup.sqf b/Sources/epoch_server/compile/epoch_group/EPOCH_server_upgradeGroup.sqf new file mode 100644 index 00000000..29e634ca --- /dev/null +++ b/Sources/epoch_server/compile/epoch_group/EPOCH_server_upgradeGroup.sqf @@ -0,0 +1,57 @@ +private [ + "_groupID","_player" + ,"_contentArray","_found" + ,"_newGroupSize","_groupMemberPUID" +]; + +_groupID = _this select 0; +_player = _this select 1; + +if !([_player, _this select 2] call EPOCH_server_getPToken) exitWith{}; + +diag_log format["GROUP: Upgrade %1", _this]; + +// get vars array and current Crypto value +_cIndex = EPOCH_customVars find "Crypto"; +_vars = _player getVariable["VARS", [] + EPOCH_defaultVars_SEPXVar]; +_current_crypto = _vars select _cIndex; + +// [_groupName, _leaderName, _groupSize, _modArray, _memberArray] +_response = ["Group", _groupID] call EPOCH_fnc_server_hiveGETRANGE; +if ((_response select 0) == 1 && typeName (_response select 1) == "ARRAY") then { + _contentArray = (_response select 1); + _found = EPOCH_group_upgrade_lvl_SEPXVar find (_contentArray select 2); + + if ((_found != -1) && count EPOCH_group_upgrade_lvl_SEPXVar >= (_found + 3)) then { + _newGroupSize = EPOCH_group_upgrade_lvl_SEPXVar select (_found + 2); + + _upgradePrice = parseNumber (EPOCH_group_upgrade_lvl_SEPXVar select (_found+3)); + + if (_current_crypto >= _upgradePrice) then { + + _playerCryptoLimit = [(configFile >> "CfgSecConf" >> "limits"), "playerCrypto", 25000] call EPOCH_fnc_returnConfigEntry; + _current_crypto = ((_current_crypto - _upgradePrice) min _playerCryptoLimit) max 0; + [["effectCrypto", _current_crypto], (owner _player)] call EPOCH_sendPublicVariableClient; + _vars set[_cIndex, _current_crypto]; + _player setVariable["VARS", _vars]; + + _contentArray set [2, _newGroupSize]; + + _groupMemberPUID = [_groupID]; + { + { + _groupMemberPUID pushback(_x select 0); + } forEach _x; + } forEach [_contentArray select 3, _contentArray select 4]; + + { + if (getPlayerUID _x in _groupMemberPUID) then { + [["groupUpdate", _contentArray], (owner _x)] call EPOCH_sendPublicVariableClient; + }; + } forEach playableUnits; + + // Save Group Data + ["Group", _groupID, _contentArray] call EPOCH_fnc_server_hiveSET; + }; + }; +}; diff --git a/Sources/epoch_server/compile/epoch_looting/EPOCH_server_destroyTrash.sqf b/Sources/epoch_server/compile/epoch_looting/EPOCH_server_destroyTrash.sqf new file mode 100644 index 00000000..0355a384 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_looting/EPOCH_server_destroyTrash.sqf @@ -0,0 +1,56 @@ +private["_target", "_eventArray", "_triggerType", "_nearPlayers", "_posWH", "_item", "_config", "_object", "_player", "_payout", "_type"]; + +_object = _this select 0; +_type = _this select 1; +_player = _this select 2; + +if (isNull _object) exitWith{}; +if !([_player, _this select 3] call EPOCH_server_getPToken) exitWith{}; + +if (!(_object isKindOf "All")) then { + + if (alive _object) then { + + if (isNil "EPOCH_trashLootClasses") then{ + _config = 'CfgEpochClient' call EPOCH_returnConfig; + EPOCH_trashLootClasses = getArray(_config >> worldname >> "TrashClasses"); + }; + _payout = EPOCH_trashLootClasses param [_type, "Trash"]; + + _posWH = getPosATL _player; + _object setdamage 1; + + _item = createVehicle["groundWeaponHolder", _posWH, [], 0.0, "CAN_COLLIDE"]; + _item setPosATL _posWH; + + _config = (configFile >> "CfgMainTable" >> _payout); + if (isClass _config) then { + if (random 1 < getNumber(_config >> "chance")) then { + [_item, _payout] call EPOCH_serverLootObject; + }; + }; + + // TODO move to server config + if ((random 1) <= EPOCH_antagonistChanceTrash) then { + _nearPlayers = _posWH nearEntities[["Epoch_Male_F", "Epoch_Female_F"], 50]; + + if (!(_nearPlayers isEqualTo[])) then { + _target = _nearPlayers select floor(random(count _nearPlayers)); + + _antagTable = ["Trash", "CfgMainTable", "antagonists"] call EPOCH_weightedArray; + + _antagTableArray = _antagTable select 0; + if !(_antagTableArray isEqualTo[]) then{ + + _weightedArray = _antagTable select 1; + _weightedArrayCount = _antagTable select 2; + + _triggerType = _antagTableArray select(_weightedArray select floor(random _weightedArrayCount)); + + [_target, _triggerType] call EPOCH_server_triggerEvent; + }; + }; + }; + }; +}; +true diff --git a/Sources/epoch_server/compile/epoch_looting/EPOCH_server_knockDownTree.sqf b/Sources/epoch_server/compile/epoch_looting/EPOCH_server_knockDownTree.sqf new file mode 100644 index 00000000..379fc740 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_looting/EPOCH_server_knockDownTree.sqf @@ -0,0 +1,35 @@ +private["_posWH", "_item", "_nearbyWH", "_payout", "_object", "_type", "_player"]; +_player = _this select 2; +if !([_player, _this select 3] call EPOCH_server_getPToken) exitWith{}; + +_object = _this select 0; +if (isNull _object) exitWith{}; +if (_player distance2D (getposATL _object) > 6) exitWith{}; + +if !(_object isKindOf "All") then { + if (alive _object) then { + _posWH = getPosATL _object; + _posWH set[2, 0]; + if (damage _object > 0.7) then { + _object setdamage 1; + _type = _this select 1; + + _lootType = "Tree"; + if (_type == 1) then { + _lootType = "Bush"; + }; + + _nearbyWH = nearestObjects[_posWH, ["groundWeaponHolder"], 2]; + if !(_nearbyWH isEqualTo[]) then { + [(_nearbyWH select 0), _lootType] call EPOCH_serverLootObject; + } else { + _item = createVehicle["groundWeaponHolder", _posWH, [], 0, "CAN_COLLIDE"]; + _item setPosATL _posWH; + [_item, _lootType] call EPOCH_serverLootObject; + }; + } else { + _object setdamage((damage _object) + 0.25) min 1; + }; + }; +}; +true diff --git a/Sources/epoch_server/compile/epoch_looting/EPOCH_server_lootAnimal.sqf b/Sources/epoch_server/compile/epoch_looting/EPOCH_server_lootAnimal.sqf new file mode 100644 index 00000000..f32a766b --- /dev/null +++ b/Sources/epoch_server/compile/epoch_looting/EPOCH_server_lootAnimal.sqf @@ -0,0 +1,24 @@ +private["_item", "_class", "_pos", "_objectClass", "_object", "_player"]; + +_object = _this select 0; +_player = _this select 1; + +if !([_player, _this select 2] call EPOCH_server_getPToken) exitWith{}; + +if !(isNull _object) then { + _pos = getPosATL _object; + _objectClass = typeOf _object; + + deleteVehicle _object; + + _item = createVehicle["groundWeaponHolder", _pos, [], 0.0, "CAN_COLLIDE"]; + _item setPosATL _pos; + + _class = "SeaFood"; + _config = configFile >> "CfgMainTable" >> _objectClass; + if (isClass(_config)) then { + _class = _objectClass; + }; + [_item, _class] call EPOCH_serverLootObject; +}; +true \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_looting/EPOCH_server_lootContainer.sqf b/Sources/epoch_server/compile/epoch_looting/EPOCH_server_lootContainer.sqf new file mode 100644 index 00000000..c58af0ad --- /dev/null +++ b/Sources/epoch_server/compile/epoch_looting/EPOCH_server_lootContainer.sqf @@ -0,0 +1,58 @@ +private ["_class","_pos","_dir","_object","_whConfig","_type","_lootClasses","_player","_maxLoot","_triggerType","_eventArray","_animated","_config"]; + +_object = _this select 0; + +_player = _this select 1; + +if !([_player, _this select 2] call EPOCH_server_getPToken) exitWith{}; +if (isNull _object) exitWith{}; +if !(alive _object) exitWith{}; +if (_player distance _object > 20) exitWith{}; + + +if !(_object in EPOCH_cleanupQueue) then { + + EPOCH_cleanupQueue pushBack _object; + + _type = typeOf _object; + + _animated = configFile >> "CfgVehicles" >> _type >> "Destruction" >> "animations"; + if (isArray _animated) then { + _object setDamage 1; + //diag_log format["DEBUG: lootContainer %1", _object]; + }; + _config = (configFile >> "CfgMainTable" >> _type); + _lootClasses = getArray(_config >> "tables"); + + if !(_lootClasses isEqualTo []) then { + _whConfig = configFile >> "CfgVehicles" >> _type >> "weaponHolderProxy"; + if (isText _whConfig) then { + _class = getText (_whConfig); + _pos = getPosATL _object; + _dir = getDir _object; + _object = createVehicle [_class, _pos, [], 0.0, "CAN_COLLIDE"]; + _object setDir _dir; + _object setPosATL _pos; + }; + + [_object, _type] call EPOCH_serverLootObject; + } else { + [_object, "Food"] call EPOCH_serverLootObject; + }; + + if ((random 1) <= EPOCH_antagonistChanceLoot) then{ + + _antagTable = [_type, "CfgMainTable", "antagonists"] call EPOCH_weightedArray; + + _antagTableArray = _antagTable select 0; + if !(_antagTableArray isEqualTo[]) then{ + + _weightedArray = _antagTable select 1; + _weightedArrayCount = _antagTable select 2; + + _triggerType = _antagTableArray select(_weightedArray select floor(random _weightedArrayCount)); + + [_player, _triggerType] call EPOCH_server_triggerEvent; + }; + }; +}; diff --git a/Sources/epoch_server/compile/epoch_looting/EPOCH_server_mineRocks.sqf b/Sources/epoch_server/compile/epoch_looting/EPOCH_server_mineRocks.sqf new file mode 100644 index 00000000..28d54e31 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_looting/EPOCH_server_mineRocks.sqf @@ -0,0 +1,44 @@ +private["_posWH", "_item", "_nearbyWH", "_rock", "_player"]; + +_object = _this select 0; +_index = _this select 1; +_player = _this select 2; + +if !([_player, _this select 3] call EPOCH_server_getPToken) exitWith{}; + +if !(_object isKindOf "All") then { + if (alive _object) then { + + _posWH = getPosATL _player; + _posWH set[2, 0]; + + // defaults + _selectedPayout = ["ItemRock", 4]; + // Not Rock + if (_index >= 0) then { + _selectedPayout = ["ItemScraps", 2]; + if (_index == 0) then { + _selectedPayout = ["CinderBlocks", 1]; + }; + } else { + _lootables = [["PartOre", 2], ["ItemRock", 4]]; + _selectedPayout = _lootables select(floor random(count _lootables)); + }; + + _payout = _selectedPayout select 0; + _payoutQty = _selectedPayout select 1; + + _object setdamage ((damage _object) + (1/_payoutQty)) min 1; + + _nearbyWH = nearestObjects[_posWH, ["groundWeaponHolder"], 2]; + if !(_nearbyWH isEqualTo[]) then { + _posWH = getPosATL(_nearbyWH select 0); + (_nearbyWH select 0) addMagazineCargoGlobal[_payout, _payoutQty]; + } else { + _item = createVehicle["groundWeaponHolder", _posWH, [], 0, "CAN_COLLIDE"]; + _item setPosATL _posWH; + _item addMagazineCargoGlobal[_payout, _payoutQty]; + }; + }; +}; +true \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_looting/EPOCH_server_spawnBoatLoot.sqf b/Sources/epoch_server/compile/epoch_looting/EPOCH_server_spawnBoatLoot.sqf new file mode 100644 index 00000000..53acb7a5 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_looting/EPOCH_server_spawnBoatLoot.sqf @@ -0,0 +1,16 @@ +private ["_item"]; +{ + // 20 percent chance for loot to spawn + if ((random 1) <= 0.4) then { + _item = createVehicle["container_epoch", _x, [], 0, "NONE"]; + _item setMass 220; + + if (EPOCH_SHOW_BOATLOOT) then { + _marker = createMarker[str(_x), _x]; + _marker setMarkerShape "ICON"; + _marker setMarkerType "mil_dot"; + // _marker setMarkerText "Shipwreak"; + _marker setMarkerColor "ColorOrange"; + }; + }; +} foreach (getArray (configFile >> "CfgEpoch" >> worldname >> "containerPos")); \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_missions/EPOCH_Server_airDropCrate.sqf b/Sources/epoch_server/compile/epoch_missions/EPOCH_Server_airDropCrate.sqf new file mode 100644 index 00000000..8c4590f2 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_missions/EPOCH_Server_airDropCrate.sqf @@ -0,0 +1,22 @@ +private["_plyr","_axeCopter","_pos","_axeCrate","_crateSmoke","_weps","_mags","_items"]; +_plyr = _this select 1; +if !([_plyr,_this select 2]call EPOCH_server_getPToken)exitWith{}; + +_axeCopter = _this select 0; +_pos = getPos _axeCopter; +//diag_log format["Air Drop At: %1 for %2",_pos, name _plyr]; + _pos set [2,(_pos select 2) - 2]; +_axeCrate = createVehicle ["B_supplyCrate_F", _pos, [], 10, "NONE"]; +_axeChute = createVehicle ["NonSteerable_Parachute_F", _pos, [], 10, "FLY"]; +_axeCrate attachTo [_axeChute, [0, 0, 0] ]; +_crateSmoke = "SmokeShell" createVehicle _pos; +_crateSmoke attachTo [_axeChute,[0,0,-0.4]]; +clearWeaponCargoGlobal _axeCrate; +clearItemCargoGlobal _axeCrate; +clearMagazineCargoGlobal _axeCrate; +clearBackpackCargoGlobal _axeCrate; +_axeLight = "Land_Camping_Light_F" createvehicle _pos; +_axeLight attachTo [_axeCrate, [0.71, 0.18, -0.22] ]; +_axeCrate setPos _pos; +// universal payout system +[_axeCrate, "AirDrop_Payout1"] call EPOCH_serverLootObject; diff --git a/Sources/epoch_server/compile/epoch_missions/EPOCH_Server_createAirDrop.sqf b/Sources/epoch_server/compile/epoch_missions/EPOCH_Server_createAirDrop.sqf new file mode 100644 index 00000000..59bd50dc --- /dev/null +++ b/Sources/epoch_server/compile/epoch_missions/EPOCH_Server_createAirDrop.sqf @@ -0,0 +1,65 @@ +private["_plyr","_objType","_obj","_pos","_unitPos","_driver","_unit","_grp","_axeCopter","_plyrOwner"]; +_plyr = _this select 0; +if !([_plyr,_this select 1]call EPOCH_server_getPToken)exitWith{}; + +_pos = _this select 2; +_pos set[2, 2400]; + +if !((nearestObjects[_pos, ["B_Heli_Transport_01_F"], 1000]) isEqualTo[]) exitWith{ diag_log "DEBUG: prevented air drop, too many in area." }; + +_plyrOwner = owner _plyr; + +_objType = "B_Heli_Transport_01_F"; +diag_log format["DEBUG: Creating %1 for %3 (Owner ID: %4) at %2",_objType, _pos, name _plyr, owner _plyr]; +_obj = createVehicle [_objType, _pos, [], 0, "FLY"]; +_obj call EPOCH_server_setVToken; +addToRemainsCollector[_obj]; +_obj disableTIEquipment true; + +clearWeaponCargoGlobal _obj; +clearItemCargoGlobal _obj; +clearMagazineCargoGlobal _obj; +clearBackpackCargoGlobal _obj; + +_obj allowdamage false; +_obj setPosATL _pos; +_obj setFuel 1; +_obj flyInHeight 120; +_grp = createGroup RESISTANCE; + +_unitPos = _pos; +_driver = _grp createUnit["I_helipilot_F", _unitPos, [], 0, "CAN_COLLIDE"]; +_driver assignAsDriver _obj; +_driver moveInDriver _obj; + +_unitPos = _pos findEmptyPosition [1,75,"I_helipilot_F"]; + +_unit = _grp createUnit["I_helicrew_F", _unitPos, [], 0, "CAN_COLLIDE"]; +_unit assignAsGunner _obj; +_unit moveInGunner _obj; + +_grp setCombatMode "BLUE"; + +(driver _obj) action ["engineOn", _obj]; +_obj setVehicleLock "LOCKEDPLAYER"; + +[_obj,_driver,_plyr] spawn { + axenotSent = false; + axenotSent = true; + _obj = _this select 0; + _driver = _this select 1; + _plyr = _this select 2; + while {axenotSent} do { + _drvOwner = owner _driver; + _plyrOwner = owner _plyr; + (group _driver) setGroupOwner _plyrOwner; + if((_drvOwner == _plyrOwner)) then { + [["airDrop", _obj], owner _plyr] call EPOCH_sendPublicVariableClient; + diag_log format["DEBUG: Transferred ownership of %1 to %2, new owner ID is %3",_driver, name _plyr, owner _driver]; + axenotSent = false; + // since we found an owner, add cleanup if ownership reverts to server. This can also be used to change ownership instead later. + _obj call EPOCH_localCleanup; + }; + uiSleep 0.5; + }; +}; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_missions/EPOCH_Server_createObject.sqf b/Sources/epoch_server/compile/epoch_missions/EPOCH_Server_createObject.sqf new file mode 100644 index 00000000..6f47c3c9 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_missions/EPOCH_Server_createObject.sqf @@ -0,0 +1,79 @@ +private["_plyr","_objType","_obj","_objSpc","_clearCargo","_pos","_chance","_driver","_driverType","_gunner","_gunnerType","_commander","_commanderType","_crew","_crewType","_grp","_doOwner","_missionVehList"]; +_missionVehList = ["O_UAV_01_F","B_UAV_01_F","I_Boat_Armed_01_minigun_F","B_Heli_Transport_01_F",""]; + +_plyr = _this select 0; +if !([_plyr,_this select 1]call EPOCH_server_getPToken)exitWith{}; +if (count _this != 11) exitWith {diag_log format ["Debug: %1 exit with %2",__FILE__,_this]}; + +_objType = _this select 2; +if!(_objType in _missionVehList)exitWith{}; + + +_clearCargo = _this select 3; +if ((_this select 4) isEqualTo []) then { + _pos = _this select 4; +} else { + _pos = (getPosATL _plyr) findEmptyPosition [1,250,_objType]; + if (count _pos < 1) then { + _pos = getPosATL _plyr; + }; +}; + +_objSpc = if (_this select 5 == "") then {"CAN_COLLIDE"}else{_this select 5}; +_driverType = _this select 6; +_gunnerType = _this select 7; +_commanderType = _this select 8; +_crewType = _this select 9; +//_doOwner = _this select 10; + + +_obj = createVehicle [_objType, _pos, [], 0, _objSpc]; +_obj call EPOCH_server_setVToken; +addToRemainsCollector[_obj]; +_obj disableTIEquipment true; + +_obj allowdamage false; +_obj setPosATL _pos; +_obj setFuel 1; +//if (_doOwner) then {_obj setOwner (owner _plyr)}; + +if (_clearCargo) then { + clearWeaponCargoGlobal _obj; + clearItemCargoGlobal _obj; + clearMagazineCargoGlobal _obj; + clearBackpackCargoGlobal _obj; +}; + +if (_driverType != "" || _gunnerType != "" ||_commanderType != "") then { + _grp = createGroup RESISTANCE; +}; + +if (_driverType != "") then { + _driver = _grp createUnit[_driverType, position _obj, [], 1, "CAN_COLLIDE"]; + _driver assignAsDriver _obj; + _driver moveInDriver _obj; + //if (_doOwner) then {_driver setOwner (owner _plyr)}; +}; + +if (_gunnerType != "") then { + _gunner = _grp createUnit[_gunnerType, position _obj, [], 1, "CAN_COLLIDE"]; + _gunner assignAsGunner _obj; + _gunner moveInGunner _obj; + //if (_doOwner) then {_gunner setOwner (owner _plyr)}; +}; + +if (_commanderType != "") then { + _commander = _grp createUnit[_commanderType, position _obj, [], 1, "CAN_COLLIDE"]; + _commander assignAsCommander _obj; + _commander moveInCommander _obj; + //if (_doOwner) then {_commander setOwner (owner _plyr)}; +}; + +if (_crewType != "") then { + _crew = _grp createUnit[_crewType, position _obj, [], 1, "CAN_COLLIDE"]; + _crew assignAsCargo _obj; + _crew moveInCargo _obj; + //if (_doOwner) then {_crew setOwner (owner _plyr)}; +}; +_obj allowdamage true; +//diag_log format["Spawned Object %1(%5) for %3(%4) at %2",_objType,_pos,name _plyr,owner _plyr,owner _obj]; diff --git a/Sources/epoch_server/compile/epoch_missions/EPOCH_Server_fillContainer.sqf b/Sources/epoch_server/compile/epoch_missions/EPOCH_Server_fillContainer.sqf new file mode 100644 index 00000000..b12de647 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_missions/EPOCH_Server_fillContainer.sqf @@ -0,0 +1,32 @@ +private["_plyr","_container","_clearFirst","_pos","_chance","_weps","_mags","_items"]; +_plyr = _this select 0; +if !([_plyr,_this select 1]call EPOCH_server_getPToken)exitWith{}; + +_container = objNull; +if (typename (_this select 2) == "OBJECT") then {_container = _this select 2;}; + +_clearFirst = false; +if (count _this > 3) then {_clearFirst = _this select 3;}; + +_chance = 25; +if (count _this > 4) then {_chance = _this select 4;}; + +_pos = getPosATL _plyr; +if (count _this > 5) then {_pos = _this select 5;}; + +if (isNull _container) then { +_container = createVehicle ["GroundWeaponHolder", _pos, [], 12, "CAN_COLLIDE"]; +_container setPosATL _pos; +}; +//diag_log format["Creating GroundWeaponHolder %3 at %1 for %2",_pos, name _plyr,_container]; +if (_clearFirst) then { +clearWeaponCargoGlobal _container; +clearItemCargoGlobal _container; +clearMagazineCargoGlobal _container; +clearBackpackCargoGlobal _container; +}; + +if (_chance > 0) then { + // TODO add separate loot tables for each payout type + [_container, "Mission_Payout1"] call EPOCH_serverLootObject; +}; diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_server_checkPlayer.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_server_checkPlayer.sqf new file mode 100644 index 00000000..bde9a420 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_server_checkPlayer.sqf @@ -0,0 +1,54 @@ +/* +Player Check + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private["_arr", "_dead", "_isMale", "_medical", "_apperance", "_class", "_vars", "_hitpoints", "_deadPlayer", "_response", "_plyrUID", "_plyrObj"]; + +if (typename _this == "OBJECT") then { + _plyrObj = _this; + if (!isNull _plyrObj) then { + _plyrUID = getPlayerUID _plyrObj; + if (_plyrUID != "") then { + + _response = ["Player", _plyrUID] call EPOCH_fnc_server_hiveGETRANGE; + + _dead = false; + _isMale = true; + + _arr = []; + if ((_response select 0) == 1 && typeName(_response select 1) == "ARRAY") then { + _arr = (_response select 1); + }; + + if (count _arr < 11) then { + _dead = true; + } else { + _medical = _arr select 1; + _apperance = _arr select 2; + _class = _apperance select 5; + if (_class == "Epoch_Female_F") then { + _isMale = false; + }; + + _vars = _arr select 4; + _hitpoints = _vars select 11; + + _deadPlayer = ["PlayerStats", _plyrUID, 0] call EPOCH_fnc_server_hiveGETBIT; + + if (_deadPlayer || (_medical select 3 == 1) || (_hitpoints select 2 == 1) || (_hitpoints select 3 == 1) || (_vars select 12 >= 180)) then { + _dead = true; + }; + }; + /* true => New Char + false => load old Char */ + EPOCH_checkPlayer_PVC = _dead; + (owner _plyrObj) publicVariableClient "EPOCH_checkPlayer_PVC"; + + if (!_dead) then { //Load old Char + [_plyrObj, _isMale] call EPOCH_server_loadPlayer; + }; + }; + }; +}; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_server_deadPlayer.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_server_deadPlayer.sqf new file mode 100644 index 00000000..e846ee33 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_server_deadPlayer.sqf @@ -0,0 +1,61 @@ +/* +Player Death + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private ["_playerObj","_pos","_veh","_triggerType","_playerName","_bankBalance","_bankData","_response","_killer","_plyrUID","_cIndex","_vars","_current_crypto"]; +_playerObj = _this select 0; +_killer = _this select 1; + +// handle token check and isnull for _plyr +if !([_playerObj, _this select 3] call EPOCH_server_getPToken) exitWith{}; +_plyrUID = getPlayerUID _playerObj; +_pos = getposATL _playerObj; + +if (_playerObj != _killer) then { + if (random 1 <= EPOCH_antagonistChancePDeath) then { + _triggerType = 2; + if (surfaceIsWater _pos) then { + _triggerType = 3; + }; + [_killer, "Sapper"] call EPOCH_server_triggerEvent; + }; + + // backwards compat for now - + _playerName = _this select 2; + if (typeName _playerName == "ARRAY") then{ + _playerName = toString (_this select 2); + }; + + ['deathlog', format['%1 (%2) Killed By %3 (%4) with weapon %5 from %6m at %7', _playerName, _plyrUID, name _killer, getPlayerUID _killer, currentWeapon _killer, _playerObj distance _killer, _pos]] call EPOCH_fnc_server_hiveLog; +}; + +// get vars array and current Crypto value +_cIndex = EPOCH_customVars find "Crypto"; +_vars = _playerObj getVariable["VARS", [] + EPOCH_defaultVars_SEPXVar]; +_current_crypto = _vars select _cIndex; + +if (_current_crypto > 0) then{ + _veh = createVehicle["Land_MPS_EPOCH", _pos, [], 1.5, "NONE"]; + diag_log format["ADMIN: Created crypto device for %1 with %2 at %3", getPlayerUID _playerObj, _current_crypto, _pos]; + _veh setVariable["Crypto", _current_crypto, true]; +}; + +[_playerObj, [] + EPOCH_defaultVars_SEPXVar] call EPOCH_server_savePlayer; + +// death cost +if (EPOCH_cloneCost > 0) then { + _response = ["Bank", _plyrUID] call EPOCH_fnc_server_hiveGETRANGE; + if ((_response select 0) == 1 && typeName(_response select 1) == "ARRAY") then { + _bankData = _response select 1; + _bankBalance = 0; + + if !(_bankData isEqualTo[]) then { + _bankBalance = _bankData select 0; + }; + + _bankBalance = _bankBalance - EPOCH_cloneCost; + ["Bank", _plyrUID, EPOCH_expiresBank, [_bankBalance]] call EPOCH_fnc_server_hiveSETEX; + }; +}; diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_server_equippedItem.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_server_equippedItem.sqf new file mode 100644 index 00000000..d770fd8d --- /dev/null +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_server_equippedItem.sqf @@ -0,0 +1,25 @@ +/* +Radio handeler + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private["_channelID", "_selectedChannel", "_class", "_status", "_plyr"]; + +_class = _this select 0; +_status = _this select 1; +_plyr = _this select 2; + +_selectedChannel = EPOCH_customChannels select 0; + +if (isClass(configfile >> "CfgWeapons" >> _class)) then { + _channelID = getNumber(configfile >> "CfgWeapons" >> _class >> "channelID"); + _selectedChannel = EPOCH_customChannels select _channelID; +}; + +if (_status) then { + {_x radioChannelRemove[_plyr];} ForEach EPOCH_customChannels; + _selectedChannel radioChannelAdd[_plyr]; +} else { + {_x radioChannelRemove[_plyr];} ForEach EPOCH_customChannels; +}; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_server_loadPlayer.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_server_loadPlayer.sqf new file mode 100644 index 00000000..b95b7de8 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_server_loadPlayer.sqf @@ -0,0 +1,329 @@ +/* + Player Login + + Epoch Mod - EpochMod.com + All Rights Reserved. +*/ +private["_reject", "_plyr", "_instanceID", "_plyrNetID", "_plyrUID", "_response", "_arr", "_defaultUniform", "_class", "_vest", "_medical", "_alreadyDead", "_worldspace", "_dir", "_location", "_prevInstance", "_plyrGroup", "_canBeRevived", "_vars", "_hitpoints", "_group", "_newPlyr", "_currWeap", "_apperance", "_goggles", "_headgear", "_backpack", "_uniform", "_weaponsAndItems", "_equipped", "_weapon", "_type", "_attachments", "_attachment", "_wMags", "_itemSlot", "_itemqtys", "_found", "_contentArray", "_deadPlayer"]; + +_reject = true; + +if (typename _this == "ARRAY") then { + + _plyr = _this select 0; + + _instanceID = call EPOCH_fn_InstanceID; + + _plyrNetID = owner _plyr; + if (!isNull _plyr) then { + + _plyrUID = getPlayerUID _plyr; + if (_plyrUID != "") then { + + // Make Hive call + _response = ["Player", _plyrUID] call EPOCH_fnc_server_hiveGETRANGE; + _arr = []; + if ((_response select 0) == 1 && typeName(_response select 1) == "ARRAY") then { + _arr = (_response select 1); + }; + _defaultUniform = "U_Test_uniform"; + _class = "Epoch_Female_F"; + _vest = "V_F41_EPOCH"; + if (_this select 1) then { //true == male + _defaultUniform = "U_Test1_uniform"; + _class = "Epoch_Male_F"; + _vest = "V_41_EPOCH"; + }; + + if (count _arr < 11) then { // invaild format attempt to override + _arr = [[0, [], _instanceID], [0, 0, 1, 0, []], ["", "", _vest, "", _defaultUniform, _class], [""], [] + EPOCH_defaultVars_SEPXVar, ["", []], ["ItemMap"], [], [], [], "", true]; + }; + + _worldspace = _arr select 0; + _dir = _worldspace select 0; + _location = _worldspace select 1; + _prevInstance = _worldspace select 2; + + _medical = _arr select 1; + + _plyrGroup = _arr select 10; + _canBeRevived = _arr select 11; + + _server_vars = _arr select 3; + _vars = _arr select 4; + + _hitpoints = _vars select 11; + + _deadPlayer = ["PlayerStats", _plyrUID, 0] call EPOCH_fnc_server_hiveGETBIT; + _alreadyDead = (_deadPlayer || (_medical select 3 == 1) || (_hitpoints select 2 == 1) || (_hitpoints select 3 == 1) || (_vars select 12 >= 180)); + + if (_alreadyDead || _prevInstance != _instanceID || (count _location) < 3 || typeName _location != "ARRAY") then { + _dir = random 360; + _location = getMarkerPos "respawn_west"; + _location set[2, 0]; + if (_alreadyDead) then { + _vars = [] + EPOCH_defaultVars_SEPXVar; + _canBeRevived = true; + }; + }; + + _group = grpNull; + + // Delete any left over units with same PUID + { + if ((_x getVariable["PUID", "0"]) == _plyrUID) then { + deleteVehicle _x; + }; + } forEach allUnits; + + if (_plyrGroup != "") then { + { + if ((_x getVariable["GROUP", ""]) == _plyrGroup) exitWith{ + _group = group _x; + }; + } forEach playableUnits; + }; + + if (isNull _group) then { + _group = createGroup west; + }; + + _newPlyr = _group createUnit[_class, _location, [], 0, "CAN_COLLIDE"]; + + if !(isNull _newPlyr) then { + + //diag_log format ["DEBUG Created New Player: %1", _newPlyr]; + { + _newPlyr disableAI _x; + } forEach["FSM", "MOVE", "AUTOTARGET", "TARGET"]; + + _newPlyr setDir _dir; + _newPlyr setPosATL _location; + + _currWeap = ""; + + if (!_alreadyDead) then { + // Medical + _newPlyr setBleedingRemaining(_medical select 0); + // _newPlyr setFatigue (_medical select 1); + _newPlyr setOxygenRemaining(_medical select 2); + _newPlyr setDamage(_medical select 3); + + // Apperance + _apperance = _arr select 2; + _goggles = _apperance select 0; + _headgear = _apperance select 1; + _vest = _apperance select 2; + _backpack = _apperance select 3; + _uniform = _apperance select 4; + + if (_uniform != "") then { + _newPlyr addUniform _uniform; + }; + if (_backpack != "") then { + _newPlyr addBackpack _backpack; + }; + if (_goggles != "") then { + _newPlyr addGoggles _goggles; + }; + if (_headgear != "") then { + _newPlyr addHeadgear _headgear; + }; + if (_vest != "") then { + _newPlyr addVest _vest; + }; + + // Weapons + _weaponsAndItems = _arr select 5; + if (count _weaponsAndItems >= 2) then { + + _equipped = _weaponsAndItems select 2; + { + _weapon = _x deleteAt 0; + _type = getNumber(configfile >> "cfgweapons" >> _weapon >> "type"); + + _attachments = []; + _wMags = false; + _wMagsArray = []; + // suppressor, laser, optics, magazines(array), bipods + { + // magazines + if (typeName(_x) == "ARRAY") then{ + _wMags = true; + _wMagsArray = _x; + } + else { + // attachments + if (_x != "") then{ + _attachments pushBack _x; + }; + }; + } forEach _x; + + // add weapon if equiped + if (_weapon in _equipped) then { + + _equipped = _equipped - [_weapon]; + + if (_wMags) then { + _newPlyr addMagazine _wMagsArray; + }; + + if (_weapon != "") then { + _newPlyr addWeapon _weapon; + }; + + switch _type do { + case 1: { // primary + removeAllPrimaryWeaponItems _newPlyr; + { _newPlyr addPrimaryWeaponItem _x } forEach _attachments; + }; + case 2: { // handgun + removeAllHandgunItems _newPlyr; + { _newPlyr addHandgunItem _x } forEach _attachments; + }; + case 4: { // secondary + // removeAllSecondaryWeaponItems player; does not exist ? + { + _newPlyr removeSecondaryWeaponItem _x; + } forEach (secondaryWeaponItems _newPlyr); + { _newPlyr addSecondaryWeaponItem _x } forEach _attachments; + }; + }; + } + else { // overflow need to add these items to storage + { + _newPlyr addItem _x; + } forEach _attachments; + + if (_wMags) then { + _newPlyr addMagazine _wMagsArray; + }; + }; + } forEach(_weaponsAndItems select 1); + + _currWeap = _weaponsAndItems select 0; + }; + + // Linked items + { + if (_x in["Binocular", "Rangefinder"]) then { + _newPlyr addWeapon _x; + } + else { + _newPlyr linkItem _x; + }; + } forEach(_arr select 6); + + // add items to containers + { + _itemSlot = _forEachIndex; + _itemqtys = _x select 1; + { + for "_i" from 1 to(_itemqtys select _forEachIndex) do { + switch _itemSlot do { + case 0: { _newPlyr addItemToUniform _x }; + case 1: { _newPlyr addItemToVest _x }; + case 2: { _newPlyr addItemToBackpack _x }; + }; + }; + } forEach(_x select 0); + } forEach(_arr select 8); + + // add weapons to containers + { + _itemSlot = _forEachIndex; + _itemqtys = _x select 1; + { + for "_i" from 1 to(_itemqtys select _forEachIndex) do { + switch _itemSlot do { + case 0: { _newPlyr addItemToUniform _x }; + case 1: { _newPlyr addItemToVest _x }; + case 2: { _newPlyr addItemToBackpack _x }; + }; + }; + } forEach(_x select 0); + } forEach(_arr select 9); + + // Add magazines + { + _newPlyr addMagazine _x; + } forEach(_arr select 7); + }; + + // Final Push + if (isNull _plyr) then { + deleteVehicle _newPlyr; + diag_log "DEBUG: _plyr object was null reject connection"; + } else { + + _reject = false; + + if (_plyrGroup != "") then { + _response = ["Group", _plyrGroup] call EPOCH_fnc_server_hiveGETRANGE; + diag_log format["DEBUG (Load Player) Group Content: %1", _response]; + _found = false; + if ((_response select 0) == 1 && typeName(_response select 1) == "ARRAY" && !((_response select 1) isEqualTo[])) then { + _contentArray = _response select 1; + _found = _plyrGroup == _plyrUID; + if (!_found) then { + { + if (_x select 0 == _plyrUID) exitWith{ + _found = true; + }; + }forEach(_contentArray select 4); + }; + if (!_found) then { + { + if (_x select 0 == _plyrUID) exitWith{ + _found = true; + }; + }forEach(_contentArray select 3); + }; + if (_found) then { + Epoch_my_Group = _contentArray; + _plyrNetID publicVariableClient "Epoch_my_Group"; + _newPlyr setVariable["GROUP", _plyrGroup]; + }; + }; + + if (!_found) then { + _plyrGroup = ""; + }; + diag_log format["DEBUG (Load Player) Set Group: %1", _plyrGroup]; + }; + + // may not be needed, just here to see if we can force the data to sync quicker + // _plyr setPosATL _location; + + _newPlyr setVariable["SETUP", true]; + _newPlyr setVariable["PUID", _plyrUID]; + + + if !(_vars isEqualTo[]) then { + _newPlyr setVariable["VARS", _vars]; + }; + + if !(_server_vars isEqualTo[]) then{ + _newPlyr setVariable["SERVER_VARS", _server_vars]; + }; + + if (!_canBeRevived) then { + _newPlyr setVariable["REVIVE", _canBeRevived] + }; + [_plyrNetID, _plyrUID, [_newPlyr, _vars, _currWeap, count(magazines _newPlyr), _plyrGroup, _canBeRevived, _newPlyr call EPOCH_server_setPToken]] call EPOCH_server_pushPlayer; + }; + } else { + diag_log format["LOGIN FAILED UNIT NULL: %1 [%2|%3]", _plyr, _group, count allgroups]; + }; + }; + }; +}; + +if (_reject) then { + diag_log format ["DEBUG PLAYER NOT SETUP OR INVAILD: %1", _plyr]; + BAD_HIVE = true; + _plyrNetID publicVariableClient "BAD_HIVE"; +}; + +true diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_server_onPlayerDisconnect.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_server_onPlayerDisconnect.sqf new file mode 100644 index 00000000..e7db125e --- /dev/null +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_server_onPlayerDisconnect.sqf @@ -0,0 +1,26 @@ +/* +Player Disconnect + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ + +private["_plyr", "_return"]; + +_plyr = _this select 0; +//_id = _this select 1; +//_uid = _this select 2; +//_name = _this select 3; +// diag_log format["Handle Disconnect: %1 return: %2", _this, _return]; +_return = false; +if (!isNull _plyr) then { + if (_plyr getVariable["SETUP", false]) then { + [_plyr, _plyr getVariable["VARS", []], true, true] call EPOCH_server_savePlayer; + if (alive _plyr) then { + deleteVehicle _plyr; + }; + } else { + deleteVehicle _plyr; + }; +}; +_return \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_server_respawnPlayer.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_server_respawnPlayer.sqf new file mode 100644 index 00000000..7a6a3660 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_server_respawnPlayer.sqf @@ -0,0 +1,43 @@ +/* + Player Respawn + + Epoch Mod - EpochMod.com - All Rights Reserved. +*/ +private["_defaultUniform", "_class", "_vest", "_dir", "_location", "_plyrObj", "_plyr"]; + +if !([_this select 0, _this select 1] call EPOCH_server_getPToken) exitWith{}; + +_plyr = _this select 0; +_plyrObj = _plyr; + +if (count _this == 3) then { + + _defaultUniform = "U_Test_uniform"; + _class = "Epoch_Female_F"; + _vest = "V_F41_EPOCH"; + if (_this select 2) then { //true == male + _defaultUniform = "U_Test1_uniform"; + _class = "Epoch_Male_F"; + _vest = "V_41_EPOCH"; + }; + + _dir = random 360; + _location = getMarkerPos "respawn_west"; + _location set[2, 0]; + + + _plyrObj = (group _plyr) createUnit [_class, _location, [], 0, "CAN_COLLIDE"]; + { + _plyrObj disableAI _x; + } forEach["FSM", "MOVE", "AUTOTARGET", "TARGET"]; + + _plyrObj setDir _dir; + _plyrObj setPosATL _location; + + EPOCH_switchPlayer_PVC = _plyrObj; + (owner _plyr) publicVariableClient "EPOCH_switchPlayer_PVC"; +}; + + +_plyrObj setVariable ["REVIVE", true]; +true \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_server_revivePlayer.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_server_revivePlayer.sqf new file mode 100644 index 00000000..02fc8441 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_server_revivePlayer.sqf @@ -0,0 +1,250 @@ +/* +Player Revive + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private["_plyr", "_plyrUID", "_items", "_class", "_dir", "_location", "_type", "_weapon", "_attachments", "_currWeap", "_itemSlot", "_itemqtys", "_goggles", "_headgear", "_vest", "_backpack", "_uniform", "_weapons", "_magazinesAmmo", "_itemsplayer", "_weaponsplayer", "_group", "_primaryWeapon", "_secondaryWeapon", "_attachment", "_equipped", "_wMags", "_plyrGroup", "_droppedWeapons", "_newPlyr", "_token", "_owner", "_reviver"]; + +_plyr = _this select 0; +_owner = owner _plyr; +_reviver = _this select 1; + +if !([_reviver, _this select 2] call EPOCH_server_getPToken) exitWith{}; +if (isNull _plyr) exitWith{}; +if (_plyr distance _reviver > 20) exitWith{}; + +if (!local _plyr) then { + _plyrUID = getPlayerUID _plyr; + if (!isNil "_plyrUID" && !alive _plyr) then { + + if (_plyr == _reviver) exitWith { + 'epochserver' callExtension format['820|%1|EpochMod.com Autoban #R1',getPlayerUID _reviver]; + ['ahb', format['%1 (%2): Tried to Revive yourself (%3)', name _reviver, getPlayerUID _reviver, _this]] call EPOCH_fnc_server_hiveLog; + }; + + _class = typeOf _plyr; + + if (_class in ["Epoch_Male_F", "Epoch_Female_F"]) then { + + + if (_plyr getVariable["REVIVE", true]) then { + + diag_log format["DEBUG server_revivePlayer : %1", _this]; + + _location = getPosATL _plyr; + _dir = getDir _plyr; + _plyrGroup = _plyr getVariable["GROUP", ""]; + + _goggles = goggles _plyr; + _headgear = headgear _plyr; + _vest = vest _plyr; + _backpack = backpack _plyr; + _uniform = uniform _plyr; + + _items = assignedItems _plyr; + _magazinesAmmo = magazinesAmmo _plyr; + + _primaryWeapon = ""; + _secondaryWeapon = ""; + + _droppedWeapons = []; + { + { + _droppedWeapons pushBack _x; + _type = getNumber(configfile >> "cfgweapons" >> (_x select 0) >> "type"); + switch _type do { + case 1: { _primaryWeapon = _x select 0 }; + case 4: { _secondaryWeapon = _x select 0 }; + }; + } forEach (weaponsItemsCargo _x); + + } forEach nearestObjects[_plyr, ["WeaponHolderSimulated"], 12]; + + // diag_log ["DEBUG: _droppedWeapons %1", _droppedWeapons]; + + _itemsplayer = [getItemCargo(uniformContainer _plyr), getItemCargo(vestContainer _plyr), getItemCargo(backpackContainer _plyr)]; + _weaponsplayer = [getWeaponCargo(uniformContainer _plyr), getWeaponCargo(vestContainer _plyr), getWeaponCargo(backpackContainer _plyr)]; + _weapons = [currentWeapon _plyr, ((weaponsItems _plyr) + _droppedWeapons), [_primaryWeapon, _secondaryWeapon, handgunWeapon _plyr]]; + + hideObjectGlobal _plyr; + + // create new player unit change this class later + _group = grpNull; + if (_plyrGroup != "") then { + { + if ((_x getVariable["GROUP",""]) == _plyrGroup) exitWith { + _group = group _x; + }; + }forEach playableUnits; + + if (isNull _group) then { + _group = createGroup west; + }; + + diag_log format["DEBUG Group Found: %1", _group]; + } else { + _group = createGroup west; + diag_log format["DEBUG Group Created: %1", _group]; + }; + + _newPlyr = _group createUnit[_class, _location, [], 0, "CAN_COLLIDE"]; + + _newPlyr allowDammage false; + { + _newPlyr disableAI _x; + }forEach["FSM", "MOVE", "AUTOTARGET", "TARGET"]; + + _newPlyr setVariable ["SETUP", true]; + _newPlyr setVariable ["PUID", _plyrUID]; + _newPlyr setVariable ["GROUP", _plyrGroup]; + _newPlyr setVariable ["REVIVE", false]; + + // _plyr playActionNow "Die"; + + _newPlyr setDir _dir; + _newPlyr setPosATL _location; + + // Medical + _newPlyr setFatigue 1; + _newPlyr setDamage 0.25; + + // Apperance + if (_uniform != "") then { + _newPlyr addUniform _uniform; + }; + if (_backpack != "") then { + _newPlyr addBackpack _backpack; + }; + if (_goggles != "") then { + _newPlyr addGoggles _goggles; + }; + if (_headgear != "") then { + _newPlyr addHeadgear _headgear; + }; + if (_vest != "") then { + _newPlyr addVest _vest; + }; + + // Weapons + if (count _weapons >= 2) then { + + _equipped = _weapons select 2; + { + _weapon = _x select 0; + _type = getNumber(configfile >> "cfgweapons" >> _weapon >> "type"); + + _attachments = []; + // suppressor, laser, optics + for "_a" from 1 to 3 do { + _attachment = _x select _a; + if (_attachment != "") then { + _attachments pushBack _attachment; + }; + }; + _wMags = (count _x) == 5; + + // add weapon if equiped + + if (_weapon in _equipped) then { + _equipped = _equipped - [_weapon]; + + if (_wMags) then { + _newPlyr addMagazine(_x select 4); + }; + + if (_weapon != "") then { + _newPlyr addWeapon _weapon; + }; + + switch _type do { + case 1: { // primary + removeAllPrimaryWeaponItems _newPlyr; + { _newPlyr addPrimaryWeaponItem _x }forEach _attachments; + }; + case 2: { // handgun + removeAllHandgunItems _newPlyr; + { _newPlyr addHandgunItem _x }forEach _attachments; + }; + case 4: { // secondary + // removeAllSecondaryWeaponItems player; does not exist ? + { + _newPlyr removeSecondaryWeaponItem _x; + } forEach(secondaryWeaponItems _newPlyr); + { _newPlyr addSecondaryWeaponItem _x }forEach _attachments; + }; + }; + } else { + { + _newPlyr addItem _x; + }forEach _attachments; + + if (_wMags) then { + _newPlyr addMagazine(_x select 4); + }; + }; + + } forEach (_weapons select 1); + + _currWeap = (_weapons select 0); + + }; + + // Linked items + { + if (_x in ["Binocular","Rangefinder"]) then { + _newPlyr addWeapon _x; + } else { + _newPlyr linkItem _x; + }; + }forEach _items; + + + // add items to containers + { + _itemSlot = _forEachIndex; + _itemqtys = _x select 1; + { + for "_i" from 1 to (_itemqtys select _forEachIndex) do { + switch _itemSlot do { + case 0: { _newPlyr addItemToUniform _x }; + case 1: { _newPlyr addItemToVest _x }; + case 2: { _newPlyr addItemToBackpack _x }; + }; + //diag_log format["DEBUG additemtoVest: %1", _x]; + }; + + }forEach (_x select 0); + }forEach _itemsplayer; + + // add weapons to containers + { + _itemSlot = _forEachIndex; + _itemqtys = _x select 1; + { + for "_i" from 1 to (_itemqtys select _forEachIndex) do { + switch _itemSlot do { + case 0: { _newPlyr addItemToUniform _x }; + case 1: { _newPlyr addItemToVest _x }; + case 2: { _newPlyr addItemToBackpack _x }; + }; + //diag_log format["DEBUG additemtoVest: %1", _x]; + }; + + }forEach (_x select 0); + }forEach _weaponsplayer; + + // Add magazines + { + _newPlyr addMagazine _x; + //diag_log format["DEBUG addMagazine: %1", _x]; + }forEach _magazinesAmmo; + + // Final Push + _token = _newPlyr call EPOCH_server_setPToken; + + [["clientRevive", [_newPlyr, _token]], _owner] call EPOCH_sendPublicVariableClient; + }; + }; + }; +}; diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_server_savePlayer.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_server_savePlayer.sqf new file mode 100644 index 00000000..c8e1e0b4 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_server_savePlayer.sqf @@ -0,0 +1,104 @@ +/* +Player Save + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private["_return", "_pos", "_medical", "_plyrUID", "_weapons", "_vars", "_itemsplayer", "_weaponsplayer", "_appearance", "_plyr", "_dmg", "_allowSave", "_cIndex", "_Svars", "_current_crypto", "_group", "_revive", "_vehiclePlyr","_server_vars"]; + +_plyr = _this select 0; +_vars = _this select 1; + +if (isNull _plyr) exitWith { + diag_log "DEBUG SAVE ABORT null player object"; +}; + +if !(_plyr getVariable ["SETUP", false]) exitWith { + diag_log format ["DEBUG SAVE ABORT not setup: %1", _plyr] +}; +_plyrUID = _plyr getVariable ["PUID", ""]; // getPlayerUID _plyr +if (_plyrUID == "") exitWith { + diag_log format ["DEBUG SAVE ABORT %1", _plyrUID] +}; + +if !(alive _plyr) exitWith{ + // Dead Stat bit index 0 + _return = ["PlayerStats", _plyrUID, 0, 1] call EPOCH_fnc_server_hiveSETBIT; +}; + +// add vehicle to update queue +_vehiclePlyr = vehicle _plyr; +if (_vehiclePlyr != _plyr) then { + if !(_vehiclePlyr in EPOCH_saveVehQueue) then { + EPOCH_saveVehQueue pushBack _vehiclePlyr; + }; +}; + +if (typeName _vars == "ARRAY") then { + if (count _vars == EPOCH_customVarCount) then{ + _allowSave = true; + { + if (typeName (_vars select _forEachIndex) != typeName _x) exitWith { _allowSave = false }; + } forEach EPOCH_defaultVars; + + if (_allowSave) then{ + + if !(_vars isEqualTo EPOCH_defaultVars_SEPXVar) then{ + _serverOnly = ["Crypto"]; + _Svars = _plyr getVariable["VARS", [] + EPOCH_defaultVars_SEPXVar]; + { + _cIndex = EPOCH_customVars find _x; + if (_cIndex != -1) then{ + _vars set[_cIndex, (_Svars select _cIndex)]; + }; + } forEach _serverOnly; + }; + + // Server Only Stats + _server_vars = _plyr getVariable["SERVER_VARS", []]; + + _group = _plyr getVariable ["GROUP", ""]; + _revive = _plyr getVariable ["REVIVE", true]; + + _pos = getPosATL _plyr; + + if (vehicle _plyr != _plyr) then { + + _staticTraderLocationsDistances = []; + { + _staticTraderLocationsDistances pushBack [_x distance player, _x] + } forEach EPOCH_staticTraderLocations; + + if !(_staticTraderLocationsDistances isEqualTo []) then{ + _staticTraderLocationsDistances sort true; + _pos = _staticTraderLocationsDistances select 0 select 1; + _pos set[2, 0]; + }; + }; + + _dmg = damage _plyr; + _medical = [getBleedingRemaining _plyr, 0, getOxygenRemaining _plyr, _dmg]; + _appearance = [goggles _plyr, headgear _plyr, vest _plyr, backpack _plyr, uniform _plyr, typeOf _plyr]; + _itemsplayer = [getItemCargo(uniformContainer _plyr), getItemCargo(vestContainer _plyr), getItemCargo(backpackContainer _plyr)]; + _weaponsplayer = [getWeaponCargo(uniformContainer _plyr), getWeaponCargo(vestContainer _plyr), getWeaponCargo(backpackContainer _plyr)]; + _weapons = [currentWeapon _plyr, weaponsItems _plyr, [primaryWeapon _plyr, secondaryWeapon _plyr, handgunWeapon _plyr]]; + + if (count _this >= 4) then { + _plyr setVariable ["VARS", nil]; + } else { + _plyr setVariable ["VARS", _vars]; + }; + + // save player + _return = ["Player", _plyrUID, EPOCH_expiresPlayer, [[getDir _plyr, _pos, (call EPOCH_fn_InstanceID)], _medical, _appearance, _server_vars, _vars, _weapons, assignedItems _plyr, magazinesAmmo _plyr, _itemsplayer, _weaponsplayer, _group, _revive]] call EPOCH_fnc_server_hiveSETEX; + + // kill player if blood pressure >= 180 + if (_vars select 12 >= 180) then { + _plyr setDamage 1; + } else { + // set player alive bit + ["PlayerStats", _plyrUID, 0, 0] call EPOCH_fnc_server_hiveSETBIT; + }; + }; + }; +}; diff --git a/Sources/epoch_server/compile/epoch_player/EPOCH_server_storeCrypto.sqf b/Sources/epoch_server/compile/epoch_player/EPOCH_server_storeCrypto.sqf new file mode 100644 index 00000000..ee530c8b --- /dev/null +++ b/Sources/epoch_server/compile/epoch_player/EPOCH_server_storeCrypto.sqf @@ -0,0 +1,114 @@ +/* +Player Bank + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private["_plyr", "_bankBalance", "_bankBalanceBefore", "_current_crypto", "_transferBankBalance", "_transferBankBalanceBefore", "_return", "_transferBankData", "_transferTargetUID", "_transferResponse", "_transferAmountIn", "_transferAmountOut", "_transferBalance", "_transferTarget", "_cIndex", "_vars", "_plyrNetID", "_bankData", "_tradeArray", "_plyrUID", "_response"]; + +_plyr = _this select 0; +_tradeArray = _this select 1; + +// handle token check and isnull for _plyr +if !([_plyr, _this select 2] call EPOCH_server_getPToken) exitWith{}; + +_plyrUID = getPlayerUID _plyr; + +// load players account +_response = ["Bank", _plyrUID] call EPOCH_fnc_server_hiveGETRANGE; + +if ((_response select 0) == 1 && typeName(_response select 1) == "ARRAY") then { + + _plyrNetID = owner _plyr; + + _bankData = _response select 1; + _bankBalance = 0; + _bankBalanceBefore = 0; + if !(_bankData isEqualTo[]) then { + _bankBalance = _bankData select 0; + _bankBalanceBefore = _bankBalance; + }; + + // return balance to player + if (_tradeArray isEqualTo[]) then { + [["bankBalance", _bankBalance], _plyrNetID] call EPOCH_sendPublicVariableClient; + } else { + + // Transaction Data - TODO add check for validity of transaction + _transferAmountIn = _tradeArray select 0; + _transferAmountOut = _tradeArray select 1; + + // Send to another player + _transferBalance = _tradeArray select 2 select 0; + _transferTarget = objectFromNetId (_tradeArray select 2 select 1); + + // get vars array and current Crypto value + _cIndex = EPOCH_customVars find "Crypto"; + _vars = _plyr getVariable["VARS", [] + EPOCH_defaultVars_SEPXVar]; + _current_crypto = _vars select _cIndex; + + // Make Transaction + _playerCryptoLimit = [(configFile >> "CfgSecConf" >> "limits"), "playerCrypto", 25000] call EPOCH_fnc_returnConfigEntry; + + if (_transferAmountIn > 0) then { + + // diag_log format["Store: _current_crypto: %1 _cIndex:%2", _current_crypto, _cIndex]; + + if (_current_crypto >= _transferAmountIn) then { + _bankBalance = _bankBalance + _transferAmountIn; + _current_crypto = ((_current_crypto - _transferAmountIn) min _playerCryptoLimit) max 0; + [["effectCrypto", _current_crypto], _plyrNetID] call EPOCH_sendPublicVariableClient; + _vars set[_cIndex, _current_crypto]; + _plyr setVariable["VARS", _vars]; + }; + }; + + if (_transferAmountOut > 0) then { + if (_bankBalance >= _transferAmountOut) then { + _bankBalance = _bankBalance - _transferAmountOut; + _current_crypto = ((_current_crypto + _transferAmountOut) min _playerCryptoLimit) max 0; + [["effectCrypto", _current_crypto], _plyrNetID] call EPOCH_sendPublicVariableClient; + _vars set[_cIndex, _current_crypto]; + _plyr setVariable["VARS", _vars]; + }; + }; + + // send money to another players account + if (!(isNull _transferTarget) && _bankBalance >= _transferBalance) then { + + if (_transferBalance > 0) then { + + _transferTargetUID = getPlayerUID _transferTarget; + _transferResponse = ["Bank", _transferTargetUID] call EPOCH_fnc_server_hiveGETRANGE; + + if ((_transferResponse select 0) == 1 && typeName(_transferResponse select 1) == "ARRAY") then { + + _transferBankData = _transferResponse select 1; + _transferBankBalance = 0; + _transferBankBalanceBefore = 0; + + if !(_transferBankData isEqualTo[]) then { + _transferBankBalance = _transferBankData select 0; + _transferBankBalanceBefore = _transferBankBalance; + }; + + // take from player + _bankBalance = _bankBalance - _transferBalance; + + // give to player + _transferBankBalance = _transferBankBalance + _transferBalance; + + if (_transferBankBalanceBefore != _transferBankBalance) then { + _return = ["Bank", _transferTargetUID, EPOCH_expiresPlayer, [_transferBankBalance]] call EPOCH_fnc_server_hiveSETEX; + [["bankBalance", _transferBankBalance], (owner _transferTarget)] call EPOCH_sendPublicVariableClient; + }; + }; + }; + }; + + if (_bankBalanceBefore != _bankBalance) then { + _return = ["Bank", _plyrUID, EPOCH_expiresBank, [_bankBalance]] call EPOCH_fnc_server_hiveSETEX; + }; + }; +}; +diag_log format["BANK: %1 (%2) TRADE: %3", _plyr, _plyrUID, _tradeArray]; diff --git a/Sources/epoch_server/compile/epoch_server/EPOCH_localCleanup.sqf b/Sources/epoch_server/compile/epoch_server/EPOCH_localCleanup.sqf new file mode 100644 index 00000000..92f2c599 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_server/EPOCH_localCleanup.sqf @@ -0,0 +1,22 @@ +if (typename _this != "ARRAY") then { + _this = [_this]; +}; + +{ + if (!isNull _x) then { + _x addEventHandler["local", { + if (_this select 1) then { + private "_unit"; + _unit = _this select 0; + { + _unit removeAllMPEventHandlers _x; + }forEach ["mpkilled","mphit","mprespawn"]; + { + _unit removeAllEventHandlers _x; + }forEach ["FiredNear","HandleDamage","Killed","Fired","GetOut","GetIn","Local"]; + deleteVehicle _unit; + deleteGroup (group _unit); + }; + }]; + }; +}forEach _this; diff --git a/Sources/epoch_server/compile/epoch_server/EPOCH_serverLootObject.sqf b/Sources/epoch_server/compile/epoch_server/EPOCH_serverLootObject.sqf new file mode 100644 index 00000000..40667cfd --- /dev/null +++ b/Sources/epoch_server/compile/epoch_server/EPOCH_serverLootObject.sqf @@ -0,0 +1,114 @@ +private["_randomItemArray", "_quan", "_randomLootClass", "_type", "_randomItem", "_object", "_lootPaid", "_mags", "_lootItemWeightedArray", "_lootItemArray", "_weightedItemArray", "_weightedItemArrayCount", "_exit", "_maxPayout", "_lootTable", "_lootTableArray", "_weightedArray", "_weightedArrayCount"]; +_object = _this select 0; +_type = _this select 1; + +if !(isNull _object) then{ + + _lootTable = [_type, "CfgMainTable", "tables"] call EPOCH_weightedArray; + + // diag_log format["%1: lootTable %2", __FILE__, _lootTable]; + + _lootTableArray = _lootTable select 0; + _weightedArray = _lootTable select 1; + _weightedArrayCount = _lootTable select 2; + + if !(_lootTableArray isEqualTo []) then { + + _loots = []; + + _config = configFile >> "CfgMainTable" >> _type; + _minLoot = getNumber(_config >> "lootMin"); + _maxLoot = getNumber(_config >> "lootMax"); + + _maxPayout = ((random(_maxLoot) * EPOCH_lootMultiplier) min _maxLoot) max _minLoot; + for "_k" from 1 to _maxPayout do { + _loots pushBack (_lootTableArray select(_weightedArray select floor(random _weightedArrayCount))); + }; + + // diag_log format["%1: loots: %2", __FILE__, _loots]; + + { + // get weighted array + _lootItemWeightedArray = [_x, "CfgLootTable", "items"] call EPOCH_weightedArray; + + // diag_log format["%1: lootItemWeightedArray1 %2", __FILE__, _lootItemWeightedArray]; + + _lootItemArray = _lootItemWeightedArray select 0; + if !(_lootItemArray isEqualTo[]) then { + _weightedItemArray = _lootItemWeightedArray select 1; + _weightedItemArrayCount = _lootItemWeightedArray select 2; + + _randomItemArray = _lootItemArray select (_weightedItemArray select floor(random _weightedItemArrayCount)); + + _randomItem = _randomItemArray select 0; + _type = _randomItemArray select 1; + + _quan = 1; + + /* + if ((count _randomItem) >= 3) then { + _quan = _randomItem select 2; + }; + */ + + _loop = true; + _exit = false; + + while {_loop} do { + + switch _type do { + case "item": { + _object additemCargoGlobal [_randomItem, _quan]; + _loop = false; + }; + case "magazine": { + _object addMagazineCargoGlobal [_randomItem, _quan]; + _loop = false; + }; + case "backpack": { + _object addBackpackCargoGlobal [_randomItem, _quan]; + _loop = false; + }; + case "weapon": { + _object addWeaponCargoGlobal [_randomItem, _quan]; + _mags = getArray (configFile >> "CfgWeapons" >> _randomItem >> "magazines"); + + if !(_mags isEqualTo []) then { + _object addMagazineCargoGlobal [_mags select 0, ceil(random 2)]; + }; + _loop = false; + }; + case "CfgLootTable": { + + // go down the rabit hole + _lootItemWeightedArray = [_randomItem, "CfgLootTable", "items"] call EPOCH_weightedArray; + + // diag_log format["%1: lootItemWeightedArray2 %2", __FILE__, _lootItemWeightedArray]; + + _lootItemArray = _lootItemWeightedArray select 0; + if !(_lootItemArray isEqualTo[]) then { + + _weightedItemArray = _lootItemWeightedArray select 1; + _weightedItemArrayCount = _lootItemWeightedArray select 2; + + _randomItemArray = _lootItemArray select(_weightedItemArray select floor(random _weightedItemArrayCount)); + + _randomItem = _randomItemArray select 0; + _type = _randomItemArray select 1; + } else { + _exit = true; + }; + }; + + default { + _exit = true; + }; + }; + if (_exit) exitWith{ diag_log format["%1: CASE DEFAULT WITH %2", __FILE__, _this] }; + }; + //diag_log format["DEBUG SPAWN LOOT IN VEH: %1 %2 %3 type:%4", typeOf _object, _x, _randomItem, _type]; + }; + } forEach _loots; + }; + +}; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_server/EPOCH_server_buildingInit.sqf b/Sources/epoch_server/compile/epoch_server/EPOCH_server_buildingInit.sqf new file mode 100644 index 00000000..c82eddea --- /dev/null +++ b/Sources/epoch_server/compile/epoch_server/EPOCH_server_buildingInit.sqf @@ -0,0 +1,2 @@ +_this addMPEventHandler["MPKilled", { _this call EPOCH_server_save_killedBuilding; }]; +// _this addMPEventHandler["MPHit", { if !((_this select 0) in EPOCH_saveBldQueue) then { EPOCH_saveBldQueue pushBack(_this select 0) } }]; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_server/EPOCH_server_createTeleport.sqf b/Sources/epoch_server/compile/epoch_server/EPOCH_server_createTeleport.sqf new file mode 100644 index 00000000..fd595fe3 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_server/EPOCH_server_createTeleport.sqf @@ -0,0 +1,76 @@ +private ["_pos1","_pos","_veh","_veh1","_veh2"]; + +_debugLocation = getMarkerPos "respawn_west"; +_debugLocation set[2, 0]; +_debug = createVehicle["Debug_static_F", _debugLocation, [], 0, "CAN_COLLIDE"]; +_protection = createVehicle["ProtectionZone_Invisible_F", _debugLocation, [], 0, "CAN_COLLIDE"]; + +for "_i" from 1 to 4 do { + _class = ["clone_empty_static_F", "clone_male_static_F", "clone_female_static_F"] select(floor(random 3)); + _debug1 = createVehicle[_class, (_debug modelToWorld(_debug selectionPosition(str _i))), [], 0, "CAN_COLLIDE"]; + _debug1 setDir-90; + +}; +for "_i" from 5 to 8 do { + _class = ["clone_empty_static_F", "clone_male_static_F", "clone_female_static_F"] select(floor(random 3)); + _debug1 = createVehicle[_class, (_debug modelToWorld(_debug selectionPosition(str _i))), [], 0, "CAN_COLLIDE"]; + _debug1 setDir 90; +}; + + +_config = configFile >> "CfgEpoch"; + +// spawn area props +{ + // diag_log str(_x); + _class = _x select 0; + _pos = _x select 1; + _dir = _x select 2; + + _deSimulate = _class isKindOf "ThingX"; + if (count _x >= 4) then { + + _deSimulate = (_x select 3) isEqualTo "true"; + }; + + _ep = createVehicle[_class, _pos, [], 0, "CAN_COLLIDE"]; + + _ep allowDamage false; + if (typeName _dir == "ARRAY") then{ + _ep setVectorDirAndUp _dir; + } else { + _ep setDir _dir; + }; + _ep setposATL _pos; + + if (_deSimulate) then{ + _ep enableSimulationGlobal false; + }; + +} forEach(getArray(_config >> worldname >> "propsPos")); + +{ + _enterClass = _x select 0; + _pos1 = _debug modelToWorld (_x select 1); + _exitClass = _x select 2; + _pos = _x select 3; + + _pro1 = createVehicle ["ProtectionZone_Invisible_F", _pos1, [], 0, "CAN_COLLIDE"]; + _veh1 = createVehicle[_enterClass, _pos1, [], 0, "CAN_COLLIDE"]; + _veh1 enableSimulationGlobal false; + _veh1 allowDamage false; + _veh1 setVariable["ParentBuilding", _pos]; + _veh1 setDir 0; + _veh1 setposATL _pos1; + + if (_exitClass != "") then { + _veh2 = createVehicle[_exitClass, _pos, [], 0, "CAN_COLLIDE"]; + _veh2 enableSimulationGlobal false; + _veh2 allowDamage false; + _veh2 setVariable["ParentBuilding", _pos1]; + _veh2 setDir 0; + _veh2 setposATL _pos; + }; + _pro2 = createVehicle ["ProtectionZone_Invisible_F", _pos, [], 0, "CAN_COLLIDE"]; + EPOCH_staticTraderLocations pushBack _pos; +} foreach (getArray(_config >> worldname >> "telePos")); diff --git a/Sources/epoch_server/compile/epoch_server/EPOCH_server_setWeather.sqf b/Sources/epoch_server/compile/epoch_server/EPOCH_server_setWeather.sqf new file mode 100644 index 00000000..6fadf9b1 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_server/EPOCH_server_setWeather.sqf @@ -0,0 +1,54 @@ +private ["_rain","_fog","_overcast","_windValX","_windValZ","_tempOVRD","_rainOVRD","_fogOVRD","_overcastOVRD","_windOVRD","_arr","_response","_rnd_temp"]; + +if !(EPOCH_WeatherStaticForecast isEqualTo []) then { + _tempOVRD = EPOCH_WeatherStaticForecast select 0; + _rainOVRD = EPOCH_WeatherStaticForecast select 1; + _fogOVRD = EPOCH_WeatherStaticForecast select 2; + _overcastOVRD = EPOCH_WeatherStaticForecast select 3; + _windOVRD = EPOCH_WeatherStaticForecast select 4; + diag_log format["DEBUG: static weather: %1", EPOCH_WeatherStaticForecast]; +} else { + _response = ["Weather", (call EPOCH_fn_InstanceID)] call EPOCH_fnc_server_hiveGETRANGE; + if ((_response select 0) == 1 && typeName(_response select 1) == "ARRAY" && !((_response select 1) isEqualTo[])) then { + _arr = _response select 1; + _tempOVRD = _arr select 0; + _rainOVRD = _arr select 1; + _fogOVRD = _arr select 2; + _overcastOVRD = _arr select 3; + _windOVRD = _arr select 4; + diag_log format["DEBUG: hive weather: %1", _arr]; + }; +}; + +_rnd_temp = if (sunOrMoon < 1) then { (random 35) + 15 } else { (random 75) + 50 }; + +EPOCH_CURRENT_WEATHER = if (isNil "_tempOVRD") then { _rnd_temp } else { _tempOVRD }; +publicVariable "EPOCH_CURRENT_WEATHER"; + +_fog = if (isNil "_fogOVRD") then { [random 0.2, random 0.2, random 20] } else { _fogOVRD }; +_rain = if (isNil "_rainOVRD") then { random 1 } else { _rainOVRD }; +_overcast = if (isNil "_overcastOVRD") then { random 1 } else { _overcastOVRD }; + +EPOCH_WeatherChangeTime setFog _fog; +EPOCH_WeatherChangeTime setOvercast _overcast; +EPOCH_WeatherChangeTime setRain _rain; + +_windValX = random 10 - 5; +_windValZ = random 10 - 5; +if (_rain > 0.5) then { + _windValX = random 20 - 10; + _windValZ = random 20 - 10; +}; + +if !(isNil "_windOVRD") then { + _windValX = _windOVRD select 0; + _windValZ = _windOVRD select 1; +}; + +setWind[_windValX, _windValZ, true]; + +if (_this) then { + forceWeatherChange; +}; + +diag_log format["Weather Change: fog: %1 rain: %2 overcast: %3 windx: %4 windz: %5 forced: %6", _fog, _overcast, _rain, _windValX, _windValZ, _this]; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_server/EPOCH_server_storageInit.sqf b/Sources/epoch_server/compile/epoch_server/EPOCH_server_storageInit.sqf new file mode 100644 index 00000000..f1a02d3d --- /dev/null +++ b/Sources/epoch_server/compile/epoch_server/EPOCH_server_storageInit.sqf @@ -0,0 +1,2 @@ +_this addMPEventHandler["MPKilled", { _this call EPOCH_server_save_killedStorage }]; +// _this addMPEventHandler["MPHit", { if !((_this select 0) in EPOCH_saveStorQueue) then { EPOCH_saveStorQueue pushBack(_this select 0) } }]; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_server/EPOCH_server_teleportPlayer.sqf b/Sources/epoch_server/compile/epoch_server/EPOCH_server_teleportPlayer.sqf new file mode 100644 index 00000000..26ce3d9f --- /dev/null +++ b/Sources/epoch_server/compile/epoch_server/EPOCH_server_teleportPlayer.sqf @@ -0,0 +1,13 @@ +private ["_player","_teleporter","_pos","_telePosArray"]; + +_player = _this select 0; +_teleporter = _this select 1; + +if !([_player, _this select 2] call EPOCH_server_getPToken) exitWith{}; +if (isNull _teleporter) exitWith{}; +if (_plyr distance _teleporter > 20) exitWith{}; + +_tp = _teleporter getVariable["ParentBuilding", []]; +if !(_tp isEqualTo []) then { + _player setPosATL _tp; +}; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_server/EPOCH_server_traderKilled.sqf b/Sources/epoch_server/compile/epoch_server/EPOCH_server_traderKilled.sqf new file mode 100644 index 00000000..5750cd5c --- /dev/null +++ b/Sources/epoch_server/compile/epoch_server/EPOCH_server_traderKilled.sqf @@ -0,0 +1,16 @@ +private ["_marker","_slot","_objHiveKey"]; +if (!isNull (_this select 0)) then { + _marker = (_this select 0) getVariable["MARKER_REF",""]; + if (_marker != "") then { + _marker setMarkerColor "ColorRed"; + }; + + _slot = (_this select 0) getVariable["AI_SLOT", -1]; + if (_slot != -1) then { + // Spawn Drone on player + [(_this select 1), "UAV"] call EPOCH_server_triggerEvent; + + _objHiveKey = format ["%1:%2", (call EPOCH_fn_InstanceID), _slot]; + ["AI", _objHiveKey, []] call EPOCH_fnc_server_hiveSET; + }; +}; diff --git a/Sources/epoch_server/compile/epoch_server/EPOCH_server_vehicleInit.sqf b/Sources/epoch_server/compile/epoch_server/EPOCH_server_vehicleInit.sqf new file mode 100644 index 00000000..da8064c7 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_server/EPOCH_server_vehicleInit.sqf @@ -0,0 +1,4 @@ +_this addMPEventHandler["MPKilled", { _this call EPOCH_server_save_killedVehicle }]; +_this addMPEventHandler["MPHit", { if !((_this select 0) in EPOCH_saveVehQueue) then { EPOCH_saveVehQueue pushBack(_this select 0) } }]; +_this addEventHandler["Local", { if !((_this select 0) in EPOCH_saveVehQueue) then { EPOCH_saveVehQueue pushBack(_this select 0) } }]; +_this addEventHandler["GetOut", { if !((_this select 0) in EPOCH_saveVehQueue) then { EPOCH_saveVehQueue pushBack(_this select 0) } }]; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_server/EPOCH_test_damage.sqf b/Sources/epoch_server/compile/epoch_server/EPOCH_test_damage.sqf new file mode 100644 index 00000000..c6dac4fb --- /dev/null +++ b/Sources/epoch_server/compile/epoch_server/EPOCH_test_damage.sqf @@ -0,0 +1 @@ +diag_log format["DEBUG DMG: %1 ", _this]; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_traders/EPOCH_server_loadTraders.sqf b/Sources/epoch_server/compile/epoch_traders/EPOCH_server_loadTraders.sqf new file mode 100644 index 00000000..26639f00 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_traders/EPOCH_server_loadTraders.sqf @@ -0,0 +1,162 @@ +private [ + "_staticTradersArray","_staticTradersArrCount","_aiTables" + ,"_staticTrader" + ,"_class","_pos","_dir" + ,"_agent","_randomIndex","_randomAIUniform" + ,"_arr","_objHiveKey","_response" + ,"_marker" + ,"_home","_work","_schedule" +]; + +_staticTradersArray = getArray(configFile >> "CfgEpoch" >> worldName >> "staticNpcPos"); +_staticTradersArrCount = count _staticTradersArray; +_aiTables = ["U_OG_leader", "U_C_Poloshirt_stripped", "U_C_Poloshirt_blue", "U_C_Poloshirt_burgundy", "U_C_Poloshirt_tricolour", "U_C_Poloshirt_salmon", "U_C_Poloshirt_redwhite", "U_C_Poor_1", "U_C_WorkerCoveralls", "U_C_Journalist", "U_C_Scientist", "U_OrestesBody"]; + +EPOCH_storedVehicleCount = 0; + +for "_i" from 0 to _this do { + + // Spawn static traders first + if (_staticTradersArrCount > 0 && _i < _staticTradersArrCount) then { + + _staticTrader = _staticTradersArray select _i; + + _class = _staticTrader select 0; + _pos = _staticTrader select 1; + _dir = _staticTrader select 2; + + _agent = createAgent [_class, _pos, [], 0, "CAN_COLLIDE"]; + + _randomIndex = floor(random(count _aiTables)); + _randomAIUniform = _aiTables select _randomIndex; + _agent addUniform _randomAIUniform; + + _agent setDir _dir; + _agent setPosATL _pos; + + _agent setVariable ["AI_SLOT", _i, true]; + + _agent disableAI "FSM"; + _agent setBehaviour "CARELESS"; + _agent setCombatMode "RED"; + _agent setSkill 0; + + _agent addEventHandler ["Killed", { _this call EPOCH_server_traderKilled; }]; + + _arr = [[], []]; + _objHiveKey = format ["%1:%2", (call EPOCH_fn_InstanceID), _i]; + _response = ["AI_ITEMS", _objHiveKey] call EPOCH_fnc_server_hiveGETRANGE; + // diag_log format ["TRADER LOAD DATA: %1", _response]; + + if ((_response select 0) == 1 && typeName (_response select 1) == "ARRAY") then { + _arr = (_response select 1); + if (_arr isEqualTo []) then { + _arr = [[], []]; + }; + + // count vehicles + { + if (_x isKindOf "Air" || _x isKindOf "Ship" || _x isKindOf "LandVehicle" || _x isKindOf "Tank") then { + EPOCH_storedVehicleCount = EPOCH_storedVehicleCount + ((_arr select 1) select _forEachIndex); + }; + } forEach (_arr select 0); + }; + + if (_arr isEqualTo [[], []]) then{ + _arr = EPOCH_starterTraderItems; + }; + + _agent setVariable ["AI_ITEMS", _arr, true]; + + EPOCH_TraderSlots set [_i, 1]; + + if (EPOCH_SHOW_TRADERS) then { + _marker = createMarker [str(_agent), (_pos)]; + _marker setMarkerShape "ICON"; + _marker setMarkerType "mil_dot"; + _marker setMarkerColor "ColorBlack"; + + _agent setVariable["MARKER_REF", _marker]; + }; + } + // Spawn dynamic traders + else { + _objHiveKey = format ["%1:%2", (call EPOCH_fn_InstanceID), _i]; + _response = ["AI", _objHiveKey] call EPOCH_fnc_server_hiveGETRANGE; + if ((_response select 0) == 1 && typeName (_response select 1) == "ARRAY" && !((_response select 1) isEqualTo [])) then { + _arr = (_response select 1); + + _class = _arr select 0; //"C_man_1" + _home = _arr select 1; + _work = _arr select 2; + + if (typeName _home == "ARRAY" && typeName _work == "ARRAY") then { + // check schedule + _pos = _home; + + _schedule = [9, 17]; + if (typeName(_work select 1) == "ARRAY") then { + _schedule = _work select 1; + } + else { + diag_log format ["DEBUG INVAILD SCHEDULE: SLOT: %1 CLASS: %2 POS: %3 WORK: %4", _i, _class, _pos, _work]; + }; + + if (daytime > (_schedule select 0) && daytime < (_schedule select 1)) then { + _pos = (_work select 0); + }; + _agent = createAgent [_class, _pos, [], 0, "NONE"]; + + addToRemainsCollector[_agent]; + + _randomIndex = floor(random(count _aiTables)); + _randomAIUniform = _aiTables select _randomIndex; + _agent addUniform _randomAIUniform; + + // _agent enableSimulationGlobal false; + _agent setPos _pos; + + _agent addEventHandler ["Killed", { _this call EPOCH_server_traderKilled; }]; + + if !(EPOCH_forceStaticTraders) then { + [_agent, _home, _work] execFSM "\x\addons\a3_epoch_server\system\Trader_brain.fsm"; + }; + + _agent setVariable ["AI_SLOT", _i, true]; + + _arr = [[],[]]; + _objHiveKey = format ["%1:%2", (call EPOCH_fn_InstanceID), _i]; + _response = ["AI_ITEMS", _objHiveKey] call EPOCH_fnc_server_hiveGETRANGE; + //diag_log format ["TRADER LOAD DATA: %1", _response]; + + if ((_response select 0) == 1 && typeName (_response select 1) == "ARRAY") then { + _arr = (_response select 1); + + if (_arr isEqualTo []) then { + _arr = [[],[]]; + }; + }; + _agent setVariable ["AI_ITEMS", _arr, true]; + + EPOCH_TraderSlots set [_i, 1]; + + if (EPOCH_SHOW_TRADERS) then { + _marker = createMarker [str(_agent), (_pos)]; + _marker setMarkerShape "ICON"; + _marker setMarkerType "mil_dot"; + _marker setMarkerColor "ColorBrown"; + + _agent setVariable["MARKER_REF", _marker]; + }; + } + else { + EPOCH_TraderSlots set [_i, 0]; + }; + } + else { + EPOCH_TraderSlots set [_i, 0]; + }; + }; +}; + +true diff --git a/Sources/epoch_server/compile/epoch_traders/EPOCH_server_spawnTraders.sqf b/Sources/epoch_server/compile/epoch_traders/EPOCH_server_spawnTraders.sqf new file mode 100644 index 00000000..352e4e8f --- /dev/null +++ b/Sources/epoch_server/compile/epoch_traders/EPOCH_server_spawnTraders.sqf @@ -0,0 +1,127 @@ +private [ + "_aiTables","_counter" + ,"_slot","_position" + ,"_randomIndex","_randomAIUniform","_randomAIClass","_usedBuildings","_building" + ,"_home","_pos","_homeBuildingPositions","_homeBuildingPosition","_acceptableBlds","_buildings" + ,"_buildingWork","_work","_buildingPositions","_buildingPosition","_startTime","_endTime","_schedule","_pos","_agent","_objHiveKey" + ,"_marker" +]; +// find free AI slot or exit +_aiTables = ["U_OG_leader", "U_C_Poloshirt_stripped", "U_C_Poloshirt_blue", "U_C_Poloshirt_burgundy", "U_C_Poloshirt_tricolour", "U_C_Poloshirt_salmon", "U_C_Poloshirt_redwhite", "U_C_Poor_1", "U_C_WorkerCoveralls", "U_C_Journalist", "U_C_Scientist", "U_OrestesBody"]; +_counter = 0; +while {true} do { + + if (_counter >= EPOCH_NPCSlotsLimit) exitWith{}; + + _slot = EPOCH_TraderSlots find 0; + if (_slot == -1) exitWith{}; + + _counter = _counter + 1; + + _position = [epoch_centerMarkerPosition, 0, EPOCH_dynamicVehicleArea, 20, 0, 4000, 0] call BIS_fnc_findSafePos; + + // only proceed if two params otherwise BIS_fnc_findSafePos failed and may spawn in air + if (count _position == 2) then { + + _randomIndex = floor(random(count _aiTables)); + _randomAIUniform = _aiTables select _randomIndex; + _randomAIClass = "C_man_1"; + + _usedBuildings = []; + + // find home + _building = nearestBuilding _position; + + if !(_building in _usedBuildings) then { + + _home = getPosATL _building; + _pos = _home; + + _usedBuildings pushBack _building; + + _homeBuildingPositions = []; + for "_p" from 0 to 20 do { + _homeBuildingPosition = _building buildingPos _p; + if (_homeBuildingPosition isEqualTo[0, 0, 0]) exitWith{}; + if (_homeBuildingPosition nearEntities[_randomAIClass, 5] isEqualTo[]) then { + _homeBuildingPositions pushBack _homeBuildingPosition; + }; + }; + if !(_homeBuildingPositions isEqualTo []) then { + _home = _homeBuildingPositions select floor(random(count _homeBuildingPositions)); + }; + + _acceptableBlds = getArray(configFile >> "CfgEpoch" >> worldName >> "traderBlds"); + _buildings = nearestObjects[_home, _acceptableBlds, 500]; + + if !(_buildings isEqualTo []) then { + + _buildingWork = _buildings select floor(random(count _buildings)); + + if !(_buildingWork in _usedBuildings) then { + + _usedBuildings pushBack _building; + + _work = getPosATL _buildingWork; + + _buildingPositions = []; + for "_p" from 0 to 20 do { + _buildingPosition = _buildingWork buildingPos _p; + if (_buildingPosition isEqualTo[0, 0, 0]) exitWith{}; + if (_buildingPosition nearEntities[_randomAIClass, 5] isEqualTo []) then { + _buildingPositions pushBack _buildingPosition; + }; + }; + + if !(_buildingPositions isEqualTo []) then { + _work = _buildingPositions select floor(random(count _buildingPositions)); + }; + + _startTime = floor(random 16); + _endTime = _startTime + 8; + _schedule = [_startTime, _endTime]; + + if (daytime > (_schedule select 0) && daytime < (_schedule select 1)) then { + _pos = _work; + }; + + _agent = createAgent[_randomAIClass, _pos, [], 0, "CAN_COLLIDE"]; + + addToRemainsCollector[_agent]; + + _agent addUniform _randomAIUniform; + + EPOCH_TraderSlots set[_slot, 1]; + + // Set slot used by vehicle + _agent setVariable["AI_SLOT", _slot, true]; + + // allow input here to provide default items + _agent setVariable["AI_ITEMS", EPOCH_starterTraderItems, true]; + + _objHiveKey = format["%1:%2", (call EPOCH_fn_InstanceID), _slot]; + + ["AI_ITEMS", _objHiveKey, EPOCH_expiresAIdata, EPOCH_starterTraderItems] call EPOCH_fnc_server_hiveSETEX; + + _agent addEventHandler["Killed", { _this call EPOCH_server_traderKilled; }]; + + if !(EPOCH_forceStaticTraders) then { + [_agent, _home, [_work, _schedule]] execFSM "\x\addons\a3_epoch_server\system\Trader_brain.fsm"; + }; + + ["AI", _objHiveKey, [_randomAIClass, _home, [_work, _schedule]]] call EPOCH_fnc_server_hiveSET; + + if (EPOCH_SHOW_TRADERS) then { + _marker = createMarker[str(_agent), (_pos)]; + _marker setMarkerShape "ICON"; + _marker setMarkerType "mil_dot"; + _marker setMarkerColor "ColorKhaki"; + + _agent setVariable["MARKER_REF", _marker]; + }; + }; + }; + }; + }; +}; +true diff --git a/Sources/epoch_server/compile/epoch_trading/EPOCH_server_makeNPCTrade.sqf b/Sources/epoch_server/compile/epoch_trading/EPOCH_server_makeNPCTrade.sqf new file mode 100644 index 00000000..396fcb77 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_trading/EPOCH_server_makeNPCTrade.sqf @@ -0,0 +1,255 @@ +/* +NPC trade mech + +Epoch Mod - EpochMod.com +All Rights Reserved. +*/ +private["_vehicleSold", "_vehicleBought", "_vehHiveKey", "_VAL", "_vehSlot", "_vehicle", "_vehicles", "_trader", "_item", "_plyrNetID", "_plyr", "_itemWorth", "_position", "_tmpposition", "_textures", "_textureSelectionIndex", "_selections", "_colors", "_color", "_count", "_helipad", "_slot", "_vehObj", "_config", "_makeTradeIn", "_tradeTotal", "_current_crypto", "_tradeQtyTotal", "_currQty", "_qtyIndex", "_itemQty", "_foundSmoke", "_objOwner", "_lockOwner", "_plyrGroup", "_itemTax", "_tax", "_objHiveKey", "_cIndex", "_aiItems", "_itemClasses", "_itemQtys", "_itemsIn", "_itemsOut", "_returnIn", "_returnOut", "_smoke", "_vehLockHiveKey", "_colorsConfig", "_vars", "_current_cryptoRaw"]; +_trader = _this select 0; +_itemsIn = _this select 1; +_itemsOut = _this select 2; +_plyr = _this select 3; + +_vehicleSold = false; +_vehicleBought = false; + +_returnIn = []; +_returnOut = []; + +if (isNull _trader) exitWith{}; +if !([_plyr,_this select 4] call EPOCH_server_getPToken) exitWith {}; +if (_plyr distance _trader > 20) exitWith{}; + +_slot = _trader getVariable["AI_SLOT", -1]; +if (_slot != -1) then { + + _tradeTotal = 0; + _tradeQtyTotal = 0; + + _config = 'CfgPricing' call EPOCH_returnConfig; + + // get vars array and current Crypto value + _cIndex = EPOCH_customVars find "Crypto"; + _vars = _plyr getVariable["VARS", [] + EPOCH_defaultVars_SEPXVar]; + _current_crypto = _vars select _cIndex; + _current_cryptoRaw = _current_crypto; + + // diag_log format["_current_crypto: %1 _cIndex:%2", _current_crypto, _cIndex]; + + // SELL ITEMS TO TRADER + _aiItems = _trader getVariable["AI_ITEMS", [[], []]]; + _itemClasses = _aiItems select 0; + _itemQtys = _aiItems select 1; + { + _item = _x; + _itemQty = 1; + + if (isClass (_config >> _item)) then{ + _itemWorth = getNumber(_config >> _item >> "price"); + + _makeTradeIn = false; + + if (_item isKindOf "Air" || _item isKindOf "Ship" || _item isKindOf "LandVehicle" || _item isKindOf "Tank") then{ + + _vehicles = _trader nearEntities[[_item], 30]; + if !(_vehicles isEqualTo[]) then { + + _vehicle = _vehicles select 0; + if (!isNull _vehicle) then { + + _plyrNetID = owner _plyr; + if (_plyrNetID == (owner _vehicle)) then { + + _vehSlot = _vehicle getVariable["VEHICLE_SLOT", "ABORT"]; + if (!_vehicleSold && _vehSlot != "ABORT") then { + + removeFromRemainsCollector[_vehicle]; + deleteVehicle _vehicle; + _vehicleSold = true; + + _vehHiveKey = format["%1:%2", (call EPOCH_fn_InstanceID), _vehSlot]; + _VAL = []; + ["Vehicle", _vehHiveKey, _VAL] call EPOCH_fnc_server_hiveSET; + + EPOCH_VehicleSlots pushBack _vehSlot; + EPOCH_VehicleSlotCount = count EPOCH_VehicleSlots; + publicVariable "EPOCH_VehicleSlotCount"; + + _makeTradeIn = true; + }; + }; + }; + }; + } else { + _makeTradeIn = true; + }; + + if (_makeTradeIn) then { + + _returnIn pushBack _item; + + _qtyIndex = _itemClasses find _item; + if (_qtyIndex == -1) then { + _itemClasses pushBack _item; + _itemQtys pushBack _itemQty; + _tradeTotal = _tradeTotal + _itemWorth; + _current_crypto = _current_crypto + _itemWorth; + _tradeQtyTotal = _tradeQtyTotal + _itemQty; + } else { + _currQty = _itemQtys select _qtyIndex; + _itemQtys set[_qtyIndex, (_currQty + _itemQty)]; + _tradeTotal = _tradeTotal + _itemWorth; + _current_crypto = _current_crypto + _itemWorth; + _tradeQtyTotal = _tradeQtyTotal + _itemQty; + }; + //diag_log format["_itemClasses: %1 _itemQtys:%2", _itemClasses, _itemQtys]; + }; + }; + } forEach _itemsIn; + + + + { + _item = _x; + _itemQty = 1; + + // diag_log format["_item: %1", _item]; + if (isClass (_config >> _item)) then{ + _itemWorth = getNumber(_config >> _item >> "price"); + _itemTax = getNumber(_config >> _item >> "tax"); + _tax = _itemWorth * (EPOCH_taxRate + _itemTax); + _itemWorth = ceil(_itemWorth + _tax); + + // diag_log format["_itemWorth: %1", _itemWorth]; + + _qtyIndex = _itemClasses find _item; + // add items to array + if (_qtyIndex != -1) then { + + _currQty = _itemQtys select _qtyIndex; + + // diag_log format["_currQty: %1 >= %2", _currQty, _itemQty]; + + if (_currQty >= _itemQty) then { + + if (_current_crypto >= _itemWorth) then { + + if (_item isKindOf "Air" || _item isKindOf "Ship" || _item isKindOf "LandVehicle" || _item isKindOf "Tank") then{ + + if (!_vehicleBought) then { + + if !(EPOCH_VehicleSlots isEqualTo[]) then { + _position = getPosATL _plyr; + + _helipad = nearestObjects[_position, ["Land_HelipadEmpty_F", "Land_HelipadCircle_F"], 100]; + _smoke = nearestObject[_position, "SmokeShell"]; + if (!isNull _smoke) then { + _helipad pushBack _smoke; + }; + + // diag_log format["DEBUG: helipad: %1", _helipad]; + + if !(_helipad isEqualTo[]) then { + + _foundSmoke = false; + { + if (_x isKindOf "SmokeShell") then { + _objOwner = owner _x; + if (_objOwner == owner _plyr) then { + _position = getPosATL _x; + _foundSmoke = true; + } else { + { + if (_objOwner == owner _x) exitWith{ + _position = getPosATL _x; + _foundSmoke = true; + }; + } forEach (units _plyr); + }; + }; + if (_foundSmoke) exitWith {}; + } forEach _helipad; + if !(_foundSmoke) then { + _position = getPosATL (_helipad select 0); + }; + } else { + _tmpposition = []; + if (_item isKindOf "Ship") then { + _tmpposition = [_position, 20, 120, 10, 0, 1000, 1] call BIS_fnc_findSafePos; + _tmpposition = [_tmpposition, 0, 60, 10, 2, 1000, 0] call BIS_fnc_findSafePos; + } else { + _tmpposition = [_position, 20, 120, 20, 0, 2000, 0] call BIS_fnc_findSafePos; + }; + if ((count _tmpposition) == 2) then { + _position = _tmpposition; + }; + }; + // select available slot + _slot = EPOCH_VehicleSlots select 0; + // Remove from available slots + EPOCH_VehicleSlots = EPOCH_VehicleSlots - [_slot]; + EPOCH_VehicleSlotCount = count EPOCH_VehicleSlots; + publicVariable "EPOCH_VehicleSlotCount"; + + + + _vehicleBought = true; + + + // Group access + _lockOwner = getPlayerUID _plyr; + _plyrGroup = _plyr getVariable["GROUP", ""]; + if (_plyrGroup != "") then { + _lockOwner = _plyrGroup; + }; + + _vehObj = [_item,_position,random 360,true,_slot,_lockOwner,"NONE",false] call EPOCH_fnc_spawn_vehicle; + + + _returnOut pushBack _item; + + _itemQtys set[_qtyIndex, (_currQty - _itemQty)]; + _tradeTotal = _tradeTotal - _itemWorth; + _current_crypto = _current_crypto - _itemWorth; + _tradeQtyTotal = _tradeQtyTotal + _itemQty; + }; + }; + } else { + _returnOut pushBack _item; + + _itemQtys set[_qtyIndex, (_currQty - _itemQty)]; + _tradeTotal = _tradeTotal - _itemWorth; + _current_crypto = _current_crypto - _itemWorth; + _tradeQtyTotal = _tradeQtyTotal + _itemQty; + }; + //diag_log format["_itemClasses: %1 _itemQtys:%2", _itemClasses, _itemQtys]; + }; + }; + }; + }; + } forEach _itemsOut; + + if (_itemsIn isEqualTo _returnIn || _itemsOut isEqualTo _returnOut) then { + + // save changes to array + _trader setVariable["AI_ITEMS", [_itemClasses, _itemQtys], true]; + + // Force Save + _objHiveKey = format["%1:%2", (call EPOCH_fn_InstanceID), _slot]; + ["AI_ITEMS", _objHiveKey, EPOCH_expiresAIdata, [_itemClasses, _itemQtys]] call EPOCH_fnc_server_hiveSETEX; + // diag_log format["UPDATED DB FOR TRADER: %1 SLOT: %2 DATA: %3", _trader, _slot, [_itemClasses, _itemQtys]]; + + // diag_log format["ADMIN: %1 TRADETOTAL:%2", _plyr, _tradeTotal]; + + // push crypto changes to player + _playerCryptoLimit = [(configFile >> "CfgSecConf" >> "limits"), "playerCrypto", 25000] call EPOCH_fnc_returnConfigEntry; + _current_crypto = ((_current_cryptoRaw + _tradeTotal) min _playerCryptoLimit) max 0; + [["effectCrypto", _current_crypto], (owner _plyr)] call EPOCH_sendPublicVariableClient; + _vars set[_cIndex, _current_crypto]; + _plyr setVariable["VARS", _vars]; + }; + + // Send completed trade back to player + EPOCH_TRADE_COMPLETE = [_returnIn, _returnOut]; + (owner _plyr) publicVariableClient "EPOCH_TRADE_COMPLETE"; +}; diff --git a/Sources/epoch_server/compile/epoch_trading/EPOCH_server_makeTrade.sqf b/Sources/epoch_server/compile/epoch_trading/EPOCH_server_makeTrade.sqf new file mode 100644 index 00000000..c5c38e33 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_trading/EPOCH_server_makeTrade.sqf @@ -0,0 +1,68 @@ +// Epoch Mod P2P Trading + +private["_player1", "_player2", "_trade1", "_trade2", "_tradeOffer1", "_tradeOffer2", "_tradeCryptoOffer1", "_tradeCryptoOffer2", "_overFlowItems", "_current_crypto1", "_cIndex", "_player1_vars", "_player2_vars", "_current_crypto2"]; + +_player1 = _this select 0; +_player2 = _this select 1; + +if (isNull _player2) exitWith{}; +if !([_player1, _this select 4] call EPOCH_server_getPToken) exitWith{}; +if (_player1 distance _player2 > 10) exitWith{}; + +if ((_player1 getVariable["currentTradeKey", -1]) isEqualto (_player2 getVariable["currentTradeKey", -2])) then{ + if ((_player1 getVariable["Accept", false]) && (_player2 getVariable["Accept", false])) then{ + + _trade1 = _player1 getVariable["Offer", [[], 0]]; + _trade2 = _player2 getVariable["Offer", [[], 0]]; + + _tradeOffer1 = _trade1 select 0; + _tradeOffer2 = _trade2 select 0; + + _tradeCryptoOffer1 = _trade1 select 1; + _tradeCryptoOffer2 = _trade2 select 1; + + _cIndex = EPOCH_customVars find "Crypto"; + _player1_vars = _player1 getVariable["VARS", [] + EPOCH_defaultVars_SEPXVar]; + _player2_vars = _player2 getVariable["VARS", [] + EPOCH_defaultVars_SEPXVar]; + _current_crypto1 = _player1_vars select _cIndex; + _current_crypto2 = _player2_vars select _cIndex; + //diag_log format["p2p: _current_crypto1: %1 _current_crypto2: %2 _cIndex:%2", _current_crypto1, _current_crypto2, _cIndex]; + + // test this may work since players crypto is + if (_current_crypto1 >= _tradeCryptoOffer1 && _current_crypto2 >= _tradeCryptoOffer2) then{ + + _playerCryptoLimit = [(configFile >> "CfgSecConf" >> "limits"), "playerCrypto", 25000] call EPOCH_fnc_returnConfigEntry; + + if (_tradeCryptoOffer1 > 0) then{ + + _current_crypto1 = ((_current_crypto1 - _tradeCryptoOffer1) min _playerCryptoLimit) max 0; + [["effectCrypto", _current_crypto1], (owner _player1)] call EPOCH_sendPublicVariableClient; + _player1_vars set[_cIndex, _current_crypto1]; + _player1 setVariable["VARS", _player1_vars]; + }; + + if !(_tradeOffer2 isEqualTo[]) then{ + _overFlowItems = createVehicle["groundWeaponHolder", getPosATL _player1, [], 0, "CAN_COLLIDE"]; + { + if ([_x, "CfgWeapons"] call EPOCH_fnc_isAny) then{ + _overFlowItems addItemCargoGlobal[_x, 1]; + } + else { + _overFlowItems addMagazineCargoGlobal[_x, 1]; + }; + } forEach _tradeOffer2; + }; + + if (_tradeCryptoOffer2 > 0) then{ + + _current_crypto1 = ((_current_crypto1 + _tradeCryptoOffer2) min _playerCryptoLimit) max 0; + [["effectCrypto", _current_crypto1], (owner _player1)] call EPOCH_sendPublicVariableClient; + _player1_vars set[_cIndex, _current_crypto1]; + _player1 setVariable["VARS", _player1_vars]; + }; + + diag_log format["ADMIN: P1:%1 P2:%2 In:%3:%4 Out:%5:%6", _player1, _player2, _tradeOffer2, _tradeCryptoOffer2, _tradeOffer1, _tradeCryptoOffer1]; + }; + }; + +}; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_trading/EPOCH_server_takeCrypto.sqf b/Sources/epoch_server/compile/epoch_trading/EPOCH_server_takeCrypto.sqf new file mode 100644 index 00000000..34938a96 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_trading/EPOCH_server_takeCrypto.sqf @@ -0,0 +1,30 @@ +// Epoch Mod - Server isde take crypto + +private ["_cIndex","_vars","_current_crypto","_change","_player","_object","_player1","_player2","_getCrypto"]; + +_player = _this select 0; +if !([_player,_this select 1] call EPOCH_server_getPToken) exitWith {}; + +_object = _this select 2; +if (isNull _object) exitWith {}; + +if (_player distance _object > 10) exitWith {}; + +_getCrypto = _object getVariable["Crypto", 0]; + +if (_getCrypto > 0) then { + + deleteVehicle _object; + + // get vars array and current Crypto value + _cIndex = EPOCH_customVars find "Crypto"; + _vars = _player getVariable["VARS", [] + EPOCH_defaultVars_SEPXVar]; + _current_crypto = _vars select _cIndex; + + _playerCryptoLimit = [(configFile >> "CfgSecConf" >> "limits"), "playerCrypto", 25000] call EPOCH_fnc_returnConfigEntry; + + _current_crypto = ((_current_crypto + _getCrypto) min _playerCryptoLimit) max 0; + [["effectCrypto", _current_crypto], (owner _player)] call EPOCH_sendPublicVariableClient; + _vars set[_cIndex, _current_crypto]; + _player setVariable["VARS", _vars]; +}; diff --git a/Sources/epoch_server/compile/epoch_trading/EPOCH_server_tradeRequest.sqf b/Sources/epoch_server/compile/epoch_trading/EPOCH_server_tradeRequest.sqf new file mode 100644 index 00000000..842d040f --- /dev/null +++ b/Sources/epoch_server/compile/epoch_trading/EPOCH_server_tradeRequest.sqf @@ -0,0 +1,14 @@ +private ["_target","_source","_token"]; +_target = _this select 0; +_source = _this select 1; + +if !([_source, _this select 2] call EPOCH_server_getPToken) exitWith{}; +if (isNull _target) exitWith{}; +if (_source distance _target > 10) exitWith{}; + +// Generate Unique Key good for only this trade request between these two players. +_tradeKey = floor(diag_tickTime + random 9999); +_source setVariable["currentTradeKey", _tradeKey]; +_target setVariable["currentTradeKey", _tradeKey]; + +[["tradeRequest", _source], (owner _target)] call EPOCH_sendPublicVariableClient; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_fill_inventory.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_fill_inventory.sqf new file mode 100644 index 00000000..1e57b7e3 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_fill_inventory.sqf @@ -0,0 +1,13 @@ +private ["_vehicle","_class","_qty"]; +_vehicle = _this select 0; +if (!isNull _vehicle) then { + //_type = _this select 1; + _class = _this select 2; + _qty = _this select 3; + switch (_this select 1) do { + case 0: { _vehicle addWeaponCargoGlobal[_class, _qty] }; + case 1: { _vehicle addBackpackCargoGlobal[_class, _qty] }; + case 2: { _vehicle addMagazineCargoGlobal[_class, _qty] }; + case 3: { _vehicle addItemCargoGlobal[_class, _qty] }; + }; +}; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_load_storage.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_load_storage.sqf new file mode 100644 index 00000000..193171d0 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_load_storage.sqf @@ -0,0 +1,202 @@ +private [ + "_storageSlotIndex","_vehHiveKey","_response","_arr" + ,"_objType","_objTypes","_objQty" + ,"_class","_damage","_hitpoints","_fuel","_count","_inventory","_dir","_location","_vehicle","_actualHitpoints","_marker","_isAir","_isShip","_config","_magazines","_colors","_color" +]; + +_diag = diag_tickTime; + +EPOCH_StorageSlots = []; +for "_i" from 1 to _this do { + + _storageSlotIndex = EPOCH_StorageSlots pushBack str(_i); + + _vehHiveKey = format ["%1:%2", (call EPOCH_fn_InstanceID), _i]; + _response = ["Storage", _vehHiveKey] call EPOCH_fnc_server_hiveGETRANGE; + + // diag_log format["STORAGE _response %1",_response]; + + if ((_response select 0) == 1 && typeName (_response select 1) == "ARRAY") then { + + _arr = _response select 1; + if !(_arr isEqualTo []) then { + + EPOCH_StorageSlots deleteAt _storageSlotIndex; + + _class = _arr select 0; + _damage = _arr select 2; + _inventory = _arr select 3; + + if (typeName(_inventory) != "ARRAY") then { _inventory = []; }; + + _dir = _arr select 1 select 0; + _location = _arr select 1 select 1; + + // increased position precision + if (count _location == 2) then{ + _location = (_location select 0) vectorAdd(_location select 1); + }; + + _vehicle = createVehicle [_class, _location, [], 0, "CAN_COLLIDE"]; + // _vehicle setDamage _damage; + _vehicle setDir _dir; + + diag_log format ["STORAGE: created storage %1 at %2", _class, _location]; + + if (count _location == 2) then { + _location set [2, 0]; + }; + + _vehicle setposATL _location; + + _vehicle setVariable ["STORAGE_SLOT", str(_i), true]; + + missionNamespace setVariable [format ["EPOCH_STORAGE_%1", _i], _vehicle]; + + _vehicle call EPOCH_server_storageInit; + + if (count _arr >= 5) then { + _color = _arr select 4; + _config = configFile >> "CfgVehicles" >> _class >> "availableColors"; + if (isArray _config) then { + _colors = getArray(_config); + _textureSelectionIndex = configFile >> "CfgVehicles" >> _class >> "textureSelectionIndex"; + _selections = if (isArray(_textureSelectionIndex)) then { getArray(_textureSelectionIndex) } else { [0] }; + _count = (count _colors)-1; + { + _textures = _colors select 0; + if (_count >= _forEachIndex) then { + _textures = _colors select _forEachIndex; + }; + _vehicle setObjectTextureGlobal [_x, (_textures select _color)]; + } forEach _selections; + _vehicle setVariable ["STORAGE_TEXTURE", _color]; + }; + }; + + if (count _arr >= 6) then { + _vehicle setVariable ["STORAGE_OWNERS", _arr select 5]; + + if (_class == "LockBoxProxy_EPOCH") then { + + if ((_arr select 6) != -1) then { + _vehicle setVariable ["EPOCH_secStorParent", _arr select 6]; + _location set [2, -10]; + _vehicle setPosATL _location; + }; + }; + }; + + clearWeaponCargoGlobal _vehicle; + clearMagazineCargoGlobal _vehicle; + clearBackpackCargoGlobal _vehicle; + clearItemCargoGlobal _vehicle; + + if !(_inventory isEqualTo []) then { + + //diag_log format ["FILLING: storage %1 pos: %2", _vehicle, (getPosATL _vehicle)]; + { + _objType = _forEachIndex; + + _objTypes = _x; + _objQty = []; + + if (_objType in [1, 2, 3]) then { + _objTypes = _x select 0; + _objQty = _x select 1; + }; + + { + switch _objType do { + // Weapon cargo + case 0: { + if (typeName _x == "ARRAY") then { + if ((count _x) >= 4) then { + _vehicle addWeaponCargoGlobal[_x deleteAt 0, 1]; + + _attachments = []; + _wMags = false; + _wMagsArray = []; + // suppressor, laser, optics, magazines(array), bipods + { + // magazines + if (typeName(_x) == "ARRAY") then{ + _wMags = true; + _wMagsArray = _x; + } + else { + // attachments + if (_x != "") then{ + _attachments pushBack _x; + }; + }; + } forEach _x; + + // add all attachments to vehicle + // TODO replace with adding attachments directly to gun (Arma feature dependant) + { + _vehicle addItemCargoGlobal[_x, 1]; + } forEach _attachments; + + if (_wMags) then{ + if (typeName _wMagsArray == "ARRAY" && (count _wMagsArray) >= 2) then{ + _vehicle addMagazineAmmoCargo[_wMagsArray select 0, 1, _wMagsArray select 1]; + }; + }; + + }; + }; + }; + // Magazine cargo + case 1: { + _magazineName = _x; + _magazineSize = _objQty select _forEachIndex; + + if ((typeName _magazineName == "STRING") && (typeName _magazineSize == "SCALAR")) then { + _magazineSizeMax = getNumber (configFile >> "CfgMagazines" >> _magazineName >> "count"); + + // Add full magazines cargo + _vehicle addMagazineAmmoCargo [_magazineName, floor (_magazineSize / _magazineSizeMax), _magazineSizeMax]; + + // Add last non full magazine + if ((_magazineSize % _magazineSizeMax) > 0) then { + _vehicle addMagazineAmmoCargo [_magazineName, 1, floor (_magazineSize % _magazineSizeMax)]; + }; + }; + }; + // Backpack cargo + case 2: { + if (typeName _x == "STRING") then { + _qty = _objQty select _forEachIndex; + _vehicle addBackpackCargoGlobal [_x, _qty]; + }; + }; + // Item cargo + case 3: { + if (typeName _x == "STRING") then { + _qty = _objQty select _forEachIndex; + _vehicle addItemCargoGlobal [_x, _qty]; + }; + }; + }; + }forEach _objTypes; + }forEach _inventory; + }; + + if (EPOCH_DEBUG_VEH) then { + _marker = createMarker [str(_location) , _location]; + _marker setMarkerShape "ICON"; + _marker setMarkerType "mil_dot"; + _marker setMarkerText _class; + _marker setMarkerColor "ColorBlue"; + }; + }; + }; +}; + +EPOCH_StorageSlotsCount = count EPOCH_StorageSlots; +publicVariable "EPOCH_StorageSlotsCount"; + +diag_log format ["Storage SPAWN TIMER %1", diag_tickTime - _diag]; + +true diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_load_vehicles.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_load_vehicles.sqf new file mode 100644 index 00000000..03abc776 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_load_vehicles.sqf @@ -0,0 +1,254 @@ +private["_vehicleSlotIndex", "_vehHiveKey", "_response", "_arr", "_arrNum", "_dataFormat", "_objType", "_objTypes", "_objQty", "_location", "_vdir", "_vup", "_vehicle", "_actualHitpoints", "_config", "_colors", "_textureSelectionIndex", "_selections", "_count", "_textures", "_weapon", "_suppressor", "_laser", "_optics", "_magazine", "_magazineName", "_magazineSize", "_magazineSizeMax", "_qty", "_diag", "_marker", "_class", "_worldspace", "_damage", "_hitpoints", "_fuel", "_inventory", "_magazines", "_color", "_dataFormatCount"]; +_diag = diag_tickTime; +_dataFormat = ["", [], 0, [], 0, [], [], 0]; +_dataFormatCount = count _dataFormat; +EPOCH_VehicleSlots = []; +_allVehicles = []; + +_serverSettingsConfig = configFile >> "CfgEpochServer"; +_simulationHandler = [_serverSettingsConfig, "simulationHandler", false] call EPOCH_fnc_returnConfigEntry; +_immuneVehicleSpawn = [_serverSettingsConfig, "immuneVehicleSpawn", false] call EPOCH_fnc_returnConfigEntry; + +for "_i" from 1 to _this do { + _vehicleSlotIndex = EPOCH_VehicleSlots pushBack str(_i); + + _vehHiveKey = format ["%1:%2", call EPOCH_fn_InstanceID,_i]; + _response = ["Vehicle", _vehHiveKey] call EPOCH_fnc_server_hiveGETRANGE; + + if ((_response select 0) == 1 && typeName (_response select 1) == "ARRAY") then { + _arr = _response select 1; + _arrNum = count _arr; + + if (_arrNum == _dataFormatCount) then { + + // Validate and replace invaild data + { + if (typeName (_arr select _forEachIndex) != typeName _x) then {_arr set[_forEachIndex, _x]}; + } forEach _dataFormat; + + _class = _arr select 0; + _worldspace = _arr select 1; + _damage = _arr select 2; + + if (_class != "" && _damage < 1) then { + _location = _worldspace deleteAt 0; + + if !(_location isEqualTo []) then { + + // increased position precision + if (count _location == 2) then{ + _location = (_location select 0) vectorAdd (_location select 1); + }; + + EPOCH_VehicleSlots deleteAt _vehicleSlotIndex; + + // temp for changes in class names + _found = ["O_Heli_Transport_04_F","O_Heli_Transport_04_bench_F","O_Heli_Transport_04_box_F","O_Heli_Transport_04_covered_F","B_Heli_Transport_03_unarmed_F","O_Truck_03_covered_F"] find _class; + if (_found != -1) then { + _class = ["O_Heli_Transport_04_EPOCH","O_Heli_Transport_04_bench_EPOCH","O_Heli_Transport_04_box_EPOCH","O_Heli_Transport_04_covered_EPOCH","B_Heli_Transport_03_unarmed_EPOCH","O_Truck_03_covered_EPOCH"] select _found; + }; + + _vehicle = createVehicle [_class, _location, [], 0, "CAN_COLLIDE"]; + + + _allVehicles pushBack _vehicle; + + _vehicle call EPOCH_server_setVToken; + + _vehicle setposATL _location; + _vehicle setVectorDirAndUp _worldspace; + + _vehicle setDamage _damage; + + _allHitpoints = getAllHitPointsDamage _vehicle; + if !(_allHitpoints isEqualTo []) then{ + _actualHitpoints = _allHitpoints select 0; + _hitpoints = _arr select 3; + if ((count _actualHitpoints) == (count _hitpoints)) then{ + { + _dmg = _hitpoints param [_forEachIndex,0]; + if (_x in ["HitFuel", "HitEngine"]) then { + _dmg = _dmg min 0.9; + }; + _vehicle setHitIndex [_forEachIndex, _dmg]; + } forEach _actualHitpoints; + }; + }; + + if (_immuneVehicleSpawn) then{ + _vehicle allowDamage false; + }; + + _vehicle setFuel (_arr select 4); + + _vehicle call EPOCH_server_vehicleInit; + + _config = configFile >> "CfgVehicles" >> _class >> "availableColors"; + if (isArray(_config)) then { + _color = _arr select 7; + _colors = getArray(_config); + _textureSelectionIndex = configFile >> "CfgVehicles" >> _class >> "textureSelectionIndex"; + _selections = if (isArray(_textureSelectionIndex)) then { getArray(_textureSelectionIndex) } else { [0] }; + _count = (count _colors) - 1; + { + _textures = _colors select 0; + if (_count >= _forEachIndex) then { + _textures = _colors select _forEachIndex; + }; + _vehicle setObjectTextureGlobal [_x, _textures select _color]; + } forEach _selections; + _vehicle setVariable ["VEHICLE_TEXTURE", _color]; + }; + + clearWeaponCargoGlobal _vehicle; + clearMagazineCargoGlobal _vehicle; + clearBackpackCargoGlobal _vehicle; + clearItemCargoGlobal _vehicle; + + _vehicle disableTIEquipment true; + + _vehicle lock true; + + _vehicle setVariable ["VEHICLE_SLOT", str(_i), true]; + + //diag_log format ["FILLING: _vehicle %1 pos: %2", _vehicle, (getPosATL _vehicle)]; + { + _objType = _forEachIndex; + + _objTypes = _x; + _objQty = []; + + if (_objType in [1, 2, 3]) then { + _objTypes = _x select 0; + _objQty = _x select 1; + }; + + { + switch _objType do { + // Weapon cargo + case 0: { + if (typeName _x == "ARRAY") then { + if ((count _x) >= 4) then { + + _vehicle addWeaponCargoGlobal[_x deleteAt 0, 1]; + + _attachments = []; + _wMags = false; + _wMagsArray = []; + // suppressor, laser, optics, magazines(array), bipods + { + // magazines + if (typeName(_x) == "ARRAY") then{ + _wMags = true; + _wMagsArray = _x; + } + else { + // attachments + if (_x != "") then{ + _attachments pushBack _x; + }; + }; + } forEach _x; + + // add all attachments to vehicle + // TODO replace with adding attachments directly to gun (Arma feature dependant) + { + _vehicle addItemCargoGlobal[_x, 1]; + } forEach _attachments; + + if (_wMags) then{ + if (typeName _wMagsArray == "ARRAY" && (count _wMagsArray) >= 2) then{ + _vehicle addMagazineAmmoCargo[_wMagsArray select 0, 1, _wMagsArray select 1]; + }; + }; + + }; + }; + }; + // Magazine cargo + case 1: { + _magazineName = _x; + _magazineSize = _objQty select _forEachIndex; + + if ((typeName _magazineName == "STRING") && (typeName _magazineSize == "SCALAR")) then { + _magazineSizeMax = getNumber (configFile >> "CfgMagazines" >> _magazineName >> "count"); + + // Add full magazines cargo + _vehicle addMagazineAmmoCargo [_magazineName, floor (_magazineSize / _magazineSizeMax), _magazineSizeMax]; + + // Add last non full magazine + if ((_magazineSize % _magazineSizeMax) > 0) then { + _vehicle addMagazineAmmoCargo [_magazineName, 1, floor (_magazineSize % _magazineSizeMax)]; + }; + }; + }; + // Backpack cargo + case 2: { + if (typeName _x == "STRING") then { + _qty = _objQty select _forEachIndex; + _vehicle addBackpackCargoGlobal [_x, _qty]; + }; + }; + // Item cargo + case 3: { + if (typeName _x == "STRING") then { + _qty = _objQty select _forEachIndex; + _vehicle addItemCargoGlobal [_x, _qty]; + }; + }; + }; + } forEach _objTypes; + } forEach (_arr select 5); + + // remove and add back magazines works for armed trucks but not helis ATM + {_vehicle removeMagazineGlobal _x}count (magazines _vehicle); + {_vehicle addMagazine _x}count (_arr select 6); + + // turrets + /* + _mags = _vehicle magazinesTurret [0]; + { + _object removeMagazinesTurret [_x, [0]]; + } forEach _mags; + + _mags = _vehicle magazinesTurret [-1]; + { + _object removeMagazinesTurret [_x, [-1]]; + } forEach _mags; + */ + + if (EPOCH_DEBUG_VEH) then { + _marker = createMarker [str(_location) , _location]; + _marker setMarkerShape "ICON"; + _marker setMarkerType "mil_dot"; + _marker setMarkerText _class; + _marker setMarkerColor "ColorGreen"; + }; + + if (_simulationHandler) then{ + _vehicle enableSimulationGlobal false; + }; + + + + }; + }; + }; + }; +}; + +// re-enable damage to vehicles after we wait +if (_immuneVehicleSpawn) then{ + _immuneVehicleSpawnTime = [_serverSettingsConfig, "immuneVehicleSpawnTime", 120] call EPOCH_fnc_returnConfigEntry; + [_allVehicles,_immuneVehicleSpawnTime] spawn{ + sleep (_this select 1); + {_x allowDamage true} count (_this select 0); + }; +}; + +addToRemainsCollector _allVehicles; + +diag_log format ["VEH SPAWN TIMER %1", diag_tickTime - _diag]; +// diag_log (EPOCH_VehicleSlots); + +true diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_killedBuilding.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_killedBuilding.sqf new file mode 100644 index 00000000..aa872889 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_killedBuilding.sqf @@ -0,0 +1,19 @@ +private ["_building","_vehSlot","_vehHiveKey","_killer"]; + +_building = _this select 0; +_killer = _this select 1; + +if (!isNull _building) then { + + _vehSlot = _building getVariable["BUILD_SLOT", -1]; + if (_vehSlot != -1) then { + _vehHiveKey = format ["%1:%2", (call EPOCH_fn_InstanceID), _vehSlot]; + ["Building", _vehHiveKey, []] call EPOCH_fnc_server_hiveSET; + EPOCH_BuildingSlots set [_vehSlot, 0]; + + EPOCH_BuildingSlotCount = { _x == 0 } count EPOCH_BuildingSlots; + publicVariable "EPOCH_BuildingSlotCount"; + + ['BuildingKilled', format["%1 was killed by %2 at %3", typeOf _building, _killer, getPosATL _building]] call EPOCH_fnc_server_hiveLog; + }; +}; diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_killedStorage.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_killedStorage.sqf new file mode 100644 index 00000000..ee84320d --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_killedStorage.sqf @@ -0,0 +1,18 @@ +private ["_vehicle","_vehSlot","_vehHiveKey","_storage","_killer"]; + +_storage = _this select 0; +_killer = _this select 1; + +if (!isNull _storage) then { + _vehSlot = _storage getVariable["STORAGE_SLOT", "ABORT"]; + if (_vehSlot != "ABORT") then { + _vehHiveKey = format ["%1:%2", (call EPOCH_fn_InstanceID), _vehSlot]; + ["Storage", _vehHiveKey, []] call EPOCH_fnc_server_hiveSET; + EPOCH_StorageSlots pushBack _vehSlot; + + EPOCH_StorageSlotsCount = count EPOCH_StorageSlots; + publicVariable "EPOCH_StorageSlotsCount"; + + ['StorageKilled', format["%1 was killed by %2 at %3", typeOf _storage, _killer, getPosATL _storage]] call EPOCH_fnc_server_hiveLog; + }; +}; diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_killedVehicle.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_killedVehicle.sqf new file mode 100644 index 00000000..93f03903 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_killedVehicle.sqf @@ -0,0 +1,17 @@ +private ["_vehicle","_vehSlot","_vehHiveKey","_killer"]; + +_vehicle = _this select 0; +_killer = _this select 1; + +if (!isNull _vehicle) then { + _vehSlot = _vehicle getVariable ["VEHICLE_SLOT", "ABORT"]; + if (_vehSlot != "ABORT") then { + _vehHiveKey = format ["%1:%2", (call EPOCH_fn_InstanceID), _vehSlot]; + ["Vehicle", _vehHiveKey, []] call EPOCH_fnc_server_hiveSET; + EPOCH_VehicleSlots pushBack _vehSlot; + EPOCH_VehicleSlotCount = count EPOCH_VehicleSlots; + publicVariable "EPOCH_VehicleSlotCount"; + + ['VehicleKilled', format["%1 was killed by %2 at %3", typeOf _vehicle, _killer, getPosATL _vehicle]] call EPOCH_fnc_server_hiveLog; + }; +}; diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_storage.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_storage.sqf new file mode 100644 index 00000000..88c417bf --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_storage.sqf @@ -0,0 +1,76 @@ +private ["_vehicle","_class","_vehSlot","_vehHiveKey","_damage","_fuel","_pos","_dir","_worldspace","_hitpoints","_actualHitpoints","_inventory","_VAL","_return","_magazines","_colorSlot","_wepsItemsCargo","_magsAmmoCargo","_magsAmmoCargoMinimized","_cargoIndex"]; +if (!isNull _this) then { + _vehicle = _this; + + _class = typeOf _vehicle; + _vehSlot = _vehicle getVariable["STORAGE_SLOT", "ABORT"]; + if (_vehSlot != "ABORT") then { + + _vehHiveKey = format ["%1:%2", (call EPOCH_fn_InstanceID),_vehSlot]; + _damage = damage _vehicle; + + _pos = getposATL _vehicle call EPOCH_precisionPos; + _dir = getDir _vehicle; + _worldspace = [_dir,_pos]; + + // may not be needed but should prevent in DB. + _wepsItemsCargo = weaponsItemsCargo _vehicle; + if (isNil "_wepsItemsCargo") then { + _wepsItemsCargo = []; + }; + _magsAmmoCargo = magazinesAmmoCargo _vehicle; + if (isNil "_magsAmmoCargo") then { + _magsAmmoCargo = []; + }; + + // minimize magazine ammo cargo + _magsAmmoCargoMinimized = [[],[]]; + { + // find cargo in temp var + _cargoIndex = _magsAmmoCargoMinimized find (_x select 0); + if (_cargoIndex >= 0) then { + (_magsAmmoCargoMinimized select 1) set [_cargoIndex, ((_magsAmmoCargoMinimized select 1) select _cargoIndex) + (_x select 1)]; // get count & add current + } + else { + (_magsAmmoCargoMinimized select 0) pushBack (_x select 0); // classname + (_magsAmmoCargoMinimized select 1) pushBack (_x select 1); // count + }; + } forEach _magsAmmoCargo; + + _inventory = [ + _wepsItemsCargo, + _magsAmmoCargoMinimized, + getBackpackCargo _vehicle, + getItemCargo _vehicle + ]; + + _colorSlot = _vehicle getVariable ["STORAGE_TEXTURE",0]; + + _storageOwners = _vehicle getVariable["STORAGE_OWNERS",[]]; + _storageParent = _vehicle getVariable["EPOCH_secStorParent",-1]; + + _parentID = _vehicle getVariable["EPOCH_secStorParent", -1]; + _parent = missionNamespace getVariable[format["EPOCH_BUILD_%1", _parentID], objNull]; + + /* + if (!isNull _parent) then { + _objSlot = _parent getVariable["BUILD_SLOT", -1]; + if (_objSlot != -1) then { + _objHiveKey = format["%1:%2", (call EPOCH_fn_InstanceID), _objSlot]; + _VAL2 = [typeOf _parent, [(getposATL _parent call EPOCH_precisionPos), vectordir _parent, vectorup _parent], _vehSlot, _parent getVariable["BUILD_OWNER", "-1"], _parent getVariable["TEXTURE_SLOT", 0]]; + + _parent call EPOCH_fnc_saveBuilding; + + ["Building", _objHiveKey, EPOCH_expiresBuilding, _VAL2] call EPOCH_fnc_server_hiveSETEX; + }; + }; + */ + + _VAL = [_class, _worldspace, _damage, _inventory, _colorSlot, _storageOwners, _storageParent]; + ["Storage", _vehHiveKey, EPOCH_expiresBuilding, _VAL] call EPOCH_fnc_server_hiveSETEX; + //["Storage", _vehHiveKey, _VAL] call EPOCH_fnc_server_hiveSET; + + diag_log format["STORAGE: saved to hive %1 Pos %2 Owners %3 Parent %4", _class, _worldspace, _storageOwners, _storageParent]; + }; + +}; diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_vehicle.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_vehicle.sqf new file mode 100644 index 00000000..ac76e08c --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_vehicle.sqf @@ -0,0 +1,49 @@ +private ["_vehicle","_class","_vehSlot","_vehHiveKey","_damage","_fuel","_pos","_dir","_worldspace","_hitpoints","_actualHitpoints","_inventory","_VAL","_return","_magazines","_colorSlot","_magsAmmoCargoMinimized","_cargoIndex"]; +if (!isNull _this) then { + + _vehicle = _this; + // if (!alive _vehicle) exitWith {diag_log format["DEBUG DEAD VEHICLE SKIPPED SAVE: %1 %2", _vehicle]}; + _vehSlot = _this getVariable["VEHICLE_SLOT", "ABORT"]; + if (_vehSlot != "ABORT") then { + + _vehHiveKey = format ["%1:%2", (call EPOCH_fn_InstanceID),_vehSlot]; + + _hitpoints = (getAllHitPointsDamage _vehicle) param [2,[]]; + + // may not be needed but should prevent in DB. + _wepsItemsCargo = weaponsItemsCargo _vehicle; + if (isNil "_wepsItemsCargo") then { + _wepsItemsCargo = []; + }; + _magsAmmoCargo = magazinesAmmoCargo _vehicle; + if (isNil "_magsAmmoCargo") then { + _magsAmmoCargo = []; + }; + + // minimize magazine ammo cargo + _magsAmmoCargoMinimized = [[],[]]; + { + // find cargo in temp var + _cargoIndex = _magsAmmoCargoMinimized find (_x select 0); + if (_cargoIndex >= 0) then { + (_magsAmmoCargoMinimized select 1) set [_cargoIndex, ((_magsAmmoCargoMinimized select 1) select _cargoIndex) + (_x select 1)]; // get count & add current + } + else { + (_magsAmmoCargoMinimized select 0) pushBack (_x select 0); // classname + (_magsAmmoCargoMinimized select 1) pushBack (_x select 1); // count + }; + } forEach _magsAmmoCargo; + + _inventory = [ + _wepsItemsCargo, + _magsAmmoCargoMinimized, + getBackpackCargo _vehicle, + getItemCargo _vehicle + ]; + _colorSlot = _vehicle getVariable ["VEHICLE_TEXTURE",0]; + + _VAL = [typeOf _vehicle,[(getposATL _vehicle call EPOCH_precisionPos),vectordir _vehicle,vectorup _vehicle],damage _vehicle,_hitpoints,fuel _vehicle,_inventory,magazinesAmmo _vehicle,_colorSlot]; + ["Vehicle", _vehHiveKey, EPOCH_expiresVehicle, _VAL] call EPOCH_fnc_server_hiveSETEX; + //["Vehicle", _vehHiveKey, _VAL] call EPOCH_fnc_server_hiveSET; + }; +}; diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_vehicles.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_vehicles.sqf new file mode 100644 index 00000000..4b989c0d --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_save_vehicles.sqf @@ -0,0 +1,15 @@ +private ["_vehSlot"]; +{ + _vehSlot = _x getVariable ["VEHICLE_SLOT", "ABORT"]; + if (_vehSlot != "ABORT") then { + if !(_x in EPOCH_saveVehQueue) then { EPOCH_saveVehQueue pushBack _x }; + }; + _storSlot = _x getVariable["STORAGE_SLOT", "ABORT"]; + if (_storSlot != "ABORT") then { + if !(_x in EPOCH_saveStorQueue) then { EPOCH_saveStorQueue pushBack _x }; + }; + _objSlot = _x getVariable["BUILD_SLOT", -1]; + if (_objSlot != -1) then{ + if !(_x in EPOCH_saveBuildQueue) then{ EPOCH_saveBuildQueue pushBack _x }; + }; +} forEach _this; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_fillVehicle.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_fillVehicle.sqf new file mode 100644 index 00000000..9adf385e --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_fillVehicle.sqf @@ -0,0 +1,15 @@ +private ["_owner","_vehicle","_value"]; +_vehicle = _this select 0; +_plyr = _this select 2; + +if !([_plyr, _this select 3] call EPOCH_server_getPToken) exitWith{}; +if (_plyr distance _vehicle > 20) exitWith{}; + +if (!isNull _vehicle) then { + _value = _this select 1; + if (local _vehicle) then { + _vehicle setFuel _value; + } else { + [["fillVehicle", [_vehicle, _value]], (owner _vehicle)] call EPOCH_sendPublicVariableClient; + }; +}; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_lockStorage.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_lockStorage.sqf new file mode 100644 index 00000000..ac9d0793 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_lockStorage.sqf @@ -0,0 +1,85 @@ +_unit = _this select 0; +_lockStatus = _this select 1; +_plyr = _this select 2; + +if !([_plyr, _this select 3] call EPOCH_server_getPToken) exitWith{}; +if (isNull _unit) exitWith{}; +if (_plyr distance _unit > 20) exitWith{}; + +_type = typeOf _unit; +if (_type in ["LockBox_EPOCH","LockBoxProxy_EPOCH"]) then { + + _parentID = _unit getVariable ["EPOCH_secureStorage", "-1"]; + _weaponHolder = missionNamespace getVariable [format ["EPOCH_STORAGE_%1",_parentID], objNull]; + + //diag_log format["_parentID %1", _parentID]; + if (!isNull _weaponHolder) then { + _owners = _weaponHolder getVariable["STORAGE_OWNERS", []]; + //diag_log format["_owners %1", _owners]; + + // allow group members and owner access + _plyrUID = getPlayerUID _plyr; + _plyrGroup = _plyr getVariable ["GROUP",""]; + + if (_plyrGroup != "") then { + if (_plyrGroup in _owners) then { + _unit setVariable["EPOCH_Locked", _lockStatus, true]; + _weaponHolder setPosATL(getPosATL _unit); + } else { + _response = ["Group", _plyrGroup] call EPOCH_fnc_server_hiveGETRANGE; + if ((_response select 0) == 1 && typeName(_response select 1) == "ARRAY") then { + _gArray = _response select 1; + if ( + { (_x select 0) in _owners }count(_gArray select 3) > 0 || + {(_x select 0) in _owners}count(_gArray select 4) > 0 || + _plyrUID in _owners + ) then { + _unit setVariable["EPOCH_Locked", _lockStatus, true]; + _weaponHolder setPosATL(getPosATL _unit); + }; + }; + }; + } else { + if (_plyrUID in _owners) then { + _unit setVariable ["EPOCH_Locked", _lockStatus, true]; + _weaponHolder setPosATL (getPosATL _unit); + }; + }; + }; + + _parentID = _unit getVariable ["EPOCH_secStorParent", -1]; + _parent = missionNamespace getVariable [format ["EPOCH_BUILD_%1", _parentID], objNull]; + //diag_log format["_parentID2 %1", _parentID]; + if (!isNull _parent) then { + _owners = _unit getVariable["STORAGE_OWNERS", []]; + //diag_log format["_owners %1", _owners]; + + // allow group members and owner access + _plyrUID = getPlayerUID _plyr; + _plyrGroup = _plyr getVariable ["GROUP",""]; + if (_plyrGroup != "") then { + _response = ["Group", _plyrGroup] call EPOCH_fnc_server_hiveGETRANGE; + if ((_response select 0) == 1 && typeName (_response select 1) == "ARRAY") then { + _gArray = _response select 1; + if ( + {(_x select 0) in _owners}count(_gArray select 3) > 0 || + {(_x select 0) in _owners}count(_gArray select 4) > 0 || + _plyrUID in _owners + ) then { + _parent setVariable ["EPOCH_Locked", _lockStatus, true]; + _currentPos = getPosATL _unit; + _currentPos set[2, -10]; + _unit setPosATL _currentPos; + }; + }; + } + else { + if (_plyrUID in _owners) then { + _parent setVariable ["EPOCH_Locked", _lockStatus, true]; + _currentPos = getPosATL _unit; + _currentPos set [2, -10]; + _unit setPosATL _currentPos; + }; + }; + }; +}; diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_lockVehicle.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_lockVehicle.sqf new file mode 100644 index 00000000..a873f701 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_lockVehicle.sqf @@ -0,0 +1,51 @@ +private ["_vehicle","_value"]; + +_vehicle = _this select 0; +_player = _this select 2; + +if (isNull _vehicle) exitWith {}; + +// Token check +if !([_player,_this select 3] call EPOCH_server_getPToken) exitWith {}; +if (_player distance _vehicle > 20) exitWith {}; + +// Group access +_plyrUID = getPlayerUID _player; +_plyrGroup = _player getVariable["GROUP", ""]; + +_lockOwner = _plyrUID; +if (_plyrGroup != "") then { + _lockOwner = _plyrGroup; +}; + +_lockedOwner = "-1"; +_vehSlot = _vehicle getVariable["VEHICLE_SLOT", "ABORT"]; +_vehLockHiveKey = format["%1:%2", (call EPOCH_fn_InstanceID), _vehSlot]; +if (_vehSlot != "ABORT") then { + _response = ["VehicleLock", _vehLockHiveKey] call EPOCH_fnc_server_hiveGETRANGE; + if ((_response select 0) == 1 && typeName(_response select 1) == "ARRAY" && !((_response select 1) isEqualTo[])) then { + _lockedOwner = _response select 1 select 0; + }; +}; + +_isLocked = locked _vehicle in[2, 3]; + +// Lockout mech +if (!_isLocked || _lockedOwner == _lockOwner || _lockedOwner == "-1") then { + + _value = _this select 1; + + if (_value) then { + ["VehicleLock", _vehLockHiveKey, EPOCH_vehicleLockTime, [_lockOwner]] call EPOCH_fnc_server_hiveSETEX; + }; + + if (local _vehicle) then { + _vehicle lock _value; + } else { + if (_value) then { + [["lockVehicle", _vehicle], (owner _vehicle)] call EPOCH_sendPublicVariableClient; + } else { + [["unlockVehicle", _vehicle], (owner _vehicle)] call EPOCH_sendPublicVariableClient; + }; + }; +}; \ No newline at end of file diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_packJack.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_packJack.sqf new file mode 100644 index 00000000..2bb4cc12 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_packJack.sqf @@ -0,0 +1,12 @@ +_unit = _this select 0; +_plyr = _this select 1; + +if !([_plyr, _this select 2] call EPOCH_server_getPToken) exitWith{}; +if (isNull _unit) exitWith{}; +if (_plyr distance _unit > 20) exitWith{}; + +if (typeOf _unit == "Jack_SIM_EPOCH") then { + deleteVehicle _unit; + _plyr addMagazine["JackKit", 1]; + // diag_log format["added JackKit to %1", _plyr]; +}; diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_packStorage.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_packStorage.sqf new file mode 100644 index 00000000..abd54dcb --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_packStorage.sqf @@ -0,0 +1,127 @@ +_unit = _this select 0; +_plyr = _this select 1; + +if !([_plyr, _this select 2] call EPOCH_server_getPToken) exitWith{}; +if (isNull _unit) exitWith{}; +if (_plyr distance _unit > 20) exitWith{}; + +if (typeOf _unit == "LockBox_EPOCH") then { + _parentID = _unit getVariable["EPOCH_secureStorage", "-1"]; + _weaponHolder = missionNamespace getVariable[format["EPOCH_STORAGE_%1", _parentID], objNull]; + if (!isNull _weaponHolder) then { + _owners = _weaponHolder getVariable["STORAGE_OWNERS", []]; + if ((getPlayerUID _plyr) in _owners) then { + + _posWH = getPosATL _unit; + [_unit, _plyr] call EPOCH_server_save_killedBuilding; + deleteVehicle _unit; + + // may not be needed but should prevent in DB. + _wepsItemsCargo = weaponsItemsCargo _weaponHolder; + if (isNil "_wepsItemsCargo") then { + _wepsItemsCargo = []; + }; + _magsAmmoCargo = magazinesAmmoCargo _weaponHolder; + if (isNil "_magsAmmoCargo") then { + _magsAmmoCargo = []; + }; + + // dump items on ground + _inventory = [ + _wepsItemsCargo, + _magsAmmoCargo, + getBackpackCargo _weaponHolder, + getItemCargo _weaponHolder + ]; + + + [_weaponHolder, _plyr] call EPOCH_server_save_killedStorage; + deleteVehicle _weaponHolder; + + _gwh = createVehicle["groundWeaponHolder", _posWH, [], 0, "CAN_COLLIDE"]; + _gwh setPosATL _posWH; + _gwh addMagazineCargoGlobal["ItemLockbox", 1]; + + { + _objType = _forEachIndex; + + _objTypes = _x; + _objQty = []; + + if (_objType in[2, 3]) then { + _objTypes = _x select 0; + _objQty = _x select 1; + }; + + { + switch _objType do { + case 0: { + if (typeName _x == "ARRAY") then { + _arrCount = count _x; + if (_arrCount >= 4) then { + + _gwh addWeaponCargoGlobal[_x deleteAt 0, 1]; + + _attachments = []; + _wMags = false; + _wMagsArray = []; + // suppressor, laser, optics, magazines(array), bipods + { + // magazines + if (typeName(_x) == "ARRAY") then{ + _wMags = true; + _wMagsArray = _x; + } + else { + // attachments + if (_x != "") then{ + _attachments pushBack _x; + }; + }; + } forEach _x; + + // add all attachments to vehicle + // TODO replace with adding attachments directly to gun (Arma feature dependant) + { + _gwh addItemCargoGlobal[_x, 1]; + } forEach _attachments; + + if (_wMags) then{ + if (typeName _wMagsArray == "ARRAY" && (count _wMagsArray) >= 2) then{ + _gwh addMagazineAmmoCargo[_wMagsArray select 0, 1, _wMagsArray select 1]; + }; + }; + + }; + }; + }; + case 1: { + if (typeName _x == "ARRAY") then { + if ((count _x) == 2) then { + _magazineName = _x select 0; + _magazineSize = _x select 1; + + if ((typeName _magazineName == "STRING") && (typeName _magazineSize == "SCALAR")) then { + _gwh addMagazineAmmoCargo[_magazineName, 1, _magazineSize]; + }; + }; + }; + }; + case 2: { + if (typeName _x == "STRING") then { + _qty = _objQty select _forEachIndex; + _gwh addBackpackCargoGlobal[_x, _qty]; + }; + }; + case 3: { + if (typeName _x == "STRING") then { + _qty = _objQty select _forEachIndex; + _gwh addItemCargoGlobal[_x, _qty]; + }; + }; + }; + }forEach _objTypes; + }forEach _inventory; + }; + }; +}; diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_repairVehicle.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_repairVehicle.sqf new file mode 100644 index 00000000..ab3c75da --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_server_repairVehicle.sqf @@ -0,0 +1,22 @@ +private ["_vehicle","_value"]; +_vehicle = _this select 0; +_value = _this select 1; +_plyr = _this select 2; +if (isNull _vehicle) exitWith{}; + +if !([_plyr, _this select 3] call EPOCH_server_getPToken) exitWith{}; +if (_plyr distance _vehicle > 20) exitWith{}; +// if (vehicle _plyr != _plyr) exitWith{}; + +if ((_value select 0) == "ALL") then { + _vehicle setDamage 0; +} else { + if (local _vehicle) then { + _vehicle setHitIndex _value; + //diag_log format["REPAIR VEHICLE: %1 server local", _vehicle]; + } else { + [["repairVehicle", [_vehicle, _value]], (owner _vehicle)] call EPOCH_sendPublicVariableClient; + //diag_log format["REPAIR VEHICLE: %1 owner: %2", _vehicle, owner _vehicle]; + }; +}; +_vehicle call EPOCH_server_save_vehicle; diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_spawn_vehicle.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_spawn_vehicle.sqf new file mode 100644 index 00000000..68180c8e --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_spawn_vehicle.sqf @@ -0,0 +1,103 @@ +/* + Epoch Vehicle Spawn Function +*/ + +_vehClass = _this select 0; +_position = _this select 1; +_direction = _this select 2; +_locked = _this select 3; +_slot = _this select 4; + +_lockOwner = param [5, ""]; +_can_collide = param [6, "CAN_COLLIDE"]; +_spawnLoot = param [7, false]; + + + +//place vehicle +_vehObj = createVehicle[_vehClass, _position, [], 0, _can_collide]; +_vehObj call EPOCH_server_setVToken; + +// Set Direction +if (typeName _direction == "ARRAY") then{ + _vehObj setVectorDirAndUp _direction; +} else { + _vehObj setdir _direction; +}; +// Set Position +_vehObj setposATL _position; + +// Normalize vehicle inventory +clearWeaponCargoGlobal _vehObj; +clearMagazineCargoGlobal _vehObj; +clearBackpackCargoGlobal _vehObj; +clearItemCargoGlobal _vehObj; + +// Disable Termal Equipment +_vehObj disableTIEquipment true; + +// Vehicle Lock +_vehObj lock _locked; + +// randomize fuel TODO push min max to config +_vehObj setFuel ((random 1 max 0.1) min 0.9); + +// get colors from config +_config = (configFile >> "CfgVehicles" >> _vehClass >> "availableColors"); + +if (isArray(_config)) then{ + + _textureSelectionIndex = configFile >> "CfgVehicles" >> _vehClass >> "textureSelectionIndex"; + _selections = if (isArray(_textureSelectionIndex)) then{ getArray(_textureSelectionIndex) } else { [0] }; + _colors = getArray(_config); + _textures = _colors select 0; + _color = floor(random(count _textures)); + _count = (count _colors) - 1; + { + if (_count >= _forEachIndex) then{ + _textures = _colors select _forEachIndex; + }; + _vehObj setObjectTextureGlobal[_x, (_textures select _color)]; + } forEach _selections; + _vehObj setVariable["VEHICLE_TEXTURE", _color]; +}; + +// add random loots +if (_spawnLoot) then { + if (_vehClass isKindOf "Ship") then{ + [_vehObj, "VehicleBoat"] call EPOCH_serverLootObject; + } else { + [_vehObj, "Vehicle"] call EPOCH_serverLootObject; + }; +}; + +// Set slot used by vehicle +_vehObj setVariable["VEHICLE_SLOT", _slot, true]; + +// Lock vehicle for owner +if (_locked && _lockOwner != "") then { + _vehLockHiveKey = format["%1:%2", (call EPOCH_fn_InstanceID), _slot]; + ["VehicleLock", _vehLockHiveKey, EPOCH_vehicleLockTime, [_lockOwner]] call EPOCH_fnc_server_hiveSETEX; +} else { + _vehLockHiveKey = format["%1:%2", (call EPOCH_fn_InstanceID), _slot]; + ["VehicleLock", _vehLockHiveKey] call EPOCH_fnc_server_hiveDEL; +}; + +// SAVE VEHICLE +_vehObj call EPOCH_server_save_vehicle; + +// Event Handlers +_vehObj call EPOCH_server_vehicleInit; + +// Markers +if (EPOCH_DEBUG_VEH) then{ + _marker = createMarker[str(_position), _position]; + _marker setMarkerShape "ICON"; + _marker setMarkerType "mil_dot"; + _marker setMarkerText _vehClass; +}; + +// Add to A3 remains collector +addToRemainsCollector[_vehObj]; + +_vehObj diff --git a/Sources/epoch_server/compile/epoch_vehicle/EPOCH_spawn_vehicles.sqf b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_spawn_vehicles.sqf new file mode 100644 index 00000000..20662c7c --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/EPOCH_spawn_vehicles.sqf @@ -0,0 +1,159 @@ +private [ + "_spawnPositionSize","_spawnPositions","_type","_position","_range","_roads","_maxSpawnSize" + ,"_vehicleFound","_vehClass" + ,"_countAllowedVeh","_randomVehicleIndex","_randomVehicle","_velimit","_vehicleCount" + ,"_isShip" + ,"_spawnPositionIndex","_spawnPosition","_roadPosition" + ,"_dir","_vehObj","_config" + ,"_textureSelectionIndex","_selections","_colors","_textures","_color","_count" + ,"_marker" +]; + +_allowedVehiclesList = []; +{ + _vehClass = _x select 0; + _velimit = _x select 1; + _vehicleCount = {typeOf _x == _vehClass} count vehicles; + for "_i" from 1 to (_velimit-_vehicleCount) do { + _allowedVehiclesList pushBack _vehClass; + }; +} forEach EPOCH_allowedVehiclesList; + +if (_allowedVehiclesList isEqualTo []) exitWith { + diag_log "DEBUG: All vehicles over limit"; +}; + +_spawnPositionSize = [ + ["FlatAreaCity",1], + ["FlatAreaCitySmall",1], + ["NameCity",2], + ["NameVillage",1], + ["NameCityCapital",4], + ["Airport",5] +]; +if (worldName in ["Bornholm","Australia"]) then { + _spawnPositionSize append [ + ["NameLocal",2], + ["StrongpointArea",1], + ["VegetationBroadleaf",1], + ["VegetationFir",1], + ["ViewPoint",1] + ]; +}; + + +_allowedTypes = []; +{ + _allowedTypes pushBack (_x select 0) +}forEach _spawnPositionSize; + + +_allCitys = "getText(_x >> 'type') in _allowedTypes" configClasses (configfile >> "CfgWorlds" >> worldName >> "Names"); +_allCitysDync = []; + +{ + _cityPos = getArray(_x >> "position"); + _range = getNumber(_x >> "radiusA") * 1.3; + _nearBy = count(_cityPos nearEntities[["LandVehicle", "Ship", "Air", "Tank"], _range]); + _find = _allowedTypes find (getText(_x >> "type")); + if (_find > -1) then{ + _limit = _spawnPositionSize select _find select 1; + if (_limit > _nearBy) then{ + _allCitysDync pushBack _x; + }; + }; +} forEach _allCitys; + + +_position = [0,0,0]; + + +{ + if (count EPOCH_VehicleSlots <= EPOCH_storedVehicleCount) exitWith{}; + + _vehCount = count _allowedVehiclesList; + if (_vehCount <= 0) exitWith{}; + + _vehClass = _allowedVehiclesList deleteAt(floor(random(_vehCount))); + if (isNil "_vehClass") exitWith{}; + + _direction = random 360; + _position = [0,0,0]; + _getRandomPos = true; + + + _preferedPos = getArray(configFile >> "CfgEpoch" >> worldname >> "whitelistedVehiclePos" >> _vehClass); + if !(_preferedPos isEqualTo []) then{ + _newPosition = _preferedPos select(floor(random(count _preferedPos))); + if ((nearestObjects[(_newPosition select 0), ["LandVehicle", "Ship", "Air", "Tank"], 50]) isEqualTo []) then{ + _position = _newPosition select 0; + _direction = _newPosition select 1; + _getRandomPos = false; + }; + }; + + + if (_getRandomPos) then{ + _isShip = _vehClass isKindOf "Ship"; + if (_isShip || (_vehClass isKindOf "Air")) then{ + if (_isShip) then{ + _position = [epoch_centerMarkerPosition, 0, EPOCH_dynamicVehicleArea, 10, 0, 4000, 1] call BIS_fnc_findSafePos; + _position = [_position, 0, 100, 10, 2, 4000, 0] call BIS_fnc_findSafePos; + } else { + _position = [epoch_centerMarkerPosition, 0, EPOCH_dynamicVehicleArea, 10, 0, 1000, 0] call BIS_fnc_findSafePos; + }; + } else { + + if (_allCitysDync isEqualTo []) then { + _position = [epoch_centerMarkerPosition, 0, EPOCH_dynamicVehicleArea, 10, 0, 1000, 0] call BIS_fnc_findSafePos; + } else { + _selectedCity = _allCitysDync deleteAt (floor random(count _allCitysDync)); + _cityPos = getArray(_selectedCity >> "position"); + _range = getNumber(_selectedCity >> "radiusA") * 1.3; + + _roads = _cityPos nearRoads _range; + if !(_roads isEqualTo []) then { + _road = _roads select(floor random(count _roads)); + _position = getPosATL _road; + _position deleteAt 2; + }; + }; + }; + }; + + if ((count _position == 2 && _getRandomPos) || !_getRandomPos) then{ + + + _collide = "CAN_COLLIDE"; + if (_getRandomPos) then{ + _collide = "NONE"; + _position set[2, 0]; + if (surfaceIsWater _position) then{ + _position = ASLToATL _position; + }; + }; + + _vehObj = [_vehClass,_position,_direction,true,_x,"",_collide,true] call EPOCH_fnc_spawn_vehicle; + + + if (EPOCH_DEBUG_VEH) then { + _marker = createMarker [str(_position) , _position]; + _marker setMarkerShape "ICON"; + _marker setMarkerType "mil_dot"; + _marker setMarkerText _vehClass; + _marker setMarkerColor "ColorBlue"; + }; + + + EPOCH_VehicleSlots set[_forEachIndex, "REM"]; + }; + +} forEach EPOCH_VehicleSlots; + +EPOCH_VehicleSlots = EPOCH_VehicleSlots - ["REM"]; + +EPOCH_VehicleSlotCount = count EPOCH_VehicleSlots; +publicVariable "EPOCH_VehicleSlotCount"; + +EPOCH_allowedVehiclesList = nil; +true diff --git a/Sources/epoch_server/compile/epoch_vehicle/test.sqf b/Sources/epoch_server/compile/epoch_vehicle/test.sqf new file mode 100644 index 00000000..e2f7f5a7 --- /dev/null +++ b/Sources/epoch_server/compile/epoch_vehicle/test.sqf @@ -0,0 +1,205 @@ +epoch_centerMarkerPosition = getpos player; +EPOCH_dynamicVehicleArea = 20000 / 2; + +EPOCH_VehicleSlots = []; +for "_i" from 1 to 156 do { + EPOCH_VehicleSlots pushBack str(_i); +}; + +EPOCH_storedVehicleCount = 0; + +EPOCH_allowedVehiclesList = [ + ["C_Offroad_01_EPOCH", 8], + ["C_Quadbike_01_EPOCH", 8], + ["C_Hatchback_01_EPOCH", 10], + ["C_Hatchback_02_EPOCH", 10], + ["C_SUV_01_EPOCH", 10], + ["C_Rubberboat_EPOCH", 5], + ["C_Rubberboat_02_EPOCH", 5], + ["C_Rubberboat_03_EPOCH", 5], + ["C_Rubberboat_04_EPOCH", 5], + ["C_Van_01_box_EPOCH", 8], + ["C_Van_01_transport_EPOCH", 9], + ["C_Boat_Civil_01_EPOCH", 5], + ["C_Boat_Civil_01_police_EPOCH", 5], + ["C_Boat_Civil_01_rescue_EPOCH", 5], + ["B_Heli_Light_01_EPOCH", 2], + ["B_SDV_01_EPOCH", 2], + ["B_MRAP_01_EPOCH", 3], + ["B_Truck_01_transport_EPOCH", 1], + ["B_Truck_01_covered_EPOCH", 2], + ["B_Truck_01_mover_EPOCH", 1], + ["B_Truck_01_box_EPOCH", 1], + ["O_Truck_02_covered_EPOCH", 2], + ["O_Truck_02_transport_EPOCH", 1], + ["O_Truck_03_covered_EPOCH", 1], + ["O_Truck_02_box_EPOCH", 1], + ["I_Heli_light_03_unarmed_EPOCH", 1], + ["O_Heli_Light_02_unarmed_EPOCH", 1], + ["I_Heli_Transport_02_EPOCH", 1], + ["O_Heli_Transport_04_EPOCH", 1], + ["O_Heli_Transport_04_bench_EPOCH", 1], + ["O_Heli_Transport_04_box_EPOCH", 1], + ["O_Heli_Transport_04_covered_EPOCH", 1], + ["B_Heli_Transport_03_unarmed_EPOCH", 1], + ["jetski_epoch", 7], + ["K01", 2], + ["K02", 2], + ["K03", 2], + ["K04", 2], + ["ebike_epoch", 7], + ["mosquito_epoch", 5], + ["C_Heli_Light_01_civil_EPOCH",5] +]; + + + +_allowedVehiclesList = []; +{ + _vehClass = _x select 0; + _velimit = _x select 1; + _vehicleCount = {typeOf _x == _vehClass} count vehicles; + for "_i" from 1 to (_velimit-_vehicleCount) do { + _allowedVehiclesList pushBack _vehClass; + }; +} forEach EPOCH_allowedVehiclesList; + + + + + + + +_spawnPositionSize = [ + ["FlatAreaCity",1], + ["FlatAreaCitySmall",1], + ["NameCity",2], + ["NameVillage",1], + ["NameCityCapital",4], + ["Airport",5] +]; +if (worldName in ["Bornholm","Australia"]) then { + _spawnPositionSize append [ + ["NameLocal",2], + ["StrongpointArea",1], + ["VegetationBroadleaf",1], + ["VegetationFir",1], + ["ViewPoint",1] + ]; +}; + + +_allowedTypes = []; +{ + _allowedTypes pushBack (_x select 0) +}forEach _spawnPositionSize; + + + + + + +_allCitys = "getText(_x >> 'type') in _allowedTypes" configClasses (configfile >> "CfgWorlds" >> worldName >> "Names"); +_allCitysDync = []; + +{ + _cityPos = getArray(_x >> "position"); + _range = getNumber(_x >> "radiusA") * 1.3; + _nearBy = count(_cityPos nearEntities[["LandVehicle", "Ship", "Air", "Tank"], _range]); + _find = _allowedTypes find (getText(_x >> "type")); + if (_find > -1) then{ + _limit = _spawnPositionSize select _find select 1; + if (_limit > _nearBy) then{ + _allCitysDync pushBack _x; + }; + }; +} forEach _allCitys; + + + +_position = [0,0,0]; + + +{ + if (count EPOCH_VehicleSlots <= EPOCH_storedVehicleCount) exitWith{}; + + _vehClass = _allowedVehiclesList deleteAt (floor(random(count _allowedVehiclesList))); + + _direction = random 360; + _position = [0,0,0]; + _getRandomPos = true; + + + _preferedPos = getArray(configFile >> "CfgEpoch" >> worldname >> "whitelistedVehiclePos" >> _vehClass); + if !(_preferedPos isEqualTo []) then{ + _newPosition = _preferedPos select(floor(random(count _preferedPos))); + if ((nearestObjects[(_newPosition select 0), ["LandVehicle", "Ship", "Air", "Tank"], 50]) isEqualTo []) then{ + _position = _newPosition select 0; + _direction = _newPosition select 1; + _getRandomPos = false; + }; + }; + + + if (_getRandomPos) then{ + _isShip = _vehClass isKindOf "Ship"; + if (_isShip || (_vehClass isKindOf "Air")) then{ + if (_isShip) then{ + _position = [epoch_centerMarkerPosition, 0, EPOCH_dynamicVehicleArea, 10, 0, 4000, 1] call BIS_fnc_findSafePos; + _position = [_position, 0, 100, 10, 2, 4000, 0] call BIS_fnc_findSafePos; + } else { + _position = [epoch_centerMarkerPosition, 0, EPOCH_dynamicVehicleArea, 10, 0, 1000, 0] call BIS_fnc_findSafePos; + }; + } else { + + if (_allCitysDync isEqualTo []) then { + _position = [epoch_centerMarkerPosition, 0, EPOCH_dynamicVehicleArea, 10, 0, 1000, 0] call BIS_fnc_findSafePos; + } else { + + _selectedCity = _allCitysDync deleteAt (floor random(count _allCitysDync)); + _cityPos = getArray(_selectedCity >> "position"); + _range = getNumber(_selectedCity >> "radiusA") * 1.3; + + _roads = _cityPos nearRoads _range; + _road = _roads select(floor random(count _roads)); + + _position = getPosATL _road; + _position deleteAt 2; + }; + }; + }; + + if ((count _position == 2 && _getRandomPos) || !_getRandomPos) then{ + + + _collide = "CAN_COLLIDE"; + if (_getRandomPos) then{ + _collide = "NONE"; + _position set[2, 0]; + if (surfaceIsWater _position) then{ + _position = ASLToATL _position; + }; + }; + + _vehObj = [_vehClass,_position,_direction,true,_x,"",_collide,true] call EPOCH_fnc_spawn_vehicle; + + + _marker = createMarker [str(_position) , _position]; + _marker setMarkerShape "ICON"; + _marker setMarkerType "mil_dot"; + _marker setMarkerText format ["%1",_vehClass]; + _marker setMarkerColor "ColorRed"; + + + EPOCH_VehicleSlots set[_forEachIndex, "REM"]; + }; + +} forEach EPOCH_VehicleSlots; + +EPOCH_VehicleSlots = EPOCH_VehicleSlots - ["REM"]; + +EPOCH_VehicleSlotCount = count EPOCH_VehicleSlots; +publicVariable "EPOCH_VehicleSlotCount"; + +EPOCH_allowedVehiclesList = nil; +true diff --git a/Sources/epoch_server/config.cpp b/Sources/epoch_server/config.cpp new file mode 100644 index 00000000..60ebbf2b --- /dev/null +++ b/Sources/epoch_server/config.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +Copyright (C) 2015 - ARMA 3 EPOCH MOD [EpochMod.com] (v0.3.0.1) +*****************************************************************************/ + +#define _ARMA_ + +class CfgPatches { + class A3_epoch_server { + units[] = {}; + weapons[] = {}; + requiredVersion = 0.1; + requiredAddons[] = {"A3_epoch_server_core","A3_epoch_config","A3_server_settings"}; + }; +}; +class cfgFunctions +{ + class A3E + { + tag = "EPOCH"; + class Epoch_Server + { + file = "\x\addons\a3_epoch_server\init"; + class init + { + preInit = 1; + }; + class postinit + { + postInit = 1; + }; + }; + class vehicles { + class spawn_vehicle { + file = "\x\addons\a3_epoch_server\compile\epoch_vehicle\EPOCH_spawn_vehicle.sqf"; + }; + }; + class bases { + class saveBuilding { + file = "\x\addons\a3_epoch_server\compile\epoch_bases\fn_saveBuilding.sqf"; + }; + }; + }; + +}; +class CfgServerVersion +{ + client = "0.3.3.1"; + config = "0.3.3.1"; + hive = "0.5.1.7"; +}; diff --git a/Sources/epoch_server/init/fn_init.sqf b/Sources/epoch_server/init/fn_init.sqf new file mode 100644 index 00000000..0cb0cc71 --- /dev/null +++ b/Sources/epoch_server/init/fn_init.sqf @@ -0,0 +1,8 @@ + +if !(isNil "Epoch_SStart1") exitWith { false }; +Epoch_SStart1 = true; + +diag_log "Epoch: Init Compiles"; +call compile preprocessFileLineNumbers "\x\addons\a3_epoch_server\init\server_compiles.sqf"; + +true diff --git a/Sources/epoch_server/init/fn_postinit.sqf b/Sources/epoch_server/init/fn_postinit.sqf new file mode 100644 index 00000000..10bb51f0 --- /dev/null +++ b/Sources/epoch_server/init/fn_postinit.sqf @@ -0,0 +1,9 @@ +if (isNil "Epoch_SStart") then { + Epoch_SStart = true; + [] spawn { + call compile preprocessFileLineNumbers "\x\addons\a3_epoch_code\init\both_init.sqf"; + call compile preprocessFileLineNumbers "\x\addons\a3_epoch_server\init\server_init.sqf"; + }; +}; + +true \ No newline at end of file diff --git a/Sources/epoch_server/init/server_compiles.sqf b/Sources/epoch_server/init/server_compiles.sqf new file mode 100644 index 00000000..e4abeb2e --- /dev/null +++ b/Sources/epoch_server/init/server_compiles.sqf @@ -0,0 +1,116 @@ +EPOCH_server_publicEH = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\init\server_publicEH.sqf"; +EPOCH_server_triggerEvent = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_antagonists\EPOCH_server_triggerEvent.sqf"; +EPOCH_server_upgradeGroup = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_group\EPOCH_server_upgradeGroup.sqf"; +EPOCH_server_updatePlayerGroup = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_group\EPOCH_server_updatePlayerGroup.sqf"; +EPOCH_server_createGroup = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_group\EPOCH_server_createGroup.sqf"; +EPOCH_server_deleteGroup = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_group\EPOCH_server_deleteGroup.sqf"; +EPOCH_server_invitePlayer = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_group\EPOCH_server_invitePlayer.sqf"; +EPOCH_server_loadBuildings = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_bases\EPOCH_server_loadBuildings.sqf"; +EPOCH_server_saveBuilding = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_bases\EPOCH_server_saveBuilding.sqf"; +// EPOCH_server_saveBuildingDamage = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_bases\EPOCH_server_saveBuildingDamage.sqf"; +EPOCH_server_upgradeBUILD = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_bases\EPOCH_server_upgradeBUILD.sqf"; +EPOCH_server_removeBUILD = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_bases\EPOCH_server_removeBUILD.sqf"; +EPOCH_server_paintBUILD = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_bases\EPOCH_server_paintBUILD.sqf"; +EPOCH_server_maintBUILD = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_bases\EPOCH_server_maintBUILD.sqf"; +EPOCH_server_simulSwap = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_bases\EPOCH_server_simulSwap.sqf"; +EPOCH_server_simToStatic = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_bases\EPOCH_server_simToStatic.sqf"; +EPOCH_server_unsuppported = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_bases\EPOCH_server_unsuppported.sqf"; +EPOCH_server_handle_say3D = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_antagonists\EPOCH_server_handle_say3D.sqf"; +EPOCH_server_handle_switchMove = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_antagonists\EPOCH_server_handle_switchMove.sqf"; +EPOCH_server_lootContainer = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_looting\EPOCH_server_lootContainer.sqf"; +EPOCH_server_spawnBoatLoot = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_looting\EPOCH_server_spawnBoatLoot.sqf"; +EPOCH_server_destroyTrash = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_looting\EPOCH_server_destroyTrash.sqf"; +EPOCH_server_knockDownTree = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_looting\EPOCH_server_knockDownTree.sqf"; +EPOCH_server_mineRocks = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_looting\EPOCH_server_mineRocks.sqf"; +EPOCH_server_lootAnimal = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_looting\EPOCH_server_lootAnimal.sqf"; +EPOCH_server_savePlayer = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_player\EPOCH_server_savePlayer.sqf"; +EPOCH_server_loadPlayer = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_player\EPOCH_server_loadPlayer.sqf"; +EPOCH_server_checkPlayer = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_player\EPOCH_server_checkPlayer.sqf"; +EPOCH_server_respawnPlayer = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_player\EPOCH_server_respawnPlayer.sqf"; +EPOCH_server_onPlayerDisconnect = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_player\EPOCH_server_onPlayerDisconnect.sqf"; +EPOCH_server_deadPlayer = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_player\EPOCH_server_deadPlayer.sqf"; +EPOCH_server_revivePlayer = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_player\EPOCH_server_revivePlayer.sqf"; +EPOCH_server_storeCrypto = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_player\EPOCH_server_storeCrypto.sqf"; +EPOCH_server_equippedItem = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_player\EPOCH_server_equippedItem.sqf"; +EPOCH_server_loadTraders = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_traders\EPOCH_server_loadTraders.sqf"; +EPOCH_server_spawnTraders = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_traders\EPOCH_server_spawnTraders.sqf"; +EPOCH_server_makeTrade = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_trading\EPOCH_server_makeTrade.sqf"; +EPOCH_server_tradeRequest = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_trading\EPOCH_server_tradeRequest.sqf"; +EPOCH_server_makeNPCTrade = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_trading\EPOCH_server_makeNPCTrade.sqf"; +EPOCH_server_takeCrypto = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_trading\EPOCH_server_takeCrypto.sqf"; +EPOCH_server_save_vehicles = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_vehicle\EPOCH_save_vehicles.sqf"; +EPOCH_server_save_vehicle = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_vehicle\EPOCH_save_vehicle.sqf"; +EPOCH_server_save_killedVehicle = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_vehicle\EPOCH_save_killedVehicle.sqf"; +EPOCH_server_save_killedStorage = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_vehicle\EPOCH_save_killedStorage.sqf"; +EPOCH_server_save_killedBuilding = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_vehicle\EPOCH_save_killedBuilding.sqf"; +EPOCH_load_vehicles = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_vehicle\EPOCH_load_vehicles.sqf"; +EPOCH_load_storage = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_vehicle\EPOCH_load_storage.sqf"; +EPOCH_server_save_storage = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_vehicle\EPOCH_save_storage.sqf"; +EPOCH_spawn_vehicles = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_vehicle\EPOCH_spawn_vehicles.sqf"; +EPOCH_server_lockVehicle = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_vehicle\EPOCH_server_lockVehicle.sqf"; +EPOCH_server_fillVehicle = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_vehicle\EPOCH_server_fillVehicle.sqf"; +EPOCH_server_repairVehicle = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_vehicle\EPOCH_server_repairVehicle.sqf"; +EPOCH_server_lockStorage = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_vehicle\EPOCH_server_lockStorage.sqf"; +EPOCH_server_packStorage = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_vehicle\EPOCH_server_packStorage.sqf"; +EPOCH_server_packJack = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_vehicle\EPOCH_server_packJack.sqf"; +EPOCH_serverLootObject = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_server\EPOCH_serverLootObject.sqf"; +EPOCH_server_vehicleInit = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_server\EPOCH_server_vehicleInit.sqf"; +EPOCH_server_storageInit = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_server\EPOCH_server_storageInit.sqf"; +EPOCH_server_buildingInit = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_server\EPOCH_server_buildingInit.sqf"; +EPOCH_server_traderKilled = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_server\EPOCH_server_traderKilled.sqf"; +EPOCH_server_setWeather = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_server\EPOCH_server_setWeather.sqf"; +EPOCH_localCleanup = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_server\EPOCH_localCleanup.sqf"; +EPOCH_server_createTeleport = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_server\EPOCH_server_createTeleport.sqf"; +EPOCH_server_teleportPlayer = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_server\EPOCH_server_teleportPlayer.sqf"; +EPOCH_Server_createObject = compile preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_missions\EPOCH_Server_createObject.sqf"; +EPOCH_server_airDropCrate = compile preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_missions\EPOCH_server_airDropCrate.sqf"; +EPOCH_server_fillContainer = compile preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_missions\EPOCH_Server_fillContainer.sqf"; +EPOCH_server_handle_sapperObjs = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_antagonists\EPOCH_server_handle_sapperObjs.sqf"; +EPOCH_Server_createAirDrop = compileFinal preprocessFileLineNumbers "\x\addons\a3_epoch_server\compile\epoch_missions\EPOCH_Server_createAirDrop.sqf"; + +EPOCH_weightedArray = compileFinal ' + private["_return","_lootTableArray","_weightedArray","_keyName","_configName","_arrayName"]; + _keyName = _this select 0; + _configName = _this select 1; + _arrayName = _this select 2; + _return = missionNamespace getVariable[format["EPOCH_LT_%1_%2_%3",_configName,_keyName,_arrayName],[]]; + if(_return isEqualTo[]) then { + _lootTableArray = []; + _weightedArray = []; + { + if(typeName _x == "ARRAY") then { + _lootTableArray pushBack(_x select 0); + for "_i" from 1 to(_x select 1) do { + _weightedArray pushBack _forEachIndex; + }; + } else { + _lootTableArray pushBack _x; + _weightedArray pushBack _forEachIndex; + }; + }forEach getArray(configFile >> _configName >> _keyName >> _arrayName); + _return = [_lootTableArray,_weightedArray,count _weightedArray]; + missionNamespace setVariable[format["EPOCH_LT_%1_%2_%3",_configName,_keyName,_arrayName],_return]; + }; + _return +'; + +EPOCH_returnConfig = compileFinal ' +private["_return", "_config"]; +_return = (configfile >> _this); +_config = (missionConfigFile >> _this); +if (isClass _config) then{ + _return = _config; +}; +_return +'; + +EPOCH_precisionPos = compileFinal ' + private["_low", "_high"]; + _low = [ + (_this select 0) - ((_this select 0) % 1), + (_this select 1) - ((_this select 1) % 1), + (_this select 2) - ((_this select 2) % 1) + ]; + _high = _this vectorDiff _low; + [_low, _high] +'; \ No newline at end of file diff --git a/Sources/epoch_server/init/server_init.sqf b/Sources/epoch_server/init/server_init.sqf new file mode 100644 index 00000000..437c910f --- /dev/null +++ b/Sources/epoch_server/init/server_init.sqf @@ -0,0 +1,200 @@ +_startTime = diag_tickTime; +Epoch_ServerVersion = getText(configFile >> "CfgMods" >> "Epoch" >> "version"); +EPOCH_SERVER = []; +diag_log format["Epoch: Starting ArmA3 Epoch Server, Version %1",Epoch_ServerVersion]; + +_abortAndError = { + publicVariable "EPOCH_SERVER"; + EPOCH_BADHIVE = true; //Kick all player + publicVariable "EPOCH_BADHIVE"; + for "_i" from 0 to 15 do { + diag_log _this; + }; +}; + +_clientVersion = getText(configFile >> "CfgServerVersion" >> "client"); +_configVersion = getText(configFile >> "CfgServerVersion" >> "config"); +_hiveVersion = getText(configFile >> "CfgServerVersion" >> "hive"); + +if (_clientVersion != Epoch_ServerVersion) exitWith{ + format["Epoch: Version mismatch! Current: %2 Needed: %1", _clientVersion, Epoch_ServerVersion] call _abortAndError; +}; +if (_configVersion != getText(configFile >> "CfgPatches" >> "A3_server_settings" >> "epochVersion")) exitWith { + format["Epoch: Config file needs updated! Current: %1 Needed: %2", _configVersion, getText(configFile >> "CfgPatches" >> "A3_server_settings" >> "epochVersion")] call _abortAndError; +}; + + +if (isClass(missionConfigFile >> "CfgEpochClient") && _configVersion != getText(missionConfigFile >> "CfgEpochClient" >> "epochVersion")) exitWith{ + format["Epoch: Mission Config file needs updated! Current: %1 Needed: %2", _configVersion, getText(missionConfigFile >> "CfgEpochClient" >> "epochVersion")] call _abortAndError; +}; + +if (("epochserver" callExtension "") != _hiveVersion) exitWith { + format["Epoch: Server DLL mismatch! Current: %1 Needed: %2", "epochserver" callExtension "",_hiveVersion] call _abortAndError; +}; + +_serverConfig = call compile ("epochserver" callExtension "000"); +EPOCH_fn_InstanceID = compileFinal (str (_serverConfig select 0)); +_instanceID = call EPOCH_fn_InstanceID; +if (isNil "_instanceID") exitWith{ + "Epoch: InstanceID missing!" call _abortAndError; +}; + +diag_log "Epoch: Init Variables"; +call compile preprocessFileLineNumbers "\x\addons\a3_epoch_server\init\server_variables.sqf"; +call compile preprocessFileLineNumbers "\x\addons\a3_epoch_server\init\server_securityfunctions.sqf"; + +["I", _instanceID, "86400", ["CONTINUE"]] call EPOCH_fnc_server_hiveSETEX; +diag_log format["Epoch: Start Hive, Instance ID: '%1'", _instanceID]; + +call EPOCH_server_publicEH; +diag_log "Epoch: Init PublicEH"; + +// Connect/Disconnect +addMissionEventHandler ["HandleDisconnect", { _this call EPOCH_server_onPlayerDisconnect }]; +onPlayerDisconnected{ + diag_log format["playerDisconnected:%1:%2", _uid, _name]; + ['Disconnected', [_uid, _name]] call EPOCH_fnc_server_hiveLog; + _uid call EPOCH_server_disconnect; +}; +onPlayerConnected{ + "epochserver" callExtension format["001|%1", _uid]; + diag_log format["playerConnected:%1:%2", _uid, _name]; + ['Connected', [_uid, _name]] call EPOCH_fnc_server_hiveLog; + ["PlayerData", _uid, EPOCH_expiresPlayer, [_name]] call EPOCH_fnc_server_hiveSETEX; +}; + +diag_log "Epoch: Setup Side Settings"; +//set side status +_SideHQ1 = createCenter resistance; +_SideHQ2 = createCenter east; +_SideHQ3 = createCenter west; +RESISTANCE setFriend [WEST, 0]; +WEST setFriend [RESISTANCE, 0]; +RESISTANCE setFriend [EAST, 0]; +EAST setFriend [RESISTANCE, 0]; +// friendly +EAST setFriend[WEST, 1]; +WEST setFriend[EAST, 1]; + +diag_log format["Epoch: Setup World Settings for %1",worldName]; +//World Settings +_worldSize = worldSize; +_epochWorldPath = configfile >> "CfgEpoch" >> worldName; +if (isClass _epochWorldPath) then { + _configSize = getNumber(_epochWorldPath >> "worldSize"); + if (_configSize > 0) then { + _worldSize = _configSize; + }; +}; +epoch_centerMarkerPosition = getMarkerPos "center"; +if (epoch_centerMarkerPosition isEqualTo [0,0,0]) then { + diag_log "Epoch: Error cannot find center marker!"; +}; +EPOCH_dynamicVehicleArea = _worldSize / 2; + +diag_log "Epoch: Set Weather"; +true call EPOCH_server_setWeather; + +// custom radio channels +EPOCH_customChannels = []; +for "_i" from 0 to 9 do { + _radio = configfile >> "CfgWeapons" >> format["EpochRadio%1", _i]; + _channelTXT = getText(_radio >> "displayName"); + // _channelNumber = getNumber(_radio >> "channelID"); + _channelColor = getArray(_radio >> "channelColor"); + _index = radioChannelCreate[_channelColor, _channelTXT, "%UNIT_NAME", []]; + EPOCH_customChannels pushBack _index; +}; +//Execute Server Functions +_startTime spawn { + + diag_log "Epoch: Loading buildings"; + _workload1 = EPOCH_BuildingSlotsLimit call EPOCH_server_loadBuildings; + + + // Underground and teleports + diag_log "Epoch: Loading teleports and static props"; + _workload8 = [] call EPOCH_server_createTeleport; + + + // Traders + diag_log "Epoch: Loading NPC traders"; + _workload4 = EPOCH_NPCSlotsLimit call EPOCH_server_loadTraders; + + + diag_log "Epoch: Spawning NPC traders"; + _workload5 = [] call EPOCH_server_spawnTraders; + + + // Vehicles + diag_log "Epoch: Loading vehicles"; + _workload2 = EPOCH_VehicleSlotsLimit call EPOCH_load_vehicles; + + + diag_log "Epoch: Spawning vehicles"; + _workload3 = [] call EPOCH_spawn_vehicles; + + + // Storage + diag_log "Epoch: Loading storage"; + _workload6 = EPOCH_StorageSlotsLimit call EPOCH_load_storage; + + + // Loot + diag_log "Epoch: Loading static loot"; + _workload9 = [] call EPOCH_server_spawnBoatLoot; + + + [] execFSM "\x\addons\a3_epoch_server\system\server_monitor.fsm"; + + _serverSettingsConfig = configFile >> "CfgEpochServer"; + + // Setting Server Date and Time + _dateChanged = false; + _date = date; + + _staticDateTime = [_serverSettingsConfig, "StaticDateTime", []] call EPOCH_fnc_returnConfigEntry; + _timeDifference = [_serverSettingsConfig, "timeDifference", 0] call EPOCH_fnc_returnConfigEntry; + + if (_staticDateTime isEqualto []) then { + _response = "epochserver" callExtension "510"; + if (_response != "") then { + diag_log format ["Epoch: Set Real Time: %1", _response]; + _date = call compile _response; + _date resize 5; + _date set[0, (_date select 0) + 21]; + _date set[3, (_date select 3) + _timeDifference]; + _dateChanged = true; + }; + } else { + { + if (_x != 0) then { + _date set [_forEachIndex, _x]; + _dateChanged = true; + }; + }forEach _staticDateTime; + }; + if (_dateChanged) then { + setDate _date; + }; + + // set time multiplier + setTimeMultiplier ([_serverSettingsConfig, "timeMultiplier", 1] call EPOCH_fnc_returnConfigEntry); + + // globalize tax rate + EPOCH_taxRate = [_serverSettingsConfig, "taxRate", 0.1] call EPOCH_fnc_returnConfigEntry; + publicVariable "EPOCH_taxRate"; + + if !(EPOCH_SERVER isEqualTo []) then { + publicVariable "EPOCH_SERVER"; + }; + publicVariable "Epoch_ServerVersion"; + + diag_log format ["Epoch: Server Start Complete: %1 seconds",diag_tickTime-_this]; + + if (_dateChanged) then { + uiSleep 60; + _date set [4, (_date select 4) + 1]; //add 1 min to be 100% correct + setDate _date; + }; +}; diff --git a/Sources/epoch_server/init/server_publicEH.sqf b/Sources/epoch_server/init/server_publicEH.sqf new file mode 100644 index 00000000..3fd3a30e --- /dev/null +++ b/Sources/epoch_server/init/server_publicEH.sqf @@ -0,0 +1,44 @@ +"EPOCH_SAVEBUILD" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_saveBuilding}; +"EPOCH_UPBUILD" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_upgradeBUILD}; +"EPOCH_REMBUILD" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_removeBUILD}; +"EPOCH_PAINTBUILD" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_paintBUILD}; +"EPOCH_MAINTBUILD" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_maintBUILD}; +"EPOCH_selectedGender_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_loadPlayer}; +"EPOCH_checkPlayer_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_checkPlayer}; +"EPOCH_respawnPlayer_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_respawnPlayer}; +// "EPOCH_S_S_VEHICLES" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_save_vehicles}; +"EPOCH_pushPlayer_PVS" addPublicVariableEventHandler{if([_this select 1 select 0,_this select 1 select 2]call EPOCH_server_getPToken)then{(_this select 1)call EPOCH_server_savePlayer}}; +"EPOCH_deadPlayer_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_deadPlayer}; +"EPOCH_destroyTrash" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_destroyTrash}; +"EPOCH_knockDownTree" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_knockDownTree}; +"EPOCH_mineRocks_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_mineRocks}; +"EPOCH_lootAnimal" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_lootAnimal}; +"EPOCH_say3D_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_handle_say3D}; +"EPOCH_switchMove_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_handle_switchMove}; +"EPOCH_GROUP_Upgrade_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_upgradeGroup}; +"EPOCH_GROUP_Player_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_updatePlayerGroup}; +"EPOCH_GROUP_create_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_createGroup}; +"EPOCH_GROUP_Delete_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_deleteGroup}; +"EPOCH_GROUP_Invite_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_invitePlayer}; +"EPOCH_lootContainer" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_lootContainer}; +"EPOCH_revivePlayer_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_revivePlayer}; +"EPOCH_storeCrypto_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_storeCrypto}; +"EPOCH_MAKETRADEREQ" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_tradeRequest}; +"EPOCH_MAKETRADE" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_makeTrade}; +"EPOCH_MAKENPCTRADE" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_makeNPCTrade}; +"EPOCH_takeCrypto_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_takeCrypto}; +"EPOCH_repairVehicle_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_repairVehicle}; +"EPOCH_fillVehicle_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_fillVehicle}; +"EPOCH_lockVehicle_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_lockVehicle}; +"EPOCH_equippedItem_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_equippedItem}; +"EPOCH_lockStorage_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_lockStorage}; +"EPOCH_packStorage_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_packStorage}; +"EPOCH_packJack_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_packJack}; +"EPOCH_TEMPOBJ_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_localCleanup}; +"EPOCH_oneWayTP" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_teleportPlayer}; +"EPOCH_FillContainer_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_fillContainer}; +"EPOCH_SapperObjs_PVS" addPublicVariableEventHandler{(_this select 1)call EPOCH_server_handle_sapperObjs}; +"EPOCH_createAirDrop_PVS" addPublicVariableEventHandler{ (_this select 1)call EPOCH_Server_createAirDrop }; +"EPOCH_airDropCrate_PVS" addPublicVariableEventHandler{ (_this select 1)call EPOCH_server_airDropCrate }; + + diff --git a/Sources/epoch_server/init/server_securityfunctions.sqf b/Sources/epoch_server/init/server_securityfunctions.sqf new file mode 100644 index 00000000..c5c328ad --- /dev/null +++ b/Sources/epoch_server/init/server_securityfunctions.sqf @@ -0,0 +1,2346 @@ +comment 'Epoch Mod Antihack - Niklas Wagner - www.skaronator.com - Aaron Clark - www.epochmod.com - License: (CC) Attribution-NonCommercial-NoDerivatives 4.0 International'; + +/* ANTIHACK SETTINGS */ + +_config = (configFile >> "CfgSecConf"); +if (isClass _config) then {diag_log "Loading config..."}; + +_debugClass = if ([_config,"debug",false] call EPOCH_fnc_returnConfigEntry) then { "DebugActive" } else { "DebugDisabled" }; + +_cfg_systemDebug = (_config >> _debugClass); +_skn_systemDebug1 = getText(_cfg_systemDebug >> "systemChat1"); +_skn_systemDebug2 = getText(_cfg_systemDebug >> "systemChat2"); +_skn_systemDebug3 = getText(_cfg_systemDebug >> "systemChat3"); +_skn_systemDebug4 = getText(_cfg_systemDebug >> "systemChat4"); +_skn_systemDebug5 = getText(_cfg_systemDebug >> "systemChat5"); + +_cfg_limits = (_config >> "limits"); +_skn_playerCryptoLimit = [_cfg_limits, "playerCrypto", 25000] call EPOCH_fnc_returnConfigEntry; + +_cfg_learning = (_config >> "learning"); +_skn_trustedUsers = [_cfg_learning,"trustedUsers",[]] call EPOCH_fnc_returnConfigEntry; +_str_learningModeCheck = if ([_cfg_learning,"mode",true] call EPOCH_fnc_returnConfigEntry) then{"((getPlayerUID _player) in "+str _skn_trustedUsers+")"} else {"true"}; + +_cfg_quality = (_config >> "forcedQuality"); +_skn_perfMode = getText(_cfg_quality >> "mode"); +_skn_viewDistance = [_cfg_quality >> _skn_perfMode, "viewDistance", 2500] call EPOCH_fnc_returnConfigEntry; +_skn_viewDistanceObects = [_cfg_quality >> _skn_perfMode, "viewDistanceObects", 2000] call EPOCH_fnc_returnConfigEntry; +_skn_terrainGrid = [_cfg_quality >> _skn_perfMode, "terrainGrid", 10] call EPOCH_fnc_returnConfigEntry; + +_cfg_blacklistConfig = (_config >> "blacklist"); +_skn_badDisplaysArray = [_cfg_blacklistConfig, "badDisplays", [-1337,17,19,30,32,45,59,69,71,125,132,155,156,157,162,165,166,167,312,1320,1321,2727,2928,2929,316000]] call EPOCH_fnc_returnConfigEntry; +_skn_badAnimations = [_cfg_blacklistConfig, "animations", ['AmovPercMstpSnonWnonDnon_exerciseKata','AmovPercMstpSnonWnonDnon_exercisePushup','GestureSpasm1','GestureSpasm4','GestureNod']] call EPOCH_fnc_returnConfigEntry; + +_cfg_variablesConfig = (_config >> "variables"); +_skn_badVarCheckArray = [_cfg_variablesConfig, "badVars", ['ESP_map','ESP_mainMap','ESP_adminMap','AntiAntiAntiAntiHax','fnc_usec_damageHandler','fnc_usec_unconscious','VAGINA_secret','yolo','VERSION','life_fnc_handleDamage','EPOCH_spawnVehicle_PVS','CLASS911_Menu','nuke_vars','JJMMEE_INIT_MENU','PLAYERON','PLAYERNEXT2','ALTISLIFEON','LY_Menu','PLAY','LY_SwaggerLikeUs','BIS_fnc_dbg_reminder_value','BIS_fnc_dbg_reminder']] call EPOCH_fnc_returnConfigEntry; +_skn_nilVarCheckArray = [_cfg_variablesConfig, "nilVars", ['EPOCH_antiWallCount','EPOCH_playerEnergy','EPOCH_playerHunger','EPOCH_playerStamina','EPOCH_playerCrypto','EPOCH_target','EPOCH_ESP_TARGETS','EPOCH_ESPMAP_TARGETS','EPOCH_taxRate','EPOCH_ESP_VEHICLEPLAYER','EPOCH_ESP_PLAYER','EPOCH_ESP_VEHICLES']] call EPOCH_fnc_returnConfigEntry; +_skn_commandMenuArray = [(_config >> "commandMenu"), "menus",['','RscSelectTeam','RscTeam','RscMoveHigh','#GETIN','#RscStatus','#WATCH0','RscCombatMode','RscMenuReply','RscCallSupport','#CUSTOM_RADIO','#User:BIS_fnc_addCommMenuItem_menu','RscRadio','RscReply','#ACTION','RscMenuFormations','#WATCH','RscGroupRootMenu','RscMainMenu','RscMenuMove','RscWatchDir','RscWatchMoveDir','#User:BIS_Menu_GroupCommunication','RscMenuStatus','RscFormations']] call EPOCH_fnc_returnConfigEntry; + +_skn_displayAddEHKeyDown = [(_config >> "displayAddEventHandler"), "keyDown",'_this call EPOCH_KeyDown'] call EPOCH_fnc_returnConfigEntry; +_skn_displayAddEHKeyUp = [(_config >> "displayAddEventHandler"), "keyUp",''] call EPOCH_fnc_returnConfigEntry; + +_skn_addEHConfig = (_config >> "addEventHandler"); +_skn_displayAddEHChecks = [_skn_addEHConfig, "checks",[]] call EPOCH_fnc_returnConfigEntry; + +_skn_addEHArray = []; +{ + _code = [_skn_addEHConfig, _x,""] call EPOCH_fnc_returnConfigEntry; + _skn_addEHArray pushBack [_x,_code,(_code != "")]; +} forEach _skn_displayAddEHChecks; + + +_serverSettingsConfig = configFile >> "CfgEpochServer"; +_skn_enableAntihack = [_serverSettingsConfig, "antihack_Enabled", true] call EPOCH_fnc_returnConfigEntry; +_skn_check_addons = [_serverSettingsConfig, "antihack_cfgPatchesCheck", true] call EPOCH_fnc_returnConfigEntry; +_checkFiles = [ + ["\x\addons\a3_epoch_code\compile\setup\EPOCH_clientInit.sqf", "EPOCH_clientInit"], + ["\x\addons\a3_epoch_code\compile\EPOCH_onEachFrame.sqf", "EPOCH_onEachFrame"], + ["\x\addons\a3_epoch_code\compile\setup\EPOCH_masterLoop.sqf", "EPOCH_masterLoop"], + ["\x\addons\a3_epoch_code\compile\setup\EPOCH_client_rejectPlayer.sqf", "EPOCH_client_rejectPlayer"], + ["\x\addons\a3_epoch_code\compile\setup\EPOCH_clientRespawn.sqf", "EPOCH_clientRespawn"], + ["\x\addons\a3_epoch_code\compile\interface_event_handlers\EPOCH_KeyDown.sqf", "EPOCH_KeyDown"] +]; +_skn_check_files = [_serverSettingsConfig, "antihack_checkFiles", _checkFiles] call EPOCH_fnc_returnConfigEntry; +_whitelistPatches = ["A3_AIR_F_RTD","AiA_Worlds_Author","AiA_Worlds_Grid","AiA_BaseConfig_F","AiA_A1AlwaysDummy","CAVideo2_PMC","CA_AnimsHotfix","CA_CutSceneAnims","CAIntroAnims","CAUSMCD","CAVoice","CAweapons3_aks74pso","CAWeapons3_ammocrates","CAweapons3_ksvk","CAweapons3_m107","CAweapons3_m16a4_acg_gl","CAweapons3_m16a4_acg","CAweapons3_m16a4_gl","CAweapons3_m16a4","CAWeapons3","CTI_buildingsBmp2_hq","CTI_buildingsM113_hq","DSHkM_Mini","M2HD_Mini","MK19_Tripod","Warfare","WarfareBuildings_Stinger_Twice_static","WarfareBuildings_T72_RACS","WarfareBuildings_TOW_Tripod","AiA_cba_xeh_a2_Dummy","AiA_CBA_A2_xeh_Dummy","AiA_cba_xeh_oa_Dummy","AiA_CBA_OA_xeh_Dummy","AiA_CA_Data","AiA_A10_Data","AiA_Afghan_Data","AiA_Air2_Data","AiA_Air3_Data","AiA_Air_Data","AiA_Air_e_Data","AiA_Animations_Data","AiA_Animations_Config","AiA_Bohemia_Data","AiA_Bootcamp_acr_Data","AiA_Buildings2_Data","AiA_Buildings2_Ind_Cementworks_Data","AiA_Buildings_Data","AiA_Ca_acr_Data","AiA_CA_Config","CAData","AiA_CA_Config_Data_ParticleEffects","CAData_ParticleEffects","AiA_Ca_e_Data","AiA_Ca_pmc_Data","AiA_Characters2_Data","AiA_Chernarus_Data","AiA_Chernarus_Data_Data","AiA_Chernarus_Data_Layers_Data","AiA_Chernarus_Summer_Data","AiA_Cti_buildings_Data","AiA_CA_Data_Data_ParticleEffects","AiA_Data_baf_Data","AiA_Desert2_Data","Desert2_Objects","AiA_Desert_Data","AiA_Desert_e_Data","AiA_Hotfix_Data","AiA_Introanims_Data","CALanguage","AiA_Language_acr_Data","AiA_Language_baf_Data","AiA_Language_e_Data","AiA_Language_pmc_Data","CALanguage_missions","AiA_Languagemissions_acr_Data","AiA_Languagemissions_baf_Data","CALanguage_missions_e","AiA_Languagemissions_pmc_Data","AiA_Misc2_Data","AiA_Misc3_Data","AiA_Misc_Data","AiA_Misc_acr_Data","AiA_Misc_e_Data","AiA_Plants2_Bush_Data","AiA_Plants2_Clutter_Data","AiA_Plants2_Misc_Data","AiA_Plants2_Plant_Data","AiA_Plants2_Tree_Data","AiA_Plants_Data","AiA_Plants_Config","CAPlants","AiA_Plants_e2_Data","AiA_Plants_e_Data","AiA_Plants_pmc_Data","AiA_Provinggrounds_pmc_Data","AiA_Roads2_Data","AiA_Roads2_Config","CARoads2","CARoads2Bridge","CARoads2Dam","AiA_Roads_Data","AiA_Roads_Config","CARoads","AiA_Roads_e_Data","AiA_Roads_pmc_Data","AiA_Roads_pmc_Config","CARoads_PMC_Bridge","AiA_Rocks2_Data","AiA_Rocks2_Config","CARocks2","AiA_Rocks_Data","AiA_Rocks_Config","CARocks","AiA_Rocks_e_Data","AiA_Sara_Data","AiA_Saralite_Data","AiA_Shapur_baf_Data","AiA_Signs2_Data","AiA_Signs2_Config","CASigns2","AiA_Signs_Data","AiA_Signs_Config","CASigns","AiA_Signs_e_Data","AiA_Sounds_Data","AiA_Sounds_Config","CASounds","AiA_Sounds_e_Data","AiA_Structures_Data","pond_test","AiA_Structures_e_Data","AiA_Structures_pmc_Data","AiA_Takistan_Data","AiA_Takistan_Data_Data","AiA_Takistan_Data_Layers_Data","AiA_Tracked2_Data","AiA_Tracked_Data","AiA_Tracked_e_Data","AiA_Ui_Data","AiA_Utes_Data","AiA_Utes_Config","Utes","AiA_Water2_Data","CAWater2_LHD","AiA_Water_Data","AiA_Weapons2_Data","AiA_Weapons_Data","AiA_Weapons_e_Data","AiA_Weapons_pmc_Data","AiA_Wheeled2_Data","AiA_Wheeled_Data","AiA_Wheeled_e_Data","AiA_Zargabad_Data","AiA_Models_DBE1_Data","Music_DBE1","ploty_DBE1","Roads_DBE1","AiA_Sara_dbe1_Data","Disable_XEH_Logging","AiA_TKOH_Dummy","HSim_Data_H","HSim_Data_H_data_ParticleEffects","HSim_Data_H_data_ParticleEffects_rotor_blades","HSim_Dubbing_H","HSim_DubbingRadio_H","HSim_Editor_H","Intro_Island_H","HSim_Missions_H","HSim_ModulesCore_H","HSim_ModulesCore_H_AmbientCombat","HSim_ModulesCore_H_DynO","HSim_ModulesCore_H_Functions","HSim_ModulesCore_H_GarbageCollector","HSim_ModulesCore_H_Functions_E","HSim_ModulesCore_H_OO","HSim_ModulesCore_H_Functions_PMC","HSim_Music_H","HSim_Sounds_H","South_Asia_H","HSim_UIFonts_H","United_States_H","HSim_Animals_H","HSim_Animals_H_Anim_Config","HSim_Animals_H_Dog","HSim_Characters_H_Faces","HSim_Characters_H_Heads","HSim_Modules_H","HSim_UI_H","HSim_Weapons_H","HSim_Weapons_H_AK47","HSim_Weapons_H_DShKM","HSim_Weapons_H_Glock","HSim_Weapons_H_HandItems","HSim_Weapons_H_M16","HSim_Weapons_US_H","HSim_Characters_H","HSim_Characters_US_H","HSim_Missions_H_FreeFlight","HSim_Functions_Base_H","HSim_Water_H","HSim_Water_H_Civ_FishingBoat_Large","HSim_Water_H_Civ_Jetboat","HSim_Water_H_Civ_Yacht","HSim_Water_H_Container_Ship","HSim_Water_H_Cruise_Ship","HSim_Water_H_Destroyer","HSim_Water_H_Fishing_Boat","HSim_Water_H_Fregata","HSim_Water_H_LHD","HSim_Water_H_Oil_tanker","HSim_Water_H_Rubber_Boat","HSim_Water_H_Whales","HSim_Water_H_Whales_GreyWhale","HSim_Water_H_Whales_Whale1","HSim_Weapons_H_IGLA","HSim_Weapons_US_H_M2","HSim_Wheeled_H","HSim_Wheeled_H_Ambulance","HSim_Wheeled_H_FireTruck","HSim_Wheeled_H_Hatchback","HSim_Wheeled_H_Military_Offroad_LR","HSim_Wheeled_H_Military_Pickup_DSHKM","HSim_Wheeled_H_Offroad","HSim_Wheeled_H_Police_Car","HSim_Wheeled_H_TowingTractor","HSim_Wheeled_H_Tractor","HSim_Wheeled_H_Trailers","HSim_Wheeled_H_Truck_Light_Transport","HSim_Wheeled_H_Ural","HSim_Wheeled_H_Van_Passenger","HSim_Wheeled_US_H","HSim_Wheeled_US_H_Military_Offroad","HSim_Wheeled_US_H_Military_Truck","HSim_Wheeled_US_H_Pickup_01","HSim_Wheeled_US_H_Pickup_02","HSim_Wheeled_US_H_SUV","HSim_Wheeled_US_H_Truck_US_Type","HSim_Air_H","HSim_Air_H_Aircraft_A","HSim_Air_H_Aircraft_C","HSim_Air_H_Aircraft_D","HSim_Air_H_Aircraft_E_H","HSim_Air_H_Airliner_A","HSim_Air_H_Airliner_B","HSim_Air_H_Parachute","HSim_Air_US_H","HSim_Air_US_H_Helicopters_Heavy","HSim_Air_US_H_Helicopters_Light","HSim_Air_US_H_Helicopters_Medium","HSim_Misc_H","HSim_Misc_H_Antena","HSim_Misc_H_Barels","HSim_Misc_H_Bleacher","HSim_Misc_H_BoardsPack","HSim_Misc_H_CncBlock","HSim_Misc_H_Doghouse","HSim_Misc_H_Engine_Crane","HSim_Misc_H_Fence","HSim_Misc_H_Fire_Extinguisher","HSim_Misc_H_Fire_Suppression","HSim_Misc_H_First_Aid","HSim_Misc_H_Flagpole","HSim_Misc_H_Folding_Ladder","HSim_Misc_H_FuelCan","HSim_Misc_H_Heliport_Furniture","HSim_Misc_H_Helicopter_Parts","HSim_Misc_H_Helipads","HSim_Misc_H_Heliport_Objects","HSim_Misc_H_Helpers","HSim_Misc_H_Info_Board","HSim_Misc_H_Infostands","HSim_Misc_H_Inspection_Visuals","HSim_Misc_H_Interior","HSim_Misc_H_Loudspeakers","HSim_Misc_H_Market","HSim_Misc_H_Office_Objects","HSim_Misc_H_Perimeter_Ligh","HSim_Misc_H_Pike","HSim_Misc_H_Platform_Cart","HSim_Misc_H_Portable_Generator","HSim_Misc_H_Props","HSim_Misc_H_SawHorse","HSim_Misc_H_Shooting_Range","HSim_Misc_H_Signs","HSim_Misc_H_Sink","HSim_Misc_H_Targets","HSim_Misc_H_Tent","HSim_Misc_H_Toilet","HSim_Misc_H_Tools","HSim_Misc_H_Tools_Racking","HSim_Misc_H_Trash","HSim_Misc_H_Weather_Station","HSim_Misc_H_Weld_Gastank","HSim_Misc_H_Wheel_Chocks","HSim_Misc_H_Wheeled_Scaffolding","HSim_Misc_H_wheeled_tool_cart","HSim_Misc_H_Wheeled_Whiteboard","HSim_Misc_H_Winch","HSim_Misc_H_Windsock","HSim_Misc_H_Workbench","HSim_Misc_H_Wrecks","HSim_Structures_H","HSim_Structures_H_Airport_Papi","HSim_Structures_H_Harbour","HSim_Structures_H_Heliports_Heliport_Big","HSim_Structures_H_Heliports_Heliport_Small","HSim_Structures_H_Industrial_A_CraneCon","HSim_Structures_H_Industrial_Rooftop_Objects","HSim_Structures_US_H","HSim_Structures_US_H_Bld_US","HSim_Structures_US_H_Landmarks_Space_Needle","HSim_Tracked_H","HSim_Tracked_H_BMP2","HSim_Tracked_US_H","HSim_Tracked_US_H_M1A2","HSim_Tracked_US_H_MLRS","HSim_Data_H_EditorGroups","HSim_Anims_H","HSim_Anims_H_config_sdr","HSim_Anims_H_config_wmn","Hsim_Language_H","Hsim_Language_missions_H","AiA_StandaloneTerrainPack_Dummy","CA_ACR","CA_Animals2_Anim_Config","CA_Anims_Char","CA_Anims_E_Wmn","CA_E","CA_PMC","CAAir","CACharacters","CATracked","CAUI","CAWater","CAWater2","CAWater2_seafox","CAWeapons","CAWeapons_Warfare_weapons","CAWheeled","CAWheeled_E","CAWheeled2","6G30_DBE1","Arma2_Ka52","BI_SRRS","CA_AH64D","CA_AIR_E_MQ9PredatorB","CA_AIR_E_Su25","CA_AIR2_Su25","CA_Animals_E","CA_Animals2","CA_Animals2_Chicken","CA_Animals2_Cow","CA_Animals2_Dogs","CA_Animals2_Dogs_Fin","CA_Animals2_Dogs_Pastor","CA_Animals2_Goat","CA_Animals2_Rabbit","CA_Animals2_Sheep","CA_Animals2_WildBoar","CA_Anims","CA_Anims_E","CA_Anims_E_Sdr","CA_Anims_Sdr","CA_Anims_Wmn","CA_CommunityConfigurationProject_E","CA_CruiseMissile","CA_Dubbing","CA_Dubbing_Baf","CA_Dubbing_Counterattack","CA_Dubbing_E","CA_Dubbing_PMC","CA_DubbingRadio_E","CA_DubbingRadio_PMC","CA_E_ParticleEffects","CA_Editor","CA_HC_Sounds","CA_Heads","CA_HighCommand","CA_L39","CA_Missions","CA_Missions_AlternativeInjurySimulation","CA_Missions_AmbientCombat","CA_Missions_Armory1","CA_Missions_Armory2","CA_Missions_BAF","CA_Missions_BAF_2","CA_Missions_BAF_Templates_SecOps","CA_Missions_BattlefieldClearance","CA_Missions_E","CA_Missions_E_Armory2","CA_Missions_E_SecOps","CA_Missions_E_Templates_SecOps","CA_Missions_FirstAidSystem","CA_Missions_GarbageCollector","CA_Missions_PMC","CA_Missions_SecOps","CA_Missions_Templates_SecOps","CA_Missions2_PMC","CA_Modules","CA_Modules_Alice","CA_Modules_Animals","CA_Modules_ARTY","CA_Modules_clouds","CA_Modules_Coin","CA_Modules_DynO","CA_Modules_E","CA_Modules_E_DynO","CA_Modules_E_Jukebox","CA_Modules_E_OO","CA_Modules_E_UAV","CA_Modules_E_UAV_Heli","CA_Modules_E_Weather","CA_Modules_Functions","CA_Modules_Marta","CA_Modules_PMC","CA_Modules_PMC_SimpleFIrstAid","CA_Modules_Silvie","CA_Modules_StratLayer","CA_Modules_UAV","CA_Modules_ZoRA","CA_MPA","CA_MPA_Challenges","CA_MPA_Core","CA_MPA_MP","CA_MPA_Scenarios","CA_Sounds_Baf","CA_SoundsMissions_E","CA_Support","CAA10","CAAir_BAF","CAAir_BAF_CH_47F","CAAir_E","CAAir_E_A10","CAAir_E_AH64D","CAAir_E_AH6J","CAAir_E_An2","CAAir_E_C130J","CAAir_E_CH_47F","CAAir_E_Halo","CAAir_E_Mi24","CAAir_E_MI8","CAAir_E_UH1H_EP1","CAAir_E_UH60M","CAAir_PMC","CAAir_PMC_KA137","CAAir_PMC_KA60","CAAir2","CAAir2_C130J","CAAir2_ChukarTarget","CAAir2_F35B","CAAir2_MQ9PredatorB","CAAir2_MV22","CAAir2_Pchela1T","CAAir2_UH1Y","CAAir3","CAAir3_Su34","CAAnimals","CACharacters_BAF","CACharacters_BAF_Head","CACharacters_E","CACharacters_E_Head","CACharacters_PMC","CACharacters_PMC_Head","CACharacters_W_BAF","CACharacters2","CAFonts","CAMisc_fix","CAMisc_fix_A2FREE","CAMisc_fix_air","CAMisc_fix_Ch2","CAMisc_fix_Str","CAMisc_fix_Weap","CAMP_Armory_Misc","CAMP_Armory_Misc_Concrete_Wall","CAMP_Armory_Misc_Entrance_Gate","CAMP_Armory_Misc_Info_Board","CAMP_Armory_Misc_Infostands","CAMP_Armory_Misc_Laptop","CAMP_Armory_Misc_Loudspeakers","CAMP_Armory_Misc_Plasticpole","CAMP_Armory_Misc_Red_Light","CAMP_Armory_Misc_Sign_Armex","CAMP_Armory_Misc_Sign_Direction","CAMusic","CAMusic_E","CAMusic_PMC","CASounds_E","CASounds_Missions","CATracked_BAF","CATracked_E","CATracked_E_BMP2","CATracked_E_M1_Abrams","CATracked_E_M113","CATracked_E_M2A2_Bradley","CATracked_E_T34","CATracked_E_T55","CATracked_E_T72","CATracked_E_us_m270mlrs","CATracked_E_ZSU","CATracked_W_BAF","CATracked2","CATracked2_2S6M_Tunguska","CATracked2_AAV","CATracked2_BMP3","CATracked2_T34","CATracked2_T90","CATracked2_us_m270mlrs","CAWater2_Destroyer","CAWater2_fishing_boat","CAWater2_Fregata","CAWater2_smallboat_1","CAWeapons_2b14_82mm_Mortar","CAWeapons_AK","CAWeapons_AmmoBoxes","CAWeapons_BAF","CAWeapons_bizon","CAWeapons_Colt1911","CAWeapons_DMR","CAWeapons_E","CAWeapons_E_AGS","CAWeapons_E_AK","CAWeapons_E_AmmoBoxes","CAWeapons_E_Colt1911","CAWeapons_E_D30","CAWeapons_E_DSHKM","CAWeapons_E_FIM92_static","CAWeapons_E_fnfal","CAWeapons_E_G36","CAWeapons_E_GrenadeLauncher","CAWeapons_E_Igla","CAWeapons_E_Javelin","CAWeapons_E_KORD","CAWeapons_E_ksvk","CAWeapons_E_LeeEnfield","CAweapons_E_m107","CAWeapons_E_M110","CAWeapons_E_M119_Howitzer","CAWeapons_E_M136","CAWeapons_E_M14","CAWeapons_E_M16","CAWeapons_E_M240","CAWeapons_E_M252_81mm_Mortar","CAWeapons_E_M2StaticMG","CAWeapons_E_M47","CAWeapons_E_M9","CAWeapons_E_MAAWS","CAWeapons_E_Makarov","CAWeapons_E_Metis","CAWeapons_E_Mk19_MiniTriPod","CAWeapons_E_PK","CAWeapons_E_Podnos_2b14_82mm","CAWeapons_E_RPG18","CAWeapons_E_RPG7","CAWeapons_E_scar","CAWeapons_E_Searchlight","CAWeapons_E_SPG9","CAWeapons_E_STATIC","CAWeapons_E_Stinger","CAWeapons_E_Strela","CAWeapons_E_TOW","CAWeapons_E_ZU23","CAWeapons_Kord","CAweapons_ksvk","CAWeapons_M1014","CAweapons_m107","CAWeapons_M252_81mm_Mortar","CAWeapons_Metis_AT_13","CAWeapons_PMC","CAWeapons_PMC_AA_12","CAWeapons_PMC_AS50","CAWeapons_PMC_XM8","CAWeapons_Saiga12K","CAWeapons_SPG9","CAWeapons_VSS_vintorez","CAWeapons_ZU23","CAWeapons2","CAWeapons2_HuntingRifle","CAWeapons2_RPG18","CAWeapons2_SMAW","CAWheeled_D_BAF","CAWheeled_E_ATV","CAWheeled_E_BRDM2","CAWheeled_E_BTR40","CAWheeled_E_BTR60","CAWheeled_E_HMMWV","CAWheeled_E_Ikarus","CAWheeled_E_LADA","CAWheeled_E_LandRover","CAWheeled_E_M1030","CAWheeled_E_MTVR","CAWheeled_E_Offroad","CAWheeled_E_Old_bike","CAWheeled_E_Old_moto","CAWheeled_E_Pickup","CAWheeled_E_s1203","CAWheeled_E_SCUD","CAWheeled_E_stryker","CAWheeled_E_SUV","CAWheeled_E_TT650","CAWheeled_E_UAZ","CAWheeled_E_Ural","CAWheeled_E_V3S","CAWheeled_E_Volha","CAWheeled_Offroad","CAWheeled_Pickup","CAWheeled_PMC","CAWheeled_PMC_ArmoredSUV","CAWheeled_W_BAF","CAWheeled2_BTR90","CAWheeled2_GAZ39371","CAWheeled2_HMMWV_Ambulance","CAWheeled2_HMMWV_BASE","CAWheeled2_Ikarus","CAWheeled2_Kamaz","CAWheeled2_LADA","CAWheeled2_LAV25","CAWheeled2_M1114_Armored","CAWheeled2_M998A2_Avenger","CAWheeled2_MMT","CAWheeled2_MTVR","CAWheeled2_TowingTractor","CAWheeled2_V3S","CAWheeled2_VWGolf","CAWheeled3","CAWheeled3_M1030","CAWheeled3_TT650","Datsun_armed_DBE1","DBE1","DBE1_UI","DC3_DBE1","HALO_Test","Hilux_armed_DBE1","Warfare2","Warfare2_E","Warfare2Vehicles","AiA_Buildings_Config","CABuildings","CABuildings_Misc","Desert2_Buildings","CA_desert2_Characters","DBE1_Hotfix","AiA_Language_acr_Config","CALanguage_ACR","AiA_Language_e_Config","CALanguage_e","AiA_Language_pmc_Config","CALanguage_PMC","AiA_Languagemissions_acr_Config","CALanguage_missions_ACR","AiA_Languagemissions_pmc_Config","CALanguage_missions_PMC","AiA_Misc_Config","CAMisc","CAWater2_seafox_EP1","AiA_Roads_e_Config","CARoads_E","AiA_Rocks_e_Config","CARocks_E","AiA_Sara_Config","Sara","AiA_Saralite_Config","SaraLite","AiA_Structures_Config","CAStructures","CAStructures_A_BuildingWIP","CAStructures_A_CraneCon","CAStructuresLand_A_MunicipalOffice","CAStructuresBarn_W","CAStructures_Castle","CAStructuresHouse","CAStructuresHouse_A_FuelStation","CAStructuresHouse_A_Hospital","CAStructuresHouse_A_Office01","CAStructuresHouse_A_Office02","CAStructuresHouse_a_stationhouse","CAStructuresHouse_Church_02","CAStructuresHouse_Church_03","CAStructuresHouse_Church_05R","CAStructuresHouse_HouseBT","CAStructuresHouse_HouseV2","CAStructuresHouse_HouseV","CAStructuresLand_Ind_Stack_Big","CAStructures_IndPipe1","CAStructuresInd_Quarry","Ind_SawMill","CAStructures_Mil","CAStructures_Misc","CAStructures_Misc_Armory","CAStructures_Misc_Armory_Armor_Popuptarget","CAStructures_Misc_Powerlines","CAStructures_Nav","CAStructuresLand_Nav_Boathouse","CAStructures_Proxy_BuildingParts","CAStructures_Proxy_Ruins","CAStructures_Rail","CAStructuresHouse_rail_station_big","CAStructures_Ruins","CAStructuresShed_Small","CAStructuresHouse_Shed_Ind","CAStructures_Wall","AiA_Models_DBE1_Config","Models_DBE1","Anims_DBE1","HMMWV_DBE1","Kamenolom_DBE1","Mercenary_DBE1","Misc_DBE1","NPCs_DBE1","Pila_DBE1","Prisoners_DBE1","UH60Desert","UI_DBE1","Vysilac_DBE1","Zakladna_DBE1","AiA_Sara_dbe1_Config","Sara_dbe1","AiA_Buildings2_Config","CABuildings2","A_Crane_02","A_GeneralStore_01","CABuildings2_A_Pub","A_statue","Barn_Metal","CABuildingParts","CABuildingParts_Signs","CATEC","Church_01","Farm_Cowshed","Farm_WTower","CAHouseBlock_A","CAHouseBlock_B","CAHouseBlock_C","CAHouseBlock_D","HouseRuins","Ind_Dopravnik","Ind_Expedice","Ind_MalyKomin","Ind_Mlyn","Ind_Pec","ind_silomale","Ind_SiloVelke","Ind_Vysypka","Ind_Garage01","CAStructures_IndPipe1_todo_delete","IndPipe2","Ind_Shed_01","Ind_Shed_02","Ind_Tank","Ind_Workshop01","CABuildings2_Misc_Cargo","Misc_PowerStation","Misc_WaterStation","Rail_House_01","Shed_small","Shed_wooden","particle_effects","AiA_Chernarus_Config","Chernarus","AiA_Chernarus_Summer_Config","Chernarus_Summer","AiA_Desert2_Config","Porto","AiA_Desert_Config","Desert","AiA_Hotfix_Config","CA_Hotfix","CA_QGClutterHotfix","CA_Hotfix_vez_ropa","AiA_Misc2_Config","CAMisc2","AiA_Misc3_Config","CAMisc3","WarfareBuildings","AiA_Misc_e_Config","CAMisc_E","CAMisc_E_WF","AiA_Signs_e_Config","CASigns_E","A_TVTower","CAStructures_Nav_pier","CAStructures_Railway","AiA_Structures_e_Config","CAStructures_E","CAStructures_E_HouseA","CAStructures_E_HouseA_A_BuildingWIP","CAStructures_E_HouseA_A_CityGate1","CAStructures_E_HouseA_A_Minaret","CAStructures_E_HouseA_A_Minaret_Porto","CAStructures_E_HouseA_A_Mosque_big","CAStructures_E_HouseA_A_Mosque_small","CAStructures_E_HouseA_A_Office01","CAStructures_E_HouseA_a_stationhouse","CAStructures_E_HouseA_A_Statue","CAStructures_E_HouseA_A_Villa","CAStructures_E_HouseC","CAStructures_E_HouseK","CAStructures_E_HouseL","CAStructures_E_Ind","CAStructures_E_Ind_Ind_Coltan_Mine","CAStructures_E_Ind_Ind_FuelStation","CAStructures_E_Ind_Ind_Garage01","CAStructures_E_Ind_Oil_Mine","CAStructures_E_Ind_IndPipes","CAStructures_E_Ind_Misc_PowerStation","CAStructures_E_Ind_Ind_Shed","CAStructures_E_Mil","CAStructures_E_Misc","CAStructures_E_Misc_Misc_cables","CAStructures_E_Misc_Misc_Construction","CAStructures_E_Misc_Misc_Garbage","CAStructures_E_Misc_Misc_Interier","CAStructures_E_Misc_Misc_Lamp","CAStructures_E_Misc_Misc_Market","CAStructures_E_Misc_Misc_powerline","CAStructures_E_Misc_Misc_Water","CAStructures_E_Misc_Misc_Well","CAStructures_E_Wall","CAStructures_E_Wall_Wall_L","AiA_Structures_pmc_Config","CAStructures_PMC","CAStructures_PMC_Buildings","CAStructures_PMC_Buildings_Bunker","CAStructures_PMC_Buildings_GeneralStore_PMC","CAStructures_PMC_Buildings_Ruin_Cowshed","CAStructures_PMC_Ind","CAStructures_PMC_FuelStation","CAStructures_PMC_Misc","CAStructures_PMC_Misc_Shed","CAStructures_PMC_Ruins","CAStructures_PMC_Walls","AiA_Takistan_Config","Takistan","AiA_Zargabad_Config","zargabad","AiA_Afghan_Config","Mountains_ACR","AiA_Bohemia_Config","Woodland_ACR","AiA_Bootcamp_acr_Config","Bootcamp_ACR","AiA_Data_baf_Config","CA_BAF","AiA_Desert_e_Config","Desert_E","AiA_Language_baf_Config","CALanguage_Baf","AiA_Languagemissions_baf_Config","CALanguageMissions_baf","AiA_Misc_acr_Config","CAMisc_ACR","CAMisc_ACR_3DMarkers","CAMisc_ACR_Container","CAMisc_ACR_Dog","CAMisc_ACR_Helpers","CAMisc_ACR_PBX","CAMisc_ACR_ScaffoldingSmall","CAMisc_ACR_Shooting_range","CAMisc_ACR_Sign_Mines","CAMisc_ACR_Targets","CAMisc_ACR_Targets_InvisibleTarget","CAMisc_ACR_TestSphere","AiA_Provinggrounds_pmc_Config","ProvingGrounds_PMC","AiA_Shapur_baf_Config","Shapur_BAF","AiA_Core","AiA_Worlds","AiA_Worlds_Ambient","AiA_Worlds_Clutter","AiA_Worlds_ClutterDist","AiA_Worlds_Delete","AiA_Worlds_DisableInfiniteTerrain","AiA_Worlds_DustEffects","AiA_Worlds_EnvSounds","AiA_Worlds_FullDetailDist","AiA_Worlds_Intros","AiA_Worlds_Lighting","AiA_Worlds_Lighting_Chernarus","AiA_Worlds_Lighting_Desert","AiA_Worlds_MapSize","AiA_Worlds_MidDetailTexture","AiA_Worlds_NoDetailDist","AiA_Worlds_PictureMap","AiA_Worlds_PictureShot","AiA_Worlds_Seabed","AiA_Worlds_SkyTexture","AiA_Worlds_StreetLamp","AiA_Worlds_Surfaces","AiA_Worlds_Water","AiA_StandaloneTerrainPack_Core","AiA_StandaloneTerrainPack_Core_Faction","AiA_StandaloneTerrainPack_Core_VehicleClass"]; +_skn_whitelist_cfgPatches = [_serverSettingsConfig, "antihack_whitelistedCfgPatches", _whitelistPatches] call EPOCH_fnc_returnConfigEntry; +_skn_adminsOwner = [_serverSettingsConfig, "adminMenu_Owner", []] call EPOCH_fnc_returnConfigEntry; +_skn_adminsHigh = [_serverSettingsConfig, "adminMenu_High", []] call EPOCH_fnc_returnConfigEntry; +_skn_adminsLow = [_serverSettingsConfig, "adminMenu_Low", []] call EPOCH_fnc_returnConfigEntry; +_skn_banReason = [_serverSettingsConfig, "antihack_banReason", "EpochMod.com Autoban"] call EPOCH_fnc_returnConfigEntry; +_ownerSettings = ["ESP-PLAYER","ESP-VEHICLE","ESP-LOOT","OLD-ESP","OLD-MAP","PLAYER-TELEPORT","MAP-TELEPORT","INFRONT-TELEPORT","MAP-PLAYER","MAP-CORPSE","MAP-LOOT","MAP-VEHICLE","MAP-AI","MAP-BASEBUILDING","TARGET-HEAL","TARGET-AMMO","TARGET-KILL","TARGET-CRYPTO","TARGET-VEHICLEREPAIR","VEHICLEFLIP","BANPANNEL","SPAWN-MENU","FREE-CAM","INVISIBLE","SPAWNLOOT","GODMODE","HEAL","VEHICLEREPAIR"]; +_skn_adminMenuOwnerSetting = [_serverSettingsConfig, "adminMenu_OwnerSetting", _ownerSettings] call EPOCH_fnc_returnConfigEntry; +_adminSettings = ["PLAYER-TELEPORT","MAP-TELEPORT","TARGET-HEAL","TARGET-AMMO","TARGET-KILL","VEHICLEFLIP","BANPANNEL"]; +_skn_adminMenuHighSetting = [_serverSettingsConfig, "adminMenu_HighSetting", _adminSettings] call EPOCH_fnc_returnConfigEntry; +_lowSettings = ["PLAYER-TELEPORT","MAP-TELEPORT","TARGET-HEAL"]; +_skn_adminMenuLowSetting = [_serverSettingsConfig, "adminMenu_LowSetting", _lowSettings] call EPOCH_fnc_returnConfigEntry; +_skn_adminMenuMenuKey = [_serverSettingsConfig, "adminMenu_menuKey", 0x3B] call EPOCH_fnc_returnConfigEntry; +_skn_adminMenuInfrontTeleport = [_serverSettingsConfig, "adminMenu_infrontTeleport", 0x06] call EPOCH_fnc_returnConfigEntry; +_skn_adminMenuBanReasons = [_serverSettingsConfig, "adminMenu_BanReasons", ["Traderzone","Hacking","Glitch","Combat Log"]] call EPOCH_fnc_returnConfigEntry; +_skn_adminMenuCryproCfg = [_serverSettingsConfig, "adminMenu_cryptoCfg", [2500,1000,500,100,50,-1000]] call EPOCH_fnc_returnConfigEntry; +_skn_cfgPatchesCfg = [_serverSettingsConfig, "antihack_cfgPatchesCfg", [0]] call EPOCH_fnc_returnConfigEntry; +_skn_PVSPrefix = [_serverSettingsConfig, "antihack_PVSPrefix", "EPAH_"] call EPOCH_fnc_returnConfigEntry; +_skn_customVariablesCheck = [_serverSettingsConfig, "antihack_customVariablesCheck", true] call EPOCH_fnc_returnConfigEntry; +_skn_customVariables = [_serverSettingsConfig, "antihack_customVariables", []] call EPOCH_fnc_returnConfigEntry; +_loots = ["CfgEpochClient", "lootClasses", EPOCH_lootClasses] call EPOCH_fnc_returnConfigEntryV2; + +_skn_PVC_NAMES = ['tradeRequest', 'repairVehicle', 'lockVehicle', 'unlockVehicle', 'fillVehicle', 'clientRevive', 'earthQuake', 'unitSpawn', 'say3D', 'switchMove', 'bankBalance', 'effectCrypto', 'resetGroup', 'BADHIVE', 'groupUpdate', 'groupUidUpdate', 'groupInvitePlayer', 'serverMessage', 'healPlayer', 'airDrop']; +_rndVAR_Count = 83 + (count _skn_PVC_NAMES); // 82 = number of (_skn_rndVA deleteAt 0) uses + _skn_PVC_NAMES count +_skn_rndVA = call compile('epochserver' callExtension format['810|%1', _rndVAR_Count]); + +EPOCH_hiveWhitelistVarsArray = []; +if (_skn_customVariablesCheck) then{ + _whitelistConfig = _cfg_variablesConfig >> "whitelist"; + _skn_customVariables append(getArray(_whitelistConfig >> "bis")); //BIS Variables + _skn_customVariables append(getArray(_whitelistConfig >> "epoch")); //Epoch Variables + _skn_customVariables append(getArray(_whitelistConfig >> "custom")); //Custom Variables + // Get any automatically added whitelist vars from Learning feature. + _response = ["AH-WhitelistVars", (call EPOCH_fn_InstanceID)] call EPOCH_fnc_server_hiveGETRANGE; + if ((_response select 0) == 1 && typeName(_response select 1) == "ARRAY") then{ + if !((_response select 1) isEqualTo[]) then{ + EPOCH_hiveWhitelistVarsArray = _response select 1; + _skn_customVariables append EPOCH_hiveWhitelistVarsArray; + }; + }; +}; + +// For client PVC +_skn_PVC_INDEX = _skn_rndVA deleteAt 0; +{ + _ret = EPOCH_SERVER pushBack (_skn_rndVA deleteAt 0); +}count _skn_PVC_NAMES; + +// [["function", _transferBankBalance],owner _transferTarget] +EPOCH_sendPublicVariableClient = compileFinal (" + private '_index'; + _index = "+str _skn_PVC_NAMES+" find (_this select 0 select 0); + if (_index != -1) then { + "+_skn_PVC_INDEX+" = ["+str EPOCH_SERVER+" select _index, _this select 0 select 1]; + (_this select 1) publicVariableClient '"+_skn_PVC_INDEX+"'; + }; +"); +// [["serverMessage",["str_epoch_restart_in",5]]] +EPOCH_sendPublicVariableAll = compileFinal(" +private '_index'; +_index = "+str _skn_PVC_NAMES+" find(_this select 0 select 0); +if (_index != -1) then{ + "+_skn_PVC_INDEX+" = ["+str EPOCH_SERVER+" select _index, _this select 0 select 1]; + publicVariable '"+_skn_PVC_INDEX+"'; +}; +"); + +_skn_AH_rndVarVehicle = _skn_rndVA deleteAt 0; +_skn_AH_rndVarPlayer = _skn_rndVA deleteAt 0; + +EPOCH_serverCommand = compileFinal (" +switch (_this select 0) do { + case 'shutdown': { 'epochserver' callExtension '991' }; + case 'message': { 'epochserver' callExtension format['901|%1', _this select 1] }; + case 'lock': { 'epochserver' callExtension '931' }; + case 'unlock': { 'epochserver' callExtension '930' }; + case 'kick': { + _playerUID = _this select 1; + if (typeName _playerUID == 'OBJECT') then{ + if (!isNull(_playerUID)) then{ + _playerUID = getPlayerUID _playerUID; + }; + }; + if (_playerUID != '') then{ + 'epochserver' callExtension format['911|%1|%2', _playerUID, _this select 2]; + }; + }; + case 'ban': { + _playerUID = _this select 1; + if (typeName _playerUID == 'OBJECT') then{ + if (!isNull(_playerUID)) then{ + _playerUID = getPlayerUID _playerUID; + }; + }; + if (_playerUID != '') then{ + 'epochserver' callExtension format['921|%1|%2|%3', _playerUID, _this select 2, _this select 3]; + }; + }; + }; +"); + +EPOCH_server_getVToken = compileFinal ("_this getVariable ['"+_skn_AH_rndVarVehicle+"',false]"); +EPOCH_server_setVToken = compileFinal ("_this setVariable ['"+_skn_AH_rndVarVehicle+"',true];true"); +EPOCH_server_getPToken = compileFinal ("private['_ret','_var'];_ret = false;if (typeName(_this select 0)=='OBJECT')then{if (!isNull(_this select 0))then{_var=(_this select 0) getVariable '"+_skn_AH_rndVarPlayer+"';if (!isNil '_var') then {_ret= _var==(_this select 1)}}};if(!_ret)then{['kick',(_this select 0),'Token Check Failed'] call EPOCH_serverCommand};_ret"); +EPOCH_server_setPToken = compileFinal ("private '_var';_var = 'epochserver' callExtension '810';_this setVariable ['"+_skn_AH_rndVarPlayer+"',_var];_var"); + +if (!_skn_enableAntihack) exitWith { + EPOCH_server_pushPlayer = compileFinal ("EPOCH_C_SET = _this select 2;EPOCH_C_SET pushBack '"+_skn_PVC_INDEX+"';EPOCH_C_SET pushBack '';(_this select 0) publicVariableClient 'EPOCH_C_SET'"); + EPOCH_server_isPAdmin = compileFinal ("false"); + EPOCH_server_Authed = compileFinal ("true"); + EPOCH_server_disconnect = compileFinal("true"); + EPOCH_server_kickToLobby = compileFinal("true"); +}; + +// Check AH init code +_skn_AH_rndVarAHInitCheck = _skn_rndVA deleteAt 0; +// Init as array +call compile(_skn_AH_rndVarAHInitCheck+"=[];"); + +_skn_AH_Init = _skn_rndVA deleteAt 0; +_skn_AH_Code = _skn_rndVA deleteAt 0; +_skn_AH_Code_CA = _skn_rndVA deleteAt 0; +_skn_AH_Code_CB = _skn_rndVA deleteAt 0; +_skn_AH_Ban = _skn_rndVA deleteAt 0; +_skn_AH_rndVar = _skn_rndVA deleteAt 0; +_skn_doKickBan = _skn_PVSPrefix + (_skn_rndVA deleteAt 0); + + +_skn_server_getRealTime = _skn_rndVA deleteAt 0; +//ADMIN STUFF: +//PVC from SERVER: +_skn_pv_hackerLog = _skn_rndVA deleteAt 0; +_skn_pv_adminLog = _skn_rndVA deleteAt 0; +//Server Functions: +_skn_server_adminLog = _skn_rndVA deleteAt 0; + +//PVS from CLIENT: +_skn_doAdminRequest = _skn_PVSPrefix + (_skn_rndVA deleteAt 0); +_skn_doAdminLog = _skn_PVSPrefix + (_skn_rndVA deleteAt 0); +_skn_doTokenAuth = _skn_PVSPrefix + (_skn_rndVA deleteAt 0); +_skn_antiTeleportPVC = _skn_rndVA deleteAt 0; + +//ADMIN MENU CODE & INIT +_skn_Admin_Code = _skn_rndVA deleteAt 0; +_skn_Admin_Init = _skn_rndVA deleteAt 0; + +//ADMIN FUNCTIONS +_skn_adminRequest_PVC = _skn_rndVA deleteAt 0; +_skn_adminLog_PVC = _skn_rndVA deleteAt 0; +_skn_adminLog = _skn_rndVA deleteAt 0; +_skn_AdminKeyDown = _skn_rndVA deleteAt 0; +_skn_AdminMenu_Init = _skn_rndVA deleteAt 0; +_skn_getCtrl = _skn_rndVA deleteAt 0; +_skn_fnc_Spec = _skn_rndVA deleteAt 0; +_skn_Update_AdminButtons = _skn_rndVA deleteAt 0; +_skn_mainMenuCfg = _skn_rndVA deleteAt 0; +_skn_FillMainMenu = _skn_rndVA deleteAt 0; +_skn_FillPlayerMenu = _skn_rndVA deleteAt 0; +_skn_switchMainMenu = _skn_rndVA deleteAt 0; +_skn_dbClickMainMenu = _skn_rndVA deleteAt 0; +_skn_spawnMenu = _skn_rndVA deleteAt 0; +_skn_spawnSpawnMenu = _skn_rndVA deleteAt 0; +_skn_removespawnMenu = _skn_rndVA deleteAt 0; +_skn_fillSpawnMenu = _skn_rndVA deleteAt 0; +_skn_hackerLog = _skn_rndVA deleteAt 0; +_skn_switchTable = _skn_rndVA deleteAt 0; +_skn_customBanreason = _skn_rndVA deleteAt 0; +_skn_flipVehicle = _skn_rndVA deleteAt 0; +_skn_freeCam = _skn_rndVA deleteAt 0; +_skn_delete = _skn_rndVA deleteAt 0; +_skn_deleteMenu = _skn_rndVA deleteAt 0; +_skn_deleteNow = _skn_rndVA deleteAt 0; +_skn_doBan = _skn_rndVA deleteAt 0; +_skn_mapTeleport = _skn_rndVA deleteAt 0; +_skn_old_esp = _skn_rndVA deleteAt 0; +_skn_hideAdmin = _skn_rndVA deleteAt 0; +_skn_old_espMap = _skn_rndVA deleteAt 0; +_skn_infrontTP = _skn_rndVA deleteAt 0; +_skn_esp = _skn_rndVA deleteAt 0; +_skn_godMode = _skn_rndVA deleteAt 0; +_skn_repairVehicle = _skn_rndVA deleteAt 0; +_skn_spawnLoot = _skn_rndVA deleteAt 0; +_skn_mapLootArray = _skn_rndVA deleteAt 0; + +//ADMIN TOGGLE VARIABLES +_skn_tg_Spec = _skn_rndVA deleteAt 0; +_skn_tg_sortOrder = _skn_rndVA deleteAt 0; +_skn_tg_toggle = _skn_rndVA deleteAt 0; +_skn_tg_BanPlayer = _skn_rndVA deleteAt 0; +_skn_tg_delete = _skn_rndVA deleteAt 0; +_skn_tg_mapTeleport = _skn_rndVA deleteAt 0; +_skn_tg_spawnTyp = _skn_rndVA deleteAt 0; +_skn_tg_limitSpawn = _skn_rndVA deleteAt 0; +_skn_tg_old_espMap = _skn_rndVA deleteAt 0; +_skn_tg_old_esp = _skn_rndVA deleteAt 0; +_skn_tg_hideAdmin = _skn_rndVA deleteAt 0; +_skn_tg_infrontTP = _skn_rndVA deleteAt 0; +_skn_tg_godMode = _skn_rndVA deleteAt 0; + +_skn_tg_map_player = _skn_rndVA deleteAt 0; +_skn_tg_map_corpse = _skn_rndVA deleteAt 0; +_skn_tg_map_loot = _skn_rndVA deleteAt 0; +_skn_tg_map_vehicle = _skn_rndVA deleteAt 0; +_skn_tg_map_ai = _skn_rndVA deleteAt 0; +_skn_tg_map_basebuilding = _skn_rndVA deleteAt 0; + +_skn_t1 = _skn_rndVA deleteAt 0; +_skn_t2 = _skn_rndVA deleteAt 0; +_skn_t3 = _skn_rndVA deleteAt 0; +_skn_t4 = _skn_rndVA deleteAt 0; +_skn_t5 = _skn_rndVA deleteAt 0; + +_skn_kickToLobby = _skn_rndVA deleteAt 0; +_skn_whitelistVars = _skn_rndVA deleteAt 0; + +if (_skn_customVariablesCheck) then{ + // Gather all random global vars from AH for whitelist var checks + _skn_customVariables append [_skn_PVC_INDEX,_skn_whitelistVars,_skn_kickToLobby,toLower(_skn_doKickBan),toLower(_skn_doTokenAuth)]; + _skn_customVariables append [_skn_AH_Init,_skn_AH_Code,_skn_AH_Code_CA,_skn_AH_Code_CB,_skn_AH_Ban,_skn_antiTeleportPVC,_skn_Admin_Init]; + _skn_customVariables append [toLower("FW"+_skn_AH_rndVar),toLower("FA"+_skn_AH_rndVar),toLower("FWC"+_skn_AH_rndVar)]; + + // Globally brodcast whitelist vars array + missionNamespace setVariable [_skn_whitelistVars,_skn_customVariables]; + call compile("publicVariable " + str _skn_whitelistVars + ";"); +}; + +EPOCH_server_kickToLobby = compileFinal ("if !(isNull _this) then {"+_skn_kickToLobby+" = true;(owner _this) publicVariableClient '"+_skn_kickToLobby+"';};"); + +_skn_AH_rndVarAHInitCheckToken = _skn_t1+_skn_t2+_skn_t3+_skn_t4+_skn_t5; +EPOCH_server_Authed = compileFinal("_this in "+_skn_AH_rndVarAHInitCheck); +EPOCH_server_disconnect = compileFinal(" + _ret = false; + _index = " +_skn_AH_rndVarAHInitCheck + " find _this; + if (_index != -1) then { + " +_skn_AH_rndVarAHInitCheck + " deleteAt _index; + _ret = true; + }; + _ret +"); + +_stringInArray = { + private "_ret"; + _ret = false; + {if (_x in _case)exitWith {_ret = true}}forEach _this; + _ret +}; + +_displaysArray = []; +{_displaysArray pushBack [_x,[],[]]} forEach ["RscDisplayMainMap","RscDisplayGetReady","RscDisplayInventory","RscDisplayLoadMission","RscDisplayInterrupt","RscDisplayOptionsVideo","RscDisplayOptions","RscDisplayAVTerminal","RscDisplayConfigure","RscDisplayConfigureAction","RscDisplayConfigureControllers","RscDisplayControlSchemes","RscDisplayCustomizeController","RscDisplayDebriefing","RscDisplayDiary","RscDisplayGameOptions","RscDisplayJoystickSchemes","RscDisplayLoading","RscDisplayMicSensitivityOptions","RscDisplayOptionsAudio","RscDisplayOptionsLayout","RscDisplayStart","RscDisplayVehicleMsgBox","RscDisplayInsertMarker"]; +_displays = [(_config >> "displayOnload"), "checkDisplays", _displaysArray] call EPOCH_fnc_returnConfigEntry; + + +_escapeQuotes = { + _return = []; + { + _return pushback _x; + if (_x == 34) then { + _return pushback _x; + }; + } forEach toArray _this; + toString _return +}; + +_cfg_displayArray = []; +{ + _onLoad = ((getText(configFile >> (_x select 0) >> "onLoad")) call _escapeQuotes); + _onUnload = ((getText(configFile >> (_x select 0) >> "onUnload")) call _escapeQuotes); + _onLoad = [_onLoad]; + _onUnload = [_onUnload]; + { + _onLoad pushBack(_x call _escapeQuotes); + } forEach(_x select 1); + { + _onUnload pushBack(_x call _escapeQuotes); + } forEach(_x select 2); + _cfg_displayArray pushBack[(_x select 0), _onLoad, _onUnload]; +}forEach _displays; + +_skn_adminUIDArray = []; +_skn_adminNAMEArray = []; +_skn_tempuid = []; +{ + _skn_adminUIDArray pushBack(_x select 0); + _skn_adminNAMEArray pushBack(_x select 1); + +} forEach _skn_adminsOwner; +_skn_adminsOwner = _skn_adminUIDArray; +{ + _skn_tempuid pushBack(_x select 0); + _skn_adminUIDArray pushBack(_x select 0); + _skn_adminNAMEArray pushBack(_x select 1); + +} forEach _skn_adminsHigh; +_skn_adminsHigh = _skn_tempuid; +_skn_tempuid = []; +{ + _skn_adminUIDArray pushBack(_x select 0); + _skn_tempuid pushBack(_x select 0); + _skn_adminNAMEArray pushBack(_x select 1); +} forEach _skn_adminsLow; +_skn_adminsLow = _skn_tempuid; +_skn_tempuid = nil; + +{_skn_adminMenuOwnerSetting set[_forEachIndex, toUpper _x]}forEach _skn_adminMenuOwnerSetting; +{_skn_adminMenuHighSetting set [_forEachIndex,toUpper _x]}forEach _skn_adminMenuHighSetting; +{_skn_adminMenuLowSetting set [_forEachIndex,toUpper _x]}forEach _skn_adminMenuLowSetting; + +_skn_adminMenuOwner = "[]"; +_skn_adminMenuHigh = "[]"; +_skn_adminMenuLow = "[]"; + +_skn_blockedSpawnMenuUID = []; +if !("SPAWN-MENU" in _skn_adminMenuHighSetting) then {_skn_blockedSpawnMenuUID = _skn_adminsHigh}; +if !("SPAWN-MENU" in _skn_adminMenuLowSetting) then {{_skn_blockedSpawnMenuUID pushBack _x}forEach _skn_adminsLow}; +if !("SPAWN-MENU" in _skn_adminMenuOwnerSetting) then {{_skn_blockedSpawnMenuUID pushBack _x}forEach _skn_adminsOwner}; + +_case = _skn_adminMenuOwnerSetting; //All Cfg for Owner Menu +for "_i" from 1 to 3 do { + _temp = "[['=============== MAIN MENU ===============',[],'','1',[]]"; + if (["PLAYER-TELEPORT","MAP-TELEPORT","INFRONT-TELEPORT"] call _stringInArray) then { + + if ("PLAYER-TELEPORT" in _case) then { + _temp = _temp + " + ,[' Player To Admin',[],{[101,_this select 1] call "+_skn_adminRequest_PVC+"},'4',[]] + ,[' Admin To Player', [], { [102, _this select 1] call "+_skn_adminRequest_PVC+" },'4',[]] + "; + }; + if ("INFRONT-TELEPORT" in _case) then { + _temp = _temp + " + ,[' In Front', [], {"+_skn_tg_infrontTP+" = !"+_skn_tg_infrontTP+"},'2',[]] + "; + }; + if ("MAP-TELEPORT" in _case) then { + _temp = _temp + " + ,[' Ctrl+Click Map', [], {"+_skn_tg_mapTeleport+"=!"+_skn_tg_mapTeleport+";['Map to Teleport', if ("+_skn_tg_mapTeleport+") then[{2}, { 1 }]] call "+_skn_adminLog_PVC+" },'2',[]] + "; + }; + }; + if (["FREE-CAM","INVISIBLE"] call _stringInArray) then { + _temp = _temp + ",['Spectate', [],'','1',[]]"; + if ("MAP-TELEPORT" in _case) then { + _temp = _temp + " + ,[' Free Look Cam ', [], "+_skn_freeCam+",'0',[]] + "; + }; + if ("INVISIBLE" in _case) then { + _temp = _temp + " + ,[' Invisible Mode', [], "+_skn_hideAdmin+", '2', []] + "; + }; + }; + if (["MAP-PLAYER","MAP-CORPSE","MAP-LOOT","MAP-VEHICLE","MAP-AI","MAP-BASEBUILDING"] call _stringInArray) then { + _temp = _temp + ",['Map Tools', [],'','1',[]]"; + if ("MAP-PLAYER" in _case) then { + _temp = _temp + " + ,[' Player Marker', [], {"+_skn_tg_map_player+" = !"+_skn_tg_map_player+"; ['Player MARKER',if ("+_skn_tg_map_player+") then [{2},{1}]] call "+_skn_adminLog_PVC+"}, '2', []] + "; + }; + if ("MAP-CORPSE" in _case) then { + _temp = _temp + " + ,[' Corpse Marker', [], {"+_skn_tg_map_corpse+" = !"+_skn_tg_map_corpse+"; ['Corpse MARKER',if ("+_skn_tg_map_corpse+") then [{2},{1}]] call "+_skn_adminLog_PVC+"}, '2', []] + "; + }; + if ("MAP-LOOT" in _case) then { + _temp = _temp + " + ,[' Loot Marker', [], {"+_skn_tg_map_loot+" = !"+_skn_tg_map_loot+"; if ("+_skn_tg_map_loot+") then {waitUntil {"+_skn_mapLootArray+" = nearestObjects[getPos player, ['WH_Loot', 'Animated_Loot'], 10000];uiSleep 10;!"+_skn_tg_map_loot+"};"+_skn_mapLootArray+" = []};['Loot MARKER',if ("+_skn_tg_map_loot+") then [{2},{1}]] call "+_skn_adminLog_PVC+"}, '2', []] + "; + }; + if ("MAP-VEHICLE" in _case) then { + _temp = _temp + " + ,[' Vehicle Marker', [], {"+_skn_tg_map_vehicle+" = !"+_skn_tg_map_vehicle+"; ['Vehicle MARKER',if ("+_skn_tg_map_vehicle+") then [{2},{1}]] call "+_skn_adminLog_PVC+"}, '2', []] + "; + }; + if ("MAP-AI" in _case) then { + _temp = _temp + " + ,[' AI Marker', [], {"+_skn_tg_map_ai+" = !"+_skn_tg_map_ai+"; ['AI MARKER',if ("+_skn_tg_map_ai+") then [{2},{1}]] call "+_skn_adminLog_PVC+"}, '2', []] + "; + }; + if ("MAP-BASEBUILDING" in _case) then { + _temp = _temp + " + ,[' Base Building Marker (WIP)', [], {"+_skn_tg_map_basebuilding+" = !"+_skn_tg_map_basebuilding+"; ['Base Building MARKER',if ("+_skn_tg_map_basebuilding+") then [{2},{1}]] call "+_skn_adminLog_PVC+"}, '2', []] + "; + }; + }; + if (["ESP-PLAYER","ESP-LOOT","ESP-VEHICLE"] call _stringInArray) then { + _temp = _temp + ",['3D Tools', [],'','1',[]]"; + if ("ESP-PLAYER" in _case) then { + _temp = _temp + " + ,[' Player ESP', true, "+_skn_esp+", '2', []] + "; + }; + if ("ESP-VEHICLE" in _case) then { + _temp = _temp + " + ,[' Vehicle ESP', false, "+_skn_esp+", '2', []] + "; + }; + if ("ESP-LOOT" in _case) then { + _temp = _temp + " + ,[' Loot ESP (WIP)', [], '', '1', []] + "; + }; + }; + if (["OLD-ESP","OLD-MAP"] call _stringInArray) then { + _temp = _temp + ",['Old Visualisation Tools', [],'','1',[]]"; + if ("OLD-ESP" in _case) then { + _temp = _temp + ",[' 3D ESP', [], "+_skn_old_esp+", '2', []]"; + }; + if ("OLD-MAP" in _case) then { + _temp = _temp + ",[' MAP ESP', [], "+_skn_old_espMap+", '2', []]"; + }; + }; + if (["GODMODE","HEAL","VEHICLEREPAIR"] call _stringInArray) then { + _temp = _temp + ",['Self Menu', [], '', '1', []]"; + if ("GODMODE" in _case) then { + _temp = _temp + ",[' Godmode', [], "+_skn_godMode+", '2', []]"; + }; + if ("HEAL" in _case) then { + _temp = _temp + ",[' Heal',[],{[103,netId player] call "+_skn_adminRequest_PVC+"},'4',[0.016,0.702,0.078,1]]"; + }; + if ("VEHICLEREPAIR" in _case) then { + _temp = _temp + ",[' Repair Vehicle', [], "+_skn_repairVehicle+", '0', []]"; + }; + }; + if (["TARGET-HEAL","TARGET-AMMO","TARGET-KILL","TARGET-CRYPTO","TARGET-VEHICLEREPAIR"] call _stringInArray) then { + _temp = _temp + ",['Target Actions', [], '', '1', []]"; + if ("TARGET-HEAL" in _case) then { + _temp = _temp + ",[' Heal',[],{[103,_this select 1] call "+_skn_adminRequest_PVC+"},'4',[0.016,0.702,0.078,1]]"; + }; + if ("TARGET-KILL" in _case) then { + _temp = _temp + ",[' Kill',[],{[100,_this select 1] call "+_skn_adminRequest_PVC+"},'4',[0.859,0.094,0.094,1]]"; + }; + if ("TARGET-AMMO" in _case) then { + _temp = _temp + ",[' Give Ammo',[],{[200,_this select 1] call "+_skn_adminRequest_PVC+"},'4',[]]"; + }; + if ("TARGET-VEHICLEREPAIR" in _case) then { + _temp = _temp + ",[' Repair Vehicle', [], "+_skn_flipVehicle+", '0', []]"; + }; + if ("TARGET-CRYPTO" in _case) then { + { + _temp = _temp + ",[' Give Crypto - "+str _x+"',"+str _x+",{[107,[_this select 1,_this select 2]] call "+_skn_adminRequest_PVC+"},'4',[]]" + }count _skn_adminMenuCryproCfg; + }; + }; + _temp = _temp + ",['Custom Stuff', [], '', '1', []]"; + if ("VEHICLEFLIP" in _case) then { + _temp = _temp + ",[' Unflip Vehicle', [], "+_skn_flipVehicle+", '0', []]"; + }; + if ("SPAWNLOOT" in _case) then { + _temp = _temp + ",[' Loot Buildings (25m)', 25, "+_skn_spawnLoot+", '0', []]"; + }; + _temp = _temp + ",[' Disconnect yourself', [], { (findDisplay 46) closeDisplay 0 }, '0', []]"; + if ("BANPANNEL" in _case) then { + _temp = _temp + ",['Ban Menu',[],'','1',[]] + ,[' BattlEye Ban - Custom Ban Reason',[],"+_skn_customBanreason+",'4',[]] + "; + { + _temp = _temp + ",[' BattlEye Ban - "+_x+"','"+_x+"',"+_skn_customBanreason+",'4',[]]" + }count _skn_adminMenuBanReasons; + }; + + _temp = _temp + " + ,['Key Binds',[],'','1',[]] + ,[' 3 Key - Teleport In Front',[],'','1',[]] + ,[' F2 - Cancel Spectating',[],'','1',[]] + ,[' F5 - Delete Target',[],'','1',[]] + ]; + "; + if (_i == 1) then { + _skn_adminMenuOwner = _temp; + _case = _skn_adminMenuHighSetting; + }; + if (_i == 2) then { + _skn_adminMenuHigh = _temp; + _case = _skn_adminMenuLowSetting; + }; + if (_i == 3) then { + _skn_adminMenuLow = _temp; + }; +}; + +_skn_spawnPointCenter = getMarkerPos "respawn_west"; +_centerDistance = 30; + +// Only set these if prefix is not used since we can filter for it +if (_skn_PVSPrefix == "") then { + "epochserver" callExtension format["800|%1|%2|%3|%4", _skn_doKickBan, _skn_doAdminRequest, _skn_doAdminLog, _skn_doTokenAuth]; +}; + +EPOCH_server_pushPlayer = compileFinal (" + EPOCH_C_SET = _this select 2; + if (_this select 1 in "+ str _skn_adminUIDArray+") then { + (_this select 0) publicVariableClient '"+_skn_Admin_Code+"'; + (_this select 0) publicVariableClient '"+_skn_pv_adminLog+"'; + (_this select 0) publicVariableClient '"+_skn_pv_hackerLog+"'; + EPOCH_C_SET pushBack '"+_skn_PVC_INDEX+"'; + EPOCH_C_SET pushBack '[] spawn "+_skn_Admin_Init+"'; + } else { + EPOCH_C_SET pushBack '"+_skn_PVC_INDEX+"'; + EPOCH_C_SET pushBack '[] spawn "+_skn_AH_Init+"'; + }; + (_this select 0) publicVariableClient 'EPOCH_C_SET'; + true +"); +EPOCH_server_isPAdmin = compileFinal ("if (isNull _this) then {false} else {getPlayerUID _this in "+str _skn_adminUIDArray+"}"); + +_sknBanANDSleep = _skn_AH_Ban+"; uiSleep 60"; +_sknBanANDSleepQuick = _skn_AH_Ban+"; uiSleep 1"; + +// CfgPatches Check +_sknPatches = []; +"_sknPatches pushBack (configName _x)" configClasses (configFile >> "CfgPatches"); +{if !(_x in _sknPatches) then {_sknPatches pushBack _x}}forEach _skn_whitelist_cfgPatches; +_skn_addonCheckCode = if (_skn_check_addons) then {"[] spawn{_config = '!(configName _x in "+str _sknPatches+")' configClasses (configFile >> 'CfgPatches');if !(_config isEqualTo []) then {[format['Disallowed Addon %1',_config],"+str (_skn_cfgPatchesCfg select 0)+"] call "+_skn_AH_Ban+"}};"} else {""}; +_skn_fileCheckCode = if (_skn_check_files isEqualTo []) then {""} else {"{if (str(compile preprocessFileLineNumbers (_x select 0)) != str(missionNamespace getVariable [_x select 1,'']))exitWith{[format['Modified File %1 (%2/%3)',_x select 1,count toArray str (compile preprocessFileLineNumbers (_x select 0)),count toArray str(missionNamespace getVariable [_x select 1,''])],0] call "+_skn_AH_Ban+"}} forEach "+str _skn_check_files+";"}; + +_sknCustomVarCheckModeCode = [_serverSettingsConfig, "antihack_customVariablesCheckMode", 0] call EPOCH_fnc_returnConfigEntry; +_sknCustomVarCheckCode = if (_skn_customVariablesCheck) then {" +{ + if !(_x in (missionNamespace getVariable ["+str _skn_whitelistVars+",[]])) then{ + [format['(WIP) Unknown Variable (missionNamespace): %1', _x], ["+str _sknCustomVarCheckModeCode+",[toArray(_x)]]] call "+_sknBanANDSleepQuick+"; + } +}forEach(allVariables missionNamespace); +"} else {""}; + + +_sknAddActionCheck = if ([_serverSettingsConfig, "antihack_addActionCheck", true] call EPOCH_fnc_returnConfigEntry) then{ " +if (player == _ActionVehicle) then[{_ActionCount = _ActionCount + 1}, { _ActionVehicle = player; _ActionCount = 0 }]; +_addCase = player addAction['', '', [], -5, false, true, '', 'false']; +player removeAction _addCase; +if (_addCase != _ActionCount) then{ + [format['addAction %1/%2', _addCase, _ActionCount], 0] call "+_sknBanANDSleep+"; +}; +"} else {""}; + + +call compile (_skn_server_getRealTime+" = { + _time = call compile ('epochserver' callExtension '510'); + _hour = _time select 3; + _min = _time select 4; + if (_min < 10) then {_min = '0'+str _min}; + if (_hour < 10) then {_hour = '0'+str _hour}; + format ['%1:%2',_hour,_min] +};"); + +//[_data,_player,_token]; +call compile("'"+_skn_doTokenAuth+"' addPublicVariableEventHandler { + _array = _this select 1; + _tokenSet = false; + if !([_array select 1, _array select 2] call EPOCH_server_getPToken) exitWith{}; + if (typeName(_array select 0) == 'STRING') then { + if (_array select 0 == '"+_skn_AH_rndVarAHInitCheckToken+"') then { + _tokenSet = true; + _puid = (_array select 1) getVariable['PUID', '']; + if (_puid != '') then { + if !(_puid in "+_skn_AH_rndVarAHInitCheck+") then { + "+_skn_AH_rndVarAHInitCheck+" pushBack _puid; + diag_log format['DEBUG: player auth token set %1', _array]; + }; + }; + }; + }; + if !(_tokenSet) then { + _playerUID = getPlayerUID (_array select 1); + if (_playerUID != '') then{ + 'epochserver' callExtension format['911|%1|%2', _playerUID, 'Auth failure, Please reconnect']; + }; + }; +};"); + + +//[[_case,_time,_name,_uid,_save],[1, 0, 0, 1]] +call compile ("'"+_skn_doKickBan+"' addPublicVariableEventHandler { + _array = _this select 1; + _player =_array select 2; + if !([_player,_array select 3] call EPOCH_server_getPToken) exitWith { + ['ahe', format['Token is different [%1,%2] %3',if (!isNull _player) then { _player getVariable ['"+_skn_AH_rndVarPlayer+"','']}else{'PlayerObj NULL'}, _array select 3, _array]] call EPOCH_fnc_server_hiveLog; + }; + _text = toString(_array select 0); + + _mode = _array select 1; + _data = []; + if (typeName _mode == 'ARRAY') then{ + _mode = (_array select 1) select 0; + _data = (_array select 1) select 1; + }; + + if (_mode == 0) then{ + ['ahb', format['%1 (%2): %3', name _player, getPlayerUID _player, _text]] call EPOCH_fnc_server_hiveLog; + "+_skn_pv_hackerLog+" pushBack [[0,call "+_skn_server_getRealTime+",name _player,getPlayerUID _player,_text],[1, 0, 0, 1]]; + 'epochserver' callExtension format['820|%1|"+_skn_banReason+"',getPlayerUID _player]; + } else { + if (_mode == 2) then{ + _unknownVar = toString(_data select 0); + _safeVars = missionNamespace getVariable ["+str _skn_whitelistVars+",[]]; + _trusted = "+_str_learningModeCheck+"; + if !(_unknownVar in _safeVars) then{ + if (_trusted) then { + + _safeVars pushBack _unknownVar; + missionNamespace setVariable ["+str _skn_whitelistVars+",_safeVars]; + publicVariable "+str _skn_whitelistVars+"; + + if !(_unknownVar in EPOCH_hiveWhitelistVarsArray) then{ + EPOCH_hiveWhitelistVarsArray pushBack _unknownVar; + ['AH-WhitelistVars', (call EPOCH_fn_InstanceID), EPOCH_hiveWhitelistVarsArray] call EPOCH_fnc_server_hiveSET; + }; + + ['ahl', format['LEARNING: %1 (%2): %3', name _player, getPlayerUID _player, _text]] call EPOCH_fnc_server_hiveLog; + "+_skn_pv_hackerLog+" pushBack[[1, call "+_skn_server_getRealTime+", name _player, getPlayerUID _player, format['LEARNING: %1',_text]], []]; + } else { + ['ahb', format['%1 (%2): %3', name _player, getPlayerUID _player, _text]] call EPOCH_fnc_server_hiveLog; + "+_skn_pv_hackerLog+" pushBack [[0,call "+_skn_server_getRealTime+",name _player,getPlayerUID _player,_text],[1, 0, 0, 1]]; + _banID = 1; + 'epochserver' callExtension format['820|%1|"+_skn_banReason+" #V%2',getPlayerUID _player,_banID]; + }; + }; + }else { + ['ahl', format['%1 (%2): %3', name _player, getPlayerUID _player, _text]] call EPOCH_fnc_server_hiveLog; + "+_skn_pv_hackerLog+" pushBack[[1, call "+_skn_server_getRealTime+", name _player, getPlayerUID _player, _text], []]; + }; + }; + { + if (_x call EPOCH_server_isPAdmin) then { + (owner _x) publicVariableClient '"+_skn_pv_hackerLog+"'; + }; + }forEach playableUnits; +};"); +//0 = BAN +//1 = LOG +//[2,varname] = Self-learning vars from trusted users. + +_skn_code_ban = compileFinal (" + _this set [0,toArray (_this select 0)]; + _this pushBack player; + _this pushBack Epoch_personalToken; + "+_skn_doKickBan+" = _this; + publicVariableServer '"+_skn_doKickBan+"'; + true +"); +_skn_code_init = compileFinal (" + comment 'Epoch Mod Antihack - Niklas Wagner - www.skaronator.com - Aaron Clark - www.epochmod.com - License: (CC) Attribution-NonCommercial-NoDerivatives 4.0 International'; + waitUntil {(getPlayerUID player) != ''}; + _start = diag_tickTime; + waitUntil {!isNil '"+_skn_AH_Code+"' || (diag_tickTime-_start > 20)}; + if (isNil '"+_skn_AH_Code+"') exitWith { + "+_skn_doKickBan+" = [format['Cannot Load AH [%1,%2]',!isNil '"+_skn_AH_Code_CA+"',!isNil '"+_skn_AH_Code_CB+"'],1,player,Epoch_personalToken]; + publicVariableServer '"+_skn_doKickBan+"'; + (findDisplay 46) closeDisplay 0 + }; + [] spawn "+_skn_AH_Code+"; + uiSleep 3; + if ((isNil '"+_skn_AH_Code_CA+"') || (isNil '"+_skn_AH_Code_CB+"')) then { + uiSleep 5; + if ((isNil '"+_skn_AH_Code_CA+"') || (isNil '"+_skn_AH_Code_CB+"')) then { + [] spawn "+_skn_AH_Code+"; + uiSleep 3; + }; + }; + uiSleep 5; + if ((isNil '"+_skn_AH_Code_CA+"') || (isNil '"+_skn_AH_Code_CB+"')) then { + "+_skn_doKickBan+" = [format['Cannot Load AH [%1,%2]',!isNil '"+_skn_AH_Code_CA+"',!isNil '"+_skn_AH_Code_CB+"'],1,player,Epoch_personalToken]; + publicVariableServer '"+_skn_doKickBan+"'; + (findDisplay 46) closeDisplay 0 + }; + "); +_skn_code_antihack = compileFinal (" + comment 'Epoch Mod Antihack - Niklas Wagner - www.skaronator.com - Aaron Clark - www.epochmod.com - License: (CC) Attribution-NonCommercial-NoDerivatives 4.0 International'; + if ((!isNil '"+_skn_AH_Code_CA+"') && (!isNil '"+_skn_AH_Code_CB+"')) exitWith {}; + "+_skn_AH_Code_CA+" = true; + "+_skn_addonCheckCode+" + _t = '"+_skn_t1+"'; + [] spawn { + uiSleep 5; + FW"+_skn_AH_rndVar+" = ''; + FA"+_skn_AH_rndVar+" = 0; + FWC"+_skn_AH_rndVar+" = 0; + _sknOnFire = { + _wep = _this select 1; + _ammo = player ammo _wep; + if !(_wep in ['Throw','Put']) then { + if (FW"+_skn_AH_rndVar+" == _wep && FA"+_skn_AH_rndVar+" == _ammo) then { + if (FWC"+_skn_AH_rndVar+" > 1) then { + [format['[TEST] Unlimited Ammo: [%1,%2]', _wep, _ammo], 1] call "+_skn_AH_Ban+"; + [] spawn {uiSleep 60;FWC"+_skn_AH_rndVar+" = 0}; + }; + FWC"+_skn_AH_rndVar+" = FWC"+_skn_AH_rndVar+" +1; + [] spawn {uiSleep 20;FWC"+_skn_AH_rndVar+" = 0}; + }; + }; + FA"+_skn_AH_rndVar+" = _ammo; + FW"+_skn_AH_rndVar+" = _wep; + true + }; + + uiNamespace setVariable['RscDisplayRemoteMissions',displayNull]; + uiNamespace setVariable['RscDisplayArsenal',displayNull]; + missionnamespace setVariable['BIS_fnc_showNotification_queue',nil]; + while {true} do { + { + if (!isNull (_x select 0)) then { + [format['Menu: %1',_x select 1],0] call "+_sknBanANDSleep+"; + }; + }forEach[ + [(findDisplay 64) displayCtrl 1002,'findDisplay 64'], + [(findDisplay 49) displayCtrl 0,'findDisplay 49'], + [uiNamespace getVariable 'RscDisplayRemoteMissions','RscDisplayRemoteMissions'], + [uiNamespace getVariable 'RscDisplayArsenal','RscDisplayArsenal'], + [missionnamespace getvariable 'BIS_fnc_showNotification_queue','showNotification'] + ]; + { + if (!isNull (findDisplay _x)) then { + [format['Menu: findDisplay %1',_x],0] call "+_sknBanANDSleep+"; + }; + }forEach "+str _skn_badDisplaysArray+"; + if (!isNull (uiNamespace getVariable 'RscDisplayConfigureAction')) then { + _ctrlTxt = toLower ctrlText 1000; + if (_ctrlTxt != '') then { + if (_ctrlTxt != toLower localize 'STR_A3_RscDisplayConfigureAction_Title') then { + [format['Menu: RscDisplayConfigureAction-A %1',_ctrlTxt],0] call "+_sknBanANDSleep+"; + }; + }; + { + if (buttonAction _x != '') then { + [format['Menu: RscDisplayConfigureAction-B (%1)',_x],0] call "+_sknBanANDSleep+"; + }; + }forEach [1,104,105,106,107,108,109]; + }; + if (!isNull (uiNamespace getVariable 'RscDisplayInsertMarker')) then { + _ctrlTxt = toLower ctrlText 1001; + if (_ctrlTxt != '') then { + if (_ctrlTxt != toLower localize 'STR_A3_RscDisplayInsertMarker_Title') then { + [format['Menu: RscDisplayInsertMarker-A %1',_ctrlTxt],0] call "+_sknBanANDSleep+"; + }; + }; + if ((buttonAction 1 != '') || (buttonAction 2 != '')) then { + [format['Menu: RscDisplayInsertMarker-B [%1,%2]',buttonAction 1,buttonAction 2],0] call "+_sknBanANDSleep+"; + }; + }; + if (!isNull (findDisplay 129)) then {closeDialog 0}; + + if !(commandingMenu in "+str _skn_commandMenuArray+") then { + [format['Menu: commandMenu: %1',commandingMenu],0] call "+_sknBanANDSleep+"; + }; + + onMapSingleClick ''; + player allowDamage true; + vehicle player allowDamage true; + onEachFrame EPOCH_onEachFrame; + + _addCase = addMissionEventHandler ['Draw3D', {}]; + removeMissionEventHandler ['Draw3D',0]; + if (_addCase > 0) then { + [format['MEH: Draw3D %1',_addCase],0] call "+_sknBanANDSleep+"; + }; + + { + _ehKey = _x select 0; + if (_x select 2) then { + player removeEventHandler [_ehKey, 0]; + }; + _ehCode = _x select 1; + if (_ehKey == 'Fired') then {_ehCode = (_ehCode + '_this call '+str(_sknOnFire)) }; + _addCase = player addEventHandler [_ehKey, _ehCode]; + if !(_x select 2) then { + player removeEventHandler [_ehKey, 0]; + }; + if (_addCase > 0) then { + [format['EH: %1 %2',_ehKey,_addCase],0] call "+_sknBanANDSleep+"; + }; + } forEach "+str _skn_addEHArray+"; + + uiSleep 0.01; + }; + }; + _t = _t + '"+_skn_t2+"'; + [] spawn { + disableSerialization; + _ActionCount = -1; + _ActionVehicle = player; + _displayCountKD = 0; + _displayCount = 0; + _personalToken = Epoch_personalToken; + _antiWallCount = 0; + waitUntil{!isNull (findDisplay 46)}; + setViewDistance "+str _skn_viewDistance+"; + setObjectViewDistance["+str _skn_viewDistanceObects+", 100]; + setTerrainGrid "+str _skn_terrainGrid+"; + uiSleep 5; + while {true} do { + if (isNil 'Epoch_personalToken') then { + "+_skn_doKickBan+" = [format['personalToken NIL: %1/%2',Epoch_personalToken,_personalToken],0,player,_personalToken]; + publicVariableServer '"+_skn_doKickBan+"'; + uiSleep 60; + }; + { + if (isNil _x) then { + [format['%1: nil',_x],0] call "+_sknBanANDSleep+"; + }; + }forEach "+str _skn_nilVarCheckArray+"; + if !(groupIconsVisible isEqualTo [false,false]) then { + [format['GroupIcons %1',groupIconsVisible],0] call "+_sknBanANDSleep+"; + }; + if (unitRecoilCoefficient player != 1) then { + [format['Recoil %1',unitRecoilCoefficient player],0] call "+_sknBanANDSleep+"; + }; + if (animationState player in "+str _skn_badAnimations+") then { + [format['BadMove: %1',animationState player],0] call "+_sknBanANDSleep+"; + }; + if (EPOCH_playerEnergy > 2500 || EPOCH_playerEnergy < 0) then { + [format['Energy: %1',EPOCH_playerEnergy],0] call "+_sknBanANDSleep+"; + }; + if (EPOCH_playerHunger > 5000 || EPOCH_playerHunger < 0) then { + [format['Hunger: %1',EPOCH_playerHunger],0] call "+_sknBanANDSleep+"; + }; + if (EPOCH_playerThirst > 2500 || EPOCH_playerThirst < 0) then { + [format['Thirsk: %1',EPOCH_playerThirst],0] call "+_sknBanANDSleep+"; + }; + if (EPOCH_playerStamina > 2500 || EPOCH_playerStamina < 0) then { + [format['Stamina: %1',EPOCH_playerStamina],0] call "+_sknBanANDSleep+"; + }; + if (EPOCH_playerCrypto > "+str _skn_playerCryptoLimit+" || EPOCH_playerCrypto < 0) then { + [format['Crypto: %1',EPOCH_playerCrypto],0] call "+_sknBanANDSleep+"; + }; + if (_antiWallCount != EPOCH_antiWallCount) then { + if (_antiWallCount > EPOCH_antiWallCount) then { + [format['antiWall: %1/%2',EPOCH_antiWallCount,_antiWallCount],0] call "+_sknBanANDSleep+"; + }; + _antiWallCount = EPOCH_antiWallCount; + }; + if (EPOCH_target isEqualTo player) then { + [format['setVelocityTarget: %1', EPOCH_target], 0] call "+_sknBanANDSleep+"; + }; + if !(EPOCH_ESP_TARGETS isEqualTo []) then { + [format['ESP-O: %1', EPOCH_ESP_TARGETS], 0] call "+_sknBanANDSleep+"; + }; + if !(EPOCH_ESPMAP_TARGETS isEqualTo []) then { + [format['MAP-ESP: %1', EPOCH_ESPMAP_TARGETS], 0] call "+_sknBanANDSleep+"; + }; + if !(EPOCH_ESP_VEHICLEPLAYER isEqualTo []) then { + [format['ESP-N: %1', EPOCH_ESP_VEHICLEPLAYER], 0] call "+_sknBanANDSleep+"; + }; + if (EPOCH_ESP_PLAYER || EPOCH_ESP_VEHICLES) then { + [format['ESP-N: %1', EPOCH_ESP_VEHICLES], 0] call "+_sknBanANDSleep+"; + }; + if (EPOCH_taxRate != "+str EPOCH_taxRate+") then { + [format['taxTate: %1',EPOCH_taxRate],0] call "+_sknBanANDSleep+"; + }; + if !(EPOCH_group_upgrade_lvl isEqualTo "+str EPOCH_group_upgrade_lvl+") then { + [format['groupUpgradeLvL: %1',EPOCH_group_upgrade_lvl],0] call "+_sknBanANDSleep+"; + }; + if (viewDistance != "+str _skn_viewDistance+") then{ + [format['viewDistance %1',viewDistance],0] call "+_sknBanANDSleep+"; + }; + "+_sknAddActionCheck+" + _display46 = findDisplay 46; + if !(isNull _display46) then { + _display46 displayRemoveAllEventHandlers 'KeyDown'; + _addCase = _display46 displayAddEventHandler ['KeyDown',{"+_skn_displayAddEHKeyDown+"}]; + if (_addCase != _displayCountKD) then { + [format['DEH: KeyDown %1/%2',_addCase,_displayCountKD],0] call "+_sknBanANDSleep+"; + }; + _display46 displayRemoveAllEventHandlers 'KeyUp'; + _addCase = _display46 displayAddEventHandler ['KeyUp',{"+_skn_displayAddEHKeyUp+"}]; + if (_addCase != _displayCount) then { + [format['DEH: KeyUp %1/%2',_addCase,_displayCount],0] call "+_sknBanANDSleep+"; + }; + }; + uiSleep ((random 1)+1); + }; + }; + _t = _t + '"+_skn_t3+"'; + [] spawn { + _cntBan = 0; + while {true} do { + _lastTime = diag_tickTime; + _lastPos = getPosATL vehicle player; + _notNearbySpawn = _lastPos distance "+str _skn_spawnPointCenter+" > "+str _centerDistance+"; + while {alive player} do { + _curTime = diag_tickTime; + _curPos = getPosATL vehicle player; + _distance = _lastPos distance _curPos; + + if ((_curTime-_lastTime)>1 || _distance>10) then { + if (((_distance/(_curTime-_lastTime)) > 10) && _notNearbySpawn && (player == vehicle player)) then { + if (isNil '"+_skn_antiTeleportPVC+"') then { + [format['[TEST] TP from %1 to %2, %3 meters, now at %4', _lastPos, _curPos, round _distance, getPosATL player],1] call "+_sknBanANDSleep+"; + vehicle player setPosATL _lastPos; + _cntBan = _cntBan + 1; + if (_cntBan > 4) then { + + }; + } else { + uiSleep 10; + _lastPos = getPosATL vehicle player; + _lastTime = diag_tickTime; + _notNearbySpawn = false; + }; + } else { + _lastPos = _curPos; + _lastTime = _curTime; + _notNearbySpawn = _lastPos distance "+str _skn_spawnPointCenter+" > "+str _centerDistance+"; + }; + }; + }; + uiSleep 0.1; + }; + uiSleep 0.25; + }; + _t = _t + '"+_skn_t4+"'; + [] spawn { + uiNamespace setVariable['ESP_mainMap', nil]; + uiNamespace setVariable['ESP_adminMap', nil]; + while {true} do { + { + _badVar = _x; + { + _var = _x getVariable _badVar; + if (!isNil '_var') then { + [format['BadVar %1=%2 (%3)',_badVar,_var,_forEachIndex],0] call "+_sknBanANDSleep+"; + _x setVariable [_badVar,nil]; + }; + }forEach [missionNamespace, parsingNamespace, uiNamespace]; + }forEach "+str _skn_badVarCheckArray+"; + "+_skn_fileCheckCode+" + { + _display = _x select 0; + _displayCheckOkay = false; + { + if ((getText(configFile>>_display>>'onLoad'))==_x) exitWith { _displayCheckOkay = true }; + }forEach (_x select 1); + if (!_displayCheckOkay) then { + [format['Changed %1 >> onLoad >> %2', _display, getText(configFile>>_display>>'onLoad')],0] call "+_sknBanANDSleep+"; + _displayCheckOkay = false; + }; + { + if ((getText(configFile>>_display>>'onUnload'))==_x) exitWith { _displayCheckOkay = true }; + }forEach (_x select 2); + if (!_displayCheckOkay) then { + [format['Changed %1 >> onUnload >> %2', _display, getText(configFile>>_display>>'onUnload')],0] call "+_sknBanANDSleep+"; + } + }forEach "+str _cfg_displayArray+"; + "+_sknCustomVarCheckCode+" + uiSleep ((random 10)+10); + }; + }; + _t = _t + '"+_skn_t5+"'; + "+_skn_doTokenAuth+" = [_t,player,Epoch_personalToken]; + publicVariableServer '"+_skn_doTokenAuth+"'; + "+_skn_doTokenAuth+" = nil; + '"+_skn_kickToLobby+"' addPublicVariableEventHandler { + [] spawn {waitUntil {(findDisplay 46) closeDisplay 0; false}} + }; + "+_skn_AH_Code_CB+" = true; + true +"); + +call compile (_skn_AH_Ban+" = _skn_code_ban;publicVariable '"+_skn_AH_Ban+"'"); +call compile (_skn_AH_Code+" = _skn_code_antihack;publicVariable '"+_skn_AH_Code+"'"); +call compile (_skn_AH_Init+" = _skn_code_init;publicVariable '"+_skn_AH_Init+"'"); +/*********************************************** ADMIN MENU *****************************************************/ +/*********************************************** ADMIN MENU *****************************************************/ +/*********************************************** ADMIN MENU *****************************************************/ +/*********************************************** ADMIN MENU *****************************************************/ +/*********************************************** ADMIN MENU *****************************************************/ +call compile (" + "+_skn_pv_adminLog+" = []; + "+_skn_pv_hackerLog+" = []; + "+_skn_server_adminLog+" = { + _toggle = ' -----'; + if ((_this select 1) != 0) then { + _toggle = if ((_this select 1) == 2) then {' -ON-'} else {'-OFF-'}; + }; + _adminUID = getPlayerUID _admin; + _adminNAME = "+str _skn_adminNAMEArray+" select ("+str _skn_adminUIDArray+" find _adminUID); + ['aml', format['%1 (%2): [%4] %3',_adminNAME,_adminUID,_this select 0,_toggle]] call EPOCH_fnc_server_hiveLog; + + "+_skn_pv_adminLog+" pushBack [call "+_skn_server_getRealTime+",_adminNAME,_toggle,_this select 0]; + diag_log format ['SKN2 AdminRequest %1',"+_skn_pv_adminLog+"]; + { + if (_x call EPOCH_server_isPAdmin) then { + (owner _x) publicVariableClient '"+_skn_pv_adminLog+"'; + }; + }forEach playableUnits; + true + }; +"); +//[text,toggle,admin,token] +//toggle: 0:NOTHING 1:OFF 2:ON +call compile ("'"+_skn_doAdminLog+"' addPublicVariableEventHandler { + _array = _this select 1; + diag_log format ['SKN AdminLog %1',_array]; + _admin = _array select 2; + + if !([_admin,_array select 3] call EPOCH_server_getPToken) exitWith {}; + if !(_admin call EPOCH_server_isPAdmin) exitWith {}; + [_array select 0,_array select 1] call "+_skn_server_adminLog+"}; +"); +//[case,[contentarray],player,token] +call compile ("'"+_skn_doAdminRequest+"' addPublicVariableEventHandler { + _array = _this select 1; + diag_log format ['SKN AdminRequest %1',_array]; + _admin = _array select 2; + + if !([_admin,_array select 3] call EPOCH_server_getPToken) exitWith {}; + if !(_admin call EPOCH_server_isPAdmin) exitWith {}; + + _case = _array select 0; + _content = _array select 1; + + if (_case == 100) then { + _playerObj = objectFromNetId _content; + [format['Kill Target: %1 (%2)',name _playerObj,getPlayerUID _playerObj],0] call "+_skn_server_adminLog+"; + _playerObj setDamage 1; + }; + if (_case == 101) then { + _playerObj = objectFromNetId _content; + "+_skn_antiTeleportPVC+" = true; + (owner _playerObj) publicVariableClient '"+_skn_antiTeleportPVC+"'; + [format['Teleport To Admin: %1 (%2)', name _playerObj, getPlayerUID _playerObj], 0] call "+_skn_server_adminLog+"; + [vehicle _playerObj,_admin] spawn { + uiSleep 0.5; + (_this select 0) setPos ((_this select 1) modelToWorld [0,1,0]); + (_this select 0) setDir (getDir (_this select 1)); + }; + }; + if (_case == 102) then { + _playerObj = objectFromNetId _content; + _behindM = if (vehicle _playerObj == _playerObj) then [{-1},{-5}]; + + vehicle _admin setPos (_playerObj modelToWorld [0,_behindM,0]); + vehicle _admin setDir (getDir _playerObj); + [format['Teleport Admin To: %1 (%2)', name _playerObj, getPlayerUID _playerObj], 0] call "+_skn_server_adminLog+"; + }; + if (_case == 103) then { + _playerObj = objectFromNetId _content; + _playerObj setDamage 0; + [['healPlayer'], owner _playerObj] call EPOCH_sendPublicVariableClient; + if (_playerObj == _admin) then { + ['Healed Self',0] call "+_skn_server_adminLog+"; + } else { + [format['Heal Target: %1 (%2)',name _playerObj,getPlayerUID _playerObj],0] call "+_skn_server_adminLog+"; + } + }; + if (_case == 104) then { + if ((_content isKindOf 'LandVehicle') || (_content isKindOf 'Air') || (_content isKindOf 'Ship') || (_content isKindOf 'Tank')) then { + [_content, _admin] call EPOCH_server_save_killedVehicle; + } else { + if (typeOf _content in ['LockBoxProxy_EPOCH'] || (_content isKindOf 'Buildable_Storage')) then { + [_content, _admin] call EPOCH_server_save_killedStorage; + } else { + [_content, _admin] call EPOCH_server_save_killedBuilding; + }; + }; + [format['Delete: %1 at [%2]',typeOf _content, getPos _content],0] call "+_skn_server_adminLog+"; + deleteVehicle _content; + }; + if (_case == 106) then { + _admin hideObjectGlobal _content; + }; + if (_case == 107) then { + _player = objectFromNetId (_content select 0); + if (!isNull _player) then { + _cIndex = EPOCH_customVars find 'Crypto'; + _vars = _player getVariable['VARS', [] + EPOCH_defaultVars_SEPXVar]; + _current_crypto = (((_vars select _cIndex) + (_content select 1)) min "+str _skn_playerCryptoLimit+") max 0; + [['effectCrypto', _current_crypto], (owner _player)] call EPOCH_sendPublicVariableClient; + _vars set[_cIndex, _current_crypto]; + _player setVariable['VARS', _vars]; + if (_player == _admin) then { + [format['Give Crypto Myself: %1',_content select 1],0] call "+_skn_server_adminLog+"; + } else { + [format['Give Crypto to %1 (%2): %3',name _player,getPlayerUID _player,_content select 1],0] call "+_skn_server_adminLog+"; + } + }; + }; + if (_case == 108) then { + if (!isNull _content) then { + [format['Repaire Vehicle: %1',typeOf _content],0] call "+_skn_server_adminLog+"; + _content setDamage 0; + diag_log format ['Debug-Vehicle: Repair: 108,%1',_content]; + if (local _content) then { + _content setFuel 1; + } else { + [['fillVehicle', [_content, 1]], owner _admin] call EPOCH_sendPublicVariableClient; + }; + _content call EPOCH_server_save_vehicle; + }; + }; + if (_case == 109) then { + if (surfaceIsWater _content) then [{vehicle _admin setPosASL _content},{vehicle _admin setPosATL _content}]; + }; + if (_case == 200) then { + _playerObj = objectFromNetId _content; + _weaponClass = currentWeapon _playerObj; + _mags = getArray(configFile >> 'CfgWeapons' >> _weaponClass >> 'magazines'); + if !(_mags isEqualTo[]) then { + _firstMag = _mags select 0; + _magazineSizeMax = getNumber(configFile >> 'CfgMagazines' >> _firstMag >> 'count'); + _playerObj addMagazine[_firstMag, _magazineSizeMax]; + if (_playerObj == _admin) then { + [format['Gave Ammo (%1) to Self', _firstMag], 0] call "+_skn_server_adminLog+"; + } else { + [format['Gave Ammo (%3) to Target: %1 (%2)', name _playerObj, getPlayerUID _playerObj, _firstMag], 0] call "+_skn_server_adminLog+"; + }; + }; + }; + if (_case == 555) then { + _target = objectFromNetId (_content select 1); + + _itemSpawner = { + _nearbyWH = objNull; + if (vehicle _target != _target) then { + _nearbyWH = vehicle _target; + } else { + _nearbyWHArr = nearestObjects[_target, ['groundWeaponHolder'], 2]; + if !(_nearbyWHArr isEqualTo[]) then { + _nearbyWH = _nearbyWHArr select 0; + } else { + _posWH = getposATL _target; + _nearbyWH = createVehicle['groundWeaponHolder', _posWH, [], 0, 'CAN_COLLIDE']; + _nearbyWH setPosATL _posWH; + }; + }; + if !(isNull _nearbyWH) then { + switch (_this select 1) do { + case 1: { _nearbyWH addMagazineCargoGlobal[(_this select 0), 1] }; + case 2: { _nearbyWH addWeaponCargoGlobal[(_this select 0), 1] }; + case 3: { _nearbyWH addItemCargoGlobal[(_this select 0), 1] }; + case 4: { _nearbyWH addBackpackCargoGlobal[(_this select 0), 1] }; + }; + }; + }; + + _permVehicleSpawner = { + _item = _this; + _return = false; + if (_item isKindOf 'Air' || _item isKindOf 'Ship' || _item isKindOf 'LandVehicle') then { + if !(EPOCH_VehicleSlots isEqualTo[]) then { + _position = getPosATL _target; + + _slot = EPOCH_VehicleSlots select 0; + EPOCH_VehicleSlots = EPOCH_VehicleSlots - [_slot]; + EPOCH_VehicleSlotCount = count EPOCH_VehicleSlots; + publicVariable 'EPOCH_VehicleSlotCount'; + + _vehObj = createVehicle[_item, _position, [], 20, 'NONE']; + _return = true; + _vehObj call EPOCH_server_setVToken; + addToRemainsCollector[_vehObj]; + + _vehObj disableTIEquipment true; + + clearWeaponCargoGlobal _vehObj; + clearMagazineCargoGlobal _vehObj; + clearBackpackCargoGlobal _vehObj; + clearItemCargoGlobal _vehObj; + _vehObj lock true; + + _plyrUID = getPlayerUID _target; + _plyrGroup = _target getVariable['GROUP', '']; + + _lockOwner = _plyrUID; + if (_plyrGroup != '') then { + _lockOwner = _plyrGroup; + }; + + _vehLockHiveKey = format['%1:%2', (call EPOCH_fn_InstanceID), _slot]; + ['VehicleLock', _vehLockHiveKey, EPOCH_vehicleLockTime, [_lockOwner]] call EPOCH_fnc_server_hiveSETEX; + + _config = (configFile >> 'CfgVehicles' >> _item >> 'availableColors'); + if (isArray(_config)) then { + _textureSelectionIndex = configFile >> 'CfgVehicles' >> _item >> 'textureSelectionIndex'; + _selections = if (isArray(_textureSelectionIndex)) then {getArray(_textureSelectionIndex)} else {[0]}; + _colors = getArray(_config); + _textures = _colors select 0; + _color = floor(random(count _textures)); + _count = (count _colors) - 1; + { + if (_count >= _forEachIndex) then { + _textures = _colors select _forEachIndex; + }; + _vehObj setObjectTextureGlobal[_x, (_textures select _color)]; + } forEach _selections; + _vehObj setVariable['VEHICLE_TEXTURE', _color]; + }; + + _vehObj setVariable['VEHICLE_SLOT', _slot, true]; + _vehObj call EPOCH_server_save_vehicle; + _vehObj call EPOCH_server_vehicleInit; + } else { + diag_log 'ADMIN: Unable to spawn vehicle, no slots available'; + }; + }; + _return + }; + + _allClasses = []; + { + _classname = _x select 0; + _allClasses pushBack _classname; + _type = _x select 1; + if (_type in [0,1,2]) then {_classname call _permVehicleSpawner}; + if (_type in [3,4,5]) then {[_classname,2] call _itemSpawner}; + if (_type in [6,7]) then {[_classname,1] call _itemSpawner}; + if (_type == 8) then {[_classname,4] call _itemSpawner}; + if (_type == 9) then {[_classname,3] call _itemSpawner}; + }forEach (_content select 0); + + if (_target == _admin) then { + [format['Spawn: %1',_allClasses], 0] call "+_skn_server_adminLog+"; + } else { + [format['Spawn Target: %1 (%2) %3', name _target, getPlayerUID _target, _allClasses], 0] call "+_skn_server_adminLog+"; + }; + }; + if (_case == 666) then { + _playerObj = objectFromNetId (_content select 1); + _banID = 0; + 'epochserver' callExtension format['820|%1|"+_skn_banReason+" #%2',getPlayerUID _playerObj,_banID]; + ['amb', format['%1 (%2): %3', name _playerObj, getPlayerUID _playerObj, _content select 0]] call EPOCH_fnc_server_hiveLog; + }; +};"); + +_skn_admincode = compileFinal (" + comment 'Epoch Mod Antihack - Niklas Wagner - www.skaronator.com - Aaron Clark - www.epochmod.com - License: (CC) Attribution-NonCommercial-NoDerivatives 4.0 International'; + waitUntil {(getPlayerUID player) != ''}; + "+_skn_tg_sortOrder+" = 'Range'; + "+_skn_tg_toggle+" = []; + "+_skn_tg_BanPlayer+" = objNull; + "+_skn_tg_delete+" = objNull; + "+_skn_tg_mapTeleport+" = false; + "+_skn_tg_old_esp+" = false; + "+_skn_tg_godMode+" = false; + "+_skn_tg_old_espMap+" = false; + "+_skn_tg_spawnTyp+" = 64; + "+_skn_tg_hideAdmin+" = false; + "+_skn_tg_infrontTP+" = false; + + "+_skn_tg_map_player+" = false; + "+_skn_tg_map_corpse+" = false; + "+_skn_tg_map_loot+" = false; + "+_skn_mapLootArray+" = []; + "+_skn_tg_map_vehicle+" = false; + "+_skn_tg_map_ai+" = false; + "+_skn_tg_map_basebuilding+" = false; + + uiNamespace setVariable['ESP_mainMap', findDisplay 12 displayCtrl 51]; + uiNamespace setVariable['ESP_adminMap', findDisplay -1337 displayCtrl 7]; + (findDisplay 46) displayAddEventHandler ['KeyDown','_this call "+_skn_AdminKeyDown+"']; + ((findDisplay 12) displayCtrl 51) ctrlAddEventHandler ['MouseButtonDown', 'if (_this select 5) then {_this call "+_skn_mapTeleport+"}']; + + { + (uiNamespace getVariable _x) ctrlRemoveAllEventHandlers 'Draw'; + (uiNamespace getVariable _x) ctrlAddEventHandler['Draw',{ + + _getDmgColor = { + _color = [1,1,1,1]; + _dmg = damage _this; + if (_dmg >= 0.25) then {_color = [1,1,0,1]; + if (_dmg >= 0.5) then { _color = [1,0.55,0,1]; + if (_dmg >= 0.75) then { _color = [1,0,0,1]; + if (_dmg >= 0.9) then { _color = [0,0,0,1]; + }; + }; + }; + }; + _color + }; + _display = _this select 0; + if ("+_skn_tg_map_player+") then { + _size = (0.5/ctrlMapScale _display) max 20; + { + if (isPlayer _x) then { + _display drawIcon [ + getText (configFile >> 'CfgVehicles' >> typeOf _x >> 'Icon'), _x call _getDmgColor, visiblePosition _x, _size, _size, getDir _x, name _x + ]; + }; + }forEach playableUnits; + }; + if ("+_skn_tg_map_corpse+") then { + _size = (1/ctrlMapScale _display) max 20; + { + if (!isNull _x) then { + _color = [1,1,1,1]; + _display drawIcon [ + getText (configFile >> 'CfgVehicles' >> typeOf _x >> 'Icon'), _color, visiblePosition _x, _size, _size, getDir _x, typeOf _x + ]; + }; + }forEach allDeadMen; + }; + if ("+_skn_tg_map_loot+") then { + { + if (!isNull _x) then { + _color = [1,1,1,1]; + _display drawRectangle [ + visiblePosition _x, + 5, + 5, + getDir _x, + [1,1,1,1], + '#(rgb,8,8,3)color(1,0,0,1)' + ]; + }; + }forEach "+_skn_mapLootArray+"; + }; + if ("+_skn_tg_map_vehicle+") then { + _size = (1/ctrlMapScale _display) max 20; + { + if (alive _x) then { + _display drawIcon [ + getText (configFile >> 'CfgVehicles' >> typeOf _x >> 'Icon'), _x call _getDmgColor, visiblePosition _x, _size, _size, getDir _x, + getText (configFile >> 'CfgVehicles' >> typeOf _x >> 'displayName') + ]; + }; + }forEach vehicles; + }; + if ("+_skn_tg_map_ai+") then { + _size = (0.5/ctrlMapScale _display) max 20; + { + if (isPlayer _x) then { + _display drawIcon [ + getText (configFile >> 'CfgVehicles' >> typeOf _x >> 'Icon'), _x call _getDmgColor, visiblePosition _x, _size, _size, getDir _x, + getText (configFile >> 'CfgVehicles' >> typeOf _x >> 'displayName') + ]; + }; + }forEach allUnits-playableUnits; + }; + if ("+_skn_tg_map_basebuilding+") then { + + }; + if ("+_skn_tg_old_espMap+") then { + { + if !(isNull _x) then { + _pos = visiblePosition _x; + if (isPlayer _x) then { + _lastPos = _x getVariable['ESP_old_MAP', []]; + _playerGrp = group _x; + _grpColorIndex = EPOCH_ESPGROUPS find _playerGrp; + if (_grpColorIndex == -1) then { + EPOCH_ESPGROUPCOLORS pushBack[random 1, random 1, random 1, 1]; + _grpColorIndex = EPOCH_ESPGROUPS pushBack _playerGrp; + }; + _color = EPOCH_ESPGROUPCOLORS select _grpColorIndex; + (_this select 0) drawIcon[getText(configFile >> 'CfgVehicles' >> typeOf(vehicle _x) >> 'Icon'), _color, _pos, 0.5 / ctrlMapScale(_this select 0), 0.5 / ctrlMapScale(_this select 0), getDir _x, name _x, 1, 0.05, 'PuristaMedium']; + if ((count _lastPos) >= 100) then { + for '_i' from 10 to 100 step 10 do { + _pos1 = _lastPos select(_i - 10); + _pos2 = _lastPos select _i; + if (!isNil '_pos1' && !isNil '_pos2') then { + (_this select 0) drawLine[_pos1, _pos2, [1, 0, 0, 1]]; + }; + }; + }; + }; + }; + }forEach EPOCH_ESPMAP_TARGETS; + }; + }]; + }forEach ['ESP_mainMap','ESP_adminMap']; + "+_skn_adminRequest_PVC+" = { + _this pushBack player; + _this pushBack Epoch_personalToken; + "+_skn_doAdminRequest+" = _this; + publicVariableServer '"+_skn_doAdminRequest+"'; + }; + "+_skn_adminLog_PVC+" = { + _this pushBack player; + _this pushBack Epoch_personalToken; + "+_skn_doAdminLog+" = _this; + publicVariableServer '"+_skn_doAdminLog+"'; + }; + "+_skn_AdminKeyDown+" = { + _keyDown = _this select 1; + if (_keyDown == "+str _skn_adminMenuMenuKey+") then {call "+_skn_AdminMenu_Init+"}; + if (_keyDown == 0x3C) then {if (cameraOn != vehicle player) then { vehicle player switchCamera 'External' } }; + if (_keyDown == "+str _skn_adminMenuInfrontTeleport+") then {call "+_skn_infrontTP+"}; + if (_keyDown == 0x3F) then {call "+_skn_delete+"}; + }; + "+_skn_AdminMenu_Init+" = { + disableSerialization; + _hours = floor(servertime/60/60); + _minutes = round((serverTime/60)-(_hours*60)); + + if (!dialog) then {createDialog 'Skaronator_AdminMenu'; + {(_x call "+_skn_getCtrl+") ctrlShow false}forEach[40,41,42,43,50,51,52,60,61,62,63,64,65,66,67,68,69,70,71] }; + if (getPlayerUID player in "+str _skn_blockedSpawnMenuUID+") then {ctrlEnable [21,false]}; + ctrlEnable [22,false]; + (1 call "+_skn_getCtrl+") ctrlSetText format['Players %1 of %2',count playableUnits,playersNumber civilian]; + (2 call "+_skn_getCtrl+") ctrlSetText format['Epoch Mod Admin Menu by Skaronator.com - Server Uptime: %1h %2min', _hours, _minutes]; + (5 call "+_skn_getCtrl+") ctrlSetEventHandler ['LBDblClick', '_this call "+_skn_fnc_Spec+"']; + (6 call "+_skn_getCtrl+") ctrlSetEventHandler ['LBDblClick', '_this call "+_skn_dbClickMainMenu+"']; + (7 call "+_skn_getCtrl+") ctrlSetEventHandler ['MouseButtonDown', 'if (_this select 5) then {_this call "+_skn_mapTeleport+"}']; + if (call "+_skn_removespawnMenu+") then {uiSleep 0.4}; + + call "+_skn_Update_AdminButtons+"; + _menu = call "+_skn_mainMenuCfg+"; + _menu call "+_skn_FillMainMenu+"; + call "+_skn_FillPlayerMenu+"; + 0 call "+_skn_switchMainMenu+"; + }; + "+_skn_hideAdmin+" = { + "+_skn_tg_hideAdmin+" = !"+_skn_tg_hideAdmin+"; + [106, "+_skn_tg_hideAdmin+"] call "+_skn_adminRequest_PVC+"; + }; + "+_skn_esp+" = { + _enable = false; + if (_this) then { + EPOCH_ESP_PLAYER = !EPOCH_ESP_PLAYER; + if (EPOCH_ESP_PLAYER) then { + ['Player ESP',2] call "+_skn_adminLog_PVC+"; + _enable = true + } else { + ['Player ESP',1] call "+_skn_adminLog_PVC+"; + } + } else { + EPOCH_ESP_VEHICLES = !EPOCH_ESP_VEHICLES; + if (EPOCH_ESP_VEHICLES) then { + ['Vehicle ESP',2] call "+_skn_adminLog_PVC+"; + _enable = true + } else { + ['Vehicle ESP',1] call "+_skn_adminLog_PVC+"; + } + }; + + if (EPOCH_ESP_VEHICLEPLAYER isEqualTo [] && _enable) then { + waitUntil { + EPOCH_ESP_VEHICLEPLAYER = (cameraOn nearEntities [['Epoch_Male_F', 'Epoch_Female_F', 'LandVehicle', 'Ship', 'Air', 'Tank'], viewDistance max 1000 min 2500]) - [vehicle player]; + uiSleep 1; + !EPOCH_ESP_PLAYER && !EPOCH_ESP_VEHICLES + }; + EPOCH_ESP_VEHICLEPLAYER = []; + }; + }; + "+_skn_godMode+" = { + "+_skn_tg_godMode+" = !"+_skn_tg_godMode+"; + if ("+_skn_tg_godMode+") then { + ['God Mode',2] call "+_skn_adminLog_PVC+"; + waitUntil { + player setBleedingRemaining 0; + player setOxygenRemaining 1; + player allowDamage false; + { + missionNamespace setVariable[format['EPOCH_player%1', _x], EPOCH_defaultVars select(EPOCH_customVars find _x)] + } forEach['Temp','Hunger','Thirst','Toxicity','Stamina','HitPoints','BloodP']; + EPOCH_playerEnergy = EPOCH_playerEnergyMax; + uiSleep 0.25; + !"+_skn_tg_godMode+" + }; + player allowDamage true; + } else { + ['God Mode',1] call "+_skn_adminLog_PVC+"; + } + }; + "+_skn_repairVehicle+" = { + "+_skn_systemDebug5+" + _veh = objNull; + if (_this isEqualTo []) then { + if (vehicle player == player) then { + _veh = cursorTarget + } else { + _veh = vehicle player + } + } else { + _player = netId (_this select 1); + if (vehicle _player != _player) then { + _veh = vehicle _player + } + }; + "+_skn_systemDebug4+" + if (!isNull _veh) then { + if ((_veh isKindOf 'LandVehicle') || (_veh isKindOf 'Air') || (_veh isKindOf 'Ship') || (_veh isKindOf 'Tank')) then { + [108,_veh] call "+_skn_adminRequest_PVC+"; + "+_skn_systemDebug3+" + } + } + }; + "+_skn_spawnLoot+" = { + _lootLoc = getPosASL player; + _lootClasses = (configFile >> 'CfgBuildingLootPos') call Bis_fnc_getCfgSubClasses; + _lootClasses = _lootClasses - ['Default']; + + _objects = nearestObjects[_lootLoc, _lootClasses, _this]; + + _cntItem = 0; + _cntBuildings = 0; + + { + _building = _x; + _pos = getPosATL _building; + _config = configFile >> 'CfgBuildingLootPos' >> (typeOf _building); + if (isClass(_config)) then { + _cntBuildings = _cntBuildings + 1; + { + _positions = [] + getArray(_config >> (_x select 0)); + if !(_positions isEqualTo[]) then { + _class = _x select 1; + _randomColor = _x select 2; + { + _lootBiasPos = getNumber(_config >> 'lootBiasPos'); + _lootType = getText(_config >> 'lootType'); + if ((random 100) < _lootBiasPos) then { + + _pos = _building modelToWorld(_x select 0); + + if (nearestObjects[_pos, ['WH_Loot', 'Animated_Loot'], 2] isEqualTo[]) then { + _cntItem = _cntItem + 1; + + if ((typeName _class) == 'ARRAY') then { + _class = _class select(floor(random(count _class))); + }; + _dir = (_x select 1) + (getDir _building); + if (_dir > 360) then { + _dir = _dir - 360; + }; + if (_lootType == 'mil' && _class == 'Bed_EPOCH') then { + _class = 'Bunk_EPOCH'; + }; + _item = createVehicle[_class, _pos, [], 0.0, 'CAN_COLLIDE']; + _item setDir _dir; + + if (_pos select 2 < 0) then { + _pos set[2, 0]; + }; + + if (surfaceIsWater _pos) then { + _item setPosASL _pos; + } else { + _item setPosATL _pos; + }; + + if (typeName _randomColor isEqualTo 'STRING') then{ + _randomColor = _randomColor isEqualTo 'true'; + }; + + if (_randomColor) then { + _colors = [] + getArray(configFile >> 'CfgVehicles' >> _class >> 'availableTextures'); + if !(_colors isEqualTo[]) then { + _color = _colors select floor(random(count _colors)); + _item setObjectTextureGlobal[0, _color]; + }; + }; + }; + }; + }forEach _positions; + }; + }forEach "+str _loots+"; + }; + }forEach (nearestObjects[getPosASL player, _lootClasses, _this]); + [format['Spawn Loot (%1) for %2 Buildings (%3 Container)',_this,_cntBuildings,_cntItem],0] call "+_skn_adminLog_PVC+"; + hint format['Spawned Loot for %1 Buildings (%2 Container)',_cntBuildings,_cntItem]; + }; + "+_skn_old_esp+" = { + "+_skn_tg_old_esp+" = !"+_skn_tg_old_esp+"; + if ("+_skn_tg_old_esp+") then { + ['ESP Old',2] call "+_skn_adminLog_PVC+"; + waitUntil{ + EPOCH_ESP_TARGETS = (cameraOn nearEntities[['Epoch_Male_F', 'Epoch_Female_F', 'LandVehicle', 'Ship', 'Air', 'Tank'], 1000]) - [vehicle player]; + uiSleep 1; + !"+_skn_tg_old_esp+" + }; + } else { + ['ESP Old',1] call "+_skn_adminLog_PVC+"; + EPOCH_ESP_TARGETS = []; + }; + }; + "+_skn_old_espMap+" = { + "+_skn_tg_old_espMap+" = !"+_skn_tg_old_espMap+"; + if ("+_skn_tg_old_espMap+") then { + ['ESP-map Old', 2] call "+_skn_adminLog_PVC+"; + waitUntil{ + uiSleep 1; + EPOCH_ESPMAP_TARGETS = (cameraOn nearEntities[['CAManBase', 'LandVehicle', 'Ship', 'Air', 'Tank'], 10000]) - [player, vehicle player]; + { + if (isPlayer _x) then { + _pos = visiblePosition _x; + _lastPos = _x getVariable['ESP_old_MAP', []]; + _lastPos pushBack _pos; + reverse _lastPos; + if (count _lastPos > 101) then { + _lastPos resize 101; + }; + reverse _lastPos; + _x setVariable['ESP_old_MAP', _lastPos]; + }; + }forEach EPOCH_ESPMAP_TARGETS; + !"+_skn_tg_old_espMap+" + }; + } else { + ['ESP-map Old', 1] call "+_skn_adminLog_PVC+"; + EPOCH_ESPMAP_TARGETS = []; + }; + }; + "+_skn_getCtrl+" = compileFinal '(findDisplay -1337) displayCtrl _this'; + "+_skn_Update_AdminButtons+" = { + disableSerialization; + + {((_x select 0) call "+_skn_getCtrl+") ctrlSetText (_x select 1)}forEach + [ + [23,format['Hacker Log (%1)',count "+_skn_pv_hackerLog+"]], + [24,format['Admin Log (%1)',count "+_skn_pv_adminLog+"]] + ]; + }; + "+_skn_mapTeleport+" = { + if ("+_skn_tg_mapTeleport+") then { + _pos = (_this select 0) posScreenToWorld [_this select 2, _this select 3]; + if (vehicle player == player) then { + if (surfaceIsWater _pos) then [{vehicle player setPosASL _pos},{vehicle player setPosATL _pos}]; + } else { + [109,_pos] call "+_skn_adminRequest_PVC+"; + }; + if (!dialog) then {openMap [false, false]}; + }; + }; + "+_skn_deleteMenu+" = [ + ['Delete Menu',true], + [format ['%1',typeOf "+_skn_tg_delete+"], [-1], '', -5, [['expression', '']], '1', '0'], + ['Delete', [2], '', -5, [['expression', '[] spawn "+_skn_deleteNow+"']], '1', '1'], + ['Exit', [0], '', -5, [['expression', '']], '1', '1'] + ]; + "+_skn_deleteNow+" = { + if (!isNull "+_skn_tg_delete+") then { + if (!isPlayer "+_skn_tg_delete+") then { + [104,"+_skn_tg_delete+"] call "+_skn_adminRequest_PVC+"; + }; + }; + "+_skn_tg_delete+" = objNull; + }; + "+_skn_delete+" = { + showCommandingMenu ''; + if (!isNull cursorTarget) then { + "+_skn_tg_delete+" = cursorTarget; + showCommandingMenu '#USER:"+_skn_deleteMenu+"'; + }; + }; + "+_skn_fnc_Spec+" = { + _player = objectFromNetId (_this select 0 lbData (_this select 1)); + if (isNull _player) exitWith {}; + if (!isPlayer _player) exitWith {}; + cutText ['F2 To Cancel!','PLAIN DOWN',1]; + vehicle _player switchCamera 'External'; + }; + "+_skn_mainMenuCfg+" = {"+_skn_adminMenuLow+"}; + if (getPlayerUID player in "+str _skn_adminsOwner+") then { + "+_skn_mainMenuCfg+" = {"+_skn_adminMenuOwner+"}; + }; + if (getPlayerUID player in "+str _skn_adminsHigh+") then { + "+_skn_mainMenuCfg+" = {"+_skn_adminMenuHigh+"}; + }; + "+_skn_freeCam+" = { + _getPos = player modelToWorld[0, -1.5, 1.75]; + _cam = 'camera' camCreate _getPos; + _cam setDir([_getPos, player] call BIS_fnc_dirTo); + _cam camCommand 'MANUAL ON'; + _cam camCommand 'INERTIA OFF'; + _cam cameraEffect['INTERNAL', 'BACK']; + showCinemaBorder false; + cutText['Right Click To Cancel!', 'PLAIN DOWN', 1]; + }; + "+_skn_FillMainMenu+" = { + lbClear (8 call "+_skn_getCtrl+"); + _ctrl = 6 call "+_skn_getCtrl+"; + lbClear _ctrl; + for '_i' from 0 to count _menu -1 do { + _item = _menu select _i; + + _titleoption = _item select 3; + _color = _item select 4; + + _index = _ctrl lbAdd format['%1',_item select 0]; + if (count _color == 0) then { + _color = [1, 1, 1, 1]; + if (_titleoption == '1') then {_color = [0.42,0.64,0.88,1]}; + if (_titleoption == '3') then {_color = [0.27,0.39,0.53,1]}; + }; + + if (_titleoption == '2') then { + _color = if (_index in "+_skn_tg_toggle+") then [{[0.17,1,0,1]},{[0.51,0.51,0.51,1]}]; + }; + + _ctrl lbSetColor [_i,_color]; + _ctrl lbSetData [_i,str [_item select 1,_item select 2,_titleoption]]; + }; + }; + "+_skn_switchMainMenu+" = { + disableSerialization; + + _main = 6 call "+_skn_getCtrl+"; + _map = 7 call "+_skn_getCtrl+"; + _table = 8 call "+_skn_getCtrl+"; + if (_this == 0) then { + _main ctrlSetPosition [0.293698 * safezoneW + safezoneX,0.2888 * safezoneH + safezoneY,0.206297 * safezoneW,0.4862 * safezoneH]; + _map ctrlSetPosition [0.501031 * safezoneW + safezoneX,0.28836 * safezoneH + safezoneY,0.205265 * safezoneW,0.486548 * safezoneH]; + _table ctrlShow false; + _table ctrlSetPosition [0.293698 * safezoneW + safezoneX,0.2888 * safezoneH + safezoneY,0.206297 * safezoneW,0.4862 * safezoneH]; + _table ctrlCommit 0; + _main ctrlSetFade 0; + _map ctrlShow true; + }; + if (_this in [1,2]) then { + {(_x call "+_skn_getCtrl+") ctrlShow false}forEach[30,31,32,33,34]; + + _main ctrlSetPosition [0.293698 * safezoneW + safezoneX,0.2888 * safezoneH + safezoneY,0.412598 * safezoneW,0.4862 * safezoneH]; + _map ctrlSetPosition [0.709388 * safezoneW + safezoneX,0.28836 * safezoneH + safezoneY,-0.00312413 * safezoneW,0.486548 * safezoneH]; + _main ctrlSetFade 0; + if (_this == 2) then { + _main ctrlcommit 0; + _main ctrlSetFade 1; + }; + }; + _main ctrlCommit 0.8; + _map ctrlCommit 0.8; + }; + "+_skn_dbClickMainMenu+" = { + _currentSelect = _this select 1; + _data = call compile (_this select 0 lbData _currentSelect); + _tO = _data select 2; + + if (_tO == '1') exitWith {}; + if (_tO == '2') exitWith { + (_data select 0) spawn (_data select 1); + if (_currentSelect in "+_skn_tg_toggle+") then { + lbSetColor [6,_currentSelect,[0.51,0.51,0.51,1]]; + "+_skn_tg_toggle+" = "+_skn_tg_toggle+" - [_currentSelect]; + } else { + lbSetColor [6,_currentSelect,[0.165,1,0,1]]; + "+_skn_tg_toggle+" pushBack _currentSelect; + }; + }; + if (_tO == '4') exitWith { + if ((lbCurSel 5) >= 0) then { + [_text,lbData [5, lbCurSel 5],(_data select 0)] spawn (_data select 1); + }; + }; + if (typeName (_data select 1) == 'CODE') then {(_data select 0) spawn (_data select 1)}; + }; + Skaronator_fnc_handleButton = compileFinal (' + disableSerialization; + _idc = ctrlIDC (_this select 0); + if (_idc == 10) then { "+_skn_tg_sortOrder+" = ''Range''; call "+_skn_FillPlayerMenu+"}; + if (_idc == 11) then { "+_skn_tg_sortOrder+" = ''Alphabetically''; call "+_skn_FillPlayerMenu+"}; + + if (_idc == 20) then {call "+_skn_AdminMenu_Init+"}; + if (_idc == 21) then {call "+_skn_spawnMenu+"}; + + if (_idc == 23) then {call "+_skn_hackerLog+"}; + if (_idc == 24) then {call "+_skn_adminLog+"}; + + if (_idc == 32) then {true call "+_skn_doBan+"}; + if (_idc == 33) then {false call "+_skn_doBan+"}; + + if (_idc == 50) then {lbClear 43;"+_skn_tg_limitSpawn+" = [true,true,true,true,true,true,true,true,true,true,true]}; + if (_idc == 51) then {true call "+_skn_spawnSpawnMenu+"}; + if (_idc == 52) then {false call "+_skn_spawnSpawnMenu+"}; + if (_idc in [61,62,63,64,65,66,67,68,69,70,71]) then { + "+_skn_tg_spawnTyp+" = _idc; + _idc call "+_skn_fillSpawnMenu+"; + }; + '); + "+_skn_spawnSpawnMenu+" = { + _target = objNull; + if (_this) then { + if ((lbCurSel 5) >= 0) then { + _target = objectFromNetId (lbData [5, lbCurSel 5]); + }; + } else { + _target = player; + }; + if (isNull _target) exitWith {}; + _ctrl = 43 call "+_skn_getCtrl+"; + _spawn = []; + for '_i' from 0 to (lbSize _ctrl)-1 do { + _data = call compile (_ctrl lbData _i); + _spawn pushBack [_data select 0, _data select 2]; + }; + lbClear _ctrl; + "+_skn_tg_limitSpawn+" = [true,true,true,true,true,true,true,true,true,true,true]; + "+_skn_systemDebug2+" + [555,[_spawn,netId _target]] call "+_skn_adminRequest_PVC+"; + }; + "+_skn_spawnMenu+" = { + false call "+_skn_doBan+"; + if (!isNull "+_skn_tg_BanPlayer+") then {uiSleep 0.8;false spawn "+_skn_switchTable+"}; + 2 call "+_skn_switchMainMenu+"; + lbclear (6 call "+_skn_getCtrl+"); + _table = 8 call "+_skn_getCtrl+"; + lbclear _table; + _table ctrlShow false; + "+_skn_tg_limitSpawn+" = [true,true,true,true,true,true,true,true,true,true,true]; + comment '[primaryWeapon,secondaryWeapon,launcher,backpack,map,rangefinderSlot,vehicleSlot]'; + (41 call "+_skn_getCtrl+") ctrlSetEventHandler ['LBDblClick', "" + _ctrl = _this select 0; + _currentSelect = _this select 1; + _type = call compile (_ctrl lbData _currentSelect) select 1; + _allowed = true; + if (_type != -1) then { + _allowed = "+_skn_tg_limitSpawn+" select _type; + "+_skn_tg_limitSpawn+" set [_type,false]; + }; + "+_skn_systemDebug1+" + if (_allowed) then { + _otherList = 43 call "+_skn_getCtrl+"; + _index = _otherList lbAdd format ['%1',_ctrl lbText _currentSelect]; + _otherList lbSetData [_index, _ctrl lbData _currentSelect]; + _otherList lbSetPicture [_index,_ctrl lbPicture _currentSelect]; + } else { + hint 'You can just select one Weapon/Item of this Type!'; + }; + ""]; + + (43 call "+_skn_getCtrl+") ctrlSetEventHandler ['LBDblClick', ' + _ctrl = _this select 0; + _currentSelect = _this select 1; + _type = call compile (_ctrl lbData _currentSelect) select 1; + if (_type != -1) then { + "+_skn_tg_limitSpawn+" set [_type,true]; + }; + _ctrl lbDelete _currentSelect; + ']; + + {_i = _x call "+_skn_getCtrl+";_i ctrlShow true;_i ctrlSetFade 1;_i ctrlcommit 0;_i ctrlSetFade 0;_i ctrlcommit 0.8}forEach[40,41,42,43,50,51,52,60,61,62,63,64,65,66,67,68,69,70,71]; + "+_skn_tg_spawnTyp+" call "+_skn_fillSpawnMenu+"; + }; + "+_skn_removespawnMenu+" = { + if (ctrlShown (40 call "+_skn_getCtrl+")) then { + {_i = _x call "+_skn_getCtrl+";_i ctrlShow true;_i ctrlSetFade 1;_i ctrlcommit 0.8}forEach[40,41,42,43,50,51,52,60,61,62,63,64,65,66,67,68,69,70,71]; + [] spawn {uiSleep 0.8;{_x call "+_skn_getCtrl+" ctrlShow false}forEach[40,41,42,43,50,51,52,60,61,62,63,64,65,66,67,68,69,70,71]}; + true + } else {false}; + }; + "+_skn_fillSpawnMenu+" = { + _ctrl = 41 call "+_skn_getCtrl+"; + lbclear _ctrl; + _button = _this call "+_skn_getCtrl+"; + _button ctrlSetTextColor [1, 0, 0, 1]; + {_x call "+_skn_getCtrl+" ctrlSetTextColor [1, 1, 1, 1]}forEach([61,62,63,64,65,66,67,68,69,70,71]-[_this]); + if (_this == 61) then { + _airVehicles = "" + getText(_x >> 'displayName') != '' && + getText(_x >> 'picture') != '' && + getNumber(_x >> 'type') != 0 && + getText (_x >> 'vehicleClass') in ['Air'] + ""configClasses (configFile >> 'CfgVehicles'); + { + _config = 'CfgPricing' call EPOCH_returnConfig; + if (isClass(_config >> configName _x)) then{ + _index = _ctrl lbAdd format['%1', getText(_x >> 'displayName')]; + _ctrl lbSetData[_index, str[configName _x, 6, 0]]; + _ctrl lbSetPicture[_index, getText(_x >> 'picture')]; + }; + }forEach _airVehicles; + }; + if (_this == 62) then { + _landVehicles = "" + getText(_x >> 'displayName') != '' && + getText(_x >> 'picture') != '' && + configName _x != 'PaperCar' && + getText (_x >> 'vehicleClass') in ['Car'] + ""configClasses (configFile >> 'CfgVehicles'); + { + _config = 'CfgPricing' call EPOCH_returnConfig; + if (isClass(_config >> configName _x)) then{ + _index = _ctrl lbAdd format['%1', getText(_x >> 'displayName')]; + _ctrl lbSetData[_index, str[configName _x, 6, 1]]; + _ctrl lbSetPicture[_index, getText(_x >> 'picture')]; + }; + }forEach _landVehicles; + }; + if (_this == 63) then { + _shipVehicles = "" + getText(_x >> 'displayName') != '' && + getText(_x >> 'picture') != '' && + getNumber(_x >> 'type') in [1,2,3,4] && + getText (_x >> 'vehicleClass') in ['Ship'] + ""configClasses (configFile >> 'CfgVehicles'); + { + _config = 'CfgPricing' call EPOCH_returnConfig; + if (isClass(_config >> configName _x)) then{ + _index = _ctrl lbAdd format['%1', getText(_x >> 'displayName')]; + _ctrl lbSetData[_index, str[configName _x, 6, 2]]; + _ctrl lbSetPicture[_index, getText(_x >> 'picture')]; + }; + }forEach _shipVehicles; + }; + if (_this == 64) then { + _weapons = "" + getText(_x >> 'displayName') != '' && + getText(_x >> 'picture') != '' && + getNumber(_x >> 'scope') in [0,2] && + getNumber(_x >> 'type') in [1,2,4] + ""configClasses (configFile >> 'CfgWeapons'); + { + _config = 'CfgPricing' call EPOCH_returnConfig; + if (isClass(_config >> configName _x)) then{ + _index = _ctrl lbAdd format['%1', getText(_x >> 'displayName')]; + _type = getNumber(_x >> 'type') - 1; + if (getNumber(_x >> 'type') == 4) then { _type = 2 }; + _ctrl lbSetData[_index, str[configName _x, _type, _type + 3]]; + _ctrl lbSetPicture[_index, getText(_x >> 'picture')]; + }; + }forEach _weapons; + }; + if (_this == 65) then { + _magazines = "" + getText(_x >> 'displayName') != '' && + getText(_x >> 'picture') != '' && + getNumber(_x >> 'scope') in [0,2] && + getText(_x >> 'ammo') != '' + ""configClasses (configFile >> 'CfgMagazines'); + { + _config = 'CfgPricing' call EPOCH_returnConfig; + if (isClass(_config >> configName _x)) then{ + _index = _ctrl lbAdd format['%1', getText(_x >> 'displayName')]; + _ctrl lbSetData[_index, str[configName _x, -1, 6]]; + _ctrl lbSetPicture[_index, getText(_x >> 'picture')]; + }; + }forEach _magazines; + }; + if (_this == 66) then { + _magazines = "" + getText(_x >> 'displayName') != '' && + getText(_x >> 'picture') != '' && + getNumber(_x >> 'scope') in[0, 2] && + getText(_x >> 'ammo') == '' + ""configClasses(configFile >> 'CfgMagazines'); + { + _config = 'CfgPricing' call EPOCH_returnConfig; + if (isClass(_config >> configName _x)) then{ + _index = _ctrl lbAdd format['%1', getText(_x >> 'displayName')]; + _ctrl lbSetData[_index, str[configName _x, -1, 7]]; + _ctrl lbSetPicture[_index, getText(_x >> 'picture')]; + }; + }forEach _magazines; + }; + if (_this == 67) then { + + _backpack = ""getText(_x >> 'displayName') != '' && getText(_x >> 'picture') != '' && getNumber(_x >> 'isbackpack') == 1""configClasses(configFile >> 'CfgVehicles'); + { + _config = 'CfgPricing' call EPOCH_returnConfig; + if (isClass(_config >> configName _x)) then{ + _index = _ctrl lbAdd format['%1', getText(_x >> 'displayName')]; + _ctrl lbSetData[_index, str[configName _x, 3, 8]]; + _ctrl lbSetPicture[_index, getText(_x >> 'picture')]; + }; + }forEach _backpack; + }; + if (_this == 68) then { + _uniforms = ['U_O_FullGhillie_lsh', + 'U_O_FullGhillie_sard', + 'U_O_FullGhillie_ard', + 'U_O_CombatUniform_ocamo', + 'U_O_GhillieSuit', + 'U_O_PilotCoveralls', + 'U_O_Wetsuit', + 'U_OG_Guerilla1_1', + 'U_OG_Guerilla2_1', + 'U_OG_Guerilla2_2', + 'U_OG_Guerilla2_3', + 'U_OG_Guerilla3_1', + 'U_OG_Guerilla3_2', + 'U_OG_leader', + 'U_C_Poloshirt_stripped', + 'U_C_Poloshirt_blue', + 'U_C_Poloshirt_burgundy', + 'U_C_Poloshirt_tricolour', + 'U_C_Poloshirt_salmon', + 'U_C_Poloshirt_redwhite', + 'U_C_Poor_1', + 'U_C_WorkerCoveralls', + 'U_C_Journalist', + 'U_C_Scientist', + 'U_OrestesBody', + 'U_Wetsuit_uniform', + 'U_Wetsuit_White', + 'U_Wetsuit_Blue', + 'U_Wetsuit_Purp', + 'U_Wetsuit_Camo', + 'U_CamoRed_uniform', + 'U_CamoBrn_uniform', + 'U_CamoBlue_uniform', + 'U_Camo_uniform', + 'U_ghillie1_uniform', + 'U_ghillie2_uniform', + 'U_ghillie3_uniform', + 'U_C_Driver_1', + 'U_C_Driver_2', + 'U_C_Driver_3', + 'U_C_Driver_4', + 'U_C_Driver_1_black', + 'U_C_Driver_1_blue', + 'U_C_Driver_1_green', + 'U_C_Driver_1_red', + 'U_C_Driver_1_white', + 'U_C_Driver_1_yellow', + 'U_C_Driver_1_orange', + 'U_C_Driver_1_red']; + + { + _index = _ctrl lbAdd format['%1', getText(configFile >> 'CfgWeapons' >> _x >> 'displayName')]; + _ctrl lbSetData[_index, str[_x, -1, 9]]; + _ctrl lbSetPicture[_index, getText(configFile >> 'CfgWeapons' >> _x >> 'picture')]; + }forEach _uniforms; + }; + if (_this == 69) then { + _optics = ['optic_Arco', 'optic_Hamr', 'optic_Aco', 'optic_ACO_grn', 'optic_Aco_smg', 'optic_ACO_grn_smg', 'optic_Holosight', 'optic_Holosight_smg', 'optic_SOS', 'optic_MRCO', 'optic_DMS', 'optic_Yorris', 'optic_MRD', 'optic_LRPS', 'optic_NVS', 'optic_tws', 'optic_tws_mg']; + _muzzles = ['muzzle_snds_H','muzzle_snds_L','muzzle_snds_M','muzzle_snds_B','muzzle_snds_H_MG','muzzle_snds_acp','Heal_EPOCH','Defib_EPOCH','Repair_EPOCH','acc_flashlight','acc_pointer_IR']; + _misc = ['Binocular','NVG_EPOCH','ItemCompass','ItemGPS','ItemMap','EpochRadio0','EpochRadio1','EpochRadio2','EpochRadio3','EpochRadio4','EpochRadio5','EpochRadio6','EpochRadio7','EpochRadio8','EpochRadio9','ItemWatch']; + _attachments = _optics + _muzzles + _misc; + { + _config = 'CfgPricing' call EPOCH_returnConfig; + if (isClass(_config >> _x)) then{ + _index = _ctrl lbAdd format['%1', getText(configFile >> 'CfgWeapons' >> _x >> 'displayName')]; + _ctrl lbSetData[_index, str[_x, -1, 9]]; + _ctrl lbSetPicture[_index, getText(configFile >> 'CfgWeapons' >> _x >> 'picture')]; + }; + }forEach _attachments; + }; + if (_this == 70) then { + _headgear = ['wolf_mask_epoch','pkin_mask_epoch']; + for '_h' from 1 to 104 do + { + _headgear pushBack format['H_%1_EPOCH',_h]; + }; + { + _index = _ctrl lbAdd format['%1', getText(configFile >> 'cfgWeapons' >> _x >> 'displayName')]; + _ctrl lbSetData[_index, str[_x, -1, 9]]; + _ctrl lbSetPicture[_index, getText(configFile >> 'cfgWeapons' >> _x >> 'picture')]; + }forEach _headgear; + }; + if (_this == 71) then { + _vests = []; + for '_v' from 1 to 40 do + { + _vests pushBack format['V_%1_EPOCH', _v]; + }; + { + _index = _ctrl lbAdd format['%1', getText(configFile >> 'cfgWeapons' >> _x >> 'displayName')]; + _ctrl lbSetData[_index, str[_x, -1, 9]]; + _ctrl lbSetPicture[_index, getText(configFile >> 'cfgWeapons' >> _x >> 'picture')]; + }forEach _vests; + }; + }; + "+_skn_FillPlayerMenu+" = { + _ctrl = 5 call "+_skn_getCtrl+"; + lbclear _ctrl; + + _sorted = []; + _unsorted = playableUnits; + + _buttonRange = 10 call "+_skn_getCtrl+"; + _buttonRange ctrlSetText 'Range'; + _buttonAlphabetically = 11 call "+_skn_getCtrl+"; + _buttonAlphabetically ctrlSetText 'Alphabet'; + + if ("+_skn_tg_sortOrder+" == 'Range') then { + _pos = getPosATL vehicle player; + { + _temp = _x; + { + if ((getPosATL _x distance _pos) < (getPosATL _temp distance _pos)) exitWith { + _unsorted = _unsorted - [_x]; + _sorted pushBack _x; + _temp = _x; + }; + }forEach _unsorted; + }forEach _unsorted; + _buttonRange ctrlSetTextColor [1, 0, 0, 1]; + _buttonAlphabetically ctrlSetTextColor [1, 1, 1, 1]; + }; + if ("+_skn_tg_sortOrder+" == 'Alphabetically') then { + _unsortedName = []; + { + _unsortedName pushBack (name _x); + }forEach _unsorted; + + _alphabetically = _unsortedName call BIS_fnc_sortAlphabetically; + { + { + if (name _x == (_alphabetically select 0)) exitWith { + _alphabetically = _alphabetically - [_alphabetically select 0]; + _unsorted = _unsorted - [_x]; + _sorted pushBack _x; + }; + }forEach _unsorted; + }forEach _unsorted; + + _buttonAlphabetically ctrlSetTextColor [1, 0, 0, 1]; + _buttonRange ctrlSetTextColor [1, 1, 1, 1]; + }; + if (_sorted isEqualTo []) then {_sorted = [player]}; + _skn_fnc_addPlayerToList = { + _player = _this select 0; + _index = _ctrl lbAdd format ['%1', name _player]; + _ctrl lbSetData [_index, netId _player]; + _ctrl lbSetColor [_index, _this select 1]; + if (vehicle _player == _player) then { + _pic = ''; + if (currentWeapon _player != '') then { + _pic = getText(configFile >> 'CfgWeapons' >> currentweapon _player >> 'picture') + } else { + if (primaryWeapon _player == '') then { + _pic = getText(configFile >> 'CfgVehicles' >> typeof vehicle _player >> 'picture') + } else { + _pic = getText(configFile >> 'CfgWeapons' >> primaryweapon _player >> 'picture') + }; + }; + _ctrl lbSetPicture [_index,_pic]; + } else { + _ctrl lbSetPicture [_index,getText(configFile >> 'CfgVehicles' >> typeof vehicle _player >> 'picture')]; + }; + }; + + _ctrl lbAdd ' Admins'; + _ctrl lbSetColor [(lbsize _ctrl)-1, [0,0.6,1,1]]; + { + if (getPlayerUID _x in "+str _skn_adminUIDArray+") then {_sorted = _sorted - [_x];[_x,[0,1,0,1]] call _skn_fnc_addPlayerToList}; + }forEach _sorted; + _ctrl lbAdd ''; + _ctrl lbAdd ' Normal Player'; + _ctrl lbSetColor [(lbsize _ctrl)-1, [1,1,1,1]]; + + { + if (vehicle _x == _x) then {_sorted = _sorted - [_x];[_x,[0,1,0,1]] call _skn_fnc_addPlayerToList}; + }forEach _sorted; + _ctrl lbAdd ''; + _ctrl lbAdd ' Vehicle Player'; + _ctrl lbSetColor [(lbsize _ctrl)-1, [1,1,1,1]]; + + {[_x,[0,1,0,1]] call _skn_fnc_addPlayerToList}forEach _sorted; + _ctrl lbAdd '';_ctrl lbAdd ''; +}; +"+_skn_switchTable+" = { + disableSerialization; + _map = 7 call "+_skn_getCtrl+"; + _table = 8 call "+_skn_getCtrl+"; + + if ((ctrlPosition _table) isEqualTo [0.293698 * safezoneW + safezoneX,0.2888 * safezoneH + safezoneY,0.206297 * safezoneW,0.4862 * safezoneH]) then { + _table ctrlSetPosition [0.293698 * safezoneW + safezoneX,0.2888 * safezoneH + safezoneY,0.206297 * safezoneW,0.4862 * safezoneH]; + _table ctrlCommit 0; + + + _table ctrlSetEventHandler ['LBSelChanged', 'if ((_this select 1) != -1) then {lnbSetCurSelRow [8,-1]};']; + + _table ctrlShow _this; + _table ctrlSetPosition [0.293698 * safezoneW + safezoneX,0.2888 * safezoneH + safezoneY,0.412598 * safezoneW,0.4862 * safezoneH]; + _table ctrlCommit 0.8; + }; + + _time = diag_tickTime; + waitUntil { + if (diag_tickTime-_time>1) exitWith {true}; + if ((ctrlPosition _map) isEqualTo [0.709388 * safezoneW + safezoneX,0.28836 * safezoneH + safezoneY,-0.00312413 * safezoneW,0.486548 * safezoneH]) exitWith {_map ctrlShow false;true}; + }; +}; +"+_skn_hackerLog+" = { + 1 call "+_skn_switchMainMenu+"; + + lbClear (6 call "+_skn_getCtrl+"); + _table = 8 call "+_skn_getCtrl+"; + lbClear _table; + true spawn "+_skn_switchTable+"; + if (call "+_skn_removespawnMenu+") then { + uiSleep 0.4; + _table ctrlSetFade 1; + _table ctrlcommit 0; + _table ctrlSetFade 0; + _table ctrlcommit 0.8; + }; + + _table ctrlShow true; + _table lnbAddRow ['==================================== HACKER LOG ======================================']; + + { + _player = _x select 0; + _color = _x select 1; + + _index = _table lnbAddRow [_player select 1,_player select 2,nil,if (_player select 0 == 0) then [{format['BANNED: %1',_player select 4]},{_player select 4}]]; + if (count _color > 0) then { + lnbSetColor [8,[_index,0],_color]; + lnbSetColor [8,[_index,1],_color]; + lnbSetColor [8,[_index,3],_color]; + }; + }forEach "+_skn_pv_hackerLog+"; +}; +"+_skn_adminLog+" = { + 1 call "+_skn_switchMainMenu+"; + lbClear (6 call "+_skn_getCtrl+"); + + _table = 8 call "+_skn_getCtrl+"; + lbClear _table; + true spawn "+_skn_switchTable+"; + if (call "+_skn_removespawnMenu+") then {uiSleep 0.4; + _table ctrlSetFade 1; + _table ctrlcommit 0; + _table ctrlSetFade 0; + _table ctrlcommit 0.8; + }; + + _table ctrlShow true; + _table lnbAddRow ['===================================== ADMIN LOG ======================================']; + + {_table lnbAddRow _x}forEach "+_skn_pv_adminLog+"; +}; +"+_skn_flipVehicle+" = { + _target = cursorTarget; + if (isNull _target) then { + _vehicles = player nearEntities[['LandVehicle', 'Ship', 'Air'], 15]; + if !(_vehicles isEqualTo []) then { + _target = _vehicles select 0; + }; + }; + + if (!isNull _target) then { + if (!isPlayer _target) then { + _target setVectorUp [0, 0, 1]; + cutText [format ['Unflipping Vehicle..'],'PLAIN DOWN']; + }; + }; +}; +"+_skn_infrontTP+" = { + "+_skn_tg_infrontTP+" = !"+_skn_tg_infrontTP+"; + if ("+_skn_tg_infrontTP+") then { + if (vehicle player == player) then { + _distance = 10; + _object = vehicle player; + _dir = getdir _object; + _pos = getPosATL _object; + if (_object isKindOf 'Air') then { + _distance = 50; + _pos = [(_pos select 0)+_distance*sin(_dir),(_pos select 1)+_distance*cos(_dir),((getpos _object) select 2)+100]; + } else { + _pos = [(_pos select 0)+_distance*sin(_dir),(_pos select 1)+_distance*cos(_dir),0]; + if (surfaceIsWater _pos) then {_pos set [2,2]}; + }; + if (surfaceIsWater _pos) then [{vehicle player setPosASL _pos},{vehicle player setPosATL _pos}]; + } else { + cutText ['You can just Teleport Infront when you are not inside of a Vehicle!','PLAIN DOWN']; + }; + }; +}; +"+_skn_customBanreason+" = { + disableSerialization; + _player = objectFromNetId (_this select 1); + _name = name _player; + {(_x call "+_skn_getCtrl+") ctrlShow true}forEach[30,31,32,33,34]; + + _edit = 31 call "+_skn_getCtrl+"; + _edit ctrlSetText ''; + if (typename (_this select 2) == 'STRING') then { + _edit ctrlSetText format['%1',(_this select 2)]; + }; + + _text = 34 call "+_skn_getCtrl+"; + _text ctrlSetText format ['Custom Banreason for %1:',_name]; + "+_skn_tg_BanPlayer+" = _player; + findDisplay -1337 displayAddEventHandler ['Unload', {"+_skn_tg_BanPlayer+" = objNull}]; + + _map = 7 call "+_skn_getCtrl+"; + _map ctrlSetPosition [0.501031 * safezoneW + safezoneX,0.44456 * safezoneH + safezoneY,0.205265 * safezoneW,0.328148 * safezoneH]; + _map ctrlCommit 0.8; +}; +"+_skn_doBan+" = { + disableSerialization; + if (_this && !isNull "+_skn_tg_BanPlayer+") then { + _reason = ctrlText 31; + if (_reason == '') then { + ctrlSetText [31, 'Please enter a banreason!']; + } else { + [666,[_reason,netId "+_skn_tg_BanPlayer+"]] call "+_skn_adminRequest_PVC+"; + }; + }; + + {_i = _x call "+_skn_getCtrl+";_i ctrlShow false;_i ctrlShow true}forEach[32,33]; + + "+_skn_tg_BanPlayer+" = objNull; + + _map = 7 call "+_skn_getCtrl+"; + _map ctrlSetPosition [0.501031 * safezoneW + safezoneX,0.28836 * safezoneH + safezoneY,0.205265 * safezoneW,0.486548 * safezoneH]; + _map ctrlCommit 0.8; +}; +"); + +_skn_admininit = compileFinal ("waitUntil {(!isNil '"+_skn_Admin_Code+"') && (!isNil '"+_skn_pv_adminLog+"') && (!isNil '"+_skn_pv_hackerLog+"')};[] spawn "+_skn_Admin_Code+""); +call compile (_skn_Admin_Code+" = _skn_admincode"); +call compile (_skn_Admin_Init+" = _skn_admininit;publicVariable '"+_skn_Admin_Init+"'"); diff --git a/Sources/epoch_server/init/server_variables.sqf b/Sources/epoch_server/init/server_variables.sqf new file mode 100644 index 00000000..fc0cb476 --- /dev/null +++ b/Sources/epoch_server/init/server_variables.sqf @@ -0,0 +1,124 @@ +EPOCH_BuildingSlots = []; +EPOCH_TraderSlots = []; +EPOCH_saveBldQueue = []; +EPOCH_saveVehQueue = []; +EPOCH_saveStorQueue = []; +EPOCH_saveBuildQueue = []; +EPOCH_cleanupQueue = []; +EPOCH_defaultVars_SEPXVar = EPOCH_defaultVars; +EPOCH_group_upgrade_lvl_SEPXVar = EPOCH_group_upgrade_lvl; +EPOCH_staticTraderLocations = []; + +_configArray = [ + ["serverRestart", false], + ["forceRestartTime", 14400], + ["StorageSlotsLimit",1500], + ["BuildingSlotsLimit", 1500], + ["StaticDateTime", []], + ["timeDifference", 0], + ["lootMultiplier", 0.5], + ["WeatherChangeTime", 1200], + ["WeatherStaticForecast", []], + ["showEarthQuakes", true], + ["showShippingContainers", true], + ["cloneCost", 100], + ["vehicleLockTime", 1800], + ["antagonistChanceTrash", 0.09], + ["antagonistChancePDeath", 0.33], + ["antagonistChanceLoot", 0.09], + ["allowedVehiclesList", + [ + ["C_Offroad_01_EPOCH", 8], + ["C_Quadbike_01_EPOCH", 8], + ["C_Hatchback_01_EPOCH", 10], + ["C_Hatchback_02_EPOCH", 10], + ["C_SUV_01_EPOCH", 10], + ["C_Rubberboat_EPOCH", 5], + ["C_Rubberboat_02_EPOCH", 5], + ["C_Rubberboat_03_EPOCH", 5], + ["C_Rubberboat_04_EPOCH", 5], + ["C_Van_01_box_EPOCH", 8], + ["C_Van_01_transport_EPOCH", 9], + ["C_Boat_Civil_01_EPOCH", 5], + ["C_Boat_Civil_01_police_EPOCH", 5], + ["C_Boat_Civil_01_rescue_EPOCH", 5], + ["B_Heli_Light_01_EPOCH", 2], + ["B_SDV_01_EPOCH", 2], + ["B_MRAP_01_EPOCH", 3], + ["B_Truck_01_transport_EPOCH", 1], + ["B_Truck_01_covered_EPOCH", 2], + ["B_Truck_01_mover_EPOCH", 1], + ["B_Truck_01_box_EPOCH", 1], + ["O_Truck_02_covered_EPOCH", 2], + ["O_Truck_02_transport_EPOCH", 1], + ["O_Truck_03_covered_EPOCH", 1], + ["O_Truck_02_box_EPOCH", 1], + ["I_Heli_light_03_unarmed_EPOCH", 1], + ["O_Heli_Light_02_unarmed_EPOCH", 1], + ["I_Heli_Transport_02_EPOCH", 1], + ["O_Heli_Transport_04_EPOCH", 1], + ["O_Heli_Transport_04_bench_EPOCH", 1], + ["O_Heli_Transport_04_box_EPOCH", 1], + ["O_Heli_Transport_04_covered_EPOCH", 1], + ["B_Heli_Transport_03_unarmed_EPOCH", 1], + ["jetski_epoch", 7], + ["K01", 2], + ["K02", 2], + ["K03", 2], + ["K04", 2], + ["ebike_epoch", 7], + ["mosquito_epoch", 5], + ["C_Heli_Light_01_civil_EPOCH",5] + ] + ], + ["taxRate", 0.1], + ["starterTraderItems", [[], []]], + ["SHOW_TRADERS", true], + ["SHOW_JAMMERS", true], + ["SHOW_BOATLOOT", true], + ["NPCSlotsLimit", 50], + ["forceStaticTraders", true], + ["expiresBuilding", "604800"], + ["expiresPlayer", "2592000"], + ["expiresBank", "7776000"], + ["expiresVehicle", "604800"], + ["expiresAIdata", "604800"], + ["hiveAsync", true], + ["hiveAdminCmdExec", false], + ["hiveAdminSavePlayerList", true], + ["hiveAdminCmdTime", 5], + ["DEBUG_VEH", false] +]; + +EPOCH_fnc_returnConfigEntry = { + private["_defaultData", "_config", "_varData"]; + _defaultData = _this select 2; + _config = (_this select 0) >> (_this select 1); + if (isClass(_this select 0)) then{ + _varData = switch (typeName _defaultData) do { + case "SCALAR": {getNumber _config}; + case "BOOL": {(getNumber _config) == 1}; + case "ARRAY": {getArray _config}; + case "STRING": {getText _config}; + default {_defaultData}; + }; + } else { + _varData = _defaultData; + }; + _varData +}; + +// Cast default vars to global vars +// Note: TODO not all of these should be cast to a global var to save memory. If used only once use config lookup. +_serverSettingsConfig = configFile >> "CfgEpochServer"; +{ + _varData = [_serverSettingsConfig,_x select 0,_x select 1] call EPOCH_fnc_returnConfigEntry; + missionNamespace setVariable[format["EPOCH_%1", _x select 0], _varData]; +}forEach _configArray; + +// Vehicle slot limit set to total of all allowed limits +if (!isNil "EPOCH_allowedVehiclesList") then { + _vehicleSlotLimit = 0; + {_vehicleSlotLimit = _vehicleSlotLimit + (_x select 1)} forEach EPOCH_allowedVehiclesList; + EPOCH_VehicleSlotsLimit = _vehicleSlotLimit; +}; \ No newline at end of file diff --git a/Sources/epoch_server/system/Trader_brain.fsm b/Sources/epoch_server/system/Trader_brain.fsm new file mode 100644 index 00000000..fc6e1835 --- /dev/null +++ b/Sources/epoch_server/system/Trader_brain.fsm @@ -0,0 +1,559 @@ +/*%FSM*/ +/*%FSM*/ +/* +item0[] = {"trader",0,250,-200.000000,-275.000000,-100.000000,-225.000000,0.000000,"trader"}; +item1[] = {"_",8,218,50.000000,375.000000,150.000000,425.000000,5.000000,""}; +item2[] = {"decision",2,250,175.000000,-200.000000,275.000000,-150.000000,0.000000,"decision"}; +item3[] = {"decision_made",4,218,175.000000,-25.000000,275.000000,25.000000,100.000000,"decision made"}; +item4[] = {"action",2,250,50.000000,125.000000,150.000000,175.000000,0.000000,"action"}; +item5[] = {"actioned",4,218,-200.000000,125.000000,-100.000000,175.000000,100.000000,"actioned"}; +item6[] = {"dispose",4,218,125.000000,-325.000000,225.000000,-275.000000,90.000000,"dispose"}; +item7[] = {"reset_vars",2,250,-75.000000,-200.000000,25.000000,-150.000000,0.000000,"reset vars"}; +item8[] = {"_",8,218,-75.000000,-25.000000,25.000000,25.000000,5.000000,""}; +item9[] = {"met",4,218,-200.000000,-125.000000,-100.000000,-75.000000,10.000000,"met"}; +item10[] = {"_",8,218,50.000000,50.000000,150.000000,100.000000,5.000000,""}; +item11[] = {"end",1,250,425.000000,25.000000,525.000000,75.000000,0.000000,"end"}; +item12[] = {"dispose",4,218,250.000000,25.000000,350.000000,75.000000,80.000000,"dispose"}; +item13[] = {"criteria",2,250,-200.000000,-25.000000,-100.000000,25.000000,0.000000,"criteria"}; +item14[] = {"interrupt_action",2,250,50.000000,-25.000000,150.000000,25.000000,0.000000,"interrupt action"}; +item15[] = {"player",4,218,50.000000,-125.000000,150.000000,-75.000000,10.000000,"player"}; +item16[] = {"_",8,218,50.000000,-200.000000,150.000000,-150.000000,5.000000,""}; +item17[] = {"go_work",4,218,307.360077,-260.220886,397.360077,-210.220947,70.000000,"go work"}; +item18[] = {"go_home",4,218,350.000000,-200.000000,450.000000,-150.000000,60.000000,"go home"}; +item19[] = {"work",4,218,175.000000,250.000000,275.000000,300.000000,60.000000,"work"}; +item20[] = {"move_to_work",2,4346,425.000000,250.000000,525.000000,300.000000,0.000000,"move to work"}; +item21[] = {"home",4,218,100.000000,300.000000,200.000000,350.000000,50.000000,"home"}; +item22[] = {"move_to_home",2,250,425.000000,325.000000,525.000000,375.000000,0.000000,"move to home"}; +item23[] = {"look_at",4,218,225.000000,-300.000000,325.000000,-250.000000,80.000000,"look at"}; +item24[] = {"serve",4,218,225.000000,175.000000,325.000000,225.000000,70.000000,"serve"}; +item25[] = {"look_at",2,250,425.000000,175.000000,525.000000,225.000000,0.000000,"look at"}; +item26[] = {"no_decisiion",4,218,50.000000,-275.000000,150.000000,-225.000000,85.000000,"no decisiion"}; +item27[] = {"interrupt",4,218,250.000000,100.000000,350.000000,150.000000,75.000000,"interrupt"}; +item28[] = {"trade",2,250,425.000000,100.000000,525.000000,150.000000,0.000000,"trade"}; +item29[] = {"_",8,218,-200.000000,-200.000000,-100.000000,-150.000000,5.000000,""}; +link0[] = {0,29}; +link1[] = {1,4}; +link2[] = {2,3}; +link3[] = {2,6}; +link4[] = {2,17}; +link5[] = {2,18}; +link6[] = {2,23}; +link7[] = {2,26}; +link8[] = {3,4}; +link9[] = {4,5}; +link10[] = {4,12}; +link11[] = {4,19}; +link12[] = {4,21}; +link13[] = {4,24}; +link14[] = {4,27}; +link15[] = {5,13}; +link16[] = {6,2}; +link17[] = {7,16}; +link18[] = {8,14}; +link19[] = {9,7}; +link20[] = {10,4}; +link21[] = {12,11}; +link22[] = {13,8}; +link23[] = {13,9}; +link24[] = {14,10}; +link25[] = {14,15}; +link26[] = {15,2}; +link27[] = {16,2}; +link28[] = {17,2}; +link29[] = {18,2}; +link30[] = {19,20}; +link31[] = {20,1}; +link32[] = {21,22}; +link33[] = {22,1}; +link34[] = {23,2}; +link35[] = {24,25}; +link36[] = {25,1}; +link37[] = {26,7}; +link38[] = {27,28}; +link39[] = {28,1}; +link40[] = {29,7}; +globals[] = {25.000000,1,0,0,16777215,640,480,1,92,6316128,1,-256.926910,577.747742,523.678101,-359.150879,832,880,1}; +window[] = {2,-1,-1,-1,-1,603,1758,2783,78,3,850}; +*//*%FSM*/ +class FSM +{ + fsmName = "traders"; + class States + { + /*%FSM*/ + class trader + { + name = "trader"; + init = /*%FSM*/"_trader = _this select 0;" \n + "_home = _this select 1;" \n + "_work = _this select 2 select 0;" \n + "_schedule = _this select 2 select 1;" \n + "_trgt = objNull;" \n + "" \n + "_trader disableAI ""FSM"";" \n + "_trader disableAI ""TARGET"";" \n + "_trader disableAI ""AUTOTARGET"";" \n + "_trader setBehaviour ""CARELESS"";" \n + "_trader setCombatMode ""BLUE"";" \n + "" \n + "_traderNames=[""Aaron"",""Kenneth"",""Paul"",""Darren"",""Damian"",""Niklas"",""Andrew"",""Nigel"",""Harry"",""Phil"",""Antony"",""Dave"",""Hammish"",""Richard"",""Peter"",""Conor""];" \n + "_traderName = _traderNames select (floor(random count _traderNames));" \n + "" \n + "_trgtArray = [""Epoch_Man_base_F"",""Epoch_Female_base_F""];" \n + "_tRange = 20;//Travel Range - Pause if players within range when travelling home" \n + "_sRange = 10;//Serve Range - Look at players within this distance" \n + "_maxTravelTime = 480;//Max time before process times out and continues, after moving. moveToCompleted will timeout before this." \n + "_atWork = false;" \n + "_atHome = true;" \n + "_lastDir = getDir _trader;" \n + "_l = diag_tickTime;" \n + "" \n + "" \n + "" \n + "" \n + "" \n + ""/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class _ + { + priority = 5.000000; + to="reset_vars"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/""/*%FSM*/; + action=/*%FSM*/"_doneCheck = false;"/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class decision + { + name = "decision"; + init = /*%FSM*/""/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class decision_made + { + priority = 100.000000; + to="action"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"_decisionMade;"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class dispose + { + priority = 90.000000; + to="decision"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"!(alive _trader)"/*%FSM*/; + action=/*%FSM*/"_doDispose = true;" \n + "_decisionMade = true;"/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class no_decisiion + { + priority = 85.000000; + to="reset_vars"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"!_decisionMade && diag_tickTime - _t > 3;"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class look_at + { + priority = 80.000000; + to="decision"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"count _nrPlyrs >0 && diag_tickTime - _l > 3;"/*%FSM*/; + action=/*%FSM*/"_servePlyr = true;" \n + "_decisionMade = true;" \n + "_trgt = _nrPlyrs select 0;"/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class go_work + { + priority = 70.000000; + to="decision"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"(!_atWork) && (_daytime > (_schedule select 0) && _daytime < (_schedule select 1));"/*%FSM*/; + action=/*%FSM*/"_goWork = true;" \n + "_decisionMade = true;"/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class go_home + { + priority = 60.000000; + to="decision"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"(!_atHome) && (!(_daytime > (_schedule select 0) && _daytime < (_schedule select 1)));"/*%FSM*/; + action=/*%FSM*/"_goHome = true;" \n + "_decisionMade = true;"/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class action + { + name = "action"; + init = /*%FSM*/"_nrPlyrs = _trader nearEntities [_trgtArray, _tRange];"/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class actioned + { + priority = 100.000000; + to="criteria"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"_actionDone;"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class dispose + { + priority = 80.000000; + to="end"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"_doDispose;"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class interrupt + { + priority = 75.000000; + to="trade"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"_override;"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class serve + { + priority = 70.000000; + to="look_at"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"_servePlyr;"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class work + { + priority = 60.000000; + to="move_to_work"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"_goWork && !_override;"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class home + { + priority = 50.000000; + to="move_to_home"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"_goHome && !_override;"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class reset_vars + { + name = "reset_vars"; + init = /*%FSM*/"//Default Vars" \n + "" \n + "" \n + "_rnd = 0;" \n + "_actionDone = false;" \n + "_decisionMade = false;" \n + "_sWait = 0;" \n + "_doDispose = false;" \n + "_chooseTarget = false;" \n + "_criteria = Nil;" \n + "_criteriaMet = false;" \n + "_allowInterrupt = false;" \n + "_t = diag_tickTime;" \n + "" \n + "" \n + "_traderPos=[0,0,0];" \n + "_goWork = false;" \n + "_goHome = false;" \n + "_nrPlyrs = [];" \n + "_servePlyr = false;" \n + "_override = false;" \n + "" \n + "_criteriaMetAction = nil;" \n + "" \n + "_traderPos = getPosATL _trader;" \n + "_daytime = daytime;" \n + "_nrPlyrs = _trader nearEntities [_trgtArray, _sRange];"/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class _ + { + priority = 5.000000; + to="decision"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/""/*%FSM*/; + action=/*%FSM*/"_doneCheck = false;"/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class end + { + name = "end"; + init = /*%FSM*/"diag_log format[""KILLED TRADER: %1"", (!alive _trader)];"/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + }; + }; + /*%FSM*/ + /*%FSM*/ + class criteria + { + name = "criteria"; + init = /*%FSM*/"//intentionally left blank"/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class met + { + priority = 10.000000; + to="reset_vars"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"(call compile _criteria) || (diag_tickTime > (_t + _sWait));"/*%FSM*/; + action=/*%FSM*/"if (!isNil ""_criteriaMetAction"") then {" \n + "call compile _criteriaMetAction;" \n + "};"/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class _ + { + priority = 5.000000; + to="interrupt_action"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/""/*%FSM*/; + action=/*%FSM*/"_doneCheck = false;"/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class interrupt_action + { + name = "interrupt_action"; + init = /*%FSM*/""/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class player + { + priority = 10.000000; + to="decision"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"(count _nrPlyrs > 0) && _allowInterrupt;"/*%FSM*/; + action=/*%FSM*/"_trader moveTo getPos _trader;" \n + "_override = true;" \n + "_actionDone = false;"/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class _ + { + priority = 5.000000; + to="action"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/""/*%FSM*/; + action=/*%FSM*/"_doneCheck = false;"/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class move_to_work + { + name = "move_to_work"; + init = /*%FSM*/"_trader moveTo _work;" \n + "_sWait = _maxTravelTime;" \n + "_actionDone = true;" \n + "_t = diag_tickTime;" \n + "_criteria = format[""moveToCompleted %1"",""_trader""];" \n + "_criteriaMetAction = format [""_atWork = %1"",true];" \n + "_atHome = false;" \n + "_allowInterrupt = true;" \n + "" \n + "_marker = _trader getVariable[""MARKER_REF"",""""];" \n + "if (_marker != """") then {" \n + " deleteMarker _marker;" \n + " _pos = getPosATL _trader;" \n + " _marker = createMarker [str(_pos), (_pos)];" \n + " _marker setMarkerShape ""ICON"";" \n + " _marker setMarkerType ""mil_dot"";" \n + " _marker setMarkerColor ""ColorBrown"";" \n + " _trader setVariable[""MARKER_REF"", _marker];" \n + "};" \n + ""/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class _ + { + priority = 5.000000; + to="action"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/""/*%FSM*/; + action=/*%FSM*/"_doneCheck = false;"/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class move_to_home + { + name = "move_to_home"; + init = /*%FSM*/"_trader moveTo _home;" \n + "_sWait = _maxTravelTime;" \n + "_actionDone = true;" \n + "_t = diag_tickTime;" \n + "_criteria = format[""moveToCompleted %1"",""_trader""];" \n + "_criteriaMetAction = format [""_atHome = %1"",true];" \n + "_atWork = false;" \n + "_allowInterrupt = true;" \n + "" \n + "_marker = _trader getVariable[""MARKER_REF"",""""];" \n + "if (_marker != """") then {" \n + " deleteMarker _marker;" \n + " _pos = getPosATL _trader;" \n + " _marker = createMarker [str(_pos), (_pos)];" \n + " _marker setMarkerShape ""ICON"";" \n + " _marker setMarkerType ""mil_dot"";" \n + " _marker setMarkerColor ""ColorBrown"";" \n + " _trader setVariable[""MARKER_REF"", _marker];" \n + "};" \n + ""/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class _ + { + priority = 5.000000; + to="action"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/""/*%FSM*/; + action=/*%FSM*/"_doneCheck = false;"/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class look_at + { + name = "look_at"; + init = /*%FSM*/"if !(isNull _trgt) then {" \n + "_dir = [_trader, _trgt] call BIS_fnc_dirTo;" \n + "if(_lastDir != _dir)then{" \n + " _trader setDir _dir;" \n + " _lastDir = _dir;" \n + "};" \n + "};" \n + "_sWait = 1;" \n + "_actionDone = true;" \n + "_t = diag_tickTime;" \n + "_criteria = format [""%1"", true ];" \n + "_l = diag_tickTime;"/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class _ + { + priority = 5.000000; + to="action"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/""/*%FSM*/; + action=/*%FSM*/"_doneCheck = false;"/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class trade + { + name = "trade"; + init = /*%FSM*/"if !(isNull _trgt) then {" \n + " _trader setDir ([_trader, _trgt] call BIS_fnc_dirTo);" \n + "};" \n + "_sWait = 480;" \n + "_actionDone = true;" \n + "_t = diag_tickTime;" \n + "_allowInterrupt = true;" \n + "_criteria = format [""count %1 < %2"",""_nrPlyrs"",1];" \n + "" \n + "if (_goHome) then {" \n + "_criteriaMetAction = format [""%1 moveTo %2"",""_trader"",""_home""];" \n + "};" \n + "" \n + "if (_goWork) then {" \n + "_criteriaMetAction = format [""%1 moveTo %2"",""_trader"",""_work""];" \n + "};" \n + ""/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class _ + { + priority = 5.000000; + to="action"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/""/*%FSM*/; + action=/*%FSM*/"_doneCheck = false;"/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + }; + initState="trader"; + finalStates[] = + { + "end" + }; +}; +/*%FSM*/ \ No newline at end of file diff --git a/Sources/epoch_server/system/server_monitor.fsm b/Sources/epoch_server/system/server_monitor.fsm new file mode 100644 index 00000000..6750545d --- /dev/null +++ b/Sources/epoch_server/system/server_monitor.fsm @@ -0,0 +1,463 @@ +/*%FSM*/ +/*%FSM*/ +/* +item0[] = {"Init",0,250,600.000000,-575.000000,700.000000,-525.000000,0.000000,"Init"}; +item1[] = {"_",8,218,600.000000,-500.000000,700.000000,-450.000000,0.000000,""}; +item2[] = {"Process",2,250,600.000000,-350.000000,700.000000,-300.000000,0.000000,"Process"}; +item3[] = {"De_simulate_Vehicle",4,218,750.000000,-225.000000,850.000000,-175.000000,2.000000,"De-simulate" \n "Vehicle Check"}; +item4[] = {"Simulate_Vehicle",4,218,750.000000,-300.000000,850.000000,-250.000000,1.000000,"Simulate" \n "Vehicle Check"}; +item5[] = {"CMD_queue",4,218,450.000000,-450.000000,550.000000,-400.000000,10.000000,"CMD queue"}; +item6[] = {"Save_Players",4,218,450.000000,-375.000000,550.000000,-325.000000,3.000000,"Save" \n "Players"}; +item7[] = {"Cleanup",4,218,750.000000,-375.000000,850.000000,-325.000000,8.000000,"Cleanup"}; +item8[] = {"Events",4,218,450.000000,-225.000000,550.000000,-175.000000,0.000000,"Events"}; +item9[] = {"Save_Vehicles",4,218,450.000000,-300.000000,550.000000,-250.000000,4.000000,"Save" \n "Vehicles"}; +item10[] = {"Cleanup_Handler",4,218,750.000000,-450.000000,850.000000,-400.000000,8.000000,"Cleanup" \n "Handler"}; +item11[] = {"Server_FPS",4,218,600.000000,-225.000000,700.000000,-175.000000,0.000000,"Server FPS"}; +link0[] = {0,1}; +link1[] = {1,2}; +link2[] = {2,3}; +link3[] = {2,4}; +link4[] = {2,5}; +link5[] = {2,6}; +link6[] = {2,7}; +link7[] = {2,8}; +link8[] = {2,9}; +link9[] = {2,10}; +link10[] = {2,11}; +link11[] = {3,2}; +link12[] = {4,2}; +link13[] = {5,2}; +link14[] = {6,2}; +link15[] = {7,2}; +link16[] = {8,2}; +link17[] = {9,2}; +link18[] = {10,2}; +link19[] = {11,2}; +globals[] = {25.000000,1,0,0,0,640,480,1,2,6316128,1,323.926788,885.320923,-53.358742,-574.484070,948,880,1}; +window[] = {2,-1,-1,-1,-1,968,208,1646,208,3,966}; +*//*%FSM*/ +class FSM +{ + fsmName = "Server Monitor"; + class States + { + /*%FSM*/ + class Init + { + name = "Init"; + init = /*%FSM*/"diag_log ""Loaded Server FSM"";" \n + "" \n + "_serverSettingsConfig = configFile >> ""CfgEpochServer"";" \n + "_ahInitAuthCfg = [_serverSettingsConfig, ""antihack_ahInitAuthCfg"", [0,90]] call EPOCH_fnc_returnConfigEntry;" \n + "_events = [_serverSettingsConfig, ""events"", [[3600, ""CarnivalSpawner""], [2400, ""EarthQuake""], [1800, ""ChangeWeather""], [1200, ""ContainerSpawner""], [300, ""PlantSpawner""]]] call EPOCH_fnc_returnConfigEntry;" \n + "_simulationHandler = [_serverSettingsConfig, ""simulationHandler"", false] call EPOCH_fnc_returnConfigEntry;" \n + "" \n + "_initAhInitBanOrLog = _ahInitAuthCfg select 0;" \n + "_initTimeLimit = _ahInitAuthCfg select 1;" \n + "" \n + "_cmdDelay = EPOCH_hiveAdminCmdTime;" \n + "_cmdRun = EPOCH_hiveAdminCmdExec;" \n + "_savePlayerList = EPOCH_hiveAdminSavePlayerList;" \n + "" \n + "_scriptBasedRestart = EPOCH_ServerRestart;" \n + "_forceRestartTime = EPOCH_forceRestartTime;" \n + "_forceRestartTimeWarning = _forceRestartTime-300;" \n + "_prevRestartIn = 0;" \n + "_serverLocked = false;" \n + "_serverRestarting = false;" \n + "" \n + "_activeVehicles = [];" \n + "_toBeDesimulated = [];" \n + "_players = [];" \n + "_prevPlayers = [];" \n + "_cleanupItems = [];" \n + "_oldFPS = -1;" \n + "EPOCH_diag_fps = -1;" \n + "_serverFpsTime = diag_tickTime;" \n + "_serverFPSCheckFine = true;" \n + "" \n + "_safeVehicles = [""I_UAV_01_F"",""B_Heli_Transport_01_F"",""Steerable_Parachute_F"",""NonSteerable_Parachute_F"",""Land_Camping_Light_F""];" \n + "" \n + "_delayTimeSim = diag_tickTime;" \n + "_delayTimeCMD = diag_tickTime;" \n + "_delayTimeDeSim = diag_tickTime;" \n + "_delayTimeSaveVeh = diag_tickTime;" \n + "_lastWeatherChange = diag_tickTime;" \n + "_lastObjectCleanup = diag_tickTime;" \n + "_lastObjectCleanup1 = diag_tickTime;" \n + "" \n + "_pvehTime = diag_tickTime;" \n + "" \n + "_instanceID = call EPOCH_fn_InstanceID;" \n + "" \n + "_checkAuth = {" \n + " _puid = _this select 0;" \n + " _player = _this select 1;" \n + " if !(isNull _player) then {" \n + " if !(_puid call EPOCH_server_Authed) then {" \n + " _lastCheck = _player getVariable ""LAST_AUTH_CHECK"";" \n + " if (isNil ""_lastCheck"") then {" \n + " _player setVariable[""LAST_AUTH_CHECK"", diag_tickTime];" \n + " _lastCheck = diag_tickTime;" \n + " };" \n + " if (diag_tickTime - _lastCheck > _initTimeLimit) then {" \n + " _player setVariable[""LAST_AUTH_CHECK"", nil];" \n + " if (_initAhInitBanOrLog == 0) then {" \n + " 'epochserver' callExtension format['820|%1|EpochMod.com Autoban #R2', _puid];" \n + " ['ahb', format['%1 (%2): Player not Authenticated', name _player, _puid]] call EPOCH_fnc_server_hiveLog;" \n + " } else {" \n + " ['ahl', format['%1 (%2): Player not Authenticated', name _player, _puid]] call EPOCH_fnc_server_hiveLog;" \n + " };" \n + " };" \n + " } else {" \n + " _player setVariable[""LAST_AUTH_CHECK"", nil];" \n + " };" \n + " };" \n + "};" \n + "" \n + "_cleanIt = {" \n + " if !(isNull _this) then {" \n + " _lastCheck = _this getVariable ""LAST_CHECK"";" \n + " if (isNil ""_lastCheck"") then {" \n + " _this setVariable[""LAST_CHECK"", diag_tickTime];" \n + " _lastCheck = diag_tickTime;" \n + " };" \n + " if (diag_tickTime - _lastCheck > 1200) then {" \n + " _list = _this nearEntities[[""Epoch_Male_F"", ""Epoch_Female_F"", ""LandVehicle"", ""Ship"", ""Air"", ""Tank""], 45];" \n + " if ({ isPlayer _x }count _list == 0) then {" \n + " _this setVariable [""LAST_CHECK"",nil];" \n + " deleteVehicle _this;" \n + " };" \n + " };" \n + " };" \n + "};" \n + "" \n + "_cleanIt2 = {" \n + " if !(isNull _this) then {" \n + " _removed = false;" \n + " _lastCheck = _this getVariable ""LAST_CHECK"";" \n + " if (isNil ""_lastCheck"") then {" \n + " _this setVariable[""LAST_CHECK"", diag_tickTime];" \n + " _lastCheck = diag_tickTime;" \n + " };" \n + " if (diag_tickTime - _lastCheck > 1200) then {" \n + " _list = _this nearEntities[[""Epoch_Male_F"", ""Epoch_Female_F"", ""LandVehicle"", ""Ship"", ""Air"", ""Tank""], 45];" \n + " if ({ isPlayer _x }count _list == 0) then {" \n + " {" \n + " deleteVehicle _x;" \n + " }forEach nearestObjects[_this, [""WeaponHolder""], 2];" \n + " _this setVariable [""LAST_CHECK"",nil];" \n + " deleteVehicle _this;" \n + " _removed = true;" \n + " };" \n + " };" \n + " if !(_removed) then {" \n + " EPOCH_cleanupQueue pushBack _this;" \n + " };" \n + " };" \n + "};"/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class _ + { + priority = 0.000000; + to="Process"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"true"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class Process + { + name = "Process"; + init = /*%FSM*/""/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class CMD_queue + { + priority = 10.000000; + to="Process"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"_cmdRun && ((diag_tickTime - _delayTimeCMD) > _cmdDelay)"/*%FSM*/; + action=/*%FSM*/"_delayTimeCMD = diag_tickTime;" \n + "" \n + "// Execute next item from CMD queue" \n + "_response = ""epochserver"" callExtension format[""600|%1"",_instanceID];" \n + "if (_response != '[1,""""]') then { " \n + " _output = call compile _response; " \n + " if (_output select 0 == 1 && _output select 1 != """") then {" \n + " 0 spawn compile (_output select 1);" \n + " };" \n + "};" \n + ""/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class Cleanup + { + priority = 8.000000; + to="Process"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"((diag_tickTime - _lastObjectCleanup1) > 1)"/*%FSM*/; + action=/*%FSM*/"_lastObjectCleanup1 = diag_tickTime;" \n + "" \n + "if !(_cleanupItems isEqualTo []) then {" \n + " (_cleanupItems deleteAt 0) call _cleanIt;" \n + "};" \n + "if !(EPOCH_cleanupQueue isEqualTo []) then {" \n + " (EPOCH_cleanupQueue deleteAt 0) call _cleanIt2;" \n + "};"/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class Cleanup_Handler + { + priority = 8.000000; + to="Process"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"((diag_tickTime - _lastObjectCleanup) > 300)"/*%FSM*/; + action=/*%FSM*/"_lastObjectCleanup = diag_tickTime;" \n + "" \n + "// TODO need better way allMissionObjects is not performant" \n + "if (_cleanupItems isEqualTo []) then {" \n + " _cleanupItems = allMissionObjects ""groundWeaponHolder"" + entities ""Land_MPS_EPOCH"" + entities ""WeaponHolderSimulated"";" \n + "};"/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class Save_Vehicles + { + priority = 4.000000; + to="Process"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"((diag_tickTime - _delayTimeSaveVeh) > 1)"/*%FSM*/; + action=/*%FSM*/"_delayTimeSaveVeh = diag_tickTime;" \n + "if !(EPOCH_saveVehQueue isEqualTo []) then {" \n + " _saveVehicle = EPOCH_saveVehQueue deleteAt 0;" \n + " if !(isNull _saveVehicle) then {" \n + " _saveVehicle call EPOCH_server_save_vehicle;" \n + " };" \n + "};" \n + "if !(EPOCH_saveStorQueue isEqualTo []) then {" \n + " _saveStorage = EPOCH_saveStorQueue deleteAt 0;" \n + " if !(isNull _saveStorage) then {" \n + " _saveStorage call EPOCH_server_save_storage;" \n + " };" \n + "};" \n + "if !(EPOCH_saveBuildQueue isEqualTo []) then {" \n + " _saveBuilding = EPOCH_saveBuildQueue deleteAt 0;" \n + " if !(isNull _saveBuilding) then {" \n + " _saveBuilding call EPOCH_fnc_saveBuilding;" \n + " };" \n + "};"/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class Save_Players + { + priority = 3.000000; + to="Process"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"!(_players isEqualTo _prevPlayers)"/*%FSM*/; + action=/*%FSM*/"_prevPlayers = _players;" \n + "" \n + "if (_savePlayerList) then {" \n + " [""PLAYERS"", (call EPOCH_fn_InstanceID), _players] call EPOCH_fnc_server_hiveSET;" \n + "};" \n + "" \n + "{if (units _x isEqualTo []) then {deleteGroup _x}}forEach allGroups"/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class De_simulate_Vehicle + { + priority = 2.000000; + to="Process"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"((diag_tickTime - _delayTimeDeSim) > 12)"/*%FSM*/; + action=/*%FSM*/"_delayTimeDeSim = diag_tickTime;" \n + "" \n + "if !(_activeVehicles isEqualTo []) then {" \n + " _selectedVehicle = _activeVehicles deleteAt 0;" \n + " if !(isNull _selectedVehicle) then {" \n + " _deSim = false;" \n + " if (crew _selectedVehicle isEqualTo []) then {" \n + " if ((getPos _selectedVehicle) select 2 < 1) then {" \n + " if ({isPlayer _selectedVehicle} count (_selectedVehicle nearEntities[[""CAManBase"", ""LandVehicle"", ""Ship"", ""Air"", ""Tank""], 300]) == 0) then {" \n + " _selectedVehicle enableSimulationGlobal false;" \n + " _deSim = true;" \n + " };" \n + " };" \n + " };" \n + " // add vehicle to back of list for later de-simulation" \n + " if !(_deSim) then {" \n + " _activeVehicles pushBack _selectedVehicle;" \n + " };" \n + " };" \n + "};"/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class Simulate_Vehicle + { + priority = 1.000000; + to="Process"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"((diag_tickTime - _delayTimeSim) > 5)"/*%FSM*/; + action=/*%FSM*/"_delayTimeSim = diag_tickTime;" \n + "_playersTemp = [];" \n + "{ " \n + " if (isPlayer _x) then {" \n + " if (_simulationHandler) then {" \n + " {" \n + " if !(typeOf _x in _safeVehicles) then {" \n + " if (_x call EPOCH_server_getVToken) then {" \n + " if !(simulationEnabled _x) then {" \n + " _x enableSimulationGlobal true;" \n + " _activeVehicles pushBack _x;" \n + " };" \n + " } else {" \n + " deleteVehicle _x;" \n + " };" \n + " };" \n + " }forEach (_x nearEntities[[""LandVehicle"", ""Ship"", ""Air"", ""Tank""], 300]);" \n + " };" \n + "" \n + " _pUID = getPlayerUID _x;" \n + "" \n + " if !(_x call EPOCH_server_isPAdmin) then {" \n + " if (isObjectHidden _x) then {" \n + " _x hideObjectGlobal false;" \n + " };" \n + " if (_pUID != """") then {" \n + " _playersTemp pushBack _pUID;" \n + " [_pUID, _x] call _checkAuth;" \n + " };" \n + " } else {" \n + " if (_pUID != """") then { _playersTemp pushBack _pUID; };" \n + " };" \n + " };" \n + "}forEach playableUnits;" \n + "_players = _playersTemp;"/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class Server_FPS + { + priority = 0.000000; + to="Process"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"((diag_tickTime - _serverFpsTime) > 30) && _serverFPSCheckFine"/*%FSM*/; + action=/*%FSM*/"_serverFpsTime = diag_tickTime;" \n + "" \n + "if (_oldFPS isEqualTo EPOCH_diag_fps) then {" \n + " _currentFPS = round(diag_fps);" \n + " if !(_oldFPS isEqualTo _currentFPS) then {" \n + " EPOCH_diag_fps = _currentFPS;" \n + " publicVariable ""EPOCH_diag_fps"";" \n + " _oldFPS = _currentFPS;" \n + " };" \n + "} else {" \n + " EPOCH_diag_fps = compileFinal """";" \n + " publicVariable ""EPOCH_diag_fps"";" \n + " _serverFPSCheckFine = false;" \n + "};" \n + ""/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class Events + { + priority = 0.000000; + to="Process"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"((diag_tickTime - _pvehTime) > 20)"/*%FSM*/; + action=/*%FSM*/"_pvehTime = diag_tickTime;" \n + "call EPOCH_server_publicEH;" \n + "" \n + "removeAllMissionEventHandlers ""HandleDisconnect"";" \n + "addMissionEventHandler [""HandleDisconnect"", { _this call EPOCH_server_onPlayerDisconnect }];" \n + "" \n + "onPlayerDisconnected{ " \n + " diag_log format[""playerDisconnected:%1:%2"", _uid, _name]; " \n + " ['Disconnected', [_uid, _name]] call EPOCH_fnc_server_hiveLog;" \n + " _uid call EPOCH_server_disconnect;" \n + "};" \n + "onPlayerConnected{" \n + " ""epochserver"" callExtension format[""001|%1"", _uid];" \n + " diag_log format[""playerConnected:%1:%2"", _uid, _name];" \n + " ['Connected', [_uid, _name]] call EPOCH_fnc_server_hiveLog;" \n + " [""PlayerData"", _uid, EPOCH_expiresPlayer, [_name]] call EPOCH_fnc_server_hiveSETEX;" \n + "};" \n + "" \n + "{" \n + " _eventKey = format[""EPOCH_EVENT_%1"", _forEachIndex];" \n + " _lastTime = missionNamespace getVariable _eventKey;" \n + " if (isNil ""_lastTime"") then {" \n + " missionNamespace setVariable[_eventKey, diag_tickTime];" \n + " _lastTime = diag_tickTime;" \n + " };" \n + " if ((diag_tickTime - _lastTime) >= (_x select 0)) then {" \n + " missionNamespace setVariable[_eventKey, diag_tickTime];" \n + " _handle = [] execVM format[""\a3_epoch_server_settings\EpochEvents\%1.sqf"",_x select 1];" \n + " diag_log format[""DEBUG: _event %1"", _x select 1];" \n + " };" \n + "} forEach _events;" \n + "" \n + "// restart script" \n + "if (_scriptBasedRestart) then {" \n + " if (diag_tickTime >= _forceRestartTimeWarning) then {" \n + " if (!_serverLocked) then {" \n + " diag_log ""server shutdown: locked"";" \n + " _serverLocked = true;" \n + " [""lock""] call EPOCH_serverCommand;" \n + " };" \n + " " \n + " _restartIn = round((_forceRestartTime-diag_tickTime)/60);" \n + "" \n + " if (_prevRestartIn != _restartIn) then {" \n + " _prevRestartIn = _restartIn;" \n + " if (_restartIn > 1) then {" \n + " [""message"", format[""Server restart in %1 minutes"",_restartIn]] call EPOCH_serverCommand;" \n + " } else {" \n + " [""message"", format[""Server restart in %1 minute"",1]] call EPOCH_serverCommand;" \n + " };" \n + " };" \n + " };" \n + "" \n + " // kick all remaining players before shutdown to force player save" \n + " if (diag_tickTime >= _forceRestartTime) then {" \n + " if (_serverRestarting) then {" \n + " [""shutdown""] call EPOCH_serverCommand;" \n + " diag_log ""server shutdown: now"";" \n + " } else {" \n + " {" \n + " if (isPlayer _x) then {" \n + " [""kick"", _x , ""Server Restarting""] call EPOCH_serverCommand;" \n + " };" \n + " } forEach playableUnits;" \n + " diag_log format [""server shutdown: kicking players %1"",playableUnits];" \n + " _serverRestarting = true;" \n + " };" \n + " };" \n + "};"/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + }; + initState="Init"; + finalStates[] = + { + }; +}; +/*%FSM*/ \ No newline at end of file