Cache innocent & treasure items, completed rsc handler

This commit is contained in:
rsakeys 2020-03-07 01:54:12 +00:00
parent 0021ad1ad1
commit b20d0297bb
3 changed files with 137 additions and 66 deletions

View File

@ -1,5 +1,5 @@
from houdini.data import db, AbstractDataCollection from houdini.data import db, AbstractDataCollection
from functools import cached_property
class Flooring(db.Model): class Flooring(db.Model):
__tablename__ = 'flooring' __tablename__ = 'flooring'
@ -25,6 +25,7 @@ class Furniture(db.Model):
innocent = db.Column(db.Boolean, nullable=False, server_default=db.text("false")) innocent = db.Column(db.Boolean, nullable=False, server_default=db.text("false"))
class Igloo(db.Model): class Igloo(db.Model):
__tablename__ = 'igloo' __tablename__ = 'igloo'
@ -133,6 +134,10 @@ class FurnitureCollection(AbstractDataCollection):
__indexby__ = 'id' __indexby__ = 'id'
__filterby__ = 'id' __filterby__ = 'id'
@cached_property
def innocent(self):
return [item for item in self.values() if item.innocent]
class PenguinFurnitureCollection(AbstractDataCollection): class PenguinFurnitureCollection(AbstractDataCollection):
__model__ = PenguinFurniture __model__ = PenguinFurniture

View File

@ -1,6 +1,5 @@
from houdini.data import db, AbstractDataCollection from houdini.data import db, AbstractDataCollection
from functools import cached_property
class Item(db.Model): class Item(db.Model):
__tablename__ = 'item' __tablename__ = 'item'
@ -62,6 +61,14 @@ class ItemCollection(AbstractDataCollection):
__indexby__ = 'id' __indexby__ = 'id'
__filterby__ = 'id' __filterby__ = 'id'
@cached_property
def treasure(self):
return [item for item in self.values() if item.treasure]
@cached_property
def innocent(self):
return [item for item in self.values() if item.innocent]
class PenguinItemCollection(AbstractDataCollection): class PenguinItemCollection(AbstractDataCollection):
__model__ = PenguinItem __model__ = PenguinItem

View File

@ -1,7 +1,8 @@
from houdini import handlers from houdini import handlers
from houdini.handlers import XTPacket from houdini.handlers import XTPacket
from houdini.constants import ClientType from houdini.constants import ClientType
from houdini.data.item import Item
from houdini.data.igloo import Furniture, Igloo
from houdini.data import db from houdini.data import db
from houdini.data.redemption import RedemptionCode, RedemptionAwardCard, RedemptionAwardFlooring, \ from houdini.data.redemption import RedemptionCode, RedemptionAwardCard, RedemptionAwardFlooring, \
RedemptionAwardFurniture, RedemptionAwardIgloo, RedemptionAwardItem, RedemptionAwardLocation,\ RedemptionAwardFurniture, RedemptionAwardIgloo, RedemptionAwardItem, RedemptionAwardLocation,\
@ -32,92 +33,150 @@ async def handle_join_redemption_server_vanilla(p, credentials: str, confirmatio
@handlers.handler(XTPacket('rsc', ext='red'), pre_login=True) @handlers.handler(XTPacket('rsc', ext='red'), pre_login=True)
@handlers.depends_on_packet(XTPacket('rjs', ext='red')) @handlers.depends_on_packet(XTPacket('rjs', ext='red'))
async def handle_code(p, redemption_code: str): async def handle_code(p, redemption_code: str):
query = RedemptionCode.load(cards=RedemptionAwardCard, query = RedemptionCode.distinct(RedemptionCode.id)\
flooring=RedemptionAwardFlooring, .load(cards=RedemptionAwardCard.distinct(RedemptionAwardCard.card_id),
furniture=RedemptionAwardFurniture, items=RedemptionAwardItem.distinct(RedemptionAwardItem.item_id),
igloos=RedemptionAwardIgloo, furniture=RedemptionAwardFurniture.distinct(RedemptionAwardFurniture.furniture_id),
items=RedemptionAwardItem, igloos=RedemptionAwardIgloo.distinct(RedemptionAwardIgloo.igloo_id),
locations=RedemptionAwardLocation, locations=RedemptionAwardLocation.distinct(RedemptionAwardLocation.location_id),
puffles=RedemptionAwardPuffle, puffles=RedemptionAwardPuffle.distinct(RedemptionAwardPuffle.puffle_id),
puffle_items=RedemptionAwardPuffleItem)\ puffle_items=RedemptionAwardPuffleItem.distinct(RedemptionAwardPuffleItem.puffle_item_id)
)\
.query.where(RedemptionCode.code == redemption_code) .query.where(RedemptionCode.code == redemption_code)
code = await query.gino.first() code = await query.gino.all()
items = [] awards = []
if code is None: if code[0] is None:
return await p.send_error(720) return await p.send_error(720)
if code.uses is not None: if code[0].uses is not None:
redeemed_count = await db.select([db.func.count(PenguinRedemptionCode.code_id)]).where( redeemed_count = await db.select([db.func.count(PenguinRedemptionCode.code_id)]).where(
PenguinRedemptionCode.code_id == code.id).gino.scalar() PenguinRedemptionCode.code_id == code[0].id).gino.scalar()
if redeemed_count >= code.uses: if redeemed_count >= code[0].uses:
return await p.send_error(721) return await p.send_error(721)
penguin_redeemed = await PenguinRedemptionCode.query.where((PenguinRedemptionCode.code_id == code.id) & penguin_redeemed = await PenguinRedemptionCode.query.where((PenguinRedemptionCode.code_id == code[0].id) &
(PenguinRedemptionCode.penguin_id == p.id)).gino.scalar() (PenguinRedemptionCode.penguin_id == p.id)).gino.scalar()
if penguin_redeemed: if penguin_redeemed:
return await p.send_error(721) return await p.send_error(721)
if code.expires is not None and code.expires < datetime.now(): if code[0].expires is not None and code[0].expires < datetime.now():
return await p.send_error(726) return await p.send_error(726)
if code.type == 'CATALOG': if code[0].type == 'CATALOG':
num_redeemed_codes = await PenguinRedemptionCode.join(RedemptionCode).count().where( num_redeemed_codes = await PenguinRedemptionCode.join(RedemptionCode).count().where(
(PenguinRedemptionCode.penguin_id == p.id) & (RedemptionCode.type == 'CATALOG') (PenguinRedemptionCode.penguin_id == p.id) & (RedemptionCode.type == 'CATALOG')
).gino.scalar() ).gino.scalar()
owned_ids = ','.join((str(item.id) for item in p.server.items.values() if item.treasure and item.id in p.inventory)) owned_ids = ','.join((str(item) for item in p.server.items.treasure if item in p.inventory))
p.tb_validation = True
return await p.send_xt('rsc', 'treasurebook', 3, owned_ids, num_redeemed_codes) return await p.send_xt('rsc', 'treasurebook', 3, owned_ids, num_redeemed_codes)
if code.type == 'INNOCENT': if code[0].type == 'INNOCENT':
all_innocent_items = [item.id for item in p.server.items.values() if item.id in p.inventory and item.innocent] innocent_redeemed_items = { item for item in p.server.items.innocent if item.id in p.inventory }
all_innocent_furniture = [item.id for item in p.server.furniture.values() if item.id in p.furniture and item.innocent] innocent_redeemed_furniture = { item for item in p.server.furniture.innocent if item.id in p.furniture }
innocent_redeemed = all_innocent_items + all_innocent_furniture innocent_redeemed = innocent_redeemed_items.union(innocent_redeemed_furniture)
innocent_items = set(p.server.items.innocent + p.server.furniture.innocent)
innocent_furniture = ['f' + str(item.id) for item in p.server.furniture.values() if item.innocent] innocent_remaining = innocent_items - innocent_redeemed
innocent_clothing = [str(item.id) for item in p.server.items.values() if item.innocent]
innocent_items = innocent_clothing + innocent_furniture choices = random.sample(innocent_remaining, min(len(innocent_remaining), 3))
awards = [] if len(innocent_redeemed) + 3 == len(innocent_items):
choices.append(p.server.igloos[53])
for item in choices:
if type(item) is Item:
awards.append(str(item.id))
await p.add_inventory(item, notify=False)
elif type(item) is Igloo:
awards.append('g' + str(item.id))
await p.add_igloo(item, notify=False)
elif type(item) is Furniture:
awards.append('f' + str(item.id))
await p.add_furniture(item, notify=False)
while len(awards) < 3: await PenguinRedemptionCode.create(penguin_id=p.id, code_id=code[0].id)
if len(innocent_redeemed) >= len(innocent_items):
choice = random.choice(innocent_furniture)
if choice not in awards:
p.add_furniture(int(choice[1:]), 1, False)
awards.append(choice)
else:
choice = random.choice(innocent_items)
if choice in innocent_clothing:
if int(choice) not in innocent_redeemed and choice not in awards:
p.add_inventory(int(choice), False)
awards.append(choice)
elif choice in innocent_furniture:
if int(choice[1:]) not in innocent_redeemed and choice not in awards:
p.add_furniture(int(choice[1:]), 1, False)
awards.append(choice)
redeemed = len(innocent_redeemed) + 3 return await p.send_xt('rsc', 'INNOCENT', ','.join(map(str, awards)),
if redeemed == len(innocent_items): len(innocent_redeemed) + len(choices),
redeemed += 1 len(innocent_items))
p.add_igloo(53, False) if code[0].type == 'GOLDEN':
awards.append("g53")
if code.uses != -1:
await PenguinRedemptionCode.create(penguin_id=p.id, code_id=code.id)
return await p.send_xt('rsc', 'INNOCENT', ','.join(map(str, awards)), redeemed, len(innocent_items))
if code.type == 'GOLDEN':
return await p.send_xt('rsc', 'GOLDEN', p.ninja_rank, p.fire_ninja_rank, p.water_ninja_rank, 0, return await p.send_xt('rsc', 'GOLDEN', p.ninja_rank, p.fire_ninja_rank, p.water_ninja_rank, 0,
int(p.fire_ninja_rank > 0), int(p.water_ninja_rank > 0), 0) int(p.fire_ninja_rank > 0), int(p.water_ninja_rank > 0), 0)
if code.type == 'GOLDEN': if code[0].type == 'CARD':
return await p.send_xt('rsc', 'GOLDEN', p.ninja_rank, p.fire_ninja_rank, p.water_ninja_rank, 0, for award in code[0].cards:
int(p.fire_ninja_rank > 0), int(p.water_ninja_rank > 0), 0) awards.append(str(award.card_id))
if code.type == 'CARD':
for award in code.cards:
items.append(str(award.card_id))
await p.add_card(p.server.cards[award.card_id]) await p.add_card(p.server.cards[award.card_id])
else:
if code[0].items:
for award in code[0].items:
awards.append(str(award.item_id))
await p.add_inventory(p.server.items[award.item_id], notify=False)
if code[0].furniture:
for award in code[0].furniture:
awards.append('f'+str(award.furniture_id))
await p.add_furniture(p.server.furniture[award.furniture_id], notify=False)
if code[0].igloos:
for award in code[0].igloos:
awards.append('g'+str(award.igloo_id))
await p.add_igloo(p.server.igloos[award.igloo_id], notify=False)
if code[0].locations:
for award in code[0].locations:
awards.append('loc'+str(award.location_id))
await p.add_location(p.server.locations[award.location_id], notify=False)
if code[0].flooring:
for award in code[0].flooring:
awards.append('flr'+str(award.flooring_id))
await p.add_flooring(p.server.flooring[award.flooring_id], notify=False)
if code[0].puffles:
for award in code[0].puffles:
awards.append('p'+str(award.puffle_id))
if code[0].puffle_items:
for award in code[0].puffle_items:
awards.append('pi'+str(award.puffle_item_id))
await p.add_puffle_item(p.server.puffle_items[award.puffle_item_id], notify=False)
await PenguinRedemptionCode.create(penguin_id=p.id, code_id=code[0].id)
await p.update(coins=p.coins + code[0].coins).apply()
coins = "" if code[0].coins == 0 else code[0].coins
return await p.send_xt('rsc', code[0].type, ','.join(map(str, awards)), coins)
@handlers.handler(XTPacket('rsgc', ext='red'), pre_login=True)
@handlers.depends_on_packet(XTPacket('rsc', ext='red'))
async def handle_golden_choice(p, redemption_code: str, choice: int):
query = RedemptionCode.distinct(RedemptionCode.id)\
.load(cards=RedemptionAwardCard.distinct(RedemptionAwardCard.card_id),
items=RedemptionAwardItem.distinct(RedemptionAwardItem.item_id),
furniture=RedemptionAwardFurniture.distinct(RedemptionAwardFurniture.furniture_id),
igloos=RedemptionAwardIgloo.distinct(RedemptionAwardIgloo.igloo_id),
locations=RedemptionAwardLocation.distinct(RedemptionAwardLocation.location_id),
puffles=RedemptionAwardPuffle.distinct(RedemptionAwardPuffle.puffle_id),
puffle_items=RedemptionAwardPuffleItem.distinct(RedemptionAwardPuffleItem.puffle_item_id)
)\
.query.where(RedemptionCode.code == redemption_code)
code = await query.gino.all()
if len(code[0].cards) < 6:
return await p.close()
penguin_redeemed = await PenguinRedemptionCode.query.where((PenguinRedemptionCode.code_id == code[0].id) & (PenguinRedemptionCode.penguin_id == p.id)).gino.scalar()
if penguin_redeemed:
return await p.close()
if choice == 1: