📄 gameconnection.cc
字号:
//find the last control object in the chain (client->player->turret->whatever...)
ShapeBase *obj = getCameraObject();
ShapeBase *cObj = NULL;
while (obj)
{
cObj = obj;
obj = obj->getControlObject();
}
if (cObj)
{
// allow shapebase to clamp fov to its datablock values
cObj->setCameraFov(mClampF(fov, MinCameraFov, MaxCameraFov));
fov = cObj->getCameraFov();
// server fov of client has 1degree resolution
if(S32(fov) != S32(mCameraFov))
mUpdateCameraFov = true;
mCameraFov = fov;
return(true);
}
return(false);
}
bool GameConnection::getControlCameraVelocity(Point3F *vel)
{
if (ShapeBase* obj = getCameraObject()) {
*vel = obj->getVelocity();
return true;
}
return false;
}
void GameConnection::setFirstPerson(bool firstPerson)
{
mFirstPerson = firstPerson;
mUpdateFirstPerson = true;
}
//----------------------------------------------------------------------------
bool GameConnection::onAdd()
{
if (!Parent::onAdd())
return false;
return true;
}
void GameConnection::onRemove()
{
if(isNetworkConnection())
{
sendDisconnectPacket(mDisconnectReason);
}
if(!isConnectionToServer())
Con::executef(this, 2, "onDrop", mDisconnectReason);
if (mControlObject)
mControlObject->setControllingClient(0);
Parent::onRemove();
}
void GameConnection::setDisconnectReason(const char *str)
{
dStrncpy(mDisconnectReason, str, sizeof(mDisconnectReason) - 1);
mDisconnectReason[sizeof(mDisconnectReason) - 1] = 0;
}
//----------------------------------------------------------------------------
void GameConnection::handleRecordedBlock(U32 type, U32 size, void *data)
{
switch(type)
{
case BlockTypeMove:
pushMove(*((Move *) data));
if(isRecording()) // put it back into the stream
recordBlock(type, size, data);
break;
default:
Parent::handleRecordedBlock(type, size, data);
break;
}
}
void GameConnection::writeDemoStartBlock(ResizeBitStream *stream)
{
// write all the data blocks to the stream:
for(SimObjectId i = DataBlockObjectIdFirst; i <= DataBlockObjectIdLast; i++)
{
SimDataBlock *data;
if(Sim::findObject(i, data))
{
stream->writeFlag(true);
SimDataBlockEvent evt(data);
evt.pack(this, stream);
stream->validate();
}
}
stream->writeFlag(false);
stream->write(mFirstPerson);
stream->write(mCameraPos);
stream->write(mCameraSpeed);
stream->write(mLastMoveAck);
stream->write(mLastClientMove);
stream->write(mFirstMoveIndex);
stream->writeString(Con::getVariable("$Client::MissionFile"));
stream->write(U32(mMoveList.size()));
for(U32 j = 0; j < mMoveList.size(); j++)
mMoveList[j].pack(stream);
// dump all the "demo" vars associated with this connection:
SimFieldDictionaryIterator itr(getFieldDictionary());
SimFieldDictionary::Entry *entry;
while((entry = *itr) != NULL)
{
if(!dStrnicmp(entry->slotName, "demo", 4))
{
stream->writeFlag(true);
stream->writeString(entry->slotName + 4);
stream->writeString(entry->value);
stream->validate();
}
++itr;
}
stream->writeFlag(false);
Parent::writeDemoStartBlock(stream);
stream->validate();
// dump out the control object ghost id
S32 idx = mControlObject ? getGhostIndex(mControlObject) : -1;
stream->write(idx);
if(mControlObject)
mControlObject->writePacketData(this, stream);
idx = mCameraObject ? getGhostIndex(mCameraObject) : -1;
stream->write(idx);
if(mCameraObject && mCameraObject != mControlObject)
mCameraObject->writePacketData(this, stream);
mLastControlRequestTime = Platform::getVirtualMilliseconds();
}
bool GameConnection::readDemoStartBlock(BitStream *stream)
{
while(stream->readFlag())
{
SimDataBlockEvent evt;
evt.unpack(this, stream);
evt.process(this);
}
while(mDataBlockLoadList.size())
{
preloadNextDataBlock(false);
if(mErrorBuffer[0])
return false;
}
stream->read(&mFirstPerson);
stream->read(&mCameraPos);
stream->read(&mCameraSpeed);
stream->read(&mLastMoveAck);
stream->read(&mLastClientMove);
stream->read(&mFirstMoveIndex);
char buf[256];
stream->readString(buf);
Con::setVariable("$Client::MissionFile",buf);
U32 size;
Move mv;
stream->read(&size);
mMoveList.clear();
while(size--)
{
mv.unpack(stream);
pushMove(mv);
}
// read in all the demo vars associated with this recording
// they are all tagged on to the object and start with the
// string "demo"
while(stream->readFlag())
{
StringTableEntry slotName = StringTable->insert("demo");
char array[256];
char value[256];
stream->readString(array);
stream->readString(value);
setDataField(slotName, array, value);
}
bool ret = Parent::readDemoStartBlock(stream);
// grab the control object
S32 idx;
stream->read(&idx);
ShapeBase * obj = 0;
if(idx != -1)
{
obj = dynamic_cast<ShapeBase*>(resolveGhost(idx));
setControlObject(obj);
obj->readPacketData(this, stream);
}
// Get the camera object, and read it in if it's different
S32 idx2;
stream->read(&idx2);
obj = 0;
if(idx2 != -1 && idx2 != idx)
{
obj = dynamic_cast<ShapeBase*>(resolveGhost(idx2));
setCameraObject(obj);
obj->readPacketData(this, stream);
}
return ret;
}
void GameConnection::demoPlaybackComplete()
{
static const char *demoPlaybackArgv[1] = { "demoPlaybackComplete" };
Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(1, demoPlaybackArgv, false));
Parent::demoPlaybackComplete();
}
//----------------------------------------------------------------------------
void GameConnection::readPacket(BitStream *bstream)
{
char stringBuf[256];
stringBuf[0] = 0;
bstream->setStringBuffer(stringBuf);
bstream->clearCompressionPoint();
if (isConnectionToServer())
{
///去除mLastMoveAck传递
#ifndef TGE_RPGCLIENT /// TGE_RPGClientCtrl
mLastMoveAck = bstream->readInt(32);
if (mLastMoveAck < mFirstMoveIndex)
mLastMoveAck = mFirstMoveIndex;
if(mLastMoveAck > mLastClientMove)
mLastClientMove = mLastMoveAck;
while(mFirstMoveIndex < mLastMoveAck)
{
AssertFatal(mMoveList.size(), "Popping off too many moves!");
mMoveList.pop_front();
mFirstMoveIndex++;
}
#endif
mDamageFlash = 0;
mWhiteOut = 0;
if(bstream->readFlag())
{
if(bstream->readFlag())
mDamageFlash = bstream->readFloat(7);
if(bstream->readFlag())
mWhiteOut = bstream->readFloat(7) * 1.5;
}
if (bstream->readFlag())
{
if(bstream->readFlag())
{
/// 设置Connection控制体
// the control object is dirty...
// so we get an update:
mLastClientMove = mLastMoveAck;
bool callScript = false;
if(mControlObject.isNull())
callScript = true;
S32 gIndex = bstream->readInt(GhostConnection::GhostIdBitSize);
ShapeBase* obj = static_cast<ShapeBase*>(resolveGhost(gIndex));
if (mControlObject != obj)
setControlObject(obj);
obj->readPacketData(this, bstream);
/// 在脚本中,将调用Canvas.setContent(PlayGui);
if(callScript)
Con::executef(this, 2, "initialControlSet");
}
else
{
// read out the compression point
Point3F pos;
bstream->read(&pos.x);
bstream->read(&pos.y);
bstream->read(&pos.z);
bstream->setCompressionPoint(pos);
}
}
/// 设置相机控制体
if (bstream->readFlag())
{
S32 gIndex = bstream->readInt(GhostConnection::GhostIdBitSize);
ShapeBase* obj = static_cast<ShapeBase*>(resolveGhost(gIndex));
setCameraObject(obj);
obj->readPacketData(this, bstream);
}
else
setCameraObject(0);
#ifndef TGE_RPGCLIENT /// TGE_RPGClientCtrl
// server changed first person
if(bstream->readFlag()) {
setFirstPerson(bstream->readFlag());
mUpdateFirstPerson = false;
}
#endif
// server forcing a fov change?
if(bstream->readFlag())
{
S32 fov = bstream->readInt(8);
setControlCameraFov(fov);
// don't bother telling the server if we were able to set the fov
F32 setFov;
if(getControlCameraFov(&setFov) && (S32(setFov) == fov))
mUpdateCameraFov = false;
// update the games fov info
GameSetCameraFov(fov);
}
}
else
{
bool fp = bstream->readFlag();
if(fp)
mCameraPos = 0;
else
mCameraPos = 1;
bstream->read(&mLastControlObjectChecksum);
///去除Move传到Server处理
#ifndef TGE_RPGCLIENT /// TGE_RPGClientCtrl
moveReadPacket(bstream);
// client changed first person
if(bstream->readFlag()) {
setFirstPerson(bstream->readFlag());
mUpdateFirstPerson = false;
}
#endif
// check fov change.. 1degree granularity on server
if(bstream->readFlag())
{
S32 fov = mClamp(bstream->readInt(8), S32(MinCameraFov), S32(MaxCameraFov));
setControlCameraFov(fov);
// may need to force client back to a valid fov
F32 setFov;
if(getControlCameraFov(&setFov) && (S32(setFov) == fov))
mUpdateCameraFov = false;
}
}
Parent::readPacket(bstream);
bstream->clearCompressionPoint();
bstream->setStringBuffer(NULL);
}
void GameConnection::writePacket(BitStream *bstream, PacketNotify *note)
{
char stringBuf[256];
bstream->clearCompressionPoint();
stringBuf[0] = 0;
bstream->setStringBuffer(stringBuf);
GamePacketNotify *gnote = (GamePacketNotify *) note;
U32 startPos = bstream->getCurPos();
//////////////////////////////////////////
//客户端数据包填充处理
if (isConnectionToServer())
{
bstream->writeFlag(mCameraPos == 0);
U32 sum = 0;
if(mControlObject)
{
mControlObject->interpolateTick(0);
sum = mControlObject->getPacketDataChecksum(this);
mControlObject->interpolateTick(gClientProcessList.getLastInterpDelta());
}
// if we're recording, we want to make sure that we get periodic updates of the
// control object "just in case" - ie if the math copro is different between the
// recording machine (SIMD vs FPU), we get periodic corrections
if(isRecording())
{
U32 currentTime = Platform::getVirtualMilliseconds();
if(currentTime - mLastControlRequestTime > ControlRequestTime)
{
mLastControlRequestTime = currentTime;
sum = 0;
}
}
bstream->write(sum);
///去除Move传到Server处理
#ifndef TGE_RPGCLIENT /// TGE_RPGClientCtrl
moveWritePacket(bstream);
// first person changed?
if(bstream->writeFlag(mUpdateFirstPerson))
{
bstream->writeFlag(mFirstPerson);
mUpdateFirstPerson = false;
}
#endif
// camera fov changed? (server fov resolution is 1 degree)
if(bstream->writeFlag(mUpdateCameraFov))
{
bstream->writeInt(mClamp(S32(mCameraFov), S32(MinCameraFov), S32(MaxCameraFov)), 8);
mUpdateCameraFov = false;
}
DEBUG_LOG(("PKLOG %d CLIENTMOVES: %d", getId(), bstream->getCurPos() - startPos));
}
else
{
// The only time mMoveList will not be empty at this
// point is during a change in control object.
///去除mLastMoveAck传递
#ifndef TGE_RPGCLIENT /// TGE_RPGClientCtrl
bstream->writeInt(mLastMoveAck - mMoveList.size(),32);
#endif
S32 gIndex = -1;
// get the ghost index of the control object, and write out
// all the damage flash & white out
if (!mControlObject.isNull())
{
gIndex = getGhostIndex(mControlObject);
F32 flash = mControlObject->getDamageFlash();
F32 whiteOut = mControlObject->getWhiteOut();
if(bstream->writeFlag(flash != 0 || whiteOut != 0))
{
if(bstream->writeFlag(flash != 0))
bstream->writeFloat(flash, 7);
if(bstream->writeFlag(whiteOut != 0))
bstream->writeFloat(whiteOut/1.5, 7);
}
}
else
bstream->writeFlag(false);
if (bstream->writeFlag(gIndex != -1))
{
// assume that the control object will write in a compression point
if(bstream->writeFlag(mControlObject->getPacketDataChecksum(this) != mLastControlObjectChecksum))
{
#ifdef TORQUE_DEBUG_NET
Con::printf("packetDataChecksum disagree!");
#endif
bstream->writeInt(gIndex, GhostConnection::GhostIdBitSize);
mControlObject->writePacketData(this, bstream);
}
else
{
// we'll have to use the control object's position as the compression point
// should make this lower res for better space usage:
Point3F coPos = mControlObject->getPosition();
bstream->write(coPos.x);
bstream->write(coPos.y);
bstream->write(coPos.z);
bstream->setCompressionPoint(coPos);
}
}
DEBUG_LOG(("PKLOG %d CONTROLOBJECTSTATE: %d", getId(), bstream->getCurPos() - startPos));
startPos = bstream->getCurPos();
if (!mCameraObject.isNull() && mCameraObject != mControlObject)
{
gIndex = getGhostIndex(mCameraObject);
if (bstream->writeFlag(gIndex != -1))
{
bstream->writeInt(gIndex, GhostConnection::GhostIdBitSize);
mCameraObject->writePacketData(this, bstream);
}
}
else
bstream->writeFlag( false );
#ifndef TGE_RPGCLIENT /// TGE_RPGClientCtrl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -