ReplicatedLogin.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #include "RakPeerInterface.h"
  11. #include "BitStream.h"
  12. #include "GetTime.h"
  13. #include "RakSleep.h"
  14. #include "Gets.h"
  15. #include "MessageIdentifiers.h"
  16. #include "Kbhit.h"
  17. #include "ReplicaManager3.h"
  18. #include "RakPeerInterface.h"
  19. #include "NetworkIDManager.h"
  20. using namespace RakNet;
  21. // Purpose: UDP network communication
  22. // Required?: Yes
  23. RakPeerInterface *rakPeer;
  24. // Purpose: Game object replication
  25. // Required?: No, but manages object replication automatically. Some form of this is required for almost every game
  26. ReplicaManager3 *replicaManager3;
  27. // Purpose: Lookup game objects given ID. Used by ReplicaManager3
  28. // Required?: Required to use ReplicaManager3, and some form of this is required for almost every game
  29. NetworkIDManager *networkIDManager;
  30. bool runningAsServer;
  31. class User : public Replica3
  32. {
  33. public:
  34. User() {score=0;}
  35. virtual ~User() {}
  36. virtual void WriteAllocationID(RakNet::Connection_RM3 *destinationConnection, RakNet::BitStream *allocationIdBitstream) const {allocationIdBitstream->Write("User");}
  37. virtual RM3ConstructionState QueryConstruction(RakNet::Connection_RM3 *destinationConnection, ReplicaManager3 *replicaManager3) {
  38. return QueryConstruction_ServerConstruction(destinationConnection, runningAsServer);
  39. }
  40. virtual bool QueryRemoteConstruction(RakNet::Connection_RM3 *sourceConnection) {return QueryRemoteConstruction_ServerConstruction(sourceConnection, runningAsServer);}
  41. static void SerializeToBitStream(User *user, BitStream *bitStream)
  42. {
  43. bitStream->Write(user->score);
  44. bitStream->Write(user->username);
  45. bitStream->Write(user->guid);
  46. }
  47. static void DeserializeToBitStream(User *user, BitStream *bitStream)
  48. {
  49. bitStream->Read(user->score);
  50. bitStream->Read(user->username);
  51. bitStream->Read(user->guid);
  52. }
  53. virtual void SerializeConstruction(RakNet::BitStream *constructionBitstream, RakNet::Connection_RM3 *destinationConnection) {
  54. SerializeToBitStream(this, constructionBitstream);
  55. }
  56. virtual bool DeserializeConstruction(RakNet::BitStream *constructionBitstream, RakNet::Connection_RM3 *sourceConnection) {
  57. DeserializeToBitStream(this, constructionBitstream);
  58. if (guid==rakPeer->GetMyGUID())
  59. printf("My user created with name %s and score %i\n", username.C_String(), score);
  60. else
  61. printf("Another user created with name %s and score %i\n", username.C_String(), score);
  62. return true;
  63. }
  64. virtual void SerializeDestruction(RakNet::BitStream *destructionBitstream, RakNet::Connection_RM3 *destinationConnection) {}
  65. virtual bool DeserializeDestruction(RakNet::BitStream *destructionBitstream, RakNet::Connection_RM3 *sourceConnection) {return true;}
  66. virtual RakNet::RM3ActionOnPopConnection QueryActionOnPopConnection(RakNet::Connection_RM3 *droppedConnection) const {
  67. if (runningAsServer)
  68. return QueryActionOnPopConnection_Server(droppedConnection);
  69. else
  70. return QueryActionOnPopConnection_Client(droppedConnection);}
  71. virtual void DeallocReplica(RakNet::Connection_RM3 *sourceConnection) {delete this;}
  72. virtual RakNet::RM3QuerySerializationResult QuerySerialization(RakNet::Connection_RM3 *destinationConnection) {return QuerySerialization_ServerSerializable(destinationConnection, runningAsServer);}
  73. virtual RM3SerializationResult Serialize(RakNet::SerializeParameters *serializeParameters) {
  74. SerializeToBitStream(this, &serializeParameters->outputBitstream[0]);
  75. return RM3SR_BROADCAST_IDENTICALLY;
  76. }
  77. virtual void Deserialize(RakNet::DeserializeParameters *deserializeParameters) {
  78. if (deserializeParameters->bitstreamWrittenTo[0])
  79. DeserializeToBitStream(this, &deserializeParameters->serializationBitstream[0]);
  80. }
  81. static void DeleteUserWithGuid(RakNetGUID guid)
  82. {
  83. for (unsigned int i=0; i < replicaManager3->GetReplicaCount(); i++)
  84. {
  85. User *u = (User *) replicaManager3->GetReplicaAtIndex(i);
  86. if (u->guid==guid)
  87. {
  88. u->BroadcastDestruction();
  89. replicaManager3->Dereference(u);
  90. delete u;
  91. break;
  92. }
  93. }
  94. }
  95. virtual void PreDestruction(RakNet::Connection_RM3 *sourceConnection) {
  96. if (guid==rakPeer->GetMyGUID())
  97. printf("My user destroyed with name %s and score %i\n", username.C_String(), score);
  98. else
  99. printf("Another user destroyed with name %s and score %i\n", username.C_String(), score);
  100. }
  101. int score;
  102. RakString username;
  103. RakNetGUID guid;
  104. };
  105. // Required by ReplicaManager3. Acts as a class factory for Replica3 derived instances
  106. class SampleConnectionRM3 : public Connection_RM3
  107. {
  108. public:
  109. SampleConnectionRM3(const SystemAddress &_systemAddress, RakNetGUID _guid) : Connection_RM3(_systemAddress, _guid) {}
  110. virtual ~SampleConnectionRM3() {}
  111. virtual Replica3 *AllocReplica(RakNet::BitStream *allocationIdBitstream, ReplicaManager3 *replicaManager3)
  112. {
  113. RakString objectType;
  114. // Types are written by WriteAllocationID()
  115. allocationIdBitstream->Read(objectType);
  116. if (objectType=="User") return new User;
  117. RakAssert("Unknown type in AllocReplica" && 0);
  118. return 0;
  119. }
  120. };
  121. // Required by ReplicaManager3. Acts as a class factory for Connection_RM3 derived instances
  122. class SampleRM3 : public ReplicaManager3
  123. {
  124. public:
  125. SampleRM3() {}
  126. virtual ~SampleRM3() {}
  127. virtual Connection_RM3* AllocConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID) const {return new SampleConnectionRM3(systemAddress,rakNetGUID);}
  128. virtual void DeallocConnection(Connection_RM3 *connection) const {delete connection;}
  129. };
  130. int serverMain(void);
  131. int clientMain(void);
  132. int main(void)
  133. {
  134. rakPeer=RakNet::RakPeerInterface::GetInstance();
  135. networkIDManager = NetworkIDManager::GetInstance();
  136. replicaManager3=new SampleRM3;
  137. // ---------------------------------------------------------------------------------------------------------------------
  138. // Attach plugins
  139. // ---------------------------------------------------------------------------------------------------------------------
  140. rakPeer->AttachPlugin(replicaManager3);
  141. // Tell ReplicaManager3 which networkIDManager to use for object lookup, used for automatic serialization
  142. replicaManager3->SetNetworkIDManager(networkIDManager);
  143. printf("(S)erver or (C)lient?\n");
  144. char ch = getch();
  145. if (ch=='s' || ch=='S')
  146. return serverMain();
  147. else
  148. return clientMain();
  149. }
  150. int serverMain(void)
  151. {
  152. runningAsServer=true;
  153. RakNet::SocketDescriptor sd;
  154. sd.port=60000;
  155. StartupResult sr = rakPeer->Startup(8,&sd,1);
  156. RakAssert(sr==RAKNET_STARTED);
  157. rakPeer->SetMaximumIncomingConnections(8);
  158. rakPeer->SetTimeoutTime(30000,RakNet::UNASSIGNED_SYSTEM_ADDRESS);
  159. printf("Waiting for connections\n");
  160. Packet *packet;
  161. while (1)
  162. {
  163. for (packet = rakPeer->Receive(); packet; rakPeer->DeallocatePacket(packet), packet = rakPeer->Receive())
  164. {
  165. switch (packet->data[0])
  166. {
  167. case ID_NEW_INCOMING_CONNECTION:
  168. printf("ID_NEW_INCOMING_CONNECTION from %s. guid=%s.\n", packet->systemAddress.ToString(true), packet->guid.ToString());
  169. break;
  170. case ID_CONNECTION_REQUEST_ACCEPTED:
  171. printf("ID_CONNECTION_REQUEST_ACCEPTED from %s,guid=%s\n", packet->systemAddress.ToString(true), packet->guid.ToString());
  172. break;
  173. case ID_CONNECTION_LOST:
  174. printf("ID_CONNECTION_LOST from %s,guid=%s\n", packet->systemAddress.ToString(true), packet->guid.ToString());
  175. User::DeleteUserWithGuid(packet->guid);
  176. break;
  177. case ID_DISCONNECTION_NOTIFICATION:
  178. printf("ID_DISCONNECTION_NOTIFICATION from %s,guid=%s\n", packet->systemAddress.ToString(true), packet->guid.ToString());
  179. User::DeleteUserWithGuid(packet->guid);
  180. break;
  181. // Login
  182. case ID_USER_PACKET_ENUM:
  183. {
  184. BitStream bsIn(packet->data, packet->length, false);
  185. bsIn.IgnoreBytes(sizeof(MessageID));
  186. RakString username;
  187. bsIn.Read(username);
  188. printf("Accepting login from %s\n", username.C_String());
  189. User *newUser = new User;
  190. newUser->score=0;
  191. newUser->guid=packet->guid;
  192. newUser->username = username;
  193. replicaManager3->Reference(newUser);
  194. }
  195. break;
  196. }
  197. }
  198. RakSleep(30);
  199. }
  200. }
  201. int clientMain(void)
  202. {
  203. runningAsServer=false;
  204. RakNet::SocketDescriptor sd;
  205. sd.port=0;
  206. StartupResult sr = rakPeer->Startup(1,&sd,1);
  207. RakAssert(sr==RAKNET_STARTED);
  208. rakPeer->SetTimeoutTime(30000,RakNet::UNASSIGNED_SYSTEM_ADDRESS);
  209. rakPeer->Connect("127.0.0.1", 60000, 0, 0);
  210. printf("Connecting to server...\n");
  211. Packet *packet;
  212. while (1)
  213. {
  214. for (packet = rakPeer->Receive(); packet; rakPeer->DeallocatePacket(packet), packet = rakPeer->Receive())
  215. {
  216. switch (packet->data[0])
  217. {
  218. case ID_NEW_INCOMING_CONNECTION:
  219. printf("ID_NEW_INCOMING_CONNECTION from %s. guid=%s.\n", packet->systemAddress.ToString(true), packet->guid.ToString());
  220. break;
  221. case ID_CONNECTION_REQUEST_ACCEPTED:
  222. {
  223. printf("ID_CONNECTION_REQUEST_ACCEPTED from %s,guid=%s\n", packet->systemAddress.ToString(true), packet->guid.ToString());
  224. printf("Logging in...\n");
  225. BitStream bsOut;
  226. // Login
  227. bsOut.WriteCasted<MessageID>(ID_USER_PACKET_ENUM);
  228. RakString username("User %s", rakPeer->GetMyGUID().ToString());
  229. bsOut.Write(username);
  230. rakPeer->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
  231. }
  232. break;
  233. case ID_CONNECTION_LOST:
  234. printf("ID_CONNECTION_LOST from %s,guid=%s\n", packet->systemAddress.ToString(true), packet->guid.ToString());
  235. break;
  236. case ID_DISCONNECTION_NOTIFICATION:
  237. printf("ID_DISCONNECTION_NOTIFICATION from %s,guid=%s\n", packet->systemAddress.ToString(true), packet->guid.ToString());
  238. break;
  239. }
  240. }
  241. RakSleep(30);
  242. }
  243. }
粤ICP备19079148号