home *** CD-ROM | disk | FTP | other *** search
- Attribute VB_Name = "NetClient"
- '
- ' Xceed Winsock Library Sample: Tron Sample
- ' Copyright (c) 2000 Xceed Software Inc.
- '
- ' [Code module for client event handling]
- '
- ' This sample application for the Xceed Winsock Library demonstrates
- ' service advertising and service lookup using the SAP protocol, as
- ' well as connectionless asynchronous byte transfers using the IPX
- ' protocol. All transfer events are handled via the "Implements"
- ' statement. To successfully create a game, you must have the SAP
- ' protocol installed on your system. Otherwise, you can only list
- ' and join games.
- '
- ' This file is part of the Xceed Winsock Library Samples.
- ' The source code in this file is only intended as a supplement
- ' to Xceed Winsock Library's documentation, and is provided "as is",
- ' without warranty of any kind, either expressed or implied.
- '
-
- Option Explicit
-
- ' Variables for communicating to server and receiving events
-
- Dim GameServerAddress As Address ' The address of the game server we are joined to
- Dim ClientSocket As ConnectionlessSocket ' Our socket for communicating to the game server
- Dim ClientEvents As ClientTransferEvents ' Our event handlers for byte transfer notifications
- Dim ClientEventsCookie As Long ' A cookie assigned to our implemented evetn handler interface
-
- ' A random number tag string identifying ourselves to the server
-
- Public PlayerTag As String
-
- ' Call this procedure to setup a client socket in order to be able to join a game
- '
- Public Function SetUpClientSocket() As Boolean
-
- Dim xProtocols As New Protocols
- Dim xProtocol As Protocol
-
- On Error GoTo ClientSocketSetupError
-
- ' Get the protocol we want to use (in this case, IPX)
-
- Set xProtocol = xProtocols.GetProtocol(wafIpx, wstUnspecified, wptNS_IPX)
-
- ' Create the client socket
-
- Dim SF As New SocketFactory
-
- Set ClientSocket = SF.CreateConnectionlessSocket(xProtocol, 0)
-
- ' Instantiate our implementation of the IaXWAddressedByteTransferEvents interface
- ' which contains event handlers for handling data the client socket receives.
-
- Set ClientEvents = New ClientTransferEvents
-
- ' Inform the Xceed Winsock Library that we have implemented an interface which
- ' can receive notifications (events) related to byte transfers. More specifically,
- ' we use the wtaAdviseReceivedAlways flag to specify we are only interested in
- ' receiving events concerning incoming data, and no other events. The "cookie"
- ' is a value kept for later, in order to tell the library we no longer need
- ' notifications.
-
- ClientEventsCookie = ClientSocket.AddressedByteTransferAdvise(ClientEvents, wtaAdviseReceivedAlways)
-
- SetUpClientSocket = True
-
- Exit Function
-
- ClientSocketSetupError:
-
- Call GameForm.PrintInfo("Error seting up the client socket: " & Err.Description, True, vbRed)
-
- SetUpClientSocket = False
-
- Exit Function
-
- End Function
-
- ' Shuts down the client socket because a game has been unjoined.
- '
- Public Sub ShutdownClientSocket()
-
- On Error GoTo ClientSocketShutdownError
-
- ' Tell the Xceed Winsock Library we no longer need to be advised of incoming data
-
- ClientSocket.AddressedByteTransferUnadvise (ClientEventsCookie)
-
- ' Free the instantiated objects we no longer need
-
- Set ClientEvents = Nothing
- Set ClientSocket = Nothing
-
- Exit Sub
-
- ClientSocketShutdownError:
-
- MsgBox "Error closing the client socket: '" & Err.Description & "'", vbExclamation, "Tron Sample"
-
- Exit Sub
-
- End Sub
-
- ' Call this procedure to request a connection with a game server.
- ' The GameNumber parameter specifies which of the listed game
- ' servers (kept in the GameAddresses array) to join.
- '
- Public Sub ConnectToGameServer(GameNumber As Integer)
-
- Set GameServerAddress = GameAddresses(GameNumber) ' Get the game server's address
-
- ' Request to join the game, providing our player name while we're at it.
-
- Call SendClientSignal(sRequestJoinGame, "<player name=" & Chr$(34) & GameForm.GetLocalName() & Chr$(34) & "></player>", False)
-
- End Sub
-
- ' Send a client signal to the joined game server
- '
- Public Sub SendClientSignal(GS As Signals, Data As String, WaitForDataSent As Boolean)
-
- Dim baData() As Byte
-
- On Error GoTo SendClientSignalError
-
- ' We convert the string data into a byte array so we can send it out
- ' to the server using one of Xceed Winsock Library's Byte Transfer methods.
-
- baData = StrConv("<Tron tag=" & PlayerTag & " signal=" & CStr(GS) & ">" & Data & "</Tron>", vbFromUnicode)
-
- If WaitForDataSent = False Then
-
- ' Send data out asynchronously. We don't care when it happens, so
- ' we haven't set up any AdviseByteTransferEvents for outgoing data.
-
- Call ClientSocket.AsyncSendBytesTo(GameServerAddress, baData, 0, wsoNone)
-
- Else
-
- ' Send data with a blocking call, so when the following SendBytesTo
- ' method call completes, we know the data has actually been sent on
- ' its way by the library. We use this only in the case where the
- ' client is quitting the game and wants to make sure the sUnjoining
- ' client signal is sent to the server before the client socket is
- ' closed. If we sent it asynchronously, we could not be sure the data
- ' was sent before our socket is closed and all outgoing data is erased.
-
- Call ClientSocket.SendBytesTo(GameServerAddress, baData, wsoNone)
-
- End If
-
- Exit Sub
-
- SendClientSignalError:
-
- Call GameForm.PrintInfo("Error sending signal to server: " & Err.Description, True, vbRed)
-
- Exit Sub
-
- End Sub
-
-
- ' List available game servers using the SAP protocol
- '
- Public Sub ListGames()
-
- Dim SM As New ServiceManager
- Dim SPS As ServiceProviders
- Dim SP As ServiceProvider
-
- On Error GoTo ListGamesError
-
- ' Update the game interface to indicate search has started
-
- Call GameForm.PrintInfo("Searching for games...", False, vbBlack)
-
- Call GameForm.SetState(isStartBusy)
-
- ' Disable any submenus in the "Join game" menu.
-
- If JoinGameSubmenuMaxIndex > 0 Then
- Dim I As Integer
- For I = 1 To JoinGameSubmenuMaxIndex ' First menu item can't be made invisible
- GameForm.mnuGamesList(I).Visible = False
- Next I
- End If
-
- DoEvents
-
- ' Start searching for advertised service providers that have
- ' the appropriate service provider GUID
-
- Set SPS = SM.EnumServiceProviders("*", GameGuid, 1, False, wnsSAP, "", "", Empty, "", Empty, wesUseRemoteAddress)
-
- GamesFound = 0
-
- For Each SP In SPS
- GamesFound = GamesFound + 1
-
- ' Add the game name to the GameNames array
-
- ReDim Preserve GameNames(GamesFound) As String
- GameNames(GamesFound) = SP.Name
-
- ' Add the game address to the GameAddresses array
-
- ReDim Preserve GameAddresses(GamesFound) As Address
- Set GameAddresses(GamesFound) = SP.ServiceAddresses(0).RemoteAddress
-
- ' Add the game name as an option in the "Join game" submenus.
-
- If GamesFound > (JoinGameSubmenuMaxIndex + 1) Then
- Load GameForm.mnuGamesList(GamesFound - 1)
- JoinGameSubmenuMaxIndex = GamesFound - 1
- End If
-
- GameForm.mnuGamesList(GamesFound - 1).Caption = GameNames(GamesFound)
- If GamesFound > 1 Then GameForm.mnuGamesList(GamesFound - 1).Visible = True
- GameForm.mnuGamesList(GamesFound - 1).Enabled = True
-
- ' Display the game which was found.
-
- Call GameForm.PrintInfo("Found " & SP.Name & " (Game " & CStr(GamesFound) & ")", True, vbBlack)
-
- DoEvents ' Update screen
-
- Next SP
-
- If GamesFound = 0 Then
- Call GameForm.PrintInfo("No games found.", False, vbBlack)
- End If
-
- Call GameForm.SetState(isStopBusy)
-
- Exit Sub
-
- ListGamesError:
-
- Call GameForm.PrintInfo("Error listing games: " & Err.Description, True, vbRed)
-
- Exit Sub
-
- End Sub
-