netEvent.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "network/connectionProtocol.h"
  24. #include "sim/simBase.h"
  25. #include "network/netConnection.h"
  26. #include "io/bitStream.h"
  27. #define DebugChecksum 0xF00DBAAD
  28. FreeListChunker<NetEventNote> NetConnection::mEventNoteChunker;
  29. NetEvent::~NetEvent()
  30. {
  31. AssertWarn(mRefCount == 0, "NetEvent::~NetEvent - encountered non-zero ref count!");
  32. }
  33. void NetEvent::notifyDelivered(NetConnection *, bool)
  34. {
  35. }
  36. void NetEvent::notifySent(NetConnection *)
  37. {
  38. }
  39. #ifdef TORQUE_DEBUG_NET
  40. const char *NetEvent::getDebugName()
  41. {
  42. return getClassName();
  43. }
  44. #endif
  45. void NetConnection::eventOnRemove()
  46. {
  47. while(mNotifyEventList)
  48. {
  49. NetEventNote *temp = mNotifyEventList;
  50. mNotifyEventList = temp->mNextEvent;
  51. temp->mEvent->notifyDelivered(this, true);
  52. temp->mEvent->decRef();
  53. mEventNoteChunker.free(temp);
  54. }
  55. while(mUnorderedSendEventQueueHead)
  56. {
  57. NetEventNote *temp = mUnorderedSendEventQueueHead;
  58. mUnorderedSendEventQueueHead = temp->mNextEvent;
  59. temp->mEvent->notifyDelivered(this, true);
  60. temp->mEvent->decRef();
  61. mEventNoteChunker.free(temp);
  62. }
  63. while(mSendEventQueueHead)
  64. {
  65. NetEventNote *temp = mSendEventQueueHead;
  66. mSendEventQueueHead = temp->mNextEvent;
  67. temp->mEvent->notifyDelivered(this, true);
  68. temp->mEvent->decRef();
  69. mEventNoteChunker.free(temp);
  70. }
  71. }
  72. void NetConnection::eventPacketDropped(PacketNotify *notify)
  73. {
  74. NetEventNote *walk = notify->eventList;
  75. NetEventNote **insertList = &mSendEventQueueHead;
  76. NetEventNote *temp;
  77. while(walk)
  78. {
  79. switch(walk->mEvent->mGuaranteeType)
  80. {
  81. // It was a guaranteed ordered packet, reinsert it back into
  82. // mSendEventQueueHead in the right place (based on seq numbers)
  83. case NetEvent::GuaranteedOrdered:
  84. //Con::printf("EVT %d: DROP - %d", getId(), walk->mSeqCount);
  85. while(*insertList && (*insertList)->mSeqCount < walk->mSeqCount)
  86. insertList = &((*insertList)->mNextEvent);
  87. temp = walk->mNextEvent;
  88. walk->mNextEvent = *insertList;
  89. if(!walk->mNextEvent)
  90. mSendEventQueueTail = walk;
  91. *insertList = walk;
  92. insertList = &(walk->mNextEvent);
  93. walk = temp;
  94. break;
  95. // It was a guaranteed packet, put it at the top of
  96. // mUnorderedSendEventQueueHead.
  97. case NetEvent::Guaranteed:
  98. temp = walk->mNextEvent;
  99. walk->mNextEvent = mUnorderedSendEventQueueHead;
  100. mUnorderedSendEventQueueHead = walk;
  101. if(!walk->mNextEvent)
  102. mUnorderedSendEventQueueTail = walk;
  103. walk = temp;
  104. break;
  105. // Or else it was an unguaranteed packet, notify that
  106. // it was _not_ delivered and blast it.
  107. case NetEvent::Unguaranteed:
  108. walk->mEvent->notifyDelivered(this, false);
  109. walk->mEvent->decRef();
  110. temp = walk->mNextEvent;
  111. mEventNoteChunker.free(walk);
  112. walk = temp;
  113. }
  114. }
  115. }
  116. void NetConnection::eventPacketReceived(PacketNotify *notify)
  117. {
  118. NetEventNote *walk = notify->eventList;
  119. NetEventNote **noteList = &mNotifyEventList;
  120. while(walk)
  121. {
  122. NetEventNote *next = walk->mNextEvent;
  123. if(walk->mEvent->mGuaranteeType != NetEvent::GuaranteedOrdered)
  124. {
  125. walk->mEvent->notifyDelivered(this, true);
  126. walk->mEvent->decRef();
  127. mEventNoteChunker.free(walk);
  128. walk = next;
  129. }
  130. else
  131. {
  132. while(*noteList && (*noteList)->mSeqCount < walk->mSeqCount)
  133. noteList = &((*noteList)->mNextEvent);
  134. walk->mNextEvent = *noteList;
  135. *noteList = walk;
  136. noteList = &walk->mNextEvent;
  137. walk = next;
  138. }
  139. }
  140. while(mNotifyEventList && mNotifyEventList->mSeqCount == mLastAckedEventSeq + 1)
  141. {
  142. mLastAckedEventSeq++;
  143. NetEventNote *next = mNotifyEventList->mNextEvent;
  144. //Con::printf("EVT %d: ACK - %d", getId(), mNotifyEventList->mSeqCount);
  145. mNotifyEventList->mEvent->notifyDelivered(this, true);
  146. mNotifyEventList->mEvent->decRef();
  147. mEventNoteChunker.free(mNotifyEventList);
  148. mNotifyEventList = next;
  149. }
  150. }
  151. void NetConnection::eventWritePacket(BitStream *bstream, PacketNotify *notify)
  152. {
  153. #ifdef TORQUE_DEBUG_NET
  154. bstream->writeInt(DebugChecksum, 32);
  155. #endif
  156. NetEventNote *packQueueHead = NULL, *packQueueTail = NULL;
  157. while(mUnorderedSendEventQueueHead)
  158. {
  159. if(bstream->isFull())
  160. break;
  161. // dequeue the first event
  162. NetEventNote *ev = mUnorderedSendEventQueueHead;
  163. mUnorderedSendEventQueueHead = ev->mNextEvent;
  164. bstream->writeFlag(true);
  165. S32 classId = ev->mEvent->getClassId(getNetClassGroup());
  166. bstream->writeClassId(classId, NetClassTypeEvent, getNetClassGroup());
  167. ev->mEvent->pack(this, bstream);
  168. DEBUG_LOG(("PKLOG %d EVENT %d: %s", getId(), bstream->getCurPos() - start, ev->mEvent->getDebugName()) );
  169. #ifdef TORQUE_DEBUG_NET
  170. bstream->writeInt(classId ^ DebugChecksum, 32);
  171. #endif
  172. // add this event onto the packet queue
  173. ev->mNextEvent = NULL;
  174. if(!packQueueHead)
  175. packQueueHead = ev;
  176. else
  177. packQueueTail->mNextEvent = ev;
  178. packQueueTail = ev;
  179. }
  180. bstream->writeFlag(false);
  181. S32 prevSeq = -2;
  182. while(mSendEventQueueHead)
  183. {
  184. if(bstream->isFull())
  185. break;
  186. // if the event window is full, stop processing
  187. if(mSendEventQueueHead->mSeqCount > mLastAckedEventSeq + 126)
  188. break;
  189. // dequeue the first event
  190. NetEventNote *ev = mSendEventQueueHead;
  191. mSendEventQueueHead = ev->mNextEvent;
  192. //Con::printf("EVT %d: SEND - %d", getId(), ev->mSeqCount);
  193. bstream->writeFlag(true);
  194. ev->mNextEvent = NULL;
  195. if(!packQueueHead)
  196. packQueueHead = ev;
  197. else
  198. packQueueTail->mNextEvent = ev;
  199. packQueueTail = ev;
  200. if(!bstream->writeFlag(ev->mSeqCount == prevSeq + 1))
  201. bstream->writeInt(ev->mSeqCount, 7);
  202. prevSeq = ev->mSeqCount;
  203. S32 classId = ev->mEvent->getClassId(getNetClassGroup());
  204. bstream->writeClassId(classId, NetClassTypeEvent, getNetClassGroup());
  205. ev->mEvent->pack(this, bstream);
  206. DEBUG_LOG(("PKLOG %d EVENT %d: %s", getId(), bstream->getCurPos() - start, ev->mEvent->getDebugName()) );
  207. #ifdef TORQUE_DEBUG_NET
  208. bstream->writeInt(classId ^ DebugChecksum, 32);
  209. #endif
  210. }
  211. for(NetEventNote *ev = packQueueHead; ev; ev = ev->mNextEvent)
  212. ev->mEvent->notifySent(this);
  213. notify->eventList = packQueueHead;
  214. bstream->writeFlag(0);
  215. }
  216. void NetConnection::eventReadPacket(BitStream *bstream)
  217. {
  218. #ifdef TORQUE_DEBUG_NET
  219. U32 sum = bstream->readInt(32);
  220. AssertISV(sum == DebugChecksum, "Invalid checksum.");
  221. #endif
  222. S32 prevSeq = -2;
  223. NetEventNote **waitInsert = &mWaitSeqEvents;
  224. bool unguaranteedPhase = true;
  225. while(true)
  226. {
  227. bool bit = bstream->readFlag();
  228. if(unguaranteedPhase && !bit)
  229. {
  230. unguaranteedPhase = false;
  231. bit = bstream->readFlag();
  232. }
  233. if(!unguaranteedPhase && !bit)
  234. break;
  235. S32 seq = -1;
  236. if(!unguaranteedPhase) // get the sequence
  237. {
  238. if(bstream->readFlag())
  239. seq = (prevSeq + 1) & 0x7f;
  240. else
  241. seq = bstream->readInt(7);
  242. prevSeq = seq;
  243. }
  244. S32 classId = bstream->readClassId(NetClassTypeEvent, getNetClassGroup());
  245. if(classId == -1)
  246. {
  247. setLastError("Invalid packet.");
  248. return;
  249. }
  250. NetEvent *evt = (NetEvent *) ConsoleObject::create(getNetClassGroup(), NetClassTypeEvent, classId);
  251. if(!evt)
  252. {
  253. setLastError("Invalid packet.");
  254. return;
  255. }
  256. AbstractClassRep *rep = evt->getClassRep();
  257. if((rep->mNetEventDir == NetEventDirServerToClient && !isConnectionToServer())
  258. || (rep->mNetEventDir == NetEventDirClientToServer && isConnectionToServer()) )
  259. {
  260. setLastError("Invalid Packet.");
  261. return;
  262. }
  263. evt->mSourceId = getId();
  264. evt->unpack(this, bstream);
  265. if(mErrorBuffer[0])
  266. return;
  267. #ifdef TORQUE_DEBUG_NET
  268. U32 checksum = bstream->readInt(32);
  269. AssertISV( (checksum ^ DebugChecksum) == (U32)classId,
  270. avar("unpack did not match pack for event of class %s.",
  271. evt->getClassName()) );
  272. #endif
  273. if(unguaranteedPhase)
  274. {
  275. evt->process(this);
  276. evt->decRef();
  277. if(mErrorBuffer[0])
  278. return;
  279. continue;
  280. }
  281. seq |= (mNextRecvEventSeq & ~0x7F);
  282. if(seq < mNextRecvEventSeq)
  283. seq += 128;
  284. NetEventNote *note = mEventNoteChunker.alloc();
  285. note->mEvent = evt;
  286. note->mEvent->incRef();
  287. note->mSeqCount = seq;
  288. //Con::printf("EVT %d: RECV - %d", getId(), evt->mSeqCount);
  289. while(*waitInsert && (*waitInsert)->mSeqCount < seq)
  290. waitInsert = &((*waitInsert)->mNextEvent);
  291. note->mNextEvent = *waitInsert;
  292. *waitInsert = note;
  293. waitInsert = &(note->mNextEvent);
  294. }
  295. while(mWaitSeqEvents && mWaitSeqEvents->mSeqCount == mNextRecvEventSeq)
  296. {
  297. mNextRecvEventSeq++;
  298. NetEventNote *temp = mWaitSeqEvents;
  299. mWaitSeqEvents = temp->mNextEvent;
  300. //Con::printf("EVT %d: PROCESS - %d", getId(), temp->mSeqCount);
  301. temp->mEvent->process(this);
  302. temp->mEvent->decRef();
  303. mEventNoteChunker.free(temp);
  304. if(mErrorBuffer[0])
  305. return;
  306. }
  307. }
  308. bool NetConnection::postNetEvent(NetEvent *theEvent)
  309. {
  310. if(!mSendingEvents)
  311. {
  312. theEvent->decRef();
  313. return false;
  314. }
  315. NetEventNote *event = mEventNoteChunker.alloc();
  316. event->mEvent = theEvent;
  317. theEvent->incRef();
  318. event->mNextEvent = NULL;
  319. if(theEvent->mGuaranteeType == NetEvent::GuaranteedOrdered)
  320. {
  321. event->mSeqCount = mNextSendEventSeq++;
  322. if(!mSendEventQueueHead)
  323. mSendEventQueueHead = event;
  324. else
  325. mSendEventQueueTail->mNextEvent = event;
  326. mSendEventQueueTail = event;
  327. }
  328. else
  329. {
  330. event->mSeqCount = InvalidSendEventSeq;
  331. if(!mUnorderedSendEventQueueHead)
  332. mUnorderedSendEventQueueHead = event;
  333. else
  334. mUnorderedSendEventQueueTail->mNextEvent = event;
  335. mUnorderedSendEventQueueTail = event;
  336. }
  337. return true;
  338. }
  339. void NetConnection::eventWriteStartBlock(ResizeBitStream *stream)
  340. {
  341. stream->write(mNextRecvEventSeq);
  342. for(NetEventNote *walk = mWaitSeqEvents; walk; walk = walk->mNextEvent)
  343. {
  344. stream->writeFlag(true);
  345. S32 classId = walk->mEvent->getClassId(getNetClassGroup());
  346. stream->writeClassId(classId, NetClassTypeEvent, getNetClassGroup());
  347. walk->mEvent->write(this, stream);
  348. stream->validate();
  349. }
  350. stream->writeFlag(false);
  351. }
  352. void NetConnection::eventReadStartBlock(BitStream *stream)
  353. {
  354. stream->read(&mNextRecvEventSeq);
  355. NetEventNote *lastEvent = NULL;
  356. while(stream->readFlag())
  357. {
  358. S32 classTag = stream->readClassId(NetClassTypeEvent, getNetClassGroup());
  359. NetEvent *evt = (NetEvent *) ConsoleObject::create(getNetClassGroup(), NetClassTypeEvent, classTag);
  360. evt->unpack(this, stream);
  361. NetEventNote *add = mEventNoteChunker.alloc();
  362. add->mEvent = evt;
  363. evt->incRef();
  364. add->mNextEvent = NULL;
  365. if(!lastEvent)
  366. mWaitSeqEvents = add;
  367. else
  368. lastEvent->mNextEvent = add;
  369. lastEvent = add;
  370. }
  371. }