// 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; }
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; }
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); }
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; }
/// 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; }