oldschool-toontown/otp/avatar/DistributedPlayer.py
2019-12-30 01:00:16 -05:00

455 lines
18 KiB
Python

from pandac.PandaModules import *
from libotp import WhisperPopup
from libotp import CFQuicktalker, CFPageButton, CFQuitButton, CFSpeech, CFThought, CFTimeout
from otp.chat import ChatGarbler
import string
from direct.task import Task
from otp.otpbase import OTPLocalizer
from otp.speedchat import SCDecoders
from direct.showbase import PythonUtil
from otp.avatar import DistributedAvatar
import time
from otp.avatar import Avatar, PlayerBase
from otp.chat import TalkAssistant
from otp.otpbase import OTPGlobals
from otp.avatar.Avatar import teleportNotify
from otp.distributed.TelemetryLimited import TelemetryLimited
if base.config.GetBool('want-chatfilter-hacks', 0):
from otp.switchboard import badwordpy
import os
badwordpy.init(os.environ.get('OTP') + '\\src\\switchboard\\', '')
class DistributedPlayer(DistributedAvatar.DistributedAvatar, PlayerBase.PlayerBase, TelemetryLimited):
TeleportFailureTimeout = 60.0
chatGarbler = ChatGarbler.ChatGarbler()
def __init__(self, cr):
try:
self.DistributedPlayer_initialized
except:
self.DistributedPlayer_initialized = 1
DistributedAvatar.DistributedAvatar.__init__(self, cr)
PlayerBase.PlayerBase.__init__(self)
TelemetryLimited.__init__(self)
self.__teleportAvailable = 0
self.inventory = None
self.experience = None
self.friendsList = []
self.oldFriendsList = None
self.timeFriendsListChanged = None
self.ignoreList = []
self.lastFailedTeleportMessage = {}
self._districtWeAreGeneratedOn = None
self.DISLname = ''
self.DISLid = 0
self.autoRun = 0
self.whiteListEnabled = base.config.GetBool('whitelist-chat-enabled', 1)
return
@staticmethod
def GetPlayerGenerateEvent():
return 'DistributedPlayerGenerateEvent'
@staticmethod
def GetPlayerNetworkDeleteEvent():
return 'DistributedPlayerNetworkDeleteEvent'
@staticmethod
def GetPlayerDeleteEvent():
return 'DistributedPlayerDeleteEvent'
def networkDelete(self):
DistributedAvatar.DistributedAvatar.networkDelete(self)
messenger.send(self.GetPlayerNetworkDeleteEvent(), [self])
def disable(self):
DistributedAvatar.DistributedAvatar.disable(self)
messenger.send(self.GetPlayerDeleteEvent(), [self])
def delete(self):
try:
self.DistributedPlayer_deleted
except:
self.DistributedPlayer_deleted = 1
del self.experience
if self.inventory:
self.inventory.unload()
del self.inventory
DistributedAvatar.DistributedAvatar.delete(self)
def generate(self):
DistributedAvatar.DistributedAvatar.generate(self)
def announceGenerate(self):
DistributedAvatar.DistributedAvatar.announceGenerate(self)
messenger.send(self.GetPlayerGenerateEvent(), [self])
def setLocation(self, parentId, zoneId):
DistributedAvatar.DistributedAvatar.setLocation(self, parentId, zoneId)
if not (parentId in (0, None) and zoneId in (0, None)):
if not self.cr._isValidPlayerLocation(parentId, zoneId):
self.cr.disableDoId(self.doId)
self.cr.deleteObject(self.doId)
return None
def isGeneratedOnDistrict(self, districtId = None):
if districtId is None:
return self._districtWeAreGeneratedOn is not None
else:
return self._districtWeAreGeneratedOn == districtId
return
def getArrivedOnDistrictEvent(self, districtId = None):
if districtId is None:
return 'arrivedOnDistrict'
else:
return 'arrivedOnDistrict-%s' % districtId
return
def arrivedOnDistrict(self, districtId):
curFrameTime = globalClock.getFrameTime()
if hasattr(self, 'frameTimeWeArrivedOnDistrict') and curFrameTime == self.frameTimeWeArrivedOnDistrict:
if districtId == 0 and self._districtWeAreGeneratedOn:
self.notify.warning('ignoring arrivedOnDistrict 0, since arrivedOnDistrict %d occured on the same frame' % self._districtWeAreGeneratedOn)
return
self._districtWeAreGeneratedOn = districtId
self.frameTimeWeArrivedOnDistrict = globalClock.getFrameTime()
messenger.send(self.getArrivedOnDistrictEvent(districtId))
messenger.send(self.getArrivedOnDistrictEvent())
def setLeftDistrict(self):
self._districtWeAreGeneratedOn = None
return
def hasParentingRules(self):
if self is localAvatar:
return True
def setAccountName(self, accountName):
self.accountName = accountName
def setSystemMessage(self, aboutId, chatString, whisperType = WhisperPopup.WTSystem):
self.displayWhisper(aboutId, chatString, whisperType)
def displayWhisper(self, fromId, chatString, whisperType):
print('Whisper type %s from %s: %s' % (whisperType, fromId, chatString))
def displayWhisperPlayer(self, playerId, chatString, whisperType):
print('WhisperPlayer type %s from %s: %s' % (whisperType, playerId, chatString))
def whisperSCTo(self, msgIndex, sendToId, toPlayer):
if toPlayer:
base.cr.playerFriendsManager.sendSCWhisper(sendToId, msgIndex)
else:
messenger.send('wakeup')
self.sendUpdate('setWhisperSCFrom', [self.doId, msgIndex], sendToId)
def setWhisperSCFrom(self, fromId, msgIndex):
handle = base.cr.identifyAvatar(fromId)
if handle == None:
return
if base.cr.avatarFriendsManager.checkIgnored(fromId):
self.d_setWhisperIgnored(fromId)
return
if fromId in self.ignoreList:
self.d_setWhisperIgnored(fromId)
return
chatString = SCDecoders.decodeSCStaticTextMsg(msgIndex)
if chatString:
self.displayWhisper(fromId, chatString, WhisperPopup.WTQuickTalker)
base.talkAssistant.receiveAvatarWhisperSpeedChat(TalkAssistant.SPEEDCHAT_NORMAL, msgIndex, fromId)
return
def whisperSCCustomTo(self, msgIndex, sendToId, toPlayer):
if toPlayer:
base.cr.playerFriendsManager.sendSCCustomWhisper(sendToId, msgIndex)
return
messenger.send('wakeup')
self.sendUpdate('setWhisperSCCustomFrom', [self.doId, msgIndex], sendToId)
def _isValidWhisperSource(self, source):
return True
def setWhisperSCCustomFrom(self, fromId, msgIndex):
handle = base.cr.identifyAvatar(fromId)
if handle == None:
return
if not self._isValidWhisperSource(handle):
self.notify.warning('displayWhisper from non-toon %s' % fromId)
return
if base.cr.avatarFriendsManager.checkIgnored(fromId):
self.d_setWhisperIgnored(fromId)
return
if fromId in self.ignoreList:
self.d_setWhisperIgnored(fromId)
return
chatString = SCDecoders.decodeSCCustomMsg(msgIndex)
if chatString:
self.displayWhisper(fromId, chatString, WhisperPopup.WTQuickTalker)
base.talkAssistant.receiveAvatarWhisperSpeedChat(TalkAssistant.SPEEDCHAT_CUSTOM, msgIndex, fromId)
return
def whisperSCEmoteTo(self, emoteId, sendToId, toPlayer):
print('whisperSCEmoteTo %s %s %s' % (emoteId, sendToId, toPlayer))
if toPlayer:
base.cr.playerFriendsManager.sendSCEmoteWhisper(sendToId, emoteId)
return
messenger.send('wakeup')
self.sendUpdate('setWhisperSCEmoteFrom', [self.doId, emoteId], sendToId)
def setWhisperSCEmoteFrom(self, fromId, emoteId):
handle = base.cr.identifyAvatar(fromId)
if handle == None:
return
if base.cr.avatarFriendsManager.checkIgnored(fromId):
self.d_setWhisperIgnored(fromId)
return
chatString = SCDecoders.decodeSCEmoteWhisperMsg(emoteId, handle.getName())
if chatString:
self.displayWhisper(fromId, chatString, WhisperPopup.WTEmote)
base.talkAssistant.receiveAvatarWhisperSpeedChat(TalkAssistant.SPEEDCHAT_EMOTE, emoteId, fromId)
return
def d_setWhisperIgnored(self, sendToId):
pass
def setChatAbsolute(self, chatString, chatFlags, dialogue = None, interrupt = 1, quiet = 0):
DistributedAvatar.DistributedAvatar.setChatAbsolute(self, chatString, chatFlags, dialogue, interrupt)
if not quiet:
pass
def b_setChat(self, chatString, chatFlags):
if self.cr.wantMagicWords and len(chatString) > 0 and chatString[0] == '~':
messenger.send('magicWord', [chatString])
else:
if base.config.GetBool('want-chatfilter-hacks', 0):
if base.config.GetBool('want-chatfilter-drop-offending', 0):
if badwordpy.test(chatString):
return
else:
chatString = badwordpy.scrub(chatString)
messenger.send('wakeup')
self.setChatAbsolute(chatString, chatFlags)
self.d_setChat(chatString, chatFlags)
def d_setChat(self, chatString, chatFlags):
self.sendUpdate('setChat', [chatString, chatFlags, 0])
def setTalk(self, fromAV, fromAC, avatarName, chat, mods, flags):
newText, scrubbed = self.scrubTalk(chat, mods)
self.displayTalk(newText)
if base.talkAssistant.isThought(newText):
newText = base.talkAssistant.removeThoughtPrefix(newText)
base.talkAssistant.receiveThought(fromAV, avatarName, fromAC, None, newText, scrubbed)
else:
base.talkAssistant.receiveOpenTalk(fromAV, avatarName, fromAC, None, newText, scrubbed)
return
def setTalkWhisper(self, fromAV, fromAC, avatarName, chat, mods, flags):
newText, scrubbed = self.scrubTalk(chat, mods)
self.displayTalkWhisper(fromAV, avatarName, chat, mods)
base.talkAssistant.receiveWhisperTalk(fromAV, avatarName, fromAC, None, self.doId, self.getName(), newText, scrubbed)
return
def displayTalkWhisper(self, fromId, avatarName, chatString, mods):
print('TalkWhisper from %s: %s' % (fromId, chatString))
def scrubTalk(self, chat, mods):
return chat
def setChat(self, chatString, chatFlags, DISLid):
self.notify.error('Should call setTalk')
chatString = base.talkAssistant.whiteListFilterMessage(chatString)
if base.cr.avatarFriendsManager.checkIgnored(self.doId):
return
if base.localAvatar.garbleChat and not self.isUnderstandable():
chatString = self.chatGarbler.garble(self, chatString)
chatFlags &= ~(CFQuicktalker | CFPageButton | CFQuitButton)
if chatFlags & CFThought:
chatFlags &= ~(CFSpeech | CFTimeout)
else:
chatFlags |= CFSpeech | CFTimeout
self.setChatAbsolute(chatString, chatFlags)
def b_setSC(self, msgIndex):
self.setSC(msgIndex)
self.d_setSC(msgIndex)
def d_setSC(self, msgIndex):
messenger.send('wakeup')
self.sendUpdate('setSC', [msgIndex])
def setSC(self, msgIndex):
if base.cr.avatarFriendsManager.checkIgnored(self.doId):
return
if self.doId in base.localAvatar.ignoreList:
return
chatString = SCDecoders.decodeSCStaticTextMsg(msgIndex)
if chatString:
self.setChatAbsolute(chatString, CFSpeech | CFQuicktalker | CFTimeout, quiet=1)
base.talkAssistant.receiveOpenSpeedChat(TalkAssistant.SPEEDCHAT_NORMAL, msgIndex, self.doId)
def b_setSCCustom(self, msgIndex):
self.setSCCustom(msgIndex)
self.d_setSCCustom(msgIndex)
def d_setSCCustom(self, msgIndex):
messenger.send('wakeup')
self.sendUpdate('setSCCustom', [msgIndex])
def setSCCustom(self, msgIndex):
if base.cr.avatarFriendsManager.checkIgnored(self.doId):
return
if self.doId in base.localAvatar.ignoreList:
return
chatString = SCDecoders.decodeSCCustomMsg(msgIndex)
if chatString:
self.setChatAbsolute(chatString, CFSpeech | CFQuicktalker | CFTimeout)
base.talkAssistant.receiveOpenSpeedChat(TalkAssistant.SPEEDCHAT_CUSTOM, msgIndex, self.doId)
def b_setSCEmote(self, emoteId):
self.b_setEmoteState(emoteId, animMultiplier=self.animMultiplier)
def d_friendsNotify(self, avId, status):
self.sendUpdate('friendsNotify', [avId, status])
def friendsNotify(self, avId, status):
avatar = base.cr.identifyFriend(avId)
if avatar != None:
if status == 1:
self.setSystemMessage(avId, OTPLocalizer.WhisperNoLongerFriend % avatar.getName())
elif status == 2:
self.setSystemMessage(avId, OTPLocalizer.WhisperNowSpecialFriend % avatar.getName())
return
def d_teleportQuery(self, requesterId, sendToId = None):
teleportNotify.debug('sending teleportQuery%s' % ((requesterId, sendToId),))
self.sendUpdate('teleportQuery', [requesterId], sendToId)
def teleportQuery(self, requesterId):
teleportNotify.debug('receieved teleportQuery(%s)' % requesterId)
avatar = base.cr.playerFriendsManager.identifyFriend(requesterId)
if avatar != None:
teleportNotify.debug('avatar is not None')
if base.cr.avatarFriendsManager.checkIgnored(requesterId):
teleportNotify.debug('avatar ignored via avatarFriendsManager')
self.d_teleportResponse(self.doId, 2, 0, 0, 0, sendToId=requesterId)
return
if requesterId in self.ignoreList:
teleportNotify.debug('avatar ignored via ignoreList')
self.d_teleportResponse(self.doId, 2, 0, 0, 0, sendToId=requesterId)
return
if hasattr(base, 'distributedParty'):
if base.distributedParty.partyInfo.isPrivate:
if requesterId not in base.distributedParty.inviteeIds:
teleportNotify.debug('avatar not in inviteeIds')
self.d_teleportResponse(self.doId, 0, 0, 0, 0, sendToId=requesterId)
return
if base.distributedParty.isPartyEnding:
teleportNotify.debug('party is ending')
self.d_teleportResponse(self.doId, 0, 0, 0, 0, sendToId=requesterId)
return
if self.__teleportAvailable and not self.ghostMode and base.config.GetBool('can-be-teleported-to', 1):
teleportNotify.debug('teleport initiation successful')
self.setSystemMessage(requesterId, OTPLocalizer.WhisperComingToVisit % avatar.getName())
messenger.send('teleportQuery', [avatar, self])
return
teleportNotify.debug('teleport initiation failed')
if self.failedTeleportMessageOk(requesterId):
self.setSystemMessage(requesterId, OTPLocalizer.WhisperFailedVisit % avatar.getName())
teleportNotify.debug('sending try-again-later message')
self.d_teleportResponse(self.doId, 0, 0, 0, 0, sendToId=requesterId)
return
def failedTeleportMessageOk(self, fromId):
now = globalClock.getFrameTime()
lastTime = self.lastFailedTeleportMessage.get(fromId, None)
if lastTime != None:
elapsed = now - lastTime
if elapsed < self.TeleportFailureTimeout:
return 0
self.lastFailedTeleportMessage[fromId] = now
return 1
def d_teleportResponse(self, avId, available, shardId, hoodId, zoneId, sendToId = None):
teleportNotify.debug('sending teleportResponse%s' % ((avId,
available,
shardId,
hoodId,
zoneId,
sendToId),))
self.sendUpdate('teleportResponse', [avId,
available,
shardId,
hoodId,
zoneId], sendToId)
def teleportResponse(self, avId, available, shardId, hoodId, zoneId):
teleportNotify.debug('received teleportResponse%s' % ((avId,
available,
shardId,
hoodId,
zoneId),))
messenger.send('teleportResponse', [avId,
available,
shardId,
hoodId,
zoneId])
def d_teleportGiveup(self, requesterId, sendToId = None):
teleportNotify.debug('sending teleportGiveup(%s) to %s' % (requesterId, sendToId))
self.sendUpdate('teleportGiveup', [requesterId], sendToId)
def teleportGiveup(self, requesterId):
teleportNotify.debug('received teleportGiveup(%s)' % (requesterId,))
avatar = base.cr.identifyAvatar(requesterId)
if not self._isValidWhisperSource(avatar):
self.notify.warning('teleportGiveup from non-toon %s' % requesterId)
return
if avatar != None:
self.setSystemMessage(requesterId, OTPLocalizer.WhisperGiveupVisit % avatar.getName())
return
def b_teleportGreeting(self, avId):
self.d_teleportGreeting(avId)
self.teleportGreeting(avId)
def d_teleportGreeting(self, avId):
self.sendUpdate('teleportGreeting', [avId])
def teleportGreeting(self, avId):
avatar = base.cr.getDo(avId)
if isinstance(avatar, Avatar.Avatar):
self.setChatAbsolute(OTPLocalizer.TeleportGreeting % avatar.getName(), CFSpeech | CFTimeout)
elif avatar is not None:
self.notify.warning('got teleportGreeting from %s referencing non-toon %s' % (self.doId, avId))
return
def setTeleportAvailable(self, available):
self.__teleportAvailable = available
def getTeleportAvailable(self):
return self.__teleportAvailable
def getFriendsList(self):
return self.friendsList
def setFriendsList(self, friendsList):
self.oldFriendsList = self.friendsList
self.friendsList = friendsList
self.timeFriendsListChanged = globalClock.getFrameTime()
messenger.send('friendsListChanged')
Avatar.reconsiderAllUnderstandable()
def setDISLname(self, name):
self.DISLname = name
def setDISLid(self, id):
self.DISLid = id
def setAutoRun(self, value):
self.autoRun = value
def getAutoRun(self):
return self.autoRun