ai: Some fixes
This commit is contained in:
parent
70602f7231
commit
a5c5ecbf47
|
|
@ -708,7 +708,7 @@ class AIRepository(ConnectionRepository):
|
|||
# Look up the dclass
|
||||
dclass = self.dclassesByNumber[classId]
|
||||
# Is it in our dictionary?
|
||||
if self.doId2do.has_key(doId):
|
||||
if doId in self.doId2do:
|
||||
self.notify.warning("Object Entered " + str(doId) +
|
||||
" re-entered without exiting")
|
||||
# Create a new distributed object
|
||||
|
|
@ -720,7 +720,7 @@ class AIRepository(ConnectionRepository):
|
|||
# sure why or how this happens, but it does come up from time to
|
||||
# time in production
|
||||
# Asad Todo take out this security check for now don't publish to toontown!!!
|
||||
## if self.doId2do.has_key(doId):
|
||||
## if doId in self.doId2do:
|
||||
## self.writeServerEvent('suspicious', doId, 'Avatar re-entered without exiting')
|
||||
## # Note: until we figure out what is causing this bug, it will be an error
|
||||
## # This is listed as bug 50608 in the production remarks db
|
||||
|
|
@ -736,7 +736,7 @@ class AIRepository(ConnectionRepository):
|
|||
# Look up the dclass
|
||||
dclass = self.dclassesByNumber[classId]
|
||||
# Is it in our dictionary?
|
||||
if self.doId2do.has_key(doId):
|
||||
if doId in self.doId2do:
|
||||
self.notify.warning("Object Entered " + str(doId) +
|
||||
" re-entered without exiting")
|
||||
# Create a new distributed object
|
||||
|
|
@ -748,7 +748,7 @@ class AIRepository(ConnectionRepository):
|
|||
# sure why or how this happens, but it does come up from time to
|
||||
# time in production
|
||||
# Asad Todo take out this security check for now don't publish to toontown!!!
|
||||
## if self.doId2do.has_key(doId):
|
||||
## if doId in self.doId2do:
|
||||
## self.writeServerEvent('suspicious', doId, 'Avatar re-entered without exiting')
|
||||
## # Note: until we figure out what is causing this bug, it will be an error
|
||||
## # This is listed as bug 50608 in the production remarks db
|
||||
|
|
@ -817,7 +817,7 @@ class AIRepository(ConnectionRepository):
|
|||
pass
|
||||
|
||||
def _generateFromDatagram(self, parentId, zoneId, dclass, doId, di, addToTables=True):
|
||||
if (self.doId2do.has_key(doId)):
|
||||
if (doId in self.doId2do):
|
||||
# added to prevent objects already generated from being generated again (was
|
||||
# happening with some traded inventory objects, quests specfically)
|
||||
return self.doId2do[doId]
|
||||
|
|
@ -1225,7 +1225,7 @@ class AIRepository(ConnectionRepository):
|
|||
__builtins__["debug_dictionary"] = self.debug_dictionary
|
||||
|
||||
for id in self.debug_dictionary.keys():
|
||||
if not self.doId2do.has_key(id):
|
||||
if id not in self.doId2do:
|
||||
print("--------------------- Not In DOID table")
|
||||
print(id)
|
||||
#traceback.print_list(self.debug_dictionary[id])
|
||||
|
|
@ -1408,14 +1408,14 @@ class AIRepository(ConnectionRepository):
|
|||
# (classId, context))
|
||||
if ownerChannel == 0 and ownerAvId is not None:
|
||||
ownerChannel = (1<<32) + ownerAvId
|
||||
if self.dclassesByNumber.has_key(classId):
|
||||
if classId in self.dclassesByNumber:
|
||||
dclass = self.dclassesByNumber[classId]
|
||||
else:
|
||||
if self.dclassesByName.has_key(classId):
|
||||
if classId in self.dclassesByName:
|
||||
dclass = self.dclassesByName[classId]
|
||||
elif self.dclassesByName.has_key(classId+self.dcSuffix):
|
||||
elif classId+self.dcSuffix in self.dclassesByName:
|
||||
dclass = self.dclassesByName[classId+self.dcSuffix]
|
||||
elif self.dclassesByName.has_key(classId+'AI'):
|
||||
elif classId+'AI' in self.dclassesByName:
|
||||
dclass = self.dclassesByName[classId+'AI']
|
||||
else:
|
||||
self.notify.warning("dclass not found %s"%(classId,))
|
||||
|
|
@ -1499,7 +1499,7 @@ class AIRepository(ConnectionRepository):
|
|||
def handleDatagram(self, di):
|
||||
if self.notify.getDebug():
|
||||
print("AIRepository received datagram:")
|
||||
di.getDatagram().dumpHex(ostream)
|
||||
di.getDatagram().dumpHex(Notify.out())
|
||||
|
||||
channel=self.getMsgChannel()
|
||||
if channel in self.netMessenger.channels:
|
||||
|
|
@ -1911,3 +1911,6 @@ class AIRepository(ConnectionRepository):
|
|||
print('########## startReaderPollTask New ')
|
||||
self.stopReaderPollTask()
|
||||
self.accept(CConnectionRepository.getOverflowEventName(),self.handleReaderOverflow)
|
||||
|
||||
def getTrackClsends(self):
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -1,32 +1,151 @@
|
|||
from .AIBaseGlobal import *
|
||||
from pandac.PandaModules import *
|
||||
from direct.distributed.ClockDelta import *
|
||||
from direct.task import Task
|
||||
from direct.distributed import DistributedObjectAI
|
||||
from direct.directnotify import DirectNotifyGlobal
|
||||
from direct.showbase import GarbageReport
|
||||
from otp.otpbase import OTPGlobals
|
||||
from otp.ai.GarbageLeakServerEventAggregatorAI import GarbageLeakServerEventAggregatorAI
|
||||
import time
|
||||
|
||||
from direct.directnotify import DirectNotifyGlobal
|
||||
from direct.distributed.ClockDelta import globalClockDelta
|
||||
from direct.distributed.DistributedObjectAI import DistributedObjectAI
|
||||
|
||||
from otp.otpbase import OTPGlobals
|
||||
|
||||
|
||||
class TimeManagerAI(DistributedObjectAI):
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory('TimeManagerAI')
|
||||
class TimeManagerAI(DistributedObjectAI.DistributedObjectAI):
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory("TimeManagerAI")
|
||||
|
||||
def __init__(self, air):
|
||||
DistributedObjectAI.__init__(self, air)
|
||||
self.avId2disconnectcode = {}
|
||||
DistributedObjectAI.DistributedObjectAI.__init__(self, air)
|
||||
if not __dev__:
|
||||
# double-check that we're not implementing a client-sendable debug DC method in production
|
||||
if hasattr(self, 'checkForGarbageLeaks'):
|
||||
self.notify.error('checkForGarbageLeaks should not be defined outside of __dev__')
|
||||
|
||||
def requestServerTime(self, context):
|
||||
avId = self.air.getAvatarIdFromSender()
|
||||
if not avId:
|
||||
return
|
||||
|
||||
self.sendUpdateToAvatarId(avId, 'serverTime',
|
||||
[context, globalClockDelta.getRealNetworkTime(bits=32), int(time.time())])
|
||||
"""requestServerTime(self, int8 context)
|
||||
|
||||
This message is sent from the client to the AI to initiate a
|
||||
synchronization phase. The AI should immediately report back
|
||||
with its current time. The client will then measure the round
|
||||
trip.
|
||||
"""
|
||||
timestamp = globalClockDelta.getRealNetworkTime(bits=32)
|
||||
requesterId = self.air.getAvatarIdFromSender()
|
||||
timeOfDay = int(time.time())
|
||||
self.sendUpdateToAvatarId(requesterId, "serverTime",
|
||||
[context, timestamp, timeOfDay])
|
||||
|
||||
def setDisconnectReason(self, disconnectCode):
|
||||
avId = self.air.getAvatarIdFromSender()
|
||||
if not avId:
|
||||
return
|
||||
"""setDisconnectReason(self, uint8 disconnectCode)
|
||||
|
||||
self.avId2disconnectcode[avId] = disconnectCode
|
||||
self.air.writeServerEvent('disconnect-reason', avId=avId,
|
||||
reason=OTPGlobals.DisconnectReasons.get(disconnectCode, 'unknown'))
|
||||
This method is called by the client just before it leaves a
|
||||
shard to alert the AI as to the reason it's going. If the AI
|
||||
doesn't get this message, it can assume the client aborted
|
||||
messily or its internet connection was dropped.
|
||||
"""
|
||||
requesterId = self.air.getAvatarIdFromSender()
|
||||
self.notify.info("Client %s leaving for reason %s (%s)." % (
|
||||
requesterId, disconnectCode,
|
||||
OTPGlobals.DisconnectReasons.get(disconnectCode,
|
||||
'invalid reason')))
|
||||
|
||||
if disconnectCode in OTPGlobals.DisconnectReasons:
|
||||
self.air.setAvatarDisconnectReason(requesterId, disconnectCode)
|
||||
else:
|
||||
self.air.writeServerEvent(
|
||||
'suspicious', requesterId, 'invalid disconnect reason: %s' % disconnectCode)
|
||||
|
||||
def setExceptionInfo(self, info):
|
||||
"""setExceptionInfo(self, string info)
|
||||
|
||||
In the case of the client leaving for a Python exception, we
|
||||
also follow up the above message with this one, which just
|
||||
sends a text string describing the exception for the AI log.
|
||||
"""
|
||||
requesterId = self.air.getAvatarIdFromSender()
|
||||
self.notify.info("Client %s exception: %s" % (requesterId, info))
|
||||
serverVersion = simbase.config.GetString('server-version','')
|
||||
self.air.writeServerEvent('client-exception', requesterId, '%s|%s' % (serverVersion,info))
|
||||
|
||||
def setSignature(self, signature, hash, pyc):
|
||||
"""
|
||||
This method is called by the client at startup time, to send
|
||||
the xrc signature and the prc hash to the AI for logging in
|
||||
case the client does anything suspicious.
|
||||
"""
|
||||
if signature:
|
||||
requesterId = self.air.getAvatarIdFromSender()
|
||||
prcHash = HashVal()
|
||||
prcHash.setFromBin(hash)
|
||||
info = '%s|%s' % (signature, prcHash.asHex())
|
||||
self.notify.info('Client %s signature: %s' % (requesterId, info))
|
||||
self.air.writeServerEvent('client-signature', requesterId, info)
|
||||
|
||||
pycHash = HashVal()
|
||||
pycHash.setFromBin(pyc)
|
||||
if pycHash != HashVal():
|
||||
info = pycHash.asHex()
|
||||
self.notify.info('Client %s py signature: %s' % (requesterId, info))
|
||||
self.air.writeServerEvent('client-py-signature', requesterId, info)
|
||||
|
||||
def setCpuInfo(self, info, cacheStatus):
|
||||
"""
|
||||
This method is called by the client at startup time, to send
|
||||
the detailed CPU information to the server for logging.
|
||||
"""
|
||||
requesterId = self.air.getAvatarIdFromSender()
|
||||
|
||||
self.notify.info('client-cpu %s|%s' % (requesterId, info))
|
||||
self.air.writeServerEvent('client-cpu', requesterId, info)
|
||||
# We call this cacheStatus, but really it's the mac address or
|
||||
# other client fingerprint information, in a simple
|
||||
# obfuscating cipher. Decode it.
|
||||
key = 'outrageous'
|
||||
p = 0
|
||||
fingerprint = ''
|
||||
for ch in cacheStatus:
|
||||
ic = ord(ch) ^ ord(key[p])
|
||||
p += 1
|
||||
if p >= len(key):
|
||||
p = 0
|
||||
fingerprint += chr(ic)
|
||||
|
||||
self.notify.info('client-fingerprint %s|%s' % (requesterId, fingerprint))
|
||||
self.air.writeServerEvent('client-fingerprint', requesterId, fingerprint)
|
||||
if hasattr(self.air, 'cpuInfoMgr'):
|
||||
self.air.cpuInfoMgr.sendCpuInfoToUd(info, fingerprint)
|
||||
|
||||
|
||||
def setFrameRate(self, fps, deviation, numAvs,
|
||||
locationCode, timeInLocation, timeInGame,
|
||||
gameOptionsCode, vendorId, deviceId,
|
||||
processMemory, pageFileUsage, physicalMemory,
|
||||
pageFaultCount, osInfo, cpuSpeed,
|
||||
numCpuCores, numLogicalCpus, apiName):
|
||||
""" This method is called by the client at the interval
|
||||
specified by getFrameRateInterval(), to report its current
|
||||
frame rate. """
|
||||
|
||||
requesterId = self.air.getAvatarIdFromSender()
|
||||
info = '%0.1f fps|%0.3fd|%s avs|%s|%d|%d|%s|0x%04x|0x%04x|%0.1fMB|%0.1fMB|%0.1fMB|%d|%s|%s|%s cpus|%s' % (
|
||||
fps, deviation, numAvs, locationCode, timeInLocation,
|
||||
timeInGame, gameOptionsCode,
|
||||
vendorId, deviceId, processMemory, pageFileUsage, physicalMemory,
|
||||
pageFaultCount, '%s.%d.%d.%d' % osInfo, '%0.03f,%0.03f' % cpuSpeed,
|
||||
'%d,%d' % (numCpuCores, numLogicalCpus),
|
||||
apiName)
|
||||
self.notify.info('client-fps %s|%s' % (requesterId, info))
|
||||
self.air.writeServerEvent('client-fps', requesterId, info)
|
||||
|
||||
if __dev__:
|
||||
def checkForGarbageLeaks(self, wantReply):
|
||||
senderId = self.air.getAvatarIdFromSender()
|
||||
self.notify.info("checking for garbage leaks requested by %s" % senderId)
|
||||
# okay checking for garbage leaks should only be done by devs, it's rare enough i'll flag it
|
||||
# as suspicious
|
||||
self.air.writeServerEvent('suspicious', senderId, 'checkForGarbageLeaks')
|
||||
numLeaks = GarbageReport.checkForGarbageLeaks()
|
||||
if wantReply:
|
||||
requesterId = self.air.getAvatarIdFromSender()
|
||||
self.sendUpdateToAvatarId(requesterId, 'setNumAIGarbageLeaks', [numLeaks])
|
||||
|
||||
def setClientGarbageLeak(self, num, description):
|
||||
messenger.send(GarbageLeakServerEventAggregatorAI.ClientLeakEvent, [num, description])
|
||||
|
|
|
|||
Loading…
Reference in New Issue