Lordeath19 0 Posted November 18, 2018 I have recently created a local server (just hosting from the server browser), this server has some scripts that i don't want to expose to the player (due to them stealing it). I found out you can use the profileNamespace to save data to the profile of the player and as such i am able to store strings, arrays and stuff like that. My problem arises after i try to save scripts into the namespace -> saving them using the saveProfileNamespace (script is callable and is fine so far) -> shutting down the server after finishing playing. Now, when i start the server i am able to load the variables from the namespace and use them, but i can't call\spawn code that i stored inside the profile namespace as it raises this error: Global namespace not passed during: hint "test" Error Local variable in global space in order for you to replicate do the following: 1. start the debug console in an editor mission 2. enter these 2 lines: profileNamespace setVariable ["testFunction",{hint "test";}]; saveProfileNamespace; 3. restart the game 4. start the debug console again 5. enter this line: [] spawn (profileNamespace getVariable "testFunction"); 6. wonder desperately why the function isn't being executed 1 Share this post Link to post Share on other sites
gc8 977 Posted November 18, 2018 not sure but have you tried saveProfileNamespace ? Share this post Link to post Share on other sites
davidoss 552 Posted November 18, 2018 profileNamespace setVariable ["testFunction","hint 'testing hint'"]; saveProfileNamespace; [] spawn compile (profileNamespace getVariable "testFunction"); Share this post Link to post Share on other sites
Lordeath19 0 Posted November 18, 2018 Just now, davidoss said: profileNamespace setVariable ["testFunction","hint 'testing hint'"]; saveProfileNamespace; [] spawn compile (profileNamespace getVariable "testFunction"); In this small sample this will work great but my script is several hundred lines long, how could i do the same thing with my file? just wrap everything inside a string and hope for the best or is there a specific method i should use to do this correctly? Share this post Link to post Share on other sites
SkaceKachna 52 Posted November 18, 2018 You can use preprocessFileLineNumbers to load the script from file in string form. 1 Share this post Link to post Share on other sites
davidoss 552 Posted November 18, 2018 Best way is to load extra server mod with scripts. This allow you to access serversided files like this: [] execVM "\myservermod\script.sqf"; 2 Share this post Link to post Share on other sites
jandrews 116 Posted November 18, 2018 Just now, Lordeath19 said: I have recently created a local server (just hosting from the server browser), this server has some scripts that i don't want to expose to the player (due to them stealing it). I found out you can use the profileNamespace to save data to the profile of the player and as such i am able to store strings, arrays and stuff like that. My problem arises after i try to save scripts into the namespace -> saving them using the saveProfileNamespace (script is callable and is fine so far) -> shutting down the server after finishing playing. Now, when i start the server i am able to load the variables from the namespace and use them, but i can't call\spawn code that i stored inside the profile namespace as it raises this error: Global namespace not passed during: hint "test" Error Local variable in global space in order for you to replicate do the following: 1. start the debug console in an editor mission 2. enter these 2 lines: profileNamespace setVariable ["testFunction",{hint "test";}]; saveProfileNamespace; 3. restart the game 4. start the debug console again 5. enter this line: [] spawn (profileNamespace getVariable "testFunction"); 6. wonder desperately why the function isn't being executed Its an open source community. Why not allow other members to utilize your scripts too? Just saying. 1 Share this post Link to post Share on other sites
pierremgi 4900 Posted November 19, 2018 I'm rather sure that, when you setVariable a code, this code runs and you just record the return value if any (here none). You need to stringify the code. profileNameSpace setVariable ["testFunction", " hint 'test' "]; // here str ( {hint "test"}) doesn't work because str also returns a result. then: call compileFinal (profileNameSpace getVariable ["testFunction",""] ) Just an idea, sorry not tested. Oups, I didn't see the @Lordeath19 answer. So, confirmed. Not recommended anyway. Your profilenameSpace is not a good place for such big data. compileFinal is safer. Imho, saveProfileNameSapce is just a useless command as you "save" what you want when using setVariable in the profileNameSpace. Long discussion.... But, I never used them from my mods and always kept the data from Arma sessions. So? test with and without. Any difference? Share this post Link to post Share on other sites
SkaceKachna 52 Posted November 19, 2018 Also as sidenote, I would strongly discourage you from doing this, since you'll be polluting user profile with long texts, possibly decreasing user performance not only with your mission, but in arma as general. I don't know how exactly profile values work on backend part, but they're heavily used for UI stuff (the colors and positions of elements are saved using profile values) and having too much data in profile definitely increases load times of everything and sometimes even causes lags. If you really want to do this, send the scripts to user when connecting and save them to mission namesapce, that's much better solution and your scripts will be only stored in memory and erased upon leaving the mission. Share this post Link to post Share on other sites
genesis92x 810 Posted November 19, 2018 I would not recommend using the profilenamespace for something like this, If you really would like to hide a script I would just allow -filepatching on the server and let it load the script files from outside of the mission file. 2 Share this post Link to post Share on other sites
Larrow 2822 Posted November 20, 2018 20 hours ago, pierremgi said: I'm rather sure that, when you setVariable a code, this code runs and you just record the return value if any This is not true. Code is a data type, setting something to be of said type does not cause it to run. player setVariable[ "someCode", {hint "hello world"} ]; hint str( player getVariable "someCode" ); //hints {hint "hello world"} call (player getVariable "someCode"); //hints "hello world" As for the OP, I agree with the others, saving large pieces of code to profileNamespace is a bad idea. I would suggest either what @genesis92x says or by using a server side mod. 2 Share this post Link to post Share on other sites
pierremgi 4900 Posted November 20, 2018 Just now, Larrow said: This is not true. Code is a data type, setting something to be of said type does not cause it to run. player setVariable[ "someCode", {hint "hello world"} ]; hint str( player getVariable "someCode" ); //hints {hint "hello world"} call (player getVariable "someCode"); //hints "hello world" Yep. The fact is I tested something like: this setVariable [ "someCode", hint "hello world" ]; My bad. Share this post Link to post Share on other sites
HazJ 1289 Posted November 20, 2018 May be of use to you. @Lordeath19 Share this post Link to post Share on other sites
Dedmen 2714 Posted November 20, 2018 On 19.11.2018 at 1:56 AM, pierremgi said: call compileFinal (profileNameSpace getVariable ["testFunction",""] ) Your compileFinal there is useless and doesn't make any sense. Just use compile. I remember profileNamespace randomly having problems with code entries if some other mod would spam it with a huge amount of data. Never tried saving code on it's own. On 19.11.2018 at 1:56 AM, pierremgi said: compileFinal is safer. Wat? Care to explain? On 18.11.2018 at 7:33 PM, Lordeath19 said: this server has some scripts that i don't want to expose to the player (due to them stealing it) Okey. On 18.11.2018 at 7:33 PM, Lordeath19 said: you can use the profileNamespace to save data to the profile of the player So, you don't want to expose the script to the player, but sending it to the player and storing it in HIS profileNamespace sounds like a good idea to you? I think the best solution would be to just have your script in a server-side pbo and using CfgFunctions of course. If you need to execute it on the client, you have to send it over via publicVariable or publicVariableClient. BUT! At this point you are exposing the script to the player. You can't execute a script on a players machine that he cannot see, if he doesn't know what's inside of the script, how is he supposed to be executing it? On 18.11.2018 at 8:01 PM, gc8 said: not sure but have you tried saveProfileNamespace ? have you tried reading OP's post? On 18.11.2018 at 7:33 PM, Lordeath19 said: 2. enter these 2 lines: profileNamespace setVariable ["testFunction",{hint "test";}]; saveProfileNamespace; 1 Share this post Link to post Share on other sites
pierremgi 4900 Posted November 20, 2018 50 minutes ago, Dedmen said: Your compileFinal there is useless and doesn't make any sense. Just use compile. I remember profileNamespace randomly having problems with code entries if some other mod would spam it with a huge amount of data. Never tried saving code on it's own. Wat? Care to explain? CompileFinal is described in BIKI. This command is supposed to block cheat overriding, which is the first aim of this post, if I'm right. You protect the code to be over written by remote script. So, useless or not, I'll bet on this usage here, with no impact on performance (or perhaps positive one!). In fact, I always use it in all my server scripts. I'll change my mind the day some skilled people will demonstrate it's harmful for whatever reason. See also these posts: http://killzonekid.com/arma-scripting-tutorials-bis_fnc_compilefinal/ https://forums.bohemia.net/forums/topic/145078-compilefinal-is-nice-but-lets-improve-security-even-more/?page=4 (old one but interesting) 1 Share this post Link to post Share on other sites
Larrow 2822 Posted November 21, 2018 3 hours ago, pierremgi said: You protect the code to be over written by remote script. How is it going to be overwritten? If you call compileFinal someCode the code is compiled and called in the exact same instance, it is not stored anywhere in its compiled state so cannot be overwritten. So call compileFinal here makes no sense. This is the point @Dedmen is getting at. 1 Share this post Link to post Share on other sites
pierremgi 4900 Posted November 21, 2018 13 minutes ago, Larrow said: How is it going to be overwritten? If you call compileFinal someCode the code is compiled and called in the exact same instance, it is not stored anywhere in its compiled state so cannot be overwritten. So call compileFinal here makes no sense. This is the point @Dedmen is getting at. Thanks for this explanation. I understand you are referring to my " call compileFinal (profileNameSpace getVariable ["testFunction",""] )" above. It was just (a bad) example. To be sure I understand, is there still an interest for something like: blabla = compileFinal (profileNameSpace getVariable ["testFunction",""]; supposed to be run at mission start, then, further during the mission: call blabla (from anywhere) ? Please, consider that i'm not arguing but I'd like to understand. Thanks for your added comment, more understandable than "makes no sense". Share this post Link to post Share on other sites
Larrow 2822 Posted November 21, 2018 2 minutes ago, pierremgi said: blabla = compileFinal (profileNameSpace getVariable ["testFunction",""]; Ignoring the profileNamespace, which as discussed in this thread as generally a bad idea. Sure that is totally fine as the compiled string is being stored in the variable blabla and the variable is set as final, cannot be overwritten. For most general functions I would always recommend CfgFunctions which are always compiled final at mission load. Rather than compiling/preprocessing files your self, but this is still a valid method. 2 1 Share this post Link to post Share on other sites
HazJ 1289 Posted November 21, 2018 TAG_fnc_something = compileFinal preprocessFileLineNumbers "fn_something.sqf"; Maybe makes sense for this case if you don't use CfgFunctions as @Larrow said but honestly, I personally wouldn't say it makes a huge difference. If a hacker gets access then they usually just run their own code and cause havoc. They wouldn't care about hiding it into a already created function. Rarely see hackers on servers these days, especially with BE filters. Share this post Link to post Share on other sites
Lordeath19 0 Posted November 22, 2018 On 11/20/2018 at 9:18 PM, Dedmen said: So, you don't want to expose the script to the player, but sending it to the player and storing it in HIS profileNamespace sounds like a good idea to you? profile namespace is seperate to each client (and the server as well) so when i store a variable in profilenamespace when the script is executed on the server it will save the variable on the server. The idea is i store the functions on the server, and then use either remoteExec or some other form of function execution to run the function without exposing said function to the player On 11/20/2018 at 9:18 PM, Dedmen said: I think the best solution would be to just have your script in a server-side pbo and using CfgFunctions of course. If you need to execute it on the client, you have to send it over via publicVariable or publicVariableClient. BUT! At this point you are exposing the script to the player. You can't execute a script on a players machine that he cannot see, if he doesn't know what's inside of the script, how is he supposed to be executing it? I think i am gonna go with this solution and use remoteExec instead of publicVariables. Thanks everyone for all the help! Share this post Link to post Share on other sites
TheDusty01 3 Posted November 23, 2018 Hey, you could setup your CfgFunctions etc. on a server side mod (like in Altis Life with life_server stuff) and add all your client variables there and broadcast them over to the client which is connecting by using publicVariableClient. I know it works since it got used on a server. Since I don't have the codes right now I can only give you my idea right now. When client has the initialization part done, he calls a server-side script which broadcasts all the function variables over: private _unit = param [0, objNull, [objNull]]; { (owner _unit) publicVariableClient _x; } forEach (allVariables missionNameSpace); Hope I was able to help, Regards, Dusty 1 Share this post Link to post Share on other sites
Larrow 2822 Posted November 24, 2018 4 hours ago, TheDusty01 said: } forEach (allVariables missionNameSpace); NO do NOT EVER do this, broadcasting all missionNamespace variables is a terrible idea. It will broadcast all global variables potentially breaking many systems. As well as ALL functions, BI's and users this is potentially a couple of thousand, they may be safe due to compileFinal but it will still overload the network traffic. 1 Share this post Link to post Share on other sites
TheDusty01 3 Posted November 30, 2018 On 24.11.2018 at 5:00 AM, Larrow said: NO do NOT EVER do this, broadcasting all missionNamespace variables is a terrible idea. It will broadcast all global variables potentially breaking many systems. As well as ALL functions, BI's and users this is potentially a couple of thousand, they may be safe due to compileFinal but it will still overload the network traffic. You you're right with that. Obviously you should filter out variables which you don't need but in practice it works but I can't recommend it either, just a way to do it. Share this post Link to post Share on other sites