100 lines
2.9 KiB
Python
Executable File
100 lines
2.9 KiB
Python
Executable File
|
|
from direct.directnotify import DirectNotifyGlobal
|
|
from direct.distributed.PyDatagram import PyDatagram
|
|
from direct.showbase.Messenger import Messenger
|
|
|
|
import sys
|
|
if sys.version_info >= (3, 0):
|
|
from pickle import dumps, loads
|
|
else:
|
|
from cPickle import dumps, loads
|
|
|
|
|
|
# Messages do not need to be in the MESSAGE_TYPES list.
|
|
# This is just an optimization. If the message is found
|
|
# in this list, it is reduced to an integer index and
|
|
# the message string is not sent. Otherwise, the message
|
|
# string is sent in the datagram.
|
|
MESSAGE_TYPES=(
|
|
"avatarOnline",
|
|
"avatarOffline",
|
|
"create",
|
|
"needUberdogCreates",
|
|
"transferDo",
|
|
)
|
|
|
|
# This is the reverse look up for the recipient of the
|
|
# datagram:
|
|
MESSAGE_STRINGS={}
|
|
for i in zip(MESSAGE_TYPES, range(1, len(MESSAGE_TYPES)+1)):
|
|
MESSAGE_STRINGS[i[0]]=i[1]
|
|
|
|
|
|
class NetMessenger(Messenger):
|
|
"""
|
|
This works very much like the Messenger class except that messages
|
|
are sent over the network and (possibly) handled (accepted) on a
|
|
remote machine (server).
|
|
"""
|
|
notify = DirectNotifyGlobal.directNotify.newCategory('NetMessenger')
|
|
|
|
def __init__(self, air, channels):
|
|
"""
|
|
air is the AI Repository.
|
|
channels is a list of channel IDs (uint32 values)
|
|
"""
|
|
assert self.notify.debugCall()
|
|
Messenger.__init__(self)
|
|
self.air=air
|
|
self.channels=channels
|
|
for i in self.channels:
|
|
self.air.registerForChannel(i)
|
|
|
|
def clear(self):
|
|
assert self.notify.debugCall()
|
|
for i in self.channels:
|
|
self.air.unRegisterChannel(i)
|
|
del self.air
|
|
del self.channels
|
|
Messenger.clear(self)
|
|
|
|
def send(self, message, sentArgs=[]):
|
|
"""
|
|
Send message to All AI and Uber Dog servers.
|
|
"""
|
|
assert self.notify.debugCall()
|
|
datagram = PyDatagram()
|
|
# To:
|
|
datagram.addUint8(1)
|
|
datagram.addChannel(self.channels[0])
|
|
# From:
|
|
datagram.addChannel(self.air.ourChannel)
|
|
#if 1: # We send this just because the air expects it:
|
|
# # Add an 'A' for AI
|
|
# datagram.addUint8(ord('A'))
|
|
|
|
messageType=MESSAGE_STRINGS.get(message, 0)
|
|
datagram.addUint16(messageType)
|
|
if messageType:
|
|
datagram.addString(str(dumps(sentArgs)))
|
|
else:
|
|
datagram.addString(str(dumps((message, sentArgs))))
|
|
self.air.send(datagram)
|
|
|
|
def handle(self, pickleData):
|
|
"""
|
|
Send pickleData from the net on the local netMessenger.
|
|
The internal data in pickleData should have a tuple of
|
|
(messageString, sendArgsList).
|
|
"""
|
|
assert self.notify.debugCall()
|
|
messageType=self.air.getMsgType()
|
|
if messageType:
|
|
message=MESSAGE_TYPES[messageType-1]
|
|
sentArgs=loads(pickleData)
|
|
else:
|
|
(message, sentArgs) = loads(pickleData)
|
|
Messenger.send(self, message, sentArgs=sentArgs)
|
|
|
|
|