import string import sys from direct.showbase import DirectObject from otp.otpbase import OTPGlobals from direct.fsm import ClassicFSM from direct.fsm import State from otp.login import SecretFriendsInfoPanel from otp.login import PrivacyPolicyPanel from otp.otpbase import OTPLocalizer from direct.directnotify import DirectNotifyGlobal from otp.login import LeaveToPayDialog from direct.gui.DirectGui import * from pandac.PandaModules import * ChatEvent = 'ChatEvent' NormalChatEvent = 'NormalChatEvent' SCChatEvent = 'SCChatEvent' SCCustomChatEvent = 'SCCustomChatEvent' SCEmoteChatEvent = 'SCEmoteChatEvent' OnScreen = 0 OffScreen = 1 Thought = 2 ThoughtPrefix = '.' def isThought(message): if len(message) == 0: return 0 elif string.find(message, ThoughtPrefix, 0, len(ThoughtPrefix)) >= 0: return 1 else: return 0 def removeThoughtPrefix(message): if isThought(message): return message[len(ThoughtPrefix):] else: return message class ChatManager(DirectObject.DirectObject): notify = DirectNotifyGlobal.directNotify.newCategory('ChatManager') execChat = base.config.GetBool('exec-chat', 0) def __init__(self, cr, localAvatar): self.cr = cr self.localAvatar = localAvatar self.wantBackgroundFocus = 1 self.__scObscured = 0 self.__normalObscured = 0 self.openChatWarning = None self.unpaidChatWarning = None self.teaser = None self.paidNoParentPassword = None self.noSecretChatAtAll = None self.noSecretChatAtAllAndNoWhitelist = None self.noSecretChatWarning = None self.activateChatGui = None self.chatMoreInfo = None self.chatPrivacyPolicy = None self.secretChatActivated = None self.problemActivatingChat = None self.leaveToPayDialog = None self.fsm = ClassicFSM.ClassicFSM('chatManager', [State.State('off', self.enterOff, self.exitOff), State.State('mainMenu', self.enterMainMenu, self.exitMainMenu), State.State('speedChat', self.enterSpeedChat, self.exitSpeedChat), State.State('normalChat', self.enterNormalChat, self.exitNormalChat), State.State('whisper', self.enterWhisper, self.exitWhisper), State.State('whisperChat', self.enterWhisperChat, self.exitWhisperChat), State.State('whisperChatPlayer', self.enterWhisperChatPlayer, self.exitWhisperChatPlayer), State.State('whisperSpeedChat', self.enterWhisperSpeedChat, self.exitWhisperSpeedChat), State.State('whisperSpeedChatPlayer', self.enterWhisperSpeedChatPlayer, self.exitWhisperSpeedChatPlayer), State.State('openChatWarning', self.enterOpenChatWarning, self.exitOpenChatWarning), State.State('leaveToPayDialog', self.enterLeaveToPayDialog, self.exitLeaveToPayDialog), State.State('unpaidChatWarning', self.enterUnpaidChatWarning, self.exitUnpaidChatWarning), State.State('noSecretChatAtAll', self.enterNoSecretChatAtAll, self.exitNoSecretChatAtAll), State.State('noSecretChatAtAllAndNoWhitelist', self.enterNoSecretChatAtAllAndNoWhitelist, self.exitNoSecretChatAtAllAndNoWhitelist), State.State('noSecretChatWarning', self.enterNoSecretChatWarning, self.exitNoSecretChatWarning), State.State('noFriendsWarning', self.enterNoFriendsWarning, self.exitNoFriendsWarning), State.State('otherDialog', self.enterOtherDialog, self.exitOtherDialog), State.State('activateChat', self.enterActivateChat, self.exitActivateChat), State.State('chatMoreInfo', self.enterChatMoreInfo, self.exitChatMoreInfo), State.State('chatPrivacyPolicy', self.enterChatPrivacyPolicy, self.exitChatPrivacyPolicy), State.State('secretChatActivated', self.enterSecretChatActivated, self.exitSecretChatActivated), State.State('problemActivatingChat', self.enterProblemActivatingChat, self.exitProblemActivatingChat), State.State('whiteListOpenChat', self.enterWhiteListOpenChat, self.exitWhiteListOpenChat), State.State('whiteListAvatarChat', self.enterWhiteListAvatarChat, self.exitWhiteListAvatarChat), State.State('whiteListPlayerChat', self.enterWhiteListPlayerChat, self.exitWhiteListPlayerChat), State.State('trueFriendTeaserPanel', self.enterTrueFriendTeaserPanel, self.exitTrueFriendTeaserPanel)], 'off', 'off') self.fsm.enterInitialState() return def delete(self): self.ignoreAll() del self.fsm if hasattr(self.chatInputNormal, 'destroy'): self.chatInputNormal.destroy() self.chatInputNormal.delete() del self.chatInputNormal self.chatInputSpeedChat.delete() del self.chatInputSpeedChat if self.openChatWarning: self.openChatWarning.destroy() self.openChatWarning = None if self.unpaidChatWarning: self.payButton = None self.unpaidChatWarning.destroy() self.unpaidChatWarning = None if self.teaser: self.teaser.cleanup() self.teaser.unload() self.teaser = None if self.noSecretChatAtAll: self.noSecretChatAtAll.destroy() self.noSecretChatAtAll = None if self.noSecretChatAtAllAndNoWhitelist: self.noSecretChatAtAllAndNoWhitelist.destroy() self.noSecretChatAtAllAndNoWhitelist = None if self.noSecretChatWarning: self.noSecretChatWarning.destroy() self.noSecretChatWarning = None if self.activateChatGui: self.activateChatGui.destroy() self.activateChatGui = None if self.chatMoreInfo: self.chatMoreInfo.destroy() self.chatMoreInfo = None if self.chatPrivacyPolicy: self.chatPrivacyPolicy.destroy() self.chatPrivacyPolicy = None if self.secretChatActivated: self.secretChatActivated.destroy() self.secretChatActivated = None if self.problemActivatingChat: self.problemActivatingChat.destroy() self.problemActivatingChat = None del self.localAvatar del self.cr return def obscure(self, normal, sc): self.__scObscured = sc if self.__scObscured: self.scButton.hide() self.__normalObscured = normal if self.__normalObscured: self.normalButton.hide() def isObscured(self): return (self.__normalObscured, self.__scObscured) def stop(self): self.fsm.request('off') self.ignoreAll() def start(self): self.fsm.request('mainMenu') def announceChat(self): messenger.send(ChatEvent) def announceSCChat(self): messenger.send(SCChatEvent) self.announceChat() def sendChatString(self, message): chatFlags = CFSpeech | CFTimeout if base.cr.wantSwitchboardHacks: from otp.switchboard import badwordpy badwordpy.init('', '') message = badwordpy.scrub(message) if isThought(message): message = removeThoughtPrefix(message) chatFlags = CFThought messenger.send(NormalChatEvent) self.announceChat() def sendWhisperString(self, message, whisperAvatarId): pass def sendSCChatMessage(self, msgIndex): base.talkAssistant.sendOpenSpeedChat(1, msgIndex) def sendSCWhisperMessage(self, msgIndex, whisperAvatarId, toPlayer): if toPlayer: base.talkAssistant.sendPlayerWhisperSpeedChat(1, msgIndex, whisperAvatarId) else: base.talkAssistant.sendAvatarWhisperSpeedChat(1, msgIndex, whisperAvatarId) def sendSCCustomChatMessage(self, msgIndex): base.talkAssistant.sendOpenSpeedChat(3, msgIndex) def sendSCCustomWhisperMessage(self, msgIndex, whisperAvatarId, toPlayer): if toPlayer: base.talkAssistant.sendPlayerWhisperSpeedChat(3, msgIndex, whisperAvatarId) else: base.talkAssistant.sendAvatarWhisperSpeedChat(3, msgIndex, whisperAvatarId) def sendSCEmoteChatMessage(self, emoteId): base.talkAssistant.sendOpenSpeedChat(2, emoteId) def sendSCEmoteWhisperMessage(self, emoteId, whisperAvatarId, toPlayer): if toPlayer: base.talkAssistant.sendPlayerWhisperSpeedChat(2, emoteId, whisperAvatarId) else: base.talkAssistant.sendAvatarWhisperSpeedChat(2, emoteId, whisperAvatarId) def enterOff(self): self.scButton.hide() self.normalButton.hide() self.ignoreAll() def exitOff(self): pass def enterMainMenu(self): self.checkObscurred() if self.localAvatar.canChat() or self.cr.wantMagicWords: if self.wantBackgroundFocus: self.chatInputNormal.chatEntry['backgroundFocus'] = 1 self.acceptOnce('enterNormalChat', self.fsm.request, ['normalChat']) def checkObscurred(self): if not self.__scObscured: self.scButton.show() if not self.__normalObscured: self.normalButton.show() def exitMainMenu(self): self.scButton.hide() self.normalButton.hide() self.ignore('enterNormalChat') if self.wantBackgroundFocus: self.chatInputNormal.chatEntry['backgroundFocus'] = 0 def whisperTo(self, avatarName, avatarId, playerId = None): self.fsm.request('whisper', [avatarName, avatarId, playerId]) def noWhisper(self): self.fsm.request('mainMenu') def handleWhiteListSelect(self): self.fsm.request('whiteListOpenChat') def enterWhiteListOpenChat(self): self.checkObscurred() if self.wantBackgroundFocus: self.chatInputNormal.chatEntry['backgroundFocus'] = 0 base.localAvatar.chatMgr.chatInputWhiteList.activateByData() def exitWhiteListOpenChat(self): pass def enterWhiteListAvatarChat(self, receiverId): if self.wantBackgroundFocus: self.chatInputNormal.chatEntry['backgroundFocus'] = 0 base.localAvatar.chatMgr.chatInputWhiteList.activateByData(receiverId, 0) def exitWhiteListAvatarChat(self): pass def enterWhiteListPlayerChat(self, receiverId): if self.wantBackgroundFocus: self.chatInputNormal.chatEntry['backgroundFocus'] = 0 base.localAvatar.chatMgr.chatInputWhiteList.activateByData(receiverId, 1) def exitWhiteListPlayerChat(self): pass def enterWhisper(self, avatarName, avatarId, playerId = None): self.whisperScButton['extraArgs'] = [avatarName, avatarId, playerId] self.whisperButton['extraArgs'] = [avatarName, avatarId, playerId] playerName = None chatToToon = 1 online = 0 if avatarId in self.cr.doId2do: online = 1 elif self.cr.isFriend(avatarId): online = self.cr.isFriendOnline(avatarId) hasManager = hasattr(base.cr, 'playerFriendsManager') if hasManager: if base.cr.playerFriendsManager.askAvatarOnline(avatarId): online = 1 avatarUnderstandable = 0 playerUnderstandable = 0 av = None if avatarId: av = self.cr.identifyAvatar(avatarId) if av != None: avatarUnderstandable = av.isUnderstandable() if playerId: if playerId in base.cr.playerFriendsManager.playerId2Info: playerInfo = base.cr.playerFriendsManager.playerId2Info.get(playerId) playerName = playerInfo.playerName online = 1 playerUnderstandable = playerInfo.understandableYesNo if playerUnderstandable or not avatarId: chatToToon = 0 if chatToToon: chatName = avatarName else: chatName = playerName normalButtonObscured, scButtonObscured = self.isObscured() if (avatarUnderstandable or playerUnderstandable) and online and not normalButtonObscured: self.whisperButton['state'] = 'normal' self.enablewhisperButton() else: self.whisperButton['state'] = 'inactive' self.disablewhisperButton() if online: self.whisperScButton['state'] = 'normal' self.changeFrameText(OTPLocalizer.ChatManagerWhisperToName % chatName) else: self.whisperScButton['state'] = 'inactive' self.changeFrameText(OTPLocalizer.ChatManagerWhisperOffline % chatName) self.whisperFrame.show() self.refreshWhisperFrame() if avatarUnderstandable or playerUnderstandable: if playerId and not chatToToon: if self.wantBackgroundFocus: self.chatInputNormal.chatEntry['backgroundFocus'] = 1 self.acceptOnce('enterNormalChat', self.fsm.request, ['whisperChatPlayer', [avatarName, playerId]]) elif online and chatToToon: if self.wantBackgroundFocus: self.chatInputNormal.chatEntry['backgroundFocus'] = 1 self.acceptOnce('enterNormalChat', self.fsm.request, ['whisperChat', [avatarName, avatarId]]) if base.cr.config.GetBool('force-typed-whisper-enabled', 0): self.whisperButton['state'] = 'normal' self.enablewhisperButton() return def disablewhisperButton(self): pass def enablewhisperButton(self): pass def refreshWhisperFrame(self): pass def changeFrameText(self, newText): self.whisperFrame['text'] = newText def exitWhisper(self): self.whisperFrame.hide() self.ignore('enterNormalChat') self.chatInputNormal.chatEntry['backgroundFocus'] = 0 def enterWhisperSpeedChat(self, avatarId): self.whisperFrame.show() if self.wantBackgroundFocus: self.chatInputNormal.chatEntry['backgroundFocus'] = 0 self.chatInputSpeedChat.show(avatarId) def exitWhisperSpeedChat(self): self.whisperFrame.hide() self.chatInputSpeedChat.hide() def enterWhisperSpeedChatPlayer(self, playerId): self.whisperFrame.show() if self.wantBackgroundFocus: self.chatInputNormal.chatEntry['backgroundFocus'] = 0 self.chatInputSpeedChat.show(playerId, 1) def exitWhisperSpeedChatPlayer(self): self.whisperFrame.hide() self.chatInputSpeedChat.hide() def enterWhisperChat(self, avatarName, avatarId): result = self.chatInputNormal.activateByData(avatarId) return result def exitWhisperChat(self): self.chatInputNormal.deactivate() def enterWhisperChatPlayer(self, avatarName, playerId): playerInfo = base.cr.playerFriendsManager.getFriendInfo(playerId) if playerInfo: avatarName = playerInfo.playerName result = self.chatInputNormal.activateByData(playerId, 1) return result def exitWhisperChatPlayer(self): self.chatInputNormal.deactivate() def enterSpeedChat(self): messenger.send('enterSpeedChat') if not self.__scObscured: self.scButton.show() if not self.__normalObscured: self.normalButton.show() if self.wantBackgroundFocus: self.chatInputNormal.chatEntry['backgroundFocus'] = 0 self.chatInputSpeedChat.show() def exitSpeedChat(self): self.scButton.hide() self.normalButton.hide() self.chatInputSpeedChat.hide() def enterNormalChat(self): result = self.chatInputNormal.activateByData() return result def exitNormalChat(self): self.chatInputNormal.deactivate() def enterOpenChatWarning(self): self.notify.error('called enterOpenChatWarning() on parent class') def exitOpenChatWarning(self): self.notify.error('called exitOpenChatWarning() on parent class') def enterLeaveToPayDialog(self): if self.leaveToPayDialog == None: self.leaveToPayDialog = LeaveToPayDialog.LeaveToPayDialog(self.paidNoParentPassword) self.leaveToPayDialog.setCancel(self.__handleLeaveToPayCancel) self.leaveToPayDialog.show() return def exitLeaveToPayDialog(self): if self.leaveToPayDialog: self.leaveToPayDialog.destroy() self.leaveToPayDialog = None return def enterUnpaidChatWarning(self): self.notify.error('called enterUnpaidChatWarning() on parent class') def exitUnpaidChatWarning(self): self.notify.error('called exitUnpaidChatWarning() on parent class') def enterNoSecretChatAtAll(self): self.notify.error('called enterNoSecretChatAtAll() on parent class') def exitNoSecretChatAtAll(self): self.notify.error('called exitNoSecretChatAtAll() on parent class') def enterNoSecretChatAtAllAndNoWhitelist(self): self.notify.error('called enterNoSecretChatAtAllAndNoWhitelist() on parent class') def exitNoSecretChatAtAllAndNoWhitelist(self): self.notify.error('called exitNoSecretChatAtAllAndNoWhitelist() on parent class') def enterNoSecretChatWarning(self): self.notify.error('called enterNoSecretChatWarning() on parent class') def exitNoSecretChatWarning(self): self.notify.error('called exitNoSecretChatWarning() on parent class') def enterNoFriendsWarning(self): self.notify.error('called enterNoFriendsWarning() on parent class') def exitNoFriendsWarning(self): self.notify.error('called exitNoFriendsWarning() on parent class') def enterActivateChat(self): self.notify.error('called enterActivateChat() on parent class') def exitActivateChat(self): self.notify.error('called exitActivateChat() on parent class') def enterOtherDialog(self): pass def exitOtherDialog(self): pass def enterChatMoreInfo(self): if self.chatMoreInfo == None: self.chatMoreInfo = SecretFriendsInfoPanel.SecretFriendsInfoPanel('secretFriendsInfoDone') self.chatMoreInfo.show() self.accept('secretFriendsInfoDone', self.__secretFriendsInfoDone) return def exitChatMoreInfo(self): self.chatMoreInfo.hide() self.ignore('secretFriendsInfoDone') def enterChatPrivacyPolicy(self): if self.chatPrivacyPolicy == None: self.chatPrivacyPolicy = PrivacyPolicyPanel.PrivacyPolicyPanel('privacyPolicyDone') self.chatPrivacyPolicy.show() self.accept('privacyPolicyDone', self.__privacyPolicyDone) return def exitChatPrivacyPolicy(self): cleanupDialog('privacyPolicyDialog') self.chatPrivacyPolicy = None self.ignore('privacyPolicyDone') return def enterSecretChatActivated(self): self.notify.error('called enterSecretChatActivated() on parent class') def exitSecretChatActivated(self): self.notify.error('called exitSecretChatActivated() on parent class') def enterProblemActivatingChat(self): self.notify.error('called enterProblemActivatingChat() on parent class') def exitProblemActivatingChat(self): self.notify.error('called exitProblemActivatingChat() on parent class') def enterTrueFriendTeaserPanel(self): self.notify.error('called enterTrueFriendTeaserPanel () on parent class') def exitTrueFriendTeaserPanel(self): self.notify.error('called exitTrueFriendTeaserPanel () on parent class') def __handleLeaveToPayCancel(self): self.fsm.request('mainMenu') def __secretFriendsInfoDone(self): self.fsm.request('activateChat') def __privacyPolicyDone(self): self.fsm.request('activateChat')