// nsIObserver interface
NS_IMETHODIMP
nsIOService::Observe(nsISupports *subject,
                     const char *topic,
                     const PRUnichar *data)
{
    if (!strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
        nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(subject);
        if (prefBranch)
            PrefsChanged(prefBranch, NS_ConvertUTF16toUTF8(data).get());
    }
    else if (!strcmp(topic, kProfileChangeNetTeardownTopic)) {
        if (!mOffline) {
            SetOffline(true);
            mOfflineForProfileChange = true;
        }
    }
    else if (!strcmp(topic, kProfileChangeNetRestoreTopic)) {
        if (mOfflineForProfileChange) {
            mOfflineForProfileChange = false;
            if (!mManageOfflineStatus ||
                NS_FAILED(TrackNetworkLinkStatusForOffline())) {
                SetOffline(false);
            }
        } 
    } 
    else if (!strcmp(topic, kProfileDoChange)) { 
        if (data && NS_LITERAL_STRING("startup").Equals(data)) {
            // Lazy initialization of network link service (see bug 620472)
            InitializeNetworkLinkService();
            // Set up the initilization flag regardless the actuall result.
            // If we fail here, we will fail always on.
            mNetworkLinkServiceInitialized = true;
        }
    }
    else if (!strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
        // Remember we passed XPCOM shutdown notification to prevent any
        // changes of the offline status from now. We must not allow going
        // online after this point.
        mShutdown = true;

        SetOffline(true);

        // Break circular reference.
        mProxyService = nullptr;
    }
    else if (!strcmp(topic, NS_NETWORK_LINK_TOPIC)) {
        if (!mOfflineForProfileChange && mManageOfflineStatus) {
            TrackNetworkLinkStatusForOffline();
        }
    }
    
    return NS_OK;
}
示例#2
0
int MainInit(WPARAM wparam,LPARAM lparam)
{
	HookEvent(ME_OPT_INITIALISE,OptionsInit);
	
	if(DBGetContactSettingByte(NULL,S_MOD,"MenuItem",1)) {
		InitMenuitem();
	}
	
	if(DBGetContactSettingByte(NULL,S_MOD,"UserinfoTab",1))
		ehuserinfo=HookEvent(ME_USERINFO_INITIALISE,UserinfoInit);

	if(DBGetContactSettingByte(NULL,S_MOD,"FileOutput",0))
		InitFileOutput();

	if(DBGetContactSettingByte(NULL,S_MOD,"MissedOnes",0))
		ehmissed_proto=HookEvent(ME_PROTO_ACK,ModeChange_mo);

	SetOffline();

	ehdb=HookEvent(ME_DB_CONTACT_SETTINGCHANGED,UpdateValues);
	ehproto[0]=HookEvent(ME_PROTO_ACK,ModeChange);
	ehproto[1]=HookEvent(ME_PROTO_ACK,GetInfoAck);

	SkinAddNewSound("LastSeenTrackedStatusChange",Translate("LastSeen: User status change"),"global.wav");
	DBWriteContactSettingString(NULL,"Uninstall",Translate("Last seen"),S_MOD);
	return 0;
}
示例#3
0
void CBCGPIE7DemoView::OnInitialUpdate() 
{
	CHtmlView::OnInitialUpdate ();

	m_nFontSize = 2l;

	SetOffline (m_bWorkOffline);

	if (m_bGoAddress)
	{
		GoHome();
	}
}
nsresult
nsIOService::TrackNetworkLinkStatusForOffline()
{
    NS_ASSERTION(mManageOfflineStatus,
                 "Don't call this unless we're managing the offline status");
    if (!mNetworkLinkService)
        return NS_ERROR_FAILURE;

    if (mShutdown)
        return NS_ERROR_NOT_AVAILABLE;
  
    // check to make sure this won't collide with Autodial
    if (mSocketTransportService) {
        bool autodialEnabled = false;
        mSocketTransportService->GetAutodialEnabled(&autodialEnabled);
        // If autodialing-on-link-down is enabled, check if the OS auto dial 
        // option is set to always autodial. If so, then we are 
        // always up for the purposes of offline management.
        if (autodialEnabled) {
#if defined(XP_WIN) || defined(MOZ_PLATFORM_MAEMO)
            // On Windows and Maemo (libconic) we should first check with the OS
            // to see if autodial is enabled.  If it is enabled then we are
            // allowed to manage the offline state.
            if(nsNativeConnectionHelper::IsAutodialEnabled()) 
                return SetOffline(false);
#else
            return SetOffline(false);
#endif
        }
    }

    bool isUp;
    nsresult rv = mNetworkLinkService->GetIsLinkUp(&isUp);
    NS_ENSURE_SUCCESS(rv, rv);
    return SetOffline(!isUp);
}
示例#5
0
nsresult
nsIOService::InitializeNetworkLinkService()
{
    NS_TIME_FUNCTION;

    nsresult rv = NS_OK;

    if (mNetworkLinkServiceInitialized)
        return rv;

    if (!NS_IsMainThread()) {
        NS_WARNING("Network link service should be created on main thread"); 
        return NS_ERROR_FAILURE; 
    }

    // go into managed mode if we can, and chrome process
    if (XRE_GetProcessType() == GeckoProcessType_Default)
    {
        mNetworkLinkService = do_GetService(NS_NETWORK_LINK_SERVICE_CONTRACTID, &rv);
    }

    if (mNetworkLinkService) {
        mNetworkLinkServiceInitialized = true;
    }
    else {
        // We can't really determine if the machine has a usable network connection,
        // so let's cross our fingers!
        mManageOfflineStatus = false;
    }
   

    if (mManageOfflineStatus)
        TrackNetworkLinkStatusForOffline();
    else
        SetOffline(false);
    
    return rv;
}
示例#6
0
/// Update the WorldSession (triggered by World update)
bool WorldSession::Update(PacketFilter& updater)
{
    std::lock_guard<std::mutex> guard(m_recvQueueLock);

    ///- Retrieve packets from the receive queue and call the appropriate handlers
    /// not process packets if socket already closed
    while (m_Socket && !m_Socket->IsClosed() && !m_recvQueue.empty())
    {
        auto const packet = std::move(m_recvQueue.front());
        m_recvQueue.pop_front();

        /*#if 1
        sLog.outError( "MOEP: %s (0x%.4X)",
                        packet->GetOpcodeName(),
                        packet->GetOpcode());
        #endif*/

        OpcodeHandler const& opHandle = opcodeTable[packet->GetOpcode()];
        try
        {
            switch (opHandle.status)
            {
                case STATUS_LOGGEDIN:
                    if (!_player)
                    {
                        // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
                        if (!m_playerRecentlyLogout)
                            LogUnexpectedOpcode(*packet, "the player has not logged in yet");
                    }
                    else if (_player->IsInWorld())
                        ExecuteOpcode(opHandle, *packet);

                    // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer

#ifdef BUILD_PLAYERBOT
                    if (_player && _player->GetPlayerbotMgr())
                        _player->GetPlayerbotMgr()->HandleMasterIncomingPacket(*packet);
#endif
                    break;
                case STATUS_LOGGEDIN_OR_RECENTLY_LOGGEDOUT:
                    if (!_player && !m_playerRecentlyLogout)
                    {
                        LogUnexpectedOpcode(*packet, "the player has not logged in yet and not recently logout");
                    }
                    else
                        // not expected _player or must checked in packet hanlder
                        ExecuteOpcode(opHandle, *packet);
                    break;
                case STATUS_TRANSFER:
                    if (!_player)
                        LogUnexpectedOpcode(*packet, "the player has not logged in yet");
                    else if (_player->IsInWorld())
                        LogUnexpectedOpcode(*packet, "the player is still in world");
                    else
                        ExecuteOpcode(opHandle, *packet);
                    break;
                case STATUS_AUTHED:
                    // prevent cheating with skip queue wait
                    if (m_inQueue)
                    {
                        LogUnexpectedOpcode(*packet, "the player not pass queue yet");
                        break;
                    }

                    // single from authed time opcodes send in to after logout time
                    // and before other STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes.
                    if (packet->GetOpcode() != CMSG_SET_ACTIVE_VOICE_CHANNEL)
                        m_playerRecentlyLogout = false;

                    ExecuteOpcode(opHandle, *packet);
                    break;
                case STATUS_NEVER:
                    sLog.outError("SESSION: received not allowed opcode %s (0x%.4X)",
                                  packet->GetOpcodeName(),
                                  packet->GetOpcode());
                    break;
                case STATUS_UNHANDLED:
                    DEBUG_LOG("SESSION: received not handled opcode %s (0x%.4X)",
                              packet->GetOpcodeName(),
                              packet->GetOpcode());
                    break;
                default:
                    sLog.outError("SESSION: received wrong-status-req opcode %s (0x%.4X)",
                                  packet->GetOpcodeName(),
                                  packet->GetOpcode());
                    break;
            }
        }
        catch (ByteBufferException&)
        {
            sLog.outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i.",
                          packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
            if (sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
            {
                DEBUG_LOG("Dumping error causing packet:");
                packet->hexlike();
            }

            if (sWorld.getConfig(CONFIG_BOOL_KICK_PLAYER_ON_BAD_PACKET))
            {
                DETAIL_LOG("Disconnecting session [account id %u / address %s] for badly formatted packet.",
                           GetAccountId(), GetRemoteAddress().c_str());

                KickPlayer();
            }
        }
    }

#ifdef BUILD_PLAYERBOT
    // Process player bot packets
    // The PlayerbotAI class adds to the packet queue to simulate a real player
    // since Playerbots are known to the World obj only by its master's WorldSession object
    // we need to process all master's bot's packets.
    if (GetPlayer() && GetPlayer()->GetPlayerbotMgr())
    {
        for (PlayerBotMap::const_iterator itr = GetPlayer()->GetPlayerbotMgr()->GetPlayerBotsBegin();
                itr != GetPlayer()->GetPlayerbotMgr()->GetPlayerBotsEnd(); ++itr)
        {
            Player* const botPlayer = itr->second;
            WorldSession* const pBotWorldSession = botPlayer->GetSession();
            if (botPlayer->IsBeingTeleported())
                botPlayer->GetPlayerbotAI()->HandleTeleportAck();
            else if (botPlayer->IsInWorld())
            {
                while (!pBotWorldSession->m_recvQueue.empty())
                {
                    auto const botpacket = std::move(pBotWorldSession->m_recvQueue.front());
                    pBotWorldSession->m_recvQueue.pop_front();

                    OpcodeHandler const& opHandle = opcodeTable[botpacket->GetOpcode()];
                    pBotWorldSession->ExecuteOpcode(opHandle, *botpacket);
                };
                pBotWorldSession->m_recvQueue.clear();
            }
        }
    }
#endif

    // check if we are safe to proceed with logout
    // logout procedure should happen only in World::UpdateSessions() method!!!
    if (updater.ProcessLogout())
    {
        switch (m_sessionState)
        {
            case WORLD_SESSION_STATE_CREATED:
            {
                if (m_requestSocket)
                {
                    if (!IsOffline())
                        SetOffline();

                    m_Socket = m_requestSocket;
                    m_requestSocket = nullptr;
                    sLog.outString("New Session key %s", m_Socket->GetSessionKey().AsHexStr());
                    SendAuthOk();
                }
                else
                {
                    if (m_inQueue)
                        SendAuthQueued();
                    else
                        SendAuthOk();
                }
                m_sessionState = WORLD_SESSION_STATE_CHAR_SELECTION;
                return true;
            }

            case WORLD_SESSION_STATE_CHAR_SELECTION:

                // waiting to go online
                // TODO:: Maybe check if have to send queue update?
                if (!m_Socket || (m_Socket && m_Socket->IsClosed()))
                {
                    // directly remove this session
                    return false;
                }

                if (ShouldLogOut(time(nullptr)) && !m_playerLoading)   // check if delayed logout is fired
                    LogoutPlayer(true);

                return true;

            case WORLD_SESSION_STATE_READY:
            {
                if (m_Socket && m_Socket->IsClosed())
                {
                    if (!_player)
                        return false;

                    // give the opportunity for this player to reconnect within 20 sec
                    SetOffline();
                }
                else if (ShouldLogOut(time(nullptr)) && !m_playerLoading)   // check if delayed logout is fired
                    LogoutPlayer(true);

                return true;
            }

            case WORLD_SESSION_STATE_OFFLINE:
            {
                if (ShouldDisconnect(time(nullptr)))   // check if delayed logout is fired
                {
                    LogoutPlayer(true);
                    if (!m_requestSocket && (!m_Socket || m_Socket->IsClosed()))
                        return false;
                }

                return true;
            }
            default:
                break;
        }
    }

    return true;
}