📄 gameconnection.cc
字号:
// first person changed?
if(bstream->writeFlag(mUpdateFirstPerson)) {
bstream->writeFlag(mFirstPerson);
mUpdateFirstPerson = false;
}
#endif
// server forcing client fov?
gnote->cameraFov = -1;
if(bstream->writeFlag(mUpdateCameraFov))
{
gnote->cameraFov = mClamp(S32(mCameraFov), S32(MinCameraFov), S32(MaxCameraFov));
bstream->writeInt(gnote->cameraFov, 8);
mUpdateCameraFov = false;
}
DEBUG_LOG(("PKLOG %d PINGCAMSTATE: %d", getId(), bstream->getCurPos() - startPos));
}
Parent::writePacket(bstream, note);
bstream->clearCompressionPoint();
bstream->setStringBuffer(NULL);
}
void GameConnection::detectLag()
{
//see if we're lagging...
S32 curTime = Sim::getCurrentTime();
if (curTime - mLastPacketTime > mLagThresholdMS)
{
if (!mLagging)
{
mLagging = true;
Con::executef(this, 2, "setLagIcon", "true");
}
}
else if (mLagging)
{
mLagging = false;
Con::executef(this, 2, "setLagIcon", "false");
}
}
GameConnection::GamePacketNotify::GamePacketNotify()
{
// need to fill in empty notifes for demo start block
cameraFov = 0;
}
NetConnection::PacketNotify *GameConnection::allocNotify()
{
return new GamePacketNotify;
}
void GameConnection::packetReceived(PacketNotify *note)
{
//record the time so we can tell if we're lagging...
mLastPacketTime = Sim::getCurrentTime();
GamePacketNotify *gnote = (GamePacketNotify *) note;
Parent::packetReceived(note);
}
void GameConnection::packetDropped(PacketNotify *note)
{
Parent::packetDropped(note);
GamePacketNotify *gnote = (GamePacketNotify *) note;
if(gnote->cameraFov != -1)
mUpdateCameraFov = true;
}
//----------------------------------------------------------------------------
void GameConnection::play2D(const AudioProfile* profile)
{
postNetEvent(new Sim2DAudioEvent(profile));
}
void GameConnection::play3D(const AudioProfile* profile, const MatrixF *transform)
{
if (transform)
{
if (mControlObject)
{
// Only post the event if it's within audible range
// of the control object.
Point3F ear,pos;
transform->getColumn(3,&pos);
mControlObject->getTransform().getColumn(3,&ear);
if ((ear - pos).len() < profile->mDescriptionObject->mDescription.mMaxDistance)
postNetEvent(new Sim3DAudioEvent(profile,transform));
}
else
postNetEvent(new Sim3DAudioEvent(profile,transform));
}
else
play2D(profile);
}
void GameConnection::doneScopingScene()
{
// Could add special post-scene scoping here, such as scoping
// objects not visible to the camera, but visible to sensors.
}
void GameConnection::preloadDataBlock(SimDataBlock *db)
{
mDataBlockLoadList.push_back(db);
if(mDataBlockLoadList.size() == 1)
preloadNextDataBlock(true);
}
void GameConnection::fileDownloadSegmentComplete()
{
// this is called when a the file list has finished processing...
// at this point we can try again to add the object
// subclasses can override this to do, for example, datablock redos.
if(mDataBlockLoadList.size())
preloadNextDataBlock(mNumDownloadedFiles != 0);
Parent::fileDownloadSegmentComplete();
}
void GameConnection::preloadNextDataBlock(bool hadNewFiles)
{
if(!mDataBlockLoadList.size())
return;
while(mDataBlockLoadList.size())
{
// only check for new files if this is the first load, or if new
// files were downloaded from the server.
if(hadNewFiles)
ResourceManager->setMissingFileLogging(true);
ResourceManager->clearMissingFileList();
SimDataBlock *object = mDataBlockLoadList[0];
if(!object)
{
// a null object is used to signify that the last ghost in the list is down
mDataBlockLoadList.pop_front();
AssertFatal(mDataBlockLoadList.size() == 0, "Error! Datablock save list should be empty!");
sendConnectionMessage(DataBlocksDownloadDone, mDataBlockSequence);
ResourceManager->setMissingFileLogging(false);
return;
}
mFilesWereDownloaded = hadNewFiles;
if(!object->preload(false, mErrorBuffer))
{
mFilesWereDownloaded = false;
// make sure there's an error message if necessary
if(!mErrorBuffer[0])
setLastError("Invalid packet.");
// if there were no new files, make sure the error message
// is the one from the last time we tried to add this object
if(!hadNewFiles)
{
dStrcpy(mErrorBuffer, mLastFileErrorBuffer);
ResourceManager->setMissingFileLogging(false);
return;
}
// object failed to load, let's see if it had any missing files
if(!ResourceManager->getMissingFileList(mMissingFileList))
{
// no missing files, must be an error
// connection will automagically delete the ghost always list
// when this error is reported.
ResourceManager->setMissingFileLogging(false);
return;
}
// ok, copy the error buffer out to a scratch pad for now
dStrcpy(mLastFileErrorBuffer, mErrorBuffer);
mErrorBuffer[0] = 0;
// request the missing files...
mNumDownloadedFiles = 0;
sendNextFileDownloadRequest();
break;
}
mFilesWereDownloaded = false;
ResourceManager->setMissingFileLogging(false);
mDataBlockLoadList.pop_front();
hadNewFiles = true;
}
}
//----------------------------------------------------------------------------
//localconnection only blackout functions
void GameConnection::setBlackOut(bool fadeToBlack, S32 timeMS)
{
mFadeToBlack = fadeToBlack;
mBlackOutStartTimeMS = Sim::getCurrentTime();
mBlackOutTimeMS = timeMS;
//if timeMS <= 0 set the value instantly
if (mBlackOutTimeMS <= 0)
mBlackOut = (mFadeToBlack ? 1.0f : 0.0f);
}
F32 GameConnection::getBlackOut()
{
S32 curTime = Sim::getCurrentTime();
//see if we're in the middle of a black out
if (curTime < mBlackOutStartTimeMS + mBlackOutTimeMS)
{
S32 elapsedTime = curTime - mBlackOutStartTimeMS;
F32 timePercent = F32(elapsedTime) / F32(mBlackOutTimeMS);
mBlackOut = (mFadeToBlack ? timePercent : 1.0f - timePercent);
}
else
mBlackOut = (mFadeToBlack ? 1.0f : 0.0f);
//return the blackout time
return mBlackOut;
}
void GameConnection::handleConnectionMessage(U32 message, U32 sequence, U32 ghostCount)
{
if(isConnectionToServer())
{
if(message == DataBlocksDone)
{
mDataBlockLoadList.push_back(NULL);
mDataBlockSequence = sequence;
if(mDataBlockLoadList.size() == 1)
preloadNextDataBlock(true);
}
}
else
{
if(message == DataBlocksDownloadDone)
{
if(getDataBlockSequence() == sequence)
Con::executef(this, 2, "onDataBlocksDone", Con::getIntArg(getDataBlockSequence()));
}
}
Parent::handleConnectionMessage(message, sequence, ghostCount);
}
//----------------------------------------------------------------------------
ConsoleMethod( GameConnection, transmitDataBlocks, void, 3, 3, "(int sequence)")
{
object->setDataBlockSequence(dAtoi(argv[2]));
SimDataBlockGroup *g = Sim::getDataBlockGroup();
// find the first one we haven't sent:
U32 i, groupCount = g->size();
S32 key = object->getDataBlockModifiedKey();
for(i = 0; i < groupCount; i++)
if(( (SimDataBlock *)(*g)[i])->getModifiedKey() > key)
break;
if (i == groupCount) {
object->sendConnectionMessage(GameConnection::DataBlocksDone, object->getDataBlockSequence());
return;
}
object->setMaxDataBlockModifiedKey(key);
// Ship the rest off...
U32 max = getMin(i + DataBlockQueueCount, groupCount);
for (;i < max; i++) {
SimDataBlock *data = (SimDataBlock *)(*g)[i];
object->postNetEvent(new SimDataBlockEvent(data, i, groupCount, object->getDataBlockSequence()));
}
}
ConsoleMethod( GameConnection, activateGhosting, void, 2, 2, "")
{
object->activateGhosting();
}
ConsoleMethod( GameConnection, resetGhosting, void, 2, 2, "")
{
object->resetGhosting();
}
ConsoleMethod( GameConnection, setControlObject, bool, 3, 3, "(ShapeBase object)")
{
ShapeBase *gb;
if(!Sim::findObject(argv[2], gb))
return false;
object->setControlObject(gb);
return true;
}
ConsoleMethod( GameConnection, getControlObject, S32, 2, 2, "")
{
argv;
SimObject* cp = object->getControlObject();
return cp? cp->getId(): 0;
}
ConsoleMethod( GameConnection, isAIControlled, bool, 2, 2, "")
{
return object->isAIControlled();
}
ConsoleMethod( GameConnection, play2D, bool, 3, 3, "(AudioProfile ap)")
{
AudioProfile *profile;
if(!Sim::findObject(argv[2], profile))
return false;
object->play2D(profile);
return true;
}
ConsoleMethod( GameConnection, play3D, bool, 4, 4, "(AudioProfile ap, Transform pos)")
{
AudioProfile *profile;
if(!Sim::findObject(argv[2], profile))
return false;
Point3F pos(0,0,0);
AngAxisF aa;
aa.axis.set(0,0,1);
aa.angle = 0;
dSscanf(argv[3],"%g %g %g %g %g %g %g",
&pos.x,&pos.y,&pos.z,&aa.axis.x,&aa.axis.y,&aa.axis.z,&aa.angle);
MatrixF mat;
aa.setMatrix(&mat);
mat.setColumn(3,pos);
object->play3D(profile,&mat);
return true;
}
ConsoleMethod( GameConnection, chaseCam, bool, 3, 3, "(int size)")
{
S32 size = dAtoi(argv[2]);
if (size != sChaseQueueSize)
{
SAFE_DELETE_ARRAY(sChaseQueue);
sChaseQueueSize = size;
sChaseQueueHead = sChaseQueueTail = 0;
if (size)
{
sChaseQueue = new MatrixF[size];
return true;
}
}
return false;
}
ConsoleMethod( GameConnection, setControlCameraFov, void, 3, 3, "(int newFOV)"
"Set new FOV in degrees.")
{
object->setControlCameraFov(dAtoi(argv[2]));
}
ConsoleMethod( GameConnection, getControlCameraFov, F32, 2, 2, "")
{
F32 fov = 0.f;
if(!object->getControlCameraFov(&fov))
return(0.f);
return(fov);
}
ConsoleMethod( GameConnection, setBlackOut, void, 4, 4, "(bool doFade, int timeMS)")
{
object->setBlackOut(dAtob(argv[2]), dAtoi(argv[3]));
}
ConsoleMethod( GameConnection, setMissionCRC, void, 3, 3, "(int CRC)")
{
if(object->isConnectionToServer())
return;
object->postNetEvent(new SetMissionCRCEvent(dAtoi(argv[2])));
}
ConsoleMethod( GameConnection, delete, void, 2, 3, "(string reason=NULL) Disconnect a client; reason is sent as part of the disconnect packet.")
{
if (argc == 3)
object->setDisconnectReason(argv[2]);
object->deleteObject();
}
//--------------------------------------------------------------------------
void GameConnection::consoleInit()
{
Con::addVariable("Pref::Net::LagThreshold", TypeS32, &mLagThresholdMS);
Con::addVariable("specialFog", TypeBool, &SceneGraph::useSpecial);
}
ConsoleMethod(GameConnection, startRecording, void, 3, 3, "(string fileName)records the network connection to a demo file.")
{
char fileName[1024];
Con::expandScriptFilename(fileName, sizeof(fileName), argv[2]);
object->startDemoRecord(fileName);
}
ConsoleMethod(GameConnection, stopRecording, void, 2, 2, "()stops the demo recording.")
{
object->stopRecording();
}
ConsoleMethod(GameConnection, playDemo, bool, 3, 3, "(string demoFileName)plays a previously recorded demo.")
{
char filename[1024];
Con::expandScriptFilename(filename, sizeof(filename), argv[2]);
// Note that calling onConnectionEstablished will change the values in argv!
object->onConnectionEstablished(true);
object->setEstablished();
if(!object->replayDemoRecord(filename))
{
Con::printf("Unable to open demo file %s.", filename);
object->deleteObject();
return false;
}
// After demo has loaded, execute the scene re-light the scene
SceneLighting::lightScene(0, 0);
return true;
}
ConsoleMethod(GameConnection, isDemoPlaying, bool, 2, 2, "isDemoPlaying();")
{
argc;
argv;
return object->isPlayingBack();
}
ConsoleMethod(GameConnection, isDemoRecording, bool, 2, 2, "()")
{
argc;
argv;
return object->isRecording();
}
ConsoleMethod( GameConnection, listClassIDs, void, 2, 2, "() List all of the "
"classes that this connection knows about, and what their IDs "
"are. Useful for debugging network problems.")
{
Con::printf("--------------- Class ID Listing ----------------");
Con::printf(" id | name");
#ifdef TGE_RPG
AssertWarn(0,"RPG模式未实现 Class ID 列表...");
#else
for(AbstractClassRep *rep = AbstractClassRep::getClassList();
rep;
rep = rep->getNextClass())
{
ConsoleObject *obj = rep->create();
if(obj && rep->getClassId(object->getNetClassGroup()) >= 0)
Con::printf("%7.7d| %s", rep->getClassId(object->getNetClassGroup()), rep->getClassName());
delete obj;
}
#endif
}
ConsoleStaticMethod(GameConnection, getServerConnection, S32, 2, 2, "() Get the server connection if any.")
{
if(GameConnection::getConnectionToServer())
return GameConnection::getConnectionToServer()->getId();
else
{
Con::errorf("GameConnection::getServerConnection - no connection available.");
return -1;
}
}
ConsoleMethod(GameConnection, setCameraObject, S32, 3, 3, "")
{
ShapeBase *obj;
if(!Sim::findObject(argv[2], obj))
return false;
object->setCameraObject(obj);
return true;
}
ConsoleMethod(GameConnection, getCameraObject, S32, 2, 2, "")
{
SimObject *obj = object->getCameraObject();
return obj ? obj->getId() : 0;
}
ConsoleMethod(GameConnection, clearCameraObject, void, 2, 2, "")
{
object->setCameraObject(NULL);
}
ConsoleMethod(GameConnection, isFirstPerson, bool, 2, 2, "() True if this connection is in first person mode.")
{
// Note: Transition to first person occurs over time via mCameraPos, so this
// won't immediately return true after a set.
return object->isFirstPerson();
}
ConsoleMethod(GameConnection, setFirstPerson, void, 3, 3, "(bool firstPerson) Sets this connection into or out of first person mode.")
{
object->setFirstPerson(dAtob(argv[2]));
}
#endif //#ifdef _USE_TGE_NETCONNTION_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -