예제 #1
0
//
// read descriptors into provided list 
// return number of bytes
//
int plSDLMgr::Read(hsStream* s, plSDL::DescriptorList* dl)
{
    int pos=s->GetPosition();

    if (dl==nil)
        dl=&fDescriptors;

    // clear dl
    IDeleteDescriptors(dl);

    uint16_t num;
    try
    {       
        // read dtor list
        s->ReadLE(&num);

        int i;
        for(i=0;i<num;i++)
        {
            plStateDescriptor* sd=new plStateDescriptor;
            if (sd->Read(s))
                dl->push_back(sd);
            else
                delete sd; // well that sucked
        }
    }
    catch (std::exception &e)
    {
        if (fNetApp)
        {
            hsLogEntry(fNetApp->DebugMsg("Something bad happened while reading SDLMgr data: {}", e.what()));
        }
        else
        {
            DebugMsg("Something bad happened while reading SDLMgr data: {}", e.what());
        }
        return 0;
    }
    catch (...)
    {
        if (fNetApp)
        {
            hsLogEntry(fNetApp->DebugMsg("Something bad happened while reading SDLMgr data"));
        }
        return 0;
    }

    int bytes=s->GetPosition()-pos;
    if (fNetApp)
    {
        hsLogEntry(fNetApp->DebugMsg("Reading {} SDL descriptors, {} bytes", num, bytes));
    }
    return bytes;
}
예제 #2
0
bool plNetLinkingMgr::IProcessLinkingMgrMsg( plLinkingMgrMsg * msg )
{
    plNetClientMgr * nc = plNetClientMgr::GetInstance();

    bool result = true;

    switch ( msg->GetCmd() )
    {
    /////////////////////
    case kLinkPlayerHere:
        {
            // player wants to link to our age
            uint32_t playerID = msg->GetArgs()->GetInt( 0 );
            hsLogEntry( nc->DebugMsg( "Linking player %lu to this age.", playerID ) );
            LinkPlayerHere( playerID );
        }
        break;
        
    /////////////////////
    case kLinkPlayerToPrevAge:
        {
            // link myself back to my last age
            hsLogEntry( nc->DebugMsg( "Linking back to my last age.") );
            LinkToPrevAge();
        }
        break;
    /////////////////////
    case kOfferLinkToPlayer:
        {
//          // Notify the KI that we received an offer.
//          plVaultNotifyMsg * notify = new plVaultNotifyMsg();
//          notify->SetType( plVaultNotifyMsg::kPlayerOfferedLink );
//          notify->GetArgs()->AddItem( 0, msg->GetArgs()->GetItem( 0 ), true );    // add to notify and have notify take over memory management of the item.
//          msg->GetArgs()->RemoveItem( 0, true );  // msg to stop memory managing item, notify msg will delete it.
//          notify->Send();

            plAgeLinkStruct *myLink = plAgeLinkStruct::ConvertNoRef(msg->GetArgs()->GetItem( 0 ));
            LinkToAge(myLink);
        }
        break;

    /////////////////////
    default:
        hsAssert( false, "IProcessLinkingMgrMsg: Unknown linking mgr cmd." );
        result = false;
        break;
    }

    return result;
}
예제 #3
0
bool plNetLinkingMgr::MsgReceive( plMessage *msg )
{
    if (s_ageLeaver && NCAgeLeaverMsgReceive(s_ageLeaver, msg))
        return true;

    if (s_ageJoiner && NCAgeJoinerMsgReceive(s_ageJoiner, msg))
        return true;

    if (plLinkToAgeMsg * pLinkMsg = plLinkToAgeMsg::ConvertNoRef(msg)) {
        if (!fLinkingEnabled)
            hsLogEntry(plNetClientMgr::GetInstance()->DebugMsg("Not linking. Linking is disabled."));
        else
            IProcessLinkToAgeMsg(pLinkMsg);
        return true;
    }

    if (plLinkingMgrMsg * pLinkingMgrMsg = plLinkingMgrMsg::ConvertNoRef(msg)) {
        IProcessLinkingMgrMsg( pLinkingMgrMsg );
        return true;
    }

    // If a link was deferred in order to register an owned age, we will
    // get a VaultNotify about the registration
    if (plVaultNotifyMsg* vaultMsg = plVaultNotifyMsg::ConvertNoRef(msg)) {
        IProcessVaultNotifyMsg(vaultMsg);
        return true;
    }

    return false;
}
void plNetTransport::DumpState()
{
    plNetClientMgr* nc=plNetClientMgr::GetInstance();
    
    hsLogEntry( nc->DebugMsg("-------------------\n") );
    hsLogEntry( nc->DebugMsg("Num Channels=%d\n", fChannelGroups.size()) );

    int i;
    for(i=0;i<fChannelGroups.size();i++)
    {
        plMembersList* mList = &fChannelGroups[i];
        hsLogEntry( nc->DebugMsg("\tChannel %d, num mbrs=%d\n", i, mList->size()) );
        int j;
        for(j=0; j<mList->size();j++)
        {
            plNetTransportMember * mbr = (*mList)[j];
            hsLogEntry( nc->DebugMsg("\t\tMbr %s\n",(*mList)[j]->AsString().c_str()) );
        }
    }

    nc->DebugMsg("Num Mbrs=%d\n", GetNumMembers());
    for(i=0;i<GetNumMembers();i++)
    {
        plNetTransportMember * mbr = GetMember(i);
        hsLogEntry (nc->DebugMsg("\tMbr %d, name=%s, plyrID=%lu, subs=%d", 
            i,mbr->AsString().c_str(),mbr->GetPlayerID(),mbr->GetNumSubscriptions()) );
        int j;
        for(j=0;j<mbr->GetNumSubscriptions();j++)
        {
            hsLogEntry( nc->DebugMsg("\t\tSub %d, chan=%d\n", j, mbr->GetSubscription(j)) );
        }
    }
    hsLogEntry( nc->DebugMsg("\n") );
}
void plCreatableListHelper::Read( hsStream* s, hsResMgr* mgr )
{
    IClearItems();

    s->LogSubStreamStart("CreatableListHelper");

    s->LogReadLE( &fFlags, "Flags" );

    fFlags &= ~kWritten;

    uint32_t bufSz;
    s->LogReadLE( &bufSz, "BufSz" );
    std::string buf;
    buf.resize( bufSz );

    if ( fFlags&kCompressed )
    {
        uint32_t zBufSz;
        s->LogReadLE( &zBufSz, "Compressed BufSz" );
        std::string zBuf;
        zBuf.resize( zBufSz );
        s->LogSubStreamPushDesc("Compressed Data");
        s->Read( zBufSz, (void*)zBuf.data() );
        plZlibCompress compressor;
        uint32_t tmp;
        hsBool ans = compressor.Uncompress( (uint8_t*)buf.data(), &tmp, (uint8_t*)zBuf.data(), zBufSz );
        hsAssert( ans!=0, "plCreatableListHelper: Failed to uncompress buffer." );
        hsAssert( tmp==bufSz, "compression size mismatch" );
        fFlags&=~kCompressed;
        hsLogEntry( plNetApp::StaticDebugMsg( "plCreatableListHelper: uncompressed from %lu to %lu", zBufSz, bufSz ) );
    }
    else
    {
        s->LogSubStreamPushDesc("Uncompressed Data");
        s->Read( bufSz, (void*)buf.data() );
    }

    hsReadOnlyStream ram( bufSz, (void*)buf.data() );

    uint16_t nItems;
    ram.ReadLE( &nItems );
    for ( int i=0; i<nItems; i++ )
    {
        uint16_t id;
        uint16_t classIdx;
        ram.ReadLE( &id );
        ram.ReadLE( &classIdx );
        plCreatable * object = plFactory::Create( classIdx );
        hsAssert( object,"plCreatableListHelper: Failed to create plCreatable object (invalid class index?)" );
        if ( object )
        {
            fManagedItems.push_back( object );
            object->Read( &ram, mgr );
            fItems[id] = object;
        }
    }
}
예제 #6
0
// link myself back to my last age
void plNetLinkingMgr::LinkToPrevAge( uint32_t playerID )
{
    if ( !fLinkingEnabled )
    {
        hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg( "Not linking. Linking is disabled." ) );
        return;
    }

    if (GetPrevAgeLink()->GetAgeInfo()->HasAgeFilename())
    {
        plLinkToAgeMsg* pMsg = new plLinkToAgeMsg( GetPrevAgeLink() );
        IDispatchMsg( pMsg, playerID );
    }
    else
    {
        hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg( "Not linking. No prev age fileName." ) );
    }
}
예제 #7
0
void plSDLParser::DebugMsg(const ST::string& msg) const
{
    return;
    plNetApp* netApp = plSDLMgr::GetInstance()->GetNetApp();

    if (netApp)
        hsLogEntry(netApp->DebugMsg(msg));
    else
        hsStatusMessage(msg.c_str());
}
예제 #8
0
bool plNetLinkingMgr::IProcessLinkToAgeMsg( plLinkToAgeMsg * msg )
{
    if (!fLinkingEnabled) {
        hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg( "Not linking. Linking is disabled." ) );
        return false;
    }

    plNetClientMgr * nc = plNetClientMgr::GetInstance();

    bool result = true;

    plAgeLinkStruct save;
    save.CopyFrom( GetPrevAgeLink() );
    GetPrevAgeLink()->CopyFrom( GetAgeLink() );
    GetAgeLink()->CopyFrom( msg->GetAgeLink() );

    // Actually do stuff...
    uint8_t pre = IPreProcessLink();
    if (pre == kLinkImmediately)
    {
        msg->Ref();
        IDoLink(msg);
    }
    else if (pre == kLinkDeferred)
    {
        msg->Ref();
        fDeferredLink = msg;
    }
    else if (pre == kLinkFailed)
    {
        hsLogEntry( nc->ErrorMsg( "IPreProcessLink failed. Not linking." ) );
        // Restore previous age info state.
        GetAgeLink()->CopyFrom( GetPrevAgeLink() );
        GetPrevAgeLink()->CopyFrom( &save );
        result = false;
    }
    
    return result;
}
//
// add a member to the master list if not already there
//
int plNetTransport::AddMember(plNetTransportMember* mbr)
{
    if (FindMember(mbr)==-1)
    {
        fMembers.push_back(mbr);
        hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg("Adding member %s", mbr->AsString().c_str()) );
        plNetClientMgr::GetInstance()->GetListenList()->AddMember(mbr);
        plNetClientMgr::GetInstance()->GetTalkList()->AddMember(mbr);
        DumpState();
        return fMembers.size()-1;
    }
    return -1;
}
예제 #10
0
void plNetLinkingMgr::LinkToAge( plAgeLinkStruct * link, const char* linkAnim, bool linkInSfx, bool linkOutSfx, uint32_t playerID )
{
    if ( !fLinkingEnabled )
    {
        hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg( "Not linking. Linking is disabled." ) );
        return;
    }

    plLinkToAgeMsg* pMsg = new plLinkToAgeMsg( link );
    if (linkAnim)
        pMsg->SetLinkInAnimName(linkAnim);
    pMsg->PlayLinkSfx(linkInSfx, linkOutSfx);
    IDispatchMsg( pMsg, playerID );
}
예제 #11
0
void plNetLinkingMgr::LinkPlayerToAge( plAgeLinkStruct * link, uint32_t playerID )
{
    if ( !fLinkingEnabled )
    {
        hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg( "Not linking. Linking is disabled." ) );
        return;
    }
    plNetClientMgr * nc = plNetClientMgr::GetInstance();

    // send the player the age link so they can link there.
    link->SetLinkingRules( plNetCommon::LinkingRules::kBasicLink );
    plLinkToAgeMsg* pMsg = new plLinkToAgeMsg( link );
    IDispatchMsg( pMsg, playerID );
}
예제 #12
0
void plNetLinkingMgr::LinkPlayerHere( uint32_t playerID )
{
    if ( !fLinkingEnabled )
    {
        hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg( "Not linking. Linking is disabled." ) );
        return;
    }
    plNetClientMgr * nc = plNetClientMgr::GetInstance();

    // send the player our current age info so they can link here.
    plAgeLinkStruct link;
    link.GetAgeInfo()->CopyFrom( GetAgeLink()->GetAgeInfo() );
    LinkPlayerToAge( &link, playerID );
}
예제 #13
0
void plNetLinkingMgr::LinkToPlayersAge( uint32_t playerID )
{
    if ( !fLinkingEnabled )
    {
        hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg( "Not linking. Linking is disabled." ) );
        return;
    }
    // Send the player a msg telling them to send us a msg to link to them. isn't that fun? :)
    plNetClientMgr * nc = plNetClientMgr::GetInstance();

    plLinkingMgrMsg* pMsg = new plLinkingMgrMsg();
    pMsg->SetCmd( kLinkPlayerHere );
    pMsg->GetArgs()->AddInt( 0, NetCommGetPlayer()->playerInt );    // send them our id.
    IDispatchMsg( pMsg, playerID );
}
예제 #14
0
//
// link the player back to his previous age
//
void plNetLinkingMgr::LinkPlayerToPrevAge( uint32_t playerID )
{
    if ( !fLinkingEnabled )
    {
        hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg( "Not linking. Linking is disabled." ) );
        return;
    }

    // Send the player a msg telling them to link to their last age
    plNetClientMgr * nc = plNetClientMgr::GetInstance();

    plLinkingMgrMsg* pMsg = new plLinkingMgrMsg();
    pMsg->SetCmd( kLinkPlayerToPrevAge);
    IDispatchMsg( pMsg, playerID );
}
예제 #15
0
void plNetTransport::IRemoveMember(plNetTransportMember* mbr)
{
    if (!mbr)
        return;

    hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg("Removing member %s", mbr->AsString().c_str()) );

//  plNetClientMgr::GetInstance()->GetNetCore()->RemovePeer(mbr->GetPeerID());
    plNetClientMgr::GetInstance()->GetTalkList()->RemoveMember(mbr);
    plNetClientMgr::GetInstance()->GetListenList()->RemoveMember(mbr);

    // remove member from subscription lists
    IUnSubscribeToAllChannelGrps(mbr);

    plMembersList::iterator it=std::find(fMembers.begin(),fMembers.end(),mbr);

    // remove member from master list
    fMembers.erase(it);

    hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg("Done Removing member %s", mbr->AsString().c_str()) );
    DumpState();
    
    delete mbr;
}
예제 #16
0
void plSDLParser::DebugMsg(const char* fmt, ...) const
{
    return;
    plNetApp* netApp = plSDLMgr::GetInstance()->GetNetApp();

    va_list args;
    va_start(args, fmt);
    
    if (netApp)
    {
        hsLogEntry(netApp->DebugMsgV(fmt, args));
    }
    else
        DebugMsgV(fmt, args);
    va_end(args);
}
예제 #17
0
void plNetLinkingMgr::LinkToMyNeighborhoodAge( uint32_t playerID )
{
    if ( !fLinkingEnabled )
    {
        hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg( "Not linking. Linking is disabled." ) );
        return;
    }
    plNetClientMgr * nc = plNetClientMgr::GetInstance();

    plAgeLinkStruct link;
    if (!VaultGetLinkToMyNeighborhood(&link))
        return;
        
    link.SetLinkingRules( plNetCommon::LinkingRules::kOwnedBook );

    plLinkToAgeMsg* pMsg = new plLinkToAgeMsg( &link );
    IDispatchMsg( pMsg, playerID );
}
예제 #18
0
void plNetLinkingMgr::LinkToMyPersonalAge( uint32_t playerID )
{
    if ( !fLinkingEnabled )
    {
        hsLogEntry( plNetClientMgr::GetInstance()->DebugMsg( "Not linking. Linking is disabled." ) );
        return;
    }
    plNetClientMgr* nc = plNetClientMgr::GetInstance();

    plAgeLinkStruct link;
    link.GetAgeInfo()->SetAgeFilename( kPersonalAgeFilename );
    link.SetLinkingRules( plNetCommon::LinkingRules::kOwnedBook );

    plSpawnPointInfo hutSpawnPoint;
    hutSpawnPoint.SetName(kPersonalAgeLinkInPointCloset);
    link.SetSpawnPoint(hutSpawnPoint);

    plLinkToAgeMsg* pMsg = new plLinkToAgeMsg( &link );
    IDispatchMsg( pMsg, playerID );
}
예제 #19
0
//
// write latest descriptors to a stream.
// return number of bytes
//
int plSDLMgr::Write(hsStream* s, const plSDL::DescriptorList* dl)
{
    int pos=s->GetPosition();

    if (dl==nil)
        dl=&fDescriptors;

    uint16_t num=dl->size();
    s->WriteLE(num);

    plSDL::DescriptorList::const_iterator it;
    for(it=dl->begin(); it!= dl->end(); it++)
        (*it)->Write(s);    

    int bytes=s->GetPosition()-pos;
    if (fNetApp)
    {
        hsLogEntry(fNetApp->DebugMsg("Writing {} SDL descriptors, {} bytes", num, bytes));
    }
    return bytes;
}
예제 #20
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; 
}
예제 #21
0
void plDispatch::IMsgDispatch()
{
    if( !fMsgDispatchLock.TryLock() )
        return;

    if( fMsgActive )
    {
        fMsgDispatchLock.Unlock();
        return;
    }

    fMsgActive = true;
    int responseLevel=0;

    fMsgCurrentMutex.Lock();

    plMsgWrap* origTail = fMsgTail;
    while((fMsgCurrent = fMsgHead))
    {
        IDequeue(&fMsgHead, &fMsgTail);
        fMsgCurrentMutex.Unlock();

        plMessage* msg = fMsgCurrent->fMsg;
        bool nonLocalMsg = msg && msg->HasBCastFlag(plMessage::kNetNonLocal);

#ifdef HS_DEBUGGING
        int watchIdx = fMsgWatch.Find(msg);
        if( fMsgWatch.kMissingIndex != watchIdx )
        {
            fMsgWatch.Remove(watchIdx);
#if HS_BUILD_FOR_WIN32
            __asm { int 3 }
#endif // HS_BUILD_FOR_WIN32
        }
#endif // HS_DEBUGGING

        static uint64_t startTicks = 0;
        if (plDispatchLogBase::IsLogging())
            startTicks = hsTimer::GetFullTickCount();

        int i, numReceivers=0;
        for( i = 0; fMsgCurrent && i < fMsgCurrent->GetNumReceivers(); i++ )
        {
            const plKey& rcvKey = fMsgCurrent->GetReceiver(i);
            plReceiver* rcv = rcvKey ? plReceiver::ConvertNoRef(rcvKey->ObjectIsLoaded()) : nil;
            if( rcv )
            {
                if (nonLocalMsg)
                {
                    // localOnly objects should not get remote messages
                    plSynchedObject* synchedObj = plSynchedObject::ConvertNoRef(rcv);
                    if (synchedObj && !synchedObj->IsNetSynched() )
                    {
                        continue;
                    }

                    if (plNetObjectDebuggerBase::GetInstance())
                    {   // log net msg if this is a debug object
                        hsKeyedObject* ko = hsKeyedObject::ConvertNoRef(rcv);
                        if (plNetObjectDebuggerBase::GetInstance()->IsDebugObject(ko))
                        {
                            hsLogEntry(plNetObjectDebuggerBase::GetInstance()->LogMsg(
                                plString::Format("<RCV> object:%s, GameMessage %s st=%.3f rt=%.3f",
                                ko->GetKeyName().c_str(), msg->ClassName(), hsTimer::GetSysSeconds(), hsTimer::GetSeconds()).c_str()));
                        }
                    }
                }

#ifndef PLASMA_EXTERNAL_RELEASE
                uint32_t rcvTicks = hsTimer::GetPrecTickCount();

                // Object could be deleted by this message, so we need to log this stuff now
                plString keyname = "(unknown)";
                const char* className = "(unknown)";
                uint32_t clonePlayerID = 0;
                if (plDispatchLogBase::IsLoggingLong())
                {
                    hsKeyedObject* ko = hsKeyedObject::ConvertNoRef(rcv);
                    if (ko)
                    {
                        keyname = ko->GetKeyName();
                        clonePlayerID = ko->GetKey()->GetUoid().GetClonePlayerID();
                        className = ko->ClassName();
                    }
                }
#endif // PLASMA_EXTERNAL_RELEASE

                #ifdef HS_DEBUGGING
                if (msg->GetBreakBeforeDispatch())
                    DebugBreakIfDebuggerPresent();
                #endif
                    
                plProfile_BeginTiming(MsgReceive);
                rcv->MsgReceive(msg);
                plProfile_EndTiming(MsgReceive);

#ifndef PLASMA_EXTERNAL_RELEASE
                if (plDispatchLogBase::IsLoggingLong())
                {
                    rcvTicks = hsTimer::GetPrecTickCount() - rcvTicks;

                    float rcvTime = (float)(hsTimer::PrecTicksToSecs(rcvTicks) * 1000.f);
                    // If the receiver takes more than 5 ms to process its message, log it
                    if (rcvTime > 5.f)
                        plDispatchLogBase::GetInstance()->LogLongReceive(keyname.c_str(), className, clonePlayerID, msg, rcvTime);
                }
#endif // PLASMA_EXTERNAL_RELEASE

                numReceivers++;

                if (fMsgRecieveCallback != nil)
                    fMsgRecieveCallback();
            }
        }

        // for message logging
//      if (plDispatchLogBase::IsLogging())
//      {
//          float sendTime = hsTimer::FullTicksToMs(hsTimer::GetFullTickCount() - startTicks);
//
//          plDispatchLogBase::GetInstance()->DumpMsg(msg, numReceivers, (int)sendTime, responseLevel*2 /* indent */);
//          if (origTail==fMsgCurrent)
//          {   // if we deliver more msgs after this, they must be response msgs
//              responseLevel++;
//              origTail = fMsgTail;
//          }
//      }

        fMsgCurrentMutex.Lock();

        delete fMsgCurrent;
        // TEMP
        fMsgCurrent = (class plMsgWrap *)0xdeadc0de;
    }
예제 #22
0
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;
}
예제 #23
0
uint8_t plNetLinkingMgr::IPreProcessLink(void)
{
    // Grab some stuff we're gonna use extensively
    plNetClientMgr* nc = plNetClientMgr::GetInstance();
    plAgeLinkStruct* link = GetAgeLink();
    plAgeInfoStruct* info = link->GetAgeInfo();

    PreProcessResult success = kLinkImmediately;

    if ( nc->GetFlagsBit( plNetClientMgr::kNullSend ) )
    {
        hsLogEntry( nc->DebugMsg( "NetClientMgr nullsend. Not linking." ) );
        return kLinkFailed;
    }

#if 0
    // Appear offline until we're done linking
    if (RelVaultNode * rvnInfo = VaultGetPlayerInfoNodeIncRef()) {
        VaultPlayerInfoNode accInfo(rvnInfo);
        accInfo.SetAgeInstName(nil);
        accInfo.SetAgeInstUuid(kNilUuid);
        accInfo.SetOnline(false);
        rvnInfo->DecRef();
    }
#else
    // Update our online status 
    if (RelVaultNode * rvnInfo = VaultGetPlayerInfoNodeIncRef()) {
        VaultPlayerInfoNode accInfo(rvnInfo);
        wchar_t ageInstName[MAX_PATH];
        plUUID ageInstGuid = *GetAgeLink()->GetAgeInfo()->GetAgeInstanceGuid();
        StrToUnicode(ageInstName, info->GetAgeInstanceName(), arrsize(ageInstName));
        accInfo.SetAgeInstName(ageInstName);
        accInfo.SetAgeInstUuid(ageInstGuid);
        accInfo.SetOnline(true);
        rvnInfo->DecRef();
    }
#endif

    //------------------------------------------------------------------------
    // Fixup empty fields
    if (info->HasAgeFilename())
    {
        info->SetAgeFilename(plNetLinkingMgr::GetProperAgeName(info->GetAgeFilename()).c_str());

        if (!info->HasAgeInstanceName())
        {
            info->SetAgeInstanceName(info->GetAgeFilename());
        }
    }

    hsLogEntry(nc->DebugMsg( "plNetLinkingMgr: Pre-Process: Linking with %s rules...",
        plNetCommon::LinkingRules::LinkingRuleStr(link->GetLinkingRules())));

    //------------------------------------------------------------------------
    // SPECIAL CASE: StartUp: force basic link
    if (info->GetAgeFilename().CompareI(kStartUpAgeFilename) == 0)
        link->SetLinkingRules( plNetCommon::LinkingRules::kBasicLink );

    //------------------------------------------------------------------------
    // SPECIAL CASE: Nexus: force original link
    if (info->GetAgeFilename().CompareI(kNexusAgeFilename) == 0)
        link->SetLinkingRules(plNetCommon::LinkingRules::kOriginalBook);

    //------------------------------------------------------------------------
    // SPECIAL CASE: ACA: force original link
    if (info->GetAgeFilename().CompareI(kAvCustomizationFilename) == 0)
        link->SetLinkingRules(plNetCommon::LinkingRules::kOriginalBook);

    hsLogEntry(nc->DebugMsg("plNetLinkingMgr: Process: Linking with %s rules...",
        plNetCommon::LinkingRules::LinkingRuleStr(link->GetLinkingRules())));

    switch (link->GetLinkingRules())
    {
        //--------------------------------------------------------------------
        // BASIC LINK. Link to a unique instance of the age, if no instance specified.
        case plNetCommon::LinkingRules::kBasicLink:
            if (!info->HasAgeInstanceGuid()) {
                plUUID newuuid = plUUID::Generate();
                info->SetAgeInstanceGuid(&newuuid);
            }
        break;

        //--------------------------------------------------------------------
        // ORIGINAL BOOK.  Become an owner of the age, if not already one.
        case plNetCommon::LinkingRules::kOriginalBook:
            {
                // create a new ageinfo struct with the filename of the age because
                // we just want to find out if we own *any* link to the age, not the specific
                // link that we're linking through
                plAgeInfoStruct ageInfo;
                ageInfo.SetAgeFilename(info->GetAgeFilename());

                plAgeLinkStruct ownedLink;
                if (!VaultGetOwnedAgeLink(&ageInfo, &ownedLink)) {
                    // Fill in fields for new age create.
                    if (!info->HasAgeUserDefinedName())
                    {
                        // set user-defined name
                        plString title;
                        unsigned nameLen = nc->GetPlayerName().GetSize();
                        if (nc->GetPlayerName().ToLower().CharAt(nameLen - 1) == 's')
                            title = plString::Format("%s'", nc->GetPlayerName().c_str());
                        else
                            title = plString::Format("%s's", nc->GetPlayerName().c_str());
                        info->SetAgeUserDefinedName(title.c_str());
                    }
                    if (!info->HasAgeDescription())
                    {
                        // set description
                        plString desc;
                        unsigned nameLen = nc->GetPlayerName().GetSize();
                        if (nc->GetPlayerName().ToLower().CharAt(nameLen - 1) == 's')
                            desc = plString::Format("%s' %s", nc->GetPlayerName().c_str(), info->GetAgeInstanceName().c_str());
                        else
                            desc = plString::Format("%s's %s", nc->GetPlayerName().c_str(), info->GetAgeInstanceName().c_str());
                        info->SetAgeDescription(desc.c_str());
                    }
                    if (!info->HasAgeInstanceGuid()) {
                        plUUID newuuid = plUUID::Generate();
                        info->SetAgeInstanceGuid(&newuuid);
                    }
                    
                    // register this as an owned age now before we link to it.
                    // Note: We MUST break or the OwnedBook code will fail!
                    VaultRegisterOwnedAge(link);
                    success = kLinkDeferred;
                    break;
                }
                else if (RelVaultNode* linkNode = VaultGetOwnedAgeLinkIncRef(&ageInfo)) {
                    // We have the age in our AgesIOwnFolder. If its volatile, dump it for the new one.
                    VaultAgeLinkNode linkAcc(linkNode);
                    if (linkAcc.GetVolatile()) {
                        if (VaultUnregisterOwnedAgeAndWait(&ageInfo)) {
                            // Fill in fields for new age create.
                            if (!info->HasAgeUserDefinedName())
                            {
                                // set user-defined name
                                plString title;
                                unsigned nameLen = nc->GetPlayerName().GetSize();
                                if (nc->GetPlayerName().ToLower().CharAt(nameLen - 1) == 's')
                                    title = plString::Format("%s'", nc->GetPlayerName().c_str());
                                else
                                    title = plString::Format("%s's", nc->GetPlayerName().c_str());
                                info->SetAgeUserDefinedName(title.c_str());
                            }

                            if (!info->HasAgeDescription())
                            {
                                // set description
                                plString desc;
                                unsigned nameLen = nc->GetPlayerName().GetSize();
                                if (nc->GetPlayerName().ToLower().CharAt(nameLen - 1) == 's')
                                    desc = plString::Format("%s' %s", nc->GetPlayerName().c_str(), info->GetAgeInstanceName().c_str());
                                else
                                    desc = plString::Format("%s's %s", nc->GetPlayerName().c_str(), info->GetAgeInstanceName().c_str());
                                info->SetAgeDescription( desc.c_str() );
                            }

                            if (!info->HasAgeInstanceGuid()) {
                                plUUID newuuid = plUUID::Generate();
                                info->SetAgeInstanceGuid(&newuuid);
                            }

                            VaultRegisterOwnedAge(link);

                            // Note: We MUST break or the OwnedBook code will fail!
                            success = kLinkDeferred;
                            break;
                        }
                    }
                    else {
                        if (info->GetAgeFilename().CompareI(kNeighborhoodAgeFilename) == 0) {
                            // if we get here then it's because we're linking to a neighborhood that we don't belong to
                            // and our own neighborhood book is not volatile, so really we want to basic link
                            link->SetLinkingRules(plNetCommon::LinkingRules::kBasicLink);
                            success = kLinkImmediately;
                            break;
                        }
                    }
                    linkNode->DecRef();
                }
            }

            link->SetLinkingRules(plNetCommon::LinkingRules::kOwnedBook);
            // falls thru to OWNED BOOK case...

        //--------------------------------------------------------------------
        // OWNED BOOK. Look for the book in our AgesIOwn folder
        case plNetCommon::LinkingRules::kOwnedBook:
            {
                plAgeLinkStruct ownedLink;
                if (VaultGetOwnedAgeLink(info, &ownedLink)) {
                    info->CopyFrom(ownedLink.GetAgeInfo());
                    // Remember spawn point (treasure book support)                     
                    plSpawnPointInfo theSpawnPt = link->SpawnPoint();
                    VaultAddOwnedAgeSpawnPoint(*info->GetAgeInstanceGuid(), theSpawnPt);
                }
                else {
                    success = kLinkFailed;
                }
            }
            break;

        //--------------------------------------------------------------------
        // VISIT BOOK. Look for the book in our AgesICanVisit folder
        case plNetCommon::LinkingRules::kVisitBook:
            {
                plAgeLinkStruct visitLink;
                if (VaultGetVisitAgeLink(info, &visitLink))
                    info->CopyFrom(visitLink.GetAgeInfo());
                else
                    success = kLinkFailed;
            }
            break;

        //--------------------------------------------------------------------
        // SUB-AGE BOOK: Look for an existing sub-age in this age's SubAges folder and use it if found.
        //  plNetClientTaskHandler will add a SubAge back link to our current age once we arrive there.
        case plNetCommon::LinkingRules::kSubAgeBook:
            {
                plAgeLinkStruct subAgeLink;
                if (VaultAgeFindOrCreateSubAgeLink(info, &subAgeLink, NetCommGetAge()->ageInstId))
                    info->CopyFrom(subAgeLink.GetAgeInfo());
                else
                    success = kLinkDeferred;
            }
            break;

        //--------------------------------------------------------------------
        // CHILD-AGE BOOK: Look for an existing child-age in this parent ageinfo ChildAges folder and use it if found.
        //  plNetClientTaskHandler will add a ChildAge back link to our current age once we arrive there.
        case plNetCommon::LinkingRules::kChildAgeBook:
            {
                plAgeLinkStruct childLink;
                wchar_t parentAgeName[MAX_PATH];
                if (link->HasParentAgeFilename())
                    StrToUnicode(parentAgeName, link->GetParentAgeFilename(), arrsize(parentAgeName));

                switch(VaultAgeFindOrCreateChildAgeLink(
                      (link->HasParentAgeFilename() ? parentAgeName : nil),
                      info,
                      &childLink))
                {
                    case static_cast<uint8_t>(hsFail):
                        success = kLinkFailed;
                        break;
                    case false:
                        success = kLinkDeferred;
                        break;
                    case true:
                        success = kLinkImmediately;
                }

                if (success == kLinkImmediately)
                    info->CopyFrom(childLink.GetAgeInfo());
            }
            break;

        //--------------------------------------------------------------------
        // ???
        DEFAULT_FATAL(link->GetLinkingRules());
    }

    hsLogEntry(nc->DebugMsg( "plNetLinkingMgr: Post-Process: Linking with %s rules...",
        plNetCommon::LinkingRules::LinkingRuleStr(link->GetLinkingRules())));

    hsAssert(info->HasAgeFilename(), "AgeLink has no AgeFilename. Link will fail.");

    return success;
}
void plCreatableListHelper::Write( hsStream* s, hsResMgr* mgr )
{
    if ( !( fFlags&kWritten ) )
    {
        // write items to ram stream
        hsRAMStream ram;
        uint16_t nItems = fItems.size();
        ram.WriteLE( nItems );
        for ( std::map<uint16_t,plCreatable*>::iterator ii=fItems.begin(); ii!=fItems.end(); ++ii )
        {
            uint16_t id = ii->first;
            plCreatable * item = ii->second;
            uint16_t classIdx = item->ClassIndex();
            ram.WriteLE( id );
            ram.WriteLE( classIdx );
            item->Write( &ram, mgr );
        }

        // read ram stream into a buffer
        uint32_t bufSz = ram.GetPosition();
        ram.Rewind();
        std::string buf;
        buf.resize( bufSz );
        ram.Read( bufSz, (void*)buf.data() );

        // maybe compress the buffer
        if ( fFlags&kWantCompression && bufSz>fCompressionThreshold )
        {
            plZlibCompress compressor;
            uint32_t zBufSz;
            std::string zBuf;
            zBuf.resize( bufSz );
            hsBool ans = compressor.Compress( (uint8_t*)zBuf.data(), &zBufSz, (const uint8_t*)buf.data(), bufSz );
            bool compressed = ( ans && zBufSz );
            hsAssert( compressed, "plCreatableListHelper: Failed to compress buffer." );
            if ( compressed )
            {
                zBuf.resize( zBufSz );
                buf = zBuf;
                fFlags |= kCompressed;
                hsLogEntry( plNetApp::StaticDebugMsg( "plCreatableListHelper: compressed from %lu to %lu", bufSz, zBufSz ) );
            }
        }

        ram.Truncate();

        ram.WriteLE( fFlags );
        ram.WriteLE( bufSz );

        if ( fFlags&kCompressed )
        {
            uint32_t zBufSz = buf.size();
            ram.WriteLE( zBufSz );
        }

        ram.Write( buf.size(), buf.data() );
        uint32_t sz = ram.GetPosition();
        ram.Rewind();

        fWritten.resize( sz );
        ram.Read( sz, (void*)fWritten.data() );

        fFlags |= kWritten;
    }

    s->Write( fWritten.size(), fWritten.data() );
}
예제 #25
0
void plNetLinkingMgr::SetEnabled( bool b )
{
    plNetClientMgr * nc = plNetClientMgr::GetInstance();
    hsLogEntry( nc->DebugMsg( "plNetLinkingMgr: %s -> %s", fLinkingEnabled?"Enabled":"Disabled",b?"Enabled":"Disabled" ) );
    fLinkingEnabled = b;
}