Click here to Skip to main content
15,880,608 members
Articles / Programming Languages / C#

Skype Game Infra

Rate me:
Please Sign up or sign in to vote.
4.78/5 (19 votes)
1 Nov 20067 min read 113.6K   4.4K   87   18
Using Skype as infrastructure for multiplayer games

Sample Image

Introduction

If you have written a nice multiplayer game, which can be played only by users on the same computer (as you never had time to even start thinking on making it online) – this article is for you. It presents a simple approach for all those “networking” tasks, and comes with a simple library implementing it. So make your game online in five minutes (well, probably two hours).

Contents

Making Online Games

For this discussion, I want to divide this task to two separate parts:

  1. Create desktop game, and
  2. Allow users to play online

The first part is interesting and difficult by itself, but is totally out of the scope of the current article. For example, for chess game, it includes UI and game engine that will allow two people to play chess on the same computer. For my demo application, I use great chess board control, created by Gregory Prentice. In addition to the nice UI, it has a fully functional chess engine which validates the moves, fires events both for UI changes (move) and game notifications (Mate!), and so on. You can read its description here, or download the most recent version from here.

Let’s look deeper into the second task – going online. Here, we should look separately at:

  1. connecting users, and
  2. supplying additional online services

Opening connection between two users:

  • server-less. Connect directly to other user’s IP? Ugly and won’t work in many cases, where the user does not have external IP address (you can’t play at work!). And this is just for finding the opponent IP, take into account the firewalls, and you will see that this solution is useless in many cases.
  • with dedicated server. Obvious advantages: all users connect to known gaming server, they can see who is online, etc. Building such server from scratch is very problematic and time-consuming task. Even if you are using some existing code (for example, I saw online games based on IRC protocol), you need to manage an online server with known IP address – not something each one wants to do.

Additional services include chat window, which is a must for a game, and optionally other communication channels – voice over IP, video, etc.

Well, currently this all seems very complicated.

Using Skype as Infrastructure

As you can already guess, this paragraph will explain how Skype can ease all those tasks.

Skype

I started using Skype a couple of years ago for VOIP – talking to my friends and family in different countries in great sound quality. Over time, they added chat and video functionality, including conference calls.

Similar to other programs of this type, you create Skype account, manage list of contacts, see when each of your friends is online, etc.

Skype API

In addition to those features, there’s a Skype Public API, which allows developing new application based on Skype capabilities. The API gives full access to all basic functionality: contacts, chats, voice calls, etc. The current solution is mostly based “Application Streams” – data channels which can be created between 3rd-party applications.

The next section describes Skype API in more detail. But the concept should already be clear – we will use those data streams to exchange game-specific info between players which will be all connected to Skype. This approach solves most of the difficulties in making online games:

  • All users are logged in to Skype servers and you don’t need to worry about the network layer but can use reliable connection to exchange data
  • You always know who is connected to Skype at any moment
  • Chat window, voice conversations and even video calls are available in Skype

Using Skype API

This section describes basic Skype API and a COM API, when special attention is given to topics related to “Application Streams”. The API is well documented, and can be found here. You can also use developers' forum to find answers on subjects that are not explained well in the documentation.

In the next section, you can find description of SkypeGameInfra library, which wraps all relevant functionality in a convenient way. You can even skip the current section for now, and go back to it only when you need to get more details, or make changes.

Skype API for Windows

Application exchanges data with Skype using WM_COPYDATA Windows messages. The format of the messages is called “Skype Protocol”, which defines set of commands that can be sent to Skype. The full description of commands can be found here.

Skype4COM

In addition to Skype API, which isn’t very friendly to use, there’s a COM wrapper which represents the Skype API as COM objects with properties and events. Again, the full description can be found here. I will describe the parts relevant for creating “Application Streams”.

  1. Skype is the top-level object. To create an instance:
    C#
    SKYPE4COMLib.Skype skype = new SKYPE4COMLib.Skype();

    This operation will pop-up a message in Skype, saying to the user that new application is attaching. The user should allow this operation (it’s recommended to use the “never ask again” option).

    Note: If, by mistake, you’ve disabled your application from using Skype, you can go to C:\Documents and Settings\WINDOWS USER NAME\Application Data\Skype\SKYPE USER NAME, and find your application in config.xml, UI/AccessControlList/ClientX node – just delete this whole node (make sure the numbering of Client nodes remains correct).

  2. In order to check whether you could connect to Skype, test AttachmentStatus property:
    C#
    SKYPE4COMLib.ISkype iskype = skype as SKYPE4COMLib.ISkype;
    if (iskype.AttachmentStatus == 
              SKYPE4COMLib.TAttachmentStatus.apiAttachNotAvailable) 
        { /* error */ }    
  3. Next, you have to register your application. Each “application” connected to Skype has a unique name, by which it can be identified.
    C#
    SKYPE4COMLib.Application app = 
              skype.get_Application(APPLICATION_NAME);
    if (app != null) {
          app.Create();
    }
  4. And we also need to register on two events: ApplicationStreams and ApplicationReceiving.
    C#
    skype.ApplicationStreams += new 
       SKYPE4COMLib._ISkypeEvents_ApplicationStreamsEventHandler(
       skype_ApplicationStreams);
    skype.ApplicationReceiving += new 
       SKYPE4COMLib._ISkypeEvents_ApplicationReceivingEventHandler(
       skype_ApplicationReceiving);
  5. When you are ready to open connection to another Skype user, just call:
    C#
    app.Connect(skypeHandle, false);
    // skypeHandle is just Skype username
    // of the user you want to connect to

    Note: The connection is received by application registered with the same APPLICATION_NAME as your application. If no such application was registered, no connection will be opened.

  6. When the connection is finally established, you will receive ApplicationStreams notification, and from now on, you can use the stream to send and receive messages.
    C#
    void skype_ApplicationStreams(SKYPE4COMLib.Application pApp, 
         SKYPE4COMLib.ApplicationStreamCollection pStreams)
    {
        SKYPE4COMLib.ApplicationStream stream = null;
        foreach (SKYPE4COMLib.ApplicationStream 
                 astream in pStreams)
            if (stream == null)
                stream = astream;
    }    
  7. To send a message, just call:
    C#
    stream.Write("My message");    
  8. And, finally, messages are received through ApplicationReceiving events:
    C#
    void skype_ApplicationReceiving(SKYPE4COMLib.Application pApp, 
         SKYPE4COMLib.ApplicationStreamCollection pStreams)
    {
        foreach (SKYPE4COMLib.ApplicationStream 
                 astream in pStreams) {
            string msg = astream.Read();
            // process message
        }
    }

    As an example, see the GameCommunications class in the SkypeGameInfra project.

Skype Contact List Control

In addition to those APIs, you can use one of two ActiveX controls to automatically get list of contacts defined in Skype: “SkypeContactList” and “SkypeContactCombo”. The use of those controls is pretty self-explanatory – just add one of them to your Form.

They can be downloaded from here - “Skype ActiveX Tools”.

SkypeGameInfra Wrapper

It’s .NET wrapper on top of Skype COM API which encapsulates all functionality needed for a game between 2 players.

DemoSkypeChess is an example project which uses this API.

  1. Creating new instance:
    C#
    SkypeGameInfra.GameCommunication skypeWrapper = 
          new SkypeGameInfra.GameCommunication("DemoChess");

    Note: Replace “DemoChess” with your unique name.

  2. Let’s say the user is connected as Alex in Skype. To invite other Skype users to a game, call:
    C#
    string username = skypeWrapper.SelectUser();
    if (username.Length > 0)
        skypeWrapper.InviteOpponent(username);

    SelectUser opens a dialog with list of all contacts, and the user should select one of them. InviteOpponent opens “Application Stream”, and sends an invitation to selected contact.

  3. At this point, your application on the remote computer (let’s say, Bob’s), which has also performed step 1 of creating GameCommunication object with the same name, will receive InvitationReceived event. In the application level you will, probably, want to show a nice dialog to the user, asking to accept or decline the game.
  4. Based on Bob’s action in step 3 AcceptGame of DeclineGame should be called, and Alex will receive OpponentAccepted or OpponentDeclined event. Starting from this point, the communication channel is established: Alex plays white, and Bob – black.
  5. Each player in his turn should make a move, resulting in the following call:
    C#
    skypeWrapper.Move(position);

    position parameter is arbitrary game-specific string, which will be received by the other side in OpponentMove event.

  6. Finally, the game ends when one of the parties is invoking StopGame function. This will release the “Application Steam” channel for both users, and bring the system back to the state it was after step 1.

Links

Chess control by Gregory Prentice:

Skype links:

License

This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below. A list of licenses authors might use can be found here.


Written By
Web Developer
Israel Israel
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionCan't able to run, Pin
Vinish Kumar26-Jul-13 0:22
Vinish Kumar26-Jul-13 0:22 
Generalgreat article! Pin
iamveritas26-Feb-12 13:09
iamveritas26-Feb-12 13:09 
GeneralGreat Idea Pin
SamNaseri1-Nov-11 14:24
SamNaseri1-Nov-11 14:24 
General[Message Deleted] Pin
it.ragester28-Mar-09 5:35
it.ragester28-Mar-09 5:35 
GeneralExcellent Sample [modified] Pin
Oleksiy Sokolovskiy17-Jul-08 16:50
Oleksiy Sokolovskiy17-Jul-08 16:50 
Generalabout skype API Pin
marcelaviles8-May-08 4:58
marcelaviles8-May-08 4:58 
GeneralRe: about skype API Pin
Michael Gopshtein8-May-08 6:07
Michael Gopshtein8-May-08 6:07 
QuestionStream Pin
freediver21113-Dec-07 16:29
freediver21113-Dec-07 16:29 
AnswerRe: Stream Pin
RobinBlood8-Jun-08 1:52
RobinBlood8-Jun-08 1:52 
If you have a 2nd PC (or VMWare) I would suggest to install C#-Express on both and register a 2nd Name on Skype.
In this case you can debug on both while initializing the communication.
Just make sure you leave the current Method on one PC before you look at the "ApplicationStream" of the 2nd.

For a quick hint:
'Alex' selects a User -> 'Bob'
while he's OPENING_CONNECTION app.Connect() is called.

'Bob' receives an ApplicationStream with the PartnerHandle: 'Alex'
and skype invokes an AppicationStream back to 'Alex'

'Alex' receives the mentioned stream with PartnerHandle 'Bob' and
compares with the invited Opponent -> MATCH !
Alex writes Game_Invite on the stream.

'Bob' ApplicationRECEIVING: "Game_Invite" and writes Invite_ACK back on the Stream

'Alex' ApplicationRECEIVING: "Invite_ACK" and sets status to 'Waiting for Bob to Accept'

'Bob' presses the YES Button on the MessageBox and Game_Accept is written on the Stream.
Status changes to "Waiting for Alex to Move" and the Board is flipped

'Alex' ApplicationRECEIVING: "Game_Accept" and calls OpponentAccepted()
Status changes to "Playing with Bob, your move"
-----------
Now the Game is played and who is in control calls wrapper.move and set Status to
"Waiting for Opponent to Move"

This invokes opponent.move on the 2nd PC and sets Status to "Playing with Opponent, your move"

The Complete Game is played over the Stream (calling ApplicationRECEIVING). From Time to time,
Skype updates the Stream calling ApplicationStreams but you don't recognize while playing.

Thanks for the Artikle and Best Regards
RobinB
GeneralThis is great! Pin
cairoso20-Aug-07 16:21
cairoso20-Aug-07 16:21 
GeneralCool indeed! Pin
Member 122908314-Aug-07 21:33
Member 122908314-Aug-07 21:33 
GeneralThanks Pin
himalayantravel19-Apr-07 8:20
himalayantravel19-Apr-07 8:20 
QuestionWhy? Pin
ALEXNG8811-Apr-07 22:45
ALEXNG8811-Apr-07 22:45 
AnswerRe: Why? Pin
Michael Gopshtein11-Apr-07 23:04
Michael Gopshtein11-Apr-07 23:04 
GeneralRe: Why? Pin
ALEXNG8818-Apr-07 23:19
ALEXNG8818-Apr-07 23:19 
GeneralRe: Why? Pin
Michael Gopshtein19-Apr-07 5:34
Michael Gopshtein19-Apr-07 5:34 
GeneralRe: Why? Pin
ALEXNG8819-Apr-07 7:14
ALEXNG8819-Apr-07 7:14 
GeneralCool! Pin
Steve Echols1-Nov-06 19:21
Steve Echols1-Nov-06 19:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.