class VOIPManager(VOIPHandler): settingsCore = dependency.descriptor(ISettingsCore) def __init__(self): _logger.info('Create') super(VOIPManager, self).__init__() self.__initialized = False self.__enabled = False self.__enabledChannelID = None self.__voipServer = '' self.__voipDomain = '' self.__testDomain = '' self.__user = ['', ''] self.__channel = ['', ''] self.__currentChannel = '' self.__isChannelRejoin = False self.__inTesting = False self.__loggedIn = False self.__needLogginAfterInit = False self.__normalLogout = False self.__loginAttemptsRemained = 2 self.__fsm = VOIPFsm() self.__expBackOff = backoff.ExpBackoff(_BACK_OFF_MIN_DELAY, _BACK_OFF_MAX_DELAY, _BACK_OFF_MODIFIER, _BACK_OFF_EXP_RANDOM_FACTOR) self.__reLoginCallbackID = None self.__activateMicByVoice = False self.__captureDevices = [] self.__currentCaptureDevice = '' self.__channelUsers = {} self.onCaptureDevicesUpdated = Event.Event() self.onPlayerSpeaking = Event.Event() self.onInitialized = Event.Event() self.onFailedToConnect = Event.Event() self.onJoinedChannel = Event.Event() self.onLeftChannel = Event.Event() self.__fsm.onStateChanged += self.__onStateChanged return @proto_getter(PROTO_TYPE.BW_CHAT2) def bwProto(self): return None @storage_getter('users') def usersStorage(self): return None @proto_getter(PROTO_TYPE.MIGRATION) def proto(self): return None def destroy(self): self.__fsm.onStateChanged -= self.__onStateChanged self.__cancelReloginCallback() BigWorld.VOIP.finalise() _logger.info('Destroy') def isEnabled(self): return self.__enabled def isInitialized(self): return self.__initialized def isNotInitialized(self): return not self.__initialized and self.getState() == STATE.NONE def isInTesting(self): return self.__inTesting def getVOIPDomain(self): return self.__voipDomain def getCurrentChannel(self): return self.__currentChannel def isVoiceSupported(self): return self.getVOIPDomain() != '' and self.isInitialized() def isChannelAvailable(self): return True if self.bwProto.voipProvider.getChannelParams()[0] else False def hasDesiredChannel(self): channelUrl = self.__channel[0] if channelUrl == self.__testDomain: return True currentChannelID = hash(channelUrl) return self.__enabledChannelID == currentChannelID def getUser(self): return self.__user[0] def isInDesiredChannel(self): if not self.__channel[0] == self.__currentChannel: return False if self.__currentChannel == self.__testDomain: return True currentChannelID = hash(self.__currentChannel) return self.__enabledChannelID == currentChannelID def getCaptureDevices(self): return self.__captureDevices def getCurrentCaptureDevice(self): return self.__currentCaptureDevice def getState(self): return self.__fsm.getState() def getAPI(self): return BigWorld.VOIP.getAPI() def isLoggedIn(self): return self.__loggedIn def onConnected(self): _logger.info('Subscribe') self.__loginAttemptsRemained = 2 voipEvents = g_messengerEvents.voip voipEvents.onChannelAvailable += self.__me_onChannelAvailable voipEvents.onChannelLost += self.__me_onChannelLost voipEvents.onCredentialReceived += self.__me_onCredentialReceived usersEvents = g_messengerEvents.users usersEvents.onUsersListReceived += self.__me_onUsersListReceived usersEvents.onUserActionReceived += self.__me_onUserActionReceived def onDisconnected(self): _logger.info('Unsubscribe') voipEvents = g_messengerEvents.voip voipEvents.onChannelAvailable -= self.__me_onChannelAvailable voipEvents.onChannelLost -= self.__me_onChannelLost voipEvents.onCredentialReceived -= self.__me_onCredentialReceived usersEvents = g_messengerEvents.users usersEvents.onUsersListReceived -= self.__me_onUsersListReceived usersEvents.onUserActionReceived -= self.__me_onUserActionReceived def enable(self, enabled, isInitFromPrefs=False): if enabled: self.__enable(isInitFromPrefs) else: dbIDs = set() for dbID, data in self.__channelUsers.iteritems(): if data['talking']: dbIDs.add(dbID) self.__disable() self.__fsm.update(self) def applyChannelSetting(self, isEnabled, channelID): self.__enabledChannelID = channelID if isEnabled else None self.__fsm.update(self) return def enableCurrentChannel(self, isEnabled=True, autoEnableVOIP=True): needsEnableVOIP = isEnabled and not self.settingsCore.getSetting(SOUND.VOIP_ENABLE) if autoEnableVOIP and needsEnableVOIP: self.settingsCore.applySetting(SOUND.VOIP_ENABLE, True) params = self.bwProto.voipProvider.getChannelParams() channelUrl = params[0] if channelUrl: _logger.debug("VOIPManager.%s '%s'", 'EnableCurrentChannel' if isEnabled else 'DisabledCurrentChannel', channelUrl) channelID = hash(channelUrl) self.settingsCore.applySetting(SOUND.VOIP_ENABLE_CHANNEL, (isEnabled, channelID)) else: _logger.error('EnableCurrentChannel: Failed to enable channel. No channel available!') def isCurrentChannelEnabled(self): params = self.bwProto.voipProvider.getChannelParams() channelUrl = params[0] if channelUrl: channelID = hash(channelUrl) return self.__enabledChannelID == channelID return False def __enable(self, isInitFromPrefs): _logger.info('Enable') self.__enabled = True if self.__channel[0]: if not self.__user[0]: self.__requestCredentials() if not isInitFromPrefs: self.enableCurrentChannel(True) def __disable(self): _logger.info('Disable') self.__enabled = False def initialize(self, domain, server): if self.__initialized: _logger.warning('VOIPManager is already initialized') return _logger.info('Initialize') self.__voipServer = server self.__voipDomain = domain self.__testDomain = 'sip:confctl-2@' + self.__voipDomain _logger.debug("voip_server: '%s'", self.__voipServer) _logger.debug("voip_domain: '%s'", self.__voipDomain) _logger.debug("test_domain: '%s'", self.__testDomain) self.__fsm.update(self) logLevel = 0 section = Settings.g_instance.userPrefs if section.has_key('development'): section = section['development'] if section.has_key('vivoxLogLevel'): logLevel = section['vivoxLogLevel'].asInt vinit = {VOIPCommon.KEY_SERVER: 'http://%s/api2' % self.__voipServer, VOIPCommon.KEY_MIN_PORT: '0', VOIPCommon.KEY_MAX_PORT: '0', VOIPCommon.KEY_LOG_PREFIX: 'voip', VOIPCommon.KEY_LOG_SUFFIX: '.txt', VOIPCommon.KEY_LOG_FOLDER: '.', VOIPCommon.KEY_LOG_LEVEL: str(logLevel)} BigWorld.VOIP.initialise(vinit) def __login(self, name, password): if not self.__initialized: self.__needLogginAfterInit = True self.__user = [name, password] if not self.__needLogginAfterInit: self.__fsm.update(self) def __loginUser(self): _logger.info('Login Request: %s', self.__user[0]) cmd = {VOIPCommon.KEY_PARTICIPANT_PROPERTY_FREQUENCY: '100'} BigWorld.VOIP.login(self.__user[0], self.__user[1], cmd) def __loginUserOnCallback(self): self.__reLoginCallbackID = None self.__loginUser() return def __reloginUser(self): self.__loginAttemptsRemained -= 1 _logger.warning('VOIPHandler.ReloginUser. Attempts remained: %d', self.__loginAttemptsRemained) if self.__enabled: self.__requestCredentials(1) def __cancelReloginCallback(self): if self.__reLoginCallbackID is not None: BigWorld.cancelCallback(self.__reLoginCallbackID) self.__reLoginCallbackID = None return def __setReloginCallback(self): delay = self.__expBackOff.next() _logger.info('__setReloginCallback. Next attempt after %d seconds', delay) self.__reLoginCallbackID = BigWorld.callback(delay, self.__loginUserOnCallback) def logout(self): _logger.info('Logout') self.__clearUser() self.__clearDesiredChannel() self.__fsm.update(self) def __setAvailableChannel(self, channel, password): if not self.__initialized and self.__fsm.inNoneState(): self.initialize(self.__voipDomain, self.__voipServer) if not self.__user[0] and self.isEnabled(): self.__requestCredentials() _logger.info('ReceivedAvailableChannel: %s', channel) self.__channel = [channel, password] self.__fsm.update(self) self.__evaluateAutoJoinChannel(channel) def __evaluateAutoJoinChannel(self, newChannel): if newChannel == self.__testDomain: return _, channelID = self.settingsCore.getSetting(SOUND.VOIP_ENABLE_CHANNEL) newChannelID = hash(newChannel) if channelID != newChannelID: self.enableCurrentChannel(self.__isAutoJoinChannel(), autoEnableVOIP=False) def __joinChannel(self, channel, password): _logger.info("JoinChannel '%s'", channel) BigWorld.VOIP.joinChannel(channel, password) def __leaveChannel(self): if not self.__initialized: return _logger.info('LeaveChannel') self.__clearDesiredChannel() self.__fsm.update(self) def enterTestChannel(self): if self.__inTesting: return _logger.info('EnterTestChannel: %s', self.__testDomain) self.__inTesting = True self.__setAvailableChannel(self.__testDomain, '') def leaveTestChannel(self): if not self.__inTesting: return _logger.info('LeaveTestChannel') self.__inTesting = False params = self.bwProto.voipProvider.getChannelParams() if params[0]: self.__setAvailableChannel(*params) else: self.__leaveChannel() def setMasterVolume(self, attenuation): BigWorld.VOIP.setMasterVolume(attenuation) def setMicrophoneVolume(self, attenuation): BigWorld.VOIP.setMicrophoneVolume(attenuation) def __setVolume(self): self.setMasterVolume(int(round(SoundGroups.g_instance.getVolume(VOIPCommon.KEY_VOIP_MASTER) * 100))) self.setMicrophoneVolume(int(round(SoundGroups.g_instance.getVolume(VOIPCommon.KEY_VOIP_MIC) * 100))) def __muffleMasterVolume(self): SoundGroups.g_instance.muffleWWISEVolume() def __restoreMasterVolume(self): SoundGroups.g_instance.restoreWWISEVolume() def setVoiceActivation(self, enabled): _logger.debug('SetVoiceActivation: %s', str(enabled)) self.__activateMicByVoice = enabled self.setMicMute(not enabled) def setMicMute(self, muted=True): if not self.__initialized: return if muted and self.__activateMicByVoice: return self.__setMicMute(muted) def __setMicMute(self, muted): _logger.debug('SetMicMute: %s', str(muted)) if muted: BigWorld.VOIP.disableMicrophone() else: BigWorld.VOIP.enableMicrophone() def requestCaptureDevices(self): _logger.debug('RequestCaptureDevices') BigWorld.VOIP.getCaptureDevices() def setCaptureDevice(self, deviceName): _logger.info('SetCaptureDevice: %s', deviceName) BigWorld.VOIP.setCaptureDevice(deviceName) def isParticipantTalking(self, dbid): outcome = self.__channelUsers.get(dbid, {}).get('talking', False) return outcome def __requestCredentials(self, reset=0): _logger.info('RequestUserCredentials') self.bwProto.voipProvider.requestCredentials(reset) def __clearDesiredChannel(self): self.__channel = ['', ''] def __clearUser(self): self.__user = ['', ''] def __onChatActionMute(self, dbid, muted): _logger.error('OnChatActionMute: dbID = %d, muted = %r', dbid, muted) if dbid in self.__channelUsers and self.__channelUsers[dbid]['muted'] != muted: self.__muteParticipantForMe(dbid, muted) def __muteParticipantForMe(self, dbid, mute): _logger.error('MuteParticipantForMe: %d, %s', dbid, str(mute)) self.__channelUsers[dbid]['muted'] = mute uri = self.__channelUsers[dbid]['uri'] cmd = {VOIPCommon.KEY_COMMAND: VOIPCommon.CMD_SET_PARTICIPANT_MUTE, VOIPCommon.KEY_PARTICIPANT_URI: uri, VOIPCommon.KEY_STATE: str(mute)} BigWorld.VOIP.command(cmd) return True def __isAnyoneTalking(self): for info in self.__channelUsers.values(): if info['talking']: return True return False def __extractDBIDFromURI(self, uri): try: domain = self.__voipDomain login = uri.partition('sip:')[2].rpartition('@' + domain)[0] s = login[login.find('.') + 1:] return (int(s), login) except Exception: return -1 def __sendLeaveChannelCommand(self, channel): _logger.info('Leaving channel %s', channel) if channel: BigWorld.VOIP.leaveChannel(channel) self.__fsm.update(self) def __resetToInitializedState(self): _logger.debug('resetToInitializesState') if self.__currentChannel != '': for dbid in self.__channelUsers.iterkeys(): self.onPlayerSpeaking(dbid, False) self.__channelUsers.clear() self.__restoreMasterVolume() self.__currentChannel = '' if self.__needLogginAfterInit: self.__fsm.update(self) self.__needLogginAfterInit = False def __onStateChanged(self, _, newState): if newState == STATE.INITIALIZED: self.__resetToInitializedState() elif newState == STATE.LOGGING_IN: self.__loginUser() elif newState == STATE.LOGGED_IN: self.__fsm.update(self) elif newState == STATE.JOINING_CHANNEL: muteMic = self.__channel[0] != self.__testDomain and not self.__activateMicByVoice self.setMicMute(muteMic) self.__joinChannel(self.__channel[0], self.__channel[1]) elif newState == STATE.JOINED_CHANNEL: _logger.info('Joined to channel: %s', self.__currentChannel) self.__fsm.update(self) elif newState == STATE.LEAVING_CHANNEL: self.__sendLeaveChannelCommand(self.getCurrentChannel()) elif newState == STATE.LOGGING_OUT: self.__normalLogout = True BigWorld.VOIP.logout() def onVoipInited(self, data): _logger.debug('onVoipInited') returnCode = int(data[VOIPCommon.KEY_RETURN_CODE]) if returnCode == VOIPCommon.CODE_SUCCESS: self.__initialized = True self.__fsm.update(self) self.onInitialized(data) else: self.__initialized = False self.__fsm.reset() _logger.info('---------------------------') _logger.info("ERROR: '%d' - '%s'", int(data[VOIPCommon.KEY_STATUS_CODE]), data[VOIPCommon.KEY_STATUS_STRING]) _logger.info('---------------------------') def onVoipDestroyed(self, data): if int(data[VOIPCommon.KEY_RETURN_CODE]) != VOIPCommon.CODE_SUCCESS: _logger.error('Voip is not destroyed: %r', data) def onCaptureDevicesArrived(self, data): if int(data[VOIPCommon.KEY_RETURN_CODE]) != VOIPCommon.CODE_SUCCESS: _logger.error('Capture devices are not arrived: %r', data) return captureDevicesCount = int(data[VOIPCommon.KEY_COUNT]) self.__captureDevices = [] for i in xrange(captureDevicesCount): self.__captureDevices.append(str(data[VOIPCommon.KEY_CAPTURE_DEVICES + '_' + str(i)])) self.__currentCaptureDevice = str(data[VOIPCommon.KEY_CURRENT_CAPTURE_DEVICE]) self.onCaptureDevicesUpdated() def onSetCaptureDevice(self, data): if int(data[VOIPCommon.KEY_RETURN_CODE]) != VOIPCommon.CODE_SUCCESS: _logger.error('Capture device is not set: %r', data) def onSetLocalSpeakerVolume(self, data): if int(data[VOIPCommon.KEY_RETURN_CODE]) != VOIPCommon.CODE_SUCCESS: _logger.error('Local speaker volume is not set: %r', data) def onSetLocalMicVolume(self, data): if int(data[VOIPCommon.KEY_RETURN_CODE]) != VOIPCommon.CODE_SUCCESS: _logger.error('Local microphone volume is not set: %r', data) def onMuteLocalMic(self, data): if int(data[VOIPCommon.KEY_RETURN_CODE]) != VOIPCommon.CODE_SUCCESS: _logger.error('Local microphone volume is not muted: %r', data) def onLoginStateChange(self, data): returnCode = int(data[VOIPCommon.KEY_RETURN_CODE]) statusCode = int(data[VOIPCommon.KEY_STATUS_CODE]) statusString = data[VOIPCommon.KEY_STATUS_STRING] _logger.debug('onLoginStateChange: Return code %s', returnCode) if returnCode == VOIPCommon.CODE_SUCCESS: state = int(data[VOIPCommon.KEY_STATE]) _logger.debug('Return state %s', state) if state == VOIPCommon.STATE_LOGGED_IN: _logger.debug('onLoginStateChange: LOGGED IN') if self.getAPI() == VOIP_SUPPORTED_API.VIVOX: self.bwProto.voipProvider.logVivoxLogin() self.__loggedIn = True self.__expBackOff.reset() if self.__fsm.getState() == STATE.JOINED_CHANNEL: self.__joinChannel(self.__channel[0], self.__channel[1]) self.__fsm.update(self) elif state == VOIPCommon.STATE_LOGGED_OUT: _logger.debug('onLoginStateChange: LOGGED OUT %d - %s', statusCode, statusString) if self.__normalLogout: _logger.debug('onLoginStateChange: Normal logout') self.__normalLogout = False self.__loggedIn = False self.__fsm.update(self) elif self.__reLoginCallbackID is None: _logger.debug('onLoginStateChange: Network lost logout') self.__setReloginCallback() elif state == VOIPCommon.STATE_LOGGIN_OUT: _logger.debug('onLoginStateChange: LOGGING OUT %d - %s', statusCode, statusString) else: _logger.info('---------------------------') _logger.info("ERROR: '%d' - '%s'", statusCode, statusString) _logger.info('---------------------------') if (statusCode == VOIPCommon.STATUS_WRONG_CREDENTIALS or statusCode == VOIPCommon.STATUS_UNKNOWN_ACCOUNT) and self.__loginAttemptsRemained > 0: self.__reloginUser() else: self.onFailedToConnect() return def onSessionAdded(self, data): if int(data[VOIPCommon.KEY_RETURN_CODE]) != VOIPCommon.CODE_SUCCESS: _logger.error('Session is not added: %r', data) return currentChannel = self.__currentChannel = data[VOIPCommon.KEY_URI] self.__setVolume() self.__fsm.update(self) isTestChannel = currentChannel == self.__testDomain self.onJoinedChannel(currentChannel, isTestChannel, self.__isChannelRejoin and not isTestChannel) def onSessionRemoved(self, data): if int(data[VOIPCommon.KEY_RETURN_CODE]) != VOIPCommon.CODE_SUCCESS: _logger.error('Session is not removed: %r', data) return for dbid in self.__channelUsers.iterkeys(): self.onPlayerSpeaking(dbid, False) self.__channelUsers.clear() self.__restoreMasterVolume() leftChannel = self.__currentChannel wasTest = leftChannel == self.__testDomain self.__currentChannel = '' self.__fsm.update(self) self.onLeftChannel(leftChannel, wasTest) def onNetworkTest(self, data): returnCode = int(data[VOIPCommon.KEY_RETURN_CODE]) if returnCode == VOIPCommon.CODE_ERROR: _logger.info('---------------------------') _logger.info("ERROR: '%d' - '%s'", int(data[VOIPCommon.KEY_STATUS_CODE]), data[VOIPCommon.KEY_STATUS_STRING]) _logger.info('---------------------------') self.onFailedToConnect() self.__clearDesiredChannel() self.__clearUser() def onParticipantAdded(self, data): if int(data[VOIPCommon.KEY_RETURN_CODE]) != VOIPCommon.CODE_SUCCESS: _logger.error('Participant is not added: %r', data) return uri = data[VOIPCommon.KEY_PARTICIPANT_URI] dbid, _ = self.__extractDBIDFromURI(uri) if dbid == -1: return self.__channelUsers[dbid] = {'talking': False, 'uri': uri, 'muted': False} user = self.usersStorage.getUser(dbid) if user and user.isMuted(): self.__muteParticipantForMe(dbid, True) def onParticipantRemoved(self, data): if int(data[VOIPCommon.KEY_RETURN_CODE]) != VOIPCommon.CODE_SUCCESS: _logger.error('Participant is not removed: %r', data) return uri = data[VOIPCommon.KEY_PARTICIPANT_URI] dbid, _ = self.__extractDBIDFromURI(uri) if dbid in self.__channelUsers: del self.__channelUsers[dbid] self.onPlayerSpeaking(dbid, False) def onParticipantUpdated(self, data): if int(data[VOIPCommon.KEY_RETURN_CODE]) != VOIPCommon.CODE_SUCCESS: _logger.error('Participant is not updated: %r', data) return uri = data[VOIPCommon.KEY_PARTICIPANT_URI] dbid, _ = self.__extractDBIDFromURI(uri) if dbid == -1: return talking = int(data[VOIPCommon.KEY_IS_SPEAKING]) if dbid in self.__channelUsers: channelUser = self.__channelUsers[dbid] if channelUser['talking'] != talking: channelUser['talking'] = talking if self.__isAnyoneTalking(): self.__muffleMasterVolume() else: self.__restoreMasterVolume() self.onPlayerSpeaking(dbid, talking) @staticmethod def __isAutoJoinChannel(): if hasattr(BigWorld.player(), 'arena'): arena = BigWorld.player().arena return not (arena is not None and arena.guiType in (ARENA_GUI_TYPE.RANDOM, ARENA_GUI_TYPE.EPIC_RANDOM, ARENA_GUI_TYPE.EPIC_BATTLE)) else: return True def __me_onChannelAvailable(self, uri, pwd, isRejoin): self.__isChannelRejoin = isRejoin if not self.__inTesting: self.__setAvailableChannel(uri, pwd) def __me_onChannelLost(self): if not self.__inTesting: self.__leaveChannel() self.settingsCore.applySetting(SOUND.VOIP_ENABLE_CHANNEL, (False, 0)) def __me_onCredentialReceived(self, name, pwd): _logger.debug('OnUserCredentials: %s', name) self.__login(name, pwd) def __me_onUsersListReceived(self, tags): if USER_TAG.MUTED not in tags: return for user in self.usersStorage.getList(MutedFindCriteria()): dbID = user.getID() if dbID in self.__channelUsers: self.__muteParticipantForMe(dbID, True) def __me_onUserActionReceived(self, actionID, user, shadowMode): if actionID in (USER_ACTION_ID.MUTE_SET, USER_ACTION_ID.MUTE_UNSET): self.__onChatActionMute(user.getID(), user.isMuted())
class VOIPManager(VOIPHandler): def __init__(self): LOG_VOIP_INT('VOIPManager.Create') VOIPHandler.__init__(self) self.__initialized = False self.__enabled = False self.__voipDomain = '' self.__testDomain = '' self.__user = ['', ''] self.__channel = ['', ''] self.__currentChannel = '' self.__inTesting = False self.__loggedIn = False self.__needLogginAfterInit = False self.__loginAttemptsRemained = 2 self.__fsm = VOIPFsm() self.__activateMicByVoice = False self.__captureDevices = [] self.__currentCaptureDevice = '' self.__channelUsers = {} self.OnCaptureDevicesUpdated = Event.Event() self.onPlayerSpeaking = Event.Event() self.onInitialized = Event.Event() self.onStateToggled = Event.Event() self.onFailedToConnect = Event.Event() self.onJoinedChannel = Event.Event() self.onLeftChannel = Event.Event() self.__fsm.onStateChanged += self.__onStateChanged @proto_getter(PROTO_TYPE.BW_CHAT2) def bwProto(self): return None @storage_getter('users') def usersStorage(self): return None def destroy(self): self.__fsm.onStateChanged -= self.__onStateChanged BigWorld.VOIP.finalise() LOG_VOIP_INT('VOIPManager.Destroy') closeLog() def isEnabled(self): return self.__enabled def isInitialized(self): return self.__initialized def isNotInitialized(self): return not self.__initialized and self.getState() == STATE.NONE def getVOIPDomain(self): return self.__voipDomain def getCurrentChannel(self): return self.__currentChannel def hasDesiredChannel(self): return self.__channel[0] != '' def getUser(self): return self.__user[0] def isInDesiredChannel(self): return self.__channel[0] == self.__currentChannel def getCaptureDevices(self): return self.__captureDevices def getCurrentCaptureDevice(self): return self.__currentCaptureDevice def getState(self): return self.__fsm.getState() def getAPI(self): return BigWorld.VOIP.getAPI() def isLoggedIn(self): return self.__loggedIn def onConnected(self): LOG_VOIP_INT('VOIPManager.Subscribe') self.__loginAttemptsRemained = 2 voipEvents = g_messengerEvents.voip voipEvents.onChannelEntered += self.__me_onChannelEntered voipEvents.onChannelLeft += self.__me_onChannelLeft voipEvents.onCredentialReceived += self.__me_onCredentialReceived usersEvents = g_messengerEvents.users usersEvents.onUsersListReceived += self.__me_onUsersListReceived usersEvents.onUserActionReceived += self.__me_onUserActionReceived def onDisconnected(self): LOG_VOIP_INT('VOIPManager.Unsubscribe') voipEvents = g_messengerEvents.voip voipEvents.onChannelEntered -= self.__me_onChannelEntered voipEvents.onChannelLeft -= self.__me_onChannelLeft voipEvents.onCredentialReceived -= self.__me_onCredentialReceived usersEvents = g_messengerEvents.users usersEvents.onUsersListReceived -= self.__me_onUsersListReceived usersEvents.onUserActionReceived -= self.__me_onUserActionReceived def enable(self, enabled): if enabled: self.__enable() self.onStateToggled(True, set()) else: dbIDs = set() for dbID, data in self.__channelUsers.iteritems(): if data['talking']: dbIDs.add(dbID) self.__disable() self.onStateToggled(False, dbIDs) self.__fsm.update(self) def __enable(self): LOG_VOIP_INT('VOIPManager.Enable') self.__enabled = True if self.__channel[0] != '' and not self.__user[0]: self.__requestCredentials() def __disable(self): LOG_VOIP_INT('VOIPManager.Disable') self.__enabled = False def initialize(self, domain): LOG_VOIP_INT('VOIPManager.Initialize') if not self.__initialized is False: raise AssertionError self.__voipDomain = domain self.__testDomain = 'sip:confctl-2@' + self.__voipDomain.partition('www.')[2] LOG_VOIP_INT("voip_domain: '%s'" % self.__voipDomain) LOG_VOIP_INT("test_domain: '%s'" % self.__testDomain) self.__fsm.update(self) logLevel = 0 section = Settings.g_instance.userPrefs if section.has_key('development'): section = section['development'] logLevel = section.has_key('vivoxLogLevel') and section['vivoxLogLevel'].asInt vinit = {KEY_SERVER: 'http://%s/api2' % self.__voipDomain, KEY_MIN_PORT: '0', KEY_MAX_PORT: '0', KEY_LOG_PREFIX: 'voip', KEY_LOG_SUFFIX: '.txt', KEY_LOG_FOLDER: '.', KEY_LOG_LEVEL: str(logLevel)} BigWorld.VOIP.initialise(vinit) def __login(self, name, password): if not self.__initialized: self.__needLogginAfterInit = True self.__user = [name, password] self.__fsm.update(self) def __loginUser(self, username, password): LOG_VOIP_INT("Login Request: '%s', '%s'" % (username, password)) cmd = {KEY_PARTICIPANT_PROPERTY_FREQUENCY: '100'} BigWorld.VOIP.login(username, password, cmd) def __reloginUser(self): self.__loginAttemptsRemained -= 1 LOG_VOIP_INT('VOIPHandler.ReloginUser. Attempts remained: %d' % self.__loginAttemptsRemained) if self.__enabled: self.__requestCredentials(1) def logout(self): LOG_VOIP_INT('VOIPManager.Logout') self.__clearUser() self.__clearDesiredChannel() self.__fsm.update(self) def __enterChannel(self, channel, password): if not self.__initialized and self.__fsm.inNoneState(): self.initialize(self.__voipDomain) if not self.__user[0] and self.isEnabled(): self.__requestCredentials() LOG_VOIP_INT("VOIPManager.EnterChannel: '%s' '%s'" % (channel, password)) self.__channel = [channel, password] self.__fsm.update(self) def __joinChannel(self, channel, password): LOG_VOIP_INT("Joining channel '%s'" % channel) BigWorld.VOIP.joinChannel(channel, password) def __leaveChannel(self): if not self.__initialized: return LOG_VOIP_INT('VOIPManager.LeaveChannel') self.__clearDesiredChannel() self.__fsm.update(self) def enterTestChannel(self): if self.__inTesting: return LOG_VOIP_INT("VOIPManager.EnterTestChannel: '%s'" % self.__testDomain) self.__inTesting = True self.__enterChannel(self.__testDomain, '') def leaveTestChannel(self): if not self.__inTesting: return LOG_VOIP_INT('VOIPManager.LeaveTestChannel') self.__inTesting = False params = self.bwProto.voipProvider.getChannelParams() if params[0]: self.__enterChannel(*params) else: self.__leaveChannel() def setMasterVolume(self, attenuation): BigWorld.VOIP.setMasterVolume(attenuation) def setMicrophoneVolume(self, attenuation): BigWorld.VOIP.setMicrophoneVolume(attenuation) def __setVolume(self): self.setMasterVolume(int(round(SoundGroups.g_instance.getVolume(KEY_VOIP_MASTER) * 100))) self.setMicrophoneVolume(int(round(SoundGroups.g_instance.getVolume(KEY_VOIP_MIC) * 100))) def __muffleMasterVolume(self): SoundGroups.g_instance.muffleFMODVolume() def __restoreMasterVolume(self): SoundGroups.g_instance.restoreFMODVolume() def setVoiceActivation(self, enabled): LOG_VOIP_INT('VOIPManager.SetVoiceActivation: %s' % str(enabled)) self.__activateMicByVoice = enabled self.setMicMute(not enabled) def setMicMute(self, muted = True): if not self.__initialized: return if muted and self.__activateMicByVoice: return self.__setMicMute(muted) def __setMicMute(self, muted): LOG_VOIP_INT('VOIPManager.SetMicMute: %s' % str(muted)) if muted: BigWorld.VOIP.disableMicrophone() else: BigWorld.VOIP.enableMicrophone() def requestCaptureDevices(self): LOG_VOIP_INT('VOIPManager.RequestCaptureDevices') BigWorld.VOIP.getCaptureDevices() def setCaptureDevice(self, deviceName): LOG_VOIP_INT("VOIPManager.SetCaptureDevice: '%s'" % deviceName) BigWorld.VOIP.setCaptureDevice(deviceName) def isParticipantTalking(self, dbid): outcome = self.__channelUsers.get(dbid, {}).get('talking', False) return outcome def __requestCredentials(self, reset = 0): LOG_VOIP_INT('VOIPManager.RequestUserCredentials') self.bwProto.voipProvider.requestCredentials(reset) def __clearDesiredChannel(self): self.__channel = ['', ''] def __clearUser(self): self.__user = ['', ''] def __onChatActionMute(self, dbid, muted): LOG_VOIP_INT('VOIPManager.OnChatActionMute', dbid, muted) if dbid in self.__channelUsers and self.__channelUsers[dbid]['muted'] != muted: self.__muteParticipantForMe(dbid, muted) def __muteParticipantForMe(self, dbid, mute): LOG_VOIP_INT('VOIPManager.MuteParticipantForMe: %d, %s' % (dbid, str(mute))) raise dbid in self.__channelUsers or AssertionError self.__channelUsers[dbid]['muted'] = mute uri = self.__channelUsers[dbid]['uri'] cmd = {KEY_COMMAND: CMD_SET_PARTICIPANT_MUTE, KEY_PARTICIPANT_URI: uri, KEY_STATE: str(mute)} BigWorld.VOIP.command(cmd) return True def __isAnyoneTalking(self): for info in self.__channelUsers.values(): if info['talking']: return True return False def __extractDBIDFromURI(self, uri): try: domain = self.__voipDomain.partition('www.')[2] login = uri.partition('sip:')[2].rpartition('@' + domain)[0] s = login[login.find('.') + 1:] return (int(s), login) except: return -1 def __sendLeaveChannelCommand(self, channel): LOG_VOIP_INT("Leaving channel '%s'" % channel) if channel: BigWorld.VOIP.leaveChannel(channel) self.__fsm.update(self) def __resetToInitializedState(self): if self.__currentChannel != '': for dbid in self.__channelUsers.keys(): self.onPlayerSpeaking(dbid, False) self.__channelUsers.clear() self.__restoreMasterVolume() self.__currentChannel = '' if self.__needLogginAfterInit: self.__fsm.update(self) self.__needLogginAfterInit = False def __onStateChanged(self, _, newState): if newState == STATE.INITIALIZED: self.__resetToInitializedState() elif newState == STATE.LOGGING_IN: self.__loginUser(self.__user[0], self.__user[1]) elif newState == STATE.LOGGED_IN: self.__fsm.update(self) elif newState == STATE.JOINING_CHANNEL: muteMic = self.__channel[0] != self.__testDomain and not self.__activateMicByVoice self.setMicMute(muteMic) self.__joinChannel(self.__channel[0], self.__channel[1]) elif newState == STATE.JOINED_CHANNEL: LOG_VOIP_INT("Joined to channel: '%s'" % self.__currentChannel) self.__fsm.update(self) elif newState == STATE.LEAVING_CHANNEL: self.__sendLeaveChannelCommand(self.getCurrentChannel()) elif newState == STATE.LOGGING_OUT: BigWorld.VOIP.logout() def onVoipInited(self, data): returnCode = int(data[KEY_RETURN_CODE]) if returnCode == CODE_SUCCESS: self.__initialized = True self.__fsm.update(self) self.onInitialized(data) else: self.__initialized = False self.__fsm.reset() LOG_VOIP_INT('---------------------------') LOG_VOIP_INT("ERROR: '%d' - '%s'" % (int(data[KEY_STATUS_CODE]), data[KEY_STATUS_STRING])) LOG_VOIP_INT('---------------------------') def onVoipDestroyed(self, data): raise int(data[KEY_RETURN_CODE]) == CODE_SUCCESS or AssertionError def onCaptureDevicesArrived(self, data): raise int(data[KEY_RETURN_CODE]) == CODE_SUCCESS or AssertionError captureDevicesCount = int(data[KEY_COUNT]) self.__captureDevices = [] for i in xrange(captureDevicesCount): self.__captureDevices.append(str(data[KEY_CAPTURE_DEVICES + '_' + str(i)])) self.__currentCaptureDevice = str(data[KEY_CURRENT_CAPTURE_DEVICE]) self.OnCaptureDevicesUpdated() def onSetCaptureDevice(self, data): raise int(data[KEY_RETURN_CODE]) == CODE_SUCCESS or AssertionError def onSetLocalSpeakerVolume(self, data): raise int(data[KEY_RETURN_CODE]) == CODE_SUCCESS or AssertionError def onSetLocalMicVolume(self, data): raise int(data[KEY_RETURN_CODE]) == CODE_SUCCESS or AssertionError def onMuteLocalMic(self, data): raise int(data[KEY_RETURN_CODE]) == CODE_SUCCESS or AssertionError def onLoginStateChange(self, data): returnCode = int(data[KEY_RETURN_CODE]) if returnCode == CODE_SUCCESS: state = int(data[KEY_STATE]) if state == STATE_LOGGED_IN: if self.getAPI() == VOIP_SUPPORTED_API.VIVOX: self.bwProto.voipProvider.logVivoxLogin() self.__loggedIn = True self.__fsm.update(self) elif state == STATE_LOGGED_OUT: self.__loggedIn = False self.__fsm.update(self) else: LOG_VOIP_INT('---------------------------') LOG_VOIP_INT("ERROR: '%d' - '%s'" % (int(data[KEY_STATUS_CODE]), data[KEY_STATUS_STRING])) LOG_VOIP_INT('---------------------------') code = int(data[KEY_STATUS_CODE]) if (code == STATUS_WRONG_CREDENTIALS or code == STATUS_UNKNOWN_ACCOUNT) and self.__loginAttemptsRemained > 0: self.__reloginUser() else: self.onFailedToConnect() def onSessionAdded(self, data): raise int(data[KEY_RETURN_CODE]) == CODE_SUCCESS or AssertionError raise not self.__channelUsers or AssertionError self.__currentChannel = data[KEY_URI] self.__setVolume() self.__fsm.update(self) self.onJoinedChannel(data) def onSessionRemoved(self, data): raise int(data[KEY_RETURN_CODE]) == CODE_SUCCESS or AssertionError for dbid in self.__channelUsers.keys(): self.onPlayerSpeaking(dbid, False) self.__channelUsers.clear() self.__restoreMasterVolume() self.__currentChannel = '' self.__fsm.update(self) self.onLeftChannel(data) def onNetworkTest(self, data): returnCode = int(data[KEY_RETURN_CODE]) if returnCode == CODE_ERROR: LOG_VOIP_INT('---------------------------') LOG_VOIP_INT("ERROR: '%d' - '%s'" % (int(data[KEY_STATUS_CODE]), data[KEY_STATUS_STRING])) LOG_VOIP_INT('---------------------------') self.onFailedToConnect() self.__clearDesiredChannel() self.__clearUser() def onParticipantAdded(self, data): if not int(data[KEY_RETURN_CODE]) == CODE_SUCCESS: raise AssertionError uri = data[KEY_PARTICIPANT_URI] dbid, _ = self.__extractDBIDFromURI(uri) if dbid == -1: return self.__channelUsers[dbid] = {'talking': False, 'uri': uri, 'muted': False} user = self.usersStorage.getUser(dbid) user and user.isMuted() and self.__muteParticipantForMe(dbid, True) def onParticipantRemoved(self, data): if not int(data[KEY_RETURN_CODE]) == CODE_SUCCESS: raise AssertionError uri = data[KEY_PARTICIPANT_URI] dbid, _ = self.__extractDBIDFromURI(uri) del dbid in self.__channelUsers and self.__channelUsers[dbid] self.onPlayerSpeaking(dbid, False) def onParticipantUpdated(self, data): if not int(data[KEY_RETURN_CODE]) == CODE_SUCCESS: raise AssertionError uri = data[KEY_PARTICIPANT_URI] dbid, participantLogin = self.__extractDBIDFromURI(uri) if dbid == -1: return talking = int(data[KEY_IS_SPEAKING]) channelUser = self.__channelUsers[dbid] if dbid in self.__channelUsers: channelUser['talking'] = channelUser['talking'] != talking and talking self.__muffleMasterVolume() if self.__isAnyoneTalking() else self.__restoreMasterVolume() self.onPlayerSpeaking(dbid, talking) def __me_onChannelEntered(self, uri, pwd): if not self.__inTesting: self.__enterChannel(uri, pwd) def __me_onChannelLeft(self): if not self.__inTesting: self.__leaveChannel() def __me_onCredentialReceived(self, name, pwd): LOG_VOIP_INT("VOIPManager.OnUserCredentials: '%s' '%s'" % (name, pwd)) self.__login(name, pwd) def __me_onUsersListReceived(self, tags): if USER_TAG.MUTED not in tags: return for user in self.usersStorage.getList(MutedFindCriteria()): dbID = user.getID() if dbID in self.__channelUsers: self.__muteParticipantForMe(dbID, True) def __me_onUserActionReceived(self, actionID, user): if actionID in (USER_ACTION_ID.MUTE_SET, USER_ACTION_ID.MUTE_UNSET): self.__onChatActionMute(user.getID(), user.isMuted())
class VOIPManager(VOIPHandler): """ VOIP manager class. It is a bridge between C++ code and the client. """ def __init__(self): LOG_VOIP_INT('VOIPManager.Create') super(VOIPManager, self).__init__() self.__initialized = False self.__enabled = False self.__voipDomain = '' self.__testDomain = '' self.__user = ['', ''] self.__channel = ['', ''] self.__currentChannel = '' self.__inTesting = False self.__loggedIn = False self.__needLogginAfterInit = False self.__loginAttemptsRemained = 2 self.__fsm = VOIPFsm() self.__activateMicByVoice = False self.__captureDevices = [] self.__currentCaptureDevice = '' self.__channelUsers = {} self.onCaptureDevicesUpdated = Event.Event() self.onPlayerSpeaking = Event.Event() self.onInitialized = Event.Event() self.onStateToggled = Event.Event() self.onFailedToConnect = Event.Event() self.onJoinedChannel = Event.Event() self.onLeftChannel = Event.Event() self.__fsm.onStateChanged += self.__onStateChanged @proto_getter(PROTO_TYPE.BW_CHAT2) def bwProto(self): """ Returns instance of chat plugin to have access to VOIP Provider. This provider contains methods: requestCredentials, logVivoxLogin. :return: instance of chat plugin """ return None @storage_getter('users') def usersStorage(self): """ Returns instance of UsersStorage from messenger package. :return: instance of UsersStorage """ return None def destroy(self): self.__fsm.onStateChanged -= self.__onStateChanged BigWorld.VOIP.finalise() LOG_VOIP_INT('VOIPManager.Destroy') closeLog() def isEnabled(self): return self.__enabled def isInitialized(self): return self.__initialized def isNotInitialized(self): """ Check if the manager is initialized and has appropriate state. :return: True if it is initialized and does not start initializing process, otherwise - False. """ return not self.__initialized and self.getState() == STATE.NONE def getVOIPDomain(self): return self.__voipDomain def getCurrentChannel(self): return self.__currentChannel def hasDesiredChannel(self): return self.__channel[0] != '' def getUser(self): return self.__user[0] def isInDesiredChannel(self): return self.__channel[0] == self.__currentChannel def getCaptureDevices(self): return self.__captureDevices def getCurrentCaptureDevice(self): return self.__currentCaptureDevice def getState(self): return self.__fsm.getState() def getAPI(self): return BigWorld.VOIP.getAPI() def isLoggedIn(self): return self.__loggedIn def onConnected(self): LOG_VOIP_INT('VOIPManager.Subscribe') self.__loginAttemptsRemained = 2 voipEvents = g_messengerEvents.voip voipEvents.onChannelEntered += self.__me_onChannelEntered voipEvents.onChannelLeft += self.__me_onChannelLeft voipEvents.onCredentialReceived += self.__me_onCredentialReceived usersEvents = g_messengerEvents.users usersEvents.onUsersListReceived += self.__me_onUsersListReceived usersEvents.onUserActionReceived += self.__me_onUserActionReceived def onDisconnected(self): LOG_VOIP_INT('VOIPManager.Unsubscribe') voipEvents = g_messengerEvents.voip voipEvents.onChannelEntered -= self.__me_onChannelEntered voipEvents.onChannelLeft -= self.__me_onChannelLeft voipEvents.onCredentialReceived -= self.__me_onCredentialReceived usersEvents = g_messengerEvents.users usersEvents.onUsersListReceived -= self.__me_onUsersListReceived usersEvents.onUserActionReceived -= self.__me_onUserActionReceived def enable(self, enabled): if enabled: self.__enable() self.onStateToggled(True, set()) else: dbIDs = set() for dbID, data in self.__channelUsers.iteritems(): if data['talking']: dbIDs.add(dbID) self.__disable() self.onStateToggled(False, dbIDs) self.__fsm.update(self) def __enable(self): LOG_VOIP_INT('VOIPManager.Enable') self.__enabled = True if self.__channel[0] != '' and not self.__user[0]: self.__requestCredentials() def __disable(self): LOG_VOIP_INT('VOIPManager.Disable') self.__enabled = False def initialize(self, domain): LOG_VOIP_INT('VOIPManager.Initialize') if not self.__initialized is False: raise AssertionError self.__voipDomain = domain self.__testDomain = 'sip:confctl-2@' + self.__voipDomain.partition('www.')[2] LOG_VOIP_INT("voip_domain: '%s'" % self.__voipDomain) LOG_VOIP_INT("test_domain: '%s'" % self.__testDomain) self.__fsm.update(self) logLevel = 0 section = Settings.g_instance.userPrefs if section.has_key('development'): section = section['development'] logLevel = section.has_key('vivoxLogLevel') and section['vivoxLogLevel'].asInt vinit = {KEY_SERVER: 'http://%s/api2' % self.__voipDomain, KEY_MIN_PORT: '0', KEY_MAX_PORT: '0', KEY_LOG_PREFIX: 'voip', KEY_LOG_SUFFIX: '.txt', KEY_LOG_FOLDER: '.', KEY_LOG_LEVEL: str(logLevel)} BigWorld.VOIP.initialise(vinit) def __login(self, name, password): if not self.__initialized: self.__needLogginAfterInit = True self.__user = [name, password] self.__fsm.update(self) def __loginUser(self, username, password): LOG_VOIP_INT("Login Request: '%s', '%s'" % (username, password)) cmd = {KEY_PARTICIPANT_PROPERTY_FREQUENCY: '100'} BigWorld.VOIP.login(username, password, cmd) def __reloginUser(self): self.__loginAttemptsRemained -= 1 LOG_VOIP_INT('VOIPHandler.ReloginUser. Attempts remained: %d' % self.__loginAttemptsRemained) if self.__enabled: self.__requestCredentials(1) def logout(self): LOG_VOIP_INT('VOIPManager.Logout') self.__clearUser() self.__clearDesiredChannel() self.__fsm.update(self) def __enterChannel(self, channel, password): if not self.__initialized and self.__fsm.inNoneState(): self.initialize(self.__voipDomain) if not self.__user[0] and self.isEnabled(): self.__requestCredentials() LOG_VOIP_INT("VOIPManager.EnterChannel: '%s' '%s'" % (channel, password)) self.__channel = [channel, password] self.__fsm.update(self) def __joinChannel(self, channel, password): LOG_VOIP_INT("Joining channel '%s'" % channel) BigWorld.VOIP.joinChannel(channel, password) def __leaveChannel(self): if not self.__initialized: return LOG_VOIP_INT('VOIPManager.LeaveChannel') self.__clearDesiredChannel() self.__fsm.update(self) def enterTestChannel(self): if self.__inTesting: return LOG_VOIP_INT("VOIPManager.EnterTestChannel: '%s'" % self.__testDomain) self.__inTesting = True self.__enterChannel(self.__testDomain, '') def leaveTestChannel(self): if not self.__inTesting: return LOG_VOIP_INT('VOIPManager.LeaveTestChannel') self.__inTesting = False params = self.bwProto.voipProvider.getChannelParams() if params[0]: self.__enterChannel(*params) else: self.__leaveChannel() def setMasterVolume(self, attenuation): BigWorld.VOIP.setMasterVolume(attenuation) def setMicrophoneVolume(self, attenuation): BigWorld.VOIP.setMicrophoneVolume(attenuation) def __setVolume(self): self.setMasterVolume(int(round(SoundGroups.g_instance.getVolume(KEY_VOIP_MASTER) * 100))) self.setMicrophoneVolume(int(round(SoundGroups.g_instance.getVolume(KEY_VOIP_MIC) * 100))) def __muffleMasterVolume(self): SoundGroups.g_instance.muffleWWISEVolume() def __restoreMasterVolume(self): SoundGroups.g_instance.restoreWWISEVolume() def setVoiceActivation(self, enabled): LOG_VOIP_INT('VOIPManager.SetVoiceActivation: %s' % str(enabled)) self.__activateMicByVoice = enabled self.setMicMute(not enabled) def setMicMute(self, muted = True): if not self.__initialized: return if muted and self.__activateMicByVoice: return self.__setMicMute(muted) def __setMicMute(self, muted): LOG_VOIP_INT('VOIPManager.SetMicMute: %s' % str(muted)) if muted: BigWorld.VOIP.disableMicrophone() else: BigWorld.VOIP.enableMicrophone() def requestCaptureDevices(self): LOG_VOIP_INT('VOIPManager.RequestCaptureDevices') BigWorld.VOIP.getCaptureDevices() def setCaptureDevice(self, deviceName): LOG_VOIP_INT("VOIPManager.SetCaptureDevice: '%s'" % deviceName) BigWorld.VOIP.setCaptureDevice(deviceName) def isParticipantTalking(self, dbid): outcome = self.__channelUsers.get(dbid, {}).get('talking', False) return outcome def __requestCredentials(self, reset = 0): LOG_VOIP_INT('VOIPManager.RequestUserCredentials') self.bwProto.voipProvider.requestCredentials(reset) def __clearDesiredChannel(self): self.__channel = ['', ''] def __clearUser(self): self.__user = ['', ''] def __onChatActionMute(self, dbid, muted): LOG_VOIP_INT('VOIPManager.OnChatActionMute', dbid, muted) if dbid in self.__channelUsers and self.__channelUsers[dbid]['muted'] != muted: self.__muteParticipantForMe(dbid, muted) def __muteParticipantForMe(self, dbid, mute): LOG_VOIP_INT('VOIPManager.MuteParticipantForMe: %d, %s' % (dbid, str(mute))) raise dbid in self.__channelUsers or AssertionError self.__channelUsers[dbid]['muted'] = mute uri = self.__channelUsers[dbid]['uri'] cmd = {KEY_COMMAND: CMD_SET_PARTICIPANT_MUTE, KEY_PARTICIPANT_URI: uri, KEY_STATE: str(mute)} BigWorld.VOIP.command(cmd) return True def __isAnyoneTalking(self): for info in self.__channelUsers.values(): if info['talking']: return True return False def __extractDBIDFromURI(self, uri): try: domain = self.__voipDomain.partition('www.')[2] login = uri.partition('sip:')[2].rpartition('@' + domain)[0] s = login[login.find('.') + 1:] return (int(s), login) except: return -1 def __sendLeaveChannelCommand(self, channel): LOG_VOIP_INT("Leaving channel '%s'" % channel) if channel: BigWorld.VOIP.leaveChannel(channel) self.__fsm.update(self) def __resetToInitializedState(self): if self.__currentChannel != '': for dbid in self.__channelUsers.keys(): self.onPlayerSpeaking(dbid, False) self.__channelUsers.clear() self.__restoreMasterVolume() self.__currentChannel = '' if self.__needLogginAfterInit: self.__fsm.update(self) self.__needLogginAfterInit = False def __onStateChanged(self, _, newState): if newState == STATE.INITIALIZED: self.__resetToInitializedState() elif newState == STATE.LOGGING_IN: self.__loginUser(self.__user[0], self.__user[1]) elif newState == STATE.LOGGED_IN: self.__fsm.update(self) elif newState == STATE.JOINING_CHANNEL: muteMic = self.__channel[0] != self.__testDomain and not self.__activateMicByVoice self.setMicMute(muteMic) self.__joinChannel(self.__channel[0], self.__channel[1]) elif newState == STATE.JOINED_CHANNEL: LOG_VOIP_INT("Joined to channel: '%s'" % self.__currentChannel) self.__fsm.update(self) elif newState == STATE.LEAVING_CHANNEL: self.__sendLeaveChannelCommand(self.getCurrentChannel()) elif newState == STATE.LOGGING_OUT: BigWorld.VOIP.logout() def onVoipInited(self, data): returnCode = int(data[KEY_RETURN_CODE]) if returnCode == CODE_SUCCESS: self.__initialized = True self.__fsm.update(self) self.onInitialized(data) else: self.__initialized = False self.__fsm.reset() LOG_VOIP_INT('---------------------------') LOG_VOIP_INT("ERROR: '%d' - '%s'" % (int(data[KEY_STATUS_CODE]), data[KEY_STATUS_STRING])) LOG_VOIP_INT('---------------------------') def onVoipDestroyed(self, data): raise int(data[KEY_RETURN_CODE]) == CODE_SUCCESS or AssertionError def onCaptureDevicesArrived(self, data): raise int(data[KEY_RETURN_CODE]) == CODE_SUCCESS or AssertionError captureDevicesCount = int(data[KEY_COUNT]) self.__captureDevices = [] for i in xrange(captureDevicesCount): self.__captureDevices.append(str(data[KEY_CAPTURE_DEVICES + '_' + str(i)])) self.__currentCaptureDevice = str(data[KEY_CURRENT_CAPTURE_DEVICE]) self.onCaptureDevicesUpdated() def onSetCaptureDevice(self, data): raise int(data[KEY_RETURN_CODE]) == CODE_SUCCESS or AssertionError def onSetLocalSpeakerVolume(self, data): raise int(data[KEY_RETURN_CODE]) == CODE_SUCCESS or AssertionError def onSetLocalMicVolume(self, data): raise int(data[KEY_RETURN_CODE]) == CODE_SUCCESS or AssertionError def onMuteLocalMic(self, data): raise int(data[KEY_RETURN_CODE]) == CODE_SUCCESS or AssertionError def onLoginStateChange(self, data): returnCode = int(data[KEY_RETURN_CODE]) if returnCode == CODE_SUCCESS: state = int(data[KEY_STATE]) if state == STATE_LOGGED_IN: if self.getAPI() == VOIP_SUPPORTED_API.VIVOX: self.bwProto.voipProvider.logVivoxLogin() self.__loggedIn = True self.__fsm.update(self) elif state == STATE_LOGGED_OUT: self.__loggedIn = False self.__fsm.update(self) else: LOG_VOIP_INT('---------------------------') LOG_VOIP_INT("ERROR: '%d' - '%s'" % (int(data[KEY_STATUS_CODE]), data[KEY_STATUS_STRING])) LOG_VOIP_INT('---------------------------') code = int(data[KEY_STATUS_CODE]) if (code == STATUS_WRONG_CREDENTIALS or code == STATUS_UNKNOWN_ACCOUNT) and self.__loginAttemptsRemained > 0: self.__reloginUser() else: self.onFailedToConnect() def onSessionAdded(self, data): raise int(data[KEY_RETURN_CODE]) == CODE_SUCCESS or AssertionError raise not self.__channelUsers or AssertionError self.__currentChannel = data[KEY_URI] self.__setVolume() self.__fsm.update(self) self.onJoinedChannel(data) def onSessionRemoved(self, data): raise int(data[KEY_RETURN_CODE]) == CODE_SUCCESS or AssertionError for dbid in self.__channelUsers.keys(): self.onPlayerSpeaking(dbid, False) self.__channelUsers.clear() self.__restoreMasterVolume() self.__currentChannel = '' self.__fsm.update(self) self.onLeftChannel(data) def onNetworkTest(self, data): returnCode = int(data[KEY_RETURN_CODE]) if returnCode == CODE_ERROR: LOG_VOIP_INT('---------------------------') LOG_VOIP_INT("ERROR: '%d' - '%s'" % (int(data[KEY_STATUS_CODE]), data[KEY_STATUS_STRING])) LOG_VOIP_INT('---------------------------') self.onFailedToConnect() self.__clearDesiredChannel() self.__clearUser() def onParticipantAdded(self, data): if not int(data[KEY_RETURN_CODE]) == CODE_SUCCESS: raise AssertionError uri = data[KEY_PARTICIPANT_URI] dbid, _ = self.__extractDBIDFromURI(uri) if dbid == -1: return self.__channelUsers[dbid] = {'talking': False, 'uri': uri, 'muted': False} user = self.usersStorage.getUser(dbid) user and user.isMuted() and self.__muteParticipantForMe(dbid, True) def onParticipantRemoved(self, data): if not int(data[KEY_RETURN_CODE]) == CODE_SUCCESS: raise AssertionError uri = data[KEY_PARTICIPANT_URI] dbid, _ = self.__extractDBIDFromURI(uri) del dbid in self.__channelUsers and self.__channelUsers[dbid] self.onPlayerSpeaking(dbid, False) def onParticipantUpdated(self, data): if not int(data[KEY_RETURN_CODE]) == CODE_SUCCESS: raise AssertionError uri = data[KEY_PARTICIPANT_URI] dbid, participantLogin = self.__extractDBIDFromURI(uri) if dbid == -1: return talking = int(data[KEY_IS_SPEAKING]) if dbid in self.__channelUsers: channelUser = self.__channelUsers[dbid] channelUser['talking'] = channelUser['talking'] != talking and talking self.__muffleMasterVolume() if self.__isAnyoneTalking() else self.__restoreMasterVolume() self.onPlayerSpeaking(dbid, talking) def __me_onChannelEntered(self, uri, pwd): """ Listener of event g_messengerEvents.voip.onChannelEntered. """ if not self.__inTesting: self.__enterChannel(uri, pwd) def __me_onChannelLeft(self): """ Listener of event g_messengerEvents.voip.onChannelLeft. """ if not self.__inTesting: self.__leaveChannel() def __me_onCredentialReceived(self, name, pwd): """ Listener of event g_messengerEvents.voip.onCredentialReceived. """ LOG_VOIP_INT("VOIPManager.OnUserCredentials: '%s' '%s'" % (name, pwd)) self.__login(name, pwd) def __me_onUsersListReceived(self, tags): """ Listener of event g_messengerEvents.users.onUsersListReceived. """ if USER_TAG.MUTED not in tags: return for user in self.usersStorage.getList(MutedFindCriteria()): dbID = user.getID() if dbID in self.__channelUsers: self.__muteParticipantForMe(dbID, True) def __me_onUserActionReceived(self, actionID, user): """ Listener of event g_messengerEvents.users.onUserActionReceived. """ if actionID in (USER_ACTION_ID.MUTE_SET, USER_ACTION_ID.MUTE_UNSET): self.__onChatActionMute(user.getID(), user.isMuted())