SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FullyConnectedMesh2.cpp
Go to the documentation of this file.
1 /*
2 * Original work: 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 * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7 * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8 *
9 *
10 * Modified work: Copyright (c) 2016-2018, SLikeSoft UG (haftungsbeschränkt)
11 *
12 * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13 * license found in the license.txt file in the root directory of this source tree.
14 */
15
18
19
20 #include "slikenet/NativeFeatureIncludes.h"
21 #if _RAKNET_SUPPORT_FullyConnectedMesh2==1
22
23 #include "slikenet/FullyConnectedMesh2.h"
24 #include "slikenet/peerinterface.h"
25 #include "slikenet/MessageIdentifiers.h"
26 #include "slikenet/assert.h"
27 #include "slikenet/GetTime.h"
28 #include "slikenet/Rand.h"
29 #include "slikenet/DS_OrderedList.h"
30
31 using namespace SLNet;
32
33 int FCM2ParticipantComp( FullyConnectedMesh2::FCM2Participant * const &key, FullyConnectedMesh2::FCM2Participant * const &data )
34 {
35 if (key->fcm2Guid < data->fcm2Guid)
36 return -1;
37 if (key->fcm2Guid > data->fcm2Guid)
38 return 1;
39 return 0;
40 }
41
42 STATIC_FACTORY_DEFINITIONS(FullyConnectedMesh2,FullyConnectedMesh2);
43
44 FullyConnectedMesh2::FullyConnectedMesh2()
45 {
46 startupTime=0;
47 totalConnectionCount=0;
48 ourFCMGuid=0;
49 autoParticipateConnections=true;
50
51
52
53
54 connectOnNewRemoteConnections=true;
55
56 hostRakNetGuid=UNASSIGNED_RAKNET_GUID;
57 }
58 FullyConnectedMesh2::~FullyConnectedMesh2()
59 {
60 Clear();
61 }
62 RakNetGUID FullyConnectedMesh2::GetConnectedHost(void) const
63 {
64 if (ourFCMGuid==0)
65 return UNASSIGNED_RAKNET_GUID;
66 return hostRakNetGuid;
67 }
68 SystemAddress FullyConnectedMesh2::GetConnectedHostAddr(void) const
69 {
70 if (ourFCMGuid==0)
71 return UNASSIGNED_SYSTEM_ADDRESS;
72 return rakPeerInterface->GetSystemAddressFromGuid(hostRakNetGuid);
73 }
74 RakNetGUID FullyConnectedMesh2::GetHostSystem(void) const
75 {
76 if (ourFCMGuid==0)
77 return rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
78
79 return hostRakNetGuid;
80 }
81 bool FullyConnectedMesh2::IsHostSystem(void) const
82 {
83 return GetHostSystem()==rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
84 }
85 void FullyConnectedMesh2::GetHostOrder(DataStructures::List<RakNetGUID> &hostList)
86 {
87 hostList.Clear(true, _FILE_AND_LINE_);
88
89 if (ourFCMGuid==0 || fcm2ParticipantList.Size()==0)
90 {
91 hostList.Push(rakPeerInterface->GetMyGUID(), _FILE_AND_LINE_);
92 return;
93 }
94
95 FCM2Participant fcm2;
96 fcm2.fcm2Guid=ourFCMGuid;
97 fcm2.rakNetGuid=rakPeerInterface->GetMyGUID();
98
99 DataStructures::OrderedList<FCM2Participant*, FCM2Participant*, FCM2ParticipantComp> olist;
100 olist.Insert(&fcm2, &fcm2, true, _FILE_AND_LINE_);
101 for (unsigned int i=0; i < fcm2ParticipantList.Size(); i++)
102 olist.Insert(fcm2ParticipantList[i], fcm2ParticipantList[i], true, _FILE_AND_LINE_);
103
104 for (unsigned int i=0; i < olist.Size(); i++)
105 {
106 hostList.Push(olist[i]->rakNetGuid, _FILE_AND_LINE_);
107 }
108 }
109 bool FullyConnectedMesh2::IsConnectedHost(void) const
110 {
111 return GetConnectedHost()==rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
112 }
113 void FullyConnectedMesh2::SetAutoparticipateConnections(bool b)
114 {
115 autoParticipateConnections=b;
116 }
117 void FullyConnectedMesh2::ResetHostCalculation(void)
118 {
119 hostRakNetGuid=UNASSIGNED_RAKNET_GUID;
120 startupTime= SLNet::GetTimeUS();
121 totalConnectionCount=0;
122 ourFCMGuid=0;
123 for (unsigned int i=0; i < fcm2ParticipantList.Size(); i++)
124 SendFCMGuidRequest(fcm2ParticipantList[i]->rakNetGuid);
125 }
126 // bool FullyConnectedMesh2::AddParticipantInternal( RakNetGUID rakNetGuid, FCM2Guid theirFCMGuid, BitStream *userContext )
127 bool FullyConnectedMesh2::AddParticipantInternal( RakNetGUID rakNetGuid, FCM2Guid theirFCMGuid )
128 {
129 for (unsigned int i=0; i < fcm2ParticipantList.Size(); i++)
130 {
131 if (fcm2ParticipantList[i]->rakNetGuid==rakNetGuid)
132 {
133 if (theirFCMGuid!=0)
134 fcm2ParticipantList[i]->fcm2Guid=theirFCMGuid;
135 /*
136 fcm2ParticipantList[i]->userContext.Reset();
137 if (userContext)
138 {
139 userContext->ResetReadPointer();
140 fcm2ParticipantList[i]->userContext.Write(userContext);
141 }
142 */
143 return false;
144 }
145 }
146
147 FCM2Participant *participant = SLNet::OP_NEW<FCM2Participant>(_FILE_AND_LINE_);
148 participant->rakNetGuid=rakNetGuid;
149 participant->fcm2Guid=theirFCMGuid;
150 /*
151 if (userContext)
152 {
153 userContext->ResetReadPointer();
154 participant->userContext.Write(userContext);
155 }
156 */
157 fcm2ParticipantList.Push(participant,_FILE_AND_LINE_);
158
159 SendFCMGuidRequest(rakNetGuid);
160
161 return true;
162 }
163 void FullyConnectedMesh2::AddParticipant( RakNetGUID rakNetGuid )
164 {
165 if (rakPeerInterface->GetConnectionState(rakPeerInterface->GetSystemAddressFromGuid(rakNetGuid))!=IS_CONNECTED)
166 {
167 #ifdef DEBUG_FCM2
168 printf("AddParticipant to %s failed (not connected)\n", rakNetGuid.ToString());
169 #endif
170 return;
171 }
172
173 // Need to query other system for userdata before calling AddParticipantInternal
174 // But maybe I can call with no data, and piggyback on ID_FCM2_REQUEST_FCMGUID
175 //AddParticipantInternal(rakNetGuid,0,0);
176 AddParticipantInternal(rakNetGuid,0);
177 }
178 void FullyConnectedMesh2::GetParticipantList(DataStructures::List<RakNetGUID> &participantList)
179 {
180 participantList.Clear(true, _FILE_AND_LINE_);
181 unsigned int i;
182 for (i=0; i < fcm2ParticipantList.Size(); i++)
183 participantList.Push(fcm2ParticipantList[i]->rakNetGuid, _FILE_AND_LINE_);
184 }
185 bool FullyConnectedMesh2::HasParticipant(RakNetGUID participantGuid)
186 {
187 unsigned int i;
188 for (i=0; i < fcm2ParticipantList.Size(); i++)
189 {
190 if (fcm2ParticipantList[i]->rakNetGuid==participantGuid)
191 return true;
192 }
193 return false;
194 }
195 /*
196 bool FullyConnectedMesh2::GetParticipantContext(RakNetGUID participantGuid, BitStream *userContext)
197 {
198 unsigned int i;
199 for (i=0; i < fcm2ParticipantList.Size(); i++)
200 {
201 if (fcm2ParticipantList[i]->rakNetGuid==participantGuid)
202 {
203 if (fcm2ParticipantList[i]->userContext.GetNumberOfBitsUsed() > 0)
204 {
205 userContext->Write(fcm2ParticipantList[i]->userContext);
206 fcm2ParticipantList[i]->userContext.ResetReadPointer();
207 return true;
208 }
209 return false;
210 }
211 }
212 return false;
213 }
214 void FullyConnectedMesh2::SetMyContext(BitStream *userContext)
215 {
216 if (userContext==0)
217 {
218 if (myContext.GetNumberOfBitsUsed()==0)
219 return;
220 myContext.Reset();
221 }
222 else
223 {
224 myContext.Write(userContext);
225 userContext->ResetReadPointer();
226 }
227
228 SLNet::BitStream bsOut;
229 bsOut.Write((MessageID)ID_FCM2_UPDATE_USER_CONTEXT);
230 bsOut.Write(myContext);
231 myContext.ResetReadPointer();
232
233 unsigned int idx;
234 for (idx=0; idx < fcm2ParticipantList.Size(); idx++)
235 {
236 rakPeerInterface->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,fcm2ParticipantList[idx]->rakNetGuid,false);
237 }
238 }
239 */
240 PluginReceiveResult FullyConnectedMesh2::OnReceive(Packet *packet)
241 {
242 switch (packet->data[0])
243 {
244 case ID_REMOTE_NEW_INCOMING_CONNECTION:
245 {
246 if (connectOnNewRemoteConnections)
247 ConnectToRemoteNewIncomingConnections(packet);
248 }
249 break;
250 case ID_FCM2_REQUEST_FCMGUID:
251 OnRequestFCMGuid(packet);
252 return RR_STOP_PROCESSING_AND_DEALLOCATE;
253 //case ID_FCM2_UPDATE_USER_CONTEXT:
254 // OnUpdateUserContext(packet);
255 // return RR_STOP_PROCESSING_AND_DEALLOCATE;
256 case ID_FCM2_RESPOND_CONNECTION_COUNT:
257 OnRespondConnectionCount(packet);
258 return RR_STOP_PROCESSING_AND_DEALLOCATE;
259 case ID_FCM2_INFORM_FCMGUID:
260 OnInformFCMGuid(packet);
261 return RR_STOP_PROCESSING_AND_DEALLOCATE;
262 case ID_FCM2_UPDATE_MIN_TOTAL_CONNECTION_COUNT:
263 OnUpdateMinTotalConnectionCount(packet);
264 return RR_STOP_PROCESSING_AND_DEALLOCATE;
265 case ID_FCM2_NEW_HOST:
266 if (packet->wasGeneratedLocally==false)
267 return RR_STOP_PROCESSING_AND_DEALLOCATE;
268 break;
269 case ID_FCM2_VERIFIED_JOIN_START:
270 return OnVerifiedJoinStart(packet);
271 case ID_FCM2_VERIFIED_JOIN_CAPABLE:
272 return OnVerifiedJoinCapable(packet);
273 case ID_FCM2_VERIFIED_JOIN_FAILED:
274 OnVerifiedJoinFailed(packet->guid, true);
275 return RR_CONTINUE_PROCESSING;
276 case ID_FCM2_VERIFIED_JOIN_ACCEPTED:
277 if (packet->wasGeneratedLocally==false)
278 OnVerifiedJoinAccepted(packet);
279 return RR_CONTINUE_PROCESSING;
280 case ID_FCM2_VERIFIED_JOIN_REJECTED:
281 OnVerifiedJoinRejected(packet);
282 return RR_CONTINUE_PROCESSING;
283
284 case ID_NAT_TARGET_UNRESPONSIVE:
285 case ID_NAT_TARGET_NOT_CONNECTED:
286 case ID_NAT_CONNECTION_TO_TARGET_LOST:
287 {
288 SLNet::RakNetGUID g;
289 SLNet::BitStream b(packet->data, packet->length, false);
290 b.IgnoreBits(8); // Ignore the ID_...
291 b.Read(g);
292 UpdateVerifiedJoinInProgressMember(g, UNASSIGNED_RAKNET_GUID, JIPS_FAILED);
293 return RR_CONTINUE_PROCESSING;
294 }
295 case ID_NAT_PUNCHTHROUGH_FAILED:
296 UpdateVerifiedJoinInProgressMember(packet->guid, UNASSIGNED_RAKNET_GUID, JIPS_FAILED);
297 return RR_CONTINUE_PROCESSING;
298 }
299
300 return RR_CONTINUE_PROCESSING;
301 }
302 void FullyConnectedMesh2::OnRakPeerStartup(void)
303 {
304 Clear();
305 startupTime= SLNet::GetTimeUS();
306 }
307 void FullyConnectedMesh2::OnAttach(void)
308 {
309 Clear();
310 // In case Startup() was called first
311 if (rakPeerInterface->IsActive())
312 startupTime= SLNet::GetTimeUS();
313 }
314 void FullyConnectedMesh2::OnRakPeerShutdown(void)
315 {
316 Clear();
317 startupTime=0;
318 }
319 void FullyConnectedMesh2::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
320 {
321 (void) lostConnectionReason;
322 (void) systemAddress;
323 (void) rakNetGUID;
324
325 unsigned int idx;
326 idx=0;
327 while (idx < joinsInProgress.Size())
328 {
329 if (joinsInProgress[idx]->requester==rakNetGUID)
330 {
331 Packet *p = AllocatePacketUnified(sizeof(MessageID)+sizeof(unsigned char));
332 p->data[0]=ID_FCM2_VERIFIED_JOIN_FAILED;
333 p->systemAddress=systemAddress;
334 p->systemAddress.systemIndex=(SystemIndex)-1;
335 p->guid=rakNetGUID;
336 p->wasGeneratedLocally=true;
337 rakPeerInterface->PushBackPacket(p, true);
338
339 for (unsigned int j=0; j < joinsInProgress[idx]->vjipMembers.Size(); j++)
340 {
341 if ( joinsInProgress[idx]->vjipMembers[j].userData != 0)
342 {
343 SLNet::OP_DELETE(joinsInProgress[idx]->vjipMembers[j].userData, _FILE_AND_LINE_);
344 }
345 }
346
347 SLNet::OP_DELETE(joinsInProgress[idx], _FILE_AND_LINE_);
348 joinsInProgress.RemoveAtIndex(idx);
349 }
350 else
351 {
352 idx++;
353 }
354 }
355
356 UpdateVerifiedJoinInProgressMember(rakNetGUID, UNASSIGNED_RAKNET_GUID, JIPS_FAILED);
357
358 for (idx=0; idx < fcm2ParticipantList.Size(); idx++)
359 {
360 if (fcm2ParticipantList[idx]->rakNetGuid==rakNetGUID)
361 {
362 fcm2ParticipantList[idx]=fcm2ParticipantList[fcm2ParticipantList.Size()-1];
363 #ifdef DEBUG_FCM2
364 printf("Popping participant %s\n", fcm2ParticipantList[fcm2ParticipantList.Size()-1].rakNetGuid.ToString());
365 #endif
366
367 fcm2ParticipantList.Pop();
368 if (rakNetGUID==hostRakNetGuid && ourFCMGuid!=0)
369 {
370 if (fcm2ParticipantList.Size()==0)
371 {
372 hostRakNetGuid=rakPeerInterface->GetMyGUID();
373 hostFCM2Guid=ourFCMGuid;
374 }
375 else
376 {
377 CalculateHost(&hostRakNetGuid, &hostFCM2Guid);
378 }
379 PushNewHost(hostRakNetGuid, rakNetGUID);
380 }
381 return;
382 }
383 }
384
385 }
386 SLNet::TimeUS FullyConnectedMesh2::GetElapsedRuntime(void)
387 {
388 SLNet::TimeUS curTime= SLNet::GetTimeUS();
389 if (curTime>startupTime)
390 return curTime-startupTime;
391 else
392 return 0;
393 }
394 void FullyConnectedMesh2::OnNewConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, bool isIncoming)
395 {
396 (void) isIncoming;
397 (void) rakNetGUID;
398 (void) systemAddress;
399
400 UpdateVerifiedJoinInProgressMember(rakNetGUID, rakNetGUID, JIPS_CONNECTED);
401
402 if (autoParticipateConnections)
403 AddParticipant(rakNetGUID);
404 }
405 void FullyConnectedMesh2::OnFailedConnectionAttempt(Packet *packet, PI2_FailedConnectionAttemptReason failedConnectionAttemptReason)
406 {
407 if (failedConnectionAttemptReason==FCAR_ALREADY_CONNECTED)
408 {
409 UpdateVerifiedJoinInProgressMember(packet->guid, packet->guid, JIPS_CONNECTED);
410 }
411 else
412 {
413 UpdateVerifiedJoinInProgressMember(packet->systemAddress, UNASSIGNED_RAKNET_GUID, JIPS_FAILED);
414 }
415 }
416 void FullyConnectedMesh2::Clear(void)
417 {
418 for (unsigned int i=0; i < fcm2ParticipantList.Size(); i++)
419 {
420 SLNet::OP_DELETE(fcm2ParticipantList[i], _FILE_AND_LINE_);
421 }
422 fcm2ParticipantList.Clear(false, _FILE_AND_LINE_);
423
424 for (unsigned int i=0; i < joinsInProgress.Size(); i++)
425 {
426 for (unsigned int j=0; j < joinsInProgress[i]->vjipMembers.Size(); j++)
427 {
428 if ( joinsInProgress[i]->vjipMembers[j].userData != 0)
429 {
430 SLNet::OP_DELETE(joinsInProgress[i]->vjipMembers[j].userData, _FILE_AND_LINE_);
431 }
432 }
433
434 SLNet::OP_DELETE(joinsInProgress[i], _FILE_AND_LINE_);
435 }
436 joinsInProgress.Clear(true, _FILE_AND_LINE_);
437
438 totalConnectionCount=0;
439 ourFCMGuid=0;
440 lastPushedHost=UNASSIGNED_RAKNET_GUID;
441 }
442 void FullyConnectedMesh2::PushNewHost(const RakNetGUID &guid, RakNetGUID oldHost)
443 {
444 Packet *p = AllocatePacketUnified(sizeof(MessageID)+sizeof(oldHost));
445 SLNet::BitStream bs(p->data,p->length,false);
446 bs.SetWriteOffset(0);
447 bs.Write((MessageID)ID_FCM2_NEW_HOST);
448 bs.Write(oldHost);
449 p->systemAddress=rakPeerInterface->GetSystemAddressFromGuid(guid);
450 p->systemAddress.systemIndex=(SystemIndex)-1;
451 p->guid=guid;
452 p->wasGeneratedLocally=true;
453 rakPeerInterface->PushBackPacket(p, true);
454
455 lastPushedHost=guid;
456 }
457 void FullyConnectedMesh2::SendFCMGuidRequest(RakNetGUID rakNetGuid)
458 {
459 if (rakNetGuid==rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS))
460 return;
461
462 SLNet::BitStream bsOut;
463 bsOut.Write((MessageID)ID_FCM2_REQUEST_FCMGUID);
464 if (ourFCMGuid==0)
465 {
466 bsOut.Write(false);
467 bsOut.Write(GetElapsedRuntime());
468 }
469 else
470 {
471 bsOut.Write(true);
472 bsOut.Write(totalConnectionCount);
473 bsOut.Write(ourFCMGuid);
474 }
475 bsOut.Write(myContext);
476 myContext.ResetReadPointer();
477 rakPeerInterface->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,rakNetGuid,false);
478 }
479 void FullyConnectedMesh2::SendOurFCMGuid(SystemAddress addr)
480 {
481 SLNet::BitStream bsOut;
482 bsOut.Write((MessageID)ID_FCM2_INFORM_FCMGUID);
483 RakAssert(ourFCMGuid!=0); // Can't inform others of our FCM2Guid if it's unset!
484 bsOut.Write(ourFCMGuid);
485 bsOut.Write(totalConnectionCount);
486 bsOut.Write(myContext);
487 myContext.ResetReadPointer();
488 rakPeerInterface->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,addr,false);
489 }
490 void FullyConnectedMesh2::SendConnectionCountResponse(SystemAddress addr, unsigned int responseTotalConnectionCount)
491 {
492 SLNet::BitStream bsOut;
493 bsOut.Write((MessageID)ID_FCM2_RESPOND_CONNECTION_COUNT);
494 bsOut.Write(responseTotalConnectionCount);
495 //bsOut.Write(myContext);
496 //myContext.ResetReadPointer();
497 rakPeerInterface->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,addr,false);
498 }
499 void FullyConnectedMesh2::AssignOurFCMGuid(void)
500 {
501 // Only assigned once ever
502 RakAssert(ourFCMGuid==0);
503 unsigned int randomNumber = randomMT();
504 randomNumber ^= (unsigned int) (SLNet::GetTimeUS() & 0xFFFFFFFF);
505 randomNumber ^= (unsigned int) (rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS).g & 0xFFFFFFFF);
506 ourFCMGuid |= randomNumber;
507 uint64_t reponse64 = totalConnectionCount;
508 ourFCMGuid |= reponse64<<32;
509 }
510 void FullyConnectedMesh2::CalculateHost(RakNetGUID *rakNetGuid, FCM2Guid *fcm2Guid)
511 {
512 // Can't calculate host without knowing our own
513 RakAssert(ourFCMGuid!=0);
514
515 // Can't calculate host without being connected to anyone else
516 RakAssert(fcm2ParticipantList.Size()>0);
517
518 // Return the lowest value of all FCM2Guid
519 FCM2Guid lowestFCMGuid=ourFCMGuid;
520 // SystemAddress associatedSystemAddress=UNASSIGNED_SYSTEM_ADDRESS;
521 RakNetGUID associatedRakNetGuid=rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
522
523 unsigned int idx;
524 for (idx=0; idx < fcm2ParticipantList.Size(); idx++)
525 {
526 if (fcm2ParticipantList[idx]->fcm2Guid!=0 && fcm2ParticipantList[idx]->fcm2Guid<lowestFCMGuid)
527 {
528 lowestFCMGuid=fcm2ParticipantList[idx]->fcm2Guid;
529 associatedRakNetGuid=fcm2ParticipantList[idx]->rakNetGuid;
530 }
531 }
532
533 *rakNetGuid=associatedRakNetGuid;
534 *fcm2Guid=lowestFCMGuid;
535 }
536 void FullyConnectedMesh2::OnRequestFCMGuid(Packet *packet)
537 {
538 SLNet::BitStream bsIn(packet->data,packet->length,false);
539 bsIn.IgnoreBytes(sizeof(MessageID));
540 bool hasRemoteFCMGuid=false;
541 bsIn.Read(hasRemoteFCMGuid);
542 SLNet::TimeUS senderElapsedRuntime=0;
543 unsigned int remoteTotalConnectionCount=0;
544 FCM2Guid theirFCMGuid=0;
545 if (hasRemoteFCMGuid)
546 {
547 bsIn.Read(remoteTotalConnectionCount);
548 bsIn.Read(theirFCMGuid);
549 }
550 else
551 {
552 bsIn.Read(senderElapsedRuntime);
553 }
554 /*
555 BitStream remoteContext;
556 bsIn.Read(remoteContext);
557 AddParticipantInternal(packet->guid,theirFCMGuid, &remoteContext);
558 */
559 AddParticipantInternal(packet->guid,theirFCMGuid);
560 if (ourFCMGuid==0)
561 {
562 if (hasRemoteFCMGuid==false)
563 {
564 // Nobody has a fcmGuid
565
566 SLNet::TimeUS ourElapsedRuntime = GetElapsedRuntime();
567 if (ourElapsedRuntime>senderElapsedRuntime)
568 {
569 // We are probably host
570 SendConnectionCountResponse(packet->systemAddress, 2);
571 }
572 else
573 {
574 // They are probably host
575 SendConnectionCountResponse(packet->systemAddress, 1);
576 }
577 }
578 else
579 {
580 // They have a fcmGuid, we do not
581 IncrementTotalConnectionCount(remoteTotalConnectionCount+1);
582
583 AssignOurFCMGuid();
584 unsigned int idx;
585 for (idx=0; idx < fcm2ParticipantList.Size(); idx++)
586 SendOurFCMGuid(rakPeerInterface->GetSystemAddressFromGuid(fcm2ParticipantList[idx]->rakNetGuid));
587 }
588 }
589 else
590 {
591 if (hasRemoteFCMGuid==false)
592 {
593 // We have a fcmGuid they do not
594 SendConnectionCountResponse(packet->systemAddress, totalConnectionCount+1);
595 }
596 else
597 {
598 // We both have fcmGuids
599 IncrementTotalConnectionCount(remoteTotalConnectionCount);
600
601 SendOurFCMGuid(packet->systemAddress);
602 }
603 }
604 CalculateAndPushHost();
605 }
606 /*
607 void FullyConnectedMesh2::OnUpdateUserContext(Packet *packet)
608 {
609 SLNet::BitStream bsIn(packet->data,packet->length,false);
610 bsIn.IgnoreBytes(sizeof(MessageID));
611 BitStream remoteContext;
612 bsIn.Read(remoteContext);
613
614 for (unsigned int i=0; i < fcm2ParticipantList.Size(); i++)
615 {
616 if (fcm2ParticipantList[i]->rakNetGuid==packet->guid)
617 {
618 fcm2ParticipantList[i]->userContext.Reset();
619 remoteContext.Read(fcm2ParticipantList[i]->userContext);
620 break;
621 }
622 }
623 }
624 */
625 void FullyConnectedMesh2::OnRespondConnectionCount(Packet *packet)
626 {
627 SLNet::BitStream bsIn(packet->data,packet->length,false);
628 bsIn.IgnoreBytes(sizeof(MessageID));
629 unsigned int responseTotalConnectionCount;
630 bsIn.Read(responseTotalConnectionCount);
631 /*
632 BitStream remoteContext;
633 bsIn.Read(remoteContext);
634
635 for (unsigned int i=0; i < fcm2ParticipantList.Size(); i++)
636 {
637 if (fcm2ParticipantList[i]->rakNetGuid==packet->guid)
638 {
639 fcm2ParticipantList[i]->userContext.Reset();
640 remoteContext.Read(fcm2ParticipantList[i]->userContext);
641 break;
642 }
643 }
644 */
645
646 IncrementTotalConnectionCount(responseTotalConnectionCount);
647 bool wasAssigned;
648 if (ourFCMGuid==0)
649 {
650 wasAssigned=true;
651 AssignOurFCMGuid();
652 }
653 else
654 wasAssigned=false;
655
656 // 1 is returned to give us lower priority, but the actual minimum is 2
657 IncrementTotalConnectionCount(2);
658
659 if (wasAssigned==true)
660 {
661 unsigned int idx;
662 for (idx=0; idx < fcm2ParticipantList.Size(); idx++)
663 SendOurFCMGuid(rakPeerInterface->GetSystemAddressFromGuid(fcm2ParticipantList[idx]->rakNetGuid));
664 CalculateAndPushHost();
665 }
666 }
667 void FullyConnectedMesh2::OnInformFCMGuid(Packet *packet)
668 {
669 SLNet::BitStream bsIn(packet->data,packet->length,false);
670 bsIn.IgnoreBytes(sizeof(MessageID));
671
672 FCM2Guid theirFCMGuid;
673 unsigned int theirTotalConnectionCount;
674 bsIn.Read(theirFCMGuid);
675 bsIn.Read(theirTotalConnectionCount);
676
677 BitStream remoteContext;
678 bsIn.Read(remoteContext);
679
680 IncrementTotalConnectionCount(theirTotalConnectionCount);
681
682 //if (AddParticipantInternal(packet->guid,theirFCMGuid, &remoteContext))
683 if (AddParticipantInternal(packet->guid,theirFCMGuid))
684 {
685 // 1/19/2010 - Relay increased total connection count in case new participant only connects to part of the mesh
686 unsigned int idx;
687 SLNet::BitStream bsOut;
688 bsOut.Write((MessageID)ID_FCM2_UPDATE_MIN_TOTAL_CONNECTION_COUNT);
689 bsOut.Write(totalConnectionCount);
690 for (idx=0; idx < fcm2ParticipantList.Size(); idx++)
691 {
692 if (packet->guid!=fcm2ParticipantList[idx]->rakNetGuid)
693 rakPeerInterface->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,fcm2ParticipantList[idx]->rakNetGuid,false);
694 }
695 }
696
697 if (ourFCMGuid==0)
698 {
699 AssignOurFCMGuid();
700 unsigned int idx;
701 for (idx=0; idx < fcm2ParticipantList.Size(); idx++)
702 SendOurFCMGuid(rakPeerInterface->GetSystemAddressFromGuid(fcm2ParticipantList[idx]->rakNetGuid));
703 }
704
705 CalculateAndPushHost();
706 }
707 void FullyConnectedMesh2::OnUpdateMinTotalConnectionCount(Packet *packet)
708 {
709 SLNet::BitStream bsIn(packet->data,packet->length,false);
710 bsIn.IgnoreBytes(sizeof(MessageID));
711 unsigned int newMin;
712 bsIn.Read(newMin);
713 IncrementTotalConnectionCount(newMin);
714 }
715 void FullyConnectedMesh2::GetParticipantCount(unsigned int *participantListSize) const
716 {
717 *participantListSize=fcm2ParticipantList.Size();
718 }
719
720 unsigned int FullyConnectedMesh2::GetParticipantCount(void) const
721 {
722 return fcm2ParticipantList.Size();
723 }
724 void FullyConnectedMesh2::CalculateAndPushHost(void)
725 {
726 RakNetGUID newHostGuid;
727 FCM2Guid newFcmGuid;
728 if (ParticipantListComplete())
729 {
730 CalculateHost(&newHostGuid, &newFcmGuid);
731 if (newHostGuid!=lastPushedHost)
732 {
733 hostRakNetGuid=newHostGuid;
734 hostFCM2Guid=newFcmGuid;
735 PushNewHost(hostRakNetGuid, lastPushedHost);
736 }
737 }
738 }
739 bool FullyConnectedMesh2::ParticipantListComplete(void)
740 {
741 for (unsigned int i=0; i < fcm2ParticipantList.Size(); i++)
742 {
743 if (fcm2ParticipantList[i]->fcm2Guid==0)
744 return false;
745 }
746 return true;
747 }
748 void FullyConnectedMesh2::IncrementTotalConnectionCount(unsigned int i)
749 {
750 if (i>totalConnectionCount)
751 {
752 totalConnectionCount=i;
753 // printf("totalConnectionCount=%i\n",i);
754 }
755 }
756 void FullyConnectedMesh2::SetConnectOnNewRemoteConnection(bool attemptConnection, SLNet::RakString pw)
757 {
758 connectOnNewRemoteConnections=attemptConnection;
759 connectionPassword=pw;
760 }
761
762 void FullyConnectedMesh2::ConnectToRemoteNewIncomingConnections(Packet *packet)
763 {
764 unsigned int count;
765 SLNet::BitStream bsIn(packet->data, packet->length, false);
766 bsIn.IgnoreBytes(sizeof(MessageID));
767 bsIn.Read(count);
768 SystemAddress remoteAddress;
769 RakNetGUID remoteGuid;
770 char str[64];
771 for (unsigned int i=0; i < count; i++)
772 {
773 bsIn.Read(remoteAddress);
774 bsIn.Read(remoteGuid);
775 remoteAddress.ToString(false,str,static_cast<size_t>(64));
776 rakPeerInterface->Connect(str,remoteAddress.GetPort(),connectionPassword.C_String(),(int) connectionPassword.GetLength());
777 }
778 }
779 unsigned int FullyConnectedMesh2::GetTotalConnectionCount(void) const
780 {
781 return totalConnectionCount;
782 }
783 void FullyConnectedMesh2::StartVerifiedJoin(RakNetGUID client)
784 {
785 // Assert is because there is no point calling StartVerifiedJoin() if this client is already a participant
786 RakAssert(HasParticipant(client)==false);
787 RakAssert(client!=rakPeerInterface->GetMyGUID());
788
789 BitStream bsOut;
790 bsOut.Write((MessageID) ID_FCM2_VERIFIED_JOIN_START);
791 bsOut.WriteCasted<unsigned short>(fcm2ParticipantList.Size());
792 unsigned int i;
793 for (i=0; i < fcm2ParticipantList.Size(); i++)
794 {
795 bsOut.Write(fcm2ParticipantList[i]->rakNetGuid);
796 bsOut.Write(rakPeerInterface->GetSystemAddressFromGuid(fcm2ParticipantList[i]->rakNetGuid));
797
798 BitStream vjsOut;
799 //WriteVJSUserData(&vjsOut, fcm2ParticipantList[i]->rakNetGuid, &fcm2ParticipantList[i]->userContext );
800 WriteVJSUserData(&vjsOut, fcm2ParticipantList[i]->rakNetGuid );
801 bsOut.Write(vjsOut.GetNumberOfBitsUsed());
802 bsOut.Write(&vjsOut);
803 bsOut.AlignWriteToByteBoundary();
804 }
805 SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, client, false);
806 }
807 void FullyConnectedMesh2::RespondOnVerifiedJoinCapable(Packet *packet, bool accept, BitStream *additionalData)
808 {
809 VerifiedJoinInProgress vjip;
810 DecomposeJoinCapable(packet, &vjip);
811
812 DataStructures::List<RakNetGUID> participatingMembersOnClientSucceeded;
813 DataStructures::List<RakNetGUID> participatingMembersOnClientFailed;
814 DataStructures::List<RakNetGUID> participatingMembersNotOnClient;
815 DataStructures::List<RakNetGUID> clientMembersNotParticipatingSucceeded;
816 DataStructures::List<RakNetGUID> clientMembersNotParticipatingFailed;
817 CategorizeVJIP(&vjip,
818 participatingMembersOnClientSucceeded,
819 participatingMembersOnClientFailed,
820 participatingMembersNotOnClient,
821 clientMembersNotParticipatingSucceeded,
822 clientMembersNotParticipatingFailed);
823
824 if (participatingMembersNotOnClient.Size()>0)
825 {
826 BitStream bsOut;
827 bsOut.Write((MessageID) ID_FCM2_VERIFIED_JOIN_START);
828 bsOut.WriteCasted<unsigned short>(participatingMembersNotOnClient.Size());
829 unsigned int i;
830 for (i=0; i < participatingMembersNotOnClient.Size(); i++)
831 {
832 bsOut.Write(participatingMembersNotOnClient[i]);
833 bsOut.Write(rakPeerInterface->GetSystemAddressFromGuid(participatingMembersNotOnClient[i]));
834
835 bool written=false;
836 for (unsigned int j=0; j < fcm2ParticipantList.Size(); j++)
837 {
838 if (fcm2ParticipantList[j]->rakNetGuid == participatingMembersNotOnClient[i])
839 {
840 written=true;
841
842 BitStream vjsOut;
843 //WriteVJSUserData(&vjsOut, fcm2ParticipantList[j]->rakNetGuid, &fcm2ParticipantList[j]->userContext );
844 WriteVJSUserData(&vjsOut, fcm2ParticipantList[j]->rakNetGuid );
845 bsOut.Write(vjsOut.GetNumberOfBitsUsed());
846 bsOut.Write(&vjsOut);
847 bsOut.AlignWriteToByteBoundary();
848 break;
849 }
850 }
851 RakAssert(written==true);
852 }
853 SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
854 return;
855 }
856
857 RakAssert(participatingMembersOnClientFailed.Size()==0);
858 RakAssert(participatingMembersNotOnClient.Size()==0);
859
860 SLNet::BitStream bsOut;
861 if (accept)
862 {
863 bsOut.Write((MessageID)ID_FCM2_VERIFIED_JOIN_ACCEPTED);
864 bsOut.Write(packet->guid);
865
866 // Tell client to disconnect from clientMembersNotParticipatingSucceeded
867 bsOut.WriteCasted<unsigned short>(clientMembersNotParticipatingSucceeded.Size());
868 for (unsigned int i=0; i < clientMembersNotParticipatingSucceeded.Size(); i++)
869 bsOut.Write(clientMembersNotParticipatingSucceeded[i]);
870
871 // Tell client to call AddParticipant() for participatingMembersOnClientSucceeded
872 bsOut.WriteCasted<unsigned short>(participatingMembersOnClientSucceeded.Size());
873 for (unsigned int i=0; i < participatingMembersOnClientSucceeded.Size(); i++)
874 bsOut.Write(participatingMembersOnClientSucceeded[i]);
875
876 if (additionalData)
877 bsOut.Write(additionalData);
878
879 for (unsigned int i=0; i < fcm2ParticipantList.Size(); i++)
880 SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, fcm2ParticipantList[i]->rakNetGuid, false);
881
882 // Process immediately
883 // This is so if another ID_FCM2_VERIFIED_JOIN_CAPABLE is buffered, it responds with ID_FCM2_VERIFIED_JOIN_START
884 AddParticipant(packet->guid);
885
886 Packet *p = AllocatePacketUnified(bsOut.GetNumberOfBytesUsed());
887 memcpy(p->data, bsOut.GetData(), bsOut.GetNumberOfBytesUsed());
888 p->systemAddress=packet->systemAddress;
889 p->systemAddress.systemIndex=(SystemIndex)-1;
890 p->guid=packet->guid;
891 p->wasGeneratedLocally=true;
892 rakPeerInterface->PushBackPacket(p, true);
893 }
894 else
895 {
896 // Tell client rejected, otherwise process the same as ID_FCM2_VERIFIED_JOIN_FAILED
897 bsOut.Write((MessageID)ID_FCM2_VERIFIED_JOIN_REJECTED);
898 if (additionalData)
899 bsOut.Write(additionalData);
900 }
901
902 SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
903 }
904 void FullyConnectedMesh2::GetVerifiedJoinRequiredProcessingList(RakNetGUID host, DataStructures::List<SystemAddress> &addresses, DataStructures::List<RakNetGUID> &guids, DataStructures::List<BitStream*> &userData)
905 {
906 addresses.Clear(true, _FILE_AND_LINE_);
907 guids.Clear(true, _FILE_AND_LINE_);
908
909 unsigned int curIndex = GetJoinsInProgressIndex(host);
910 if (curIndex!=(unsigned int) -1)
911 {
912 VerifiedJoinInProgress *vjip = joinsInProgress[curIndex];
913 unsigned int j;
914 for (j=0; j < vjip->vjipMembers.Size(); j++)
915 {
916 if (vjip->vjipMembers[j].joinInProgressState==JIPS_PROCESSING)
917 {
918 addresses.Push(vjip->vjipMembers[j].systemAddress, _FILE_AND_LINE_);
919 guids.Push(vjip->vjipMembers[j].guid, _FILE_AND_LINE_);
920 userData.Push(vjip->vjipMembers[j].userData, _FILE_AND_LINE_);
921 }
922 }
923 }
924 }
925 void FullyConnectedMesh2::GetVerifiedJoinAcceptedAdditionalData(Packet *packet, bool *thisSystemAccepted, DataStructures::List<RakNetGUID> &systemsAccepted, BitStream *additionalData)
926 {
927 systemsAccepted.Clear(true, _FILE_AND_LINE_);
928
929 SLNet::BitStream bsIn(packet->data, packet->length, false);
930 bsIn.IgnoreBytes(sizeof(MessageID));
931 RakNetGUID systemToAddGuid;
932 bsIn.Read(systemToAddGuid);
933 *thisSystemAccepted = systemToAddGuid == rakPeerInterface->GetMyGUID();
934 unsigned short listSize;
935 bsIn.Read(listSize);
936 bsIn.IgnoreBytes(listSize*RakNetGUID::size());
937 bsIn.Read(listSize);
938 if (systemToAddGuid==rakPeerInterface->GetMyGUID())
939 {
940 for (unsigned short i=0; i < listSize; i++)
941 {
942 bsIn.Read(systemToAddGuid);
943 systemsAccepted.Push(systemToAddGuid, _FILE_AND_LINE_);
944 }
945 systemsAccepted.Push(packet->guid, _FILE_AND_LINE_);
946 }
947 else
948 {
949 systemsAccepted.Push(systemToAddGuid, _FILE_AND_LINE_);
950 bsIn.IgnoreBytes(listSize*RakNetGUID::size());
951 }
952 if (additionalData)
953 {
954 additionalData->Reset();
955 additionalData->Write(bsIn);
956 }
957 }
958 void FullyConnectedMesh2::GetVerifiedJoinRejectedAdditionalData(Packet *packet, BitStream *additionalData)
959 {
960 SLNet::BitStream bsIn(packet->data, packet->length, false);
961 bsIn.IgnoreBytes(sizeof(MessageID));
962 if (additionalData)
963 {
964 additionalData->Reset();
965 additionalData->Write(bsIn);
966 }
967 }
968 PluginReceiveResult FullyConnectedMesh2::OnVerifiedJoinStart(Packet *packet)
969 {
970 SLNet::BitStream bsIn(packet->data,packet->length,false);
971 bsIn.IgnoreBytes(sizeof(MessageID));
972
973 unsigned short listSize;
974 bsIn.Read(listSize);
975
976 unsigned int curIndex = GetJoinsInProgressIndex(packet->guid);
977 if (curIndex!=(unsigned int) -1)
978 {
979 // Got update to existing list
980
981 VerifiedJoinInProgress *vjip = joinsInProgress[curIndex];
982 // if (vjip->sentResults==false)
983 // {
984 // // Got ID_FCM2_VERIFIED_JOIN_START twice before sending ID_FCM2_VERIFIED_JOIN_CAPABLE
985 // RakAssert(vjip->sentResults!=false);
986 // return RR_STOP_PROCESSING_AND_DEALLOCATE;
987 // }
988
989 for (unsigned int i=0; i < vjip->vjipMembers.Size(); i++)
990 {
991 vjip->vjipMembers[i].workingFlag=false;
992 }
993
994 // Server has updated list of participants
995 for (unsigned short i=0; i < listSize; i++)
996 {
997 VerifiedJoinInProgressMember vjipm;
998 ReadVerifiedJoinInProgressMember(&bsIn, &vjipm);
999
1000 unsigned int j;
1001 if (vjipm.guid!=UNASSIGNED_RAKNET_GUID)
1002 j = GetVerifiedJoinInProgressMemberIndex(vjipm.guid, vjip);
1003 else
1004 j = GetVerifiedJoinInProgressMemberIndex(vjipm.systemAddress, vjip);
1005
1006 if (j==(unsigned int)-1)
1007 {
1008 // New
1009 vjipm.workingFlag=true;
1010
1011 // 11/13/2013 - ReadVerifiedJoinInProgressMember already sets joinInProgressState
1012 // http://www.jenkinssoftware.com/forum/index.php?topic=5211.0
1013 // vjipm.joinInProgressState=JIPS_PROCESSING;
1014 vjip->vjipMembers.Push(vjipm, _FILE_AND_LINE_);
1015
1016 // Allow resend of ID_FCM2_VERIFIED_JOIN_CAPABLE
1017 //vjip->sentResults=false;
1018 }
1019 else
1020 {
1021 vjip->vjipMembers[j].workingFlag=true;
1022 }
1023 }
1024
1025 for (unsigned int i=0; i < vjip->vjipMembers.Size(); i++)
1026 {
1027 if (vjip->vjipMembers[i].workingFlag==false)
1028 vjip->vjipMembers[i].joinInProgressState=JIPS_UNNECESSARY;
1029 }
1030
1031 if (ProcessVerifiedJoinInProgressIfCompleted(vjip))
1032 {
1033 // Completed
1034 return RR_STOP_PROCESSING_AND_DEALLOCATE;
1035 }
1036
1037 // Else tell user about new list
1038 return RR_CONTINUE_PROCESSING;
1039 }
1040
1041 VerifiedJoinInProgress *vjip = SLNet::OP_NEW<VerifiedJoinInProgress>(_FILE_AND_LINE_);
1042 vjip->requester=packet->guid;
1043 if (listSize==0)
1044 {
1045 //vjip->sentResults=true;
1046
1047 // Send back result
1048 SLNet::BitStream bsOut;
1049 bsOut.Write((MessageID)ID_FCM2_VERIFIED_JOIN_CAPABLE);
1050 bsOut.WriteCasted<unsigned short>(0);
1051 WriteVJCUserData(&bsOut);
1052 SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
1053 //vjip->sentResults=true;
1054 joinsInProgress.Push(vjip, _FILE_AND_LINE_);
1055 return RR_STOP_PROCESSING_AND_DEALLOCATE;
1056 }
1057
1058 //vjip->sentResults=false;
1059
1060 for (unsigned short i=0; i < listSize; i++)
1061 {
1062 VerifiedJoinInProgressMember vjipm;
1063 ReadVerifiedJoinInProgressMember(&bsIn, &vjipm);
1064 vjip->vjipMembers.Push(vjipm, _FILE_AND_LINE_);
1065 }
1066
1067 joinsInProgress.Push(vjip, _FILE_AND_LINE_);
1068
1069 // 11/13/2013 - ReadVerifiedJoinInProgressMember may set JIPS_CONNECTED, so this may already be done
1070 // http://www.jenkinssoftware.com/forum/index.php?topic=5211.0
1071 if (ProcessVerifiedJoinInProgressIfCompleted(vjip))
1072 {
1073 // Completed
1074 return RR_STOP_PROCESSING_AND_DEALLOCATE;
1075 }
1076
1077 return RR_CONTINUE_PROCESSING;
1078 }
1079 void FullyConnectedMesh2::SkipToVJCUserData(SLNet::BitStream *bsIn)
1080 {
1081 bsIn->IgnoreBytes(sizeof(MessageID));
1082 unsigned short listSize;
1083 bsIn->Read(listSize);
1084 for (unsigned short i=0; i < listSize; i++)
1085 {
1086 bsIn->IgnoreBytes(RakNetGUID::size());
1087 bsIn->IgnoreBytes(SystemAddress::size());
1088 bsIn->IgnoreBytes(sizeof(unsigned char));
1089 }
1090 }
1091 void FullyConnectedMesh2::DecomposeJoinCapable(Packet *packet, VerifiedJoinInProgress *vjip)
1092 {
1093 SLNet::BitStream bsIn(packet->data,packet->length,false);
1094 bsIn.IgnoreBytes(sizeof(MessageID));
1095
1096 unsigned short listSize;
1097 bsIn.Read(listSize);
1098
1099 for (unsigned short i=0; i < listSize; i++)
1100 {
1101 VerifiedJoinInProgressMember member;
1102 bsIn.Read(member.guid);
1103 bsIn.Read(member.systemAddress);
1104 bsIn.ReadCasted<unsigned char>(member.joinInProgressState);
1105 member.userData = 0;
1106 member.workingFlag=false;
1107 vjip->vjipMembers.Push(member, _FILE_AND_LINE_);
1108 }
1109 }
1110 PluginReceiveResult FullyConnectedMesh2::OnVerifiedJoinCapable(Packet *packet)
1111 {
1112 VerifiedJoinInProgress vjip;
1113 DecomposeJoinCapable(packet, &vjip);
1114
1115 // If this assert hits, AddParticipant() was called on this system, or another system, which it should not have been.
1116 RakAssert(HasParticipant(packet->guid)==false);
1117
1118 DataStructures::List<RakNetGUID> participatingMembersOnClientSucceeded;
1119 DataStructures::List<RakNetGUID> participatingMembersOnClientFailed;
1120 DataStructures::List<RakNetGUID> participatingMembersNotOnClient;
1121 DataStructures::List<RakNetGUID> clientMembersNotParticipatingSucceeded;
1122 DataStructures::List<RakNetGUID> clientMembersNotParticipatingFailed;
1123 CategorizeVJIP(&vjip,
1124 participatingMembersOnClientSucceeded,
1125 participatingMembersOnClientFailed,
1126 participatingMembersNotOnClient,
1127 clientMembersNotParticipatingSucceeded,
1128 clientMembersNotParticipatingFailed);
1129
1130 if (participatingMembersOnClientFailed.Size()>0)
1131 {
1132 // Send ID_FCM2_VERIFIED_JOIN_FAILED with GUIDs to disconnect
1133 BitStream bsOut;
1134 bsOut.Write((MessageID) ID_FCM2_VERIFIED_JOIN_FAILED);
1135 SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
1136 return RR_STOP_PROCESSING_AND_DEALLOCATE;
1137 }
1138
1139 if (participatingMembersNotOnClient.Size()>0)
1140 {
1141 BitStream bsOut;
1142 bsOut.Write((MessageID) ID_FCM2_VERIFIED_JOIN_START);
1143 bsOut.WriteCasted<unsigned short>(participatingMembersNotOnClient.Size());
1144 unsigned int i;
1145 for (i=0; i < participatingMembersNotOnClient.Size(); i++)
1146 {
1147 bsOut.Write(participatingMembersNotOnClient[i]);
1148 bsOut.Write(rakPeerInterface->GetSystemAddressFromGuid(participatingMembersNotOnClient[i]));
1149
1150 bool written=false;
1151 for (unsigned int j=0; j < fcm2ParticipantList.Size(); j++)
1152 {
1153 if (fcm2ParticipantList[j]->rakNetGuid == participatingMembersNotOnClient[i])
1154 {
1155 written=true;
1156
1157 BitStream vjsOut;
1158 //WriteVJSUserData(&vjsOut, fcm2ParticipantList[j]->rakNetGuid, &fcm2ParticipantList[j]->userContext );
1159 WriteVJSUserData(&vjsOut, fcm2ParticipantList[j]->rakNetGuid );
1160 bsOut.Write(vjsOut.GetNumberOfBitsUsed());
1161 bsOut.Write(&vjsOut);
1162 bsOut.AlignWriteToByteBoundary();
1163 break;
1164 }
1165 }
1166 RakAssert(written);
1167 }
1168 SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
1169 return RR_STOP_PROCESSING_AND_DEALLOCATE;
1170 }
1171
1172 // Let server decide if to accept or reject via RespondOnVerifiedJoinCapable
1173 return RR_CONTINUE_PROCESSING;
1174 }
1175 void FullyConnectedMesh2::OnVerifiedJoinFailed(RakNetGUID hostGuid, bool callCloseConnection)
1176 {
1177 unsigned int curIndex = GetJoinsInProgressIndex(hostGuid);
1178 if (curIndex==(unsigned int) -1)
1179 return;
1180
1181 if (callCloseConnection)
1182 {
1183 VerifiedJoinInProgress *vjip = joinsInProgress[curIndex];
1184 for (unsigned int j=0; j < vjip->vjipMembers.Size(); j++)
1185 {
1186 if (vjip->vjipMembers[j].joinInProgressState!=JIPS_FAILED)
1187 {
1188 rakPeerInterface->CloseConnection(vjip->vjipMembers[j].guid, true);
1189 }
1190
1191 if (vjip->vjipMembers[j].userData != 0)
1192 SLNet::OP_DELETE(vjip->vjipMembers[j].userData, _FILE_AND_LINE_);
1193 }
1194 }
1195
1196 for (unsigned int j=0; j < joinsInProgress[curIndex]->vjipMembers.Size(); j++)
1197 {
1198 if ( joinsInProgress[curIndex]->vjipMembers[j].userData != 0)
1199 {
1200 SLNet::OP_DELETE(joinsInProgress[curIndex]->vjipMembers[j].userData, _FILE_AND_LINE_);
1201 }
1202 }
1203
1204
1205 // Clear joinsInProgress for packet->guid
1206 SLNet::OP_DELETE(joinsInProgress[curIndex], _FILE_AND_LINE_);
1207 joinsInProgress.RemoveAtIndex(curIndex);
1208 }
1209 void FullyConnectedMesh2::OnVerifiedJoinAccepted(Packet *packet)
1210 {
1211 SLNet::BitStream bsIn(packet->data,packet->length,false);
1212 bsIn.IgnoreBytes(sizeof(MessageID));
1213
1214 RakNetGUID systemToAddGuid;
1215 bsIn.Read(systemToAddGuid);
1216
1217 if (systemToAddGuid==rakPeerInterface->GetMyGUID())
1218 {
1219 // My own system
1220 unsigned int curIndex = GetJoinsInProgressIndex(packet->guid);
1221 if (curIndex==(unsigned int)-1)
1222 return;
1223
1224 unsigned short listSize;
1225 bsIn.Read(listSize);
1226 for (unsigned short i=0; i < listSize; i++)
1227 {
1228 // List of clientMembersNotParticipatingSucceeded
1229 RakNetGUID guid;
1230 bsIn.Read(guid);
1231 rakPeerInterface->CloseConnection(guid, true);
1232 }
1233
1234 bsIn.Read(listSize);
1235 for (unsigned short i=0; i < listSize; i++)
1236 {
1237 // List of participatingMembersOnClientSucceeded
1238 RakNetGUID guid;
1239 bsIn.Read(guid);
1240 AddParticipant(guid);
1241 }
1242 AddParticipant(packet->guid);
1243
1244 for (unsigned int j=0; j < joinsInProgress[curIndex]->vjipMembers.Size(); j++)
1245 {
1246 if ( joinsInProgress[curIndex]->vjipMembers[j].userData != 0)
1247 {
1248 SLNet::OP_DELETE(joinsInProgress[curIndex]->vjipMembers[j].userData, _FILE_AND_LINE_);
1249 }
1250 }
1251
1252 // Clear joinsInProgress for packet->guid
1253 SLNet::OP_DELETE(joinsInProgress[curIndex], _FILE_AND_LINE_);
1254 joinsInProgress.RemoveAtIndex(curIndex);
1255 }
1256 else
1257 {
1258 // Another system
1259 ConnectionState cs = rakPeerInterface->GetConnectionState(systemToAddGuid);
1260 RakAssert(cs==IS_CONNECTED);
1261 if (cs==IS_CONNECTED)
1262 AddParticipant(systemToAddGuid);
1263 }
1264 }
1265 void FullyConnectedMesh2::OnVerifiedJoinRejected(Packet *packet)
1266 {
1267 OnVerifiedJoinFailed(packet->guid, true);
1268 }
1269 unsigned int FullyConnectedMesh2::GetJoinsInProgressIndex(RakNetGUID requester) const
1270 {
1271 for (unsigned int i=0; i < joinsInProgress.Size(); i++)
1272 {
1273 if (joinsInProgress[i]->requester==requester)
1274 return i;
1275 }
1276 return (unsigned int) -1;
1277 }
1278 void FullyConnectedMesh2::UpdateVerifiedJoinInProgressMember(const AddressOrGUID systemIdentifier, RakNetGUID guidToAssign, FullyConnectedMesh2::JoinInProgressState newState)
1279 {
1280 bool anythingChanged;
1281
1282 for (unsigned int i=0; i < joinsInProgress.Size(); i++)
1283 {
1284 VerifiedJoinInProgress *vjip = joinsInProgress[i];
1285 //if (vjip->sentResults==true)
1286 // continue;
1287 anythingChanged=false;
1288
1289 unsigned int j;
1290 j = GetVerifiedJoinInProgressMemberIndex(systemIdentifier, vjip);
1291 if (j!=(unsigned int)-1)
1292 {
1293 if (vjip->vjipMembers[j].guid==UNASSIGNED_RAKNET_GUID && guidToAssign!=UNASSIGNED_RAKNET_GUID)
1294 vjip->vjipMembers[j].guid = guidToAssign;
1295
1296 if (vjip->vjipMembers[j].joinInProgressState==JIPS_PROCESSING)
1297 {
1298 anythingChanged=true;
1299 vjip->vjipMembers[j].joinInProgressState=newState;
1300 }
1301 }
1302
1303 if (anythingChanged)
1304 {
1305 ProcessVerifiedJoinInProgressIfCompleted(vjip);
1306 }
1307 }
1308 }
1309 bool FullyConnectedMesh2::ProcessVerifiedJoinInProgressIfCompleted(VerifiedJoinInProgress *vjip)
1310 {
1311 //if (vjip->sentResults)
1312 // return true;
1313
1314 // If no systems in processing state, send results to server
1315 // Return true if this was done
1316 bool anyProcessing=false;
1317 for (unsigned int i=0; i < vjip->vjipMembers.Size(); i++)
1318 {
1319 if (vjip->vjipMembers[i].joinInProgressState==JIPS_PROCESSING)
1320 {
1321 anyProcessing=true;
1322 break;
1323 }
1324 }
1325
1326 if (anyProcessing==true)
1327 return false;
1328
1329 // Send results to server
1330 BitStream bsOut;
1331 WriteVerifiedJoinCapable(&bsOut, vjip);
1332 WriteVJCUserData(&bsOut);
1333 SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, vjip->requester, false);
1334
1335 //vjip->sentResults=true;
1336 return true;
1337 }
1338 void FullyConnectedMesh2::WriteVerifiedJoinCapable(SLNet::BitStream *bsOut, VerifiedJoinInProgress *vjip)
1339 {
1340 bsOut->Write((MessageID) ID_FCM2_VERIFIED_JOIN_CAPABLE);
1341 bsOut->WriteCasted<unsigned short>(vjip->vjipMembers.Size());
1342 unsigned int i;
1343 for (i=0; i < vjip->vjipMembers.Size(); i++)
1344 {
1345 bsOut->Write(vjip->vjipMembers[i].guid);
1346 bsOut->Write(vjip->vjipMembers[i].systemAddress);
1347 bsOut->WriteCasted<unsigned char>(vjip->vjipMembers[i].joinInProgressState);
1348 }
1349 }
1350
1351 void FullyConnectedMesh2::ReadVerifiedJoinInProgressMember(SLNet::BitStream *bsIn, VerifiedJoinInProgressMember *vjipm)
1352 {
1353 bsIn->Read(vjipm->guid);
1354 bsIn->Read(vjipm->systemAddress);
1355 ConnectionState cs = rakPeerInterface->GetConnectionState(vjipm->guid);
1356 if (cs==IS_CONNECTED)
1357 vjipm->joinInProgressState=JIPS_CONNECTED;
1358 else if (cs==IS_DISCONNECTING || cs==IS_SILENTLY_DISCONNECTING)
1359 vjipm->joinInProgressState=JIPS_FAILED;
1360 else
1361 vjipm->joinInProgressState=JIPS_PROCESSING;
1362
1363 BitSize_t vjsUserDataSize;
1364 bsIn->Read(vjsUserDataSize);
1365 if (vjsUserDataSize > 0)
1366 {
1367 vjipm->userData = SLNet::OP_NEW<BitStream>(_FILE_AND_LINE_);
1368 bsIn->Read(vjipm->userData, vjsUserDataSize);
1369 }
1370 else
1371 vjipm->userData = 0;
1372 bsIn->AlignReadToByteBoundary();
1373 }
1374
1375 unsigned int FullyConnectedMesh2::GetVerifiedJoinInProgressMemberIndex(const AddressOrGUID systemIdentifier, VerifiedJoinInProgress *vjip)
1376 {
1377 for (unsigned int j=0; j < vjip->vjipMembers.Size(); j++)
1378 {
1379 if ((systemIdentifier.rakNetGuid!=UNASSIGNED_RAKNET_GUID && vjip->vjipMembers[j].guid==systemIdentifier.rakNetGuid) ||
1380 (systemIdentifier.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS && vjip->vjipMembers[j].systemAddress==systemIdentifier.systemAddress))
1381 {
1382 return j;
1383 }
1384 }
1385 return (unsigned int) -1;
1386 }
1387
1388 void FullyConnectedMesh2::CategorizeVJIP(VerifiedJoinInProgress *vjip,
1389 DataStructures::List<RakNetGUID> &participatingMembersOnClientSucceeded,
1390 DataStructures::List<RakNetGUID> &participatingMembersOnClientFailed,
1391 DataStructures::List<RakNetGUID> &participatingMembersNotOnClient,
1392 DataStructures::List<RakNetGUID> &clientMembersNotParticipatingSucceeded,
1393 DataStructures::List<RakNetGUID> &clientMembersNotParticipatingFailed)
1394 {
1395 for (unsigned int i=0; i < vjip->vjipMembers.Size(); i++)
1396 vjip->vjipMembers[i].workingFlag=false;
1397
1398 for (unsigned int i=0; i < fcm2ParticipantList.Size(); i++)
1399 {
1400 unsigned int j = GetVerifiedJoinInProgressMemberIndex(fcm2ParticipantList[i]->rakNetGuid, vjip);
1401 if (j==(unsigned int)-1)
1402 {
1403 participatingMembersNotOnClient.Push(fcm2ParticipantList[i]->rakNetGuid, _FILE_AND_LINE_);
1404 }
1405 else
1406 {
1407 if (vjip->vjipMembers[j].joinInProgressState==JIPS_FAILED)
1408 participatingMembersOnClientFailed.Push(fcm2ParticipantList[i]->rakNetGuid, _FILE_AND_LINE_);
1409 else
1410 participatingMembersOnClientSucceeded.Push(fcm2ParticipantList[i]->rakNetGuid, _FILE_AND_LINE_);
1411 vjip->vjipMembers[j].workingFlag=true;
1412 }
1413 }
1414
1415
1416 for (unsigned int j=0; j < vjip->vjipMembers.Size(); j++)
1417 {
1418 if (vjip->vjipMembers[j].workingFlag==false)
1419 {
1420 if (vjip->vjipMembers[j].joinInProgressState==JIPS_FAILED)
1421 clientMembersNotParticipatingFailed.Push(vjip->vjipMembers[j].guid, _FILE_AND_LINE_);
1422 else
1423 clientMembersNotParticipatingSucceeded.Push(vjip->vjipMembers[j].guid, _FILE_AND_LINE_);
1424 }
1425 }
1426 }
1427
1428 #endif // _RAKNET_SUPPORT_*