void plKeyFinder::ReallyStupidActivatorSearch(const plString &name, std::vector<plKey>& foundKeys, const plLocation &hintLocation) { // use the createable macro so we don't have to pull in all of Python ReallyStupidSubstringSearch(name, CLASS_INDEX_SCOPED(plLogicModifier), foundKeys, hintLocation); ReallyStupidSubstringSearch(name, CLASS_INDEX_SCOPED(plPythonFileMod), foundKeys, hintLocation); ReallyStupidSubstringSearch(name, CLASS_INDEX_SCOPED(plSittingModifier), foundKeys, hintLocation); }
bool plNetClientRecorder::IsRecordableMsg(plNetMessage* msg) const { uint16_t idx = msg->ClassIndex(); return ( idx == CLASS_INDEX_SCOPED(plNetMsgLoadClone) || idx == CLASS_INDEX_SCOPED(plNetMsgSDLStateBCast) || idx == CLASS_INDEX_SCOPED(plNetMsgSDLState) || idx == CLASS_INDEX_SCOPED(plNetMsgGameMessage) ); }
bool plNetClientStressStreamRecorder::IsRecordableMsg(plNetMessage* msg) const { uint16_t idx = msg->ClassIndex(); return ( plNetClientStreamRecorder::IsRecordableMsg(msg) || idx == CLASS_INDEX_SCOPED(plNetMsgTestAndSet) || idx == CLASS_INDEX_SCOPED(plNetMsgGameMessageDirected) || idx == CLASS_INDEX_SCOPED(plNetMsgVoice) ); }
bool plNetClientStreamRecorder::IIsValidMsg(plNetMessage* msg) { if (plNetMsgGameMessage* gameMsg = plNetMsgGameMessage::ConvertNoRef(msg)) { int16_t type = gameMsg->StreamInfo()->GetStreamType(); // // These messages will be regenerated if they are for the local avatar, // so don't dispatch them in that case. // if (type == CLASS_INDEX_SCOPED(plLinkEffectsTriggerMsg)) { plLinkEffectsTriggerMsg* linkMsg = plLinkEffectsTriggerMsg::ConvertNoRef(gameMsg->GetContainedMsg(GetResMgr())); if (plNetClientApp::GetInstance()) { bool isLocal = (linkMsg->GetLinkKey() == plNetClientApp::GetInstance()->GetLocalPlayerKey()); hsRefCnt_SafeUnRef(linkMsg); if (isLocal) { ILogMsg(msg, "IGNORING "); return false; } } } else if (type == CLASS_INDEX_SCOPED(plLoadAvatarMsg)) { plLoadAvatarMsg* loadAvMsg = plLoadAvatarMsg::ConvertNoRef(gameMsg->GetContainedMsg(GetResMgr())); if (plNetClientApp::GetInstance()) { bool isLocal = (loadAvMsg->GetCloneKey() == plNetClientApp::GetInstance()->GetLocalPlayerKey()); hsRefCnt_SafeUnRef(loadAvMsg); if (isLocal) { ILogMsg(msg, "IGNORING "); return false; } } } } ILogMsg(msg); return true; }
plKey plKeyFinder::IFindSceneNodeKey(plRegistryPageNode* page) const { // Got the pageNode, try a find before loading plRegistryKeyList* keyList = page->IGetKeyList(CLASS_INDEX_SCOPED(plSceneNode)); if (keyList) { if (keyList->fStaticKeys.size() == 1) { return plKey::Make((plKeyData*)keyList->fStaticKeys[0]); } else if (keyList->fDynamicKeys.size() == 1) // happens during export { plRegistryKeyList::DynSet::const_iterator it = keyList->fDynamicKeys.begin(); plKeyImp* keyImp = *it; return plKey::Make(keyImp); } } // Try loading and see if that helps if (page->IsFullyLoaded()) return nil; IGetResMgr()->LoadPageKeys(page); // Get the list of all sceneNodes plKey retVal(nil); keyList = page->IGetKeyList(CLASS_INDEX_SCOPED(plSceneNode)); if (keyList && keyList->fStaticKeys.size() == 1) { retVal = plKey::Make((plKeyData*)keyList->fStaticKeys[0]); } // If we just loaded up all the keys for this page, then we // may have a bunch of keys with a refcount of 0. For any of // these keys that nothing else refs (yes, we have unused objects // in the data), they don't get deleted because the refcount never // rises above zero or falls back to zero. So we'll go ahead and // ref and unref all of them. The ones in use stay put, the ones // not being used go away. This is less than ideal. IGetResMgr()->DumpUnusedKeys(page); return retVal; }
bool plNetClientLoggingRecorder::IProcessRecordMsg(plNetMessage* msg, double secs) { if (msg->ClassIndex() == CLASS_INDEX_SCOPED(plNetMsgGameMessage)) { plNetMsgGameMessage* gameMsg = plNetMsgGameMessage::ConvertNoRef(msg); uint16_t gameMsgIdx = gameMsg->StreamInfo()->GetStreamType(); if (gameMsgIdx == CLASS_INDEX_SCOPED(plServerReplyMsg)) return false; // Throw out any notify messages that don't involve picking (running into // detectors and that sort of thing should be recreated automatically // during playback) if (gameMsgIdx == CLASS_INDEX_SCOPED(plNotifyMsg)) { bool hasPick = false; plNotifyMsg* notifyMsg = plNotifyMsg::ConvertNoRef(gameMsg->GetContainedMsg()); int numEvents = notifyMsg->GetEventCount(); for (int i = 0; i < numEvents; i++) { proEventData* event = notifyMsg->GetEventRecord(i); if (event->fEventType == proEventData::kPicked) hasPick = true; } hsRefCnt_SafeUnRef(notifyMsg); if (!hasPick) return false; } } if (fPlaybackTimeOffset == 0) fPlaybackTimeOffset = secs; return true; }
void plNetClientStreamRecorder::ILogMsg(plNetMessage* msg, const char* preText) { if (msg->ClassIndex() == CLASS_INDEX_SCOPED(plNetMsgGameMessage)) { plNetMsgGameMessage* gameMsg = plNetMsgGameMessage::ConvertNoRef(msg); fLog->AddLineF("%s%s(%s)", preText, msg->ClassName(), plFactory::GetNameOfClass(gameMsg->StreamInfo()->GetStreamType())); if (gameMsg->StreamInfo()->GetStreamType() == CLASS_INDEX_SCOPED(plNotifyMsg)) { plNotifyMsg* notifyMsg = plNotifyMsg::ConvertNoRef(gameMsg->GetContainedMsg(GetResMgr())); int numEvents = notifyMsg->GetEventCount(); for (int i = 0; i < numEvents; i++) { const char* eventName = ""; proEventData* event = notifyMsg->GetEventRecord(i); switch (event->fEventType) { case proEventData::kCollision: eventName = "Collision"; break; case proEventData::kPicked: eventName = "Picked"; break; case proEventData::kControlKey: eventName = "ControlKey"; break; case proEventData::kVariable: eventName = "Variable"; break; case proEventData::kFacing: eventName = "Facing"; break; case proEventData::kContained: eventName = "Contained"; break; case proEventData::kActivate: eventName = "Activate"; break; case proEventData::kCallback: eventName = "Callback"; break; case proEventData::kResponderState: eventName = "ResponderState"; break; case proEventData::kMultiStage: eventName = "MultiStage"; break; case proEventData::kSpawned: eventName = "Spawned"; break; case proEventData::kClickDrag: eventName = "ClickDrag"; break; } fLog->AddLineF("\t%s", eventName); } hsRefCnt_SafeUnRef(notifyMsg); } } else if (plNetMsgSDLState* sdlMsg = plNetMsgSDLState::ConvertNoRef(msg)) { hsReadOnlyStream stream(sdlMsg->StreamInfo()->GetStreamLen(), sdlMsg->StreamInfo()->GetStreamBuf()); char* descName=nil; int ver; if (plStateDataRecord::ReadStreamHeader(&stream, &descName, &ver)) { fLog->AddLineF("%s%s(%s)", preText, msg->ClassName(), descName); int i; plStateDataRecord sdRec(descName, ver); sdRec.Read(&stream, 0); plStateDataRecord::SimpleVarsList vars; sdRec.GetDirtyVars(&vars); for (i = 0; i < vars.size(); i++) { fLog->AddLineF("\t%s", vars[i]->GetVarDescriptor()->GetName()); } plStateDataRecord::SDVarsList sdVars; sdRec.GetDirtySDVars(&sdVars); for (i = 0; i < sdVars.size(); i++) { fLog->AddLineF("\t%s", sdVars[i]->GetSDVarDescriptor()->GetName()); } } delete [] descName; } else fLog->AddLineF("%s%s", preText, msg->ClassName()); }
void plKeyFinder::GetResponderNames(std::vector<plString>& names) { IGetNames(names, "", CLASS_INDEX_SCOPED(plResponderModifier)); }
bool plNetClientMgr::IHandlePlayerPageMsg(plPlayerPageMsg *playerMsg) { bool result = false; plKey playerKey = playerMsg->fPlayer; int idx; if(playerMsg->fUnload) { if (GetLocalPlayerKey() == playerKey) { fLocalPlayerKey = nil; DebugMsg("Net: Unloading local player %s", playerKey->GetName().c_str()); // notify server - NOTE: he might not still be around to get this... plNetMsgPlayerPage npp (playerKey->GetUoid(), playerMsg->fUnload); npp.SetNetProtocol(kNetProtocolCli2Game); SendMsg(&npp); } else if (IsRemotePlayerKey(playerKey, &idx)) { fRemotePlayerKeys.erase(fRemotePlayerKeys.begin()+idx); // remove key from list DebugMsg("Net: Unloading remote player %s", playerKey->GetName().c_str()); } } else { plSceneObject *playerSO = plSceneObject::ConvertNoRef(playerKey->ObjectIsLoaded()); if (!playerSO) { hsStatusMessageF("Ignoring player page message for non-existant player."); } else if(playerMsg->fPlayer) { if (playerMsg->fLocallyOriginated) { hsAssert(!GetLocalPlayerKey() || GetLocalPlayerKey() == playerKey, "Different local player already loaded"); hsLogEntry(DebugMsg("Adding LOCAL player %s\n", playerKey->GetName().c_str())); playerSO->SetNetGroupConstant(plNetGroup::kNetGroupLocalPlayer); // don't save avatar state permanently on server playerSO->SetSynchFlagsBit(plSynchedObject::kAllStateIsVolatile); const plCoordinateInterface* co = playerSO->GetCoordinateInterface(); if (co) { int i; for(i=0;i<co->GetNumChildren();i++) { if (co->GetChild(i) && co->GetChild(i)->GetOwner()) const_cast<plSceneObject*>(co->GetChild(i)->GetOwner())->SetSynchFlagsBit(plSynchedObject::kAllStateIsVolatile); } } // notify server plNetMsgPlayerPage npp (playerKey->GetUoid(), playerMsg->fUnload); npp.SetNetProtocol(kNetProtocolCli2Game); SendMsg(&npp); } else { hsLogEntry(DebugMsg("Adding REMOTE player %s\n", playerKey->GetName().c_str())); playerSO->SetNetGroupConstant(plNetGroup::kNetGroupRemotePlayer); idx=fTransport.FindMember(playerMsg->fClientID); if( idx != -1 ) { hsAssert(playerKey, "NIL KEY?"); hsAssert(!playerKey->GetName().IsNull(), "UNNAMED KEY"); fTransport.GetMember(idx)->SetAvatarKey(playerKey); } else { hsLogEntry(DebugMsg("Ignoring player page msg (player not found in member list) : %s\n", playerKey->GetName().c_str())); } } hsAssert(IFindModifier(playerSO, CLASS_INDEX_SCOPED(plAvatarSDLModifier)), "avatar missing avatar SDL modifier"); hsAssert(IFindModifier(playerSO, CLASS_INDEX_SCOPED(plClothingSDLModifier)), "avatar missing clothing SDL modifier"); hsAssert(IFindModifier(playerSO, CLASS_INDEX_SCOPED(plAGMasterSDLModifier)), "avatar missing AGMaster SDL modifier"); result = true; } } return result; }
void plKeyFinder::GetActivatorNames(std::vector<plString>& names) { IGetNames(names, _TEMP_CONVERT_FROM_LITERAL(""), CLASS_INDEX_SCOPED(plLogicModifier)); }
// // Try to accept/reject quickly // the netMsg arg has been peeked except for the stream // plNetMsgScreener::Answer plNetMsgScreener::IAllowMessageType(int16_t classIndex, const plNetGameMember* gm) const { // Check based on exact type switch(classIndex) { // these are wrapped in their own net msg, so the client will see them this way, but not the server // that's why they check IAmClient() - this is a special case case CLASS_INDEX_SCOPED(plLoadAvatarMsg): case CLASS_INDEX_SCOPED(plLoadCloneMsg): { Answer ans=IAmClient() ? kYes : kNo; if (ans==kNo) { IRejectLogMsg(classIndex, "Only seen in native form on client", gm); } return ans; } // definitely yes case CLASS_INDEX_SCOPED(pfMarkerMsg): case CLASS_INDEX_SCOPED(plBulletMsg): case CLASS_INDEX_SCOPED(plNotifyMsg): case CLASS_INDEX_SCOPED(plSetNetGroupIDMsg): case CLASS_INDEX_SCOPED(plAvCoopMsg): case CLASS_INDEX_SCOPED(plClothingMsg): case CLASS_INDEX_SCOPED(plEnableMsg): case CLASS_INDEX_SCOPED(plLinkToAgeMsg): case CLASS_INDEX_SCOPED(plSubWorldMsg): case CLASS_INDEX_SCOPED(plDynamicTextMsg): return kYes; // conditionally yes, requires further validation of msg contents case CLASS_INDEX_SCOPED(plAnimCmdMsg): case CLASS_INDEX_SCOPED(pfKIMsg): case CLASS_INDEX_SCOPED(plAvTaskMsg): case CLASS_INDEX_SCOPED(plLinkEffectsTriggerMsg): case CLASS_INDEX_SCOPED(plInputIfaceMgrMsg): case CLASS_INDEX_SCOPED(plParticleKillMsg): case CLASS_INDEX_SCOPED(plParticleTransferMsg): case CLASS_INDEX_SCOPED(plAvatarInputStateMsg): case CLASS_INDEX_SCOPED(plAvBrainGenericMsg): case CLASS_INDEX_SCOPED(plMultistageModMsg): return kMaybe; // definitely no default: IRejectLogMsg(classIndex, "Illegal msg class", gm); return kNo; } }
plMessage* plResponderModifier::IGetFastForwardMsg(plMessage* msg, bool python) { if (!msg) return nil; if (plAnimCmdMsg* animMsg = plAnimCmdMsg::ConvertNoRef(msg)) { if (animMsg->Cmd(plAnimCmdMsg::kContinue) || animMsg->Cmd(plAnimCmdMsg::kAddCallbacks)) { plAnimCmdMsg* newAnimMsg = new plAnimCmdMsg; newAnimMsg->fCmd = animMsg->fCmd; newAnimMsg->fBegin = animMsg->fBegin; newAnimMsg->fEnd = animMsg->fEnd; newAnimMsg->fLoopEnd = animMsg->fLoopEnd; newAnimMsg->fLoopBegin = animMsg->fLoopBegin; newAnimMsg->fSpeed = animMsg->fSpeed; newAnimMsg->fSpeedChangeRate = animMsg->fSpeedChangeRate; newAnimMsg->fTime = animMsg->fTime; newAnimMsg->SetAnimName(animMsg->GetAnimName()); newAnimMsg->SetLoopName(animMsg->GetLoopName()); // Remove the callbacks newAnimMsg->fCmd.SetBit(plAnimCmdMsg::kAddCallbacks, false); if (newAnimMsg->Cmd(plAnimCmdMsg::kContinue)) { newAnimMsg->fCmd.SetBit(plAnimCmdMsg::kContinue, false); newAnimMsg->fCmd.SetBit(plAnimCmdMsg::kFastForward, true); } for (int i = 0; i < animMsg->GetNumReceivers(); i++) newAnimMsg->AddReceiver(animMsg->GetReceiver(i)); ResponderLog(ILog(plStatusLog::kWhite, "FF Animation Play Msg")); return newAnimMsg; } ResponderLog(ILog(plStatusLog::kWhite, "FF Animation Non-Play Msg")); hsRefCnt_SafeRef(msg); return msg; } else if(plSoundMsg *soundMsg = plSoundMsg::ConvertNoRef(msg)) { if( fFlags & kSkipFFSound ) { return nil; } if(soundMsg->Cmd(plSoundMsg::kPlay) || soundMsg->Cmd(plSoundMsg::kToggleState) || soundMsg->Cmd(plAnimCmdMsg::kAddCallbacks)) { plSoundMsg *newSoundMsg = new plSoundMsg; newSoundMsg->fCmd = soundMsg->fCmd; newSoundMsg->fBegin = soundMsg->fBegin; newSoundMsg->fEnd = soundMsg->fEnd; newSoundMsg->fLoop = soundMsg->fLoop; newSoundMsg->fSpeed = soundMsg->fSpeed; newSoundMsg->fTime = soundMsg->fTime; newSoundMsg->fIndex = soundMsg->fIndex; newSoundMsg->fRepeats = soundMsg->fRepeats; newSoundMsg->fPlaying = soundMsg->fPlaying; newSoundMsg->fNameStr = soundMsg->fNameStr; newSoundMsg->fVolume = soundMsg->fVolume; // Remove the callbacks newSoundMsg->fCmd.SetBit(plSoundMsg::kAddCallbacks, false); if(newSoundMsg->Cmd(plSoundMsg::kPlay)) { newSoundMsg->fCmd.SetBit(plSoundMsg::kPlay, false); newSoundMsg->fCmd.SetBit(plSoundMsg::kFastForwardPlay); ResponderLog(ILog(plStatusLog::kWhite, "FF Sound Play Msg")); } else if(newSoundMsg->Cmd(plSoundMsg::kToggleState)) { newSoundMsg->fCmd.SetBit(plSoundMsg::kToggleState, false); newSoundMsg->fCmd.SetBit(plSoundMsg::kFastForwardToggle); ResponderLog(ILog(plStatusLog::kWhite, "FF Sound Toggle State Msg")); } for (int i = 0; i < soundMsg->GetNumReceivers(); i++) newSoundMsg->AddReceiver(soundMsg->GetReceiver(i)); return newSoundMsg; } ResponderLog(ILog(plStatusLog::kWhite, "FF Sound Non-Play/Toggle Msg")); hsRefCnt_SafeRef(msg); return msg; } else if (msg->ClassIndex() == CLASS_INDEX_SCOPED(plExcludeRegionMsg)) { ResponderLog(ILog(plStatusLog::kWhite, "FF Exclude Region Msg")); hsRefCnt_SafeRef(msg); return msg; } else if (msg->ClassIndex() == CLASS_INDEX_SCOPED(plEnableMsg)) { ResponderLog(ILog(plStatusLog::kWhite, "FF Visibility/Detector Enable Msg")); hsRefCnt_SafeRef(msg); return msg; } else if (msg->ClassIndex() == CLASS_INDEX_SCOPED(plResponderEnableMsg)) { ResponderLog(ILog(plStatusLog::kWhite, "FF Responder Enable Msg")); hsRefCnt_SafeRef(msg); return msg; } else if (msg->ClassIndex() == CLASS_INDEX_SCOPED(plSimSuppressMsg)) { ResponderLog(ILog(plStatusLog::kWhite, "FF Physical Enable Msg")); hsRefCnt_SafeRef(msg); return msg; } return nil; }
// // Message may be allowed if contents or conditions are met // bool plNetMsgScreener::IValidateMessage(const plMessage* msg, const plNetGameMember* gm) const { if (!msg) return true; switch(msg->ClassIndex()) { // Only chat KI msgs are allowed. // Admin/system-wide chat msgs are only allowed by CCRs case CLASS_INDEX_SCOPED(pfKIMsg): { const pfKIMsg* km = pfKIMsg::ConvertNoRef(msg); if (km->GetCommand() != pfKIMsg::kHACKChatMsg) { IRejectLogMsg(msg, "Non-chat KI msg", gm); return false; } ILogChatMessage(msg, gm); if (km->GetFlags() & pfKIMsg::kAdminMsg) { if (!IIsSenderCCR(gm)) { IRejectLogMsg(msg, "Must be a CCR to send an Admin KI msg", gm); return false; } } return true; } break; // Allowed for local avatar case CLASS_INDEX_SCOPED(plAvTaskMsg): case CLASS_INDEX_SCOPED(plAvatarInputStateMsg): case CLASS_INDEX_SCOPED(plAvBrainGenericMsg): case CLASS_INDEX_SCOPED(plMultistageModMsg): { bool ret=IIsLocalArmatureModKey(msg->GetReceiver(0), gm); if (!ret) { IRejectLogMsg(msg, "msg must refer to local avatar", gm); } return ret; } // Allowed for local avatar case CLASS_INDEX_SCOPED(plLinkEffectsTriggerMsg): { const plLinkEffectsTriggerMsg* linkMsg = plLinkEffectsTriggerMsg::ConvertNoRef(msg); bool ret=IIsLocalAvatarKey(linkMsg->GetLinkKey(), gm); if (!ret) { IRejectLogMsg(msg, "msg must refer to local avatar", gm); } return ret; } // Allowed for local avatar case CLASS_INDEX_SCOPED(plInputIfaceMgrMsg): { const plInputIfaceMgrMsg* iMsg = plInputIfaceMgrMsg::ConvertNoRef(msg); bool ret=IIsLocalAvatarKey(iMsg->GetAvKey(), gm); if (!ret) { IRejectLogMsg(msg, "msg must refer to local avatar", gm); } return ret; } break; case CLASS_INDEX_SCOPED(plParticleKillMsg): case CLASS_INDEX_SCOPED(plParticleTransferMsg): { bool ret = IIsLocalAvatarKey(msg->GetReceiver(0), gm); if (!ret) { IRejectLogMsg(msg, "msg must refer to local avatar", gm); } return ret; } break; case CLASS_INDEX_SCOPED(plAnimCmdMsg): { const plAnimCmdMsg *animMsg = plAnimCmdMsg::ConvertNoRef(msg); bool ret = (animMsg->GetNumCallbacks() == 0); if (!ret) { IRejectLogMsg(msg, "msg has callbacks", gm); } return ret; } break; default: return false; } }
void plKeyFinder::GetActivatorNames(std::vector<plString>& names) { IGetNames(names, "", CLASS_INDEX_SCOPED(plLogicModifier)); }
#include "plKey.h" #include "plUoid.h" #include <string.h> #include "hsResMgr.h" #define TRACK_REFS 0 // MEMLEAKFISH #if TRACK_REFS #include "plCreatableIndex.h" #include "plClassIndexMacros.h" #include "plTweak.h" int mlfTrack = 1; static const char* keyNameToLookFor = "AgeSDLHook"; static const uint16_t CLASS_TO_TRACK = CLASS_INDEX_SCOPED(plSceneObject); static const int kCloneID = 0; static const int kClonePlayerID = 0; static plKeyData* lastData = nil; static const int kLocSeq = -1; class keyDataFriend : public plKeyData { public: uint16_t RefCount() const { return fRefCount; } }; static int IsTracked(const plKeyData* keyData) { if( mlfTrack && keyData ) {
return true; } return false; } }; // Rules for SeedList: // 1) Must be in the Same order as enum fixedKey // 2) For now at least, all your fixed keys get put into the kGlobalFixedLoc room, reserved just for fixed keys // 2) Be sure your ClassIndex CLASS_INDEX(plSceneObject) matches the type of object you want to have the fixedKey // 3) Make sure the Obj is unique for this location/Type Combo... (validated at runtime) plKeySeed SeedList[] = { // Key Enum Type Obj { kFirst_Fixed_KEY, CLASS_INDEX_SCOPED( plSceneObject ), "kFirst_Fixed_KEY", }, { kLOSObject_KEY, CLASS_INDEX_SCOPED( plLOSDispatch ), "kLOSObject_KEY", }, { kTimerCallbackManager_KEY, CLASS_INDEX_SCOPED( plTimerCallbackManager ), "kTimerCallbackManager_KEY", }, { kConsoleObject_KEY, CLASS_INDEX_SCOPED( pfConsole ), "kConsoleObject_KEY", }, { kAudioSystem_KEY, CLASS_INDEX_SCOPED( plAudioSystem ), "kAudioSystem_KEY", }, { kInput_KEY, CLASS_INDEX_SCOPED( plInputManager ), "kInput_KEY", }, { kClient_KEY, CLASS_INDEX_SCOPED( plClient ), "kClient_KEY", }, { kNetClientMgr_KEY, CLASS_INDEX_SCOPED( plNetClientMgr ), "kNetClientMgr_KEY", }, { kListenerMod_KEY, CLASS_INDEX_SCOPED( plListener ), "kListenerMod_KEY", }, { kTransitionMgr_KEY, CLASS_INDEX_SCOPED( plTransitionMgr ), "kTransitionMgr_KEY", }, { kLinkEffectsMgr_KEY, CLASS_INDEX_SCOPED( plLinkEffectsMgr ), "kLinkEffectsMgr_KEY", }, { kGameGUIMgr_KEY, CLASS_INDEX_SCOPED( pfGameGUIMgr ), "kGameGUIMgr_KEY", }, { kGameGUIDynamicDlg_KEY, CLASS_INDEX_SCOPED( plSceneNode ), "kGameGUIDynamicDlg_KEY", }, { kVirtualCamera1_KEY, CLASS_INDEX_SCOPED( plVirtualCam1 ), "kVirtualCamera_KEY", }, { kDefaultCameraMod1_KEY, CLASS_INDEX_SCOPED( plCameraModifier1 ), "kDefaultCameraMod1_KEY", },
void plKeyFinder::ReallyStupidResponderSearch(const plString &name, std::vector<plKey>& foundKeys, const plLocation &hintLocation ) { ReallyStupidSubstringSearch(name, CLASS_INDEX_SCOPED(plResponderModifier), foundKeys, hintLocation); }