diff --git a/SQF/dayz_server/compile/server_onPlayerDisconnect.sqf b/SQF/dayz_server/compile/server_onPlayerDisconnect.sqf index 11d9112ec..792abe3a5 100644 --- a/SQF/dayz_server/compile/server_onPlayerDisconnect.sqf +++ b/SQF/dayz_server/compile/server_onPlayerDisconnect.sqf @@ -1,14 +1,21 @@ -private ["_playerObj","_myGroup","_playerUID","_playerPos","_playerName","_message","_newPos","_count","_maxDist","_relocate"]; +/* + WARNING: The player object is deleted by Arma shortly after onPlayerDisconnected fires + because DayZ uses disabledAI=true: + https://community.bistudio.com/wiki/Description.ext#disabledAI + + References to the player object after that point will return objNull, so this function + and server_playerSync must be fast or the player will not save. +*/ +private ["_playerObj","_playerUID","_playerPos","_playerName"]; _playerUID = _this select 0; _playerName = _this select 1; _playerObj = nil; -_playerPos = []; //Lets search all playerable units looking for the objects that matches our playerUID { if ((getPlayerUID _x) == _playerUID) exitWith { _playerObj = _x; _playerPos = getPosATL _playerObj;}; -} forEach playableUnits; +} count playableUnits; //If for some reason the playerOBj does not exist lets exit the disconnect system. if (isNil "_playerObj") exitWith { @@ -20,20 +27,8 @@ if (isNil "_playerObj") exitWith { //If the the playerObj exists lets run all sync systems _characterID = _playerObj getVariable["characterID", "?"]; -_lastDamage = _playerObj getVariable["noatlf4",0]; +_inCombat = _playerObj getVariable ["inCombat",0]; _Sepsis = _playerObj getVariable["USEC_Sepsis",false]; -_lastDamage = round(diag_ticktime - _lastDamage); -_inCombat = _playerObj getVariable ["inCombat", 0]; - -//Readded Logout debug info. -diag_log format["INFO - Player: %3(UID:%1/CID:%2) as (%4), logged off at %5%6", - getPlayerUID _playerObj, - _characterID, - _playerObj call fa_plr2str, - typeOf _playerObj, - (getPosATL _playerObj) call fa_coor2str, - if ((_lastDamage > 5 AND (_lastDamage < 30)) AND ((alive _playerObj) AND (_playerObj distance (getMarkerpos "respawn_west") >= 2000))) then {" while in combat ("+str(_lastDamage)+" seconds left)"} else {""} -]; //Login processing do not sync if (_playerUID in dayz_ghostPlayers) exitwith { @@ -41,8 +36,7 @@ if (_playerUID in dayz_ghostPlayers) exitwith { //Lets remove the object. if (!isNull _playerObj) then { - _myGroup = group _playerObj; - deleteGroup _myGroup; + deleteGroup (group _playerObj); }; }; @@ -53,22 +47,9 @@ if (_characterID != "?") exitwith { _playerObj setVariable["USEC_infected",true,true]; }; - //Record Player Login/LogOut - [_playerUID,_characterID,2,_playerName] call dayz_recordLogin; - - //Punish combat log - if ((_inCombat > 0) && {alive _playerObj && (_playerObj distance (getMarkerpos "respawn_west") >= 2000)}) then { - _playerObj setVariable ["NORRN_unconscious",true,true]; // Set status to unconscious - _playerObj setVariable ["unconsciousTime",150,true]; // Set knock out timer to 150 seconds - //_playerObj setVariable ["USEC_injured",true]; // Set status to bleeding - //_playerObj setVariable ["USEC_BloodQty",3000]; // Set blood to 3000 - diag_log format["PLAYER COMBAT LOGGED: %1(%3) at location %2",_playerName,_playerPos,_playerUID]; - _message = format["PLAYER COMBAT LOGGED: %1",_playerName]; - [nil, nil, rTitleText, _message, "PLAIN"] call RE; // Message whole server - }; - //if player object is alive lets sync the player and remove the body and if ghosting is active add the player id to the array if (alive _playerObj) then { + // High priority. Sync must finish fast before player object isNull [_playerObj,nil,true,true] call server_playerSync; if (dayz_enableGhosting) then { //diag_log format["GhostPlayers: %1, ActivePlayers: %2",dayz_ghostPlayers,dayz_activePlayers]; @@ -78,9 +59,26 @@ if (_characterID != "?") exitwith { //diag_log format["playerID %1 added to ghost list",_playerUID]; }; + }; + //Punish combat log + if (_inCombat > 0) then { + _playerObj setVariable ["NORRN_unconscious",true,true]; // Set status to unconscious + _playerObj setVariable ["unconsciousTime",150,true]; // Set knock out timer to 2 minutes 30 seconds + //_playerObj setVariable ["USEC_injured",true]; // Set status to bleeding + //_playerObj setVariable ["USEC_BloodQty",3000]; // Set blood to 3000 + + // Low priority. Player object not needed + diag_log format["PLAYER COMBAT LOGGED: %1(%3) at location %2",_playerName,_playerPos,_playerUID]; + [nil, nil, rTitleText, format["PLAYER COMBAT LOGGED: %1",_playerName], "PLAIN"] call RE; // Message whole server }; }; + /* + Low priority code below this point where + _playerObj is no longer needed and may be Null. + */ + [_playerUID,_characterID,2,_playerName] call dayz_recordLogin; + //Lets scan the area near the player logout position and save all objects. { [_x,"gear"] call server_updateObject } foreach (nearestObjects [_playerPos, DayZ_GearedObjects, 10]); }; @@ -90,6 +88,5 @@ if (isNull _playerObj) then { diag_log("Player Object does not esist"); }; //Lets remove the object. if (!isNull _playerObj) then { - _myGroup = group _playerObj; - deleteGroup _myGroup; + deleteGroup (group _playerObj); }; \ No newline at end of file diff --git a/SQF/dayz_server/compile/server_playerSync.sqf b/SQF/dayz_server/compile/server_playerSync.sqf index 5c66a7f64..81223d6c9 100644 --- a/SQF/dayz_server/compile/server_playerSync.sqf +++ b/SQF/dayz_server/compile/server_playerSync.sqf @@ -1,4 +1,9 @@ -private ["_distanceFoot","_playerPos","_lastPos","_playerGear","_medical","_currentModel","_currentAnim","_currentWpn","_muzzles","_array","_coins","_key","_globalCoins","_bankCoins","_group","_playerBackp","_backpack","_kills","_killsB","_killsH","_headShots","_humanity","_lastTime","_timeGross","_timeSince","_timeLeft","_config","_onLadder","_isTerminal","_modelChk","_temp","_currentState","_character","_magazines","_characterID","_force","_charPos","_isInVehicle","_name","_Achievements","_isNewMed","_isNewPos","_isNewGear","_debug","_distance"]; +private ["_distanceFoot","_playerPos","_lastPos","_playerGear","_medical","_currentModel","_currentAnim", +"_currentWpn","_muzzles","_array","_coins","_key","_globalCoins","_bankCoins","_group","_playerBackp", +"_backpack","_kills","_killsB","_killsH","_headShots","_humanity","_lastTime","_timeGross","_timeSince", +"_timeLeft","_config","_onLadder","_isTerminal","_modelChk","_temp","_currentState","_character", +"_magazines","_characterID","_force","_charPos","_isInVehicle","_name","_Achievements","_isNewMed", +"_isNewPos","_isNewGear","_debug","_distance","_newPos","_count","_maxDist","_relocate"]; //[player,array] _character = _this select 0;