1 #include "NativeFeatureIncludes.h"
2 #if _RAKNET_SUPPORT_ReadyEvent==1
3
4 #include "ReadyEvent.h"
5 #include "RakPeerInterface.h"
6 #include "BitStream.h"
7 #include "MessageIdentifiers.h"
8 #include "RakAssert.h"
9
10 #ifdef _MSC_VER
11 #pragma warning( push )
12 #endif
13
RemoteSystemCompBySystemAddress(const SystemAddress & key,const RemoteSystem & data)14 int ReadyEvent::RemoteSystemCompBySystemAddress( const SystemAddress &key, const RemoteSystem &data )
15 {
16 if (key < data.systemAddress)
17 return -1;
18 else if (key==data.systemAddress)
19 return 0;
20 else
21 return 1;
22 }
23
ReadyEventNodeComp(const int & key,ReadyEvent::ReadyEventNode * const & data)24 int ReadyEvent::ReadyEventNodeComp( const int &key, ReadyEvent::ReadyEventNode * const &data )
25 {
26 if (key < data->eventId)
27 return -1;
28 else if (key==data->eventId)
29 return 0;
30 else
31 return 1;
32 }
33
34
ReadyEvent()35 ReadyEvent::ReadyEvent()
36 {
37 channel=0;
38 }
39
~ReadyEvent()40 ReadyEvent::~ReadyEvent()
41 {
42 Clear();
43 }
44
45
SetEvent(int eventId,bool isReady)46 bool ReadyEvent::SetEvent(int eventId, bool isReady)
47 {
48 bool objectExists;
49 unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
50 if (objectExists==false)
51 {
52 // Totally new event
53 CreateNewEvent(eventId, isReady);
54 }
55 else
56 {
57 return SetEventByIndex(eventIndex, isReady);
58 }
59 return true;
60 }
ForceCompletion(int eventId)61 bool ReadyEvent::ForceCompletion(int eventId)
62 {
63 bool objectExists;
64 unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
65 if (objectExists==false)
66 {
67 // Totally new event
68 CreateNewEvent(eventId, true);
69 eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
70 }
71
72 ReadyEventNode *ren = readyEventNodeList[eventIndex];
73 ren->eventStatus=ID_READY_EVENT_FORCE_ALL_SET;
74 UpdateReadyStatus(eventIndex);
75
76 return true;
77 }
DeleteEvent(int eventId)78 bool ReadyEvent::DeleteEvent(int eventId)
79 {
80 bool objectExists;
81 unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
82 if (objectExists)
83 {
84 RakNet::OP_DELETE(readyEventNodeList[eventIndex], __FILE__, __LINE__);
85 readyEventNodeList.RemoveAtIndex(eventIndex);
86 return true;
87 }
88 return false;
89 }
IsEventSet(int eventId)90 bool ReadyEvent::IsEventSet(int eventId)
91 {
92 bool objectExists;
93 unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
94 if (objectExists)
95 {
96 return readyEventNodeList[eventIndex]->eventStatus==ID_READY_EVENT_SET || readyEventNodeList[eventIndex]->eventStatus==ID_READY_EVENT_ALL_SET;
97 }
98 return false;
99 }
IsEventCompletionProcessing(int eventId) const100 bool ReadyEvent::IsEventCompletionProcessing(int eventId) const
101 {
102 bool objectExists;
103 unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
104 if (objectExists)
105 {
106 bool anyAllReady=false;
107 bool allAllReady=true;
108 ReadyEventNode *ren = readyEventNodeList[eventIndex];
109 if (ren->eventStatus==ID_READY_EVENT_FORCE_ALL_SET)
110 return false;
111 for (unsigned i=0; i < ren->systemList.Size(); i++)
112 {
113 if (ren->systemList[i].lastReceivedStatus==ID_READY_EVENT_ALL_SET)
114 anyAllReady=true;
115 else
116 allAllReady=false;
117 }
118 return anyAllReady==true && allAllReady==false;
119 }
120 return false;
121 }
IsEventCompleted(int eventId) const122 bool ReadyEvent::IsEventCompleted(int eventId) const
123 {
124 bool objectExists;
125 unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
126 if (objectExists)
127 {
128 return IsEventCompletedByIndex(eventIndex);
129 }
130 return false;
131 }
132
HasEvent(int eventId)133 bool ReadyEvent::HasEvent(int eventId)
134 {
135 return readyEventNodeList.HasData(eventId);
136 }
137
GetEventListSize(void) const138 unsigned ReadyEvent::GetEventListSize(void) const
139 {
140 return readyEventNodeList.Size();
141 }
142
GetEventAtIndex(unsigned index) const143 int ReadyEvent::GetEventAtIndex(unsigned index) const
144 {
145 return readyEventNodeList[index]->eventId;
146 }
147
AddToWaitList(int eventId,SystemAddress address)148 bool ReadyEvent::AddToWaitList(int eventId, SystemAddress address)
149 {
150 bool eventExists;
151 unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &eventExists);
152 if (eventExists==false)
153 eventIndex=CreateNewEvent(eventId, false);
154
155 // Don't do this, otherwise if we are trying to start a 3 player game, it will not allow the 3rd player to hit ready if the first two players have already done so
156 //if (IsLocked(eventIndex))
157 // return false; // Not in the list, but event is already completed, or is starting to complete, and adding more waiters would fail this.
158
159 unsigned i;
160 unsigned numAdded=0;
161 if (address==UNASSIGNED_SYSTEM_ADDRESS)
162 {
163 for (i=0; i < rakPeerInterface->GetMaximumNumberOfPeers(); i++)
164 {
165 SystemAddress internalAddress = rakPeerInterface->GetSystemAddressFromIndex(i);
166 if (internalAddress!=UNASSIGNED_SYSTEM_ADDRESS)
167 {
168 numAdded+=AddToWaitListInternal(eventIndex, internalAddress);
169 }
170 }
171 }
172 else
173 {
174 numAdded=AddToWaitListInternal(eventIndex, address);
175 }
176
177 if (numAdded>0)
178 UpdateReadyStatus(eventIndex);
179 return numAdded>0;
180 }
RemoveFromWaitList(int eventId,SystemAddress address)181 bool ReadyEvent::RemoveFromWaitList(int eventId, SystemAddress address)
182 {
183 bool eventExists;
184 unsigned eventIndex = readyEventNodeList.GetIndexFromKey(eventId, &eventExists);
185 if (eventExists)
186 {
187 if (address==UNASSIGNED_SYSTEM_ADDRESS)
188 {
189 // Remove all waiters
190 readyEventNodeList[eventIndex]->systemList.Clear(false, __FILE__, __LINE__);
191 UpdateReadyStatus(eventIndex);
192 }
193 else
194 {
195 bool systemExists;
196 unsigned systemIndex = readyEventNodeList[eventIndex]->systemList.GetIndexFromKey(address, &systemExists);
197 if (systemExists)
198 {
199 bool isCompleted = IsEventCompletedByIndex(eventIndex);
200 readyEventNodeList[eventIndex]->systemList.RemoveAtIndex(systemIndex);
201
202 if (isCompleted==false && IsEventCompletedByIndex(eventIndex))
203 PushCompletionPacket(readyEventNodeList[eventIndex]->eventId);
204
205 UpdateReadyStatus(eventIndex);
206
207 return true;
208 }
209 }
210 }
211
212 return false;
213 }
IsInWaitList(int eventId,SystemAddress address)214 bool ReadyEvent::IsInWaitList(int eventId, SystemAddress address)
215 {
216 bool objectExists;
217 unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
218 if (objectExists)
219 {
220 return readyEventNodeList[readyIndex]->systemList.HasData(address);
221 }
222 return false;
223 }
224
GetRemoteWaitListSize(int eventId) const225 unsigned ReadyEvent::GetRemoteWaitListSize(int eventId) const
226 {
227 bool objectExists;
228 unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
229 if (objectExists)
230 {
231 return readyEventNodeList[readyIndex]->systemList.Size();
232 }
233 return 0;
234 }
235
GetFromWaitListAtIndex(int eventId,unsigned index) const236 SystemAddress ReadyEvent::GetFromWaitListAtIndex(int eventId, unsigned index) const
237 {
238 bool objectExists;
239 unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
240 if (objectExists)
241 {
242 return readyEventNodeList[readyIndex]->systemList[index].systemAddress;
243 }
244 return UNASSIGNED_SYSTEM_ADDRESS;
245 }
GetReadyStatus(int eventId,SystemAddress address)246 ReadyEventSystemStatus ReadyEvent::GetReadyStatus(int eventId, SystemAddress address)
247 {
248 bool objectExists;
249 unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
250 if (objectExists)
251 {
252 ReadyEventNode *ren = readyEventNodeList[readyIndex];
253 unsigned systemIndex = ren->systemList.GetIndexFromKey(address, &objectExists);
254 if (objectExists==false)
255 return RES_NOT_WAITING;
256 if (ren->systemList[systemIndex].lastReceivedStatus==ID_READY_EVENT_SET)
257 return RES_READY;
258 if (ren->systemList[systemIndex].lastReceivedStatus==ID_READY_EVENT_UNSET)
259 return RES_WAITING;
260 if (ren->systemList[systemIndex].lastReceivedStatus==ID_READY_EVENT_ALL_SET)
261 return RES_ALL_READY;
262 }
263
264 return RES_UNKNOWN_EVENT;
265 }
SetSendChannel(unsigned char newChannel)266 void ReadyEvent::SetSendChannel(unsigned char newChannel)
267 {
268 channel=newChannel;
269 }
OnReceive(Packet * packet)270 PluginReceiveResult ReadyEvent::OnReceive(Packet *packet)
271 {
272 unsigned char packetIdentifier;
273 packetIdentifier = ( unsigned char ) packet->data[ 0 ];
274
275 // bool doPrint = packet->systemAddress.port==60002 || rakPeerInterface->GetInternalID(UNASSIGNED_SYSTEM_ADDRESS).port==60002;
276
277 switch (packetIdentifier)
278 {
279 case ID_READY_EVENT_UNSET:
280 case ID_READY_EVENT_SET:
281 case ID_READY_EVENT_ALL_SET:
282 // if (doPrint) {if (packet->systemAddress.port==60002) RAKNET_DEBUG_PRINTF("FROM 60002: "); else if (rakPeerInterface->GetInternalID(UNASSIGNED_SYSTEM_ADDRESS).port==60002) RAKNET_DEBUG_PRINTF("TO 60002: "); RAKNET_DEBUG_PRINTF("ID_READY_EVENT_SET\n");}
283 OnReadyEventPacketUpdate(packet);
284 return RR_CONTINUE_PROCESSING;
285 case ID_READY_EVENT_FORCE_ALL_SET:
286 OnReadyEventForceAllSet(packet);
287 return RR_CONTINUE_PROCESSING;
288 case ID_READY_EVENT_QUERY:
289 // if (doPrint) {if (packet->systemAddress.port==60002) RAKNET_DEBUG_PRINTF("FROM 60002: "); else if (rakPeerInterface->GetInternalID(UNASSIGNED_SYSTEM_ADDRESS).port==60002) RAKNET_DEBUG_PRINTF("TO 60002: "); RAKNET_DEBUG_PRINTF("ID_READY_EVENT_QUERY\n");}
290 OnReadyEventQuery(packet);
291 return RR_STOP_PROCESSING_AND_DEALLOCATE;
292 }
293
294 return RR_CONTINUE_PROCESSING;
295 }
AddToWaitListInternal(unsigned eventIndex,SystemAddress address)296 bool ReadyEvent::AddToWaitListInternal(unsigned eventIndex, SystemAddress address)
297 {
298 ReadyEventNode *ren = readyEventNodeList[eventIndex];
299 bool objectExists;
300 unsigned systemIndex = ren->systemList.GetIndexFromKey(address, &objectExists);
301 if (objectExists==false)
302 {
303 RemoteSystem rs;
304 rs.lastReceivedStatus=ID_READY_EVENT_UNSET;
305 rs.lastSentStatus=ID_READY_EVENT_UNSET;
306 rs.systemAddress=address;
307 ren->systemList.InsertAtIndex(rs,systemIndex, __FILE__,__LINE__);
308
309 SendReadyStateQuery(ren->eventId, address);
310 return true;
311 }
312 return false;
313 }
OnReadyEventForceAllSet(Packet * packet)314 void ReadyEvent::OnReadyEventForceAllSet(Packet *packet)
315 {
316 RakNet::BitStream incomingBitStream(packet->data, packet->length, false);
317 incomingBitStream.IgnoreBits(8);
318 int eventId;
319 incomingBitStream.Read(eventId);
320 bool objectExists;
321 unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
322 if (objectExists)
323 {
324 ReadyEventNode *ren = readyEventNodeList[readyIndex];
325 if (ren->eventStatus!=ID_READY_EVENT_FORCE_ALL_SET)
326 {
327 ren->eventStatus=ID_READY_EVENT_FORCE_ALL_SET;
328 PushCompletionPacket(ren->eventId);
329 }
330 }
331 }
OnReadyEventPacketUpdate(Packet * packet)332 void ReadyEvent::OnReadyEventPacketUpdate(Packet *packet)
333 {
334 RakNet::BitStream incomingBitStream(packet->data, packet->length, false);
335 incomingBitStream.IgnoreBits(8);
336 int eventId;
337 incomingBitStream.Read(eventId);
338 bool objectExists;
339 unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
340 if (objectExists)
341 {
342 ReadyEventNode *ren = readyEventNodeList[readyIndex];
343 bool systemExists;
344 unsigned systemIndex = ren->systemList.GetIndexFromKey(packet->systemAddress, &systemExists);
345 if (systemExists)
346 {
347 // Just return if no change
348 if (ren->systemList[systemIndex].lastReceivedStatus==packet->data[0])
349 return;
350
351 bool wasCompleted = IsEventCompletedByIndex(readyIndex);
352 ren->systemList[systemIndex].lastReceivedStatus=packet->data[0];
353 // If forced all set, doesn't matter what the new packet is
354 if (ren->eventStatus==ID_READY_EVENT_FORCE_ALL_SET)
355 return;
356 UpdateReadyStatus(readyIndex);
357 if (wasCompleted==false && IsEventCompletedByIndex(readyIndex))
358 PushCompletionPacket(readyIndex);
359 }
360 }
361 }
OnReadyEventQuery(Packet * packet)362 void ReadyEvent::OnReadyEventQuery(Packet *packet)
363 {
364 RakNet::BitStream incomingBitStream(packet->data, packet->length, false);
365 incomingBitStream.IgnoreBits(8);
366 int eventId;
367 incomingBitStream.Read(eventId);
368 bool objectExists;
369 unsigned readyIndex = readyEventNodeList.GetIndexFromKey(eventId, &objectExists);
370 if (objectExists)
371 {
372 unsigned systemIndex = readyEventNodeList[readyIndex]->systemList.GetIndexFromKey(packet->systemAddress,&objectExists);
373 // Force the non-default send, because our initial send may have arrived at a system that didn't yet create the ready event
374 if (objectExists)
375 SendReadyUpdate(readyIndex, systemIndex, true);
376 }
377 }
OnClosedConnection(SystemAddress systemAddress,RakNetGUID rakNetGUID,PI2_LostConnectionReason lostConnectionReason)378 void ReadyEvent::OnClosedConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
379 {
380 (void) systemAddress;
381 (void) rakNetGUID;
382 (void) lostConnectionReason;
383
384 RemoveFromAllLists(systemAddress);
385 }
OnRakPeerShutdown(void)386 void ReadyEvent::OnRakPeerShutdown(void)
387 {
388 Clear();
389 }
390
SetEventByIndex(int eventIndex,bool isReady)391 bool ReadyEvent::SetEventByIndex(int eventIndex, bool isReady)
392 {
393 ReadyEventNode *ren = readyEventNodeList[eventIndex];
394 if ((ren->eventStatus==ID_READY_EVENT_ALL_SET || ren->eventStatus==ID_READY_EVENT_SET) && isReady==true)
395 return true; // Success - no change
396 if (ren->eventStatus==ID_READY_EVENT_UNSET && isReady==false)
397 return true; // Success - no change
398 if (ren->eventStatus==ID_READY_EVENT_FORCE_ALL_SET)
399 return true; // Can't change
400
401 if (isReady)
402 ren->eventStatus=ID_READY_EVENT_SET;
403 else
404 ren->eventStatus=ID_READY_EVENT_UNSET;
405
406 UpdateReadyStatus(eventIndex);
407
408 // Check if now completed, and if so, tell the user about it
409 if (IsEventCompletedByIndex(eventIndex))
410 {
411 PushCompletionPacket(ren->eventId);
412 }
413
414 return true;
415 }
416
IsEventCompletedByIndex(unsigned eventIndex) const417 bool ReadyEvent::IsEventCompletedByIndex(unsigned eventIndex) const
418 {
419 ReadyEventNode *ren = readyEventNodeList[eventIndex];
420 unsigned i;
421 if (ren->eventStatus==ID_READY_EVENT_FORCE_ALL_SET)
422 return true;
423 if (ren->eventStatus!=ID_READY_EVENT_ALL_SET)
424 return false;
425 for (i=0; i < ren->systemList.Size(); i++)
426 if (ren->systemList[i].lastReceivedStatus!=ID_READY_EVENT_ALL_SET)
427 return false;
428 return true;
429 }
430
Clear(void)431 void ReadyEvent::Clear(void)
432 {
433 unsigned i;
434 for (i=0; i < readyEventNodeList.Size(); i++)
435 {
436 RakNet::OP_DELETE(readyEventNodeList[i], __FILE__, __LINE__);
437 }
438 readyEventNodeList.Clear(false, __FILE__, __LINE__);
439 }
440
CreateNewEvent(int eventId,bool isReady)441 unsigned ReadyEvent::CreateNewEvent(int eventId, bool isReady)
442 {
443 ReadyEventNode *ren = RakNet::OP_NEW<ReadyEventNode>( __FILE__, __LINE__ );
444 ren->eventId=eventId;
445 if (isReady==false)
446 ren->eventStatus=ID_READY_EVENT_UNSET;
447 else
448 ren->eventStatus=ID_READY_EVENT_SET;
449 return readyEventNodeList.Insert(eventId, ren, true, __FILE__,__LINE__);
450 }
UpdateReadyStatus(unsigned eventIndex)451 void ReadyEvent::UpdateReadyStatus(unsigned eventIndex)
452 {
453 ReadyEventNode *ren = readyEventNodeList[eventIndex];
454 bool anyUnset;
455 unsigned i;
456 if (ren->eventStatus==ID_READY_EVENT_SET)
457 {
458 // If you are set, and no other systems are ID_READY_EVENT_UNSET, then change your status to ID_READY_EVENT_ALL_SET
459 anyUnset=false;
460 for (i=0; i < ren->systemList.Size(); i++)
461 {
462 if (ren->systemList[i].lastReceivedStatus==ID_READY_EVENT_UNSET)
463 {
464 anyUnset=true;
465 break;
466 }
467 }
468 if (anyUnset==false)
469 {
470 ren->eventStatus=ID_READY_EVENT_ALL_SET;
471 }
472 }
473 else if (ren->eventStatus==ID_READY_EVENT_ALL_SET)
474 {
475 // If you are all set, and any systems are ID_READY_EVENT_UNSET, then change your status to ID_READY_EVENT_SET
476 anyUnset=false;
477 for (i=0; i < ren->systemList.Size(); i++)
478 {
479 if (ren->systemList[i].lastReceivedStatus==ID_READY_EVENT_UNSET)
480 {
481 anyUnset=true;
482 break;
483 }
484 }
485 if (anyUnset==true)
486 {
487 ren->eventStatus=ID_READY_EVENT_SET;
488 }
489 }
490 BroadcastReadyUpdate(eventIndex, false);
491 }
SendReadyUpdate(unsigned eventIndex,unsigned systemIndex,bool forceIfNotDefault)492 void ReadyEvent::SendReadyUpdate(unsigned eventIndex, unsigned systemIndex, bool forceIfNotDefault)
493 {
494 ReadyEventNode *ren = readyEventNodeList[eventIndex];
495 RakNet::BitStream bs;
496 // I do this rather than write true or false, so users that do not use BitStreams can still read the data
497 if ((ren->eventStatus!=ren->systemList[systemIndex].lastSentStatus) ||
498 (forceIfNotDefault && ren->eventStatus!=ID_READY_EVENT_UNSET))
499 {
500 bs.Write(ren->eventStatus);
501 bs.Write(ren->eventId);
502 SendUnified(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, channel, ren->systemList[systemIndex].systemAddress, false);
503
504 ren->systemList[systemIndex].lastSentStatus=ren->eventStatus;
505 }
506
507 }
BroadcastReadyUpdate(unsigned eventIndex,bool forceIfNotDefault)508 void ReadyEvent::BroadcastReadyUpdate(unsigned eventIndex, bool forceIfNotDefault)
509 {
510 ReadyEventNode *ren = readyEventNodeList[eventIndex];
511 unsigned systemIndex;
512 for (systemIndex=0; systemIndex < ren->systemList.Size(); systemIndex++)
513 {
514 SendReadyUpdate(eventIndex, systemIndex, forceIfNotDefault);
515 }
516 }
SendReadyStateQuery(unsigned eventId,SystemAddress address)517 void ReadyEvent::SendReadyStateQuery(unsigned eventId, SystemAddress address)
518 {
519 RakNet::BitStream bs;
520 bs.Write((MessageID)ID_READY_EVENT_QUERY);
521 bs.Write(eventId);
522 SendUnified(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, channel, address, false);
523 }
RemoveFromAllLists(SystemAddress address)524 void ReadyEvent::RemoveFromAllLists(SystemAddress address)
525 {
526 unsigned eventIndex;
527 for (eventIndex=0; eventIndex < readyEventNodeList.Size(); eventIndex++)
528 {
529 bool isCompleted = IsEventCompletedByIndex(eventIndex);
530 bool systemExists;
531 unsigned systemIndex;
532
533 systemIndex = readyEventNodeList[eventIndex]->systemList.GetIndexFromKey(address, &systemExists);
534 if (systemExists)
535 readyEventNodeList[eventIndex]->systemList.RemoveAtIndex(systemIndex);
536
537 UpdateReadyStatus(eventIndex);
538
539 if (isCompleted==false && IsEventCompletedByIndex(eventIndex))
540 PushCompletionPacket(readyEventNodeList[eventIndex]->eventId);
541 }
542 }
PushCompletionPacket(unsigned eventId)543 void ReadyEvent::PushCompletionPacket(unsigned eventId)
544 {
545 (void) eventId;
546 // Not necessary
547 /*
548 // Pass a packet to the user that we are now completed, as setting ourselves to signaled was the last thing being waited on
549 Packet *p = rakPeerInterface->AllocatePacket(sizeof(MessageID)+sizeof(int));
550 RakNet::BitStream bs(p->data, sizeof(MessageID)+sizeof(int), false);
551 bs.SetWriteOffset(0);
552 bs.Write((MessageID)ID_READY_EVENT_ALL_SET);
553 bs.Write(eventId);
554 rakPeerInterface->PushBackPacket(p, false);
555 */
556 }
557 #ifdef _MSC_VER
558 #pragma warning( pop )
559 #endif
560
561 #endif // _RAKNET_SUPPORT_*
562