mirror of
https://github.com/tribes2/engine.git
synced 2026-03-12 00:40:34 +00:00
t2 engine svn checkout
This commit is contained in:
commit
ff569bd2ae
988 changed files with 394180 additions and 0 deletions
355
sim/netEvent.cc
Normal file
355
sim/netEvent.cc
Normal file
|
|
@ -0,0 +1,355 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// V12 Engine
|
||||
//
|
||||
// Copyright (c) 2001 GarageGames.Com
|
||||
// Portions Copyright (c) 2001 by Sierra Online, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "core/dnet.h"
|
||||
#include "console/simBase.h"
|
||||
#include "sim/netConnection.h"
|
||||
#include "core/bitStream.h"
|
||||
|
||||
#define DebugChecksum 0xF00DBAAD
|
||||
|
||||
void NetEvent::notifyDelivered(NetConnection *, bool)
|
||||
{
|
||||
}
|
||||
|
||||
void NetEvent::notifySent(NetConnection *)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef DEBUG_NET
|
||||
const char *NetEvent::getDebugName()
|
||||
{
|
||||
return getClassName();
|
||||
}
|
||||
#endif
|
||||
|
||||
void NetConnection::eventPacketDropped(PacketNotify *notify)
|
||||
{
|
||||
NetEvent *walk = notify->eventList;
|
||||
NetEvent **insertList = &mSendEventQueueHead;
|
||||
NetEvent *temp;
|
||||
|
||||
while(walk)
|
||||
{
|
||||
switch(walk->mGuaranteeType)
|
||||
{
|
||||
case NetEvent::GuaranteedOrdered:
|
||||
//Con::printf("EVT %d: DROP - %d", getId(), walk->mSeqCount);
|
||||
while(*insertList && (*insertList)->mSeqCount < walk->mSeqCount)
|
||||
insertList = &((*insertList)->mNextEvent);
|
||||
|
||||
temp = walk->mNextEvent;
|
||||
walk->mNextEvent = *insertList;
|
||||
if(!walk->mNextEvent)
|
||||
mSendEventQueueTail = walk;
|
||||
*insertList = walk;
|
||||
insertList = &(walk->mNextEvent);
|
||||
walk = temp;
|
||||
break;
|
||||
case NetEvent::Guaranteed:
|
||||
temp = walk->mNextEvent;
|
||||
walk->mNextEvent = mUnorderedSendEventQueueHead;
|
||||
mUnorderedSendEventQueueHead = walk;
|
||||
if(!walk->mNextEvent)
|
||||
mUnorderedSendEventQueueTail = walk;
|
||||
walk = temp;
|
||||
break;
|
||||
case NetEvent::Unguaranteed:
|
||||
walk->notifyDelivered(this, false);
|
||||
temp = walk->mNextEvent;
|
||||
delete walk;
|
||||
walk = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetConnection::eventPacketReceived(PacketNotify *notify)
|
||||
{
|
||||
NetEvent *walk = notify->eventList;
|
||||
NetEvent **noteList = &mNotifyEventList;
|
||||
|
||||
while(walk)
|
||||
{
|
||||
NetEvent *next = walk->mNextEvent;
|
||||
if(walk->mGuaranteeType != NetEvent::GuaranteedOrdered)
|
||||
{
|
||||
walk->notifyDelivered(this, true);
|
||||
delete walk;
|
||||
walk = next;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(*noteList && (*noteList)->mSeqCount < walk->mSeqCount)
|
||||
noteList = &((*noteList)->mNextEvent);
|
||||
|
||||
walk->mNextEvent = *noteList;
|
||||
*noteList = walk;
|
||||
noteList = &walk->mNextEvent;
|
||||
walk = next;
|
||||
}
|
||||
}
|
||||
while(mNotifyEventList && mNotifyEventList->mSeqCount == mLastAckedEventSeq + 1)
|
||||
{
|
||||
mLastAckedEventSeq++;
|
||||
NetEvent *next = mNotifyEventList->mNextEvent;
|
||||
//Con::printf("EVT %d: ACK - %d", getId(), mNotifyEventList->mSeqCount);
|
||||
mNotifyEventList->notifyDelivered(this, true);
|
||||
delete mNotifyEventList;
|
||||
mNotifyEventList = next;
|
||||
}
|
||||
}
|
||||
|
||||
void NetConnection::eventWritePacket(BitStream *bstream, PacketNotify *notify)
|
||||
{
|
||||
#ifdef DEBUG_NET
|
||||
bstream->writeInt(DebugChecksum, 32);
|
||||
#endif
|
||||
|
||||
NetEvent *packQueueHead = NULL, *packQueueTail = NULL;
|
||||
|
||||
while(mUnorderedSendEventQueueHead)
|
||||
{
|
||||
if(bstream->isFull())
|
||||
break;
|
||||
// dequeue the first event
|
||||
NetEvent *ev = mUnorderedSendEventQueueHead;
|
||||
mUnorderedSendEventQueueHead = ev->mNextEvent;
|
||||
U32 start = bstream->getCurPos();
|
||||
|
||||
bstream->writeFlag(true);
|
||||
S32 classId = ev->getClassId();
|
||||
AssertFatal(classId >= NetEventClassFirst && classId <= NetEventClassLast,
|
||||
"Out of range event class id... check simBase.h");
|
||||
bstream->writeInt(classId - NetEventClassFirst, NetEventClassBitSize);
|
||||
|
||||
ev->pack(this, bstream);
|
||||
DEBUG_LOG(("PKLOG %d EVENT %d: %s", getId(), bstream->getCurPos() - start, ev->getDebugName()) );
|
||||
|
||||
#ifdef DEBUG_NET
|
||||
bstream->writeInt(classId, 10);
|
||||
bstream->writeInt(classId ^ DebugChecksum, 32);
|
||||
#endif
|
||||
// add this event onto the packet queue
|
||||
ev->mNextEvent = NULL;
|
||||
if(!packQueueHead)
|
||||
packQueueHead = ev;
|
||||
else
|
||||
packQueueTail->mNextEvent = ev;
|
||||
packQueueTail = ev;
|
||||
}
|
||||
|
||||
bstream->writeFlag(false);
|
||||
S32 prevSeq = -2;
|
||||
|
||||
while(mSendEventQueueHead)
|
||||
{
|
||||
if(bstream->isFull())
|
||||
break;
|
||||
|
||||
// if the event window is full, stop processing
|
||||
if(mSendEventQueueHead->mSeqCount > mLastAckedEventSeq + 126)
|
||||
break;
|
||||
|
||||
// dequeue the first event
|
||||
NetEvent *ev = mSendEventQueueHead;
|
||||
mSendEventQueueHead = ev->mNextEvent;
|
||||
|
||||
//Con::printf("EVT %d: SEND - %d", getId(), ev->mSeqCount);
|
||||
|
||||
bstream->writeFlag(true);
|
||||
|
||||
ev->mNextEvent = NULL;
|
||||
if(!packQueueHead)
|
||||
packQueueHead = ev;
|
||||
else
|
||||
packQueueTail->mNextEvent = ev;
|
||||
packQueueTail = ev;
|
||||
if(!bstream->writeFlag(ev->mSeqCount == prevSeq + 1))
|
||||
bstream->writeInt(ev->mSeqCount, 7);
|
||||
prevSeq = ev->mSeqCount;
|
||||
|
||||
U32 start = bstream->getCurPos();
|
||||
S32 classId = ev->getClassId();
|
||||
AssertFatal(classId >= NetEventClassFirst && classId <= NetEventClassLast,
|
||||
"Out of range event class id... check simBase.h");
|
||||
bstream->writeInt(classId - NetEventClassFirst, NetEventClassBitSize);
|
||||
|
||||
ev->pack(this, bstream);
|
||||
DEBUG_LOG(("PKLOG %d EVENT %d: %s", getId(), bstream->getCurPos() - start, ev->getDebugName()) );
|
||||
#ifdef DEBUG_NET
|
||||
bstream->writeInt(classId, 10);
|
||||
bstream->writeInt(classId ^ DebugChecksum, 32);
|
||||
#endif
|
||||
}
|
||||
for(NetEvent *ev = packQueueHead; ev; ev = ev->mNextEvent)
|
||||
ev->notifySent(this);
|
||||
|
||||
notify->eventList = packQueueHead;
|
||||
bstream->writeFlag(0);
|
||||
}
|
||||
|
||||
void NetConnection::eventReadPacket(BitStream *bstream)
|
||||
{
|
||||
#ifdef DEBUG_NET
|
||||
U32 sum = bstream->readInt(32);
|
||||
AssertISV(sum == DebugChecksum, "Invalid checksum.");
|
||||
#endif
|
||||
|
||||
S32 prevSeq = -2;
|
||||
NetEvent **waitInsert = &mWaitSeqEvents;
|
||||
bool unguaranteedPhase = true;
|
||||
|
||||
while(true)
|
||||
{
|
||||
bool bit = bstream->readFlag();
|
||||
if(unguaranteedPhase && !bit)
|
||||
{
|
||||
unguaranteedPhase = false;
|
||||
bit = bstream->readFlag();
|
||||
}
|
||||
if(!unguaranteedPhase && !bit)
|
||||
break;
|
||||
|
||||
S32 seq = -1;
|
||||
|
||||
if(!unguaranteedPhase) // get the sequence
|
||||
{
|
||||
if(bstream->readFlag())
|
||||
seq = (prevSeq + 1) & 0x7f;
|
||||
else
|
||||
seq = bstream->readInt(7);
|
||||
prevSeq = seq;
|
||||
}
|
||||
S32 classTag = bstream->readInt(NetEventClassBitSize) + NetEventClassFirst;
|
||||
NetEvent *evt = (NetEvent *) ConsoleObject::create(classTag);
|
||||
if(!evt)
|
||||
{
|
||||
setLastError("Invalid packet.");
|
||||
return;
|
||||
}
|
||||
AbstractClassRep *rep = evt->getClassRep();
|
||||
if((rep->mClassNetClass == NetEventClassClient && !isServerConnection())
|
||||
|| (rep->mClassNetClass == NetEventClassServer && isServerConnection()) )
|
||||
{
|
||||
setLastError("Invalid Packet.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
evt->mSourceId = getId();
|
||||
evt->unpack(this, bstream);
|
||||
if(mErrorBuffer[0])
|
||||
return;
|
||||
#ifdef DEBUG_NET
|
||||
U32 classId = bstream->readInt(10);
|
||||
U32 checksum = bstream->readInt(32);
|
||||
AssertISV( (checksum ^ DebugChecksum) == (U32)classTag,
|
||||
avar("unpack did not match pack for event of class %s.",
|
||||
evt->getClassName()) );
|
||||
#endif
|
||||
if(unguaranteedPhase)
|
||||
{
|
||||
evt->process(this);
|
||||
delete evt;
|
||||
if(mErrorBuffer[0])
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
seq |= (mNextRecvEventSeq & ~0x7F);
|
||||
if(seq < mNextRecvEventSeq)
|
||||
seq += 128;
|
||||
|
||||
evt->mSeqCount = seq;
|
||||
//Con::printf("EVT %d: RECV - %d", getId(), evt->mSeqCount);
|
||||
while(*waitInsert && (*waitInsert)->mSeqCount < seq)
|
||||
waitInsert = &((*waitInsert)->mNextEvent);
|
||||
|
||||
evt->mNextEvent = *waitInsert;
|
||||
*waitInsert = evt;
|
||||
waitInsert = &(evt->mNextEvent);
|
||||
}
|
||||
while(mWaitSeqEvents && mWaitSeqEvents->mSeqCount == mNextRecvEventSeq)
|
||||
{
|
||||
mNextRecvEventSeq++;
|
||||
NetEvent *temp = mWaitSeqEvents;
|
||||
mWaitSeqEvents = temp->mNextEvent;
|
||||
|
||||
//Con::printf("EVT %d: PROCESS - %d", getId(), temp->mSeqCount);
|
||||
temp->process(this);
|
||||
delete temp;
|
||||
if(mErrorBuffer[0])
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool NetConnection::postNetEvent(NetEvent *event)
|
||||
{
|
||||
AssertFatal(event->mIsPosted == false, "Event cannot be posted to more than one connection.");
|
||||
event->mIsPosted = true;
|
||||
|
||||
if(!mSendingEvents)
|
||||
{
|
||||
delete event;
|
||||
return false;
|
||||
}
|
||||
event->mNextEvent = NULL;
|
||||
if(event->mGuaranteeType == NetEvent::GuaranteedOrdered)
|
||||
{
|
||||
event->mSeqCount = mNextSendEventSeq++;
|
||||
if(!mSendEventQueueHead)
|
||||
mSendEventQueueHead = event;
|
||||
else
|
||||
mSendEventQueueTail->mNextEvent = event;
|
||||
mSendEventQueueTail = event;
|
||||
}
|
||||
else
|
||||
{
|
||||
event->mSeqCount = InvalidSendEventSeq;
|
||||
if(!mUnorderedSendEventQueueHead)
|
||||
mUnorderedSendEventQueueHead = event;
|
||||
else
|
||||
mUnorderedSendEventQueueTail->mNextEvent = event;
|
||||
mUnorderedSendEventQueueTail = event;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void NetConnection::eventWriteStartBlock(ResizeBitStream *stream)
|
||||
{
|
||||
stream->write(mNextRecvEventSeq);
|
||||
for(NetEvent *walk = mWaitSeqEvents; walk; walk = walk->mNextEvent)
|
||||
{
|
||||
stream->writeFlag(true);
|
||||
S32 classId = walk->getClassId();
|
||||
stream->writeInt(classId - NetEventClassFirst, NetEventClassBitSize);
|
||||
walk->write(this, stream);
|
||||
stream->validate();
|
||||
}
|
||||
stream->writeFlag(false);
|
||||
}
|
||||
|
||||
void NetConnection::eventReadStartBlock(BitStream *stream)
|
||||
{
|
||||
stream->read(&mNextRecvEventSeq);
|
||||
|
||||
NetEvent *lastEvent = NULL;
|
||||
while(stream->readFlag())
|
||||
{
|
||||
S32 classTag = stream->readInt(NetEventClassBitSize) + NetEventClassFirst;
|
||||
NetEvent *evt = (NetEvent *) ConsoleObject::create(classTag);
|
||||
evt->unpack(this, stream);
|
||||
evt->mNextEvent = NULL;
|
||||
|
||||
if(!lastEvent)
|
||||
mWaitSeqEvents = evt;
|
||||
else
|
||||
lastEvent->mNextEvent = evt;
|
||||
lastEvent = evt;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue