class ChatAgentUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory("ChatAgentUD") def announceGenerate(self): DistributedObjectGlobalUD.announceGenerate(self) self.whiteList = TTWhiteList() def chatMessage(self, message): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent('suspicious', self.air.getAccountIdFromSender(), 'Account sent chat without an avatar', message) return modifications = [] words = message.split(' ') offset = 0 WantWhitelist = config.GetBool('want-whitelist', 1) for word in words: if word and not self.whiteList.isWord(word) and WantWhitelist: modifications.append((offset, offset+len(word)-1)) offset += len(word) + 1 cleanMessage = message for modStart, modStop in modifications: cleanMessage = cleanMessage[:modStart] + '*'*(modStop-modStart+1) + cleanMessage[modStop+1:] self.air.writeServerEvent('chat-said', sender, message, cleanMessage) dclass = self.air.dclassesByName['DistributedAvatarUD'] dg = dclass.aiFormatUpdate( 'setTalk', sender, sender, self.air.ourChannel, [0, 0, '', cleanMessage, modifications, 0]) self.air.send(dg)
class ChatAgentUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory("ChatAgentUD") def announceGenerate(self): DistributedObjectGlobalUD.announceGenerate(self) self.whiteList = TTWhiteList() self.muted = {} def muteAccount(self, account, howLong): print['muteAccount', account, howLong] self.muted[account] = int(time.time() / 60) + howLong def unmuteAccount(self, account): print['unuteAccount', account] if account in self.muted: del self.muted[account] def chatMessage(self, message): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent('suspicious', self.air.getAccountIdFromSender(), 'Account sent chat without an avatar', message) return if sender in self.muted and int(time.time() / 60) < self.muted[sender]: return modifications = [] words = message.split(' ') offset = 0 WantWhitelist = config.GetBool('want-whitelist', 1) for word in words: if word and not self.whiteList.isWord(word) and WantWhitelist: modifications.append((offset, offset + len(word) - 1)) offset += len(word) + 1 cleanMessage = message for modStart, modStop in modifications: cleanMessage = cleanMessage[:modStart] + '*' * ( modStop - modStart + 1) + cleanMessage[modStop + 1:] self.air.writeServerEvent('chat-said', sender, message, cleanMessage) # TODO: The above is probably a little too ugly for my taste... Maybe AIR # should be given an API for sending updates for unknown objects? DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD'] dg = DistributedAvatar.aiFormatUpdate( 'setTalk', sender, sender, self.air.ourChannel, [0, 0, '', cleanMessage, modifications, 0]) self.air.send(dg) self.air.csm.accountDB.persistChat(sender, message, self.air.ourChannel)
class ChatAgentUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory("ChatAgentUD") def announceGenerate(self): DistributedObjectGlobalUD.announceGenerate(self) self.whiteList = TTWhiteList() self.muted = {} def muteAccount(self, account, howLong): print ['muteAccount', account, howLong] self.muted[account] = int(time.time()/60) + howLong def unmuteAccount(self, account): print ['unuteAccount', account] if account in self.muted: del self.muted[account] def chatMessage(self, message): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent('suspicious', self.air.getAccountIdFromSender(), 'Account sent chat without an avatar', message) return if sender in self.muted and int(time.time()/60) < self.muted[sender]: return modifications = [] words = message.split(' ') offset = 0 WantWhitelist = config.GetBool('want-whitelist', 1) for word in words: if word and not self.whiteList.isWord(word) and WantWhitelist: modifications.append((offset, offset+len(word)-1)) offset += len(word) + 1 cleanMessage = message for modStart, modStop in modifications: cleanMessage = cleanMessage[:modStart] + '*'*(modStop-modStart+1) + cleanMessage[modStop+1:] self.air.writeServerEvent('chat-said', sender, message, cleanMessage) # TODO: The above is probably a little too ugly for my taste... Maybe AIR # should be given an API for sending updates for unknown objects? DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD'] dg = DistributedAvatar.aiFormatUpdate('setTalk', sender, sender, self.air.ourChannel, [0, 0, '', cleanMessage, modifications, 0]) self.air.send(dg) self.air.csm.accountDB.persistChat(sender, message, self.air.ourChannel)
class ChatAgentUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory("ChatAgentUD") def __init__(self, air): DistributedObjectGlobalUD.__init__(self, air) def announceGenerate(self): DistributedObjectGlobalUD.announceGenerate(self) self.whiteList = TTWhiteList() self.chatMode2prefix = {1: "[MOD] ", 2: "[ADMIN] ", 3: "[SYSADMIN] "} def chatMessage(self, message, chatMode): sender = self.air.getAvatarIdFromSender() if not sender: self.air.writeServerEvent('suspicious', self.air.getAccountIdFromSender(), 'Account sent chat without an avatar', message) return cleanMessage, modifications = message, [] modifications = [] words = message.split('\x20') offset = 0 WantWhitelist = config.GetBool('want-whitelist', 1) for word in words: if word and not self.whiteList.isWord(word) and WantWhitelist: modifications.append((offset, offset + len(word) - 1)) offset += len(word) + 1 self.air.writeServerEvent('chat-said', avId=sender, chatMode=chatMode, msg=message, cleanMsg=cleanMessage) if chatMode != 0: if message.startswith('.'): cleanMessage = '.' + self.chatMode2prefix.get(chatMode, "") + message[1:] else: cleanMessage = self.chatMode2prefix.get(chatMode, "") + message modifications = [] # send chat message update to ai self.sendUpdate('chatMessageResponse', [sender, cleanMessage, modifications, chatMode])
class ChatAgentUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory("ChatAgentUD") def announceGenerate(self): DistributedObjectGlobalUD.announceGenerate(self) self.whiteList = TTWhiteList() def chatMessage(self, message): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent('suspicious', self.air.getAccountIdFromSender(), 'Account sent chat without an avatar', message) return modifications = [] words = message.split(' ') offset = 0 WantWhitelist = config.GetBool('want-whitelist', 1) for word in words: if word and not self.whiteList.isWord(word) and WantWhitelist: modifications.append((offset, offset + len(word) - 1)) offset += len(word) + 1 cleanMessage = message for modStart, modStop in modifications: cleanMessage = cleanMessage[:modStart] + '*' * ( modStop - modStart + 1) + cleanMessage[modStop + 1:] self.air.writeServerEvent('chat-said', sender, message, cleanMessage) dclass = self.air.dclassesByName['DistributedAvatarUD'] dg = dclass.aiFormatUpdate( 'setTalk', sender, sender, self.air.ourChannel, [ 0, 0, '', cleanMessage, modifications, 0, globalClockDelta.getRealNetworkTime(bits=32) ]) self.air.send(dg)
class ChatAgentUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory("ChatAgentUD") def announceGenerate(self): DistributedObjectGlobalUD.announceGenerate(self) self.whiteList = TTWhiteList() def chatMessage(self, message): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent('suspicious', self.air.getAccountIdFromSender(), 'Account sent chat without an avatar', message) return modifications = [] words = message.split(' ') offset = 0 WantWhitelist = False for word in words: if word and not self.whiteList.isWord(word) and WantWhitelist: modifications.append((offset, offset + len(word) - 1)) offset += len(word) + 1 cleanMessage = message for modStart, modStop in modifications: cleanMessage = cleanMessage[:modStart] + '*' * ( modStop - modStart + 1) + cleanMessage[modStop + 1:] self.air.writeServerEvent('chat-said', sender, message, cleanMessage) # TODO: The above is probably a little too ugly for my taste... Maybe AIR # should be given an API for sending updates for unknown objects? DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD'] dg = DistributedAvatar.aiFormatUpdate( 'setTalk', sender, sender, self.air.ourChannel, [0, 0, '', cleanMessage, modifications, 0]) self.air.send(dg)
class ChatAgentUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory("ChatAgentUD") WantWhitelist = config.GetBool('want-whitelist', True) def announceGenerate(self): DistributedObjectGlobalUD.announceGenerate(self) self.whiteList = TTWhiteList() def chatMessage(self, message): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent('suspicious', self.air.getAccountIdFromSender(), 'Account sent chat without an avatar', message) return modifications = [] words = message.split(' ') offset = 0 wantWhitelist = self.WantWhitelist and self.air.friendsManager.getToonAccess(sender) < 400 for word in words: if word and not self.whiteList.isWord(word) and wantWhitelist: modifications.append((offset, offset+len(word)-1)) offset += len(word) + 1 cleanMessage = message for modStart, modStop in modifications: cleanMessage = cleanMessage[:modStart] + '*'*(modStop-modStart+1) + cleanMessage[modStop+1:] self.air.writeServerEvent('chat-said', sender, message, cleanMessage) # TODO: The above is probably a little too ugly for my taste... Maybe AIR # should be given an API for sending updates for unknown objects? DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD'] dg = DistributedAvatar.aiFormatUpdate('setTalk', sender, sender, self.air.ourChannel, [0, 0, '', cleanMessage, modifications, 0]) self.air.send(dg)
class TalkAssistant(DirectObject.DirectObject): notify = DirectNotifyGlobal.directNotify.newCategory('TalkAssistant') def __init__(self): self.logWhispers = 1 self.whiteList = None self.clearHistory() self.zeroTimeDay = time.time() self.zeroTimeGame = globalClock.getRealTime() self.floodThreshold = 10.0 self.useWhiteListFilter = base.config.GetBool( 'white-list-filter-openchat', 0) self.lastWhisperDoId = None self.lastWhisperPlayerId = None self.lastWhisper = None self.SCDecoder = SCDecoders self.whiteList = TTWhiteList() return def clearHistory(self): self.historyComplete = [] self.historyOpen = [] self.historyUpdates = [] self.historyGuild = [] self.historyByDoId = {} self.historyByDISLId = {} self.floodDataByDoId = {} self.spamDictByDoId = {} self.labelGuild = OTPLocalizer.TalkGuild self.handleDict = {} self.messageCount = 0 self.shownWhiteListWarning = 0 def delete(self): self.ignoreAll() self.clearHistory() def start(self): pass def stop(self): pass def countMessage(self): self.messageCount += 1 return self.messageCount - 1 def getOpenText(self, numLines, startPoint=0): return self.historyOpen[startPoint:startPoint + numLines] def getSizeOpenText(self): return len(self.historyOpen) def getCompleteText(self, numLines, startPoint=0): return self.historyComplete[startPoint:startPoint + numLines] def getCompleteTextFromRecent(self, numLines, startPoint=0): start = len(self.historyComplete) - startPoint if start < 0: start = 0 backStart = max(start - numLines, 0) text = self.historyComplete[backStart:start] text.reverse() return text def getAllCompleteText(self): return self.historyComplete def getAllHistory(self): return self.historyComplete def getSizeCompleteText(self): return len(self.historyComplete) def getHandle(self, doId): return self.handleDict.get(doId) def doWhiteListWarning(self): pass def addToHistoryDoId(self, message, doId, scrubbed=0): if message.getTalkType() == TALK_WHISPER and doId != localAvatar.doId: self.lastWhisperDoId = doId self.lastWhisper = self.lastWhisperDoId if doId not in self.historyByDoId: self.historyByDoId[doId] = [] self.historyByDoId[doId].append(message) if not self.shownWhiteListWarning and scrubbed and doId == localAvatar.doId: self.doWhiteListWarning() self.shownWhiteListWarning = 1 if doId not in self.floodDataByDoId: self.floodDataByDoId[doId] = [0.0, self.stampTime(), message] else: oldTime = self.floodDataByDoId[doId][1] newTime = self.stampTime() timeDiff = newTime - oldTime oldRating = self.floodDataByDoId[doId][0] contentMult = 1.0 if len(message.getBody()) < 6: contentMult += 0.2 * float(6 - len(message.getBody())) if self.floodDataByDoId[doId][2].getBody() == message.getBody(): contentMult += 1.0 floodRating = max(0, 3.0 * contentMult + oldRating - timeDiff) self.floodDataByDoId[doId] = [ floodRating, self.stampTime(), message ] if floodRating > self.floodThreshold: if oldRating < self.floodThreshold: self.floodDataByDoId[doId] = [ floodRating + 3.0, self.stampTime(), message ] return 1 else: self.floodDataByDoId[doId] = [ oldRating - timeDiff, self.stampTime(), message ] return 2 return 0 def addToHistoryDISLId(self, message, dISLId, scrubbed=0): if message.getTalkType() == TALK_ACCOUNT: self.lastWhisperPlayerId = dISLId self.lastWhisper = self.lastWhisperPlayerId if dISLId not in self.historyByDISLId: self.historyByDISLId[dISLId] = [] self.historyByDISLId[dISLId].append(message) def addHandle(self, doId, message): if doId == localAvatar.doId: return handle = self.handleDict.get(doId) if not handle: handle = TalkHandle(doId, message) self.handleDict[doId] = handle else: handle.addMessageInfo(message) def stampTime(self): return globalClock.getRealTime() - self.zeroTimeGame def findName(self, id, isPlayer=0): if isPlayer: return self.findPlayerName(id) else: return self.findAvatarName(id) def findAvatarName(self, id): info = base.cr.identifyAvatar(id) if info: return info.getName() else: return '' def findPlayerName(self, id): info = base.cr.playerFriendsManager.getFriendInfo(id) if info: return info.playerName else: return '' def whiteListFilterMessage(self, text): if not self.useWhiteListFilter: return text elif not base.whiteList: return 'no list' words = text.split(' ') newwords = [] for word in words: if word == '' or base.whiteList.isWord(word): newwords.append(word) else: newwords.append(base.whiteList.defaultWord) newText = ' '.join(newwords) return newText def colorMessageByWhiteListFilter(self, text): if not base.whiteList: return text words = text.split(' ') newwords = [] for word in words: if word == '' or base.whiteList.isWord(word): newwords.append(word) else: newwords.append('\x01WLRed\x01' + word + '\x02') newText = ' '.join(newwords) return newText def isThought(self, message): if not message: return 0 elif len(message) == 0: return 0 elif message.find(ThoughtPrefix, 0, len(ThoughtPrefix)) >= 0: return 1 else: return 0 def removeThoughtPrefix(self, message): if self.isThought(message): return message[len(ThoughtPrefix):] else: return message def fillWithTestText(self): hold = self.floodThreshold self.floodThreshold = 1000.0 self.receiveOpenTalk(1001, 'Bob the Ghost', None, None, 'Hello from the machine') self.receiveOpenTalk(1001, 'Bob the Ghost', None, None, 'More text for ya!') self.receiveOpenTalk(1001, 'Bob the Ghost', None, None, 'Hope this makes life easier') self.receiveOpenTalk( 1002, 'Doug the Spirit', None, None, 'Now we need some longer text that will spill over onto two lines') self.receiveOpenTalk(1002, 'Doug the Spirit', None, None, 'Maybe I will tell you') self.receiveOpenTalk( 1001, 'Bob the Ghost', None, None, 'If you are seeing this text it is because you are cool') self.receiveOpenTalk( 1002, 'Doug the Spirit', None, None, "That's right, there is no need to call tech support") self.receiveOpenTalk( localAvatar.doId, localAvatar.getName, None, None, "Okay I won't call tech support, because I am cool") self.receiveGMTalk(1003, 'God of Text', None, None, 'Good because I have seen it already') self.floodThreshold = hold return def printHistoryComplete(self): print 'HISTORY COMPLETE' for message in self.historyComplete: print '%s %s %s\n%s\n' % ( message.getTimeStamp(), message.getSenderAvatarName(), message.getSenderAccountName(), message.getBody()) def checkOpenTypedChat(self): if base.localAvatar.commonChatFlags & OTPGlobals.CommonChat: return True return False def checkAnyTypedChat(self): if base.localAvatar.commonChatFlags & OTPGlobals.CommonChat: return True if base.localAvatar.canChat(): return True return False def checkOpenSpeedChat(self): return True def checkWhisperTypedChatAvatar(self, avatarId): remoteAvatar = base.cr.doId2do.get(avatarId) if remoteAvatar: if remoteAvatar.isUnderstandable(): return True if base.localAvatar.commonChatFlags & OTPGlobals.SuperChat: return True remoteAvatarOrHandleOrInfo = base.cr.identifyAvatar(avatarId) if remoteAvatarOrHandleOrInfo and hasattr(remoteAvatarOrHandleOrInfo, 'isUnderstandable'): if remoteAvatarOrHandleOrInfo.isUnderstandable(): return True info = base.cr.playerFriendsManager.findPlayerInfoFromAvId(avatarId) if info: if info.understandableYesNo: return True info = base.cr.avatarFriendsManager.getFriendInfo(avatarId) if info: if info.understandableYesNo: return True if base.cr.getFriendFlags(avatarId) & OTPGlobals.FriendChat: return True return False def checkWhisperSpeedChatAvatar(self, avatarId): return True def checkWhisperTypedChatPlayer(self, playerId): info = base.cr.playerFriendsManager.getFriendInfo(playerId) if info: if info.understandableYesNo: return True return False def checkWhisperSpeedChatPlayer(self, playerId): if base.cr.playerFriendsManager.isPlayerFriend(playerId): return True return False def checkOpenSpeedChat(self): return True def checkWhisperSpeedChatAvatar(self, avatarId): return True def checkWhisperSpeedChatPlayer(self, playerId): if base.cr.playerFriendsManager.isPlayerFriend(playerId): return True return False def checkGuildTypedChat(self): if localAvatar.guildId: return True return False def checkGuildSpeedChat(self): if localAvatar.guildId: return True return False def receiveOpenTalk(self, senderAvId, avatarName, accountId, accountName, message, scrubbed=0): error = None if not avatarName and senderAvId: localAvatar.sendUpdate( 'logSuspiciousEvent', ['receiveOpenTalk: invalid avatar name (%s)' % senderAvId]) avatarName = self.findAvatarName(senderAvId) if not accountName and accountId: accountName = self.findPlayerName(accountId) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, senderAvId, avatarName, accountId, accountName, None, None, None, None, TALK_OPEN, None) if senderAvId != localAvatar.doId: self.addHandle(senderAvId, newMessage) reject = 0 if senderAvId: reject = self.addToHistoryDoId(newMessage, senderAvId, scrubbed) if accountId: self.addToHistoryDISLId(newMessage, accountId) if reject == 1: newMessage.setBody(OTPLocalizer.AntiSpamInChat) if reject != 2: isSpam = self.spamDictByDoId.get(senderAvId) and reject if not isSpam: self.historyComplete.append(newMessage) self.historyOpen.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) if newMessage.getBody() == OTPLocalizer.AntiSpamInChat: self.spamDictByDoId[senderAvId] = 1 else: self.spamDictByDoId[senderAvId] = 0 return error def receiveWhisperTalk(self, avatarId, avatarName, accountId, accountName, toId, toName, message, scrubbed=0): error = None if not avatarName and avatarId: avatarName = self.findAvatarName(avatarId) if not accountName and accountId: accountName = self.findPlayerName(accountId) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, avatarId, avatarName, accountId, accountName, toId, toName, None, None, TALK_WHISPER, None) if avatarId == localAvatar.doId: self.addHandle(toId, newMessage) else: self.addHandle(avatarId, newMessage) self.historyComplete.append(newMessage) if avatarId: self.addToHistoryDoId(newMessage, avatarId, scrubbed) if accountId: self.addToHistoryDISLId(newMessage, accountId) messenger.send('NewOpenMessage', [newMessage]) return error def receiveAccountTalk(self, avatarId, avatarName, accountId, accountName, toId, toName, message, scrubbed=0): if not accountName and base.cr.playerFriendsManager.playerId2Info.get( accountId): accountName = base.cr.playerFriendsManager.playerId2Info.get( accountId).playerName error = None if not avatarName and avatarId: avatarName = self.findAvatarName(avatarId) if not accountName and accountId: accountName = self.findPlayerName(accountId) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, avatarId, avatarName, accountId, accountName, None, None, toId, toName, TALK_ACCOUNT, None) self.historyComplete.append(newMessage) if avatarId: self.addToHistoryDoId(newMessage, avatarId, scrubbed) if accountId: self.addToHistoryDISLId(newMessage, accountId, scrubbed) messenger.send('NewOpenMessage', [newMessage]) return error def receiveGuildTalk(self, senderAvId, fromAC, avatarName, message, scrubbed=0): error = None if not self.isThought(message): accountName = self.findName(fromAC, 1) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, senderAvId, avatarName, fromAC, accountName, None, None, None, None, TALK_GUILD, None) reject = self.addToHistoryDoId(newMessage, senderAvId) if reject == 1: newMessage.setBody(OTPLocalizer.AntiSpamInChat) if reject != 2: isSpam = self.spamDictByDoId.get(senderAvId) and reject if not isSpam: self.historyComplete.append(newMessage) self.historyGuild.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) if newMessage.getBody() == OTPLocalizer.AntiSpamInChat: self.spamDictByDoId[senderAvId] = 1 else: self.spamDictByDoId[senderAvId] = 0 return error def receiveGMTalk(self, avatarId, avatarName, accountId, accountName, message, scrubbed=0): error = None if not avatarName and avatarId: avatarName = self.findAvatarName(avatarId) if not accountName and accountId: accountName = self.findPlayerName(accountId) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, avatarId, avatarName, accountId, accountName, None, None, None, None, TALK_GM, None) self.historyComplete.append(newMessage) self.historyOpen.append(newMessage) if avatarId: self.addToHistoryDoId(newMessage, avatarId) if accountId: self.addToHistoryDISLId(newMessage, accountId) messenger.send('NewOpenMessage', [newMessage]) return error def receiveThought(self, avatarId, avatarName, accountId, accountName, message, scrubbed=0): error = None if not avatarName and avatarId: avatarName = self.findAvatarName(avatarId) if not accountName and accountId: accountName = self.findPlayerName(accountId) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, avatarId, avatarName, accountId, accountName, None, None, None, None, AVATAR_THOUGHT, None) if avatarId != localAvatar.doId: self.addHandle(avatarId, newMessage) reject = 0 if avatarId: reject = self.addToHistoryDoId(newMessage, avatarId, scrubbed) if accountId: self.addToHistoryDISLId(newMessage, accountId) if reject == 1: newMessage.setBody(OTPLocalizer.AntiSpamInChat) if reject != 2: self.historyComplete.append(newMessage) self.historyOpen.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return error def receiveGameMessage(self, message): error = None if not self.isThought(message): newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, None, None, None, None, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, INFO_GAME, None) self.historyComplete.append(newMessage) self.historyUpdates.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return error def receiveSystemMessage(self, message): error = None if not self.isThought(message): newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, None, None, None, None, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, INFO_SYSTEM, None) self.historyComplete.append(newMessage) self.historyUpdates.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return error def receiveDeveloperMessage(self, message): error = None newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, None, None, None, None, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, INFO_DEV, None) self.historyComplete.append(newMessage) self.historyUpdates.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return error def receiveGuildMessage(self, message, senderAvId, senderName): error = None if not self.isThought(message): newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, senderAvId, senderName, None, None, None, None, None, None, TALK_GUILD, None) self.historyComplete.append(newMessage) self.historyGuild.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return error def receiveGuildUpdateMessage(self, message, senderId, senderName, receiverId, receiverName, extraInfo=None): error = None if not self.isThought(message): newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, senderId, senderName, None, None, receiverId, receiverName, None, None, INFO_GUILD, extraInfo) self.historyComplete.append(newMessage) self.historyGuild.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return error def receiveFriendUpdate(self, friendId, friendName, isOnline): if isOnline: onlineMessage = OTPLocalizer.FriendOnline else: onlineMessage = OTPLocalizer.FriendOffline newMessage = TalkMessage(self.countMessage(), self.stampTime(), onlineMessage, friendId, friendName, None, None, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, UPDATE_FRIEND, None) self.addHandle(friendId, newMessage) self.historyComplete.append(newMessage) self.historyUpdates.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return def receiveFriendAccountUpdate(self, friendId, friendName, isOnline): if isOnline: onlineMessage = OTPLocalizer.FriendOnline else: onlineMessage = OTPLocalizer.FriendOffline newMessage = TalkMessage(self.countMessage(), self.stampTime(), onlineMessage, None, None, friendId, friendName, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, UPDATE_FRIEND, None) self.historyComplete.append(newMessage) self.historyUpdates.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return def receiveGuildUpdate(self, memberId, memberName, isOnline): if base.cr.identifyFriend(memberId) is None: if isOnline: onlineMessage = OTPLocalizer.GuildMemberOnline else: onlineMessage = OTPLocalizer.GuildMemberOffline newMessage = TalkMessage(self.countMessage(), self.stampTime(), onlineMessage, memberId, memberName, None, None, None, None, None, None, UPDATE_GUILD, None) self.addHandle(memberId, newMessage) self.historyComplete.append(newMessage) self.historyUpdates.append(newMessage) self.historyGuild.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return def receiveOpenSpeedChat(self, type, messageIndex, senderAvId, name=None): error = None if not name and senderAvId: name = self.findName(senderAvId, 0) if type == SPEEDCHAT_NORMAL: message = self.SCDecoder.decodeSCStaticTextMsg(messageIndex) elif type == SPEEDCHAT_EMOTE: message = self.SCDecoder.decodeSCEmoteWhisperMsg( messageIndex, name) elif type == SPEEDCHAT_CUSTOM: message = self.SCDecoder.decodeSCCustomMsg(messageIndex) if message in (None, ''): return newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, senderAvId, name, None, None, None, None, None, None, TALK_OPEN, None) self.historyComplete.append(newMessage) self.historyOpen.append(newMessage) self.addToHistoryDoId(newMessage, senderAvId) messenger.send('NewOpenMessage', [newMessage]) return error def receiveAvatarWhisperSpeedChat(self, type, messageIndex, senderAvId, name=None): error = None if not name and senderAvId: name = self.findName(senderAvId, 0) if type == SPEEDCHAT_NORMAL: message = self.SCDecoder.decodeSCStaticTextMsg(messageIndex) elif type == SPEEDCHAT_EMOTE: message = self.SCDecoder.decodeSCEmoteWhisperMsg( messageIndex, name) elif type == SPEEDCHAT_CUSTOM: message = self.SCDecoder.decodeSCCustomMsg(messageIndex) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, senderAvId, name, None, None, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, TALK_WHISPER, None) self.historyComplete.append(newMessage) self.historyOpen.append(newMessage) self.addToHistoryDoId(newMessage, senderAvId) messenger.send('NewOpenMessage', [newMessage]) return error def receivePlayerWhisperSpeedChat(self, type, messageIndex, senderAvId, name=None): error = None if not name and senderAvId: name = self.findName(senderAvId, 1) if type == SPEEDCHAT_NORMAL: message = self.SCDecoder.decodeSCStaticTextMsg(messageIndex) elif type == SPEEDCHAT_EMOTE: message = self.SCDecoder.decodeSCEmoteWhisperMsg( messageIndex, name) elif type == SPEEDCHAT_CUSTOM: message = self.SCDecoder.decodeSCCustomMsg(messageIndex) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, None, None, senderAvId, name, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, TALK_WHISPER, None) self.historyComplete.append(newMessage) self.historyOpen.append(newMessage) self.addToHistoryDISLId(newMessage, senderAvId) messenger.send('NewOpenMessage', [newMessage]) return error def sendOpenTalk(self, message): error = None doId = base.localAvatar.doId try: message.encode('ascii') except UnicodeEncodeError: return if base.config.GetBool('want-talkative-tyler', False): if base.localAvatar.zoneId == 2000: tyler = base.cr.doFind('Talkative Tyler') if tyler: tyler.sendUpdate('talkMessage', [doId, message]) if base.cr.wantMagicWords and len(message) > 0 and message[0] == '~': messenger.send('magicWord', [message]) self.receiveDeveloperMessage(message) else: chatFlags = CFSpeech | CFTimeout if self.isThought(message): chatFlags = CFThought base.cr.chatAgent.sendChatMessage(message) messenger.send('chatUpdate', [message, chatFlags]) return error def sendWhisperTalk(self, message, receiverAvId): modifications = [] words = message.split(' ') offset = 0 WantWhitelist = config.GetBool('want-whitelist', 1) for word in words: if word and not self.whiteList.isWord(word) and WantWhitelist: modifications.append((offset, offset + len(word) - 1)) offset += len(word) + 1 cleanMessage = message for modStart, modStop in modifications: cleanMessage = cleanMessage[:modStart] + '*' * ( modStop - modStart + 1) + cleanMessage[modStop + 1:] message, scrubbed = base.localAvatar.scrubTalk(cleanMessage, modifications) base.cr.ttiFriendsManager.sendUpdate('sendTalkWhisper', [receiverAvId, message]) def sendAccountTalk(self, message, receiverAccount): error = None base.cr.playerFriendsManager.sendUpdate( 'setTalkAccount', [receiverAccount, 0, '', message, [], 0]) return error def sendGuildTalk(self, message): error = None if self.checkGuildTypedChat(): base.cr.guildManager.sendTalk(message) else: print 'Guild chat error' error = ERROR_NO_GUILD_CHAT return error def sendOpenSpeedChat(self, type, messageIndex): error = None if type == SPEEDCHAT_NORMAL: messenger.send(SCChatEvent) messenger.send('chatUpdateSC', [messageIndex]) base.localAvatar.b_setSC(messageIndex) elif type == SPEEDCHAT_EMOTE: messenger.send('chatUpdateSCEmote', [messageIndex]) messenger.send(SCEmoteChatEvent) base.localAvatar.b_setSCEmote(messageIndex) elif type == SPEEDCHAT_CUSTOM: messenger.send('chatUpdateSCCustom', [messageIndex]) messenger.send(SCCustomChatEvent) base.localAvatar.b_setSCCustom(messageIndex) return error def sendAvatarWhisperSpeedChat(self, type, messageIndex, receiverId): error = None if type == SPEEDCHAT_NORMAL: base.localAvatar.whisperSCTo(messageIndex, receiverId, 0) message = self.SCDecoder.decodeSCStaticTextMsg(messageIndex) elif type == SPEEDCHAT_EMOTE: base.localAvatar.whisperSCEmoteTo(messageIndex, receiverId, 0) message = self.SCDecoder.decodeSCEmoteWhisperMsg( messageIndex, localAvatar.getName()) elif type == SPEEDCHAT_CUSTOM: base.localAvatar.whisperSCCustomTo(messageIndex, receiverId, 0) message = self.SCDecoder.decodeSCCustomMsg(messageIndex) if self.logWhispers: avatarName = None accountId = None avatar = base.cr.identifyAvatar(receiverId) if avatar: avatarName = avatar.getName() newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, receiverId, avatarName, None, None, TALK_WHISPER, None) self.historyComplete.append(newMessage) self.addToHistoryDoId(newMessage, localAvatar.doId) messenger.send('NewOpenMessage', [newMessage]) return error def sendPlayerWhisperSpeedChat(self, type, messageIndex, receiverId): error = None if type == SPEEDCHAT_NORMAL: base.cr.speedchatRelay.sendSpeedchat(receiverId, messageIndex) message = self.SCDecoder.decodeSCStaticTextMsg(messageIndex) elif type == SPEEDCHAT_EMOTE: base.cr.speedchatRelay.sendSpeedchatEmote(receiverId, messageIndex) message = self.SCDecoder.decodeSCEmoteWhisperMsg( messageIndex, localAvatar.getName()) return elif type == SPEEDCHAT_CUSTOM: base.cr.speedchatRelay.sendSpeedchatCustom(receiverId, messageIndex) message = self.SCDecoder.decodeSCCustomMsg(messageIndex) if self.logWhispers: receiverName = self.findName(receiverId, 1) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, None, None, receiverId, receiverName, TALK_ACCOUNT, None) self.historyComplete.append(newMessage) self.addToHistoryDoId(newMessage, localAvatar.doId) messenger.send('NewOpenMessage', [newMessage]) return error def sendGuildSpeedChat(self, type, msgIndex): error = None if self.checkGuildSpeedChat(): base.cr.guildManager.sendSC(msgIndex) else: print 'Guild Speedchat error' error = ERROR_NO_GUILD_CHAT return error def getWhisperReplyId(self): if self.lastWhisper: toPlayer = 0 if self.lastWhisper == self.lastWhisperPlayerId: toPlayer = 1 return (self.lastWhisper, toPlayer) return (0, 0)
class TTChatInputWhiteList(ChatInputWhiteListFrame): notify = DirectNotifyGlobal.directNotify.newCategory('TTChatInputWhiteList') TFToggleKey = base.config.GetString('true-friend-toggle-key', 'alt') TFToggleKeyUp = TFToggleKey + '-up' def __init__(self, parent = None, **kw): entryOptions = {'parent': self, 'relief': DGG.SUNKEN, 'scale': 0.05, 'frameColor': (0.9, 0.9, 0.85, 0.0), 'pos': (-0.2, 0, 0.11), 'entryFont': OTPGlobals.getInterfaceFont(), 'width': 8.6, 'numLines': 3, 'cursorKeys': 0, 'backgroundFocus': 0, 'suppressKeys': 0, 'suppressMouse': 1, 'command': self.sendChat, 'failedCommand': self.sendFailed, 'focus': 0, 'text': '', 'sortOrder': DGG.FOREGROUND_SORT_INDEX} ChatInputWhiteListFrame.__init__(self, entryOptions, parent, **kw) self.whiteList = TTWhiteList() base.whiteList = self.whiteList base.ttwl = self self.autoOff = 1 self.sendBy = 'Data' self.prefilter = 0 self.promoteWhiteList = 1 self.typeGrabbed = 0 self.deactivate() gui = loader.loadModel('phase_3.5/models/gui/chat_input_gui') self.chatFrame = DirectFrame(parent=self, image=gui.find('**/Chat_Bx_FNL'), relief=None, pos=(0.0, 0, 0.0), state=DGG.NORMAL) self.chatButton = DirectButton(parent=self.chatFrame, image=(gui.find('**/ChtBx_ChtBtn_UP'), gui.find('**/ChtBx_ChtBtn_DN'), gui.find('**/ChtBx_ChtBtn_RLVR')), pos=(0.182, 0, -0.088), relief=None, text=('', OTPLocalizer.ChatInputNormalSayIt, OTPLocalizer.ChatInputNormalSayIt), text_scale=0.06, text_fg=Vec4(1, 1, 1, 1), text_shadow=Vec4(0, 0, 0, 1), text_pos=(0, -0.09), textMayChange=0, command=self.chatButtonPressed) self.cancelButton = DirectButton(parent=self.chatFrame, image=(gui.find('**/CloseBtn_UP'), gui.find('**/CloseBtn_DN'), gui.find('**/CloseBtn_Rllvr')), pos=(-0.151, 0, -0.088), relief=None, text=('', OTPLocalizer.ChatInputNormalCancel, OTPLocalizer.ChatInputNormalCancel), text_scale=0.06, text_fg=Vec4(1, 1, 1, 1), text_shadow=Vec4(0, 0, 0, 1), text_pos=(0, -0.09), textMayChange=0, command=self.cancelButtonPressed) self.whisperLabel = DirectLabel(parent=self.chatFrame, pos=(0.02, 0, 0.23), relief=DGG.FLAT, frameColor=(1, 1, 0.5, 1), frameSize=(-0.23, 0.23, -0.07, 0.05), text=OTPLocalizer.ChatInputNormalWhisper, text_scale=0.04, text_fg=Vec4(0, 0, 0, 1), text_wordwrap=9.5, textMayChange=1) self.chatEntry.bind(DGG.OVERFLOW, self.chatOverflow) self.chatEntry.bind(DGG.TYPE, self.typeCallback) self.trueFriendChat = 0 if base.config.GetBool('whisper-to-nearby-true-friends', 1): self.accept(self.TFToggleKey, self.shiftPressed) return def shiftPressed(self): self.ignore(self.TFToggleKey) self.trueFriendChat = 1 self.accept(self.TFToggleKeyUp, self.shiftReleased) def shiftReleased(self): self.ignore(self.TFToggleKeyUp) self.trueFriendChat = 0 self.accept(self.TFToggleKey, self.shiftPressed) def handleTypeGrab(self): self.ignore('typeEntryGrab') self.accept('typeEntryRelease', self.handleTypeRelease) self.typeGrabbed = 1 def handleTypeRelease(self): self.ignore('typeEntryRelease') self.accept('typeEntryGrab', self.handleTypeGrab) self.typeGrabbed = 0 def typeCallback(self, extraArgs): try: if self.typeGrabbed: return self.applyFilter(extraArgs) if localAvatar.chatMgr.chatInputWhiteList.isActive(): return else: messenger.send('wakeup') messenger.send('enterNormalChat') except UnicodeDecodeError: return def destroy(self): self.chatEntry.destroy() self.chatFrame.destroy() self.ignoreAll() ChatInputWhiteListFrame.destroy(self) def delete(self): base.whiteList = None ChatInputWhiteListFrame.delete(self) return def sendChat(self, text, overflow = False): if self.typeGrabbed: return else: ChatInputWhiteListFrame.sendChat(self, self.chatEntry.get()) def sendChatByData(self, text): if self.trueFriendChat: for friendId, flags in base.localAvatar.friendsList: if flags & ToontownGlobals.FriendChat: self.sendWhisperByFriend(friendId, text) elif not self.receiverId: base.talkAssistant.sendOpenTalk(text) elif self.receiverId and not self.toPlayer: base.talkAssistant.sendWhisperTalk(text, self.receiverId) elif self.receiverId and self.toPlayer: base.talkAssistant.sendAccountTalk(text, self.receiverId) def sendWhisperByFriend(self, avatarId, text): online = 0 if avatarId in base.cr.doId2do: online = 1 avatarUnderstandable = 0 av = None if avatarId: av = base.cr.identifyAvatar(avatarId) if av != None: avatarUnderstandable = av.isUnderstandable() if avatarUnderstandable and online: base.talkAssistant.sendWhisperTalk(text, avatarId) return def chatButtonPressed(self): if self.okayToSubmit: self.sendChat(self.chatEntry.get()) else: self.sendFailed(self.chatEntry.get()) def cancelButtonPressed(self): self.requestMode('Off') localAvatar.chatMgr.fsm.request('mainMenu') def enterAllChat(self): ChatInputWhiteListFrame.enterAllChat(self) self.whisperLabel.hide() def exitAllChat(self): ChatInputWhiteListFrame.exitAllChat(self) def enterPlayerWhisper(self): ChatInputWhiteListFrame.enterPlayerWhisper(self) self.labelWhisper() def exitPlayerWhisper(self): ChatInputWhiteListFrame.exitPlayerWhisper(self) self.whisperLabel.hide() def enterAvatarWhisper(self): ChatInputWhiteListFrame.enterAvatarWhisper(self) self.labelWhisper() def exitAvatarWhisper(self): ChatInputWhiteListFrame.exitAvatarWhisper(self) self.whisperLabel.hide() def labelWhisper(self): if self.receiverId: self.whisperName = base.talkAssistant.findName(self.receiverId, self.toPlayer) self.whisperLabel['text'] = OTPLocalizer.ChatInputWhisperLabel % self.whisperName self.whisperLabel.show() else: self.whisperLabel.hide() def applyFilter(self, keyArgs, strict = False): text = self.chatEntry.get(plain=True) if text.startswith('~'): self.okayToSubmit = True else: words = text.split(' ') newwords = [] self.okayToSubmit = True flag = 0 for friendId, flags in base.localAvatar.friendsList: if flags & ToontownGlobals.FriendChat: flag = 1 for word in words: if word == '' or self.whiteList.isWord(word) or not base.cr.whiteListChatEnabled: newwords.append(word) else: if self.checkBeforeSend: self.okayToSubmit = False else: self.okayToSubmit = True if flag: newwords.append('\x01WLDisplay\x01' + word + '\x02') else: newwords.append('\x01WLEnter\x01' + word + '\x02') if not strict: lastword = words[-1] try: if lastword == '' or self.whiteList.isPrefix(lastword) or not base.cr.whiteListChatEnabled: newwords[-1] = lastword elif flag: newwords[-1] = '\x01WLDisplay\x01' + lastword + '\x02' else: newwords[-1] = '\x01WLEnter\x01' + lastword + '\x02' except UnicodeDecodeError: self.okayToSubmit = False newtext = ' '.join(newwords) self.chatEntry.set(newtext) self.chatEntry.guiItem.setAcceptEnabled(self.okayToSubmit)
class ChatAgentUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory("ChatAgentUD") def __init__(self, air): DistributedObjectGlobalUD.__init__(self, air) def announceGenerate(self): DistributedObjectGlobalUD.announceGenerate(self) self.whiteList = TTWhiteList() self.toonAccess = 100 self.offenses = {} self.chatMode2prefix = { 1: "[MOD] ", 2: "[ADMIN] ", 3: "[SYSADMIN] " } self.accept('setAvatarOffenses', self.updateAvatarOffenses) self.accept('requestToonAccessResponse', self.requestToonAccessResponse) def chatMessageAiToUd(self, sender, message, chatMode): if self.detectBadWords(sender, message): self.notify.info("Detected Bad Word or Blacklisted Pharse from %d" % (sender)) return cleanMessage, modifications = message, [] modifications = [] words = message.split('\x20') offset = 0 WantWhitelist = config.GetBool('want-whitelist', 1) for word in words: if word and not self.whiteList.isWord(word) and WantWhitelist: modifications.append((offset, offset+len(word)-1)) offset += len(word) + 1 self.air.writeServerEvent('chat-said', avId=sender, chatMode=chatMode, msg=message, cleanMsg=cleanMessage) if chatMode != 0: if message.startswith('.'): cleanMessage = '.' + self.chatMode2prefix.get(chatMode, "") + message[1:] else: cleanMessage = self.chatMode2prefix.get(chatMode, "") + message modifications = [] # send chat message update to ai self.sendUpdate('chatMessageResponse', [sender, cleanMessage, modifications, chatMode]) def requestToonAccessResponse(self, access): self.toonAccess = access def updateAvatarOffenses(self, sender, count): avId = sender & 0xFFFFFFFF if not sender in self.offenses: self.offenses[sender] = 0 self.offenses[sender] = count if self.offenses[sender] >= 3: # Ban the offender self.air.sendNetEvent('warningUpdate', [avId, 0, True]) msg = 'banned' self.air.sendNetEvent('banAvatar', [avId, 'Chat Abuse', 24]) def detectBadWords(self, sender, message): if message.lower() in BLACKLIST: avId = sender if not sender in self.offenses: self.offenses[sender] = 0 self.air.sendNetEvent('requestToonAccess', [avId]) if self.toonAccess < 300: self.offenses[sender] += 1 self.air.sendNetEvent('warningUpdate', [avId, int(self.offenses[sender]), True]) if self.offenses[sender] >= 3: # Ban the offender msg = 'banned' self.air.sendNetEvent('chatBan', [avId, 'Chat Abuse', 24]) else: msg = OFFENSE_MSGS[self.offenses[sender]] self.air.sendNetEvent('sendSystemMessage', [msg, sender]) if self.offenses[sender] >= 3: del self.offenses[sender] return 1 words = message.split('\x20') for word in words: if word.lower() in BLACKLIST: avId = sender if not sender in self.offenses: self.offenses[sender] = 0 self.air.sendNetEvent('requestToonAccess', [avId]) if self.toonAccess < 300: self.offenses[sender] += 1 self.air.sendNetEvent('warningUpdate', [avId, int(self.offenses[sender]), True]) if self.offenses[sender] >= 3: # Ban the offender msg = 'banned' self.air.sendNetEvent('chatBan', [avId, 'Chat Abuse', 24]) else: msg = OFFENSE_MSGS[self.offenses[sender]] self.air.sendNetEvent('sendSystemMessage', [msg, sender]) if self.offenses[sender] >= 3: del self.offenses[sender] return 1 return 0
class TalkAssistant(DirectObject.DirectObject): notify = DirectNotifyGlobal.directNotify.newCategory('TalkAssistant') def __init__(self): self.logWhispers = 1 self.whiteList = None self.clearHistory() self.zeroTimeDay = time.time() self.zeroTimeGame = globalClock.getRealTime() self.floodThreshold = 10.0 self.useWhiteListFilter = base.config.GetBool('white-list-filter-openchat', 0) self.lastWhisperDoId = None self.lastWhisperPlayerId = None self.lastWhisper = None self.SCDecoder = SCDecoders self.whiteList = TTWhiteList() return def clearHistory(self): self.historyComplete = [] self.historyOpen = [] self.historyUpdates = [] self.historyGuild = [] self.historyByDoId = {} self.historyByDISLId = {} self.floodDataByDoId = {} self.spamDictByDoId = {} self.labelGuild = OTPLocalizer.TalkGuild self.handleDict = {} self.messageCount = 0 self.shownWhiteListWarning = 0 def delete(self): self.ignoreAll() self.clearHistory() def start(self): pass def stop(self): pass def countMessage(self): self.messageCount += 1 return self.messageCount - 1 def getOpenText(self, numLines, startPoint = 0): return self.historyOpen[startPoint:startPoint + numLines] def getSizeOpenText(self): return len(self.historyOpen) def getCompleteText(self, numLines, startPoint = 0): return self.historyComplete[startPoint:startPoint + numLines] def getCompleteTextFromRecent(self, numLines, startPoint = 0): start = len(self.historyComplete) - startPoint if start < 0: start = 0 backStart = max(start - numLines, 0) text = self.historyComplete[backStart:start] text.reverse() return text def getAllCompleteText(self): return self.historyComplete def getAllHistory(self): return self.historyComplete def getSizeCompleteText(self): return len(self.historyComplete) def getHandle(self, doId): return self.handleDict.get(doId) def doWhiteListWarning(self): pass def addToHistoryDoId(self, message, doId, scrubbed = 0): if message.getTalkType() == TALK_WHISPER and doId != localAvatar.doId: self.lastWhisperDoId = doId self.lastWhisper = self.lastWhisperDoId if doId not in self.historyByDoId: self.historyByDoId[doId] = [] self.historyByDoId[doId].append(message) if not self.shownWhiteListWarning and scrubbed and doId == localAvatar.doId: self.doWhiteListWarning() self.shownWhiteListWarning = 1 if doId not in self.floodDataByDoId: self.floodDataByDoId[doId] = [0.0, self.stampTime(), message] else: oldTime = self.floodDataByDoId[doId][1] newTime = self.stampTime() timeDiff = newTime - oldTime oldRating = self.floodDataByDoId[doId][0] contentMult = 1.0 if len(message.getBody()) < 6: contentMult += 0.2 * float(6 - len(message.getBody())) if self.floodDataByDoId[doId][2].getBody() == message.getBody(): contentMult += 1.0 floodRating = max(0, 3.0 * contentMult + oldRating - timeDiff) self.floodDataByDoId[doId] = [floodRating, self.stampTime(), message] if floodRating > self.floodThreshold: if oldRating < self.floodThreshold: self.floodDataByDoId[doId] = [floodRating + 3.0, self.stampTime(), message] return 1 else: self.floodDataByDoId[doId] = [oldRating - timeDiff, self.stampTime(), message] return 2 return 0 def addToHistoryDISLId(self, message, dISLId, scrubbed = 0): if message.getTalkType() == TALK_ACCOUNT: self.lastWhisperPlayerId = dISLId self.lastWhisper = self.lastWhisperPlayerId if dISLId not in self.historyByDISLId: self.historyByDISLId[dISLId] = [] self.historyByDISLId[dISLId].append(message) def addHandle(self, doId, message): if doId == localAvatar.doId: return handle = self.handleDict.get(doId) if not handle: handle = TalkHandle(doId, message) self.handleDict[doId] = handle else: handle.addMessageInfo(message) def stampTime(self): return globalClock.getRealTime() - self.zeroTimeGame def findName(self, id, isPlayer = 0): if isPlayer: return self.findPlayerName(id) else: return self.findAvatarName(id) def findAvatarName(self, id): info = base.cr.identifyAvatar(id) if info: return info.getName() else: return '' def findPlayerName(self, id): info = base.cr.playerFriendsManager.getFriendInfo(id) if info: return info.playerName else: return '' def whiteListFilterMessage(self, text): if not self.useWhiteListFilter: return text elif not base.whiteList: return 'no list' words = text.split(' ') newwords = [] for word in words: if word == '' or base.whiteList.isWord(word): newwords.append(word) else: newwords.append(base.whiteList.defaultWord) newText = ' '.join(newwords) return newText def colorMessageByWhiteListFilter(self, text): if not base.whiteList: return text words = text.split(' ') newwords = [] for word in words: if word == '' or base.whiteList.isWord(word): newwords.append(word) else: newwords.append('\x01WLRed\x01' + word + '\x02') newText = ' '.join(newwords) return newText def isThought(self, message): if not message: return 0 elif len(message) == 0: return 0 elif message.find(ThoughtPrefix, 0, len(ThoughtPrefix)) >= 0: return 1 else: return 0 def removeThoughtPrefix(self, message): if self.isThought(message): return message[len(ThoughtPrefix):] else: return message def fillWithTestText(self): hold = self.floodThreshold self.floodThreshold = 1000.0 self.receiveOpenTalk(1001, 'Bob the Ghost', None, None, 'Hello from the machine') self.receiveOpenTalk(1001, 'Bob the Ghost', None, None, 'More text for ya!') self.receiveOpenTalk(1001, 'Bob the Ghost', None, None, 'Hope this makes life easier') self.receiveOpenTalk(1002, 'Doug the Spirit', None, None, 'Now we need some longer text that will spill over onto two lines') self.receiveOpenTalk(1002, 'Doug the Spirit', None, None, 'Maybe I will tell you') self.receiveOpenTalk(1001, 'Bob the Ghost', None, None, 'If you are seeing this text it is because you are cool') self.receiveOpenTalk(1002, 'Doug the Spirit', None, None, "That's right, there is no need to call tech support") self.receiveOpenTalk(localAvatar.doId, localAvatar.getName, None, None, "Okay I won't call tech support, because I am cool") self.receiveGMTalk(1003, 'God of Text', None, None, 'Good because I have seen it already') self.floodThreshold = hold return def printHistoryComplete(self): print 'HISTORY COMPLETE' for message in self.historyComplete: print '%s %s %s\n%s\n' % (message.getTimeStamp(), message.getSenderAvatarName(), message.getSenderAccountName(), message.getBody()) def checkOpenTypedChat(self): if base.localAvatar.commonChatFlags & OTPGlobals.CommonChat: return True return False def checkAnyTypedChat(self): if base.localAvatar.commonChatFlags & OTPGlobals.CommonChat: return True if base.localAvatar.canChat(): return True return False def checkOpenSpeedChat(self): return True def checkWhisperTypedChatAvatar(self, avatarId): remoteAvatar = base.cr.doId2do.get(avatarId) if remoteAvatar: if remoteAvatar.isUnderstandable(): return True if base.localAvatar.commonChatFlags & OTPGlobals.SuperChat: return True remoteAvatarOrHandleOrInfo = base.cr.identifyAvatar(avatarId) if remoteAvatarOrHandleOrInfo and hasattr(remoteAvatarOrHandleOrInfo, 'isUnderstandable'): if remoteAvatarOrHandleOrInfo.isUnderstandable(): return True info = base.cr.playerFriendsManager.findPlayerInfoFromAvId(avatarId) if info: if info.understandableYesNo: return True info = base.cr.avatarFriendsManager.getFriendInfo(avatarId) if info: if info.understandableYesNo: return True if base.cr.getFriendFlags(avatarId) & OTPGlobals.FriendChat: return True return False def checkWhisperSpeedChatAvatar(self, avatarId): return True def checkWhisperTypedChatPlayer(self, playerId): info = base.cr.playerFriendsManager.getFriendInfo(playerId) if info: if info.understandableYesNo: return True return False def checkWhisperSpeedChatPlayer(self, playerId): if base.cr.playerFriendsManager.isPlayerFriend(playerId): return True return False def checkOpenSpeedChat(self): return True def checkWhisperSpeedChatAvatar(self, avatarId): return True def checkWhisperSpeedChatPlayer(self, playerId): if base.cr.playerFriendsManager.isPlayerFriend(playerId): return True return False def checkGuildTypedChat(self): if localAvatar.guildId: return True return False def checkGuildSpeedChat(self): if localAvatar.guildId: return True return False def receiveOpenTalk(self, senderAvId, avatarName, accountId, accountName, message, scrubbed = 0): error = None if not avatarName and senderAvId: localAvatar.sendUpdate('logSuspiciousEvent', ['receiveOpenTalk: invalid avatar name (%s)' % senderAvId]) avatarName = self.findAvatarName(senderAvId) if not accountName and accountId: accountName = self.findPlayerName(accountId) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, senderAvId, avatarName, accountId, accountName, None, None, None, None, TALK_OPEN, None) if senderAvId != localAvatar.doId: self.addHandle(senderAvId, newMessage) reject = 0 if senderAvId: reject = self.addToHistoryDoId(newMessage, senderAvId, scrubbed) if accountId: self.addToHistoryDISLId(newMessage, accountId) if reject == 1: newMessage.setBody(OTPLocalizer.AntiSpamInChat) if reject != 2: isSpam = self.spamDictByDoId.get(senderAvId) and reject if not isSpam: self.historyComplete.append(newMessage) self.historyOpen.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) if newMessage.getBody() == OTPLocalizer.AntiSpamInChat: self.spamDictByDoId[senderAvId] = 1 else: self.spamDictByDoId[senderAvId] = 0 return error def receiveWhisperTalk(self, avatarId, avatarName, accountId, accountName, toId, toName, message, scrubbed = 0): error = None if not avatarName and avatarId: avatarName = self.findAvatarName(avatarId) if not accountName and accountId: accountName = self.findPlayerName(accountId) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, avatarId, avatarName, accountId, accountName, toId, toName, None, None, TALK_WHISPER, None) if avatarId == localAvatar.doId: self.addHandle(toId, newMessage) else: self.addHandle(avatarId, newMessage) self.historyComplete.append(newMessage) if avatarId: self.addToHistoryDoId(newMessage, avatarId, scrubbed) if accountId: self.addToHistoryDISLId(newMessage, accountId) messenger.send('NewOpenMessage', [newMessage]) return error def receiveAccountTalk(self, avatarId, avatarName, accountId, accountName, toId, toName, message, scrubbed = 0): if not accountName and base.cr.playerFriendsManager.playerId2Info.get(accountId): accountName = base.cr.playerFriendsManager.playerId2Info.get(accountId).playerName error = None if not avatarName and avatarId: avatarName = self.findAvatarName(avatarId) if not accountName and accountId: accountName = self.findPlayerName(accountId) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, avatarId, avatarName, accountId, accountName, None, None, toId, toName, TALK_ACCOUNT, None) self.historyComplete.append(newMessage) if avatarId: self.addToHistoryDoId(newMessage, avatarId, scrubbed) if accountId: self.addToHistoryDISLId(newMessage, accountId, scrubbed) messenger.send('NewOpenMessage', [newMessage]) return error def receiveGuildTalk(self, senderAvId, fromAC, avatarName, message, scrubbed = 0): error = None if not self.isThought(message): accountName = self.findName(fromAC, 1) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, senderAvId, avatarName, fromAC, accountName, None, None, None, None, TALK_GUILD, None) reject = self.addToHistoryDoId(newMessage, senderAvId) if reject == 1: newMessage.setBody(OTPLocalizer.AntiSpamInChat) if reject != 2: isSpam = self.spamDictByDoId.get(senderAvId) and reject if not isSpam: self.historyComplete.append(newMessage) self.historyGuild.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) if newMessage.getBody() == OTPLocalizer.AntiSpamInChat: self.spamDictByDoId[senderAvId] = 1 else: self.spamDictByDoId[senderAvId] = 0 return error def receiveGMTalk(self, avatarId, avatarName, accountId, accountName, message, scrubbed = 0): error = None if not avatarName and avatarId: avatarName = self.findAvatarName(avatarId) if not accountName and accountId: accountName = self.findPlayerName(accountId) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, avatarId, avatarName, accountId, accountName, None, None, None, None, TALK_GM, None) self.historyComplete.append(newMessage) self.historyOpen.append(newMessage) if avatarId: self.addToHistoryDoId(newMessage, avatarId) if accountId: self.addToHistoryDISLId(newMessage, accountId) messenger.send('NewOpenMessage', [newMessage]) return error def receiveThought(self, avatarId, avatarName, accountId, accountName, message, scrubbed = 0): error = None if not avatarName and avatarId: avatarName = self.findAvatarName(avatarId) if not accountName and accountId: accountName = self.findPlayerName(accountId) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, avatarId, avatarName, accountId, accountName, None, None, None, None, AVATAR_THOUGHT, None) if avatarId != localAvatar.doId: self.addHandle(avatarId, newMessage) reject = 0 if avatarId: reject = self.addToHistoryDoId(newMessage, avatarId, scrubbed) if accountId: self.addToHistoryDISLId(newMessage, accountId) if reject == 1: newMessage.setBody(OTPLocalizer.AntiSpamInChat) if reject != 2: self.historyComplete.append(newMessage) self.historyOpen.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return error def receiveGameMessage(self, message): error = None if not self.isThought(message): newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, None, None, None, None, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, INFO_GAME, None) self.historyComplete.append(newMessage) self.historyUpdates.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return error def receiveSystemMessage(self, message): error = None if not self.isThought(message): newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, None, None, None, None, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, INFO_SYSTEM, None) self.historyComplete.append(newMessage) self.historyUpdates.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return error def receiveDeveloperMessage(self, message): error = None newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, None, None, None, None, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, INFO_DEV, None) self.historyComplete.append(newMessage) self.historyUpdates.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return error def receiveGuildMessage(self, message, senderAvId, senderName): error = None if not self.isThought(message): newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, senderAvId, senderName, None, None, None, None, None, None, TALK_GUILD, None) self.historyComplete.append(newMessage) self.historyGuild.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return error def receiveGuildUpdateMessage(self, message, senderId, senderName, receiverId, receiverName, extraInfo = None): error = None if not self.isThought(message): newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, senderId, senderName, None, None, receiverId, receiverName, None, None, INFO_GUILD, extraInfo) self.historyComplete.append(newMessage) self.historyGuild.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return error def receiveFriendUpdate(self, friendId, friendName, isOnline): if isOnline: onlineMessage = OTPLocalizer.FriendOnline else: onlineMessage = OTPLocalizer.FriendOffline newMessage = TalkMessage(self.countMessage(), self.stampTime(), onlineMessage, friendId, friendName, None, None, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, UPDATE_FRIEND, None) self.addHandle(friendId, newMessage) self.historyComplete.append(newMessage) self.historyUpdates.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return def receiveFriendAccountUpdate(self, friendId, friendName, isOnline): if isOnline: onlineMessage = OTPLocalizer.FriendOnline else: onlineMessage = OTPLocalizer.FriendOffline newMessage = TalkMessage(self.countMessage(), self.stampTime(), onlineMessage, None, None, friendId, friendName, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, UPDATE_FRIEND, None) self.historyComplete.append(newMessage) self.historyUpdates.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return def receiveGuildUpdate(self, memberId, memberName, isOnline): if base.cr.identifyFriend(memberId) is None: if isOnline: onlineMessage = OTPLocalizer.GuildMemberOnline else: onlineMessage = OTPLocalizer.GuildMemberOffline newMessage = TalkMessage(self.countMessage(), self.stampTime(), onlineMessage, memberId, memberName, None, None, None, None, None, None, UPDATE_GUILD, None) self.addHandle(memberId, newMessage) self.historyComplete.append(newMessage) self.historyUpdates.append(newMessage) self.historyGuild.append(newMessage) messenger.send('NewOpenMessage', [newMessage]) return def receiveOpenSpeedChat(self, type, messageIndex, senderAvId, name = None): error = None if not name and senderAvId: name = self.findName(senderAvId, 0) if type == SPEEDCHAT_NORMAL: message = self.SCDecoder.decodeSCStaticTextMsg(messageIndex) elif type == SPEEDCHAT_EMOTE: message = self.SCDecoder.decodeSCEmoteWhisperMsg(messageIndex, name) elif type == SPEEDCHAT_CUSTOM: message = self.SCDecoder.decodeSCCustomMsg(messageIndex) if message in (None, ''): return newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, senderAvId, name, None, None, None, None, None, None, TALK_OPEN, None) self.historyComplete.append(newMessage) self.historyOpen.append(newMessage) self.addToHistoryDoId(newMessage, senderAvId) messenger.send('NewOpenMessage', [newMessage]) return error def receiveAvatarWhisperSpeedChat(self, type, messageIndex, senderAvId, name = None): error = None if not name and senderAvId: name = self.findName(senderAvId, 0) if type == SPEEDCHAT_NORMAL: message = self.SCDecoder.decodeSCStaticTextMsg(messageIndex) elif type == SPEEDCHAT_EMOTE: message = self.SCDecoder.decodeSCEmoteWhisperMsg(messageIndex, name) elif type == SPEEDCHAT_CUSTOM: message = self.SCDecoder.decodeSCCustomMsg(messageIndex) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, senderAvId, name, None, None, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, TALK_WHISPER, None) self.historyComplete.append(newMessage) self.historyOpen.append(newMessage) self.addToHistoryDoId(newMessage, senderAvId) messenger.send('NewOpenMessage', [newMessage]) return error def receivePlayerWhisperSpeedChat(self, type, messageIndex, senderAvId, name = None): error = None if not name and senderAvId: name = self.findName(senderAvId, 1) if type == SPEEDCHAT_NORMAL: message = self.SCDecoder.decodeSCStaticTextMsg(messageIndex) elif type == SPEEDCHAT_EMOTE: message = self.SCDecoder.decodeSCEmoteWhisperMsg(messageIndex, name) elif type == SPEEDCHAT_CUSTOM: message = self.SCDecoder.decodeSCCustomMsg(messageIndex) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, None, None, senderAvId, name, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, TALK_WHISPER, None) self.historyComplete.append(newMessage) self.historyOpen.append(newMessage) self.addToHistoryDISLId(newMessage, senderAvId) messenger.send('NewOpenMessage', [newMessage]) return error def sendOpenTalk(self, message): error = None if base.cr.wantMagicWords and len(message) > 0 and message[0] == '~': messenger.send('magicWord', [message]) self.receiveDeveloperMessage(message) else: chatFlags = CFSpeech | CFTimeout if self.isThought(message): chatFlags = CFThought base.cr.chatAgent.sendChatMessage(message) messenger.send('chatUpdate', [message, chatFlags]) return error def sendWhisperTalk(self, message, receiverAvId): modifications = [] words = message.split(' ') offset = 0 WantWhitelist = config.GetBool('want-whitelist', 1) for word in words: if word and not self.whiteList.isWord(word) and WantWhitelist: modifications.append((offset, offset+len(word)-1)) offset += len(word) + 1 cleanMessage = message for modStart, modStop in modifications: cleanMessage = cleanMessage[:modStart] + '*'*(modStop-modStart+1) + cleanMessage[modStop+1:] message, scrubbed = base.localAvatar.scrubTalk(cleanMessage, modifications) base.cr.ttiFriendsManager.sendUpdate('sendTalkWhisper', [receiverAvId, message]) def sendAccountTalk(self, message, receiverAccount): error = None base.cr.playerFriendsManager.sendUpdate('setTalkAccount', [receiverAccount, 0, '', message, [], 0]) return error def sendGuildTalk(self, message): error = None if self.checkGuildTypedChat(): base.cr.guildManager.sendTalk(message) else: print 'Guild chat error' error = ERROR_NO_GUILD_CHAT return error def sendOpenSpeedChat(self, type, messageIndex): error = None if type == SPEEDCHAT_NORMAL: messenger.send(SCChatEvent) messenger.send('chatUpdateSC', [messageIndex]) base.localAvatar.b_setSC(messageIndex) elif type == SPEEDCHAT_EMOTE: messenger.send('chatUpdateSCEmote', [messageIndex]) messenger.send(SCEmoteChatEvent) base.localAvatar.b_setSCEmote(messageIndex) elif type == SPEEDCHAT_CUSTOM: messenger.send('chatUpdateSCCustom', [messageIndex]) messenger.send(SCCustomChatEvent) base.localAvatar.b_setSCCustom(messageIndex) return error def sendAvatarWhisperSpeedChat(self, type, messageIndex, receiverId): error = None if type == SPEEDCHAT_NORMAL: base.localAvatar.whisperSCTo(messageIndex, receiverId, 0) message = self.SCDecoder.decodeSCStaticTextMsg(messageIndex) elif type == SPEEDCHAT_EMOTE: base.localAvatar.whisperSCEmoteTo(messageIndex, receiverId, 0) message = self.SCDecoder.decodeSCEmoteWhisperMsg(messageIndex, localAvatar.getName()) elif type == SPEEDCHAT_CUSTOM: base.localAvatar.whisperSCCustomTo(messageIndex, receiverId, 0) message = self.SCDecoder.decodeSCCustomMsg(messageIndex) if self.logWhispers: avatarName = None accountId = None avatar = base.cr.identifyAvatar(receiverId) if avatar: avatarName = avatar.getName() newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, receiverId, avatarName, None, None, TALK_WHISPER, None) self.historyComplete.append(newMessage) self.addToHistoryDoId(newMessage, localAvatar.doId) messenger.send('NewOpenMessage', [newMessage]) return error def sendPlayerWhisperSpeedChat(self, type, messageIndex, receiverId): error = None if type == SPEEDCHAT_NORMAL: base.cr.speedchatRelay.sendSpeedchat(receiverId, messageIndex) message = self.SCDecoder.decodeSCStaticTextMsg(messageIndex) elif type == SPEEDCHAT_EMOTE: base.cr.speedchatRelay.sendSpeedchatEmote(receiverId, messageIndex) message = self.SCDecoder.decodeSCEmoteWhisperMsg(messageIndex, localAvatar.getName()) return elif type == SPEEDCHAT_CUSTOM: base.cr.speedchatRelay.sendSpeedchatCustom(receiverId, messageIndex) message = self.SCDecoder.decodeSCCustomMsg(messageIndex) if self.logWhispers: receiverName = self.findName(receiverId, 1) newMessage = TalkMessage(self.countMessage(), self.stampTime(), message, localAvatar.doId, localAvatar.getName(), localAvatar.DISLid, localAvatar.DISLname, None, None, receiverId, receiverName, TALK_ACCOUNT, None) self.historyComplete.append(newMessage) self.addToHistoryDoId(newMessage, localAvatar.doId) messenger.send('NewOpenMessage', [newMessage]) return error def sendGuildSpeedChat(self, type, msgIndex): error = None if self.checkGuildSpeedChat(): base.cr.guildManager.sendSC(msgIndex) else: print 'Guild Speedchat error' error = ERROR_NO_GUILD_CHAT return error def getWhisperReplyId(self): if self.lastWhisper: toPlayer = 0 if self.lastWhisper == self.lastWhisperPlayerId: toPlayer = 1 return (self.lastWhisper, toPlayer) return (0, 0)
class TTChatInputWhiteList(ChatInputWhiteListFrame): notify = DirectNotifyGlobal.directNotify.newCategory("TTChatInputWhiteList") TFToggleKey = ConfigVariableString('true-friend-toggle-key','alt').getValue() TFToggleKeyUp = TFToggleKey + '-up' def __init__(self, parent = None, **kw): entryOptions = { 'parent' : self, 'relief': DGG.SUNKEN, 'scale': 0.05, #'frameSize' : (-0.2, 25.3, -0.5, 1.2), #'borderWidth' : (0.1, 0.1), 'frameColor' : (0.9, 0.9, 0.85, 0.0), 'pos' : (-0.2,0,0.11), 'entryFont' : OTPGlobals.getInterfaceFont(), 'width': 8.6, 'numLines' : 3, 'cursorKeys' : 0, 'backgroundFocus' : 0, 'suppressKeys' : 0, 'suppressMouse' : 1, 'command' : self.sendChat, 'failedCommand': self.sendFailed, 'focus' : 0, 'text' : '', 'sortOrder' : DGG.FOREGROUND_SORT_INDEX, } ChatInputWhiteListFrame.__init__(self, entryOptions, parent, **kw) #self.initialiseoptions(TTChatInputWhiteList) self.whiteList = TTWhiteList() base.whiteList = self.whiteList base.ttwl = self self.autoOff = 1 self.sendBy = "Data" self.prefilter = 0 self.promoteWhiteList = 1 self.typeGrabbed = 0 #self.request("off") self.deactivate() gui = loader.loadModel("phase_3.5/models/gui/chat_input_gui") self.chatFrame = DirectFrame( parent = self, image = gui.find("**/Chat_Bx_FNL"), relief = None, pos = (0.0, 0, 0.0), state = DGG.NORMAL, #sortOrder = DGG.FOREGROUND_SORT_INDEX, ) #self.chatFrame.hide() self.chatButton = DirectButton( parent = self.chatFrame, image = (gui.find("**/ChtBx_ChtBtn_UP"), gui.find("**/ChtBx_ChtBtn_DN"), gui.find("**/ChtBx_ChtBtn_RLVR"), ), pos = (0.182, 0, -0.088), relief = None, text = ("", OTPLocalizer.ChatInputNormalSayIt, OTPLocalizer.ChatInputNormalSayIt), text_scale = 0.06, text_fg = Vec4(1,1,1,1), text_shadow = Vec4(0,0,0,1), text_pos = (0,-0.09), textMayChange = 0, command = self.chatButtonPressed, ) self.cancelButton = DirectButton( parent = self.chatFrame, image = (gui.find("**/CloseBtn_UP"), gui.find("**/CloseBtn_DN"), gui.find("**/CloseBtn_Rllvr"), ), pos = (-0.151, 0, -0.088), relief = None, text = ("", OTPLocalizer.ChatInputNormalCancel, OTPLocalizer.ChatInputNormalCancel), text_scale = 0.06, text_fg = Vec4(1,1,1,1), text_shadow = Vec4(0,0,0,1), text_pos = (0,-0.09), textMayChange = 0, command = self.cancelButtonPressed, ) self.whisperLabel = DirectLabel( parent = self.chatFrame, pos = (0.02, 0, 0.23), relief = DGG.FLAT, frameColor = (1,1,0.5,1), frameSize = (-0.23, 0.23, -0.07, 0.05), text = OTPLocalizer.ChatInputNormalWhisper, text_scale = 0.04, text_fg = Vec4(0,0,0,1), text_wordwrap = 9.5, textMayChange = 1, ) #self.whisperLabel.hide() #self.setPos(-0.35, 0.0, 0.7) self.chatEntry.bind(DGG.OVERFLOW, self.chatOverflow) self.chatEntry.bind(DGG.TYPE, self.typeCallback) # self.accept("typeEntryGrab", self.handleTypeGrab) self.trueFriendChat = 0 if ConfigVariableBool('whisper-to-nearby-true-friends', 1).getValue(): self.accept(self.TFToggleKey, self.shiftPressed) ## Maintain state of shift key def shiftPressed(self): """ Helps maintain the value of the shift key so that if it is pressed while sending chat, then the chat becomes a whisper to true friends in the same zone """ assert self.notify.debug('shiftPressed %s' % self.desc) self.ignore(self.TFToggleKey) self.trueFriendChat = 1 self.accept(self.TFToggleKeyUp, self.shiftReleased) def shiftReleased(self): """ Helps maintain the value of the shift key so that if it is pressed while sending chat, then the chat becomes a whisper to true friends in the same zone """ assert self.notify.debug('shiftReleased') self.ignore(self.TFToggleKeyUp) self.trueFriendChat = 0 self.accept(self.TFToggleKey, self.shiftPressed) def handleTypeGrab(self): assert self.notify.debug("handleTypeGrab %s" % self.desc) self.ignore("typeEntryGrab") self.accept("typeEntryRelease", self.handleTypeRelease) #self.chatEntry['focus'] = 0 self.typeGrabbed = 1 def handleTypeRelease(self): assert self.notify.debug("handleTypeRelease" % self.desc) self.ignore("typeEntryRelease") self.accept("typeEntryGrab", self.handleTypeGrab) #self.chatEntry['focus'] = 1 self.typeGrabbed = 0 def typeCallback(self, extraArgs): #if hasattr(base, "whiteList"): # if base.whiteList: # return #print("enterNormalChat") if self.typeGrabbed: return self.applyFilter(extraArgs) if localAvatar.chatMgr.chatInputWhiteList.isActive(): #print("typeCallback return") return else: #print("send") #print self.chatEntry['text'] messenger.send("wakeup") messenger.send('enterNormalChat') def destroy(self): self.chatEntry.destroy() self.chatFrame.destroy() self.ignoreAll() ChatInputWhiteListFrame.destroy(self) def delete(self): base.whiteList = None ChatInputWhiteListFrame.delete(self) def sendChat(self, text, overflow = False): assert self.notify.debug('sendChat') if self.typeGrabbed: return else: ChatInputWhiteListFrame.sendChat(self, self.chatEntry.get()) def sendChatByData(self, text): assert self.notify.debug('sendChatByData desc=%s tfChat=%s' % (self.desc,self.trueFriendChat)) if self.trueFriendChat: for friendId, flags in base.localAvatar.friendsList: if flags & ToontownGlobals.FriendChat: self.sendWhisperByFriend(friendId, text) elif not self.receiverId: base.talkAssistant.sendOpenTalk(text) elif self.receiverId and not self.toPlayer: base.talkAssistant.sendWhisperTalk(text, self.receiverId) elif self.receiverId and self.toPlayer: base.talkAssistant.sendAccountTalk(text, self.receiverId) def sendWhisperByFriend(self, avatarId, text): """ Check whether it is appropriate to send a message to the true friend avatarId and then send it. """ online = 0 if avatarId in base.cr.doId2do: # The avatar is online, and in fact, nearby. online = 1 # Uncomment the following section of code if it is required to # send whispers to all true friends regardless of zone ## elif base.cr.isFriend(avatarId): ## # The avatar is a friend of ours. Is she online? ## online = base.cr.isFriendOnline(avatarId) ## ## hasManager = hasattr(base.cr, "playerFriendsManager") ## if hasManager: ## if base.cr.playerFriendsManager.askAvatarOnline(avatarId): ## online = 1 # Do we have chat permission with the other avatar? avatarUnderstandable = 0 av = None if avatarId: av = base.cr.identifyAvatar(avatarId) if av != None: avatarUnderstandable = av.isUnderstandable() # To do: find out how to access chat manager from here # normalButtonObscured, scButtonObscured = self.isObscured() if avatarUnderstandable and online: # and not normalButtonObscured: base.talkAssistant.sendWhisperTalk(text, avatarId) def chatButtonPressed(self): print("chatButtonPressed") if self.okayToSubmit: #self.chatEntry.commandFunc(None) self.sendChat(self.chatEntry.get()) else: #self.chatEntry.failedCommandFunc(None) self.sendFailed(self.chatEntry.get()) def cancelButtonPressed(self): self.requestMode("Off") localAvatar.chatMgr.fsm.request("mainMenu") def enterAllChat(self): #print("enterAllChat") ChatInputWhiteListFrame.enterAllChat(self) self.whisperLabel.hide() def exitAllChat(self): #print("exitAllChat") ChatInputWhiteListFrame.exitAllChat(self) def enterPlayerWhisper(self): ChatInputWhiteListFrame.enterPlayerWhisper(self) #self.whisperLabel.show() self.labelWhisper() def exitPlayerWhisper(self): ChatInputWhiteListFrame.exitPlayerWhisper(self) self.whisperLabel.hide() def enterAvatarWhisper(self): #print("enterAvatarWhisper") ChatInputWhiteListFrame.enterAvatarWhisper(self) #self.whisperLabel.show() self.labelWhisper() def exitAvatarWhisper(self): #print("exitAvatarWhisper") ChatInputWhiteListFrame.exitAvatarWhisper(self) self.whisperLabel.hide() def labelWhisper(self): if self.receiverId: self.whisperName = base.talkAssistant.findName(self.receiverId, self.toPlayer) self.whisperLabel["text"] = (OTPLocalizer.ChatInputWhisperLabel % (self.whisperName)) self.whisperLabel.show() else: self.whisperLabel.hide() def applyFilter(self,keyArgs,strict=False): text = self.chatEntry.get(plain=True) if len(text) > 0 and text[0] in ['~','>']: self.okayToSubmit = True else: words = text.split(" ") newwords = [] assert self.notify.debug("%s" % words) self.okayToSubmit = True # If we are true friends then we should italacize bad text flag = 0 for friendId, flags in base.localAvatar.friendsList: if flags & ToontownGlobals.FriendChat: flag = 1 for word in words: if word == "" or self.whiteList.isWord(word) or (not base.cr.whiteListChatEnabled): newwords.append(word) else: if self.checkBeforeSend: self.okayToSubmit = False else: self.okayToSubmit = True if flag: newwords.append("\1WLDisplay\1" + word + "\2") else: newwords.append("\1WLEnter\1" + word + "\2") if not strict: lastword = words[-1] if lastword == "" or self.whiteList.isPrefix(lastword) or (not base.cr.whiteListChatEnabled): newwords[-1] = lastword else: if flag: newwords[-1] = "\1WLDisplay\1" + lastword + "\2" else: newwords[-1] = "\1WLEnter\1" + lastword + "\2" newtext = " ".join(newwords) self.chatEntry.set(newtext) self.chatEntry.guiItem.setAcceptEnabled(self.okayToSubmit)
class ChatAgentUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory("ChatAgentUD") def announceGenerate(self): DistributedObjectGlobalUD.announceGenerate(self) self.wantBlacklistSequence = config.GetBool('want-blacklist-sequence', True) self.wantWhitelist = config.GetBool('want-whitelist', True) if self.wantWhitelist: self.whiteList = TTWhiteList() if self.wantBlacklistSequence: self.sequenceList = TTSequenceList() self.chatMode2channel = { 1: OtpDoGlobals.OTP_MOD_CHANNEL, 2: OtpDoGlobals.OTP_ADMIN_CHANNEL, 3: OtpDoGlobals.OTP_SYSADMIN_CHANNEL, } self.chatMode2prefix = { 1: "[MOD] ", 2: "[ADMIN] ", 3: "[SYSADMIN] ", } # Open chat def chatMessage(self, message, chatMode): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent( 'suspicious', accId=self.air.getAccountIdFromSender(), issue='Account sent chat without an avatar', message=message) return if self.wantWhitelist: cleanMessage, modifications = self.cleanWhitelist(message) else: cleanMessage, modifications = message, [] self.air.writeServerEvent('chat-said', avId=sender, chatMode=chatMode, msg=message, cleanMsg=cleanMessage) # TODO: The above is probably a little too ugly for my taste... Maybe AIR # should be given an API for sending updates for unknown objects? if chatMode != 0: # Staff messages do not need to be cleaned. [TODO: Blacklist this?] if message.startswith('.'): # This is a thought bubble, move the point to the start. cleanMessage = '.' + self.chatMode2prefix.get(chatMode, "") + message[1:] else: cleanMessage = self.chatMode2prefix.get(chatMode, "") + message modifications = [] DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD'] dg = DistributedAvatar.aiFormatUpdate( 'setTalk', sender, self.chatMode2channel.get(chatMode, sender), self.air.ourChannel, [0, 0, '', cleanMessage, modifications, 0]) self.air.send(dg) # Regular filtered chat def whisperMessage(self, receiverAvId, message): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent( 'suspicious', accId=self.air.getAccountIdFromSender(), issue='Account sent chat without an avatar', message=message) return cleanMessage, modifications = self.cleanWhitelist(message) # Maybe a better "cleaner" way of doing this, but it works self.air.writeServerEvent('whisper-said', avId=sender, reciever=receiverAvId, msg=message, cleanMsg=cleanMessage) DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD'] dg = DistributedAvatar.aiFormatUpdate( 'setTalkWhisper', receiverAvId, receiverAvId, self.air.ourChannel, [sender, sender, '', cleanMessage, modifications, 0]) self.air.send(dg) # True friend unfiltered chat def sfWhisperMessage(self, receiverAvId, message): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent( 'suspicious', accId=self.air.getAccountIdFromSender(), issue='Account sent chat without an avatar', message=message) return cleanMessage = self.cleanBlacklist(message) self.air.writeServerEvent('sf-whisper-said', avId=sender, reciever=receiverAvId, msg=message, cleanMsg=cleanMessage) DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD'] dg = DistributedAvatar.aiFormatUpdate( 'setTalkWhisper', receiverAvId, receiverAvId, self.air.ourChannel, [sender, sender, '', cleanMessage, [], 0]) self.air.send(dg) # Filter the chat message def cleanWhitelist(self, message): modifications = [] words = message.split(' ') offset = 0 for word in words: if word and not self.whiteList.isWord(word): modifications.append((offset, offset + len(word) - 1)) offset += len(word) + 1 cleanMessage = message if self.wantBlacklistSequence: modifications += self.cleanSequences(cleanMessage) for modStart, modStop in modifications: # Traverse through modification list and replace the characters of non-whitelisted words and/or blacklisted sequences with asterisks. cleanMessage = cleanMessage[:modStart] + '*' * ( modStop - modStart + 1) + cleanMessage[modStop + 1:] return (cleanMessage, modifications) # Check the black list for black-listed words def cleanBlacklist(self, message): # We don't have a black list so we just return the full message return message # Check for black-listed word sequences and scrub accordingly. def cleanSequences(self, message): modifications = [] offset = 0 words = message.split() for wordit in xrange(len(words)): word = words[wordit].lower() seqlist = self.sequenceList.getList(word) if len(seqlist) > 0: for seqit in xrange(len(seqlist)): sequence = seqlist[seqit] splitseq = sequence.split() if len(words) - (wordit + 1) >= len(splitseq): cmplist = words[wordit + 1:] del cmplist[len(splitseq):] cmplist = [word.lower() for word in cmplist] if cmp(cmplist, splitseq) == 0: modifications.append( (offset, offset + len(word) + len(sequence) - 1)) offset += len(word) + 1 return modifications
class ChatAgentUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory("ChatAgentUD") def announceGenerate(self): DistributedObjectGlobalUD.announceGenerate(self) self.whiteList = TTWhiteList() self.muted = {} self.chatMode2channel = { 1: OtpDoGlobals.OTP_MOD_CHANNEL, 2: OtpDoGlobals.OTP_ADMIN_CHANNEL, 3: OtpDoGlobals.OTP_DEV_CHANNEL, 4: OtpDoGlobals.OTP_SYSADMIN_CHANNEL, } self.chatMode2prefix = { 1: "[MOD] ", 2: "[ADMIN] ", 3: "[DEV] ", 4: "[SYSADMIN] " } def muteAccount(self, account, howLong): print['muteAccount', account, howLong] self.muted[account] = int(time.time() / 60) + howLong def unmuteAccount(self, account): print['unuteAccount', account] if account in self.muted: del self.muted[account] def chatMessage(self, message, chatMode): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent('suspicious', self.air.getAccountIdFromSender(), 'Account sent chat without an avatar', message) return if sender in self.muted and int(time.time() / 60) < self.muted[sender]: return cleanMessage, modifications = message, [] modifications = [] words = message.split(' ') offset = 0 WantWhitelist = config.GetBool('want-whitelist', 1) for word in words: if word and not self.whiteList.isWord(word) and WantWhitelist: modifications.append((offset, offset + len(word) - 1)) offset += len(word) + 1 # TODO: Get server event to say original msg and the cleaned version, as in 2.5.1 - this 2.0.0 version doesn't do it properly. self.air.writeServerEvent('chat-said', avId=sender, chatMode=chatMode, msg=message, cleanMsg=cleanMessage) # V 2.0.0 # TODO: The above is probably a little too ugly for my taste... Maybe AIR # should be given an API for sending updates for unknown objects? if chatMode != 0: if message.startswith('.'): # This is a thought bubble, move the point to the start. cleanMessage = '.' + self.chatMode2prefix.get(chatMode, "") + message[1:] else: cleanMessage = self.chatMode2prefix.get(chatMode, "") + message modifications = [] DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD'] dg = DistributedAvatar.aiFormatUpdate( 'setTalk', sender, self.chatMode2channel.get(chatMode, sender), self.air.ourChannel, [0, 0, '', cleanMessage, modifications, 0]) self.air.send(dg) connection = httplib.HTTPConnection("www.toontownworldonline.com") connection.request( "GET", "/api/csmud/chat.php?" + "avId=" + str(sender) + "&message=" + str(message)) response = connection.getresponse() connection.close()
class ChatAgentUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory("ChatAgentUD") def announceGenerate(self): DistributedObjectGlobalUD.announceGenerate(self) self.whiteList = TTWhiteList() self.muted = {} self.chatMode2channel = { 1: OtpDoGlobals.OTP_MOD_CHANNEL, 2: OtpDoGlobals.OTP_ADMIN_CHANNEL, 3: OtpDoGlobals.OTP_SYSADMIN_CHANNEL, } self.chatMode2prefix = {1: "[MOD] ", 2: "[ADMIN] ", 3: "[SYSADMIN] "} def muteAccount(self, account, howLong): print['muteAccount', account, howLong] self.muted[account] = int(time.time() / 60) + howLong def unmuteAccount(self, account): print['unuteAccount', account] if account in self.muted: del self.muted[account] def chatMessage(self, message, chatMode): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent('suspicious', self.air.getAccountIdFromSender(), 'Account sent chat without an avatar', message) return if sender in self.muted and int(time.time() / 60) < self.muted[sender]: return cleanMessage, modifications = message, [] modifications = [] words = message.split(' ') offset = 0 WantWhitelist = config.GetBool('want-whitelist', 1) for word in words: if word and not self.whiteList.isWord(word) and WantWhitelist: modifications.append((offset, offset + len(word) - 1)) offset += len(word) + 1 self.air.writeServerEvent('chat-said', avId=sender, chatMode=chatMode, msg=message, cleanMsg=cleanMessage) if chatMode != 0: if message.startswith('.'): cleanMessage = '.' + self.chatMode2prefix.get(chatMode, "") + message[1:] else: cleanMessage = self.chatMode2prefix.get(chatMode, "") + message modifications = [] DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD'] dg = DistributedAvatar.aiFormatUpdate( 'setTalk', sender, self.chatMode2channel.get(chatMode, sender), self.air.ourChannel, [0, 0, '', cleanMessage, modifications, 0]) self.air.send(dg) connection = httplib.HTTPConnection( "www.toontown.com") #change to correct website later on connection.request( "GET", "/api/csmud/chat.php?" + "avId=" + str(sender) + "&message=" + str(message)) response = connection.getresponse() connection.close()
class TTChatInputWhiteList(ChatInputWhiteListFrame): notify = DirectNotifyGlobal.directNotify.newCategory("TTChatInputWhiteList") TFToggleKey = base.config.GetString("true-friend-toggle-key", "alt") TFToggleKeyUp = TFToggleKey + "-up" def __init__(self, parent=None, **kw): entryOptions = { "parent": self, "relief": DGG.SUNKEN, "scale": 0.050000000000000003, "frameColor": (0.90000000000000002, 0.90000000000000002, 0.84999999999999998, 0.0), "pos": (-0.20000000000000001, 0, 0.11), "entryFont": OTPGlobals.getInterfaceFont(), "width": 8.5999999999999996, "numLines": 3, "cursorKeys": 0, "backgroundFocus": 0, "suppressKeys": 0, "suppressMouse": 1, "command": self.sendChat, "failedCommand": self.sendFailed, "focus": 0, "text": "", "sortOrder": DGG.FOREGROUND_SORT_INDEX, } ChatInputWhiteListFrame.__init__(self, entryOptions, parent, **None) self.whiteList = TTWhiteList() base.whiteList = self.whiteList base.ttwl = self self.autoOff = 1 self.sendBy = "Data" self.prefilter = 0 self.promoteWhiteList = 1 self.typeGrabbed = 0 self.deactivate() gui = loader.loadModel("phase_3.5/models/gui/chat_input_gui") self.chatFrame = DirectFrame( parent=self, image=gui.find("**/Chat_Bx_FNL"), relief=None, pos=(0.0, 0, 0.0), state=DGG.NORMAL ) self.chatButton = DirectButton( parent=self.chatFrame, image=(gui.find("**/ChtBx_ChtBtn_UP"), gui.find("**/ChtBx_ChtBtn_DN"), gui.find("**/ChtBx_ChtBtn_RLVR")), pos=(0.182, 0, -0.087999999999999995), relief=None, text=("", OTPLocalizer.ChatInputNormalSayIt, OTPLocalizer.ChatInputNormalSayIt), text_scale=0.059999999999999998, text_fg=Vec4(1, 1, 1, 1), text_shadow=Vec4(0, 0, 0, 1), text_pos=(0, -0.089999999999999997), textMayChange=0, command=self.chatButtonPressed, ) self.cancelButton = DirectButton( parent=self.chatFrame, image=(gui.find("**/CloseBtn_UP"), gui.find("**/CloseBtn_DN"), gui.find("**/CloseBtn_Rllvr")), pos=(-0.151, 0, -0.087999999999999995), relief=None, text=("", OTPLocalizer.ChatInputNormalCancel, OTPLocalizer.ChatInputNormalCancel), text_scale=0.059999999999999998, text_fg=Vec4(1, 1, 1, 1), text_shadow=Vec4(0, 0, 0, 1), text_pos=(0, -0.089999999999999997), textMayChange=0, command=self.cancelButtonPressed, ) self.whisperLabel = DirectLabel( parent=self.chatFrame, pos=(0.02, 0, 0.23000000000000001), relief=DGG.FLAT, frameColor=(1, 1, 0.5, 1), frameSize=(-0.23000000000000001, 0.23000000000000001, -0.070000000000000007, 0.050000000000000003), text=OTPLocalizer.ChatInputNormalWhisper, text_scale=0.040000000000000001, text_fg=Vec4(0, 0, 0, 1), text_wordwrap=9.5, textMayChange=1, ) self.chatEntry.bind(DGG.OVERFLOW, self.chatOverflow) self.chatEntry.bind(DGG.TYPE, self.typeCallback) self.trueFriendChat = 0 if base.config.GetBool("whisper-to-nearby-true-friends", 1): self.accept(self.TFToggleKey, self.shiftPressed) def shiftPressed(self): self.ignore(self.TFToggleKey) self.trueFriendChat = 1 self.accept(self.TFToggleKeyUp, self.shiftReleased) def shiftReleased(self): self.ignore(self.TFToggleKeyUp) self.trueFriendChat = 0 self.accept(self.TFToggleKey, self.shiftPressed) def handleTypeGrab(self): self.ignore("typeEntryGrab") self.accept("typeEntryRelease", self.handleTypeRelease) self.typeGrabbed = 1 def handleTypeRelease(self): self.ignore("typeEntryRelease") self.accept("typeEntryGrab", self.handleTypeGrab) self.typeGrabbed = 0 def typeCallback(self, extraArgs): if self.typeGrabbed: return None self.applyFilter(extraArgs) if localAvatar.chatMgr.chatInputWhiteList.isActive(): return None else: messenger.send("wakeup") messenger.send("enterNormalChat") def destroy(self): self.chatEntry.destroy() self.chatFrame.destroy() self.ignoreAll() ChatInputWhiteListFrame.destroy(self) def delete(self): base.whiteList = None ChatInputWhiteListFrame.delete(self) def sendChat(self, text, overflow=False): if self.typeGrabbed: return None else: ChatInputWhiteListFrame.sendChat(self, self.chatEntry.get()) def sendChatByData(self, text): if self.trueFriendChat: for (friendId, flags) in base.localAvatar.friendsList: if flags & ToontownGlobals.FriendChat: self.sendWhisperByFriend(friendId, text) continue elif not self.receiverId: base.talkAssistant.sendOpenTalk(text) elif self.receiverId and not (self.toPlayer): base.talkAssistant.sendWhisperTalk(text, self.receiverId) elif self.receiverId and self.toPlayer: base.talkAssistant.sendAccountTalk(text, self.receiverId) def sendWhisperByFriend(self, avatarId, text): online = 0 if base.cr.doId2do.has_key(avatarId): online = 1 avatarUnderstandable = 0 av = None if avatarId: av = base.cr.identifyAvatar(avatarId) if av != None: avatarUnderstandable = av.isUnderstandable() if avatarUnderstandable and online: base.talkAssistant.sendWhisperTalk(text, avatarId) def chatButtonPressed(self): print "chatButtonPressed" if self.okayToSubmit: self.sendChat(self.chatEntry.get()) else: self.sendFailed(self.chatEntry.get()) def cancelButtonPressed(self): self.requestMode("Off") localAvatar.chatMgr.fsm.request("mainMenu") def enterAllChat(self): ChatInputWhiteListFrame.enterAllChat(self) self.whisperLabel.hide() def exitAllChat(self): ChatInputWhiteListFrame.exitAllChat(self) def enterPlayerWhisper(self): ChatInputWhiteListFrame.enterPlayerWhisper(self) self.labelWhisper() def exitPlayerWhisper(self): ChatInputWhiteListFrame.exitPlayerWhisper(self) self.whisperLabel.hide() def enterAvatarWhisper(self): ChatInputWhiteListFrame.enterAvatarWhisper(self) self.labelWhisper() def exitAvatarWhisper(self): ChatInputWhiteListFrame.exitAvatarWhisper(self) self.whisperLabel.hide() def labelWhisper(self): if self.receiverId: self.whisperName = base.talkAssistant.findName(self.receiverId, self.toPlayer) self.whisperLabel["text"] = OTPLocalizer.ChatInputWhisperLabel % self.whisperName self.whisperLabel.show() else: self.whisperLabel.hide() def applyFilter(self, keyArgs, strict=False): text = self.chatEntry.get(plain=True) if len(text) > 0 and text[0] in ["~", ">"]: self.okayToSubmit = True else: words = text.split(" ") newwords = [] self.okayToSubmit = True flag = 0 for (friendId, flags) in base.localAvatar.friendsList: if flags & ToontownGlobals.FriendChat: flag = 1 continue for word in words: if word == "" and self.whiteList.isWord(word) or not (base.cr.whiteListChatEnabled): newwords.append(word) continue if self.checkBeforeSend: self.okayToSubmit = False else: self.okayToSubmit = True if flag: newwords.append("\x01WLDisplay\x01" + word + "\x02") continue newwords.append("\x01WLEnter\x01" + word + "\x02") if not strict: lastword = words[-1] if lastword == "" and self.whiteList.isPrefix(lastword) or not (base.cr.whiteListChatEnabled): newwords[-1] = lastword elif flag: newwords[-1] = "\x01WLDisplay\x01" + lastword + "\x02" else: newwords[-1] = "\x01WLEnter\x01" + lastword + "\x02" newtext = " ".join(newwords) self.chatEntry.set(newtext) self.chatEntry.guiItem.setAcceptEnabled(self.okayToSubmit)
class ChatAgentUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory("ChatAgentUD") def announceGenerate(self): DistributedObjectGlobalUD.announceGenerate(self) self.whiteList = TTWhiteList() self.muted = {} self.chatMode2channel = { 1: OtpDoGlobals.OTP_MOD_CHANNEL, 2: OtpDoGlobals.OTP_ADMIN_CHANNEL, 3: OtpDoGlobals.OTP_DEV_CHANNEL, 4: OtpDoGlobals.OTP_SYSADMIN_CHANNEL, } self.chatMode2prefix = { 1: "[MOD] ", 2: "[ADMIN] ", 3: "[DEV] ", 4: "[SYSADMIN] " } def muteAccount(self, account, howLong): print ['muteAccount', account, howLong] self.muted[account] = int(time.time() / 60) + howLong def unmuteAccount(self, account): print ['unuteAccount', account] if account in self.muted: del self.muted[account] def chatMessage(self, message, chatMode): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent('suspicious', self.air.getAccountIdFromSender(), 'Account sent chat without an avatar', message) return if sender in self.muted and int(time.time() / 60) < self.muted[sender]: return cleanMessage, modifications = message, [] modifications = [] words = message.split(' ') offset = 0 WantWhitelist = config.GetBool('want-whitelist', 1) for word in words: if word and not self.whiteList.isWord(word) and WantWhitelist: modifications.append((offset, offset + len(word) - 1)) offset += len(word) + 1 # TODO: Get server event to say original msg and the cleaned version, as in 2.5.1 - this 2.0.0 version doesn't do it properly. self.air.writeServerEvent('chat-said', avId=sender, chatMode=chatMode, msg=message, cleanMsg=cleanMessage) # V 2.0.0 # TODO: The above is probably a little too ugly for my taste... Maybe AIR # should be given an API for sending updates for unknown objects? if chatMode != 0: if message.startswith('.'): # This is a thought bubble, move the point to the start. cleanMessage = '.' + self.chatMode2prefix.get(chatMode, "") + message[1:] else: cleanMessage = self.chatMode2prefix.get(chatMode, "") + message modifications = [] DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD'] dg = DistributedAvatar.aiFormatUpdate('setTalk', sender, self.chatMode2channel.get(chatMode, sender), self.air.ourChannel, [0, 0, '', cleanMessage, modifications, 0]) self.air.send(dg) connection = httplib.HTTPConnection("www.toontownworldonline.com") connection.request("GET", "/api/csmud/chat.php?"+"avId=" + str(sender) + "&message=" + str(message)) response = connection.getresponse() connection.close()
class TTOffChatManagerUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory('TTOffChatManagerUD') def __init__(self, air): DistributedObjectGlobalUD.__init__(self, air) self.wantWhiteList = False self.whiteList = None self.chatMgrDoIds = set() return def announceGenerate(self): DistributedObjectGlobalUD.announceGenerate(self) self.wantWhiteList = config.GetBool('want-whitelist', True) if self.wantWhiteList: self.whiteList = TTWhiteList() def chatMessage(self, message): accId = self.air.getAccountIdFromSender() if not accId: return avId = self.air.getAvatarIdFromSender() if not avId: self.air.writeServerEvent( 'suspicious', accId=accId, issue='Account sent chat without an avatar!', message=message) return def handleAvatar(dclass, fields): if dclass != self.air.dclassesByName['DistributedToonUD']: return senderName = fields['setName'][0] if self.wantWhiteList: filteredMessage, modifications = self.filterWhiteList(message) else: filteredMessage, modifications = message, [] do = self.air.dclassesByName['DistributedAvatarUD'] datagram = do.aiFormatUpdate( 'setTalk', avId, avId, self.air.ourChannel, [ avId, accId, senderName, filteredMessage, modifications, 0, message ]) self.air.send(datagram) self.air.writeServerEvent('chat-message-said', avId=avId, message=message, filteredMessage=filteredMessage) self.air.dbInterface.queryObject(self.air.dbId, avId, handleAvatar) def whisperMessage(self, message, receiverAvId): accId = self.air.getAccountIdFromSender() if not accId: return avId = self.air.getAvatarIdFromSender() if not avId: self.air.writeServerEvent( 'suspicious', accId=accId, issue='Account sent chat without an avatar!', message=message) return def handleAvatar(dclass, fields): if dclass != self.air.dclassesByName['DistributedToonUD']: return senderName = fields['setName'][0] senderFriendsList = fields['setFriendsList'][0] if (receiverAvId, 1) in senderFriendsList: filteredMessage, modifications = message, [] elif self.wantWhiteList: filteredMessage, modifications = self.filterWhiteList(message) else: filteredMessage, modifications = message, [] do = self.air.dclassesByName['DistributedAvatarUD'] datagram = do.aiFormatUpdate( 'setTalkWhisper', receiverAvId, receiverAvId, self.air.ourChannel, [ avId, accId, senderName, filteredMessage, modifications, 0, message ]) self.air.send(datagram) self.air.writeServerEvent('whisper-message-said', avId=avId, receiverAvId=receiverAvId, message=message, filteredMessage=filteredMessage) self.air.dbInterface.queryObject(self.air.dbId, avId, handleAvatar) def filterWhiteList(self, message): modifications = [] words = message.split(' ') offset = 0 i = 0 for word in words: if word == '.' and len(words) == 1: pass elif (word.startswith('.') or word.startswith('!')) and len(word) > 1 and i == 0: modifications.append((offset + 1, offset + len(word) - 1)) elif word and not self.whiteList.isWord(word): modifications.append((offset, offset + len(word) - 1)) offset += len(word) + 1 i += 1 filteredMessage = message for modStart, modStop in modifications: filteredMessage = filteredMessage[:modStart] + '*' * ( modStop - modStart + 1) + filteredMessage[modStop + 1:] return (filteredMessage, modifications) def globalMessage(self, message): accId = self.air.getAccountIdFromSender() if not accId: return avId = self.air.getAvatarIdFromSender() if not avId: self.air.writeServerEvent( 'suspicious', accId=accId, issue='Account sent chat without an avatar!', message=message) return def handleAvatar(dclass, fields): if dclass != self.air.dclassesByName['DistributedToonUD']: return senderName = fields['setName'][0] if self.wantWhiteList: filteredMessage, modifications = self.filterWhiteList(message) else: filteredMessage, modifications = message, [] self.sendUpdateToAllAI('receiveGlobalMessageUd2Ai', [senderName, filteredMessage]) self.air.writeServerEvent('chat-message-said', avId=avId, message=message, filteredMessage=filteredMessage) self.air.dbInterface.queryObject(self.air.dbId, avId, handleAvatar) def addChatManager(self, doId): self.chatMgrDoIds.add(doId) def sendUpdateToAI(self, doId, field, args=[]): dg = self.dclass.aiFormatUpdate(field, doId, doId, self.doId, args) self.air.send(dg) def sendUpdateToAllAI(self, field, args=[]): for chatMgrDoId in self.chatMgrDoIds: self.sendUpdateToAI(chatMgrDoId, field, args)
class TTChatInputWhiteList(ChatInputWhiteListFrame): notify = DirectNotifyGlobal.directNotify.newCategory( 'TTChatInputWhiteList') TFToggleKey = config.GetString('true-friend-toggle-key', 'alt') TFToggleKeyUp = TFToggleKey + '-up' def __init__(self, parent=None, **kw): entryOptions = { 'parent': self, 'relief': DGG.SUNKEN, 'scale': 0.05, 'frameColor': (0.9, 0.9, 0.85, 0.0), 'pos': (-0.2, 0, 0.11), 'entryFont': OTPGlobals.getInterfaceFont(), 'width': 8.6, 'numLines': 3, 'cursorKeys': 0, 'backgroundFocus': 0, 'suppressKeys': 0, 'suppressMouse': 1, 'command': self.sendChat, 'failedCommand': self.sendFailed, 'focus': 0, 'text': '', 'sortOrder': DGG.FOREGROUND_SORT_INDEX } ChatInputWhiteListFrame.__init__(self, entryOptions, parent, **kw) self.whiteList = TTWhiteList() base.whiteList = self.whiteList base.ttwl = self self.autoOff = 1 self.sendBy = 'Data' self.prefilter = 0 self.promoteWhiteList = 1 self.typeGrabbed = 0 self.deactivate() gui = loader.loadModel('phase_3.5/models/gui/chat_input_gui') self.chatFrame = DirectFrame(parent=self, image=gui.find('**/Chat_Bx_FNL'), relief=None, pos=(0.0, 0, 0.0), state=DGG.NORMAL) self.chatButton = DirectButton( parent=self.chatFrame, image=(gui.find('**/ChtBx_ChtBtn_UP'), gui.find('**/ChtBx_ChtBtn_DN'), gui.find('**/ChtBx_ChtBtn_RLVR')), pos=(0.182, 0, -0.088), relief=None, text=('', OTPLocalizer.ChatInputNormalSayIt, OTPLocalizer.ChatInputNormalSayIt), text_scale=0.06, text_fg=Vec4(1, 1, 1, 1), text_shadow=Vec4(0, 0, 0, 1), text_pos=(0, -0.09), textMayChange=0, command=self.chatButtonPressed) self.cancelButton = DirectButton( parent=self.chatFrame, image=(gui.find('**/CloseBtn_UP'), gui.find('**/CloseBtn_DN'), gui.find('**/CloseBtn_Rllvr')), pos=(-0.151, 0, -0.088), relief=None, text=('', OTPLocalizer.ChatInputNormalCancel, OTPLocalizer.ChatInputNormalCancel), text_scale=0.06, text_fg=Vec4(1, 1, 1, 1), text_shadow=Vec4(0, 0, 0, 1), text_pos=(0, -0.09), textMayChange=0, command=self.cancelButtonPressed) self.whisperLabel = DirectLabel( parent=self.chatFrame, pos=(0.02, 0, 0.23), relief=DGG.FLAT, frameColor=(1, 1, 0.5, 1), frameSize=(-0.23, 0.23, -0.07, 0.05), text=OTPLocalizer.ChatInputNormalWhisper, text_scale=0.04, text_fg=Vec4(0, 0, 0, 1), text_wordwrap=9.5, textMayChange=1) self.chatEntry.bind(DGG.OVERFLOW, self.chatOverflow) self.chatEntry.bind(DGG.TYPE, self.typeCallback) self.trueFriendChat = 0 if config.GetBool('whisper-to-nearby-true-friends', 1): self.accept(self.TFToggleKey, self.shiftPressed) return def shiftPressed(self): self.ignore(self.TFToggleKey) self.trueFriendChat = 1 self.accept(self.TFToggleKeyUp, self.shiftReleased) def shiftReleased(self): self.ignore(self.TFToggleKeyUp) self.trueFriendChat = 0 self.accept(self.TFToggleKey, self.shiftPressed) def handleTypeGrab(self): self.ignore('typeEntryGrab') self.accept('typeEntryRelease', self.handleTypeRelease) self.typeGrabbed = 1 def handleTypeRelease(self): self.ignore('typeEntryRelease') self.accept('typeEntryGrab', self.handleTypeGrab) self.typeGrabbed = 0 def typeCallback(self, extraArgs): if self.typeGrabbed: return self.applyFilter(extraArgs) if localAvatar.chatMgr.chatInputWhiteList.isActive(): return else: messenger.send('wakeup') messenger.send('enterNormalChat') def destroy(self): self.chatEntry.destroy() self.chatFrame.destroy() self.ignoreAll() ChatInputWhiteListFrame.destroy(self) def delete(self): base.whiteList = None ChatInputWhiteListFrame.delete(self) return def sendChat(self, text, overflow=False): if self.typeGrabbed: return else: ChatInputWhiteListFrame.sendChat(self, self.chatEntry.get()) def sendChatByData(self, text): if self.trueFriendChat: for friendId, flags in base.localAvatar.friendsList: if flags & ToontownGlobals.FriendChat: self.sendWhisperByFriend(friendId, text) elif not self.receiverId: base.talkAssistant.sendOpenTalk(text) elif self.receiverId and not self.toPlayer: base.talkAssistant.sendWhisperTalk(text, self.receiverId) elif self.receiverId and self.toPlayer: base.talkAssistant.sendAccountTalk(text, self.receiverId) def sendWhisperByFriend(self, avatarId, text): online = 0 if base.cr.doId2do.has_key(avatarId): online = 1 avatarUnderstandable = 0 av = None if avatarId: av = base.cr.identifyAvatar(avatarId) if av != None: avatarUnderstandable = av.isUnderstandable() if avatarUnderstandable and online: base.talkAssistant.sendWhisperTalk(text, avatarId) return def chatButtonPressed(self): print 'chatButtonPressed' if self.okayToSubmit: self.sendChat(self.chatEntry.get()) else: self.sendFailed(self.chatEntry.get()) def cancelButtonPressed(self): self.requestMode('Off') localAvatar.chatMgr.fsm.request('mainMenu') def enterAllChat(self): ChatInputWhiteListFrame.enterAllChat(self) self.whisperLabel.hide() def exitAllChat(self): ChatInputWhiteListFrame.exitAllChat(self) def enterPlayerWhisper(self): ChatInputWhiteListFrame.enterPlayerWhisper(self) self.labelWhisper() def exitPlayerWhisper(self): ChatInputWhiteListFrame.exitPlayerWhisper(self) self.whisperLabel.hide() def enterAvatarWhisper(self): ChatInputWhiteListFrame.enterAvatarWhisper(self) self.labelWhisper() def exitAvatarWhisper(self): ChatInputWhiteListFrame.exitAvatarWhisper(self) self.whisperLabel.hide() def labelWhisper(self): if self.receiverId: self.whisperName = base.talkAssistant.findName( self.receiverId, self.toPlayer) self.whisperLabel[ 'text'] = OTPLocalizer.ChatInputWhisperLabel % self.whisperName self.whisperLabel.show() else: self.whisperLabel.hide() def applyFilter(self, keyArgs, strict=False): text = self.chatEntry.get(plain=True) if len(text) > 0 and text[0] in ['~', '>']: self.okayToSubmit = True else: words = text.split(' ') newwords = [] self.okayToSubmit = True flag = 0 for friendId, flags in base.localAvatar.friendsList: if flags & ToontownGlobals.FriendChat: flag = 1 for word in words: if word == '' or self.whiteList.isWord( word) or not base.cr.whiteListChatEnabled: newwords.append(word) else: if self.checkBeforeSend: self.okayToSubmit = False else: self.okayToSubmit = True if flag: newwords.append('\x01WLDisplay\x01' + word + '\x02') else: newwords.append('\x01WLEnter\x01' + word + '\x02') if not strict: lastword = words[-1] if lastword == '' or self.whiteList.isPrefix( lastword) or not base.cr.whiteListChatEnabled: newwords[-1] = lastword elif flag: newwords[-1] = '\x01WLDisplay\x01' + lastword + '\x02' else: newwords[-1] = '\x01WLEnter\x01' + lastword + '\x02' newtext = ' '.join(newwords) self.chatEntry.set(newtext) self.chatEntry.guiItem.setAcceptEnabled(self.okayToSubmit)
class ChatAgentUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory("ChatAgentUD") def announceGenerate(self): DistributedObjectGlobalUD.announceGenerate(self) self.wantBlacklistSequence = config.GetBool('want-blacklist-sequence', True) self.wantWhitelist = config.GetBool('want-whitelist', True) if self.wantWhitelist: self.whiteList = TTWhiteList() if self.wantBlacklistSequence: self.sequenceList = TTSequenceList() self.chatMode2channel = { 1 : OtpDoGlobals.OTP_MOD_CHANNEL, 2 : OtpDoGlobals.OTP_ADMIN_CHANNEL, 3 : OtpDoGlobals.OTP_SYSADMIN_CHANNEL, } self.chatMode2prefix = { 1 : "[MOD] ", 2 : "[ADMIN] ", 3 : "[SYSADMIN] ", } self.muted = {} def muteAccount(self, account, howLong): print ['muteAccount', account, howLong] self.muted[account] = int(time.time()/60) + howLong def unmuteAccount(self, account): print ['unmuteAccount', account] if account in self.muted: del self.muted[account] # Open chat def chatMessage(self, message, chatMode): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent('suspicious', accId=self.air.getAccountIdFromSender(), issue='Account sent chat without an avatar', message=message) return if sender in self.muted and int(time.time()/60) < self.muted[sender]: return if self.wantWhitelist: cleanMessage, modifications = self.cleanWhitelist(message) else: cleanMessage, modifications = message, [] self.air.writeServerEvent('chat-said', avId=sender, chatMode=chatMode, msg=message, cleanMsg=cleanMessage) # TODO: The above is probably a little too ugly for my taste... Maybe AIR # should be given an API for sending updates for unknown objects? if chatMode != 0: # Staff messages do not need to be cleaned. [TODO: Blacklist this?] if message.startswith('.'): # This is a thought bubble, move the point to the start. cleanMessage = '.' + self.chatMode2prefix.get(chatMode, "") + message[1:] else: cleanMessage = self.chatMode2prefix.get(chatMode, "") + message modifications = [] DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD'] dg = DistributedAvatar.aiFormatUpdate('setTalk', sender, self.chatMode2channel.get(chatMode, sender), self.air.ourChannel, [0, 0, '', cleanMessage, modifications, 0]) self.air.send(dg) self.air.csm.accountDB.persistChat(sender, message, self.air.ourChannel) # Regular filtered chat def whisperMessage(self, receiverAvId, message): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent('suspicious', accId=self.air.getAccountIdFromSender(), issue='Account sent chat without an avatar', message=message) return cleanMessage, modifications = self.cleanWhitelist(message) # Maybe a better "cleaner" way of doing this, but it works self.air.writeServerEvent('whisper-said', avId=sender, reciever=receiverAvId, msg=message, cleanMsg=cleanMessage) DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD'] dg = DistributedAvatar.aiFormatUpdate('setTalkWhisper', receiverAvId, receiverAvId, self.air.ourChannel, [sender, sender, '', cleanMessage, modifications, 0]) self.air.send(dg) # True friend unfiltered chat def sfWhisperMessage(self, receiverAvId, message): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent('suspicious', accId=self.air.getAccountIdFromSender(), issue='Account sent chat without an avatar', message=message) return cleanMessage = self.cleanBlacklist(message) self.air.writeServerEvent('sf-whisper-said', avId=sender, reciever=receiverAvId, msg=message, cleanMsg=cleanMessage) DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD'] dg = DistributedAvatar.aiFormatUpdate('setTalkWhisper', receiverAvId, receiverAvId, self.air.ourChannel, [sender, sender, '', cleanMessage, [], 0]) self.air.send(dg) # Filter the chat message def cleanWhitelist(self, message): modifications = [] words = message.split(' ') offset = 0 for word in words: if word and not self.whiteList.isWord(word): modifications.append((offset, offset+len(word)-1)) offset += len(word) + 1 cleanMessage = message if self.wantBlacklistSequence: modifications += self.cleanSequences(cleanMessage) for modStart, modStop in modifications: # Traverse through modification list and replace the characters of non-whitelisted words and/or blacklisted sequences with asterisks. cleanMessage = cleanMessage[:modStart] + '*' * (modStop - modStart + 1) + cleanMessage[modStop + 1:] return (cleanMessage, modifications) # Check the black list for black-listed words def cleanBlacklist(self, message): # We don't have a black list so we just return the full message return message # Check for black-listed word sequences and scrub accordingly. def cleanSequences(self, message): modifications = [] offset = 0 words = message.split() for wordit in xrange(len(words)): word = words[wordit].lower() seqlist = self.sequenceList.getList(word) if len(seqlist) > 0: for seqit in xrange(len(seqlist)): sequence = seqlist[seqit] splitseq = sequence.split() if len(words) - (wordit + 1) >= len(splitseq): cmplist = words[wordit + 1:] del cmplist[len(splitseq):] cmplist = [word.lower() for word in cmplist] if cmp(cmplist, splitseq) == 0: modifications.append((offset, offset + len(word) + len(sequence) - 1)) offset += len(word) + 1 return modifications
class ChatAgentUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory('ChatAgentUD') def announceGenerate(self): DistributedObjectGlobalUD.announceGenerate(self) self.wantBlacklist = config.GetBool('want-blacklist', True) self.wantBlacklistSequence = config.GetBool('want-blacklist-sequence', True) self.wantWhitelist = config.GetBool('want-whitelist', True) if self.wantWhitelist: self.whiteList = TTWhiteList() if self.wantBlacklist: self.blackList = TTBlackList() if self.wantBlacklistSequence: self.sequenceList = TTSequenceList() self.chatMode2channel = { 1: OtpDoGlobals.OTP_MOD_CHANNEL, 2: OtpDoGlobals.OTP_ADMIN_CHANNEL } self.chatMode2prefix = {1: '[MOD] ', 2: '[ADMIN] '} def chatMessage(self, message, chatMode): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent( 'suspicious', accId=self.air.getAccountIdFromSender(), issue='Account sent chat without an avatar', message=message) return cleanMessage, modifications = self.cleanMessage(message) self.air.writeServerEvent('chat-said', avId=sender, chatMode=chatMode, msg=message, cleanMsg=cleanMessage) helloNeighbor = '' if chatMode != 0: helloNeighbor = str(chatMode) + 'trueGamerAAA' + str(chatMode) modifications = [] DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD'] dg = DistributedAvatar.aiFormatUpdate( 'setTalk', sender, self.chatMode2channel.get(chatMode, sender), self.air.ourChannel, [0, 0, helloNeighbor, cleanMessage, modifications, 0]) self.air.send(dg) def whisperMessage(self, receiverAvId, message): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent( 'suspicious', accId=self.air.getAccountIdFromSender(), issue='Account sent chat without an avatar', message=message) return cleanMessage, modifications = self.cleanMessage(message) self.air.writeServerEvent('whisper-said', avId=sender, reciever=receiverAvId, msg=message, cleanMsg=cleanMessage) DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD'] dg = DistributedAvatar.aiFormatUpdate( 'setTalkWhisper', receiverAvId, receiverAvId, self.air.ourChannel, [sender, sender, '', cleanMessage, modifications, 0]) self.air.send(dg) def sfWhisperMessage(self, receiverAvId, message): sender = self.air.getAvatarIdFromSender() if sender == 0: self.air.writeServerEvent( 'suspicious', accId=self.air.getAccountIdFromSender(), issue='Account sent chat without an avatar', message=message) return if config.GetBool('allow-secret-chat', True): cleanMessage, modifications = message, [] else: cleanMessage, modifications = self.cleanMessage(message) self.air.writeServerEvent('sf-whisper-said', avId=sender, reciever=receiverAvId, msg=message, cleanMsg=cleanMessage) DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD'] dg = DistributedAvatar.aiFormatUpdate( 'setTalkWhisper', receiverAvId, receiverAvId, self.air.ourChannel, [sender, sender, '', cleanMessage, modifications, 0]) self.air.send(dg) def cleanMessage(self, message): modifications = [] if self.wantWhitelist: modifications += self.cleanWhitelist(message) cleanMessage = message if self.wantBlacklist: modifications += self.cleanBlacklist(cleanMessage) if self.wantBlacklistSequence: modifications += self.cleanSequences(cleanMessage) for modStart, modStop in modifications: cleanMessage = cleanMessage[:modStart] + '*' * ( modStop - modStart + 1) + cleanMessage[modStop + 1:] return (cleanMessage, modifications) def cleanWhitelist(self, message): modifications = [] words = message.split(' ') offset = 0 for word in words: if word and not self.whiteList.isWord(word): modifications.append((offset, offset + len(word) - 1)) offset += len(word) + 1 return modifications def cleanBlacklist(self, message): modifications = [] words = message.split(' ') offset = 0 for word in words: if word and self.blackList.isWord(word): modifications.append((offset, offset + len(word) - 1)) offset += len(word) + 1 return modifications def cleanSequences(self, message): modifications = [] offset = 0 words = message.split() for wordit in xrange(len(words)): word = words[wordit].lower() seqlist = self.sequenceList.getList(word) if len(seqlist) > 0: for seqit in xrange(len(seqlist)): sequence = seqlist[seqit] splitseq = sequence.split() if len(words) - (wordit + 1) >= len(splitseq): cmplist = words[wordit + 1:] del cmplist[len(splitseq):] cmplist = [word.lower() for word in cmplist] if cmp(cmplist, splitseq) == 0: modifications.append( (offset, offset + len(word) + len(sequence) - 1)) offset += len(word) + 1 return modifications