Top Toons

This commit is contained in:
Loudrob 2015-07-20 13:16:39 -04:00
parent cf319c587b
commit c93fec2f19
16 changed files with 320 additions and 17 deletions

View file

@ -4,6 +4,7 @@ from otp.ai.MagicWordGlobal import *
from toontown.fishing import FishGlobals
from toontown.fishing.FishBase import FishBase
from toontown.toonbase import TTLocalizer
from toontown.uberdog import TopToonsGlobals
class FishManagerAI:
@ -66,6 +67,7 @@ class FishManagerAI:
av.fishTank.addFish(fish)
netlist = av.fishTank.getNetLists()
av.d_setFishTank(netlist[0], netlist[1], netlist[2])
messenger.send('topToonsManager-event', [av.doId, TopToonsGlobals.CAT_FISH, 1])
return [itemType, genus, species, weight]
elif itemType == FishGlobals.BootItem:
return [itemType, 0, 0, 0]
@ -89,6 +91,7 @@ class FishManagerAI:
av.fishTank.addFish(fish)
netlist = av.fishTank.getNetLists()
av.d_setFishTank(netlist[0], netlist[1], netlist[2])
messenger.send('topToonsManager-event', [av.doId, TopToonsGlobals.CAT_FISH, 1])
return [itemType, genus, species, weight]
else:
money = FishGlobals.Rod2JellybeanDict[av.getFishingRod()]

View file

@ -3,7 +3,7 @@ from toontown.building import FADoorCodes
from otp.ai.MagicWordGlobal import *
from toontown.hood import ZoneUtil
from toontown.quest import Quests
from toontown.uberdog import TopToonsGlobals
QuestIdIndex = 0
QuestFromNpcIdIndex = 1
@ -75,6 +75,7 @@ class QuestManagerAI:
# If they've completed a quest.
if completeStatus == Quests.COMPLETE:
# ToonUp the toon to max health.
messenger.send('topToonsManager-event', [av.doId, TopToonsGlobals.CAT_TASKS, 1])
av.toonUp(av.maxHp)
# If it's a TrackChoiceQuest then present their track choices.
@ -437,6 +438,7 @@ class QuestManagerAI:
def toonKilledBuilding(self, av, type, difficulty, floors, zoneId, cogdo):
# Get the avatars current quests.
messenger.send('topToonsManager-event', [av.doId, TopToonsGlobals.CAT_BLDG, 1])
avQuests = av.getQuests()
questList = []
zoneId = ZoneUtil.getBranchZone(zoneId)
@ -491,6 +493,7 @@ class QuestManagerAI:
def toonKilledCogs(self, av, suitsKilled, zoneId):
# Get the avatar's current quests.
messenger.send('topToonsManager-event', [av.doId, TopToonsGlobals.CAT_COGS, len(suitsKilled)])
avQuests = av.getQuests()
questList = []

View file

@ -51,6 +51,7 @@ from toontown.toon import NPCToons
from toontown.toonbase import ToontownGlobals
from toontown.tutorial.TutorialManagerAI import TutorialManagerAI
from toontown.uberdog.DistributedPartyManagerAI import DistributedPartyManagerAI
from toontown.uberdog.DistributedTopToonsManagerAI import DistributedTopToonsManagerAI
#from toontown.uberdog.DistributedLobbyManagerAI import DistributedLobbyManagerAI
class ToontownAIRepository(ToontownInternalRepository):
@ -72,6 +73,7 @@ class ToontownAIRepository(ToontownInternalRepository):
self.lawOfficeMgr = None
self.countryClubMgr = None
self.groupManager = GroupManagerAI(self)
self.topToonsMgr = DistributedTopToonsManagerAI(self)
self.zoneAllocator = UniqueIdAllocator(ToontownGlobals.DynamicZonesBegin,
ToontownGlobals.DynamicZonesEnd)
@ -103,7 +105,7 @@ class ToontownAIRepository(ToontownInternalRepository):
self.tutorialManager.generateWithRequired(2)
self.friendManager = FriendManagerAI(self)
self.friendManager.generateWithRequired(2)
self.questManager = QuestManagerAI(self)
self.questManager = QuestManagerAI(self)
self.banManager = BanManagerAI.BanManagerAI(self)
self.suitInvasionManager = SuitInvasionManagerAI(self)
self.blackCatMgr = DistributedBlackCatMgrAI(self)

View file

@ -6,6 +6,7 @@ from panda3d.core import *
from direct.fsm.FSM import FSM
from toontown.ai.ToonBarrier import *
from toontown.golf import GolfGlobals
from toontown.uberdog import TopToonsGlobals
INITIAL = 0
EXITED = 1
EXPECTED = 2
@ -970,12 +971,17 @@ class DistributedGolfCourseAI(DistributedObjectAI.DistributedObjectAI, FSM):
stillPlaying = self.getStillPlayingAvIds()
for avId in stillPlaying:
scoreList = self.scores[avId]
ns = 0
for holeIndex in xrange(len(scoreList)):
strokes = scoreList[holeIndex]
if strokes == 1:
ns +=1
holeId = self.holeIds[holeIndex]
self.air.writeServerEvent('golf_ace', avId, '%d|%d|%s' % (self.courseId, holeId, stillPlaying))
if ns:
messenger.send('topToonsManager-event', [avId, TopToonsGlobals.CAT_HOLE_IN_ONE, ns])
def recordCourseUnderPar(self):
coursePar = self.calcCoursePar()
stillPlaying = self.getStillPlayingAvIds()
@ -984,7 +990,8 @@ class DistributedGolfCourseAI(DistributedObjectAI.DistributedObjectAI, FSM):
netScore = totalScore - coursePar
if netScore < 0:
self.air.writeServerEvent('golf_underPar', avId, '%d|%d|%s' % (self.courseId, netScore, stillPlaying))
messenger.send('topToonsManager-event', [avId, TopToonsGlobals.CAT_COURSE_UNDER_PAR, 1])
def addAimTime(self, avId, aimTime):
if avId in self.aimTimes:
self.aimTimes[avId] += aimTime

View file

@ -20,7 +20,7 @@ import DistributedTwoDGameAI
import DistributedVineGameAI
from otp.ai.MagicWordGlobal import *
from toontown.toonbase import ToontownGlobals
from toontown.uberdog import TopToonsGlobals
simbase.forcedMinigameId = simbase.config.GetInt('force-minigame', 0)
RequestMinigame = {}
@ -84,6 +84,8 @@ def createMinigame(air, playerArray, trolleyZone, minigameZone=None,
toon = simbase.air.doId2do.get(doId)
if toon is not None:
toons.append(toon)
for toon in toons:
messenger.send('topToonsManager-event', [toon.doId, TopToonsGlobals.CAT_TROLLEY, 1])
for toon in toons:
simbase.air.questManager.toonPlayedMinigame(toon, toons)
retVal = {}

View file

@ -3,6 +3,7 @@ from direct.distributed.ClockDelta import *
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from direct.fsm.FSM import FSM
from direct.task import Task
from toontown.uberdog import TopToonsGlobals
import random
from toontown.racing import RaceGlobals
@ -320,6 +321,8 @@ class DistributedRaceAI(DistributedObjectAI, FSM):
self.sendUpdate('setPlace', [avId, totalTime, place, entryFee, qualify, max((winnings-entryFee), 0), bonus, trophies, [], 0])
def calculateTrophies(self, avId, won, qualify, time):
if won:
messenger.send('topToonsManager-event', [avId, TopToonsGlobals.CAT_RACE_WON, 1])
av = self.air.doId2do[avId]
kartingHistory = av.getKartingHistory()
avTrophies = av.getKartingTrophies()

View file

@ -145,6 +145,10 @@ class DistributedBossCogAI(DistributedAvatarAI.DistributedAvatarAI):
def d_setBattleExperience(self):
self.sendUpdate('setBattleExperience', self.getBattleExperience())
for toonId in self.involvedToons:
toon = simbase.air.doId2do.get(toonId)
if toon:
self.air.topToonsMgr.toonKilledBoss(toon, self.BossName)
def getBattleExperience(self):
result = BattleExperienceAI.getBattleExperience(8, self.involvedToons, self.toonExp, self.toonSkillPtsGained, self.toonOrigQuests, self.toonItems, self.toonOrigMerits, self.toonMerits, self.toonParts, self.suitsKilled, self.helpfulToons)

View file

@ -28,6 +28,7 @@ class DistributedBossbotBossAI(DistributedBossCogAI.DistributedBossCogAI, FSM.FS
2,
3,
4]
BossName = "CEO"
def __init__(self, air):
DistributedBossCogAI.DistributedBossCogAI.__init__(self, air, 'c')

View file

@ -17,6 +17,7 @@ import math
class DistributedCashbotBossAI(DistributedBossCogAI.DistributedBossCogAI, FSM.FSM):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedCashbotBossAI')
maxGoons = 8
BossName = "CFO"
def __init__(self, air):
DistributedBossCogAI.DistributedBossCogAI.__init__(self, air, 'm')

View file

@ -29,6 +29,7 @@ class DistributedLawbotBossAI(DistributedBossCogAI.DistributedBossCogAI, FSM.FSM
hitCountDamage = 35
numPies = 10
maxToonLevels = 77
BossName = "CJ"
def __init__(self, air):
DistributedBossCogAI.DistributedBossCogAI.__init__(self, air, 'l')

View file

@ -20,6 +20,7 @@ class DistributedSellbotBossAI(DistributedBossCogAI.DistributedBossCogAI, FSM.FS
limitHitCount = 6
hitCountDamage = 35
numPies = ToontownGlobals.FullPies
BossName = "VP"
def __init__(self, air):
DistributedBossCogAI.DistributedBossCogAI.__init__(self, air, 's')

View file

@ -32,6 +32,7 @@ from toontown.toonbase import TTLocalizer, ToontownBattleGlobals, ToontownGlobal
from toontown.toonbase.ToontownGlobals import *
from NPCToons import npcFriends
import Experience, InventoryBase, ToonDNA, random, time
from toontown.uberdog import TopToonsGlobals
if simbase.wantPets:
from toontown.pets import PetLookerAI, PetObserve
@ -2271,6 +2272,8 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo
return self.maxBankMoney
def addMoney(self, deltaMoney):
if deltaMoney > 0:
messenger.send('topToonsManager-event', [self.doId, TopToonsGlobals.CAT_JELLYBEAN, deltaMoney])
money = deltaMoney + self.money
pocketMoney = min(money, self.maxMoney)
self.b_setMoney(pocketMoney)

View file

@ -0,0 +1,32 @@
from direct.distributed.DistributedObjectAI import *
from direct.showbase.DirectObject import *
import TopToonsGlobals
class DistributedTopToonsManagerAI(DirectObject):
def __init__(self, air):
self.air = air
self.accept('topToonsManager-event', self.__handleEvent)
def toonKilledBoss(self, av, boss):
cat = {'VP': TopToonsGlobals.CAT_VP,
'CFO': TopToonsGlobals.CAT_CFO,
'CJ': TopToonsGlobals.CAT_CJ,
'CEO': TopToonsGlobals.CAT_CEO}.get(boss, 0)
self.__handleEvent(av.doId, cat, 1)
def __handleEvent(self, *args): # avId, categories, score
self.air.sendNetEvent('topToonsManager-AI-score-site', list(args))
from otp.ai.MagicWordGlobal import *
@magicWord(types=[int, int])
def topToon(score, cat=TopToonsGlobals._CAT_ALL):
av = spellbook.getTarget()
mgr = av.air.topToonsMgr
if not mgr:
return 'No manager!'
if cat > TopToonsGlobals._CAT_ALL:
return 'Max value: %d' % TopToonsGlobals._CAT_ALL
messenger.send('topToonsManager-event', [av.doId, cat, score])

View file

@ -0,0 +1,247 @@
# CLEANUP IMPORTS
from direct.directnotify import DirectNotifyGlobal
from direct.fsm.FSM import FSM
from direct.distributed.DistributedObjectUD import *
from direct.showbase.DirectObject import *
from toontown.toon.ToonDNA import ToonDNA, getSpeciesName
import TopToonsGlobals
import time, cPickle, random
import datetime, json
import urllib
import urllib2
import hashlib
def getCurrentMonth():
dt = datetime.date.today()
month = dt.month
year = dt.year
return year * 100 + month
def getPrevMonth():
current = getCurrentMonth()
year, month = divmod(current, 100)
month -= 1
if not month:
month = 12
year -= 1
return year * 100 + month
def getNextMonth():
current = getCurrentMonth()
year, month = divmod(current, 100)
month += 1
if month > 12:
month = 1
year += 1
return year * 100 + month
def timeToNextMonth():
now = datetime.datetime.now()
year, month = divmod(getNextMonth(), 100)
return (datetime.datetime(year, month, 1) - now).total_seconds()
def getEmptySiteToonsColl(month):
coll = {}
start = TopToonsGlobals._CAT_BEGIN
end = TopToonsGlobals._CAT_END
while start <= end:
coll[str(start)] = {}
start *= 2
coll['month'] = month
return coll
class SiteUploadFSM(FSM):
notify = DirectNotifyGlobal.directNotify.newCategory('SiteUploadFSM')
URL = config.GetString('toptoons-api-endpoint', 'http://toontownstride.com/toptoons/post/') # Let's hope jumbleweed hasn't changed this
def __init__(self, mgr, data):
FSM.__init__(self, 'SiteUploadFSM')
self.mgr = mgr
self.data = {}
self.month = data.pop('month')
for category, avs in data.items():
self.data[int(category)] = sorted(avs.items(), key=lambda x: -x[1])
self.__cat = TopToonsGlobals._CAT_BEGIN
self.__responses = {}
self.__cache = {}
self.__waiting = {}
self.__dataToSend = {}
self.__failures = -1
self.demand('QueryAvatars')
def enterQueryAvatars(self):
avs = self.data[self.__cat]
cutoff = self.__failures
if cutoff == -1:
cutoff = 5
selected, remaining = avs[:cutoff], avs[cutoff:]
self.data[self.__cat] = remaining
self.__waiting = {int(x[0]): x[1] for x in selected}
avIds = self.__waiting.keys()
for avId in avIds:
if avId in self.__cache:
self.__responses[avId] = (self.__cache[avId][0], self.__waiting.pop(avId))
self.__failures = 0
for avId in self.__waiting:
def response(x, y, avId=avId):
self.__handleToon(avId, x, y)
self.mgr.air.dbInterface.queryObject(self.mgr.air.dbId, avId, response)
if not self.__waiting:
self.demand('SortResults')
def __handleToon(self, avId, dclass, fields):
if avId not in self.__waiting:
return
if dclass != self.mgr.air.dclassesByName['DistributedToonUD']:
self.__failures += 1
self.notify.warning('%d query failed!' % avId)
del self.__waiting[avId]
if not self.__waiting:
self.demand('QueryAvatars')
return
name = fields['setName'][0]
hp = fields['setMaxHp'][0]
dna = ToonDNA(fields['setDNAString'][0])
species = getSpeciesName(dna.head)
color = dna.headColor
if species == 'pig':
dna = 'pig'
else:
if species == 'cat' and color == 26:
dna = 'blackcat'
else:
if color > 23:
color = 0
dna = '%s_%s_%d' % (species, dna.head[1:], color)
self.__responses[avId] = ((name, dna, hp), self.__waiting.pop(avId))
if not self.__waiting:
self.demand('QueryAvatars')
def enterSortResults(self):
responses = sorted(self.__responses.values(), key=lambda x: -x[-1])
self.__dataToSend[self.__cat] = responses
self.__cache.update(self.__responses)
self.__failures = -1
self.__responses = {}
self.__cat *= 2
if self.__cat * 2 == TopToonsGlobals._CAT_END:
self.demand('Upload')
return
self.demand('QueryAvatars')
def enterUpload(self):
self.__dataToSend['month'] = self.month
(success, error), res = self.post(self.URL, self.__dataToSend)
print (success, error), res
def post(self, url, data):
headers = {'User-Agent' : 'TTUberAgent'}
innerData = json.dumps(data)
hmac = hashlib.sha512(innerData + self.mgr.air.getApiKey()).hexdigest() # XXX PROVIDE THE KEY HERE
data = 'data=%s' % urllib.quote(innerData)
data += '&hmac=%s' % urllib.quote(hmac)
success = True
error = None
res = {}
try:
req = urllib2.Request(url, data, headers)
res = json.loads(urllib2.urlopen(req).read())
success = res['success']
error = res.get('error')
except Exception as e:
if hasattr(e, 'read'):
with open('../e.html', 'wb') as f:
f.write(e.read())
success = False
error = str(e)
return (success, error), res
class DistributedTopToonsManagerUD(DirectObject):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedTopToonsManagerUD')
def __init__(self, air):
self.air = air
self.__curMonth = getCurrentMonth()
coll = None
if self.air.dbConn:
coll = self.air.dbGlobalCursor.strideToons.find_one({'month': self.__curMonth})
if not coll:
lastMonthColl = self.air.dbGlobalCursor.strideToons.find_one({'month': getPrevMonth()})
if lastMonthColl:
self.__uploadLastMonth(lastMonthColl)
if not coll:
coll = getEmptySiteToonsColl(self.__curMonth)
self.__topToonsData = coll
self.__topToonsData.pop('_id', None)
self.accept('topToonsManager-AI-score-site', self.__topToonsScore)
self.waitForNextMonth()
def __uploadLastMonth(self, data):
self.notify.info('Sending last month result to site...')
SiteUploadFSM(self, data)
def waitForNextMonth(self):
def _nm(task):
self.__uploadLastMonth(self.__topToonsData)
self.__curMonth = getCurrentMonth()
self.__topToonsData = getEmptySiteToonsColl(self.__curMonth)
self.waitForNextMonth()
return task.done
taskMgr.doMethodLater(timeToNextMonth() + 1, _nm, 'DistributedTopToonsManagerUD-nextMonth')
def saveSite(self):
if self.air.dbConn:
self.air.dbGlobalCursor.strideToons.update({'month': self.__curMonth}, {'$set': self.__topToonsData}, upsert=True)
def __topToonsScore(self, avId, categories, score):
def _add(cat):
cd = self.__topToonsData[str(cat)]
cd[str(avId)] = cd.get(str(avId), 0) + score
start = TopToonsGlobals._CAT_BEGIN
end = TopToonsGlobals._CAT_END
while start <= end:
if categories & start:
_add(start)
start *= 2
self.saveSite()

View file

@ -4,28 +4,16 @@ from otp.distributed.OtpDoGlobals import *
from otp.distributed.DistributedDirectoryAI import DistributedDirectoryAI
from toontown.distributed.ToontownInternalRepository import ToontownInternalRepository
import toontown.minigame.MinigameCreatorAI
from toontown.uberdog.DistributedTopToonsManagerUD import DistributedTopToonsManagerUD
if config.GetBool('want-rpc-server', False):
from toontown.rpc.ToontownRPCServer import ToontownRPCServer
from toontown.rpc.ToontownRPCHandler import ToontownRPCHandler
if config.GetBool('want-mongo-client', False):
import pymongo
class ToontownUberRepository(ToontownInternalRepository):
def __init__(self, baseChannel, serverId):
ToontownInternalRepository.__init__(self, baseChannel, serverId, dcSuffix='UD')
if config.GetBool('want-mongo-client', False):
url = config.GetString('mongodb-url', 'mongodb://localhost')
replicaset = config.GetString('mongodb-replicaset', '')
if replicaset:
self.mongo = pymongo.MongoClient(url, replicaset=replicaset)
else:
self.mongo = pymongo.MongoClient(url)
db = (urlparse.urlparse(url).path or '/test')[1:]
self.mongodb = self.mongo[db]
self.notify.setInfo(True)
def handleConnected(self):
@ -51,4 +39,5 @@ class ToontownUberRepository(ToontownInternalRepository):
self.friendsManager = simbase.air.generateGlobalObject(OTP_DO_ID_TTS_FRIENDS_MANAGER, 'TTSFriendsManager')
self.globalPartyMgr = simbase.air.generateGlobalObject(OTP_DO_ID_GLOBAL_PARTY_MANAGER, 'GlobalPartyManager')
self.groupManager = simbase.air.generateGlobalObject(OPT_DO_ID_GROUP_MANAGER, 'GroupManager')
self.topToonsMgr = DistributedTopToonsManagerUD(self)

View file

@ -13,3 +13,7 @@ CAT_VP = 2048
CAT_CFO = 4096
CAT_CJ = 8192
CAT_CEO = 16384
_CAT_BEGIN = CAT_COGS
_CAT_END = CAT_CEO
_CAT_ALL = (_CAT_END << 1) - 1