PDA

View Full Version : Client <-> Serverside Function Caller


Inverness
04-19-2007, 11:58 PM
This is a set of functions I made after waitfor() was implemented.
The notification functions, which I made for my information system so the gui would open after the information was gotten and not before. Its used for the client and server function triggers to make the script wait until you've got the return of the function.

// This was placed in a weapon named System.
public function waitForNotify(obj, action, time) {
return waitfor(obj, "Notify" @ action, time);
}
public function notifyClient(obj, ename, time) {
triggerClient("gui", name, "notify", obj, ename, time);
}
public function notifyServer(obj, ename, time) {
scheduleEvent(0, "ActionServerSide", obj, ename, time);
}
public function clientFunction(fobj, fname, fparams) {
temp.out = 0;

client.temp.(@ "clientfunction_" @ fname) = null;
triggerClient("gui", name, "clientfunction", fname, fparams, fobj);
waitForNotify(name, "ClientFunctionEnd", 5);
out = client.temp.(@ "clientfunction_" @ fname);
client.temp.(@ "clientfunction_" @ fname) = null;
return out;
}
function onActionServerSide() {
switch (params[0]) {
case "notify":
makevar(params[1]).scheduleEvent(params[3], "Notify" @ params[2], null);
break;
case "serverfunction":
temp.r = 0;
temp.fn = params[1];

r = makevar(params[3] @ "." @ params[1])(params[2][0], params[2][1], params[2][2], params[2][3], params[2][4], params[2][5]);
client.temp.(@ "serverfunction_" @ fn) = r;
notifyClient(name, "ServerFunctionEnd", 0);
break;
}
}
//#CLIENTSIDE
function onActionClientSide() {
switch (params[0]) {
case "notify":
makevar(params[1]).scheduleEvent(params[3], "Notify" @ params[2], null);
break;
case "clientfunction":
temp.r = 0;
temp.fn = params[1];

r = makevar(params[3] @ "." @ params[1])(params[2][0], params[2][1], params[2][2], params[2][3], params[2][4], params[2][5]);
client.temp.(@ "clientfunction_" @ fn) = r;
notifyServer(name, "ClientFunctionEnd", 0);
break;
}
}
public function waitForNotify(obj, action, time) {
return waitfor(obj, "Notify" @ action, time);
}
public function notifyServer(obj, ename, time) {
triggerServer("gui", name, "notify", obj, ename, time);
}
public function notifyClient(obj, ename, time) {
scheduleEvent(0, "ActionClientSide", "notify", obj, ename, time);
}
public function serverFunction(fobj, fname, fparams) {
temp.out = 0;

client.temp.(@ "serverfunction_" @ fname) = null;
triggerServer("gui", name, "serverfunction", fname, fparams, fobj);
waitForNotify(name, "ServerFunctionEnd", 5);
out = client.temp.(@ "serverfunction_" @ fname);
client.temp.(@ "serverfunction_" @ fname) = null;
return out;
}

Obviously, to use this correctly the object containing the function you're calling must have an identifier, the name variable.

And here is the script I used to test it:

function onCreated() {
with (findPlayer("Inverness")) {
echo(System.clientFunction("InverTest","clientFunction", null));
}
}
//#CLIENTSIDE
public function clientFunction() {
return "OOGLEBOOGLESMORF";
}

Which worked obviously.

I don't know how this would affect script performance or anything, I just did it because using triggerServer() and triggerClient() and previously triggerAction() has always irritated me.

killerogue
04-20-2007, 12:42 AM
Oooh, really nice Inver. Tho I doubt I may use these they seem to be really useful!

Rep++ 4 u!

Inverness
04-20-2007, 12:49 AM
Well just think, if you have this around you don't need to use triggerServer() or triggerClient() anymore unless its some special case or so. And it would work for anything that has an identifier.

Hmm I just realized that since I'm using makevar() for triggering the function that I could probably just include the object identifier as part of the function name rather than separate :D

Edit: Its not working for some reason :cry: *sulk*

Inverness
05-03-2007, 12:41 AM
Here are some changes I did shortly afterwards.

Changes: Added serverFunction2() and clientFunction2() these functions continue the script rather than waiting that 0.05 second for a returned variable from the distant function.

Also made it so if you leave the object null it will call the function realative to the system, meaning it can call globals. So on clientside you could do: System.serverFunction(null, "addweapon", "WeaponName");

public function waitForNotify(obj, action, time) {
return waitfor(obj, "Notify" @ action, time);
}
public function notifyClient(obj, ename, time) {
triggerClient("gui", name, "notify", obj, ename, time);
}
public function notifyServer(obj, ename, time) {
scheduleEvent(0, "ActionServerSide", obj, ename, time);
}
public function clientFunction(fobj, fname, fparams) {
temp.out = 0;

client.temp.(@ "clientfunction_" @ fname) = null;
triggerClient("gui", name, "clientfunction", fname, fparams, fobj);
waitForNotify(name, "ClientFunctionEnd", 5);
out = client.temp.(@ "clientfunction_" @ fname);
client.temp.(@ "clientfunction_" @ fname) = null;
return out;
}
public function clientFunction2(fobj, fname, fparams) {
triggerClient("gui", name, "clientfunction", fname, fparams, fobj);
}
function onActionServerSide() {
switch (params[0]) {
case "notify":
makevar(params[1]).scheduleEvent(params[3], "Notify" @ params[2], null);
break;
case "serverfunction":
temp.r = 0;
temp.fn = params[1];

if (params[3] != null)
r = makevar(params[3] @ "." @ params[1])(params[2][0], params[2][1], params[2][2], params[2][3], params[2][4], params[2][5]);
else
r = makevar(params[1])(params[2][0], params[2][1], params[2][2], params[2][3], params[2][4], params[2][5]);
client.temp.(@ "serverfunction_" @ fn) = r;
notifyClient(name, "ServerFunctionEnd", 0);
break;
case "serverfunction2":
if (params[3] != null)
r = makevar(params[3] @ "." @ params[1])(params[2][0], params[2][1], params[2][2], params[2][3], params[2][4], params[2][5]);
else
r = makevar(params[1])(params[2][0], params[2][1], params[2][2], params[2][3], params[2][4], params[2][5]);
break;
}
}
//#CLIENTSIDE
function onActionClientSide() {
switch (params[0]) {
case "notify":
makevar(params[1]).scheduleEvent(params[3], "Notify" @ params[2], null);
break;
case "clientfunction":
temp.r = 0;
temp.fn = params[1];

if (params[3] != null)
r = makevar(params[3] @ "." @ params[1])(params[2][0], params[2][1], params[2][2], params[2][3], params[2][4], params[2][5]);
else
r = makevar(params[1])(params[2][0], params[2][1], params[2][2], params[2][3], params[2][4], params[2][5]);
client.temp.(@ "clientfunction_" @ fn) = r;
notifyServer(name, "ClientFunctionEnd", 0);
break;
case "clientfunction2":
if (params[3] != null)
r = makevar(params[3] @ "." @ params[1])(params[2][0], params[2][1], params[2][2], params[2][3], params[2][4], params[2][5]);
else
r = makevar(params[1])(params[2][0], params[2][1], params[2][2], params[2][3], params[2][4], params[2][5]);
}
}
public function waitForNotify(obj, action, time) {
return waitfor(obj, "Notify" @ action, time);
}
public function notifyServer(obj, ename, time) {
triggerServer("gui", name, "notify", obj, ename, time);
}
public function notifyClient(obj, ename, time) {
scheduleEvent(0, "ActionClientSide", "notify", obj, ename, time);
}
public function serverFunction(fobj, fname, fparams) {
temp.out = 0;

client.temp.(@ "serverfunction_" @ fname) = null;
triggerServer("gui", name, "serverfunction", fname, fparams, fobj);
waitForNotify(name, "ServerFunctionEnd", 5);
out = client.temp.(@ "serverfunction_" @ fname);
client.temp.(@ "serverfunction_" @ fname) = null;
return out;
}
public function serverFunction2(fobj, fname, fparams) {
triggerServer("gui", name, "serverfunction2", fname, fparams, fobj);
}

Inverness
10-25-2007, 01:18 AM
Trimmed the extra things. Also made it so the parameters weren't in array.

public function clientFunction(fobj, fname, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) {
temp.out = 0;

triggerclient("gui", name, "clientfunction", fobj, fname, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
waitfor(this, "ClientFunctionEnd", 5);
out = this.cfreturn;
this.cfreturn = null;
return out;
}
public function clientFunction2(fobj, fname, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) {
triggerclient("gui", name, "clientfunction2", fobj, fname, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
}
function onActionServerSide() {
if (params[0] == "end") {
this.cfreturn = params[1];
trigger("ClientFunctionEnd", null);
}
else if (params[0] == "serverfunction") {
if (params[1] != null)
triggerclient("gui", name, "end", makevar(params[1] @ "." @ params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]));
else
triggerclient("gui", name, "end", makevar(params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]));
}
else if (params[0] == "serverfunction2") {
if (params[1] != null)
makevar(params[1] @ "." @ params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]);
else
makevar(params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]);
}
}
//#CLIENTSIDE
function onActionClientSide() {
if (params[0] == "end") {
this.sfreturn = params[1];
trigger("ServerFunctionEnd", null);
}
else if (params[0] == "clientfunction") {
if (params[1] != null)
triggerserver("gui", name, "end", makevar(params[1] @ "." @ params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]));
else
triggerserver("gui", name, "end", makevar(params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]));
}
else if (params[0] == "clientfunction2") {
if (params[1] != null)
makevar(params[1] @ "." @ params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]);
else
makevar(params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]);
}
}
public function serverFunction(fobj, fname, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) {
temp.out = 0;

triggerserver("gui", name, "serverfunction", fobj, fname, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
waitfor(this, "ServerFunctionEnd", 5);
out = this.sfreturn;
this.sfreturn = null;
return out;
}
public function serverFunction2(fobj, fname, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) {
triggerserver("gui", name, "serverfunction2", fobj, fname, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
}

Inverness
08-12-2008, 05:48 AM
Having temp. makes variable lookup faster.

public function clientfunction(fobj, fname, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) {
triggerclient("gui", this.name, "clientfunction", temp.fobj, temp.fname, temp.p0, temp.p1, temp.p2, temp.p3, temp.p4, temp.p5, temp.p6, temp.p7, temp.p8, temp.p9);
waitfor(this, "ClientFunctionEnd", 5);
temp.out = thiso.cfreturn;
thiso.cfreturn = null;
return temp.out;
}
public function clientfunction2(fobj, fname, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) {
triggerclient("gui", this.name, "clientfunction2", temp.fobj, temp.fname, temp.p0, temp.p1, temp.p2, temp.p3, temp.p4, temp.p5, temp.p6, temp.p7, temp.p8, temp.p9);
}
public function clientfunction3(wtime, fobj, fname, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) {
triggerclient("gui", this.name, "clientfunction", temp.fobj, temp.fname, temp.p0, temp.p1, temp.p2, temp.p3, temp.p4, temp.p5, temp.p6, temp.p7, temp.p8, temp.p9);
waitfor(this, "ClientFunctionEnd", temp.wtime);
temp.out = thiso.cfreturn;
thiso.cfreturn = null;
return temp.out;
}
public function npcfunction(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) {
temp.obj = findlevel(temp.p0);
for (temp.i: obj.npcs) {
if (temp.i.id == temp.p1) {
return temp.i.(@ temp.p2)(temp.p3, temp.p4, temp.p5, temp.p6, temp.p7, temp.p8, temp.p9);
}
}
}
function onActionServerSide() {
if (params[0] == "end") {
thiso.cfreturn = params[1];
trigger("ClientFunctionEnd", null);
}
else if (params[0] == "serverfunction") {
if (params[1] != null)
triggerclient("gui", this.name, "end", makevar(params[1] @ "." @ params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]));
else
triggerclient("gui", this.name, "end", makevar(params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]));
}
else if (params[0] == "serverfunction2") {
if (params[1] != null)
makevar(params[1] @ "." @ params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]);
else
makevar(params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]);
}
}
//#CLIENTSIDE
function onActionClientSide() {
if (params[0] == "end") {
thiso.sfreturn = params[1];
trigger("ServerFunctionEnd", null);
}
else if (params[0] == "clientfunction") {
if (params[1] != null)
triggerserver("gui", this.name, "end", makevar(params[1] @ "." @ params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]));
else
triggerserver("gui", this.name, "end", makevar(params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]));
}
else if (params[0] == "clientfunction2") {
if (params[1] != null)
makevar(params[1] @ "." @ params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]);
else
makevar(params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]);
}
}
public function npcfunction(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) {
return findnpcbyid(temp.p0).(@ temp.p1)(temp.p2, temp.p3, temp.p4, temp.p5, temp.p6, temp.p7, temp.p8, temp.p9);
}
public function serverfunction(fobj, fname, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) {
triggerserver("gui", this.name, "serverfunction", temp.fobj, temp.fname, temp.p0, temp.p1, temp.p2, temp.p3, temp.p4, temp.p5, temp.p6, temp.p7, temp.p8, temp.p9);
waitfor(this, "ServerFunctionEnd", 5);
temp.out = thiso.sfreturn;
thiso.sfreturn = null;
return temp.out;
}
public function serverfunction2(fobj, fname, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) {
triggerserver("gui", this.name, "serverfunction2", temp.fobj, temp.fname, temp.p0, temp.p1, temp.p2, temp.p3, temp.p4, temp.p5, temp.p6, temp.p7, temp.p8, temp.p9);
}
public function serverfunction3(wtime, fobj, fname, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) {
triggerserver("gui", this.name, "serverfunction", temp.fobj, temp.fname, temp.p0, temp.p1, temp.p2, temp.p3, temp.p4, temp.p5, temp.p6, temp.p7, temp.p8, temp.p9);
waitfor(this, "ServerFunctionEnd", temp.wtime);
temp.out = thiso.sfreturn;
thiso.sfreturn = null;
return temp.out;
}

Dan
08-15-2008, 02:08 PM
I'm using 20 different params and it doesn't work :S what now? [/lol]

Codein
08-15-2008, 02:28 PM
Couldn't you just put the parameters in an array? =o

Admins
08-15-2008, 03:45 PM
Hmmm Can't you just use params[] ? When you call a function of another object then the parameters are put in params[] (params[] always contains the parameters of the first function called).

Chompy
08-15-2008, 07:40 PM
I'm using 20 different params and it doesn't work :S what now? [/lol]

:P

Well, some examples would be nice Invern :p

Btw, here are some:


join("triggercontrol");

public function foo(baz) {
echo(baz);
return "bar";
}

//#CLIENTSIDE
function onCreated() {
echo(serverfunction(this, "foo", "abc"));
}


Basically this will echo "abc" in RC and "bar" in F2 on client

---------------


join("triggercontrol");

public function echo2(baz, abc) {
echo(baz @" -> "@ abc);
}

//#CLIENTSIDE
function onCreated() {
serverfunction2(this, "echo2", "foo", "bar");
}


This will echo "foo -> bar" in RC

---------------


join("triggercontrol");

function onCreated() {
temp.a = "You just got poisoned by a";
temp.a @= randomstring({"n Apple", " Script"});

/* clientfunction/2/3 needs to be in the scope of
an object (preferebly a player) */
with (findplayer("Chompy")) {
clientfunction2(this.name, "f2message", temp.a);
}
}

//#CLIENTSIDE
public function f2message(msg) {
echo(msg);
}


This will echo "You just got poisoned by an Apple" or "You just got poisoned by a Script" in F2 messages

---------------


/*-- SERVERSIDE --*/

/*
How clientfunction works is that it allows to get data from the clientside.
Pretty neat feature I must say. Check out first example above. */
clientfunction(
fobj, // string or null as value, string if the function is in another wnpc (example of a string is 'this.name')
fname, // function name
p0, // params0
p1, // params1 ETC
);

/*
clientfunction2 is different from clientfunction, because clientfunction2
because it's only job is to trigger the function on client, not to return
any data back home to the serverside. */
clientfunction2(
fobj, // string or null as value, string if the function is in another wnpc (example of a string is 'this.name')
fname, // function name
p0, // params0
p1, // params1 ETC
);

/*
clientfunction3 is almost the same as clientfunction, but with a little
twist. clientfunction will only wait max 5 seconds before it continues,
wheter or not if it has got the data back from the clientside.

Basically what's different is the wtime argument. */
clientfunction3(
wtime, // specifies how long the function will wait for data from the clientside
fobj, // string or null as value, string if the function is in another wnpc (example of a string is 'this.name')
fname, // function name
p0, // params0
p1, // params1 ETC
);

/* npcfunction is to trigger an NPC in a said level with a said id. */
npcfunction(
p0, // the level to check in
p1, // the id of the npc to check fo
p2, // function name to trigger
p3, // param0
p4, // param1 ETC
);


/*
Note: When using any of the clientfunction* functions, if it's not working,
try it within a scope.

with(findplayer("Chompy")) {
clientfunction2(...);
}
*/

/*-- SERVERSIDE END --*/


/*-- CLIENTSIDE --*/

/* serverfunction is used exactly like clientfunction, but to return data from
the serverside to the clientside. */
serverfunction(
fobj, // string or null as value, string if the function is in another wnpc (example of a string is 'this.name')
fname, // function name
p0, // params0
p1, // params1 ETC
);

/* serverfunction2 is used to trigger a function on the serverside, but it won't
return any data from the serverside to the clientside. */
serverfunction2(
fobj, // string or null as value, string if the function is in another wnpc (example of a string is 'this.name')
fname, // function name
p0, // params0
p1, // params1 ETC
);

/* serverfunction3 is used almost exactly like the serverfunction, besides that
serverfunction only waits a maximum 5 seconds for data from the
serverside to arrive. */
serverfunction3(
wtime, // Specifies how long the function should wait from data from the serverside
fobj, // string or null as value, string if the function is in another wnpc (example of a string is 'this.name')
fname, // function name
p0, // params0
p1, // params1 ETC
);

/* npcfunction is used to trigger a function in an NPC with a said ID */
npcfunction(
p0, // the id of the NPC
p1, // function name to trigger in the NPC
p2, // param0
p3, // param1 ETC
};

/*-- CLIENTSIDE END --*/


/* -- GLOSSARY -- */

/*

wtime = wait time
fobj = function object
fname = function name
p0 = parameter 0 (the first parameter)
p1 = parameter 1 (the second parameter)

PS: parameters start at 0

*/

/* -- GLOSSARY END -- */


:-)

PS: Might be some spelling mistakes, if there are, my excuse is: I'm Norwegian ^^

If anything is wrong, let me now =o

Inverness
08-15-2008, 07:51 PM
Hmmm Can't you just use params[] ? When you call a function of another object then the parameters are put in params[] (params[] always contains the parameters of the first function called).Ah, why does params[] only work with different objects and not the same one? x-x

I had assumed params[] only worked with events because I couldn't get it to work with two functions in same object, never tried two functions in different objects.

Edit: Chompy, first parameter needs to be a string or null, not an object.

Chompy
08-15-2008, 09:29 PM
Ah, why does params[] only work with different objects and not the same one? x-x

I had assumed params[] only worked with events because I couldn't get it to work with two functions in same object, never tried two functions in different objects.

Edit: Chompy, first parameter needs to be a string or null, not an object.

Works with an object though, did for me :o, but I'll change the post though

Inverness
08-15-2008, 10:27 PM
Works with an object though, did for me :o, but I'll change the post thoughIt only works with an object because Stefan allows stuff that really shouldn't be allowed.

I think Stefan should make Graal's scripting language Stackless Python :D.

Chompy
08-15-2008, 11:04 PM
It only works with an object because Stefan allows stuff that really shouldn't be allowed.

I think Stefan should make Graal's scripting language Stackless Python :D.

hehe :p

DrakilorP2P
08-16-2008, 01:29 AM
I think Stefan should make Graal's scripting language Stackless Python :D.

Nay! GScript's successor will be Lisp. I shall make sure of it post-haste.

Admins
08-16-2008, 02:50 AM
Function calls take quite a lot of CPU time, thats why params[] is limited and not provided for each function. Also changing the behaviour now would break some stuff. There are e.g. scripts on Kingdoms that read #p() in sub-classes.