TeamManagerTest.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  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 <cstdio>
  11. #include <cstring>
  12. #include <stdlib.h>
  13. #include "GetTime.h"
  14. #include "Rand.h"
  15. #include "RakPeerInterface.h"
  16. #include "MessageIdentifiers.h"
  17. #include "FullyConnectedMesh2.h"
  18. #include "TeamManager.h"
  19. #include "Kbhit.h"
  20. #include "RakSleep.h"
  21. #include "RakNetTypes.h"
  22. #include "BitStream.h"
  23. #include "SocketLayer.h"
  24. #include "ReplicaManager3.h"
  25. #include "NetworkIDManager.h"
  26. using namespace RakNet;
  27. // Used by TeamManager to call SetHost() automatically when the current host peer drops
  28. // Also used to determine who the host is for the purposes of serializing objects to new systems
  29. FullyConnectedMesh2 *fullyConnectedMesh2;
  30. // UDP network communication
  31. RakPeerInterface *rakPeer;
  32. // Maintains pointers to TM_Team and TM_TeamMember, which contain team related functionality
  33. TeamManager *teamManager;
  34. // Used by ReplicaManager3 (below) for object lookup
  35. NetworkIDManager *networkIDManager;
  36. // class Team is implemented as a static object
  37. // A static object is one that already exists on systems before connection, as opposed to being created on demand.
  38. // see Help/replicamanager3.html under the topic Static Objects for what to return from the implemented interfaces
  39. class Team : public Replica3
  40. {
  41. public:
  42. Team() {tmTeam.SetOwner(this);}
  43. virtual ~Team() {}
  44. virtual void WriteAllocationID(RakNet::Connection_RM3 *destinationConnection, RakNet::BitStream *allocationIdBitstream) const {}
  45. virtual RM3ConstructionState QueryConstruction(RakNet::Connection_RM3 *destinationConnection, ReplicaManager3 *replicaManager3) {if (fullyConnectedMesh2->IsConnectedHost()) return RM3CS_ALREADY_EXISTS_REMOTELY; return RM3CS_ALREADY_EXISTS_REMOTELY_DO_NOT_CONSTRUCT;}
  46. virtual bool QueryRemoteConstruction(RakNet::Connection_RM3 *sourceConnection) {return false;}
  47. virtual void SerializeConstruction(RakNet::BitStream *constructionBitstream, RakNet::Connection_RM3 *destinationConnection) {}
  48. virtual bool DeserializeConstruction(RakNet::BitStream *constructionBitstream, RakNet::Connection_RM3 *sourceConnection) {return true;}
  49. virtual void SerializeConstructionExisting(RakNet::BitStream *constructionBitstream, RakNet::Connection_RM3 *destinationConnection) {tmTeam.SerializeConstruction(constructionBitstream);};
  50. virtual void DeserializeConstructionExisting(RakNet::BitStream *constructionBitstream, RakNet::Connection_RM3 *sourceConnection) {tmTeam.DeserializeConstruction(teamManager, constructionBitstream);};
  51. virtual void SerializeDestruction(RakNet::BitStream *destructionBitstream, RakNet::Connection_RM3 *destinationConnection) {}
  52. virtual bool DeserializeDestruction(RakNet::BitStream *destructionBitstream, RakNet::Connection_RM3 *sourceConnection) {return true;}
  53. virtual RakNet::RM3ActionOnPopConnection QueryActionOnPopConnection(RakNet::Connection_RM3 *droppedConnection) const {return RM3AOPC_DO_NOTHING;}
  54. virtual void DeallocReplica(RakNet::Connection_RM3 *sourceConnection) {}
  55. virtual RakNet::RM3QuerySerializationResult QuerySerialization(RakNet::Connection_RM3 *destinationConnection) {if (fullyConnectedMesh2->IsConnectedHost()) return RM3QSR_CALL_SERIALIZE; return RM3QSR_DO_NOT_CALL_SERIALIZE;}
  56. virtual RM3SerializationResult Serialize(RakNet::SerializeParameters *serializeParameters) {serializeParameters->outputBitstream[0].WriteCompressed(teamName); return RM3SR_BROADCAST_IDENTICALLY;}
  57. virtual void Deserialize(RakNet::DeserializeParameters *deserializeParameters) {deserializeParameters->serializationBitstream[0].ReadCompressed(teamName);}
  58. // The actual team data
  59. TM_Team tmTeam;
  60. // Example of user data not managed by TeamManager
  61. RakString teamName;
  62. };
  63. // User represents a player in the game
  64. // Each system has one user. This user is replicated to other systems.
  65. class User : public Replica3
  66. {
  67. public:
  68. User() {tmTeamMember.SetOwner(this);}
  69. virtual ~User() {}
  70. virtual void WriteAllocationID(RakNet::Connection_RM3 *destinationConnection, RakNet::BitStream *allocationIdBitstream) const {allocationIdBitstream->Write("User");}
  71. virtual RM3ConstructionState QueryConstruction(RakNet::Connection_RM3 *destinationConnection, ReplicaManager3 *replicaManager3) {return QueryConstruction_PeerToPeer(destinationConnection);}
  72. virtual bool QueryRemoteConstruction(RakNet::Connection_RM3 *sourceConnection) {return true;}
  73. virtual void SerializeConstruction(RakNet::BitStream *constructionBitstream, RakNet::Connection_RM3 *destinationConnection) {
  74. // teamMember must be serialized later than teams. This is accomplished by registering teams first with ReplicaManager3
  75. tmTeamMember.SerializeConstruction(constructionBitstream);
  76. }
  77. virtual bool DeserializeConstruction(RakNet::BitStream *constructionBitstream, RakNet::Connection_RM3 *sourceConnection) {
  78. return tmTeamMember.DeserializeConstruction(teamManager, constructionBitstream);
  79. }
  80. virtual void SerializeDestruction(RakNet::BitStream *destructionBitstream, RakNet::Connection_RM3 *destinationConnection) {}
  81. virtual bool DeserializeDestruction(RakNet::BitStream *destructionBitstream, RakNet::Connection_RM3 *sourceConnection) {return true;}
  82. virtual RakNet::RM3ActionOnPopConnection QueryActionOnPopConnection(RakNet::Connection_RM3 *droppedConnection) const {return QueryActionOnPopConnection_PeerToPeer(droppedConnection);}
  83. virtual void DeallocReplica(RakNet::Connection_RM3 *sourceConnection) {delete this;}
  84. virtual RakNet::RM3QuerySerializationResult QuerySerialization(RakNet::Connection_RM3 *destinationConnection) {return QuerySerialization_PeerToPeer(destinationConnection);}
  85. virtual RM3SerializationResult Serialize(RakNet::SerializeParameters *serializeParameters) {serializeParameters->outputBitstream[1].Write(userName); return RM3SR_BROADCAST_IDENTICALLY;}
  86. virtual void Deserialize(RakNet::DeserializeParameters *deserializeParameters) {if (deserializeParameters->bitstreamWrittenTo[1]) deserializeParameters->serializationBitstream[1].Read(userName);}
  87. void PrintTeamStatus(void)
  88. {
  89. if (tmTeamMember.GetCurrentTeamCount()==0)
  90. {
  91. printf("On 0 teams. noTeamId=%i ", tmTeamMember.GetNoTeamId());
  92. }
  93. else
  94. {
  95. printf("On %i teams: ", tmTeamMember.GetCurrentTeamCount());
  96. for (unsigned int i=0; i < tmTeamMember.GetCurrentTeamCount(); i++)
  97. {
  98. Team *t = (Team *) tmTeamMember.GetCurrentTeamByIndex(i)->GetOwner();
  99. printf("%s ", t->teamName.C_String());
  100. }
  101. }
  102. TeamSelection requestedTeam = tmTeamMember.GetRequestedTeam();
  103. if (requestedTeam.joinTeamType==JOIN_ANY_AVAILABLE_TEAM)
  104. {
  105. printf("Requested any available");
  106. }
  107. else if (requestedTeam.joinTeamType==JOIN_SPECIFIC_TEAM)
  108. {
  109. printf("Requested ");
  110. Team *t = (Team *) requestedTeam.teamParameter.specificTeamToJoin->GetOwner();
  111. printf("team %s ", t->teamName.C_String());
  112. }
  113. else
  114. {
  115. printf("No team requests.");
  116. }
  117. }
  118. // Team data managed by the TeamManager plugin
  119. TM_TeamMember tmTeamMember;
  120. // Example of user data not managed by TeamManager
  121. RakString userName;
  122. };
  123. // Required by ReplicaManager3
  124. class SampleConnectionRM3 : public Connection_RM3
  125. {
  126. public:
  127. SampleConnectionRM3(const SystemAddress &_systemAddress, RakNetGUID _guid) : Connection_RM3(_systemAddress, _guid) {}
  128. virtual ~SampleConnectionRM3() {}
  129. virtual Replica3 *AllocReplica(RakNet::BitStream *allocationIdBitstream, ReplicaManager3 *replicaManager3) {RakString objectType; allocationIdBitstream->Read(objectType); if (objectType=="User") return new User; return 0;}
  130. };
  131. // Required to derive from ReplicaManager3 as a class factory pattern to create SampleConnectionRM3
  132. class SampleRM3 : public ReplicaManager3
  133. {
  134. public:
  135. SampleRM3() {}
  136. virtual ~SampleRM3() {}
  137. virtual Connection_RM3* AllocConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID) const {return new SampleConnectionRM3(systemAddress,rakNetGUID);}
  138. virtual void DeallocConnection(Connection_RM3 *connection) const {delete connection;}
  139. };
  140. // Instance of ReplicaManager3
  141. SampleRM3 *replicaManager3;
  142. // Helper function
  143. // ReplicaManager3 does not add connections until we know who the host is via FullyConnectedMesh2
  144. // This function takes all FullyConnectedMesh2 connections and registers them with ReplicaManager3 once the host is determined.
  145. void RegisterFCM2Participants(void)
  146. {
  147. if (fullyConnectedMesh2->GetConnectedHost()!=UNASSIGNED_RAKNET_GUID)
  148. {
  149. DataStructures::List<RakNetGUID> participantList;
  150. fullyConnectedMesh2->GetParticipantList(participantList);
  151. for (unsigned int i=0; i < participantList.Size(); i++)
  152. {
  153. Connection_RM3 *connection = replicaManager3->AllocConnection(rakPeer->GetSystemAddressFromGuid(participantList[i]), participantList[i]);
  154. if (replicaManager3->PushConnection(connection)==false)
  155. replicaManager3->DeallocConnection(connection);
  156. teamManager->GetWorldAtIndex(0)->AddParticipant(participantList[i]);
  157. }
  158. }
  159. };
  160. enum TeamType
  161. {
  162. PLAYER_TEAM_1, // Plays game
  163. PLAYER_TEAM_2, // Plays game
  164. REFEREE_TEAM, // Only 1 person, only join on specific request
  165. TEAM_TYPES_COUNT
  166. };
  167. void PrintCommands(void)
  168. {
  169. printf("A. Request any team\n");
  170. printf("B. Request specific team\n");
  171. printf("C. Request team switch\n");
  172. printf("D. Cancel request team\n");
  173. printf("E. Leave specific team\n");
  174. printf("F. Leave all teams\n");
  175. printf("G. Set team member limit\n");
  176. printf("H. Turn on balance teams setting\n");
  177. printf("I. Turn off balance teams setting\n");
  178. printf("Press space to display state\n");
  179. }
  180. int main(void)
  181. {
  182. printf("This project demonstrates an in-game lobby using the team manager plugin.\n");
  183. printf("Difficulty: Intermediate\n\n");
  184. rakPeer=RakNet::RakPeerInterface::GetInstance();
  185. fullyConnectedMesh2=FullyConnectedMesh2::GetInstance();
  186. teamManager=TeamManager::GetInstance();
  187. networkIDManager = NetworkIDManager::GetInstance();
  188. replicaManager3=new SampleRM3;
  189. // test offline mode
  190. /*
  191. TM_TeamMember tmTeamMember;
  192. TM_Team tmTeam;
  193. teamManager->AddWorld(0);
  194. teamManager->GetWorldAtIndex(0)->ReferenceTeam(&tmTeam,1,false);
  195. teamManager->GetWorldAtIndex(0)->ReferenceTeamMember(&tmTeamMember,0);
  196. tmTeamMember.RequestTeam(TeamSelection::AnyAvailable());
  197. RakAssert(tmTeam.GetTeamMembersCount()==1);
  198. tmTeam.LeaveTeam(&tmTeamMember, 255);
  199. RakAssert(tmTeam.GetTeamMembersCount()==0);
  200. */
  201. rakPeer->AttachPlugin(fullyConnectedMesh2);
  202. rakPeer->AttachPlugin(teamManager);
  203. rakPeer->AttachPlugin(replicaManager3);
  204. rakPeer->AttachPlugin(fullyConnectedMesh2);
  205. // Make it so all new connections are registered with FullyConnectedMesh2
  206. fullyConnectedMesh2->SetAutoparticipateConnections(true);
  207. // Allocate a world instance to be used for team operations
  208. teamManager->AddWorld(0);
  209. // Tell ReplicaManager3 which networkIDManager to use for object lookup, used for automatic serialization
  210. replicaManager3->SetNetworkIDManager(networkIDManager);
  211. // Tell ReplicaManager3 and TeamManager to not automatically add new connections, because we wait for host calculation to complete from FullyConnectedMesh2 first
  212. replicaManager3->SetAutoManageConnections(false,true);
  213. teamManager->SetAutoManageConnections(false);
  214. // Just setup user data as an example
  215. Team teams[TEAM_TYPES_COUNT];
  216. teams[(int)PLAYER_TEAM_1].teamName="Player_Team_1";
  217. teams[(int)PLAYER_TEAM_2].teamName="Player_Team 2";
  218. teams[(int)REFEREE_TEAM].teamName="Referee_Team";
  219. for (unsigned int i=0; i < TEAM_TYPES_COUNT; i++)
  220. {
  221. // Static objects require additional setup before calling reference.
  222. teams[i].SetNetworkIDManager(networkIDManager);
  223. teams[i].SetNetworkID(i); // NetworkID value doesn't matter, just needs to be unique
  224. // We serialize teams before team members, this is required by TeamManager during remote object construction. Serialization occurs in the order that Reference() is called on the object
  225. replicaManager3->Reference(&teams[i]);
  226. // Register the team with the teamManager plugin
  227. // Do not apply team balancing to the referee team
  228. bool balancingAppliesToThisTeam = i!=REFEREE_TEAM;
  229. teamManager->GetWorldAtIndex(0)->ReferenceTeam(&teams[i].tmTeam,teams[i].GetNetworkID(),balancingAppliesToThisTeam);
  230. if (i==REFEREE_TEAM)
  231. teams[i].tmTeam.SetMemberLimit(1,0);
  232. else
  233. teams[i].tmTeam.SetMemberLimit(2,0);
  234. }
  235. // Only join the referee team on specific request
  236. teams[REFEREE_TEAM].tmTeam.SetJoinPermissions(ALLOW_JOIN_SPECIFIC_TEAM);
  237. // Setup my own
  238. User *user = new User;
  239. user->userName = rakPeer->GetMyGUID().ToString();
  240. // Inform ReplicaManager3 of my user
  241. replicaManager3->Reference(user);
  242. // Inform TeamManager of my user's team member info
  243. teamManager->GetWorldAtIndex(0)->ReferenceTeamMember(&user->tmTeamMember,user->GetNetworkID());
  244. // Startup RakNet
  245. RakNet::SocketDescriptor sd;
  246. sd.socketFamily=AF_INET; // Only IPV4 supports broadcast on 255.255.255.255
  247. sd.port=60000;
  248. while (IRNS2_Berkley::IsPortInUse(sd.port, sd.hostAddress, sd.socketFamily, SOCK_DGRAM)==true)
  249. sd.port++;
  250. StartupResult sr = rakPeer->Startup(8,&sd,1);
  251. RakAssert(sr==RAKNET_STARTED);
  252. rakPeer->SetMaximumIncomingConnections(8);
  253. rakPeer->SetTimeoutTime(30000,RakNet::UNASSIGNED_SYSTEM_ADDRESS);
  254. printf("Our guid is %s\n", rakPeer->GetGuidFromSystemAddress(RakNet::UNASSIGNED_SYSTEM_ADDRESS).ToString());
  255. printf("Started on %s\n", rakPeer->GetMyBoundAddress().ToString(true));
  256. for (int i=0; i < 32; i++)
  257. {
  258. if (rakPeer->GetInternalID(RakNet::UNASSIGNED_SYSTEM_ADDRESS,0).GetPort()!=60000+i)
  259. rakPeer->AdvertiseSystem("255.255.255.255", 60000+i, 0,0,0);
  260. }
  261. PrintCommands();
  262. bool success;
  263. bool quit=false;
  264. char ch;
  265. Packet *packet;
  266. while (!quit)
  267. {
  268. for (packet = rakPeer->Receive(); packet; rakPeer->DeallocatePacket(packet), packet = rakPeer->Receive())
  269. {
  270. switch (packet->data[0])
  271. {
  272. case ID_DISCONNECTION_NOTIFICATION:
  273. printf("ID_DISCONNECTION_NOTIFICATION\n");
  274. break;
  275. case ID_NEW_INCOMING_CONNECTION:
  276. {
  277. printf("ID_NEW_INCOMING_CONNECTION from %s. guid=%s.\n", packet->systemAddress.ToString(true), packet->guid.ToString());
  278. // Add mid-game joins to ReplicaManager3 as long as we know who the host is
  279. if (fullyConnectedMesh2->GetConnectedHost()!=UNASSIGNED_RAKNET_GUID)
  280. {
  281. bool success = replicaManager3->PushConnection(replicaManager3->AllocConnection(packet->systemAddress, packet->guid));
  282. RakAssert(success);
  283. teamManager->GetWorldAtIndex(0)->AddParticipant(packet->guid);
  284. }
  285. }
  286. break;
  287. case ID_CONNECTION_REQUEST_ACCEPTED:
  288. {
  289. printf("ID_CONNECTION_REQUEST_ACCEPTED from %s. guid=%s.\n", packet->systemAddress.ToString(true), packet->guid.ToString());
  290. // Add mid-game joins to ReplicaManager3 as long as we know who the host is
  291. if (fullyConnectedMesh2->GetConnectedHost()!=UNASSIGNED_RAKNET_GUID)
  292. {
  293. bool success = replicaManager3->PushConnection(replicaManager3->AllocConnection(packet->systemAddress, packet->guid));
  294. RakAssert(success);
  295. teamManager->GetWorldAtIndex(0)->AddParticipant(packet->guid);
  296. }
  297. }
  298. break;
  299. case ID_CONNECTION_LOST:
  300. printf("ID_CONNECTION_LOST\n");
  301. break;
  302. case ID_ADVERTISE_SYSTEM:
  303. if (packet->guid!=rakPeer->GetMyGUID())
  304. rakPeer->Connect(packet->systemAddress.ToString(false), packet->systemAddress.GetPort(),0,0);
  305. break;
  306. case ID_FCM2_NEW_HOST:
  307. {
  308. if (packet->guid==rakPeer->GetMyGUID())
  309. printf("Got new host (ourselves)");
  310. else
  311. printf("Got new host %s, GUID=%s", packet->systemAddress.ToString(true), packet->guid.ToString());
  312. RakNet::BitStream bs(packet->data,packet->length,false);
  313. bs.IgnoreBytes(1);
  314. RakNetGUID oldHost;
  315. bs.Read(oldHost);
  316. // If the old host is different, then this message was due to losing connection to the host.
  317. if (oldHost!=packet->guid)
  318. printf(". Oldhost Guid=%s\n", oldHost.ToString());
  319. else
  320. printf("\n");
  321. if (oldHost==UNASSIGNED_RAKNET_GUID)
  322. {
  323. // First time calculated host. Add existing connections to ReplicaManager3
  324. RegisterFCM2Participants();
  325. }
  326. }
  327. break;
  328. case ID_TEAM_BALANCER_TEAM_ASSIGNED:
  329. {
  330. printf("ID_TEAM_BALANCER_TEAM_ASSIGNED for ");
  331. TM_World *world;
  332. TM_TeamMember *teamMember;
  333. teamManager->DecodeTeamAssigned(packet, &world, &teamMember);
  334. printf("worldId=%i teamMember=%s\n", world->GetWorldId(), ((User*)teamMember->GetOwner())->userName.C_String());
  335. }
  336. break;
  337. case ID_TEAM_BALANCER_REQUESTED_TEAM_FULL:
  338. {
  339. printf("ID_TEAM_BALANCER_REQUESTED_TEAM_FULL\n");
  340. }
  341. break;
  342. case ID_TEAM_BALANCER_REQUESTED_TEAM_LOCKED:
  343. {
  344. printf("ID_TEAM_BALANCER_REQUESTED_TEAM_LOCKED\n");
  345. }
  346. break;
  347. case ID_TEAM_BALANCER_TEAM_REQUESTED_CANCELLED:
  348. {
  349. printf("ID_TEAM_BALANCER_TEAM_REQUESTED_CANCELLED\n");
  350. }
  351. break;
  352. }
  353. }
  354. if (kbhit())
  355. {
  356. ch=getch();
  357. if (ch=='A' || ch=='a')
  358. {
  359. printf("Request any team\n");
  360. success = user->tmTeamMember.RequestTeam(TeamSelection::AnyAvailable());
  361. printf("Success=%i\n", success);
  362. }
  363. if (ch=='B' || ch=='b')
  364. {
  365. printf("Request specific team\n");
  366. char buff1[256];
  367. printf("Enter team index (0-2): ");
  368. gets(buff1);
  369. if (buff1[0]!=0 && buff1[0]>='0' && buff1[0]<='2')
  370. {
  371. success = user->tmTeamMember.RequestTeam(TeamSelection::SpecificTeam(&(teams[buff1[0]-'0'].tmTeam)));
  372. printf("Success=%i\n", success);
  373. }
  374. else
  375. {
  376. printf("Aborted\n");
  377. }
  378. }
  379. if (ch=='C' || ch=='c')
  380. {
  381. printf("Request team switch\n");
  382. char buff1[256];
  383. printf("Enter team index to join (0-2): ");
  384. gets(buff1);
  385. char buff2[256];
  386. printf("Enter team index to leave (0-2) or leave empty for all: ");
  387. gets(buff2);
  388. if (buff1[0]!=0 && buff1[0]>='0' && buff1[0]<='2' &&
  389. (buff2[0]==0 || (buff2[0]>='0' && buff2[0]<='2')))
  390. {
  391. if (buff2[0])
  392. success = user->tmTeamMember.RequestTeamSwitch(&(teams[buff1[0]-'0'].tmTeam), &teams[buff2[0]-'0'].tmTeam);
  393. else
  394. success = user->tmTeamMember.RequestTeamSwitch(&(teams[buff1[0]-'0'].tmTeam), 0);
  395. printf("Success=%i\n", success);
  396. }
  397. else
  398. {
  399. printf("Aborted\n");
  400. }
  401. }
  402. if (ch=='D' || ch=='d')
  403. {
  404. printf("Cancel request team\n");
  405. char buff1[256];
  406. printf("Enter team index to cancel (0-2) or leave empty for all: ");
  407. gets(buff1);
  408. if ((buff1[0]!=0 && buff1[0]>='0' && buff1[0]<='2') || buff1[0]==0)
  409. {
  410. if (buff1[0])
  411. success = user->tmTeamMember.CancelTeamRequest(&(teams[buff1[0]-'0'].tmTeam));
  412. else
  413. success = user->tmTeamMember.CancelTeamRequest(0);
  414. printf("Success=%i\n", success);
  415. }
  416. else
  417. {
  418. printf("Aborted\n");
  419. }
  420. }
  421. if (ch=='E' || ch=='e')
  422. {
  423. printf("Leave specific team\n");
  424. char buff1[256];
  425. printf("Enter team index to leave (0-2): ");
  426. gets(buff1);
  427. if (buff1[0]!=0 && buff1[0]>='0' && buff1[0]<='2')
  428. {
  429. success = user->tmTeamMember.LeaveTeam(&(teams[buff1[0]-'0'].tmTeam),0);
  430. printf("Success=%i\n", success);
  431. }
  432. else
  433. {
  434. printf("Aborted\n");
  435. }
  436. }
  437. if (ch=='F' || ch=='f')
  438. {
  439. printf("Leave all teams\n");
  440. success = user->tmTeamMember.LeaveAllTeams(0);
  441. printf("Success=%i\n", success);
  442. }
  443. if (ch=='G' || ch=='g')
  444. {
  445. printf("Set team member limit\n");
  446. char buff1[256];
  447. printf("Enter team index to operate on (0-2): ");
  448. gets(buff1);
  449. char buff2[256];
  450. printf("Enter limit (0-9): ");
  451. gets(buff2);
  452. if (buff1[0]!=0 && buff1[0]>='0' && buff1[0]<='2' &&
  453. buff2[0]!=0 && buff2[0]>='0' && buff2[0]<='9')
  454. {
  455. success = teams[buff1[0]-'0'].tmTeam.SetMemberLimit(buff2[0]-'0',0);
  456. printf("Success=%i\n", success);
  457. }
  458. else
  459. {
  460. printf("Aborted\n");
  461. }
  462. }
  463. if (ch=='H' || ch=='h')
  464. {
  465. printf("Turn on balance teams setting\n");
  466. success = teamManager->GetWorldAtIndex(0)->SetBalanceTeams(true,0);
  467. printf("Success=%i\n", success);
  468. }
  469. if (ch=='I' || ch=='i')
  470. {
  471. printf("Turn off balance teams setting\n");
  472. success = teamManager->GetWorldAtIndex(0)->SetBalanceTeams(false,0);
  473. printf("Success=%i\n", success);
  474. }
  475. if (ch==' ')
  476. {
  477. if (teamManager->GetWorldAtIndex(0)->GetBalanceTeams())
  478. printf("Team balancing is on\n");
  479. else
  480. printf("Team balancing is off\n");
  481. for (unsigned int i=0; i < TEAM_TYPES_COUNT; i++)
  482. {
  483. printf("Team %i. %s %i/%i members ", i+1, teams[i].teamName.C_String(), teams[i].tmTeam.GetTeamMembersCount(), teams[i].tmTeam.GetMemberLimit());
  484. for (unsigned int j=0; j < teams[i].tmTeam.GetTeamMembersCount(); j++)
  485. {
  486. User *u = (User *) teams[i].tmTeam.GetTeamMemberByIndex(j)->GetOwner();
  487. printf("%s ", u->userName.C_String());
  488. }
  489. printf("\n");
  490. }
  491. unsigned int numUsers = teamManager->GetWorldAtIndex(0)->GetTeamMemberCount();
  492. for (unsigned int i=0; i < numUsers; i++)
  493. {
  494. User *u = (User *) teamManager->GetWorldAtIndex(0)->GetTeamMemberByIndex(i)->GetOwner();
  495. printf("User %i/%i. %s ", i+1, numUsers, u->userName.C_String());
  496. u->PrintTeamStatus();
  497. printf("\n");
  498. }
  499. printf("\n");
  500. }
  501. else if (ch=='q' || ch=='Q')
  502. {
  503. printf("Quitting.\n");
  504. quit=true;
  505. }
  506. }
  507. RakSleep(30);
  508. }
  509. rakPeer->Shutdown(100);
  510. replicaManager3->Clear();
  511. RakNet::RakPeerInterface::DestroyInstance(rakPeer);
  512. delete replicaManager3;
  513. RakNet::FullyConnectedMesh2::DestroyInstance(fullyConnectedMesh2);
  514. RakNet::TeamManager::DestroyInstance(teamManager);
  515. RakNet::NetworkIDManager::DestroyInstance(networkIDManager);
  516. for (unsigned int i=0; i < TEAM_TYPES_COUNT; i++)
  517. {
  518. // Teams are globally deallocated after NetworkIDManager, so prevent crash on automatic dereference
  519. teams[i].SetNetworkIDManager(0);
  520. }
  521. return 1;
  522. }
粤ICP备19079148号