Jump to content
Kettlewell

Retrieving variables from the server

Recommended Posts

In Arma 2 this was pretty easy using publicvariables but in Arma 3 it's just not working out for me.

How can I retrieve some booleans and integer values from the server?

If someone actually knows how to use publicvariables to send to the server and back to the client I would be most grateful because it's driving me bloody insane.

Share this post


Link to post
Share on other sites

That's interesting.

I have not noticed that it works any different in Arma 3 than in Arma 2. Use

publicVariable "Variable";

to set the variable across the network. And use

"Variable" addPublicVariableEventHandler = {
   // Event handler code here...
};

to perform actions when the value changes.

Can you have forgot anything fundamental? Misspellings or uninitialized variables?

I just released the "ASCOM framework" which contains a lot of publicVariable and event handlers. Btw, its purpose is to to solve the very problem you have. Maybe something you want to try?

http://forums.bistudio.com/showthread.php?151838-ASCOM-Framework-Release

Share this post


Link to post
Share on other sites
That's interesting.

I have not noticed that it works any different in Arma 3 than in Arma 2. Use

publicVariable "Variable";

to set the variable across the network. And use

"Variable" addPublicVariableEventHandler = {
   // Event handler code here...
};

to perform actions when the value changes.

Can you have forgot anything fundamental? Misspellings or uninitialized variables?

I just released the "ASCOM framework" which contains a lot of publicVariable and event handlers. Btw, its purpose is to to solve the very problem you have. Maybe something you want to try?

http://forums.bistudio.com/showthread.php?151838-ASCOM-Framework-Release

I'm looking at your framework trying to identify how it works so I can use it.

My problem is that with publicvariables it seems you need to have a variable defined client side such as for mine,

CapRed = 1;
publicVariableServer "CapRed";

Though CapRed is useless, I just wanted to cause the server to set off a function and that function in return is supposed to do a public variable to send the new capture point variables to all the clients but it just won't work out for me.

Share this post


Link to post
Share on other sites

What about something like

init.sqf

if (isServer) then {
 myServerFunctionName = {
   _passedVariable = _this select 0;
   [[_passedVariable],"myClientFunctionName",true,false] spawn BIS_fnc_MP;
 };
};

waitUntil {!(isNull player)};

if (!(isNull player)) then {
 myClientFunctionName = {
   hint str (_this select 0);
 };
};

//run from trigger
//[[1],"myServersFunctionName",false,false] spawn BIS_fnc_MP;  //the first false here makes the function only be called on the server

Just as an example. client calls a function on the server from the trigger (see commented command) and passes it a variable. Server calls a function on all clients and passes the variable back. All clients hint the variable.

OR

if (isServer) then {
 myServerFunctionName = {
   CapRed = _this select 0;
   publicVariable "CapRed";
 };
};

waitUntil {!(isNull player)};

if (!(isNull player)) then {
 CapRed = 0;
 "CapRed" addPublicVariableEventHandler {
   hint (str CapRed);
 };
};

//run from trigger
//[[1],"myServersFunctionName",false,false] spawn BIS_fnc_MP;  //the first false here makes the function only be called on the server

Same but server publicVariable's the value back to all clients.

I think thats correct im a little new to ARMA scripting but quickly tested it on a dedicated and looks about right.

Edited by Larrow

Share this post


Link to post
Share on other sites

Try this:

Server

if (isServer) then {
CapRed = true;
publicVariable "CapRed";
};

Client

if (!isServer) then {
"CapRed" addPublicVariableEventHandler { hint str(_this select 1)  };
};

---------- Post added at 18:06 ---------- Previous post was at 17:58 ----------

Here's an example if you want to pass the variable to a single client

Server

if (!isServer) then {
CapRed = true;

"GET_CapRed" addPublicVariableEventHandler { 
	(owner (_this select 1)) publicVariableClient "CapRed";
};
};

Client

if (!isServer) then {
GET_CapRed = player;
publicVariableServer "GET_CapRed";

"CapRed" addPublicVariableEventHandler { hint str(_this select 1)  };
};

Share this post


Link to post
Share on other sites

Hi all,

 

I am new at this point and trying to setup a simple communicatin between client and software. I am using Arma 2 OA, Dayz Epoch Server. I've placed this in an test.sqf file:

if(isServer || isDedicated) {
	
	// Server?
	"packetServer" addPublicVariableEventHandler { 
		packetClient = [];
		publicVariableClient "packetClient"; 
	};
	
}
else {
	
	// Client?
	
	"packetClient" addPublicVariableEventHandler {
		hint "MSG FROM SERVER";
	};
	publicVariableServer = "packetServer";
	systemChat "Executed test.sqf";
	
};

The test.sqf is called within init.sqf like:

[] execVM "test.sqf";

Any suggestions?

 

Cheers,

SKO85

Share this post


Link to post
Share on other sites

Thank you both for the quick reply. I have already checked the BIKI's and implemented some examples on the server, but somehow it does not work for me. In some cases it does not go further than the variable definition code or the definition handler. I have put an hint code or sideChat code to let me know that the script is loaded or executed with success, but I dont see those messages. If I remove the publicVariabel lines or handler definition, it shows the hint or sideChat message. It could be that I need to implement a some kind of WAIT call untill the required functions are loaded?

 

I am a C#.NET developer, but quite new at SQF scripting. Is it possible to provide me an example of an init.sqf or other sqf file that is called from init.sqf? Some questions I have at this moment:

 

  • Do i need to define the publicVariable before I can use it? Which construction is correct to define a server public variable? Example:myServerVar = [];
    publicVariableServer "myServerVar";
    
    // or...
    
    myServerVar = [];
    publicVariable "myServerVar";
  • And after I defined the variable, I can define the handler for it? Or the public variable definition is not required for this?
  • "myServerVar" addPublicVariableEventHandler {
    // Do some server-side coding here...
    };
  • Do i need to change my BE filters (add or remove something) to allow the public variable to work?

 

I will check the other links, just in case I missed something.

 

Cheers,

SKO85

Share this post


Link to post
Share on other sites

What exactly are you trying to do?  

 

A publicVariableEventHandler is just to monitor the value of a given variable and run some code each time it changes.  It's used usually, in my experience, to execute code by only having to transmit a single value across the network instead of a full script.

 

So like for a helicopter transport system you'd set it up so that the server is waiting for a variable named needsPickup to change from false to true and when it does it executes the script that spawns a helicopter, flies to where it was requested from and brings them back to base and then despawns.  So the true value of needsPickup is transmitted rather than the several potential kilobytes of scripts.

 

Or used to switch day to night on a server by only one client.  You can setup an addAction that only the moderator of a mission has access to that sets a variable and publicizes it.  The other clients are all waiting to see that value change and run setDate locally via PVEH to change to night since the effects of setDate are local.

 

So knowing what you're trying to do would help to explain how to do it.

Share this post


Link to post
Share on other sites

Hi kylania,

 

Thanks for the explaination. That makes sence. This is my use-case and what I am trying to do in the final setup.

 

  1. I have an action menu with an item which will need to trigger a call to the server. So I need to call a function on the server from th client.
  2. The server function will execute a MySQL Query (I am using Arma2NET with MySQL) and should return a list of items back. I need to call a function on the client from the server code to present it in a dialog, but for testing a HINT will be sufficient.
  3. So pseudo code:

Server code (PSEUDO, NOT CORRECT SQF):

fn_getStuffFromMySQL = {
    
   // Get results from MySQL.
   _results = <execute mysql query and fill results>;

   // Call client function (callback) and pass results.
   [_results] <clientCallbackFunc>

};

Client code  (PSEUDO, NOT CORRECT SQF):

// Triggered when I press an item in the Admin Tool for example.
my_menuItemAction = {

    // Execute function on server and collect results from MySQL.
    [] fn_getStuffFromMySQL;

};

// Callback called from server side code.
clientCallbackFunc = { hint "GOT SOMETHING FROM SERVER"; };

So basically this is the concept I want to use. I am creating some scripts and dialogs interacting with the MySQL database. For an example I would like to simply use something to send me numbers or text instead of doing complex stuff with MySQL now. So _results from server could be ["THIS IS A MESSAGE FROM SERVER"] or something similar.

 

Is the use-case more clear now? If you need more input, just let me know.

 

  • Is this the right way of doing this?
  • Do I need to register these functions somehow in the init? [] execVM or something similar?

 

 

Cheers,

SKO85

Share this post


Link to post
Share on other sites

Ok, I finally got it working. I have the following now and this seems to work great. For the noobs like me out there :)

 

This is my test.sqf which is called in init.sqf.

// Wait untill
waitUntil {time > 0};


// Executed by Server.
if (isDedicated) then {
    "packetTest" addPublicVariableEventHandler {
        _pcid = owner (_this select 1 select 0);
        _number1 = _this select 1 select 1;
        _number2 = _this select 1 select 2;
        _thesum = _number1 + _number2;
        packetTest = _thesum;
        _pcid publicVariableClient "packetTest";
    };
};

// Executed by client only.
if (!isDedicated && !isServer) then {
    sumNum = 0;

    "packetTest" addPublicVariableEventHandler {
        _thesum = _this select 1;
        hint str _thesum;
    };
	
    systemChat "Debug: Loaded client packetTest handler.";
};

In init.sqf I do:

[] execVM "test.sqf";

The on-click script that triggers the call to the server is a separated file which i call whenever I press an action menu item:

waitUntil {time > 0};
packetTest = [player, 22, sumNum]; 
publicVariableServer "packetTest";
sumNum = sumNum + 1;
systemChat "Debug: Hit Test Script click.";

You see that I increase the sumNum with +1 everytime I call the publicVariableServer. If you pass the same value all the time (so not chaning the publicVariable packetTest), the server-side handler will only be triggered once as the variable is not changing. At least this was so in my case.

 

A good reference that helped me out:

http://killzonekid.com/arma-scripting-tutorials-basic-multiplayer-coding/

 

 

I hope this helps someone. 

 

Cheers,

SKO85

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×