Volity

Python: module volity.volent
 
 
volity.volent
index
volity/volent.py

 
Modules
       
volity.actor
volity.game
zymb.jabber
logging
time
zymb

 
Classes
       
zymb.sched.Agent
VolEntity
exceptions.Exception
FailureToken
Literal
zymb.jabber.rpc.WrapperOpset(zymb.jabber.rpc.Opset)
ClientRPCWrapperOpset

 
class ClientRPCWrapperOpset(zymb.jabber.rpc.WrapperOpset)
    ClientRPCWrapperOpset: An Opset which wraps all RPC handlers used
by Parlors and Referees (but not Actors).
 
This Opset ensures that all RPC replies follow the Volity token rules.
A successful RPC response is returned as a ['volity.ok', value] list.
Failure tokens are returned in appropriate token-list form.
 
(This wrapper is not applied to Actors -- i.e., bots -- because a
bot is replying to a referee, not to a player. There's no need to
send translation tokens to a referee.)
 
Static method:
 
oktoken() -- create a success-token list encapsulating the given value.
 
Internal methods:
 
__call__() -- invoke an RPC.
deferredwrapper() -- callback for deferred handlers.
 
 
Method resolution order:
ClientRPCWrapperOpset
zymb.jabber.rpc.WrapperOpset
zymb.jabber.rpc.Opset

Methods defined here:
__call__(self, sender, callname, *callargs)
__call__(sender, callname, *callargs) -> <rpc outcome>
 
Invoke an RPC. This is invoked by the Zymb RPC-handling service.
deferredwrapper(self, tup)
deferredwrapper() -- callback for deferred handlers.
 
This is used by handlecall(), for the case where an RPC handler
wants to undertake a deferral operation. You should not call it,
or even try to understand it.

Static methods defined here:
oktoken(value)
oktoken(value) -> list
 
Create a success-token list encapsulating the given value.

Methods inherited from zymb.jabber.rpc.WrapperOpset:
__init__(self, subopset)
getopset(self)
getopset() -> Opset
 
Retrieve the contained opset.
setopset(self, subopset)
setopset(subopset) -> None
 
Change the contained opset.

Methods inherited from zymb.jabber.rpc.Opset:
precondition(self, sender, namehead, nametail, *callargs)
precondition(sender, namehead, nametail, *callargs) -> None
 
This method is invoked inside the __call__ method, after the
opset has decided what to do, but before it does it. The
precondition has the opportunity to raise StanzaErrors, RPCFaults,
or RPCResponses for a whole class of calls, before a specific 
function is invoked.
 
The *sender* is a JID; the *callargs* are the RPC arguments,
in the form of Python objects. The *namehead* and *nametail*
represent the callname. *namehead* is the part that has been
successfully parsed by this Opset, and *nametail* is the part
which will be passed on to the function. For some Opset classes
(NamesOpset and MethodOpset), *nametail* is always empty.
 
In all the Opset classes in this module, the precondition method
does nothing. It is provided so that you can create Opset
subclasses which do application-specific checks.

 
class FailureToken(exceptions.Exception)
    FailureToken: Represents a failure token list.
 
FailureToken(*tokens) -- constructor.
 
The *tokens* list must contain at least one element. 
 
Static method:
 
encode() -- turn an object into a token.
 
  Methods defined here:
__init__(self, tok, *tokargs)
__repr__(self)
__str__(self)

Static methods defined here:
encode(val)
encode(val) -> str
 
Turn an object into a token. The *val* must be a string, a number,
Literal object, or a Seat.
 
A string is taken to be a token name. If it is in the form
'namespace.token', it is taken as given. If it has no dot, it
is assumed to be in the game.* namespace.
 
A number is automatically turned into a literal.* namespace token,
of the form 'literal.NUMBER'.
 
A Seat object is turned into a seat.* namespace token.

Methods inherited from exceptions.Exception:
__getitem__(...)

 
class Literal
    Literal: Represents a literal string in a token list.
 
Literal(value) -- constructor.
 
The Literal token will represent the string *value*. If *value* is not
a string or unicode object, it is converted to one.
 
  Methods defined here:
__init__(self, token)

 
class VolEntity(zymb.sched.Agent)
    VolEntity: A base class for Volity entities. This does the basic
work of creating a Jabber client Agent.
 
VolEntity is an Agent itself, so it can use all the scheduling and
queueing features defined in Zymb's sched module.
 
VolEntity(jidstr, password, jidresource=None) -- constructor.
 
The *jidstr* and *password* are used to connect to a Jabber server.
If *jidresource* is provided, it overrides the resource string in
*jidstr*. If neither resource string is available, "volity" is used.
 
Static methods:
 
uniquestamp() -- Generate a number which is unique within this process.
 
Agent states and events:
 
state 'start': Initial state. Start up the Jabber connection process.
    When Jabber is fully connected, jump to 'ready'.
state 'ready': Send out initial presence. In this state, the entity
    is ready to do normal work.
state 'end': The connection is closed.
 
Public methods:
 
start() -- begin activity. (inherited)
stop() -- stop activity. (inherited)
 
Significant fields:
 
jid -- the JID by which this entity is connected.
conn -- the Jabber client agent.
 
Internal methods:
 
startup() -- 'start' state handler.
authed() -- handler for Jabber client 'authresource' state.
startpresence() -- 'ready' state handler.
finalize() -- 'end' state handler.
rpcnotfound() -- callback for RPC method-not-found case.
cappresencehook() -- callback for presence stanza generation.
 
  Methods defined here:
__init__(self, jidstr, password, jidresource=None)
authed(self)
authed() -- handler for Jabber client 'authresource' state.
 
The Jabber client has finished connecting. Jump to 'ready'.
cappresencehook(self, msg)
cappresencehook() -- callback for presence stanza generation.
 
This hook is called whenever we generate a presence stanza. It adds
a JEP-0115 Entity Capabilities tag to the stanza.
finalize(self)
finalize() -- 'end' state handler.
 
Shut down the Jabber client agent.
rpcnotfound(self, msg, callname, callargs)
rpcnotfound() -- callback for RPC method-not-found case.
 
When an RPC arrives that we do not recognize, we want to respond
with an RPC fault. (As opposed to the default behavior, which is
an <item-not-found> stanza error.)
startpresence(self)
startpresence() -- 'ready' state handler.
 
Send out initial presence.
startup(self)
startup() -- 'start' state handler.
 
Start the Jabber client agent, and then wait for it to finish
connecting.

Static methods defined here:
uniquestamp()
uniquestamp() -> int
 
Generate a number which is unique within this process. It is
approximately a Unix timestamp, but incremented when necessary
to avoid repeats.

Data and other attributes defined here:
laststamp = 0
logprefix = 'volity'
volityrole = 'UNDEFINED'

Methods inherited from zymb.sched.Agent:
__str__(self)
addcleanupaction(self, ac)
addcleanupaction(action) -> None
 
Add *action* to the list of actions to be removed when the agent
stops (i.e., jumps to the 'end' state).
 
This is intended for actions that an agent adds as handlers to
other agents. For example:
 
    ac = otheragent.addhandler('event', self.foreigneventhandler)
    # Ensure that ac is removed when *self* shuts down.
    addcleanupaction(ac)
 
You do not need to list pollers or socket-checkers as cleanup
actions. Nor do you need to list handlers that an agent adds
to itself. (All these are automatically removed when the agent
shuts down.) You also don't have to worry about the case of
*otheragent* shutting down; when that happens, all handlers added
to it are removed.
addhandler(self, state, op, *args)
addhandler(eventname, op, *args) -> action
 
Add a state or event handler. The *eventname* is a string naming
the state or event you want to handle. The *op* and *args* are
the operation to perform when that state or event occurs.
(See queueaction() for the use of *op* and *args*.)
 
Handlers are invoked in last-added-first-run order. If an agent
has a built-in handler, it is added first, so it runs last. Handlers
that you add on later run earlier.
 
Returns the Action. (You can cancel the handler by calling
ac.remove().)
addtimer(self, op, *args, **dic)
addtimer(op, *args, delay=num, when=num, periodic=bool) -> action
 
Add a timed event. You must supply exactly one of the keyword
arguments *delay* and *when*. A *when* is an absolute time,
expressed as a number of seconds since the epoch (e.g., the kind
of value returned by time.time()). A *delay* is a relative time,
expressed as a number of seconds in the future.
 
It is legal to give a time in the past (or a negative *delay*).
In that case, this is similar to queueaction() -- the operation
will occur very soon. (Although it's still a "low priority"
action.)
 
If you supply *periodic*=True, the event will occur repeatedly,
every *delay* seconds. (The interval is inferred if you give
*when*.) In this case, you may NOT give a negative *delay* or
a time in the past -- it is meaningless for a periodic event to
have a period less than or equal to zero.
 
You can also create a periodic timer by calling addtimer with
a PeriodicAction, which is a subclass of Action. This is slightly
more flexible; the interval between calls is specified when
you create the PeriodicAction, but the delay before the first
call may be specified with *delay* or *when*.
 
See queueaction() for the use of *op* and *args*.
 
Returns the Action. (You can cancel the timer by calling
ac.remove().)
basicerror(self, exc, agent)
basicerror(exc, agent) -> None
 
        A simple event handler for 'error'. This simply writes the
        received data to stdout:
        
            sys.stdout.write('Error: ' + str(agent) + ': ' + str(exc) + '
')
 
        This handler is not installed by default. You can enable it by
        calling:
        
            ag.addhandler('error', ag.basicerror)
jump(self, st, *exargs)
jump(state, *args) -> None
 
Jump to a different operating state. (If the agent is already
in the given state, nothing happens.)
 
This queues up all the state transition handlers registered
for the new state. If you provide *args*, they are passed to the
handlers when they are called.
perform(self, name, *exargs)
perform(eventname, *args) -> None
 
Trigger an event.
 
This queues up all the event handlers registered for the given
event. If you provide *args*, they are passed to the handlers when
they are called.
queueaction(self, op, *args)
queueaction(op, *args) -> action
 
Invoke an action. The action will be handed to the scheduler, which
will run it very soon.
 
("Very soon" means "before the next timed event or network message
is handled." However, if you queue several actions, they will be
handled in the order you queued them.)
 
You can pass any callable as *op*; the (optional) *args* will be
passed to it as arguments. You can also, if you like, create
an Action object and pass it as *op*. You can still pass *args*
in this case; they'll be appended to the arguments bound into
the Action.
 
Returns the Action.
registerpoll(self, op, *args, **dic)
registerpoll(op, *args, interval=num) -> action
 
Add a repeating activity check. *interval* is a (mandatory) keyword
argument; the scheduler will invoke your operation at least every
*interval* seconds. (And at least once per sched.process() call.)
 
See queueaction() for the use of *op* and *args*. Your operation
should not do any work except for absorbing input and queueing
actions. Typically, it will collect the input and then call
perform(), triggering an event, so that the agent's event
handlers can do something with the input.
 
Returns the Action. (You can cancel it by calling ac.remove().)
registersocket(self, fileno, op, *args)
registersocket(socket, op, *args) -> action
 
Add a socket-based activity check. The *socket* may be a socket
object, or a number representing a fileno, or any object which
provides a fileno() method. 
 
See queueaction() for the use of *op* and *args*. Your operation
should not do any work except for absorbing input and queueing
actions. Typically, it will collect the input and then call
perform(), triggering an event, so that the agent's event
handlers can do something with the input.
 
Returns the Action. (You can cancel it by calling ac.remove().)
shutdown(self)
shutdown() -- internal 'end' state handler. Do not call.
 
This is the final 'end' handler. It removes the agent from the
scheduler, and cancels all its remaining actions, timed events,
etc.
start(self)
start() -> None
 
Begin activity. The agent adds itself to the scheduler and moves
to the 'start' state. It does not actually begin doing work in
this call; that happens the next time the scheduler is invoked
(sched.process).
 
You should only call this once per agent.
stop(self)
stop() -> None
 
Stop activity. The agent moves to the 'end' state. Its 'end'
state handlers will take care of shutting it down and removing
it from the scheduler.
 
It is safe to call this on an agent which is already in 'end',
or which is completely shut down. (Nothing further will happen.)
 
(Remember, state handlers are not called as part of the stop()
method. They are run by the scheduler "soon" after stop() is
called. If you want to be sure the agent is completely stopped,
you can check the agent.live field. However, it is better to
register your own 'end' state handler, and consider the agent
stopped when that it called.)

Data and other attributes inherited from zymb.sched.Agent:
agentcounter = 1
hidden = False

 
Functions
       
descinterval(endtime, starttime=None, limit=None)
descinterval(endtime, starttime=None, limit=None) -> str
 
Render an interval as a human-readable string.
 
If only *endtime* is provided, this will be of the form 'X hours
Y minutes Z seconds ago'. (That is, before the present.) If *endtime*
is None, this returns 'never'.
 
If both *starttime* and *endtime* are provided, this will be of the
form 'X hours Y minutes Z seconds'. (That is, between the two times.)
 
If *limit* (an integer) is provided, it limits the number of units
which are named. For example, if *limit* is 2, then a multi-hour
time will be rendered as 'X hours Y minutes' (with the 'seconds'
trimmed off.) A multi-day time will be rendered as 'W days X hours'.
doubletoint(nod, nam)
doubletoint -- internal function used as an rpcdata value parser hook.
 
A peculiarity of Volity is that when a numeric value comes over the
RPC wire from a client, it will always be a <double>, even if the
value is a whole number. This is because Volity clients run on ECMAScript,
which has no type distinction between floats and ints.
 
Therefore, we set up an RPC parsing function which converts floats to
ints. (Games will very rarely use true non-integer values, so this is
the normal case.) Unfortunately, the rpcdata facility to handle this is
global -- sorry, I got lazy -- so this conversion applies to every RPC
received by the process.

 
Data
        VOLITY_CAPS_URI = 'http://volity.org/protocol/caps'
intervalunits = [(31536000, 'year'), (2592000, 'month'), (604800, 'week'), (86400, 'day'), (3600, 'hour'), (60, 'minute'), (1, 'second')]
volityversion = '1.0'