How to call commandToServer in C
by Kuju Manila · in Torque Game Engine · 10/17/2006 (2:16 am) · 14 replies
Hi need to call a server function called:
serverCmdSelectObject(%client, %mouseVec, %cameraPoint)
Yes, you got it right! It's from the Object Selection resource by Dave Myers.
But, I MUST call this command via commandToServer console function in C++:
Here's my code so far:
and I've tried:
Both of them just caused a crash. I know I'm doing syntactically wrong on the use of either evaluatef or commandToServer, I just don't know what's the right one. Please help. Note that both mMouseCam3DVec and mMouseCam3DPos are of type Point3F.
serverCmdSelectObject(%client, %mouseVec, %cameraPoint)
Yes, you got it right! It's from the Object Selection resource by Dave Myers.
But, I MUST call this command via commandToServer console function in C++:
Here's my code so far:
ConsoleMethod( ArcadeTSCtrl, onMouseDown, void, 2, 2, "()" ) {
Con::evaluatef("commandToServer(%s, %s, %s);", "SelectObject",
object->mMouseCam3DVec, object->mMouseCam3DPos);
}and I've tried:
ConsoleMethod( ArcadeTSCtrl, onMouseDown, void, 2, 2, "()" ) {
Con::evaluatef("commandToServer(\"%s\", \"%s\", \"%s\");", "SelectObject",
object->mMouseCam3DVec, object->mMouseCam3DPos);
}Both of them just caused a crash. I know I'm doing syntactically wrong on the use of either evaluatef or commandToServer, I just don't know what's the right one. Please help. Note that both mMouseCam3DVec and mMouseCam3DPos are of type Point3F.
#2
Also, the CommandToServer and CommandToClient calls typically take single-quoted strings, which I believe mean they get interned in the string table and turned into a number -- but I haven't seen this explicitly documented anywhere.
10/17/2006 (3:03 pm)
I'd probably just use dSprintf() to create those arguments. Each of the vec and pos arguments need to be separate strings.Also, the CommandToServer and CommandToClient calls typically take single-quoted strings, which I believe mean they get interned in the string table and turned into a number -- but I haven't seen this explicitly documented anywhere.
#3
Also, stefan is passing six numbers instead of two vectors. Which is probably a better way to do it.
Would probably be better as:
And then:
I probably made a mistake somewheree
Gary (-;
10/17/2006 (3:22 pm)
Or thirty seconds and grep shows this:ConsoleFunction( commandToServer, void, 2, RemoteCommandEvent::MaxRemoteCommandArgs + 1, "(string func, ...)"
"Send a command to the server.")
{
NetConnection *conn = NetConnection::getConnectionToServer();
if(!conn)
return;
sendRemoteCommand(conn, argc - 1, argv + 1);
}
ConsoleFunction( commandToClient, void, 3, RemoteCommandEvent::MaxRemoteCommandArgs + 2, "(NetConnection client, string func, ...)")
{
NetConnection *conn;
if(!Sim::findObject(argv[1], conn))
return;
sendRemoteCommand(conn, argc - 2, argv + 2);
}Also, stefan is passing six numbers instead of two vectors. Which is probably a better way to do it.
serverCmdSelectObject(%client, %mouseVec, %cameraPoint)
Would probably be better as:
serverCmdSelectObject(%client, %mouseVecX, %mouseVecY, %mouseVecZ, %cameraPointX, %cameraPointY, %cameraPointZ)
And then:
ConsoleMethod( ArcadeTSCtrl, onMouseDown, void, 2, 2, "()" ) {
NetConnection *conn = NetConnection::getConnectionToServer();
if(!conn)
return;
sendRemoteCommand(conn, GameAddTaggedString("SelectObject"),
object->mMouseCam3DVec.x,
object->mMouseCam3DVec.y,
object->mMouseCam3DVec.z,
object->mMouseCam3DPos.x,
object->mMouseCam3DPos.y,
object->mMouseCam3DPos.z);
}I probably made a mistake somewheree
Gary (-;
#4
On the case of Gary, I'm having trouble with the Linker because of the sendRemoteCommand call which is not found in any of the classes visible to my ArcadeTSCtrl, which is just identical to GameTSCtrl. The static function sendRemoteCommand is defined in net.cc that has no net.h to use #include on. I also tried putting an
extern void sendRemoteCommand(...blah blah); on my ArcadeTSCtrl and it results to this linker error.
10/17/2006 (10:48 pm)
I tried all of your suggestions with some small code syntax fixes but it seems on run-time, it just crashes.On the case of Gary, I'm having trouble with the Linker because of the sendRemoteCommand call which is not found in any of the classes visible to my ArcadeTSCtrl, which is just identical to GameTSCtrl. The static function sendRemoteCommand is defined in net.cc that has no net.h to use #include on. I also tried putting an
extern void sendRemoteCommand(...blah blah); on my ArcadeTSCtrl and it results to this linker error.
#5
SendRemoteCommand (); was never meant to be called directly, which is why I posted it as a script command. Gary did however forget to convert those floats into strings, which would lead to a crash as well because TorqueScript does not understand what a float is.
10/18/2006 (12:09 am)
I just tried the code I posted and there is no crash here. Where does it crash and can you post the callstack?SendRemoteCommand (); was never meant to be called directly, which is why I posted it as a script command. Gary did however forget to convert those floats into strings, which would lead to a crash as well because TorqueScript does not understand what a float is.
#6
10/18/2006 (3:06 am)
.
#7
10/18/2006 (3:20 am)
You still cannot pass a Point3F or a float to the scripting engine, Berserk.
#8
10/19/2006 (1:00 am)
I'm still having issues with this, I was careful already on what needs to be tagged, what needs to be string. Due to my frustration, I just left this part for a while, and did some other tasks needed to be done. I'll post again my update and what I tried when I get back to this. I want to resolve this since I really hate creating engine extensions with too much dependency of having .cs script files that's why I'm doing this instead of just making a script file for this functionality.
#9
I'd have to follow J hplus W's suggestion on using dSprintf to conform on how the other ConsoleFunctions, and ConsoleMethods are done. Also, I did carefully took note of my syntax. Now, here's my code.
Notice the following:
- I already made the string to be enclosed in single quotes. I also tested double quotes.
- The first use of evaluatef doesn't actually do the commandToServer call although in the console, all I see is this:
- The second use of evaluatef obviously generate a parse error, but I removed the quotes in the dSprintfs to make it right, still it only produces the same output as the first evaluatef
- The third one is using executef like most of you suggested. Using that, I only get the message:
- The fourth one:
- Fifth: Crashes
- Last one, just out of curiosity, I want to know if evaluatef does its thing. As expected, it does correctly:
Sigh, can't still find what's wrong.
10/20/2006 (12:04 am)
Hi I'm back!I'd have to follow J hplus W's suggestion on using dSprintf to conform on how the other ConsoleFunctions, and ConsoleMethods are done. Also, I did carefully took note of my syntax. Now, here's my code.
ConsoleMethod( ArcadeTSCtrl, onMouseDown, void, 2, 2, "()" ){
char* retBufferPos = Con::getReturnBuffer(256);
char* retBufferVec = Con::getReturnBuffer(256);
const Point3F &pos = object->getMouseCam3DPos();
const Point3F &vec = object->getMouseCam3DVec();
dSprintf(retBufferPos, 256, "'%g %g %g'", pos.x, pos.y, pos.z);
dSprintf(retBufferVec, 256, "'%g %g %g'", vec.x, vec.y, vec.z);
Con::printf("Doing select object...");
//Con::evaluatef("commandToServer('SelectObject', %s, %s);", retBufferVec, retBufferPos);
//Con::evaluatef("commandToServer('SelectObject', \"%s\", \"%s\");", retBufferVec, retBufferPos);
//Con::executef(4, "'commandToServer'", "'SelectObject'", retBufferVec, retBufferPos);
//Con::executef(4, "commandToServer", "'SelectObject'", retBufferVec, retBufferPos);
//Con::executef(4, GameAddTaggedString("commandToServer"), "'SelectObject'", retBufferVec, retBufferPos);
//Con::evaluatef("echo(\"EvaluateF Works!!! But not when using commandToServer\");", retBufferVec, retBufferPos);
}Notice the following:
- I already made the string to be enclosed in single quotes. I also tested double quotes.
- The first use of evaluatef doesn't actually do the commandToServer call although in the console, all I see is this:
Doing select object... Mapping string: SelectObject to index: 3My SelectObject is not run by the call.
- The second use of evaluatef obviously generate a parse error, but I removed the quotes in the dSprintfs to make it right, still it only produces the same output as the first evaluatef
- The third one is using executef like most of you suggested. Using that, I only get the message:
'commandToServer' : Unknown command.
- The fourth one:
Remote command error : Command must be tagged.
- Fifth: Crashes
- Last one, just out of curiosity, I want to know if evaluatef does its thing. As expected, it does correctly:
EvaluateF Works!!! But not when using commandToServer
Sigh, can't still find what's wrong.
#10
10/20/2006 (1:36 am)
.
#11
Whaaaat? :D I really can not get my head around this. I just did the same here, and it works perfectly. Actually, alot of the above works. I took the code I posted from my own code and Hplus's looks fine too, so you are definatly missing something.
Are you sure the following works?
I would try this:
I doubt it will solve the problem, but if you want it to look cleaner then you should because quotation marks are not needed. (Those are not seperated arguments, you are still within the evauatef string, remember!)
10/20/2006 (2:13 am)
He's now using sprintF so there should not be a problem.Quote:
'commandToServer' : Unknown command.
Whaaaat? :D I really can not get my head around this. I just did the same here, and it works perfectly. Actually, alot of the above works. I took the code I posted from my own code and Hplus's looks fine too, so you are definatly missing something.
Are you sure the following works?
Con::evaluatef("commandToServer('SelectObject', \"%s\", \"%s\");", retBufferVec, retBufferPos);I would try this:
Con::evaluatef("commandToServer('SelectObject', %s, %s);", retBufferVec, retBufferPos);I doubt it will solve the problem, but if you want it to look cleaner then you should because quotation marks are not needed. (Those are not seperated arguments, you are still within the evauatef string, remember!)
#12
10/20/2006 (9:49 am)
.
#13
10/20/2006 (9:57 am)
.
#14
I can confirm that C++ or Non-C++ serverCmdSelectObject definition works by changing it's implementation to a simple echo. It's actually the original implementation that doesn't work, not the call to SelectObject via commandToServer. Which, basically solves my problem here now but leads to another. I'll just be making a new thread.
Oh, and Thank you everyone for helping and clarifying things out.
If you want to help me on my new problem, follow this link.
10/20/2006 (9:50 pm)
Ok, my bad. The first one actually works.ConsoleMethod( ArcadeTSCtrl, onMouseDown, void, 2, 2, "()" ){
char* retBufferPos = Con::getReturnBuffer(256);
char* retBufferVec = Con::getReturnBuffer(256);
const Point3F &pos = object->getMouseCam3DPos();
const Point3F &vec = object->getMouseCam3DVec();
dSprintf(retBufferPos, 256, "\"%g %g %g\"", pos.x, pos.y, pos.z);
dSprintf(retBufferVec, 256, "\"%g %g %g\"", vec.x, vec.y, vec.z);
Con::printf("Doing select object...");
Con::evaluatef("commandToServer('SelectObject', %s, %s);", retBufferVec, retBufferPos);
}I can confirm that C++ or Non-C++ serverCmdSelectObject definition works by changing it's implementation to a simple echo. It's actually the original implementation that doesn't work, not the call to SelectObject via commandToServer. Which, basically solves my problem here now but leads to another. I'll just be making a new thread.
Oh, and Thank you everyone for helping and clarifying things out.
If you want to help me on my new problem, follow this link.
Torque Owner Stefan Lundmark
Perhaps something like this? It will look messy because of the console callbacks, but I am sure you get the basic idea.
// For simplicity. Point3F pos = object->mMouseCam3DPos; Point3F vec = object->mMouseCam3DVec; // Get those values. char * posX = Con::getFloatArg ( pos.x ); char * posY = Con::getFloatArg ( pos.y ); char * posZ = Con::getFloatArg ( pos.z ); char * vecX = Con::getFloatArg ( vec.x ); char * vecY = Con::getFloatArg ( vec.y ); char * vecZ = Con::getFloatArg ( vec.z ); // Go, go! Con::executef ( 8, "commandToServer", "SelectObject", vecX, vecY, vecZ, posX, posY, posZ );Edit: Or if you want it short (and ugly, hehe!):
Edit: Just realized you are passing Vec first and Pos second. Corrected.