Improve filterCheats and VON block

Filter cheats is now added to the main options menus that needed it.

It is not needed on the map (display 12) because KeyDown for display 46
also fires when it is open. So filterCheats was firing twice (once on
each display) in that case.

KeyDown does not fire on display 63 at all
regardless of whether PTT or VON is held down, toggled or chat open.
Keydown does fire on 55, but only after the mic icon is locked on, so it
is of limited use. MouseButtonDown does not fire on 55 or 63. So it is
useless to add to those displays. You can confirm this with:
(findDisplay 63) displayAddEventHandler ["KeyDown","systemchat
'fired';"];

Filter cheats is now only checked on display 46 when a
voice, channel, or cheat key is pressed instead of on every key press.
This still works 100% of the time for blocking cheat input. For
performance reasons it's probably not worth checking all the conditions
in filterCheats with every key press on display46 just for the VON
block. Doing so covers some edge combination bind cases better, so it
may be worth considering again if no better alternative is found. For
now this solution is good enough to cover the majority of cases without
slowing down the keyhandler during normal usage.

The VON message now
tells you exactly which channel block you triggered instead of listing
all of them.

Fixed issue mentioned in 52c9c7c with VON getting stuck on when using a
double tap keybind.

Tested:
1. Talk in side with regular/combo/mouse bind
2. Change channels
while mic is locked on with regular/combo/mouse bind
3. Change channels
with Up/Down arrows while chat is open.
4. Trying all cases in steps 1-3
with a dialog open.

It is possible to bypass the VON block with some different control
settings and combinations of the above, but for default controls and
common usage it works the majority of the time.
This commit is contained in:
ebaydayz
2016-11-29 23:43:54 -05:00
parent 429a6aec9b
commit 416fdbc4ab
9 changed files with 103 additions and 77 deletions

View File

@@ -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)

View File

@@ -1,6 +1,5 @@
class RscDisplayMainMap
{
onKeyDown = "if (!isNil 'DZE_FilterCheats') then {_this call DZE_FilterCheats;}; false";
class controls
{
delete CA_MainBackground;

View File

@@ -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;

View File

@@ -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);
_handled

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;};

View File

@@ -11005,6 +11005,15 @@
</Key>
</Package>
<Package name="dayz_epoch">
<Key ID="STR_EPOCH_NO_CHEATS">
<English>Do not enter cheats. Wait five seconds to continue.</English>
</Key>
<Key ID="STR_EPOCH_NO_VOICE">
<English>No voice in %1. Wait five seconds to continue.</English>
</Key>
<Key ID="STR_EPOCH_NO_CHANNEL_SWITCH">
<English>No switching channels while VON is active. Wait five seconds to continue.</English>
</Key>
<Key ID="str_success_gutted_zombie">
<English>%1 has been gutted, zombie parts are now on the carcass</English>
<German>Du hast den Zombie (%1) ausgenommen und kannst das Fleisch jetzt abschneiden.</German>