kibaBG 53 Posted April 18 Hi, I am trying to save players position on a mission map using prifilenamespace of each player. Its working fine in editor, but refuse to work on dedicated server ... I wonder where is the problem? //PERSISTENT PLAYER POS AND RATING //saves players pos and rating every five min //loads players pos and rating when they join server //initServer.sqf []execVM "stats.sqf"; //stats.sqf while {true} do { _kibaPos = getPosATL kiba3x; profileNamespace setVariable ["KIB_kibaPos", _kibaPos]; _kibaRating = rating kiba3x; profileNamespace setVariable ["KIB_kibaRating",_kibaRating]; _kavhanPos = getPosATL kavhan; profileNamespace setVariable ["KIB_kavhanPos", _kavhanPos]; _kavhanRating = rating kavhan; profileNamespace setVariable ["KIB_kavhanRating", _kavhanRating]; _konalPosition = getPosATL konal; profileNamespace setVariable ["KIB_konalPos", _konalPosition]; _konalRating = rating konal; profileNamespace setVariable ["KIB_konalRating", _konalRating]; sleep 300; }; //initPlayerLocal.sqf //playable units are given variable names "kiba3x","kavhan","konal" in the editor if ((str player) == "kiba3x") then { _kibaPos = profileNamespace getVariable "KIB_kibaPos"; player setPosATL _kibaPos; _kibaRating = profileNamespace getVariable "KIB_kibaRating"; player addRating _kibaRating; } else { if ((str player) == "kavhan") then { _kavhanPos = profileNamespace getVariable "KIB_kavhanPos"; player setPosATL _namalskPos; _kavhanRating = profileNamespace getVariable "KIB_kavhanRating"; player addRating _kavhanRating; } else { _konalPos = profileNamespace getVariable "KIB_konalPos"; player setPosATL _konalPos; _konalRating = profileNamespace getVariable "KIB_konalRating"; player addRating _konalRating; }; }; Share this post Link to post Share on other sites
Schatten 285 Posted April 18 1 hour ago, kibaBG said: Its working fine in editor, but refuse to work on dedicated server ... I wonder where is the problem? The problem is that a server and clients have their own profile namespaces, therefore you should request data from the server: // initServer.sqf sendDataToClient = { private ["_data", "_varNames"]; params ["_player"]; _data = []; _varNames = switch (vehicleVarName _player) do { case "kiba3x": { ["KIB_kibaPos", "KIB_kibaRating"] }; case "kavhan": { ["KIB_kavhanPos", "KIB_kavhanRating"] }; default { ["KIB_konalPos", "KIB_konalRating"] }; }; { _data pushBack (profileNamespace getVariable _x); } forEach _varNames; missionNamespace setVariable ["clientData", _data, if (_player == player) then { false } else { owner _player }]; }; // initPlayerLocal.sqf if (isServer) then { [player] call sendDataToClient; } else { [player] remoteExecCall ["sendDataToClient", 2]; }; waitUntil { !(isNil "clientData") }; clientData params ["_position", "_rating"]; clientData = nil; player setPosATL _position; player addRating _rating; 1 1 Share this post Link to post Share on other sites
Larrow 2820 Posted April 19 //initServer.sqf KIB_fnc_getPlayerData = { params[ "_player" ]; if ( vehicleVarName _player == "" ) then { _player setVehicleVarName format[ "Player_%1", getPlayerUID _player ]; _player call BIS_fnc_objectVar; }; [ profileNamespace getVariable[ format[ "KIB_%1Pos", vehicleVarName _player ], getPosATL _player ], profileNamespace getVariable[ format[ "KIB_%1Rating", vehicleVarName _player ], 0 ] ] remoteExec[ "KIB_fnc_setPlayerData", remoteExecutedOwner ]; }; KIB_fnc_savePlayerData = { params[ "_player" ]; profileNamespace setVariable[ format[ "KIB_%1Pos", vehicleVarName _player ], getPosATL _player ]; profileNamespace setVariable[ format[ "KIB_%1Rating", vehicleVarName _player ], rating _player ]; }; KIB_fnc_updatePlayerData = { params[ "_player" ]; while { true } do { [ _player ] call KIB_fnc_savePlayerData; sleep 300; }; }; //initPlayerLocal.sqf KIB_fnc_setPlayerData = { params[ "_position", "_rating" ]; //Only allow execution from the server if ( isMultiplayer && { !isRemoteExecuted || { remoteExecutedOwner isNotEqualTo 2 }} ) exitWith {}; //Set rating, not add to what they already have player addRating ( _rating - rating player ); player setPosATL _position; //Only once saved/defaults have been applied start saving data [ player ] remoteExec[ "KIB_fnc_updatePlayerData", 2 ]; }; params[ "_player" ]; [ _player ] remoteExec[ "KIB_fnc_getPlayerData", 2 ]; 2 1 Share this post Link to post Share on other sites
kibaBG 53 Posted April 19 Thank you @Larrow ! Thank you @Schatten ! I would never think of such complex script and it working perfectly on dedicated. The only question I have is how to delete the players data on the server to restart all players positions? KIB_fnc_deletePlayerData = { params[ "_player" ]; profileNamespace setVariable[ format[ "KIB_%1Pos", vehicleVarName _player ], nil ]; profileNamespace setVariable[ format[ "KIB_%1Rating", vehicleVarName _player ], nil ]; }; Share this post Link to post Share on other sites
Schatten 285 Posted April 20 17 hours ago, kibaBG said: The only question I have is how to delete the players data on the server to restart all players positions? Just remotely execute your function on server side whenever you need this. 1 Share this post Link to post Share on other sites
Larrow 2820 Posted April 20 On 4/19/2024 at 6:37 PM, kibaBG said: The only question I have is how to delete the players data on the server to restart ALL players positions? I have changed the saved data from the server's profileNamespace to missionProfileNamespace instead. Just a better idea all around... you can use this system on multiple missions without it interfering with each other, or even share if needed you can use allVariables command on it to collect all data for deletion. I have changed the data from a single var for each piece of information ( e.g KIB_#_Pos, KIB_#_Rating ) to KIB_playerData_# ( where # is the reference to the player, as per previous either varName or uid ) which is an array holding ALL the data for that player. Makes it easier to find/delete without having to poll multiple vars. I have made an action menu for the logged in admin so they can manage the data... "Show Admin Menu" - Will display the options below "Delete Players Position" - Will delete the position data for the current player you are looking at "Delete Players Rating" - Will delete the rating data for the current player you are looking at "Delete Players Data" - Will delete all data for the current player you are looking at "Delete All Players Positions" - Will delete position data for all currently connected players "Delete All Players Ratings" - Will delete rating data for all currently connected players "Delete All Players Data" - Will delete all data for all currently connected players "Delete ALL Data" - Will delete all data EVERYTHING that has ever been saved "Close Admin Menu" - Will remove the options above other than Show Menu just so you can clear the clutter from your action menu Spoiler //initServer.sqf KIB_fnc_getPlayerData = { params[ "_player" ]; if ( vehicleVarName _player == "" ) then { _player setVehicleVarName format[ "Player_%1", getPlayerUID _player ]; _player call BIS_fnc_objectVar; }; missionProfileNamespace getVariable[ format[ "KIB_playerData_%1", vehicleVarName _player ], [ getPosATL _player, rating _player ] ] remoteExec[ "KIB_fnc_setPlayerData", remoteExecutedOwner ]; if ( admin owner _player == 2 ) then { [] remoteExec[ "KIB_fnc_applyAdminMenu", remoteExecutedOwner ]; }; }; KIB_fnc_savePlayerData = { params[ "_player" ]; missionProfileNamespace setVariable[ format[ "KIB_playerData_%1", vehicleVarName _player ], [ getPosATL _player, rating _player ] ]; }; KIB_fnc_updatePlayerData = { params[ "_player" ]; KIB_playerData_updatePeriod = 300; //Change this for number of seconds between player data saves if ( isNil "KIB_playerData_updateEH" ) then { KIB_playerData_players = [ _player ]; KIB_playerData_nextUpdate = time; KIB_playerData_updateEH = addMissionEventHandler[ "EachFrame", { if ( time >= KIB_playerData_nextUpdate ) then { { [ _x ] call KIB_fnc_savePlayerData; }forEach KIB_playerData_players; saveMissionProfileNamespace; KIB_playerData_nextUpdate = time + KIB_playerData_updatePeriod; }; }]; }else{ KIB_playerData_players append [ _player ]; }; }; KIB_fnc_deletePlayerData = { params[ [ "_who", true, [ "", objNull, true, [] ] ], [ "_what", [ true, true ], [ [] ] ] ]; _what params[ [ "_delPos", true, [ true ] ], [ "_delRank", true, [ true ] ] ]; if ( isMultiplayer && { isRemoteExecuted && { admin remoteExecutedOwner isNotEqualTo 2 } } ) exitWith { "SERVER: You are not a signed in admin" remoteExec[ "hint", remoteExecutedOwner ]; }; _fnc_getWho = { params[ "_who" ]; switch ( true ) do { case ( _who isEqualType "" ) : { [ _who ]; }; case ( _who isEqualType objNull && { isPlayer _who } ) : { [ vehicleVarName _who ]; }; case ( _who isEqualType true ) : { if ( _who ) then { allVariables missionProfileNamespace select{ _x select[ 0, 15 ] == "KIB_playerData_" } apply{ _x select[ 15, count _x ] }; }else{ KIB_playerData_players apply{ vehicleVarName _x }; }; }; }; }; if ( _who isEqualType [] ) then { _who = _who apply{ ( _x call _fnc_getWho ) #0 }; }else{ _who = _who call _fnc_getWho; }; KIB_playerData_nextUpdate = time + 1e10; { _data = missionProfileNamespace getVariable format[ "KIB_playerData_%1", _x ]; if ( _delPos ) then { _data set[ 0, nil ]; }; if ( _delRank ) then { _data set[ 1, nil ]; }; missionProfileNamespace setVariable[ format[ "KIB_playerData_%1", _x ], _data ]; }forEach _who; saveMissionProfileNamespace; KIB_playerData_nextUpdate = time; }; //initPlayerLocal.sqf KIB_fnc_setPlayerData = { params[ "_position", "_rating" ]; //Only allow execution from the server if ( isMultiplayer && { !isRemoteExecuted || { remoteExecutedOwner isNotEqualTo 2 }} ) exitWith {}; if !( isNil "_position" ) then { player setPosATL _position; }; if !( isNil "_rating" ) then { //Set rating, not add to what they already have player addRating ( _rating - rating player ); }; //Only once saved/defaults have been applied start saving data [ player ] remoteExec[ "KIB_fnc_updatePlayerData", 2 ]; }; KIB_fnc_applyAdminMenu = { //Only allow execution from the server if ( isMultiplayer && { !isRemoteExecuted || { remoteExecutedOwner isNotEqualTo 2 }} ) exitWith {}; player addAction[ "Show Admin Menu", { params [ "_target", "_caller", "_id", "_args" ]; [] call KIB_fnc_showAdminMenu; }, [], 1, false, false, "", "isNil 'KIB_adminActionIDs'" ]; }; KIB_fnc_showAdminMenu = { params[ [ "_show", true ] ]; if !( call BIS_fnc_admin == 2 ) exitWith { hint "You need to be a logged in admin to apply this menu"; }; if ( _show ) then { KIB_adminActionIDs = []; { _x params[ "_title", "_code", [ "_condition", "true" ] ]; KIB_adminActionIDs append[ player addAction[ _title, { //params [ "_target", "_caller", "_id", "_args" ]; params [ "", "", "", "_args" ]; _this call ( _args #0 ); }, [ _code ], 1, false, true, "", _condition ] ]; }forEach[ //[ title, code, condition ] [ "Delete Players Position", { [ cursorObject, [ true, false ] ] remoteExec[ "KIB_fnc_deletePlayerData" ] }, "!isNull cursorObject && { cursorTarget isKindOf 'Man' && isPlayer cursorObject }" ], [ "Delete Players Rating", { [ cursorObject, [ false, true ] ] remoteExec[ "KIB_fnc_deletePlayerData" ] }, "!isNull cursorObject && { cursorTarget isKindOf 'Man' && isPlayer cursorObject }" ], [ "Delete Players Data", { [ cursorObject ] remoteExec[ "KIB_fnc_deletePlayerData" ] }, "!isNull cursorObject && { cursorTarget isKindOf 'Man' && isPlayer cursorObject }" ], [ "Delete All Players Positions", { [ false, [ true, false ] ] remoteExec[ "KIB_fnc_deletePlayerData", 2 ] } ], [ "Delete All Players Ratings", { [ false, [ false, true ] ] remoteExec[ "KIB_fnc_deletePlayerData", 2 ] } ], [ "Delete All Players Data", { [ false ] remoteExec[ "KIB_fnc_deletePlayerData", 2 ] } ], [ "Delete ALL Data", { [ true ] remoteExec[ "KIB_fnc_deletePlayerData", 2 ] } ], [ "Close Admin Menu", { [ false ] call KIB_fnc_showAdminMenu } ] ]; }else{ { player removeAction _x; }forEach KIB_adminActionIDs; KIB_adminActionIDs = nil; }; }; params[ "_player" ]; [ _player ] remoteExec[ "KIB_fnc_getPlayerData", 2 ]; Again totally untested, let me know if there are any problems. Update: New version that saves players starting position, added options to admin menu to reset position/rating. TEST MISSION 1 Share this post Link to post Share on other sites
kibaBG 53 Posted April 21 @Larrow Unfortunately, I cannot make it work and save players position ... Share this post Link to post Share on other sites
Larrow 2820 Posted April 23 Strange, I have just tested it on my dedicated with no issues. Are you seeing any errors in the server or clients RPT? Is it maybe a copy and paste issue from the forum inserting hidden characters? Share this post Link to post Share on other sites
kibaBG 53 Posted May 1 Hi, I just tested it again but its not working. How I am testing: I start the dedi server and the headless, login as admin, choose the mission ("NightZ"), spawn, wait for 10 min on some place, then get out of server, turn down server and repeat. Its no loading the player's position. I am adding the rpt log: https://drive.google.com/file/d/1ajWGH5oQj0jw1YlMfZnYiz9lheSuIHg1/view?usp=sharingMaybe the issue is I am using Grad Persistence script to save the player's loadout? I have turned off the option to save player's position in description.ext class CfgGradPersistence { missionTag = "NightZ"; loadOnMissionStart = 1; missionWaitCondition = "true"; playerWaitCondition = "true"; saveUnits = 0; saveVehicles = 1; saveContainers = 1; saveStatics = 0; saveGradFortificationsStatics = 0; saveMarkers = 0; saveTasks = 0; saveTriggers = 0; savePlayerInventory = 1; savePlayerDamage = 0; savePlayerPosition = 0; savePlayerMoney = 0; saveTeamAccounts = 0; saveTimeAndDate = 1; }; It's not loading player's position anyway ... UPDATE: @Larrow 's script works flawlessly, my problem was the dedicated server profile and connected client profile were the same preventing any changes to it. Big thanks to @Larrow who helped me to solve the problem! Share this post Link to post Share on other sites