예제 #1
0
void plNetClientMgr::IDisableNet () {
    ASSERT(fDisableMsg);
    
    if (!GetFlagsBit(kDisabled)) {
        SetFlagsBit(kDisabled);
        // cause subsequent net operations to fail immediately, but don't block
        // waiting for net subsystem to shutdown (we'll do that later)
        NetCommEnableNet(false, false);

        // display a msg to the player
        if ( fDisableMsg->yes )
        {
            if (!GetFlagsBit(plNetClientApp::kPlayingGame))
            {
                // KI may not be loaded
                plString title = plFormat("{} Error", plProduct::CoreName());
                hsMessageBox(fDisableMsg->str, title.c_str(), hsMessageBoxNormal, hsMessageBoxIconError );
                plClientMsg *quitMsg = new plClientMsg(plClientMsg::kQuit);
                quitMsg->Send(hsgResMgr::ResMgr()->FindKey(kClient_KEY));
            }
            else
            {
                pfKIMsg *msg = new pfKIMsg(pfKIMsg::kKIOKDialog);
                msg->SetString(fDisableMsg->str);
                msg->Send();
            }
        }
    }

    hsRefCnt_SafeUnRef(fDisableMsg);
    fDisableMsg = nil;
}
예제 #2
0
//
// returns yes/no
// for special cases, like sceneNodes.
//
int plNetClientMgr::IsLocallyOwned(const plUoid& uoid) const
{
    // we're non-networked
    if ( GetFlagsBit(kDisabled))
        return plSynchedObject::kYes;

    plNetGroupId netGroup = uoid.GetLocation();
    int answer=GetNetGroups()->IsGroupLocal(netGroup);
    
    if (answer==-1)
        answer = IDeduceLocallyOwned(uoid);

    hsAssert(answer==plSynchedObject::kYes || answer==plSynchedObject::kNo, "invalid answer to IsLocallyOwned()");
    return answer;
}
예제 #3
0
void plNetClientMgr::IncNumInitialSDLStates()
{
    fNumInitialSDLStates++;
    DebugMsg( "Received %d initial SDL states", fNumInitialSDLStates );
    if ( GetFlagsBit( plNetClientApp::kNeedInitialAgeStateCount ) )
    {
        DebugMsg( "Need initial SDL state count" );
        return;
    }

    if ( GetNumInitialSDLStates()>=GetRequiredNumInitialSDLStates() )
    {
        ICheckPendingStateLoad(hsTimer::GetSysSeconds());
        NotifyRcvdAllSDLStates();
    }
}
예제 #4
0
//
// check if this object is in a group which is owned (mastered) by this client.
// returns yes/no
//
int plNetClientMgr::IsLocallyOwned(const plSynchedObject* obj) const
{
    // we're non-networked
    if ( GetFlagsBit(kDisabled) )
        return plSynchedObject::kYes;

    if( !obj )
        return plSynchedObject::kNo;

    // object is flagged as local only
    if (!obj->IsNetSynched())
        return plSynchedObject::kYes;

    plNetGroupId netGroup = GetEffectiveNetGroup(obj);
    int answer=GetNetGroups()->IsGroupLocal(netGroup);

    if (answer==-1)     // not sure
        answer = IDeduceLocallyOwned(obj->GetKey()->GetUoid());

    hsAssert(answer==plSynchedObject::kYes || answer==plSynchedObject::kNo, "invalid answer to IsLocallyOwned()");
    return answer;
}
예제 #5
0
//
// initialize net client. returns hsFail on err.
//
int plNetClientMgr::Init()
{
    int ret=hsOK;
    hsLogEntry( DebugMsg("*** plNetClientMgr::Init GMT:%s", plUnifiedTime::GetCurrent().Print()) );
    
    IDumpOSVersionInfo();
    
    if (GetFlagsBit(kNullSend))
        SetNullSend(true);

    VaultInitialize();

    IAddCloneRoom();

    fNetGroups.Reset();

    plgDispatch::Dispatch()->RegisterForExactType(plNetClientMgrMsg::Index(), GetKey());    
    plgDispatch::Dispatch()->RegisterForExactType(plAgeLoadedMsg::Index(), GetKey());   
    plgDispatch::Dispatch()->RegisterForExactType(plAgeLoaded2Msg::Index(), GetKey());  
    plgDispatch::Dispatch()->RegisterForExactType(plCCRPetitionMsg::Index(), GetKey()); 
    plgDispatch::Dispatch()->RegisterForExactType(plPlayerPageMsg::Index(), GetKey());
    plgDispatch::Dispatch()->RegisterForExactType(plInitialAgeStateLoadedMsg::Index(), GetKey());
    plgDispatch::Dispatch()->RegisterForExactType(plNetVoiceListMsg::Index(), GetKey());
    plgDispatch::Dispatch()->RegisterForExactType(plClientMsg::Index(), GetKey());
    plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey());

    plgDispatch::Dispatch()->RegisterForExactType(plNetCommAuthMsg::Index(), GetKey());
    plgDispatch::Dispatch()->RegisterForExactType(plNetCommActivePlayerMsg::Index(), GetKey());
    plgDispatch::Dispatch()->RegisterForExactType(plNetCommLinkToAgeMsg::Index(), GetKey());

    // We need plVaultNotifyMsgs for the NetLinkingMgr
    plgDispatch::Dispatch()->RegisterForType(plVaultNotifyMsg::Index(), GetKey());
    plgDispatch::Dispatch()->RegisterForExactType(plResPatcherMsg::Index(), GetKey());

    IInitNetClientComm();

    return ret; 
}
예제 #6
0
//
// return true if we should send this msg
//
bool plNetClientMgr::CanSendMsg(plNetMessage * msg)
{
    // TEMP
    if (GetFlagsBit(kSilencePlayer))
    {
        if (plNetMsgVoice::ConvertNoRef(msg))
            return false;

        plNetMsgGameMessage* gm=plNetMsgGameMessage::ConvertNoRef(msg);
        if (gm && gm->StreamInfo()->GetStreamType()==pfKIMsg::Index())
        {
            hsReadOnlyStream stream(gm->StreamInfo()->GetStreamLen(), gm->StreamInfo()->GetStreamBuf());
            pfKIMsg* kiMsg = pfKIMsg::ConvertNoRef(hsgResMgr::ResMgr()->ReadCreatable(&stream));
            if (kiMsg && kiMsg->GetCommand()==pfKIMsg::kHACKChatMsg)
            {
                delete kiMsg;
                return false;
            }
            delete kiMsg;
        }
    }

    return true;
}
예제 #7
0
//
// main update fxn for net client code, return hsFail on err
//
int plNetClientMgr::Update(double secs)
{
    int ret=hsOK;   // ret code is unchecked, but what the hay
    
    if (GetFlagsBit(kDisableOnNextUpdate)) {
        SetFlagsBit(kDisableOnNextUpdate, false);
        IDisableNet();
    }
    
    // Pump net messages
    NetCommUpdate();

    static double lastUpdateTime=0;
    double curTime=hsTimer::GetSeconds();
    if (curTime-lastUpdateTime > 1.f)
    {
        DebugMsg("NetClient hasn't updated for %f secs", curTime-lastUpdateTime);
    }
    lastUpdateTime=curTime;

    if (GetFlagsBit(kPlayingGame) )
    {
        MaybeSendPendingPagingRoomMsgs();
        ICheckPendingStateLoad(secs);
        ISendDirtyState(secs);
        IUpdateListenList(secs);
        if (GetFlagsBit(plNetClientApp::kShowLists))
            IShowLists();
        if (GetFlagsBit(plNetClientApp::kShowRooms))
            IShowRooms();
        if (GetFlagsBit(plNetClientApp::kShowAvatars))
            IShowAvatars();
        if (GetFlagsBit(plNetClientApp::kShowRelevanceRegions))
            IShowRelevanceRegions();
    }

    // Send dirty nodes, deliver vault callbacks, etc.
    VaultUpdate();

    plNetLinkingMgr::GetInstance()->Update();

    return ret;
}
예제 #8
0
//
// MsgReceive handler for plasma messages
//
bool plNetClientMgr::MsgReceive( plMessage* msg )
{
    if (plNetLinkingMgr::GetInstance()->MsgReceive( msg ))
        return true;

    plEvalMsg* evalMsg = plEvalMsg::ConvertNoRef(msg);
    if (evalMsg)
    {
        IPlaybackMsgs();

        if ( GetFlagsBit( kNeedToSendAgeLoadedMsg ) )
        {
            SetFlagsBit( kNeedToSendAgeLoadedMsg, false );
            plAgeLoader::GetInstance()->NotifyAgeLoaded( true );
        }

        if ( GetFlagsBit( kNeedToSendInitialAgeStateLoadedMsg ) )
        {
            SetFlagsBit(kNeedToSendInitialAgeStateLoadedMsg, false);
            plInitialAgeStateLoadedMsg* m = new plInitialAgeStateLoadedMsg;
            m->Send();
        }

        return true;
    }

    plGenRefMsg* ref = plGenRefMsg::ConvertNoRef(msg);
    if (ref)
    {
        if( ref->fType == kVaultImage )
        {
            // Ignore, we just use it for reffing, don't care about the actual pointer
            return true;
        }

        hsAssert(ref->fType==kAgeSDLHook, "unknown ref msg context");
        if (ref->GetContext()==plRefMsg::kOnCreate)
        {
            hsAssert(fAgeSDLObjectKey==nil, "already have a ref to age sdl hook");
            fAgeSDLObjectKey = ref->GetRef()->GetKey();
            DebugMsg("Age SDL hook object created, uoid=%s", fAgeSDLObjectKey->GetUoid().StringIze().c_str());
        }
        else
        {
            fAgeSDLObjectKey=nil;
            DebugMsg("Age SDL hook object destroyed");
        }
        return true;
    }

    if (plNetClientMgrMsg * ncmMsg = plNetClientMgrMsg::ConvertNoRef(msg)) {
        if (ncmMsg->type == plNetClientMgrMsg::kCmdDisableNet) {
            SetFlagsBit(kDisableOnNextUpdate);
            hsRefCnt_SafeUnRef(fDisableMsg);
            fDisableMsg = ncmMsg;
            fDisableMsg->Ref();
        }
        return true;
    }
    
    if (plNetCommAuthMsg * authMsg = plNetCommAuthMsg::ConvertNoRef(msg)) {
        if (IS_NET_ERROR(authMsg->result)) {
            char str[256];
            StrPrintf(str, arrsize(str), "Authentication failed: %S", NetErrorToString(authMsg->result));
            QueueDisableNet(true, str);
            return false;   // @@@ TODO: Handle this failure better
        }

        return true;
    }

    if (plNetCommActivePlayerMsg * activePlrMsg = plNetCommActivePlayerMsg::ConvertNoRef(msg)) {
        if (IS_NET_ERROR(activePlrMsg->result)) {
            char str[256];
            StrPrintf(str, arrsize(str), "SetActivePlayer failed: %S", NetErrorToString(activePlrMsg->result));
            QueueDisableNet(true, str);
            return false;   // @@@ TODO: Handle this failure better.
        }
            
        return true;
    }

    plPlayerPageMsg *playerPageMsg = plPlayerPageMsg::ConvertNoRef(msg);
    if(playerPageMsg)
    {
        IHandlePlayerPageMsg(playerPageMsg);
        return true;    // handled
    }

    plLoadCloneMsg* pCloneMsg = plLoadCloneMsg::ConvertNoRef(msg);
    if(pCloneMsg)
    {
        ILoadClone(pCloneMsg);
        return true;    // handled
    }

    // player is petitioning a CCR
    plCCRPetitionMsg* petMsg=plCCRPetitionMsg::ConvertNoRef(msg);
    if (petMsg)
    {
        ISendCCRPetition(petMsg);
        return true;
    }

    // a remote CCR is turning invisible
    plCCRInvisibleMsg* invisMsg=plCCRInvisibleMsg::ConvertNoRef(msg);
    if (invisMsg)
    {
        LogMsg(kLogDebug, "plNetClientMgr::MsgReceive - Got plCCRInvisibleMsg");
        MakeCCRInvisible(invisMsg->fAvKey, invisMsg->fInvisLevel);
        return true;
    }
    
    plCCRBanLinkingMsg* banLinking = plCCRBanLinkingMsg::ConvertNoRef(msg);
    if (banLinking)
    {
        DebugMsg("Setting BanLinking to %d", banLinking->fBan);
        SetFlagsBit(kBanLinking, banLinking->fBan);
        return true;
    }

    plCCRSilencePlayerMsg* silence = plCCRSilencePlayerMsg::ConvertNoRef(msg);
    if (silence)
    {
        DebugMsg("Setting Silence to %d", silence->fSilence);
        SetFlagsBit(kSilencePlayer, silence->fSilence);
        return true;
    }

    plNetVoiceListMsg* voxList = plNetVoiceListMsg::ConvertNoRef(msg);
    if (voxList)
    {
        IHandleNetVoiceListMsg(voxList);
        return true;
    }

    plSynchEnableMsg* synchEnable = plSynchEnableMsg::ConvertNoRef(msg);
    if (synchEnable)
    {
        if (synchEnable->fPush)
        {
            plSynchedObject::PushSynchDisabled(!synchEnable->fEnable);
        }
        else
        {
            plSynchedObject::PopSynchDisabled();
        }
        return true;
    }

    plClientMsg* clientMsg = plClientMsg::ConvertNoRef(msg);
    if (clientMsg && clientMsg->GetClientMsgFlag()==plClientMsg::kInitComplete)
    {
        // add 1 debug object for age sdl
        if (plNetObjectDebugger::GetInstance())
        {
            plNetObjectDebugger::GetInstance()->RemoveDebugObject("AgeSDLHook");    
            plNetObjectDebugger::GetInstance()->AddDebugObject("AgeSDLHook");
        }

        // if we're linking to startup we don't need (or want) a player set
        plString ageName = NetCommGetStartupAge()->ageDatasetName;
        if (ageName.IsEmpty())
            ageName = "StartUp";
        if (ageName.CompareI("StartUp") == 0)
            NetCommSetActivePlayer(0, nullptr);

        plAgeLinkStruct link;
        link.GetAgeInfo()->SetAgeFilename(NetCommGetStartupAge()->ageDatasetName);
        link.SetLinkingRules(plNetCommon::LinkingRules::kOriginalBook);
        plNetLinkingMgr::GetInstance()->LinkToAge(&link);

        return true;
    }
    
    return plNetClientApp::MsgReceive(msg);
}
예제 #9
0
//
// See if there is state recvd from the network that needsto be delivered
//
void plNetClientMgr::ICheckPendingStateLoad(double secs)
{
    // We only care if we're in an age or loading state
    if (!(GetFlagsBit(kPlayingGame) || (GetFlagsBit(kLoadingInitialAgeState) && !GetFlagsBit(kNeedInitialAgeStateCount))))
        return;

    for (auto it = fPendingLoads.begin(); it != fPendingLoads.end();)
    {
        PendingLoad* load = *it;

        // If no key has been cached, we need to find it.
        if (!load->fKey)
        {
            load->fKey = hsgResMgr::ResMgr()->FindKey(load->fUoid);

            // By this point, we should have all the age's keys downloaded from filesrv
            // So, if fKey is null at this point, this state is garbage
            if (!load->fKey)
            {
                ErrorMsg("Key `%s` not found. Discarding state for `%s`",
                          load->fUoid.GetObjectName().c_str(),
                          load->fSDRec->GetDescriptor()->GetName().c_str());
                it = fPendingLoads.erase(it);
                delete load;
                continue;
            }
        }

        // Time to deliver the state!
        plSynchedObject* synchObj = plSynchedObject::ConvertNoRef(load->fKey->ObjectIsLoaded());
        if (synchObj && synchObj->IsFinal())
        {
            plSDLModifierMsg* msg = new plSDLModifierMsg(load->fSDRec->GetDescriptor()->GetName(), plSDLModifierMsg::kRecv);
            msg->SetState(load->fSDRec, true);
            load->fSDRec = nullptr;
            msg->SetPlayerID(load->fPlayerID);

#ifdef HS_DEBUGGING
            if (plNetObjectDebugger::GetInstance()->IsDebugObject(synchObj))
            {
                DebugMsg("Delivering SDL State '%s' to %s owned key %s",
                    msg->GetState()->GetDescriptor()->GetName().c_str(),
                    (synchObj->IsLocallyOwned() == plSynchedObject::kYes) ? "locally" : "remote",
                    load->fUoid.StringIze().c_str());
            }
#endif
            msg->Send(load->fKey);
            it = fPendingLoads.erase(it);
            delete load;
        }
        else if (GetFlagsBit(kPlayingGame))
        {
            // If we're playing the game and object isn't loaded/final, then this state is probably
            // never going to be useful (it's from some paged in hack or something that's been deleted)
            // Throw it away.
            it = fPendingLoads.erase(it);
            delete load;
        }
        else
            ++it;
    }
}
예제 #10
0
void plNetClientMgr::MaybeSendPendingPagingRoomMsgs()
{
    if ( GetFlagsBit( kPlayingGame ) )
        SendPendingPagingRoomMsgs();
}
예제 #11
0
//
// show lists of members, listenList, and talkList
//
void plNetClientMgr::IShowLists()
{
    plNetLinkingMgr * lm = plNetLinkingMgr::GetInstance();
    plDebugText     &txt = plDebugText::Instance();

    int y,x,i;
    const int yOff=10, xOff=300, startY=70, startX=10;
    char str[256];

    // My player info
    x=startX;
    y=startY;
    plSceneObject *player = plSceneObject::ConvertNoRef(GetLocalPlayer());
    hsPoint3 pos = (player ? player->GetLocalToWorld() * hsPoint3(0, 0, 0) : hsPoint3(0, 0, 0));
    sprintf(str, "%s%s PlyrName=%s PlyrID=%d AcctID=%d P2P=%d Join#=%d Peers=%d %.1f,%.1f,%.1f",
        GetFlagsBit(kSendingVoice) ? "V" : " ",
        GetFlagsBit(kSendingActions) ? "A" : " ",
        GetPlayerName().c_str(), GetPlayerID(), 0,
        IsPeerToPeer(), GetJoinOrder(), 0,
        pos.fX, pos.fY, pos.fZ);
    txt.DrawString(x,y,str,255,255,255,255);
    SetFlagsBit(kSendingVoice, 0);
    SetFlagsBit(kSendingActions, 0);

    y+=yOff;
    sprintf(str, "   Server=%s ILIAS=%d", "foo",
        IsLoadingInitialAgeState());
    txt.DrawString(x,y,str,255,255,255,255);
    
    // MEMBERS
    y+=yOff;
    int baseY=y;
    txt.DrawString(x,y,"   Members",255,255,255,255,plDebugText::kStyleBold);
    y+=yOff;
    plNetTransportMember** members=nil;
    fTransport.GetMemberListDistSorted(members);
    for(i=0;i<fTransport.GetNumMembers();i++)
    {
        plNetTransportMember* mbr=members[i];
        hsAssert(mbr, "ShowLists: nil member?");
        if (mbr->IsServer())
            continue;
        player = (mbr->GetAvatarKey() ? plSceneObject::ConvertNoRef(mbr->GetAvatarKey()->ObjectIsLoaded()) : nil);
        sprintf(str, "%s%s %s p2p=%d dist=%.1f",
            mbr->GetTransportFlags() & plNetTransportMember::kSendingVoice ? "V" : " ",
            mbr->GetTransportFlags() & plNetTransportMember::kSendingActions ? "A" : " ",
            mbr->AsString().c_str(),
            mbr->IsPeerToPeer(),
            mbr->GetDistSq() != FLT_MAX ? sqrt(mbr->GetDistSq()) :-1.f);
        txt.DrawString(x,y,str);
        y+=yOff;
        mbr->SetTransportFlags(mbr->GetTransportFlags() & 
            ~(plNetTransportMember::kSendingVoice|plNetTransportMember::kSendingActions));
    }

    delete [] members;
    
    // LISTENLIST
    x+=xOff;
    y=baseY;
    txt.DrawString(x,y,"ListenList",255,255,255,255,plDebugText::kStyleBold);
    y+=yOff;
    for(i=0;i<GetListenList()->GetNumMembers();i++)
    {
        sprintf(str, "name=%s", GetListenList()->GetMember(i)->AsString().c_str());
        txt.DrawString(x,y,str);
        y+=yOff;
    }

    // TALKLIST
    x+=xOff;
    y=baseY;
    txt.DrawString(x,y,"TalkList",255,255,255,255,plDebugText::kStyleBold);
    y+=yOff;
    for(i=0;i<GetTalkList()->GetNumMembers();i++)
    {
        sprintf(str, "name=%s", GetTalkList()->GetMember(i)->AsString().c_str());
        txt.DrawString(x,y,str);
        y+=yOff;
    }
}