Timeline/Server/Constants.py
TIMELINE_LOGGER = 'Timeline'
Timeline/Database/DB.py
class Puffle(DBObject):
    state = x = y = 0

    def __str__(self):
        # puffle id|type|sub_type|name|adoption|food|play|rest|clean|hat|x|y|is_walking
        return '|'.join(map(str, [int(self.id), int(self.type), self.subtype if int(self.subtype) != 0 else '',
                                  self.name, self.adopt(), int(self.food), int(self.play), int(self.rest),
                                  int(self.clean), int(self.hat), int(self.x), int(self.y), int(self.walking)]))

    def adopt(self):
        return int(time.mktime(self.adopted.timetuple()))

    def updatePuffleStats(self, engine):
        care_history = json.loads(self.lastcare)
        now = time.time()

        if care_history is None or len(care_history) < 1 or bool(int(self.backyard)) or self.walking:
            care_history['food'] = care_history['play'] = care_history['bath'] = now
            self.lastcare = json.dumps(care_history)
            self.save()

            return  # ULTIMATE PUFFLE <indefinite health and energy>

        last_fed = care_history['food']
        last_played = care_history['play']
        last_bathed = care_history['bath']

        food, play, clean = int(self.food), int(self.play), int(self.clean)

        puffleCrumb = engine.puffleCrumbs[self.subtype]
        max_food, max_play, max_clean = puffleCrumb.hunger, 100, puffleCrumb.health

        self.rest = 100  # It's in the igloo all this time?
        self.save()

        ''' It afterall is a poor creature to be taken care of.
        if not int(puffle.id) in self.penguin.engine.puffleCrumbs.defautPuffles:
            return # They aren't to be taken care of
        '''

        '''
        if remaining % < 10 : send a postcard blaming (hungry, dirty, or unhappy)
        if remaining % < 2 : move puffle to pet store, delete puffle, send a postcard, sue 1000 coins as penalty
        '''

        fed_percent = food - 5 * ((now - last_fed)/86400) # delta_food = -5% per day
        play_percent = play - 5 * ((now - last_played)/86400) # delta_play = -5% per day
        clean_percent = clean - 10 * ((now - last_bathed)/86400) # delta_clean = -10% per day

        total_percent = (fed_percent + play_percent + clean_percent) / 3.0

        if fed_percent < 3 or total_percent < 6:
            self.backyard = 1
            self.food = 100
            self.play = 100
            self.clean = 100
            self.save()

            return

        if fed_percent < 10:
            pid = self.penguin_id
            pname = self.name
            def sendMail(mail):
                if mail is not None:
                    sent = mail.sent_on
                    delta = (time.time() - sent)/3600/12
                    if delta < 1:
                        return

                Mail(penguin_id=pid, from_user=0, type=110, description=str(pname)).save()


            last_mail = Mail.find(where=['penguin_id = ? AND type = 110 AND description = ?', self.penguin_id, self.name], orderby='sent_on DESC', limit=1).addCallback(sendMail)

        self.food = fed_percent
        self.play = play_percent
        self.clean = clean_percent

        care_history['food'] = care_history['play'] = care_history['bath'] = now
        self.lastcare = json.dumps(care_history)

        self.save()
Timeline/Server/Constants.py
DIGGABLE_FURN = [507, 305, 502, 150, 616, 369, 340, 506, 149, 313, 370, 504]
Timeline/Server/Constants.py
WORLD_SERVER = 'WS'
Timeline/Handlers/Puffle.py
@PacketEventHandler.onXT('s', 'p#pw', WORLD_SERVER)
def handlePuffleWalk(client, puffle, isWalking, sendPacket = True):
    puffleById = {i.id : i for i in client['data'].puffles}

    if puffle not in puffleById or puffleById[puffle].walking == isWalking:
        return

    puffle = puffleById[puffle]

    if client['walkingPuffle'] is not None:
        if client['walkingPuffle'].id is puffle.id and isWalking:
            return None

        client['walkingPuffle'].walking = 0
        client['walkingPuffle'].state = 0
        client['walkingPuffle'].save()

        client['currencyHandler'].currencies[1] = 0
        client['currencyHandler'].refreshCurrencies()
        client.penguin.canAdoptGold = False

    puffle.walking = int(isWalking)
    puffle.save()

    client['walkingPuffle'] = puffle if isWalking else None

    client['room'].send('pw', client['id'], puffle.id, puffle.type, puffle.subtype, int(isWalking), puffle.hat) \
        if sendPacket else None
Timeline/Handlers/Puffle.py
@PacketEventHandler.onXT('s', 'p#pr', WORLD_SERVER)
def handlePuffleRest(client, puffle, sendPacket = True):
    puffleById = {i.id: i for i in client['data'].puffles}
    puffle = puffleById[puffle] if puffle in puffleById else None

    if puffle is None:
        return

    health, hunger, rest = map(int, client.engine.puffleCrumbs.defautPuffles[int(puffle.type)])

    if puffle.rest < 10 or puffle.clean < 10 or puffle.food < 10:
        return

    cx = choice(range(0, health - 10))
    fx = choice(range(10, 30))


    puffle.rest = 100
    puffle.clean = min(health, int(puffle.clean)*health - cx) / health * 100
    puffle.food = min(hunger, int(puffle.food)*hunger - fx) / hunger * 100
    puffle.play = max(0, int(puffle.play) - 10)

    puffle.save()
    print puffle.clean, puffle.food, puffle.play
    client['room'].send('pr', client['id'], puffle) if sendPacket else None

    return puffle
Timeline/Server/Constants.py
DIGGABLES = [118, 469, 412, 184, 774, 122, 498, 374, 1159, 326, 5080, 3028, 232, 112, 105, 111, 1082, 366, 1056, 790, 4039, 14523, 11343, 4154, 4082, 4199, 6219, 3205, 1196, 3003, 3183, 5100,11456, 12076, 15149, 9061, 4990, 4261, 4370, 4883, 24083, 1160, 1304, 9094, 4420] # blame arthur
Timeline/Server/Constants.py
GOLD_DIGGABLE_FURN = [2130, 2131, 2129, 2132]
Timeline/Utils/Events.py
class Event(object):
class EventListener(object):
class PacketEvent(Event):
class GeneralEvent(Event):
    def __init__(self):
    def removeListener(self, event, function):
    def addListener(self, event, function):
    def on(self, event, function = None):
        def func(function):
    def callback(self, fn, E):
    def call(self, e, *a, **kw):
    def unsetEventInModule(self, module):
    def unsetEventsInModulesAndSubModules(self, module):
    def __call__(self, event, *a, **kw):
    def Event():
    def __init__(self, name, func, k):
    def __call__(self, event):
        def err(x):
    def __init__(self):
    def unsetEventInModule(self, module):
    def unsetEventsInModulesAndSubModules(self, module):
    def FetchRule(self, type, c, h_t, s_t, server_protocol):
    def XTPacketRule(self, c, h, s_t, function = None, server_protocol = AS3_PROTOCOL):
        def func(function):
    def XMLPacketRule(self, a, s_t, t = 'sys', function = None, server_protocol = AS3_PROTOCOL):
        def func(function):
    def XTPacketRule_AS2(self, c, h, s_t, function = None):
    def XMLPacketRule_AS2(self, a, s_t, t = 'sys', function = None):
    def on(self, _type, category, server_type, handler=None, server_protocol = AS3_PROTOCOL):
    def call(self, e, args = (), kwargs = {}, rules_a = (), rules_kwarg = {}):
    def on_packet(self, event, isruled, _f = None):
        def func(function):
    def onXML(self, action, server_type, type = 'sys', p_r = True, function = None, server_protocol = AS3_PROTOCOL):
    def onXT(self, c, h, s_t, p_r = True, function = None, server_protocol = AS3_PROTOCOL):
    def onXML_AS2(self, action, server_type, type = 'sys', p_r = True, function = None):
    def onXT_AS2(self, c, h, s_t, p_r = True, function = None):
    def __init__(self):
Timeline/Handlers/Puffle.py
@PacketEventHandler.onXT('s', 'p#pp', WORLD_SERVER)
def handlePufflePlay(client, puffle, sendPacket = True):
    puffleById = {i.id: i for i in client['data'].puffles}
    puffle = puffleById[puffle] if puffle in puffleById else None

    if puffle is None:
        return

    health, hunger, rest = map(int, client.engine.puffleCrumbs.defautPuffles[int(puffle.type)])

    if puffle.rest < 10 or puffle.clean < 10 or puffle.food < 10:
        return

    rx = choice(range(10, rest-10))
    cx = choice(range(0, health - 10))
    fx = choice(range(10, hunger))

    PX = choice(range(10, 100))

    puffle.rest = min(rest, int(puffle.rest)*rest - rx)/rest * 100
    puffle.clean = min(health, int(puffle.clean)*health - cx)/health * 100
    puffle.food = min(hunger, int(puffle.food)*hunger - fx)/hunger * 100
    puffle.play = min(100, int(puffle.play) + PX)

    puffle.save()

    client['room'].send('pp', client['id'], puffle, 27) if sendPacket else None #TODO: Play type

    return puffle
Timeline/Server/Constants.py
LOGIN_SERVER = 'LS'
Timeline/Server/Constants.py
GOLD_DIGGABLES = [6209, 5386, 5385, 5384, 4994, 4993, 3187, 3186, 3185, 2139, 2138, 2137, 2136, 1735, 1734, 5434, 5382]
Timeline/Handlers/Puffle.py
@PacketEventHandler.onXT('s', 'p#pn', WORLD_SERVER)
@inlineCallbacks
def handleAdopt(client, _type, name, sub_type, sendPuffleAdopt = True):
    if not handleCheckPuffleName(client, [0, 0, [name]]):
        returnValue(None)

    if not client['id'] in PENDING:
        PENDING[client['id']] = []

    PENDING[client['id']].append(name)

    puffle = client.engine.puffleCrumbs[sub_type]
    if puffle is None or (_type == 10 and not client['canAdoptRainbow']) or (_type == 11 and not client['canAdoptGold']):
        PENDING[client['id']].remove(name)
        returnValue(None)

    cost = 800
    if sub_type in client.engine.puffleCrumbs.defautPuffles:
        cost = 400

    if puffle.member and not client['member']:
        PENDING[client['id']].remove(name)
        client.send('e', 999)
        returnValue(None)
    
    if client['coins'] < cost:
        returnValue(client.send('e', 401))

    now = int(time())
    care = '{"food" : {now},"play" : {now},"bath" : {now}}'.replace('{now}', str(now))
    puffle_db = yield Puffle(penguin_id = client['id'], name = name, type = _type, subtype = sub_type,
                             food = puffle.hunger, play = 100, rest = puffle.rest, clean = puffle.health,
                             lastcare = care).save()

    yield Coin(penguin_id=client['id'], transaction= -cost,
               comment="Pet Puffle Adoption. Puffle: {}".format(sub_type)).save()
    client['coins'] -= cost
    yield Mail(penguin_id=client['id'], from_user=0, type=111, description=name).save()

    client['RefreshHandler'].forceRefresh()

    PENDING[client['id']].remove(name)
    returnValue(puffle_db)


Question: from Timeline.Server.Constants import TIMELINE_LOGGER, LOGIN_SERVER, WORLD_SERVER, DIGGABLES, GOLD_DIGGABLES, DIGGABLE_FURN, GOLD_DIGGABLE_FURN
from Timeline.Utils.Events import Event, PacketEventHandler, GeneralEvent
from Timeline.Database.DB import Puffle
from Timeline.Handlers.Puffle import handleAdopt, handlePufflePlay, handlePuffleRest, handlePuffleWalk
from twisted.internet.defer import inlineCallbacks, returnValue
from collections import deque
from time import time
from random import choice, randint, shuffle
import logging, json




def getAS2PuffleString(client, puffles):
    puffles_as2_str = list()
    for puffle in puffles:
        p_id, p_type, p_sub_type, p_name, p_adopt, p_food, \
        p_play, p_rest, p_clean, p_hat, p_x, p_y, is_walking = puffle.split('|')

        p_crumb = client.engine.puffleCrumbs[p_sub_type]

        p_max_food, p_max_clean, p_max_health = map(str, (p_crumb.hunger, 100, p_crumb.health))
        p_as2 = '|'.join((p_id, p_name, p_type, p_clean, p_food, p_rest, p_max_health, p_max_food, '100', p_x, p_y, p_hat, is_walking))

        puffles_as2_str.append(p_as2)

    return '%'.join(puffles_as2_str)


Answer: @PacketEventHandler.onXT_AS2('s', 'p#pg', WORLD_SERVER)