Getting into a Session

We have two buttons on our form for either hosting or connecting to an existing session. Once we try to do either of these actions, we will need to disable these buttons so that we can't try to do more than one action at a time. The event handlers for these two buttons would be

 private void button1_Click(object sender, System.EventArgs e) {     button1.Enabled = false;     button2.Enabled = false;     InitializeDirectPlay(true); } private void button2_Click(object sender, System.EventArgs e) {     button1.Enabled = false;     button2.Enabled = false;     InitializeDirectPlay(false); } 

As you see, they are both remarkably similar. The only difference between the two is the parameter they pass in to the InitializeDirectPlay method; one uses true to host, the other uses false to connect. We could simplify this by having each button use the same event handler:

 private void button_Click(object sender, System.EventArgs e) {     button1.Enabled = false;     button2.Enabled = false;     InitializeDirectPlay((sender == button1)); } 

Much nicer; this eliminates the duplicated code and achieves the exact same behavior. If the sender of the event happens to be the first button (our hosting button), it will call InitializeDirectPlay with true; otherwise, it will call it with false. Hook each button's event in this way. We never actually did anything with the parameter for this method, though. We should look at that now.

Before we can either host a session or connect to an existing one, we will need a way to "recognize" a session. DirectPlay includes an application description structure that will contain all of the information we need to describe an application. Let's look at the code we'll use for our application description; add this to the end of the InitializeDirectPlay method:

 // Set up an application description ApplicationDescription desc = new ApplicationDescription(); desc.SessionName = "MDXBookPeerSession"; desc.GuidApplication = new Guid(41039, 1702,1503,178, 101,     32, 13, 121, 230, 109, 59); 

The most important member of this structure is the GuidApplication member. This GUID uniquely identifies your application, and all instances of your application must use the same GUID for this member. The other member we set is the session name. This is useful for when there are many sessions available to help identify yours. You will find all of the members of the ApplicationDescription structure in Table 18.2.

Table 18.2. ApplicationDescription Members

MEMBER

DESCRIPTION

GuidApplication

Uniquely identify your application.

GuidInstance

A unique identifier for your session, generated by DirectPlay. This is to identify separate instances of your application running simultaneously.

MaxPlayers

The maximum number of users allowed in a given session. Setting this value to zero (the default) will allow an unlimited number of players.

CurrentPlayers

The number of users currently in the session.

Flags

Used to define the session behavior, may be one or more of the following flags:

  • ClientServer

  • FastSigned

  • FullSigned

  • MigrateHost

  • NoDpnServer

  • NoEnumerations

  • RequirePassword

SessionName

User-defined name of the session.

Password

The password needed to join the session. This value must be null unless the RequirePassword flag is set.

With the application description created now, we are ready to get into a session. Since we need to have a session exist before we can connect to it, we will deal with the hosting code first. Add the following to the end of the initialize method:

 if (host) {     try     {         // Host a new session         connection.Host(desc, deviceAddress);         // We can assume after the host call succeeds we are hosting         AddText("Currently Hosting a session.");         EnableSendDataButton(true);     }     catch     {         AddText("Hosting this session has failed.");     } } 

As you can see, the Host call is relatively straightforward. We've used the simplest overload for our call that takes only the application description and our local address. There are, however, eight separate overloads for the Host method. Each of these overloads take in the application description, and either one or more address objects, as these are the only required parameters. You may also pass in an object to be used as a player context variable (we'll describe these shortly). You may also pass a member of the HostFlags enumeration. There is currently only one member of this enumeration, which allows DirectPlay to open a windows dialog to query for any missing addressing information.

PASSWORDS ARE NOT ENCRYPTED

Be careful when using passwords with these sessions. Whatever data you pass in to this member will be sent across the network in plain text, with no encryption. If you want to safeguard your passwords, you will need to encrypt them manually before sending them out.

We wrap our Host call into a try/catch block to allow for the case when the method fails for some reason. We could catch only exceptions derived from the DirectPlayExcetion class, but for this simple example, we'll simply catch them all. There are two methods we haven't seen before that will simply update the UI. We'll look at these now:

 private void AddText(string text) {     label1.Text += (text + "\r\n"); } private void EnableSendDataButton(bool enable) {     button3.Enabled = enable; } 

No need to go into these methods as they are quite self-explanatory. Running this application now and hitting the host button will start a DirectPlay peer-to-peer session, display a status message to this affect, and enable the send data button. With all that done, all we need now is another peer to connect to our session. Add the following clause to the end of the initialize method:

 else {     try     {         connection.FindHosts(desc, null, deviceAddress, null,             0, 0, 0, FindHostsFlags.OkToQueryForAddressing);         AddText("Looking for sessions.");     }     catch     {         AddText("Enumeration of sessions has failed.");     } } 

Once again, we wrap our method in a try/catch block to be notified of any errors, as well as update our UI based on what we are doing. However, we aren't calling the Connect method; we are calling the FindHosts method. In some cases, it is possible to directly connect to an existing session; however, in most cases you will need to search for any existing hosts first.

Much like the Host method, the FindHosts method takes in the application description, as well as the local device address. The second parameter is the host's address, which we don't happen to know right now, so we can just use null for this parameter. The fourth parameter for this method is any application-defined data you want to pass in to the server. The server can use this information in anyway it wants.

The next three parameters control the behavior of how the hosts are enumerated. They control the number of times to send out the enumeration packets, how often it should wait before retrying another enumeration, and finally the time out value of the enumerations. By specifying zero for each of these parameters, the default values for the service provider will be used. The last parameter can be one or more members of the FindHostsFlags enumeration. The possible values of this enumeration are listed in Table 18.3.

Table 18.3. Possible FindHostFlags Values

VALUE

DESCRIPTION

None

Using this flag will implement the default behavior.

NoBroadcastFallback

If you use this flag, the service provider that supports broadcasting these capabilities will be disabled. You can use the GetSpCaps method on the Peer object to determine if your service provider supports broadcasting.

OkToQueryForAddressing

Specifying this flag will allow DirectPlay to display a windows dialog to provide any addressing information not already provided in the method call.

Sync

The default behavior for this method is to return immediately (asynchronous operation). Using this flag will change this behavior, and the method will not return until the enumeration has completed.

If you try running the application now, you'll notice that clicking the connect button causes a dialog will show up asking for the remote machine's address. You can leave this blank to search the entire subnet of the network you are on. You can also specify the name or IP address of the machine you want to connect to. You'll notice that the FindHosts method returns no parameters, and currently there is no way to actually find out what hosts we've found.



Managed DirectX 9 Graphics and Game Programming, Kick Start
Managed DirectX 9 Kick Start: Graphics and Game Programming
ISBN: B003D7JUW6
EAN: N/A
Year: 2002
Pages: 180
Authors: Tom Miller

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