toontown-just-works/toontown/uberdog/DistributedPartyManagerAI.py
2024-07-07 18:08:39 -05:00

288 lines
11 KiB
Python

from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from direct.task import Task
from otp.distributed.OtpDoGlobals import *
from panda3d.core import *
from toontown.parties.DistributedPartyAI import DistributedPartyAI
from datetime import datetime
from toontown.parties.PartyGlobals import *
from otp.ai.MagicWordGlobal import *
class DistributedPartyManagerAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedPartyManagerAI")
def announceGenerate(self):
DistributedObjectAI.announceGenerate(self)
self.partyId2Zone = {}
self.partyId2PlanningZone = {}
self.partyId2Host = {}
self.host2PartyId = {}
self.avId2PartyId = {}
self.id2Party = {}
self.pubPartyInfo = {}
self.idPool = range(self.air.ourChannel, self.air.ourChannel + 100000)
# get 100 ids at the start and top up
#taskMgr.doMethodLater(0, self.__getIds, 'DistributedPartyManagerAI___getIds')
def receiveId(self, ids):
self.idPool += ids
# def __getIds(self, task):
# if len(self.idPool) < 50:
# self.air.globalPartyMgr.allocIds(100 - len(self.idPool))
# taskMgr.doMethodLater(180, self.__getIds, 'DistributedPartyManagerAI___getIds')
def _makePartyDict(self, struct):
PARTY_TIME_FORMAT = '%Y-%m-%d %H:%M:%S'
party = {}
party['partyId'] = struct[0]
party['hostId'] = struct[1]
start = '%s-%s-%s %s:%s:00' % (struct[2], struct[3], struct[4], struct[5], struct[6])
party['start'] = datetime.strptime(start, PARTY_TIME_FORMAT)
end = '%s-%s-%s %s:%s:00' % (struct[7], struct[8], struct[9], struct[10], struct[11])
party['end'] = datetime.strptime(end, PARTY_TIME_FORMAT)
party['isPrivate'] = struct[12]
party['inviteTheme'] = struct[13]
party['activities'] = struct[14]
party['decorations'] = struct[15]
# struct[16] = partystatus
return party
# Management stuff
def partyManagerUdStartingUp(self):
# This is sent in reply to the GPMAI's hello
self.notify.info("uberdog has said hello")
def partyManagerUdLost(self):
# well fuck. ud died.
self.notify.warning("uberdog lost!")
def canBuyParties(self):
return True
def addPartyRequest(self, hostId, startTime, endTime, isPrivate, inviteTheme, activities, decorations, inviteeIds):
if hostId != simbase.air.getAvatarIdFromSender():
self.air.writeServerEvent('suspicious',simbase.air.getAvatarIdFromSender(),'Toon tried to create a party as someone else!')
return
print 'party requested: host %s, start %s, end %s, private %s, invitetheme %s, activities omitted, decor omitted, invitees %s' % (hostId, startTime, endTime, isPrivate, inviteTheme, inviteeIds)
simbase.air.globalPartyMgr.sendAddParty(hostId, self.host2PartyId[hostId], startTime, endTime, isPrivate, inviteTheme, activities, decorations, inviteeIds)
def addPartyResponseUdToAi(self, partyId, errorCode, partyStruct):
avId = partyStruct[1]
print 'responding to client now that ud got back to us'
self.sendUpdateToAvatarId(avId, 'addPartyResponse', [avId, errorCode])
# We also need to remember to update the field on the DToon indicating parties he's hosting
self.air.doId2do[avId].sendUpdate('setHostedParties', [[partyStruct]])
pass
def markInviteAsReadButNotReplied(self, todo0, todo1):
pass
def respondToInvite(self, todo0, todo1, todo2, todo3, todo4):
pass
def respondToInviteResponse(self, todo0, todo1, todo2, todo3, todo4):
pass
def changePrivateRequest(self, todo0, todo1):
pass
def changePrivateRequestAiToUd(self, todo0, todo1, todo2):
pass
def changePrivateResponseUdToAi(self, todo0, todo1, todo2, todo3):
pass
def changePrivateResponse(self, todo0, todo1, todo2):
pass
def changePartyStatusRequest(self, partyId, newPartyStatus):
pass
def changePartyStatusRequestAiToUd(self, todo0, todo1, todo2):
pass
def changePartyStatusResponseUdToAi(self, todo0, todo1, todo2, todo3):
pass
def changePartyStatusResponse(self, todo0, todo1, todo2, todo3):
pass
def partyInfoOfHostFailedResponseUdToAi(self, todo0):
pass
def givePartyRefundResponse(self, todo0, todo1, todo2, todo3, todo4):
pass
def getPartyZone(self, hostId, zoneId, isAvAboutToPlanParty):
self.notify.debug('getPartyZone(hostId = %s, zoneId = %s, isAboutToPlan = %s' % (hostId, zoneId, isAvAboutToPlanParty))
avId = self.air.getAvatarIdFromSender()
if isAvAboutToPlanParty:
partyId = self.idPool.pop()
print 'pid %s' % partyId
self.partyId2Host[partyId] = hostId
self.partyId2PlanningZone[partyId] = zoneId
self.host2PartyId[hostId] = partyId
print 'Responding to a get party zone when planning, av,party,zone: %s %s %s' % (avId, partyId, zoneId)
else:
if hostId not in self.host2PartyId:
# Uhh, we don't know if the host even has a party. Better ask the ud
self.air.globalPartyMgr.queryPartyForHost(hostId)
print 'querying for details against hostId %s ' % hostId
return
partyId = self.host2PartyId[hostId]
# Is the party already running?
if partyId in self.partyId2Zone:
# Yep!
zoneId = self.partyId2Zone[partyId]
else:
self.notify.warning("getPartyZone did not match a case!")
self.sendUpdateToAvatarId(avId, 'receivePartyZone', [hostId, partyId, zoneId])
def partyInfoOfHostResponseUdToAi(self, partyStruct, inviteeIds):
party = self._makePartyDict(partyStruct)
av = self.air.doId2do.get(party['hostId'], None)
if not av:
return # The host isn't on the district... wat do
party['inviteeIds'] = inviteeIds
partyId = party['partyId']
# This is issued in response to a request for the party to start, essentially. So let's alloc a zone
zoneId = self.air.allocateZone()
self.partyId2Zone[partyId] = zoneId
self.host2PartyId[party['hostId']] = partyId
# We need to setup the party itself on our end, so make an ai party
partyAI = DistributedPartyAI(self.air, party['hostId'], zoneId, party)
partyAI.generateWithRequiredAndId(self.air.allocateChannel(), self.air.districtId, zoneId)
self.id2Party[partyId] = partyAI
# Alert the UD
self.air.globalPartyMgr.d_partyStarted(partyId, self.air.ourChannel, zoneId, av.getName())
# Don't forget this was initially started by a getPartyZone, so we better tell the host the partyzone
self.sendUpdateToAvatarId(party['hostId'], 'receivePartyZone', [party['hostId'], partyId, zoneId])
# And last, set up our cleanup stuff
taskMgr.doMethodLater(PARTY_DURATION, self.closeParty, 'DistributedPartyManagerAI_cleanup%s' % partyId, [partyId])
def closeParty(self, partyId):
partyAI = self.id2Party[partyId]
self.air.globalPartyMgr.d_partyDone(partyId)
for av in partyAI.avIdsAtParty:
self.sendUpdateToAvatarId(av, 'sendAvToPlayground', [av, 0])
partyAI.b_setPartyState(PartyStatus.Finished)
taskMgr.doMethodLater(10, self.__deleteParty, 'closeParty%d' % partyId, extraArgs=[partyId])
def __deleteParty(self, partyId):
partyAI = self.id2Party[partyId]
for av in partyAI.avIdsAtParty:
self.sendUpdateToAvatarId(av, 'sendAvToPlayground', [av, 1])
partyAI.requestDelete()
zoneId = self.partyId2Zone[partyId]
del self.partyId2Zone[partyId]
del self.id2Party[partyId]
del self.pubPartyInfo[partyId]
self.air.deallocateZone(zoneId)
def freeZoneIdFromPlannedParty(self, hostId, zoneId):
sender = self.air.getAvatarIdFromSender()
# Only the host of a party can free its zone
if sender != hostId:
self.air.writeServerEvent('suspicious',sender,'Toon tried to free zone for someone else\'s party!')
return
partyId = self.host2PartyId[hostId]
if partyId in self.partyId2PlanningZone:
self.air.deallocateZone(self.partyId2PlanningZone[partyId])
del self.partyId2PlanningZone[partyId]
del self.host2PartyId[hostId]
del self.partyId2Host[partyId]
return
def sendAvToPlayground(self, todo0, todo1):
pass
def exitParty(self, partyZone):
avId = simbase.air.getAvatarIdFromSender()
for partyInfo in self.pubPartyInfo.values():
if partyInfo['zoneId'] == partyZone:
party = self.id2Party.get(partyInfo['partyId'])
if party:
party._removeAvatar(avId)
def removeGuest(self, ownerId, avId):
pass
def partyManagerAIStartingUp(self, todo0, todo1):
pass
def partyManagerAIGoingDown(self, todo0, todo1):
pass
def toonHasEnteredPartyAiToUd(self, todo0):
pass
def toonHasExitedPartyAiToUd(self, todo0):
pass
def partyHasFinishedUdToAllAi(self, partyId):
# FIXME I bet i have to do some cleanup
del self.pubPartyInfo[partyId]
def updateToPublicPartyInfoUdToAllAi(self, shardId, zoneId, partyId, hostId, numGuests, maxGuests, hostName, activities, minLeft):
# The uberdog is informing us of a public party.
# Note that we never update the publicPartyInfo of our own parties without going through the UD. It's just good practice :)
started = None
self.pubPartyInfo[partyId] = {
'shardId': shardId,
'zoneId': zoneId,
'partyId': partyId,
'hostId': hostId,
'numGuests': numGuests,
'maxGuests': maxGuests,
'hostName': hostName,
'minLeft': minLeft,
'started': datetime.now(),
'activities': activities }
def updateToPublicPartyCountUdToAllAi(self, partyCount, partyId):
# Update the number of guests at a party
if partyId in self.pubPartyInfo.keys():
self.pubPartyInfo[partyId]['numGuests'] = partyCount
def getPublicParties(self):
p = []
for partyId in self.pubPartyInfo:
party = self.pubPartyInfo[partyId]
# calculate time left
minLeft = party['minLeft'] - int((datetime.now() - party['started']).seconds / 60)
#less band-aidy bandaid
guests = party.get('numGuests', 0)
if guests > 255:
guests = 255
elif guests < 0:
guests = 0
p.append([party['shardId'], party['zoneId'], guests, party.get('hostName', ''), party.get('activities', []), minLeft])
return p
def requestShardIdZoneIdForHostId(self, todo0):
pass
def sendShardIdZoneIdToAvatar(self, todo0, todo1):
pass
def updateAllPartyInfoToUd(self, todo0, todo1, todo2, todo3, todo4, todo5, todo6, todo7, todo8):
pass
def forceCheckStart(self):
pass
def requestMw(self, todo0, todo1, todo2, todo3):
pass
def mwResponseUdToAllAi(self, todo0, todo1, todo2, todo3):
pass