diff --git a/addons/armaos/XEH_PREP.hpp b/addons/armaos/XEH_PREP.hpp index 4fd158b..55f696e 100644 --- a/addons/armaos/XEH_PREP.hpp +++ b/addons/armaos/XEH_PREP.hpp @@ -49,6 +49,8 @@ PREP(computer_addGames); PREP(computer_getLocality); +PREP(computer_clone); + /* OS Link Functions */ PREP(link_add); PREP(link_init); diff --git a/addons/armaos/XEH_preInit.sqf b/addons/armaos/XEH_preInit.sqf index 7ba7569..156d321 100644 --- a/addons/armaos/XEH_preInit.sqf +++ b/addons/armaos/XEH_preInit.sqf @@ -80,4 +80,46 @@ false // Setting will be marked as needing mission restart after being changed. (optional, default false) ] call CBA_fnc_addSetting; +/* ================================================================================ */ + +[ + "AE3_MaxTerminalBufferLines", + "EDITBOX", + ["STR_AE3_Main_CbaSettings_MaxTerminalBufferLinesName", "STR_AE3_Main_CbaSettings_MaxTerminalBufferLinesTooltip"], + "STR_AE3_ArmaOS_CbaSettings_ArmaOSCategoryName", + "100", + nil, // "_isGlobal" flag. Set this to true to always have this setting synchronized between all clients in multiplayer + { + params ["_value"]; + + // use an editbox to manage a number + + // string to number + _value = parseNumber _value; + + // float to int + _value = round _value; + + // ignore negative values; -1 means "no limit" + if (_value < -1) then { _value = 100; }; + + // if 0 then reset to default + if (_value == 0) then { _value = 100; }; + + // write/sync changed value back to CBA settings + if (!isMultiplayer || (isServer && hasInterface)) then + { + // In singeplayer or as host in a multiplayer session + ["AE3_MaxTerminalBufferLines", str _value, 0, "server", true] call CBA_settings_fnc_set; + } + else + { + // As client in a multiplayer session + ["AE3_MaxTerminalBufferLines", str _value, 0, "client", true] call CBA_settings_fnc_set; + }; + + }, // function that will be executed once on mission start and every time the setting is changed. + false // Setting will be marked as needing mission restart after being changed. (optional, default false) +] call CBA_fnc_addSetting; + /* ================================================================================ */ \ No newline at end of file diff --git a/addons/armaos/functions/fnc_computer_clone.sqf b/addons/armaos/functions/fnc_computer_clone.sqf new file mode 100644 index 0000000..32af6df --- /dev/null +++ b/addons/armaos/functions/fnc_computer_clone.sqf @@ -0,0 +1,29 @@ +/** + * PUBLIC - Execution on server only + * + * This function clones filesystem, links (commands) and the userlist from computer1 to computer2. + * + * Arguments: + * 0: Computer 1 + * 0: Computer 2 + * + * Results: + * None + * +*/ + +params ["_computer1", "_computer2"]; + +if (!isServer) exitWith { false; }; + +// read variables from source computer +private _filesystem = _computer1 getVariable ["AE3_filesystem", []]; +private _links = _computer1 getVariable ["AE3_links", createHashMap]; +private _userlist = _computer1 getVariable ["AE3_userlist", createHashMap]; + +// write variables to destination computer +_computer2 setVariable ["AE3_filesystem", _filesystem]; +_computer2 setVariable ["AE3_links", _links]; +_computer2 setVariable ["AE3_userlist", _userlist, true]; + +true; \ No newline at end of file diff --git a/addons/armaos/functions/fnc_terminal_addEventHandler.sqf b/addons/armaos/functions/fnc_terminal_addEventHandler.sqf index 1555b07..9119d63 100644 --- a/addons/armaos/functions/fnc_terminal_addEventHandler.sqf +++ b/addons/armaos/functions/fnc_terminal_addEventHandler.sqf @@ -165,11 +165,11 @@ private _result = _terminalCtrl ctrlAddEventHandler { if (_scroll >= 0) then { - _terminal set ["AE3_terminalScrollPosition", _terminalScrollPosition - AE3_TerminalScrollSpeed]; + _terminal set ["AE3_terminalScrollPosition", _terminalScrollPosition + AE3_TerminalScrollSpeed]; } else { - _terminal set ["AE3_terminalScrollPosition", _terminalScrollPosition + AE3_TerminalScrollSpeed]; + _terminal set ["AE3_terminalScrollPosition", _terminalScrollPosition - AE3_TerminalScrollSpeed]; }; }; @@ -208,7 +208,7 @@ private _result = _consoleDialog displayAddEventHandler { params ["_display", "_exitCode"]; - _computer = _display getVariable "AE3_computer"; + private _computer = _display getVariable "AE3_computer"; _computer setVariable ["AE3_computer_mutex", objNull, true]; _handleUpdateBatteryStatus = _display getVariable "AE3_handleUpdateBatteryStatus"; @@ -222,10 +222,35 @@ private _result = _consoleDialog displayAddEventHandler /* ---------------------------------------- */ - // Updates terminal variable for all - _terminal = _computer getVariable "AE3_terminal"; + // load variables + private _terminal = _computer getVariable "AE3_terminal"; + private _filepointer = _computer getVariable "AE3_filepointer"; + + // crop terminal buffer to max lines; -1 means 'no limit' + if (!(AE3_MaxTerminalBufferLines isEqualTo "-1")) then + { + private _maxLines = parseNumber AE3_MaxTerminalBufferLines; + private _terminalBuffer = _terminal get "AE3_terminalBuffer"; + private _terminalBufferCount = count _terminalBuffer; + if (_terminalBufferCount <= _maxLines) then { _maxLines = _terminalBufferCount; }; + _terminalBuffer = _terminalBuffer select [(count _terminalBuffer) - _maxLines, _maxLines]; + _terminal set ["AE3_terminalBuffer", _terminalBuffer]; + }; + + // adjust cursor line and position + _terminal set ["AE3_terminalCursorLine", (count _terminalBuffer) - 1]; + _terminal set ["AE3_terminalCursorPosition", 0]; + + // clear/reset variables, that are automatically recreated in next terminal init + _terminal set ["AE3_terminalAllowedKeys", createHashMap]; + _terminal set ["AE3_terminalBufferVisible", []]; + _terminal set ["AE3_terminalRenderedBuffer", []]; + _terminal set ["AE3_terminalDesigns", []]; + _terminal set ["AE3_terminalOutput", nil]; + _terminal set ["AE3_terminalProcess", nil]; + + // Updates variables on server _computer setVariable ["AE3_terminal", _terminal, 2]; - _filepointer = _computer getVariable "AE3_filepointer"; _computer setVariable ["AE3_filepointer", _filepointer, 2]; [_computer, "inUse", false] remoteExecCall ["AE3_interaction_fnc_manageAce3Interactions", 2]; diff --git a/addons/armaos/functions/fnc_terminal_init.sqf b/addons/armaos/functions/fnc_terminal_init.sqf index fbfa5b5..f47c2fd 100644 --- a/addons/armaos/functions/fnc_terminal_init.sqf +++ b/addons/armaos/functions/fnc_terminal_init.sqf @@ -12,27 +12,36 @@ params ["_computer"]; -if (!dialog) then -{ - private _ok = createDialog "AE3_ArmaOS_Main_Dialog"; - if (!_ok) then {hint localize "STR_AE3_ArmaOS_Exception_DialogFailed"}; -}; +[_computer, "inUse", true] remoteExecCall ["AE3_interaction_fnc_manageAce3Interactions", 2]; -private _consoleDialog = findDisplay 15984; -private _consoleOutput = _consoleDialog displayCtrl 1100; -private _languageButton = _consoleDialog displayCtrl 1310; -private _designButton = _consoleDialog displayCtrl 1320; +/* ---------------------------------------- */ + +// Bugfix: All getRemoteVar calls should be done before the dialog is created +// otherwise the dialog is open, not showing anything (depending on how long the server needs for an answer) +// if, in this case, the user closes the dialog, then the laptop becomes inaccessable, +// because the mutex variable is not removed in this case, because the event handler to remove it +// on closing the dialog can't be created because of missing dialog variables + +hintSilent "Please be patient while the computer initializes ..."; + +/* ---------------------------------------- */ [_computer, "AE3_filesystem"] call AE3_main_fnc_getRemoteVar; [_computer, "AE3_filepointer"] call AE3_main_fnc_getRemoteVar; +[_computer, "AE3_terminal"] call AE3_main_fnc_getRemoteVar; + +/* ---------------------------------------- */ private _pointer = []; + if (isNil { _computer getVariable "AE3_filepointer" }) then { _computer setVariable ["AE3_filepointer", _pointer, [clientOwner, 2]]; }; _pointer = _computer getVariable "AE3_filepointer"; +/* ---------------------------------------- */ + private _terminal = createHashMapFromArray [ ["AE3_terminalBuffer", []], @@ -51,17 +60,26 @@ private _terminal = createHashMapFromArray ["AE3_terminalMaxColumns", 80] ]; -// Only nessecary to allow Event Handlers the access to _computer -_consoleOutput setVariable ["AE3_computer", _computer]; -_consoleDialog setVariable ["AE3_computer", _computer]; - -[_computer, "AE3_terminal"] call AE3_main_fnc_getRemoteVar; if (isNil { _computer getVariable "AE3_terminal" }) then { _computer setVariable ["AE3_terminal", _terminal, [clientOwner, 2]]; }; _terminal = _computer getVariable "AE3_terminal"; +/* ---------------------------------------- */ + +private _consoleDialog = createDialog ["AE3_ArmaOS_Main_Dialog", true]; + +private _consoleOutput = _consoleDialog displayCtrl 1100; +private _languageButton = _consoleDialog displayCtrl 1310; +private _designButton = _consoleDialog displayCtrl 1320; + +// Only nessecary to allow Event Handlers the access to _computer +_consoleOutput setVariable ["AE3_computer", _computer]; +_consoleDialog setVariable ["AE3_computer", _computer]; + +[_consoleDialog, _consoleOutput, _languageButton, _designButton] call AE3_armaos_fnc_terminal_addEventHandler; + _terminal set ["AE3_terminalOutput", _consoleOutput]; private _localGameLanguage = language; @@ -122,18 +140,6 @@ private _currentDesign = _designs select _currentDesignIndex; /* ---------------------------------------- */ -private _handleUpdateBatteryStatus = [_computer, _consoleDialog] call AE3_armaos_fnc_terminal_updateBatteryStatus; -_consoleDialog setVariable ["AE3_handleUpdateBatteryStatus", _handleUpdateBatteryStatus]; - -/* ------------- UI on Texture ------------ */ - -private _handleUpdateUiOnTexture = [_computer, _consoleDialog] call AE3_armaos_fnc_terminal_uiOnTex_addUpdateAllEventHandler; -_consoleDialog setVariable ["AE3_handleUpdateUiOnTexture", _handleUpdateUiOnTexture]; - -/* ---------------------------------------- */ - -[_consoleDialog, _consoleOutput, _languageButton, _designButton] call AE3_armaos_fnc_terminal_addEventHandler; - _terminalBuffer = _terminal get "AE3_terminalBuffer"; if (_terminalBuffer isEqualTo []) then { @@ -152,8 +158,30 @@ if (_terminalBuffer isEqualTo []) then [_computer] call AE3_armaos_fnc_terminal_setPrompt; }; +/* ---------------------------------------- */ + +// recreate _terminalRenderedBuffer from _terminalBuffer +// because _terminalRenderedBuffer was set to [] +// before _terminal was synced to server +[_computer] call AE3_armaos_fnc_terminal_reRenderBuffer; + +/* ---------------------------------------- */ + [_computer, _consoleOutput] call AE3_armaos_fnc_terminal_updateOutput; _computer setVariable ["AE3_terminal", _terminal]; -[_computer, "inUse", true] remoteExecCall ["AE3_interaction_fnc_manageAce3Interactions", 2]; \ No newline at end of file +/* ---------------------------------------- */ + +private _handleUpdateBatteryStatus = [_computer, _consoleDialog] call AE3_armaos_fnc_terminal_updateBatteryStatus; +_consoleDialog setVariable ["AE3_handleUpdateBatteryStatus", _handleUpdateBatteryStatus]; + +/* ------------- UI on Texture ------------ */ + +private _handleUpdateUiOnTexture = [_computer, _consoleDialog] call AE3_armaos_fnc_terminal_uiOnTex_addUpdateAllEventHandler; +_consoleDialog setVariable ["AE3_handleUpdateUiOnTexture", _handleUpdateUiOnTexture]; + +/* ---------------------------------------- */ + +// clear the previously set "be patient" message +hintSilent ""; \ No newline at end of file diff --git a/addons/armaos/functions/fnc_terminal_setKeyboardLayout.sqf b/addons/armaos/functions/fnc_terminal_setKeyboardLayout.sqf index 911d9cc..649b7ab 100644 --- a/addons/armaos/functions/fnc_terminal_setKeyboardLayout.sqf +++ b/addons/armaos/functions/fnc_terminal_setKeyboardLayout.sqf @@ -32,9 +32,7 @@ _computer setVariable ["AE3_terminal", _terminal]; if (AE3_UiOnTexture) then { - private _playersInRange = [3, _computer] call AE3_main_fnc_getPlayersInRange; - - [_computer, _terminalKeyboardLayout] remoteExec ["AE3_armaos_fnc_terminal_uiOnTex_setKeyboardLayout", _playersInRange]; + [3, _computer, "AE3_armaos_fnc_terminal_uiOnTex_setKeyboardLayout", [_computer, _terminalKeyboardLayout]] call AE3_main_fnc_executeForPlayersInRange; }; /* ---------------------------------------- */ \ No newline at end of file diff --git a/addons/armaos/functions/fnc_terminal_setTerminalDesign.sqf b/addons/armaos/functions/fnc_terminal_setTerminalDesign.sqf index b2f3c93..8050907 100644 --- a/addons/armaos/functions/fnc_terminal_setTerminalDesign.sqf +++ b/addons/armaos/functions/fnc_terminal_setTerminalDesign.sqf @@ -47,11 +47,11 @@ ctrlSetFocus _consoleOutput; if (AE3_UiOnTexture) then { - private _playersInRange = [3, _computer] call AE3_main_fnc_getPlayersInRange; - private _computer = _consoleOutput getVariable "AE3_computer"; - [_computer, _bgColorHeader, _bgColorConsole, _fontColorHeader, _fontColorConsole] remoteExec ["AE3_armaos_fnc_terminal_uiOnTex_setTerminalDesign", _playersInRange]; + private _args = [_computer, _bgColorHeader, _bgColorConsole, _fontColorHeader, _fontColorConsole]; + + [3, _computer, "AE3_armaos_fnc_terminal_uiOnTex_setTerminalDesign", _args] call AE3_main_fnc_executeForPlayersInRange; }; /* ---------------------------------------- */ \ No newline at end of file diff --git a/addons/armaos/functions/fnc_terminal_uiOnTex_addUpdateAllEventHandler.sqf b/addons/armaos/functions/fnc_terminal_uiOnTex_addUpdateAllEventHandler.sqf index e6f38e0..4fa99a5 100644 --- a/addons/armaos/functions/fnc_terminal_uiOnTex_addUpdateAllEventHandler.sqf +++ b/addons/armaos/functions/fnc_terminal_uiOnTex_addUpdateAllEventHandler.sqf @@ -18,10 +18,15 @@ _handle = { (_this select 0) params ["_computer", "_consoleDialog"]; - if (AE3_UiOnTexture) then + if (_consoleDialog isEqualTo displayNull) exitWith { - private _playersInRange = [3, _computer] call AE3_main_fnc_getPlayersInRange; + // remove this per frame event handler + private _handle = _this select 1; + [_handle] call CBA_fnc_removePerFrameHandler; + }; + if (AE3_UiOnTexture) then + { private _languageButtonCtrl = _consoleDialog displayCtrl 1310; private _batteryButtonCtrl = _consoleDialog displayCtrl 1050; private _headerBackgroundCtrl = _consoleDialog displayCtrl 900; @@ -42,7 +47,22 @@ _handle = private _terminalBufferVisible = _terminal get "AE3_terminalBufferVisible"; private _size = _terminal get "AE3_terminalSize"; - [_computer, _terminalBufferVisible, _size, _terminalKeyboardLayout, _bgColorHeader, _bgColorConsole, _fontColorHeader, _fontColorConsole, _value] remoteExec ["AE3_armaos_fnc_terminal_uiOnTex_updateAll", _playersInRange]; + private _args = [_computer, _terminalBufferVisible, _size, _terminalKeyboardLayout, _bgColorHeader, _bgColorConsole, _fontColorHeader, _fontColorConsole, _value]; + + [3, _computer, "AE3_armaos_fnc_terminal_uiOnTex_updateAll", _args] call AE3_main_fnc_executeForPlayersInRange; + } + else + { + // if UiOnTexture is disabled apply the default texture, + // but only if it isn't already set + private _textures = getObjectTextures _computer; + private _imagePath = "z\ae3\addons\armaos\textures\laptop_4_to_3_on.paa"; + private _textureIndex = 1; + if (!((_textures select _textureIndex) isEqualTo _imagePath)) then + { + _computer setVariable ["AE3_UiOnTexActive", false, true]; // reset var for all clients + _computer setObjectTextureGlobal [_textureIndex, _imagePath]; + }; }; }, _updateInterval, diff --git a/addons/armaos/functions/fnc_terminal_updateBatteryStatus.sqf b/addons/armaos/functions/fnc_terminal_updateBatteryStatus.sqf index c8fb2be..d23436a 100644 --- a/addons/armaos/functions/fnc_terminal_updateBatteryStatus.sqf +++ b/addons/armaos/functions/fnc_terminal_updateBatteryStatus.sqf @@ -56,9 +56,7 @@ _handle = if ((AE3_UiOnTexture) && !(_oldValue isEqualTo _newValue)) then { - private _playersInRange = [3, _computer] call AE3_main_fnc_getPlayersInRange; - - [_computer, _value] remoteExec ["AE3_armaos_fnc_terminal_uiOnTex_updateBatteryStatus", _playersInRange]; + [3, _computer, "AE3_armaos_fnc_terminal_uiOnTex_updateBatteryStatus", [_computer, _value]] call AE3_main_fnc_executeForPlayersInRange; }; /* ---------------------------------------- */ diff --git a/addons/armaos/functions/fnc_terminal_updateOutput.sqf b/addons/armaos/functions/fnc_terminal_updateOutput.sqf index 51bd7cf..09391ff 100644 --- a/addons/armaos/functions/fnc_terminal_updateOutput.sqf +++ b/addons/armaos/functions/fnc_terminal_updateOutput.sqf @@ -35,9 +35,7 @@ _computer setVariable ["AE3_terminal", _terminal]; if (AE3_UiOnTexture) then { - private _playersInRange = [3, _computer] call AE3_main_fnc_getPlayersInRange; - - [_computer, _output] remoteExec ["AE3_armaos_fnc_terminal_uiOnTex_updateOutput", _playersInRange]; + [3, _computer, "AE3_armaos_fnc_terminal_uiOnTex_updateOutput", [_computer, _output]] call AE3_main_fnc_executeForPlayersInRange; }; /* ---------------------------------------- */ \ No newline at end of file diff --git a/addons/armaos/stringtable.xml b/addons/armaos/stringtable.xml index 04ab5af..cae9826 100644 --- a/addons/armaos/stringtable.xml +++ b/addons/armaos/stringtable.xml @@ -1409,6 +1409,24 @@ Si activé, les joueurs environnants peuvent voir l'interface armaOS sur la texture de l'ordinateur. Se abilitato, i giocatori vicini possono vedere l'interfaccia di armaOS nella texture del computer. + + Max Terminal Buffer Lines + Max Terminal Buffer Lines + Maximale Terminal-Buffer-Zeilen + Max Terminal Buffer Lines + Max Terminal Buffer Lines + Max Terminal Buffer Lines + Max Terminal Buffer Lines + + + Determines the amount of terminal output buffer lines that is stored when leaving the computer. While using it the amount is not restricted. A value of -1 means 'no storing limit'. + Determines the amount of terminal output buffer lines that is stored when leaving the computer. While using it the amount is not restricted. A value of -1 means 'no storing limit'. + Legt die Anzahl der Terminal-Output-Buffer-Zeilen fest, die nach verlassen des Computers gespeichert werden. Während der Nutzung ist die Anzahl nicht begrenzt. Ein Wert von -1 bedeutet, 'keine Speicherbegrenzung'. + Determines the amount of terminal output buffer lines that is stored when leaving the computer. While using it the amount is not restricted. A value of -1 means 'no storing limit'. + Determines the amount of terminal output buffer lines that is stored when leaving the computer. While using it the amount is not restricted. A value of -1 means 'no storing limit'. + Determines the amount of terminal output buffer lines that is stored when leaving the computer. While using it the amount is not restricted. A value of -1 means 'no storing limit'. + Determines the amount of terminal output buffer lines that is stored when leaving the computer. While using it the amount is not restricted. A value of -1 means 'no storing limit'. + 1 line 1 line diff --git a/addons/main/XEH_PREP.hpp b/addons/main/XEH_PREP.hpp index ab20949..0318a81 100644 --- a/addons/main/XEH_PREP.hpp +++ b/addons/main/XEH_PREP.hpp @@ -16,6 +16,7 @@ PREP(3den_checkConnection); /* Misc */ PREP(getPlayersInRange); +PREP(executeForPlayersInRange); /* Terminate */ PREP(terminateDevice); diff --git a/addons/main/functions/fnc_executeForPlayersInRange.sqf b/addons/main/functions/fnc_executeForPlayersInRange.sqf new file mode 100644 index 0000000..10c5b64 --- /dev/null +++ b/addons/main/functions/fnc_executeForPlayersInRange.sqf @@ -0,0 +1,31 @@ +/** + * Gets all players within a radius around the given object and executes a given function, command or script with arguments on these clients. + * + * Arguments: + * 0: Range + * 1: Object + * 2: Function or + * 3: Arguments + * + * Return: + * Nothing + */ + + params ["_range", "_object", "_fnc", "_args"]; + +private _playersInRange = [_range, _object] call AE3_main_fnc_getPlayersInRange; + +// using remoteExec on a zero sized array leads to RPT spam warnings +if ((count _playersInRange) == 0) exitWith {}; + +// use remoteExec if _fnc is type "string" +if ((typeName _fnc) isEqualTo "STRING") then +{ + _args remoteExecCall [_fnc, _playersInRange]; +}; + +// use a remote executed "call" if _fnc is type "code" +if ((typeName _fnc) isEqualTo "CODE") then +{ + [_args, _fnc] remoteExecCall ["call", _playersInRange]; +}; \ No newline at end of file