Crazy_Man 36 Posted March 1, 2019 Hello, I wonder if is there a way of getting out of a waitUntil loop in the case when a script is remoteExec on the server in the init.sqf with player passed as argument and when the player disconnect from the server? I see on my linux server'screen when i disconnect from the server the error " Client: Remote object 4:0 not found " and the diag_log message continuing emmiting each second so the script never end. //init.sqf if (hasInterface) then { waitUntil {!isNull player}; [[player], "test.sqf"] remoteExec ["execVM", 2]; }; // test.sqf params ["_player"]; while {!isNull _player} do { waitUntil { diag_log "!!!!In waitUntil loop!!!!"; sleep 1; /*(condition code)*/ or isNull _player }; if (isNull _player) exitWith {}; //code... // // }; 1 Share this post Link to post Share on other sites
mrcurry 508 Posted March 2, 2019 8 hours ago, Crazy_Man said: Hello, I wonder if is there a way of getting out of a waitUntil loop in the case when a script is remoteExec on the server in the init.sqf with player passed as argument and when the player disconnect from the server? I see on my linux server'screen when i disconnect from the server the error " Client: Remote object 4:0 not found " and the diag_log message continuing emmiting each second so the script never end. //init.sqf if (hasInterface) then { waitUntil {!isNull player}; [[player], "test.sqf"] remoteExec ["execVM", 2]; }; // test.sqf params ["_player"]; while {!isNull _player} do { waitUntil { diag_log "!!!!In waitUntil loop!!!!"; sleep 1; /*(condition code)*/ or isNull _player }; if (isNull _player) exitWith {}; //code... // // }; Since you haven't provided the full condition its hard to say. My guess would be that your condition fails because of your OR's left-hand argument. Everything else looks fine. If your left argument requires the player to not be null then swap the left and right arguments of the OR and then wrap the new right in {} brackets. That way it will only be checked if the left side returns false i.e. when _player isn't null. Like this: //Your current code: a or isNull _player //New code: isNull _player or {a} If that fails provide full code. 2 Share this post Link to post Share on other sites
Crazy_Man 36 Posted March 2, 2019 Hi mrcurry thanks for your response, I tried your solution but it fails and the problem remains the same. So for the moment I have this : params["_player"]; // other params code... // // //////// Return flag [_player, _flag, _logique, _color, _soundReturn, _playerName] spawn { params ["_player", "_flag", "_logique", "_color", "_soundReturn","_playerName"]; while {!isNull _player} do { waitUntil { diag_log "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!WaitUntil Return flag loop!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"; sleep 1; isNull _player or {lifeState _player != "INCAPACITATED" and lifeState _player != "DEAD-RESPAWN" and _player distance _flag < 2 and vehicle _player == _player and alive _player and _logique getVariable "state" == "free"}}; if (isNull _player) exitWith {}; _flag attachTo [_logique, [0,0,1]]; [_logique, ["state", "base", true]] remoteExec ["setVariable", 0, true];///////////////////////////////// BASE _soundReturn remoteExec ["playSound", 0]; [_playerName, _color, "returned", "return"] remoteExec ["FN_msgFlag"]; }; }; // code... // // Share this post Link to post Share on other sites
mrcurry 508 Posted March 3, 2019 12 hours ago, Crazy_Man said: Hi mrcurry thanks for your response, I tried your solution but it fails and the problem remains the same. So for the moment I have this : params["_player"]; // other params code... // // //////// Return flag [_player, _flag, _logique, _color, _soundReturn, _playerName] spawn { params ["_player", "_flag", "_logique", "_color", "_soundReturn","_playerName"]; while {!isNull _player} do { waitUntil { diag_log "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!WaitUntil Return flag loop!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"; sleep 1; isNull _player or {lifeState _player != "INCAPACITATED" and lifeState _player != "DEAD-RESPAWN" and _player distance _flag < 2 and vehicle _player == _player and alive _player and _logique getVariable "state" == "free"}}; if (isNull _player) exitWith {}; _flag attachTo [_logique, [0,0,1]]; [_logique, ["state", "base", true]] remoteExec ["setVariable", 0, true];///////////////////////////////// BASE _soundReturn remoteExec ["playSound", 0]; [_playerName, _color, "returned", "return"] remoteExec ["FN_msgFlag"]; }; }; // code... // // Well that conditions looks alright so maybe something else is also messing with you. Couple of things to try: 1. Make sure the variables _flag and _logique actually are defined going into the waitUntil. EDIT: by make sure I mean do a manual check using a printout. 2. Add a log printout of _logique getVariable "state" in the waitUntil and make sure it's set to what it's supposed to be. Share this post Link to post Share on other sites
Crazy_Man 36 Posted March 3, 2019 Yes, _flag and _logique variables are well defined and the setVariable on logic entity is defined in its init field in the EDEN editor. In fact, the script works well but the problem is that if the player disconnect from the server the script doesn't stop so the performance of the server is altered. private ["_flag", "_oppFlag", "_color", "_oppSide", "_oppFlagPos", "_flagPos", "_oppLogique", "_logique", "_veh", "_soundReturn", "_soundCapture", "_actionId"]; params ["_side", "_player"]; _playerName = name _player; if (_side == east) then { _oppLogique = logiqueFlagBlue; _logique = logiqueFlagRed; _flag = flagRed; _soundReturn = "redflagreturn"; _soundCapture = "redscore"; _oppFlag = flagBlue; _oppFlagPos = blueFlagPos; _flagPos = redFlagPos; _color = ["#FF800000", "#FF004C99", "Blue", "Red"]; _oppSide = west; }; if (_side == west) then { _oppLogique = logiqueFlagRed; _logique = logiqueFlagBlue; _flag = flagBlue; _soundReturn = "blueflagreturn"; _soundCapture = "bluescore"; _oppFlag = flagRed; _oppFlagPos = redFlagPos; _flagPos = blueFlagPos; _color = ["#FF004C99", "#FF800000", "Red", "Blue"]; _oppSide = east; }; //////// Return flag [_player, _flag, _logique, _color, _soundReturn, _playerName] spawn { params ["_player", "_flag", "_logique", "_color", "_soundReturn", "_playerName"]; while {!isNull _player} do { waitUntil { diag_log "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!WaitUntil Return flag loop!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"; sleep 1; if (isNull _player) exitWith {true}; lifeState _player != "INCAPACITATED" and lifeState _player != "DEAD-RESPAWN" and _player distance _flag < 2 and vehicle _player == _player and alive _player and _logique getVariable "state" == "free"; }; if (isNull _player) exitWith {}; _flag attachTo [_logique, [0,0,1]]; [_logique, ["state", "base", true]] remoteExec ["setVariable", 0, true];///////////////////////////////// BASE _soundReturn remoteExec ["playSound", 0]; [_playerName, _color, "returned", "return"] remoteExec ["FN_msgFlag"]; }; }; // code... // // And in the init field of the logic entity : this setVariable ["state", "base", true]; Share this post Link to post Share on other sites
mrcurry 508 Posted March 3, 2019 7 hours ago, Crazy_Man said: Yes, _flag and _logique variables are well defined and the setVariable on logic entity is defined in its init field in the EDEN editor. In fact, the script works well but the problem is that if the player disconnect from the server the script doesn't stop so the performance of the server is altered. private ["_flag", "_oppFlag", "_color", "_oppSide", "_oppFlagPos", "_flagPos", "_oppLogique", "_logique", "_veh", "_soundReturn", "_soundCapture", "_actionId"]; params ["_side", "_player"]; _playerName = name _player; if (_side == east) then { _oppLogique = logiqueFlagBlue; _logique = logiqueFlagRed; _flag = flagRed; _soundReturn = "redflagreturn"; _soundCapture = "redscore"; _oppFlag = flagBlue; _oppFlagPos = blueFlagPos; _flagPos = redFlagPos; _color = ["#FF800000", "#FF004C99", "Blue", "Red"]; _oppSide = west; }; if (_side == west) then { _oppLogique = logiqueFlagRed; _logique = logiqueFlagBlue; _flag = flagBlue; _soundReturn = "blueflagreturn"; _soundCapture = "bluescore"; _oppFlag = flagRed; _oppFlagPos = redFlagPos; _flagPos = blueFlagPos; _color = ["#FF004C99", "#FF800000", "Red", "Blue"]; _oppSide = east; }; //////// Return flag [_player, _flag, _logique, _color, _soundReturn, _playerName] spawn { params ["_player", "_flag", "_logique", "_color", "_soundReturn", "_playerName"]; while {!isNull _player} do { waitUntil { diag_log "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!WaitUntil Return flag loop!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"; sleep 1; if (isNull _player) exitWith {true}; lifeState _player != "INCAPACITATED" and lifeState _player != "DEAD-RESPAWN" and _player distance _flag < 2 and vehicle _player == _player and alive _player and _logique getVariable "state" == "free"; }; if (isNull _player) exitWith {}; _flag attachTo [_logique, [0,0,1]]; [_logique, ["state", "base", true]] remoteExec ["setVariable", 0, true];///////////////////////////////// BASE _soundReturn remoteExec ["playSound", 0]; [_playerName, _color, "returned", "return"] remoteExec ["FN_msgFlag"]; }; }; // code... // // And in the init field of the logic entity : this setVariable ["state", "base", true]; Okey I had a sneaking suspicion but now I'm pretty certain this is the case. The normal behaviour is to on a disconnect event transfer the player object to the server, kill it and leave it lying on the ground as a casualty, unless the player slot is set to be a playable AI. I'm going to go out on a limb and say that the bodies of your players stay behind when disconnected, am I right? If yes go to 1. If no go to 2. 1. If I'm right that's why it will never exit because the player object (which _player actually refers to) is never deleted hence it's never turns null and will keep evaluating the rest of the condition which can never be true since the player object is dead. Now, if this is the case you've got a choice to make. Either you: A. get rid of the player objects when they are disconnected. Deleting the bodies should resolve the issue of them not becoming null and let your loop continue. It also has the nice benefit of cleaning up the battlefield if that's what you desire. It might be worth deleting the bodies on killed event as well for consistency's sake, just make sure to check how that interacts with the rest of your mission. B. adapt your condition code to handle this edge-case. That way the bodies will stay on the ground but the loop will still exit. Unfortunately I don't have a tested way to check if a certain player is still connected. From what I gleaned from your script it is running on the server meaning that you should be able to just check if the body is local to the server. I recommend you test that approach thoroughly though. If that doesn't pan out you can maybe look into some of these commands and see how they behave in your situation: owner, getPlayerUID 2. If I'm wrong then I can only advise you to print out all variables and all the separate conditionals used in your waitUntil and look through the log to see which part is screwing you over. Best of luck and please let us now how it turns out. 1 Share this post Link to post Share on other sites
Crazy_Man 36 Posted March 3, 2019 Ok, I used the owner command and it works great! It finally exit the loop when the player disconnect. Thank you a lot for putting me on the right path 😀 params ["_player"]; _playerID = owner _player; while {_playerID == owner _player} do { waitUntil { diag_log "!!!!In waitUntil loop!!!!"; sleep 1; _playerID != owner _player or {a} }; if (_playerID != owner _player) exitWith {}; //code... // // }; 2 Share this post Link to post Share on other sites