| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- /*
- * Copyright (c) 2014, Oculus VR, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
- #include "MasterClient.h"
- #include "RakPeerInterface.h"
- #include "PacketEnumerations.h"
- #include "RakNetworkFactory.h"
- #include "StringCompressor.h"
- #include "GetTime.h"
- #include <cstring>
- // Uncomment this define for debugging printfs
- #define _SHOW_MASTER_SERVER_PRINTF
- #ifdef _SHOW_MASTER_SERVER_PRINTF
- #include <cstdio>
- #endif
- MasterClient::MasterClient()
- {
- }
- MasterClient::~MasterClient()
- {
- ClearServerList();
- }
- bool MasterClient::Connect(char* host, int masterServerPort)
- {
- localServer.Clear();
- listServer=serverListed=localServerModified=false;
- localServer.connectionIdentifier.port=rakPeer->GetInternalID().port;
- ruleIdentifierList.Reset();
- return rakPeer->Connect(host, masterServerPort, 0, 0);
- }
- void MasterClient::Disconnect(void)
- {
- if (IsConnected())
- DelistServer();
- rakPeer->Disconnect(100);
- }
- bool MasterClient::IsConnected(void)
- {
- unsigned short numberOfSystems;
- rakPeer->GetConnectionList(0, &numberOfSystems);
- return numberOfSystems==1;
- }
- void MasterClient::AddQueryRule(char *ruleIdentifier)
- {
- if (ruleIdentifier && IsReservedRuleIdentifier(ruleIdentifier)==false)
- stringCompressor->EncodeString(ruleIdentifier, 256, &ruleIdentifierList);
- }
- void MasterClient::ClearQueryRules(void)
- {
- ruleIdentifierList.Reset();
- }
- void MasterClient::QueryMasterServer(void)
- {
- BitStream outgoingBitStream;
- // Request to the master server for the list of servers that contain at least one of the specified keys
- outgoingBitStream.Write((unsigned char)ID_QUERY_MASTER_SERVER);
- if (ruleIdentifierList.GetNumberOfBitsUsed()>0)
- outgoingBitStream.WriteBits(ruleIdentifierList.GetData(), ruleIdentifierList.GetNumberOfBitsUsed(), false);
- rakPeer->Send(&outgoingBitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_PLAYER_ID, true);
- }
- void MasterClient::PingServers(void)
- {
- unsigned serverIndex;
- for (serverIndex=0; serverIndex < gameServerList.serverList.Size(); serverIndex++)
- {
- rakPeer->Ping((char*)rakPeer->PlayerIDToDottedIP(gameServerList.serverList[serverIndex]->connectionIdentifier),
- gameServerList.serverList[serverIndex]->connectionIdentifier.port, false);
- }
- }
- void MasterClient::Update(RakPeerInterface *peer)
- {
- BitStream outgoingBitStream;
- if (listServer && ((serverListed && localServerModified) || (serverListed==false)))
- {
- outgoingBitStream.Write((unsigned char)ID_MASTER_SERVER_SET_SERVER);
- SerializeServer(&localServer, &outgoingBitStream);
- rakPeer->Send(&outgoingBitStream, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_PLAYER_ID, true);
- serverListed=true;
- localServerModified=false;
- }
- }
- bool MasterClient::OnReceive(RakPeerInterface *peer, Packet *packet)
- {
- switch(packet->data[0])
- {
- case ID_NO_FREE_INCOMING_CONNECTIONS:
- OnMasterServerFull();
- return false; // Do not absorb packet
- case ID_DISCONNECTION_NOTIFICATION:
- OnLostConnection();
- return false; // Do not absorb packet
- case ID_CONNECTION_LOST:
- OnLostConnection();
- return false; // Do not absorb packet
- case ID_MODIFIED_PACKET:
- OnModifiedPacket();
- return false;
- case ID_CONNECTION_ATTEMPT_FAILED:
- OnConnectionAttemptFailed();
- return false; // Do not absorb packet
- case ID_MASTER_SERVER_UPDATE_SERVER:
- HandleServerListResponse(packet, false);
- return true; // Absorb packet
- case ID_MASTER_SERVER_SET_SERVER:
- HandleServerListResponse(packet, true);
- return true; // Absorb packet
- case ID_PONG:
- HandlePong(packet);
- return false; // Absorb packet
- case ID_RELAYED_CONNECTION_NOTIFICATION:
- HandleRelayedConnectionNotification(packet);
- return true; // Absorb packet
- }
- return 0;
- }
- void MasterClient::ConnectionAttemptNotification(char *serverIP, unsigned short serverPort)
- {
- if (serverIP==0)
- return;
- BitStream bitStream(23);
- bitStream.Write((unsigned char)ID_RELAYED_CONNECTION_NOTIFICATION);
- bitStream.Write(localServer.connectionIdentifier.port); // Your own game client port
- bitStream.Write(serverPort); // The game server you are connecting to port
- stringCompressor->EncodeString(serverIP, 22, &bitStream); // The game server IP you are connecting to
- rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_PLAYER_ID, true);
- }
- void MasterClient::ListServer(void)
- {
- listServer=true;
- }
- void MasterClient::DelistServer(void)
- {
- BitStream bitStream;
- listServer=false;
- if (serverListed)
- {
- bitStream.Write((unsigned char)ID_MASTER_SERVER_DELIST_SERVER);
- bitStream.Write(localServer.connectionIdentifier.port);
- rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_PLAYER_ID, true);
- serverListed=false;
- }
- }
- void MasterClient::HandleServerListResponse(Packet *packet, bool overwriteExisting)
- {
- int serverIndex;
- bool newServerAdded;
- unsigned short numberOfServers;
- GameServer *gameServer;
- RakNetTime currentTime;
- BitStream inputBitStream(packet->data, packet->length, false);
- inputBitStream.IgnoreBits(8*sizeof(unsigned char));
-
- if (inputBitStream.ReadCompressed(numberOfServers)==false)
- return;
- currentTime=RakNet::GetTime();
- for (serverIndex=0; serverIndex < numberOfServers; serverIndex++)
- {
- gameServer = DeserializeServer(&inputBitStream);
- // Find the existing game server that matches this port/address.
- // If not found, then add it to the list.
- // else update it
- // If (overwriteExisting)
- // - Delete any fields that exist in the old and not in the new
- // Add any fields that exist in the new and do not exist in the old
- // Update any fields that exist in both
- // Unset the deletion mark
- gameServer=UpdateServerList(gameServer,overwriteExisting, &newServerAdded);
- if (newServerAdded)
- {
- // Ping the new server
- rakPeer->Ping((char*)rakPeer->PlayerIDToDottedIP(gameServer->connectionIdentifier),
- gameServer->connectionIdentifier.port, false);
- // Returns true if new server updated
- OnGameServerListAddition(gameServer);
- }
- else
- {
- // returns false if an existing server is modified
- OnGameServerListRuleUpdate(gameServer);
- }
- }
- // Any servers that were not updated on the last call to UpdateServerList
- // will have lastUpdateTime time as less than the current time
- // Delete those
- serverIndex=0;
- while (serverIndex < (int) gameServerList.serverList.Size())
- {
- if (gameServerList.serverList[serverIndex]->lastUpdateTime < currentTime)
- {
- delete gameServerList.serverList[serverIndex];
- gameServerList.serverList.RemoveAtIndex(serverIndex);
- }
- else
- serverIndex++;
- }
- OnGameServerListQueryComplete();
- }
- void MasterClient::HandleRelayedConnectionNotification(Packet *packet)
- {
- PlayerID clientSystem;
- BitStream incomingBitStream(packet->data, packet->length, false);
- incomingBitStream.IgnoreBits(8*sizeof(unsigned char));
- incomingBitStream.Read(clientSystem.binaryAddress);
- incomingBitStream.Read(clientSystem.port);
-
- OnConnectionRequest(rakPeer->PlayerIDToDottedIP(clientSystem), clientSystem.port);
- }
- void MasterClient::PostRule(char *ruleIdentifier, char *stringData, int intData)
- {
- if (ruleIdentifier)
- {
- if (IsReservedRuleIdentifier(ruleIdentifier))
- return;
- localServerModified |= UpdateServerRule(&localServer, ruleIdentifier, stringData, intData);
- }
- }
- void MasterClient::RemoveRule(char *ruleIdentifier)
- {
- if (ruleIdentifier)
- localServerModified |= RemoveServerRule(&localServer, ruleIdentifier);
- }
- void MasterClient::OnLostConnection(void)
- {
- #ifdef _SHOW_MASTER_SERVER_PRINTF
- printf("Connection lost.\n");
- #endif
- }
- void MasterClient::OnConnectionAttemptFailed(void)
- {
- #ifdef _SHOW_MASTER_SERVER_PRINTF
- printf("Connection attempt failed.\n");
- #endif
- }
- void MasterClient::OnMasterServerFull(void)
- {
- #ifdef _SHOW_MASTER_SERVER_PRINTF
- printf("Server full.\n");
- #endif
- }
- void MasterClient::OnModifiedPacket(void)
- {
- #ifdef _SHOW_MASTER_SERVER_PRINTF
- printf("Modified packet.\n");
- #endif
- }
- void MasterClient::OnGameServerListAddition(GameServer *newServer)
- {
- #ifdef _SHOW_MASTER_SERVER_PRINTF
- printf("Server added.\n");
- #endif
- }
- void MasterClient::OnGameServerListRuleUpdate(GameServer *updatedServer)
- {
- #ifdef _SHOW_MASTER_SERVER_PRINTF
- printf("Rules updated for a server.\n");
- #endif
- }
- void MasterClient::OnGameServerListQueryComplete(void)
- {
- #ifdef _SHOW_MASTER_SERVER_PRINTF
- printf("Query complete.\n");
- #endif
- }
- // Event when a game client wants to connect to our server
- // You should call AdvertiseSystem to the passed IP and port from your game instance
- void MasterClient::OnConnectionRequest(const char *clientIP, unsigned short clientPort)
- {
- #ifdef _SHOW_MASTER_SERVER_PRINTF
- printf("Master client indicates a connection request from %s:%i.\n", clientIP, clientPort);
- #endif
- rakPeer->AdvertiseSystem((char*)clientIP, clientPort,0,0);
- }
|