diff --git a/CHANGE LOG 1.0.6.txt b/CHANGE LOG 1.0.6.txt index b24a56b5d..6bd1feee0 100644 --- a/CHANGE LOG 1.0.6.txt +++ b/CHANGE LOG 1.0.6.txt @@ -54,7 +54,8 @@ [NEW] Death messages now use a PVEH instead of the unreliable MPHit. Added localization, more causes of death, systemChat and dynamicText killfeed options. @ebaydayz [NEW] Parachute can now auto open at a set height during HALO jump. Altitude and speed meter can also be enabled. See configVariables.sqf. @ebaydayz [NEW] Added hatch, fold and ramp animation UserActions to ArmoredSUV, AH1Z, MV22 and UH1Y configs. @ebaydayz -[NEW] VON in side and global is now blocked by default. See configVariables.sqf to change blocked VON channels. @icomrade +[NEW] VON in side and global is now blocked by default. See configVariables.sqf to change blocked VON channels. @icomrade @ebayShopper +[NEW] Arma cheat input (LeftShift + NumPad-) is now blocked by default to prevent abuse of FPS cap and EndMission commands for duping. @icomrade [CHANGED] Combattimeout now uses diag_tickTime instead of time. [CHANGED] AmmoBoxSmall_556/762 is replaced with DZ_AmmoBoxUS/RU/EU/CZ and MedBox0 is replaced with DZ_MedBox (new model) diff --git a/SQF/dayz_code/Configs/RscDisplay/RscMap.hpp b/SQF/dayz_code/Configs/RscDisplay/RscMap.hpp index c3f187357..9d77d01bf 100644 --- a/SQF/dayz_code/Configs/RscDisplay/RscMap.hpp +++ b/SQF/dayz_code/Configs/RscDisplay/RscMap.hpp @@ -1,6 +1,5 @@ class RscDisplayMainMap { - onKeyDown = "if (!isNil 'DZE_FilterCheats') then {_this call DZE_FilterCheats;}; false"; class controls { delete CA_MainBackground; diff --git a/SQF/dayz_code/Configs/rscTitles.hpp b/SQF/dayz_code/Configs/rscTitles.hpp index 88817df04..96c9fbcc8 100644 --- a/SQF/dayz_code/Configs/rscTitles.hpp +++ b/SQF/dayz_code/Configs/rscTitles.hpp @@ -1,3 +1,4 @@ +#define FILTER_CHEATS "_handled = if (isNil 'dze_filterCheats') then {false} else {_this call dze_filterCheats}; _handled" class RscPicture; class RscButton; class CA_IGUI_Title; @@ -37,18 +38,19 @@ class RscDisplayMission: RscDisplayEmpty { access = 0; idd = 46; - onKeyDown = "if (!isNil 'DZ_KeyDown_EH') then {_this call DZ_KeyDown_EH;};"; //assigned much quicker than spawning init_keyboard + onKeyDown = "_handled = if (isNil 'DZ_KeyDown_EH') then {false} else {_this call DZ_KeyDown_EH}; _handled"; //assigned much quicker than spawning init_keyboard }; class RscDisplayConfigure { idd = 4; onUnload = "if (!isNil 'updateControlsHandle') then {terminate updateControlsHandle;}; if (!isNil 'ui_updateControls') then {updateControlsHandle = true spawn ui_updateControls;};"; - class controlsBackground; - class controls; + onKeyDown = FILTER_CHEATS; }; class RscDisplayGameOptions { onLoad = "{(_this select 0) displayCtrl 140 lbAdd _x;} forEach [localize 'STR_DISABLED',localize 'STR_ENABLED']; (_this select 0) displayCtrl 140 lbSetCurSel (profileNamespace getVariable ['streamerMode',0]); uiNamespace setVariable ['streamerMode',(profileNamespace getVariable ['streamerMode',0])];"; onUnload = "call ui_changeDisplay;"; + onKeyDown = FILTER_CHEATS; class controls { + delete CA_ButtonDefault; //Opens non-functional difficulty selection dialog, player can not select difficulty in MP class CA_TextLanguage : RscText { x = 0.159803; y = (0.420549 + -2*0.069854); @@ -91,26 +93,19 @@ class RscDisplayGameOptions { }; }; }; -class RscDisplayChat -{ - idd = 24; - onKeyDown = "if (!isNil 'DZE_FilterCheats') then {_this call DZE_FilterCheats;}; false"; - class controls; -}; +class RscDisplayChat {onKeyDown = FILTER_CHEATS;}; +class RscDisplayOptions {onKeyDown = FILTER_CHEATS;}; +class RscDisplayOptionsAudio {onKeyDown = FILTER_CHEATS;}; +class RscDisplayOptionsVideo {onKeyDown = FILTER_CHEATS;}; +class RscDisplayConfigureControllers {onKeyDown = FILTER_CHEATS;}; class RscDisplayChannel { idd = 63; - onKeyDown = "_handle = if (!isNil 'DZE_FilterCheats') then {_this call DZE_FilterCheats} else {false}; _handle"; - onMouseButtonDown = "_handle = if (!isNil 'DZE_FilterCheats') then {[0,(_this select 1),false] call DZE_FilterCheats} else {false}; _handle"; - class controls; -}; -class RscDisplayVoiceChat -{ - idd = 55; - onKeyDown = "_handle = if (!isNil 'DZE_FilterCheats') then {_this call DZE_FilterCheats} else {false}; _handle"; - onMouseButtonDown = "_handle = if (!isNil 'DZE_FilterCheats') then {[0,(_this select 1),false] call DZE_FilterCheats} else {false}; _handle"; - class controls; + //Channel name text is nil when checking unscheduled in onLoad of display 55 and 63. Spawn gives it time to set. + //This will fire when a mouse button is assigned. KeyDown EHs will not. + onLoad = "if (!isNil 'dze_filterCheats' && !isNil 'channel_keys') then {[(_this select 0),-1,false] spawn dze_filterCheats;};"; }; + class RscPictureGUI { access = 0; @@ -332,7 +327,7 @@ class RscDisplayMain : RscStandardDisplay class RscDisplayDiary { idd = 129; movingEnable = 0; - onKeyDown = "if (!isNil 'DZE_FilterCheats') then {_this call DZE_FilterCheats;}; false"; + onKeyDown = FILTER_CHEATS; class Controls { delete Diary; @@ -442,8 +437,8 @@ class RscDisplayMPInterrupt : RscStandardDisplay { //onLoad = "_dummy = ['Init', _this] execVM '\ca\ui\scripts\pauseLoadinit.sqf'; [(_this select 0)] execVM '\z\addons\dayz_code\compile\player_onPause.sqf';"; _respawn = (_this select 0) displayCtrl 1010); _respawn ctrlEnable false; _abort = (_this select 0) displayCtrl 104); _abort ctrlEnable false; onLoad = "uiNamespace setVariable ['RscDisplayMPInterrupt', _this select 0]; _this call fn_pauseMenuChecks; [] spawn player_onPause; _dummy = ['Init', _this] execVM '\ca\ui\scripts\pauseLoadinit.sqf';"; /*diag_log[diag_tickTime,'RscDisplayMPInterrupt'];*/ onUnload = "uiNamespace setVariable ['RscDisplayMPInterrupt', nil];['Unload', _this] execVM '\ca\ui\scripts\pauseOnUnload.sqf';"; - onKeyDown = "_handle = if (!isNil 'DZE_FilterCheats') then {_this call DZE_FilterCheats} else {false}; _handle"; - + onKeyDown = FILTER_CHEATS; + class controlsBackground { class Mainback : RscPicture { idc = 1104; diff --git a/SQF/dayz_code/compile/keyboard.sqf b/SQF/dayz_code/compile/keyboard.sqf index fabbdf6c4..6b7b4714d 100644 --- a/SQF/dayz_code/compile/keyboard.sqf +++ b/SQF/dayz_code/compile/keyboard.sqf @@ -43,6 +43,10 @@ if (isNil "keyboard_keys") then { }; _handled = true; }; + _filterCheat = { + //Overriding default engine handling does not stop cheat input, need manual disableUserInput too + _handled = [displayNull,_dikCode,_shiftState] call dze_filterCheats; + }; _openGroups = { if (dayz_requireRadio && !("ItemRadio" in items player)) then { localize "STR_EPOCH_NEED_RADIO" call dayz_rollingMessages; @@ -144,7 +148,10 @@ if (isNil "keyboard_keys") then { }; // TODO: left/right, when gear open: onKeyDown = "[_this,'onKeyDown',0,107,0,107] execVM '\z\addons\dayz_code\system\handleGear.sqf'"; _noise = { - if (diag_ticktime - dayz_lastCheckBit > 10) then { + //Overriding default engine handling does not stop combination binds, need manual disableUserInput too + _handled = [displayNull,_dikCode,_shiftState] call dze_filterCheats; + + if (diag_ticktime - dayz_lastCheckBit > 10 && !(_dikCode in channel_keys)) then { dayz_lastCheckBit = diag_ticktime; [player,20,true,(getPosATL player)] call player_alertZombies; }; @@ -245,6 +252,10 @@ if (isNil "keyboard_keys") then { }; keyboard_keys = []; + channel_keys = []; + voice_keys = []; + {voice_keys = voice_keys + (actionKeys _x)} count voice_actions; + {channel_keys = channel_keys + (actionKeys _x)} count ["NextChannel","PrevChannel"]; keyboard_keys resize 256; [[DIK_ESCAPE], _cancelBuild] call _addArray; [[DIK_INSERT], {DZE_Q_alt = true;}] call _addArray; @@ -255,6 +266,7 @@ if (isNil "keyboard_keys") then { [[DIK_Q], {DZE_4 = true;}] call _addArray; [[DIK_E], {DZE_6 = true;}] call _addArray; [[DIK_0], _autoRun] call _addArray; + [[DIK_NUMPADMINUS], _filterCheat] call _addArray; [[DIK_SPACE], {DZE_5 = true;}] call _addArray; [actionKeys "User6", {DZE_F = true;}] call _addArray; [actionKeys "User7", {DZE_Q_ctrl = true;}] call _addArray; @@ -280,9 +292,16 @@ if (isNil "keyboard_keys") then { [actionKeys "MoveBack", _interrupt] call _addArray; [actionKeys "TurnLeft", _interrupt] call _addArray; [actionKeys "TurnRight", _interrupt] call _addArray; - [actionKeys "PushToTalk", _noise] call _addArray; + [actionKeys "PushToTalk", _noise] call _addArray; + [actionKeys "PushToTalkAll", _noise] call _addArray; + [actionKeys "PushToTalkCommand", _noise] call _addArray; + [actionKeys "PushToTalkDirect", _noise] call _addArray; + [actionKeys "PushToTalkGroup", _noise] call _addArray; + [actionKeys "PushToTalkSide", _noise] call _addArray; + [actionKeys "PushToTalkVehicle", _noise] call _addArray; [actionKeys "VoiceOverNet", _noise] call _addArray; - [actionKeys "PushToTalkDirect", _noise] call _addArray; + [actionKeys "NextChannel", _noise] call _addArray; + [actionKeys "PrevChannel", _noise] call _addArray; [actionKeys "Chat", _noise] call _addArray; [actionKeys "User20", _journal] call _addArray; [actionKeys "Diary", _journal] call _addArray; @@ -310,12 +329,10 @@ if (isNil "keyboard_keys") then { if (!isNil "bis_fnc_halo_keydown_eh") then {bis_fnc_halo_keydown_eh = (finddisplay 46) displayaddeventhandler ["keydown","_this call bis_fnc_halo_keydown;"];}; // halo in progress }; -_CheatHandled = _this call DZE_FilterCheats; - if (r_player_unconsciousInputDisabled) exitWith {true}; _code = keyboard_keys select _dikCode; if (!isNil "_code") then { call _code; }; -(_handled || _CheatHandled); \ No newline at end of file +_handled \ No newline at end of file diff --git a/SQF/dayz_code/compile/player_filterCheats.sqf b/SQF/dayz_code/compile/player_filterCheats.sqf new file mode 100644 index 000000000..eccb970bd --- /dev/null +++ b/SQF/dayz_code/compile/player_filterCheats.sqf @@ -0,0 +1,50 @@ +/* + Overriding default engine handling does not stop cheat input. + It also does not stop VON when combination binds like Ctrl+Z are used, because keyDown registers each key press individually. + We need to manually disable user input. +*/ +#include "\ca\editor\Data\Scripts\dikCodes.h" +_dik = _this select 1; +_shift = _this select 2; + +_handled = false; +_channel = ctrlText (findDisplay 63 displayCtrl 101); +_micIcon = ctrlShown (findDisplay 55 displayCtrl 101); +_inputAction1 = {inputAction _x > 0} count voice_actions; //Includes mouse buttons and combination binds, but does not work when a dialog is open +_inputAction2 = {inputAction _x > 0} count ["NextChannel","PrevChannel"]; +/* + _channel = previous channel when changing channels. + We can not predict which one that will be, because description.ext settings vary. + So block all changing of channels while mic is locked on for now. +*/ +_channelChange = _micIcon && ((!isNull findDisplay 24 && _dik in [DIK_DOWN,DIK_UP]) or (_dik in channel_keys) or (_inputAction2 > 0)); +_blockVoice = _channelChange or ((_dik in voice_keys or (_inputAction1 > 0)) && (_channel in DZE_DisabledChannels)); + +if ((_dik == DIK_NUMPADMINUS && _shift) or _blockVoice) then { + if (!_blockVoice) then {call player_forceSave;}; //Perform before disableUserInput to prevent reenable + disableUserInput true;disableUserInput true; + if (_blockVoice) then {findDisplay 55 closeDisplay 2;}; + + [_blockVoice,_channel,_channelChange] spawn { + _blockVoice = _this select 0; + _channel = _this select 1; + _channelChange = _this select 2; + _testTime = diag_tickTime; + CheatsDisabled = _testTime; + switch true do { + case _channelChange: {[localize "STR_EPOCH_NO_CHANNEL_SWITCH",1] call dayz_rollingMessages;}; + case _blockVoice: {[format[localize "STR_EPOCH_NO_VOICE",_channel],1] call dayz_rollingMessages;}; + default {[localize "STR_EPOCH_NO_CHEATS",1] call dayz_rollingMessages;}; + }; + uiSleep 5; + if (!r_player_unconsciousInputDisabled && CheatsDisabled == _testTime) then { + //Enable input, disable and reenable to prevent the last key press being input after re-enable + disableUserInput false;disableUserInput true;disableUserInput false;disableUserInput false; + }; + }; + _handled = true; +}; + +//diag_log format["FilterCheats - Display:%7 DIK:%1 Channel:%2 ChannelChange:%3 BlockVoice:%4 Handled:%5 MicIcon:%6 InputAction1:%8 InputAction2:%9",_dik,_channel,_channelChange,_blockVoice,_handled,_micIcon,(_this select 0),_inputAction1,_inputAction2]; + +_handled \ No newline at end of file diff --git a/SQF/dayz_code/compile/ui_updateControls.sqf b/SQF/dayz_code/compile/ui_updateControls.sqf index 761a2b6c3..91cea6209 100644 --- a/SQF/dayz_code/compile/ui_updateControls.sqf +++ b/SQF/dayz_code/compile/ui_updateControls.sqf @@ -3,11 +3,6 @@ private ["_holdBreath","_turboKey"]; //Sleep required for actionKeys to update after controls dialog closes uiSleep 1; -dayz_voiceControls = []; -DayZ_channelChangeKeys = []; -{dayz_voiceControls = dayz_voiceControls + (actionKeys _x)} count ["voiceOverNet","PushToTalk","PushToTalkAll","PushToTalkCommand","PushToTalkDirect","PushToTalkGroup","PushToTalkSide","PushToTalkVehicle"]; -{DayZ_channelChangeKeys = DayZ_channelChangeKeys + (actionKeys _x)} count ["NextChannel","PrevChannel"]; - //Refresh keyboard_keys after controls change if (_this) then { keyboard_keys = nil; diff --git a/SQF/dayz_code/init/compiles.sqf b/SQF/dayz_code/init/compiles.sqf index 20b834499..5d0bc7d8f 100644 --- a/SQF/dayz_code/init/compiles.sqf +++ b/SQF/dayz_code/init/compiles.sqf @@ -162,6 +162,7 @@ if (!isDedicated) then { // EPOCH ADDITIONS autoRunOff = {autoRunActive = false; terminate autoRunThread; player playActionNow "Stop";}; dog_findTargetAgent = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\dog_findTargetAgent.sqf"; + dze_filterCheats = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\player_filterCheats.sqf"; dze_isnearest_player = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\dze_isNearestPlayer.sqf"; dze_buildChecks = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\dze_buildChecks.sqf"; dze_requiredItemsCheck = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\dze_requiredItemsCheck.sqf"; @@ -693,44 +694,6 @@ FNC_GetPos = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\fnc_ dayz_EjectPlayer = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\dze_ejectPlayer.sqf"; dayz_groupInvite = compile preprocessFileLineNumbers "\z\addons\dayz_code\groups\handleInvite.sqf"; -DZE_FilterCheats = { - #include "\ca\editor\Data\Scripts\dikCodes.h" - _dik = _this select 1; - _shift = _this select 2; - _voiceLocked = (ctrlShown ((FindDisplay 55) displayCtrl 101)); - _textBoxShown = (ctrlShown ((FindDisplay 24) displayCtrl 101)); - //we need to check inputAction as well since ArmA is soooooo reliable that dik codes don't work with double tap or combination ActionKey mappings... - // Additionally inputAction does not work in dialogs, such as the escape menu, that are not the main display. - _channelChange = ((_dik in DayZ_channelChangeKeys) || {(inputAction "PrevChannel") > 0} || {(inputAction "NextChannel") > 0}); - _inputActionCheck = ({(inputAction _x) > 0} count ["voiceOverNet","PushToTalk","PushToTalkAll","PushToTalkCommand","PushToTalkDirect","PushToTalkGroup","PushToTalkSide","PushToTalkVehicle"]) > 0; - _isVoiceChat = ((_dik in dayz_voiceControls || _inputActionCheck) && {ctrlText (findDisplay 63 displayCtrl 101) in DZE_DisabledChannels}); //getting display directly from _this select 0 isn't reliable for chat channels! - _ChannelChangeWithVoice = ((_voiceLocked && _channelChange) || {_voiceLocked && _textBoxShown && ((_dik == DIK_DOWN) || (_dik == DIK_UP))}); - if ((_dik == DIK_NUMPADMINUS && _shift) || _isVoiceChat || _ChannelChangeWithVoice) then { - if (!_isVoiceChat) then {call player_forceSave;}; - disableUserInput true;disableUserInput true; - [_isVoiceChat, _ChannelChangeWithVoice] spawn { //disable input, this is unfortunately the only way to stop cheat input - _testTime = diag_tickTime; - CheatsDisabled = _testTime; - if (_this select 0 || _this select 1) then { - if (_this select 0) then { - titleText [(Format ["No voice chat in: %1", DZE_DisabledChannels]), "PLAIN", 1]; - } else { - titleText ["You may not change chat channels while VON is active!", "PLAIN", 1]; - }; - uiSleep 2; - } else { - titleText ["DO NOT ENTER CHEATS, WAIT 5 SECONDS TO CONTINUE!", "PLAIN", 1]; - uiSleep 5; - }; - if (!r_player_unconsciousInputDisabled && CheatsDisabled == _testTime) then { - //weird disableuserInput behavior, enable input, disable and reenable to prevent the last key press being input after re-enable - disableUserInput false;disableUserInput true;disableUserInput false;disableUserInput false; - }; - }; - }; - (_isVoiceChat || _ChannelChangeWithVoice); -}; - player_sumMedical = { private["_character","_wounds","_legs","_arms","_medical","_status"]; _character = _this; diff --git a/SQF/dayz_code/init/variables.sqf b/SQF/dayz_code/init/variables.sqf index 483cf0ed8..fdf9cfd58 100644 --- a/SQF/dayz_code/init/variables.sqf +++ b/SQF/dayz_code/init/variables.sqf @@ -684,10 +684,7 @@ if (!isDedicated) then { dayz_getout = objNull; dayz_getoutTime = 0; dayz_HitBy = objNull; - dayz_voiceControls = []; - DayZ_channelChangeKeys = []; - {dayz_voiceControls = dayz_voiceControls + (actionKeys _x)} count ["voiceOverNet","PushToTalk","PushToTalkAll","PushToTalkCommand","PushToTalkDirect","PushToTalkGroup","PushToTalkSide","PushToTalkVehicle"]; - {DayZ_channelChangeKeys = DayZ_channelChangeKeys + (actionKeys _x)} count ["NextChannel","PrevChannel"]; + voice_actions = ["voiceOverNet","PushToTalk","PushToTalkAll","PushToTalkCommand","PushToTalkDirect","PushToTalkGroup","PushToTalkSide","PushToTalkVehicle"]; // EPOCH ADDITIONS if (isNil "DZE_BackpackAntiTheft") then {DZE_BackpackAntiTheft = false;}; diff --git a/SQF/dayz_code/stringtable.xml b/SQF/dayz_code/stringtable.xml index 0884a3f4c..e3ebc67d5 100644 --- a/SQF/dayz_code/stringtable.xml +++ b/SQF/dayz_code/stringtable.xml @@ -11005,6 +11005,15 @@ + + Do not enter cheats. Wait five seconds to continue. + + + No voice in %1. Wait five seconds to continue. + + + No switching channels while VON is active. Wait five seconds to continue. + %1 has been gutted, zombie parts are now on the carcass Du hast den Zombie (%1) ausgenommen und kannst das Fleisch jetzt abschneiden.