Direct Messaging


The quickest way to get down and dirty with the client/server networking in Torque is to use the CommandToServer and CommandToClient direct messaging functions. These extremely useful "ad hoc" messaging functions are used for a wide variety of purposes in a Torque game, like in-game chat, system messages, and client/server synchronization.

CommandToServer

The CommandToServer function is used to send a message from a client to a server. Of course, the server needs to know that the message is coming and how to parse it to extract the data. The syntax is as follows:

CommandToServer(function [,arg1,argn])

Parameters:

function

Message handler function on the server to be executed.

arg1,argn

Arguments for the function.

Return:

nothing

An example of how to use the function would be a simple global chat macro capability where a player would press a key, and then a specific message would be broadcast to all other players. Here is how that would work:

First, we would bind a key combination to a specific function, say Ctrl+H bound to the function we'll call SendMacro(). In the key binding statement, we'll make sure to pass the value 1 as a parameter to SendMacro().

SendMacro() could be defined on the client as this:

 function SendMacro(%value) {   switch$ (%value)   {     case 1:         %msg = "Hello World!";     case 2:         %msg = "Hello? Is this thing on?";     default:         %msg = "Nevermind!";   }   CommandToServer('TellEveryone', %msg); } 

So now, when the player presses Ctrl+H, the SendMacro() function is called, with its %value parameter set to 1. In SendMacro(), the %value parameter is examined by the switch$ statement and sent to case 1:, where the variable %msg is stuffed with the string "Hello World!". Then CommandToServer is called with the first parameter set to the tagged string "TellEveryone" and the second parameter set to our message.

Now here is where some of the Torque client/server magic elbows its way onto the stage. The client will already have a GameConnection to the server and so will already know where to send the message. In order to act on our message, the server side needs us to define the TellEveryone message handler, which is really just a special purpose function, something like this:

 function ServerCmdTellEveryone(%client,%msg) {     TellAll(%client,%msg); } 

Notice the prefix ServerCmd. When the server receives a message from the client via the CommandToServer() function, it will look in its message handle list, which is a list of functions that have the ServerCmd prefix, and find the one that matches ServerCmdTellEveryone. It then calls that function, setting the first parameter to the GameConnection handle of the client that sent the message. It then sets the rest of the parameters to be the parameters passed in the message from the client, which in this case is %msg stuffed with the string "Hello World!".

Then we can do what we want with the incoming message. In this case we want to send the message to all of the other clients that are connected to the server, and we'll do that by calling the TellAll() function. Now we could put the code right here in our ServerCmdTellEveryone message handler, but it is a better design approach to break the code out into its own independent function. We'll cover how to do this in the next section.

CommandToClient

Okay, here we are—we're the server, and we've received a message from a client. We've figured out that the message is the TellEveryone message, we know which client sent it, and we have a string that came along with the message. What we need to do now is define the TellAll() function, so here is what it could look like:

 function TellAll( %sender, %msg) {    %count = ClientGroup.getCount();    for ( %i = 0; %i < %count; %i++ )    {      %client = ClientGroup.getObject(%i);      commandToClient(%client,'TellMessage', %sender, %msg);     } } 

Our intention here is to forward the message to all of the clients. Whenever a client connects to the server, its GameConnection handle is added to the ClientGroup's internal list. We can use the ClientGroup's method getCount to tell us how many clients are connected. ClientGroup also has other useful methods, and one of them—the getObject method—will give us the GameConnection handle of a client, if we tell it the index number we are interested in.

If you want to test these example functions, I'll show you how to do that toward the end of the chapter. If you feel like giving it a go by yourself, I'll give you a small hint: The CommandToClient function is called from the server side, and the CommandToServer functions belong on the client side.

As you can see, CommandToClient is basically the server-side analogue to CommandToServer. The syntax is as follows:

CommandToClient(client, function [,arg1,argn])

Parameters:

client

Handle of target client.

function

Message handler function on the server to be executed.

arg1,argn

Arguments for the function.

Return:

nothing

The primary difference is that although the client already knew how to contact the server when using CommandToServer, the same is not true for the server when using CommandToClient. It needs to know which client to send the message to each time it sends the message. So the simple approach is to iterate through the ClientGroup using the for loop, getting the handle for each client, and then sending each client a message using the CommandToClient() function, by specifying the client handle as the first parameter. The second parameter is the name of the message handler on the client side this time. Yup—works the same going that way as it did coming this way! Of course, the third parameter is the actual message to be passed.

So we need that message handler to be defined back over on the client. You can do it like this:

 function clientCmdTellMessage(%sender, %msgString) {  // blah blah blah } 

Notice that when we called this function there were four parameters, but our definition only has two in the parameter list. Well, the first parameter was the client handle, and because we are on the client, Torque strips that out for us. The second parameter was the message handler identifier, which was stripped out after Torque located the handler function and sent the program execution here. So the next parameter is the sender, which is the client that started this whole snowball rolling, way back when. The last parameter is, finally, the actual message.

I'll leave it up to you to decide what to do with the message. The point here was to show this powerful messaging system in operation.You can use it for almost anything you want.

Direct Messaging Wrap-up

CommandToServer and CommandToClient are two sides of the same direct messaging coin and give us, as game programmers, a tremendous ability to send messages back and forth between the game client and the game server.

Direct messaging can also be an important tool in the fight against online cheating in your game. You can, in theory and in practice, require all user inputs to go to the server for approval before executing any code on the client. Even things like changing setup options on the client—which are not normally the sort of thing that servers would control—can be easily programmed to require server control using the technique we just looked at.

The actual amount of server-side control you employ will be dictated by both available bandwidth and server-side processing power. There is a lot that can be done, but it is a never-ending series of tradeoffs to find the right balance.




3D Game Programming All in One
3D Game Programming All in One (Course Technology PTR Game Development Series)
ISBN: 159200136X
EAN: 2147483647
Year: 2006
Pages: 197

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net