mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
CConnectionRepository
This commit is contained in:
parent
0058660904
commit
ec535f800a
@ -8,7 +8,7 @@
|
|||||||
#define BUILDING_DLL BUILDING_DIRECT
|
#define BUILDING_DLL BUILDING_DIRECT
|
||||||
|
|
||||||
#define COMPONENT_LIBS \
|
#define COMPONENT_LIBS \
|
||||||
directbase dcparser showbase deadrec directd interval
|
directbase dcparser showbase deadrec directd interval distributed
|
||||||
|
|
||||||
#define OTHER_LIBS \
|
#define OTHER_LIBS \
|
||||||
panda:m \
|
panda:m \
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
"""ServerRepository module: contains the ServerRepository class"""
|
|
||||||
|
|
||||||
from PandaModules import *
|
from PandaModules import *
|
||||||
from ClusterMsgs import *
|
from ClusterMsgs import *
|
||||||
from MsgTypes import *
|
from MsgTypes import *
|
||||||
|
@ -53,7 +53,7 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
|
|||||||
self.relatedObjectMgr.abortAllRequests()
|
self.relatedObjectMgr.abortAllRequests()
|
||||||
|
|
||||||
def sendDisconnect(self):
|
def sendDisconnect(self):
|
||||||
if self.tcpConn:
|
if self.isConnected():
|
||||||
# Tell the game server that we're going:
|
# Tell the game server that we're going:
|
||||||
datagram = PyDatagram()
|
datagram = PyDatagram()
|
||||||
# Add message type
|
# Add message type
|
||||||
@ -287,8 +287,6 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
|
|||||||
# Get the DO Id
|
# Get the DO Id
|
||||||
doId = di.getArg(STUint32)
|
doId = di.getArg(STUint32)
|
||||||
#print("Updating " + str(doId))
|
#print("Updating " + str(doId))
|
||||||
if self.rsDoReport:
|
|
||||||
self.rsUpdateObjs[doId] = self.rsUpdateObjs.get(doId, 0) + 1
|
|
||||||
# Find the DO
|
# Find the DO
|
||||||
|
|
||||||
do = self.doId2do.get(doId)
|
do = self.doId2do.get(doId)
|
||||||
@ -398,8 +396,7 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
|
|||||||
self.lastHeartbeat = globalClock.getRealTime()
|
self.lastHeartbeat = globalClock.getRealTime()
|
||||||
# This is important enough to consider flushing immediately
|
# This is important enough to consider flushing immediately
|
||||||
# (particularly if we haven't run readerPollTask recently).
|
# (particularly if we haven't run readerPollTask recently).
|
||||||
if self.tcpConn:
|
self.considerFlush()
|
||||||
self.tcpConn.considerFlush()
|
|
||||||
|
|
||||||
def considerHeartbeat(self):
|
def considerHeartbeat(self):
|
||||||
"""Send a heartbeat message if we haven't sent one recently."""
|
"""Send a heartbeat message if we haven't sent one recently."""
|
||||||
|
@ -6,7 +6,7 @@ from PyDatagram import PyDatagram
|
|||||||
|
|
||||||
import types
|
import types
|
||||||
|
|
||||||
class ConnectionRepository(DirectObject.DirectObject):
|
class ConnectionRepository(DirectObject.DirectObject, CConnectionRepository):
|
||||||
"""
|
"""
|
||||||
This is a base class for things that know how to establish a
|
This is a base class for things that know how to establish a
|
||||||
connection (and exchange datagrams) with a gameserver. This
|
connection (and exchange datagrams) with a gameserver. This
|
||||||
@ -19,6 +19,7 @@ class ConnectionRepository(DirectObject.DirectObject):
|
|||||||
|
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
DirectObject.DirectObject.__init__(self)
|
DirectObject.DirectObject.__init__(self)
|
||||||
|
CConnectionRepository.__init__(self)
|
||||||
|
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
@ -40,22 +41,11 @@ class ConnectionRepository(DirectObject.DirectObject):
|
|||||||
# proxy is in place, but the NSPR interface if we don't have a
|
# proxy is in place, but the NSPR interface if we don't have a
|
||||||
# proxy.
|
# proxy.
|
||||||
self.connectMethod = self.config.GetString('connect-method', 'default')
|
self.connectMethod = self.config.GetString('connect-method', 'default')
|
||||||
|
|
||||||
self.connectHttp = None
|
self.connectHttp = None
|
||||||
self.http = None
|
self.http = None
|
||||||
self.qcm = None
|
|
||||||
self.cw = None
|
|
||||||
|
|
||||||
self.tcpConn = None
|
|
||||||
self.recorder = None
|
self.recorder = None
|
||||||
|
|
||||||
# Reader statistics
|
|
||||||
self.rsDatagramCount = 0
|
|
||||||
self.rsUpdateObjs = {}
|
|
||||||
self.rsLastUpdate = 0
|
|
||||||
self.rsDoReport = self.config.GetBool('reader-statistics', 0)
|
|
||||||
self.rsUpdateInterval = self.config.GetDouble('reader-statistics-interval', 10)
|
|
||||||
|
|
||||||
def readDCFile(self, dcFileNames = None):
|
def readDCFile(self, dcFileNames = None):
|
||||||
|
|
||||||
""" Reads in the dc files listed in dcFileNames, or if
|
""" Reads in the dc files listed in dcFileNames, or if
|
||||||
@ -162,21 +152,21 @@ class ConnectionRepository(DirectObject.DirectObject):
|
|||||||
known.
|
known.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.recorder and self.recorder.isPlaying():
|
## if self.recorder and self.recorder.isPlaying():
|
||||||
|
|
||||||
# If we have a recorder and it's already in playback mode,
|
## # If we have a recorder and it's already in playback mode,
|
||||||
# don't actually attempt to connect to a gameserver since
|
## # don't actually attempt to connect to a gameserver since
|
||||||
# we don't need to. Just let it play back the data.
|
## # we don't need to. Just let it play back the data.
|
||||||
self.notify.info("Not connecting to gameserver; using playback data instead.")
|
## self.notify.info("Not connecting to gameserver; using playback data instead.")
|
||||||
|
|
||||||
self.connectHttp = 1
|
## self.connectHttp = 1
|
||||||
self.tcpConn = SocketStreamRecorder()
|
## self.tcpConn = SocketStreamRecorder()
|
||||||
self.recorder.addRecorder('gameserver', self.tcpConn)
|
## self.recorder.addRecorder('gameserver', self.tcpConn)
|
||||||
|
|
||||||
self.startReaderPollTask()
|
## self.startReaderPollTask()
|
||||||
if successCallback:
|
## if successCallback:
|
||||||
successCallback(*successArgs)
|
## successCallback(*successArgs)
|
||||||
return
|
## return
|
||||||
|
|
||||||
hasProxy = 0
|
hasProxy = 0
|
||||||
if self.checkHttp():
|
if self.checkHttp():
|
||||||
@ -212,31 +202,10 @@ class ConnectionRepository(DirectObject.DirectObject):
|
|||||||
failureCallback, failureArgs)
|
failureCallback, failureArgs)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if self.qcm == None:
|
|
||||||
self.qcm = QueuedConnectionManager()
|
|
||||||
|
|
||||||
if self.cw == None:
|
|
||||||
self.cw = ConnectionWriter(self.qcm, 0)
|
|
||||||
self.qcr = QueuedConnectionReader(self.qcm, 0)
|
|
||||||
minLag = self.config.GetFloat('min-lag', 0.)
|
|
||||||
maxLag = self.config.GetFloat('max-lag', 0.)
|
|
||||||
if minLag or maxLag:
|
|
||||||
self.qcr.startDelay(minLag, maxLag)
|
|
||||||
|
|
||||||
# A big old 20 second timeout.
|
|
||||||
gameServerTimeoutMs = self.config.GetInt("game-server-timeout-ms",
|
|
||||||
20000)
|
|
||||||
|
|
||||||
# Try each of the servers in turn.
|
# Try each of the servers in turn.
|
||||||
for url in serverList:
|
for url in serverList:
|
||||||
self.notify.info("Connecting to %s via NSPR interface." % (url.cStr()))
|
self.notify.info("Connecting to %s via NSPR interface." % (url.cStr()))
|
||||||
self.tcpConn = self.qcm.openTCPClientConnection(
|
if self.tryConnectNspr(url):
|
||||||
url.getServer(), url.getPort(),
|
|
||||||
gameServerTimeoutMs)
|
|
||||||
|
|
||||||
if self.tcpConn:
|
|
||||||
self.tcpConn.setNoDelay(1)
|
|
||||||
self.qcr.addConnection(self.tcpConn)
|
|
||||||
self.startReaderPollTask()
|
self.startReaderPollTask()
|
||||||
if successCallback:
|
if successCallback:
|
||||||
successCallback(*successArgs)
|
successCallback(*successArgs)
|
||||||
@ -250,37 +219,31 @@ class ConnectionRepository(DirectObject.DirectObject):
|
|||||||
"""Closes the previously-established connection.
|
"""Closes the previously-established connection.
|
||||||
"""
|
"""
|
||||||
self.notify.info("Closing connection to server.")
|
self.notify.info("Closing connection to server.")
|
||||||
if self.tcpConn != None:
|
CConnectionRepository.disconnect(self)
|
||||||
if self.connectHttp:
|
|
||||||
self.tcpConn.close()
|
|
||||||
else:
|
|
||||||
self.qcm.closeConnection(self.tcpConn)
|
|
||||||
self.tcpConn = None
|
|
||||||
self.stopReaderPollTask()
|
self.stopReaderPollTask()
|
||||||
|
|
||||||
def httpConnectCallback(self, ch, serverList, serverIndex,
|
def httpConnectCallback(self, ch, serverList, serverIndex,
|
||||||
successCallback, successArgs,
|
successCallback, successArgs,
|
||||||
failureCallback, failureArgs):
|
failureCallback, failureArgs):
|
||||||
if ch.isConnectionReady():
|
if ch.isConnectionReady():
|
||||||
self.tcpConn = ch.getConnection()
|
self.setConnectionHttp(ch)
|
||||||
self.tcpConn.userManagesMemory = 1
|
|
||||||
|
|
||||||
if self.recorder:
|
## if self.recorder:
|
||||||
# If we have a recorder, we wrap the connect inside a
|
## # If we have a recorder, we wrap the connect inside a
|
||||||
# SocketStreamRecorder, which will trap incoming data
|
## # SocketStreamRecorder, which will trap incoming data
|
||||||
# when the recorder is set to record mode. (It will
|
## # when the recorder is set to record mode. (It will
|
||||||
# also play back data when the recorder is in playback
|
## # also play back data when the recorder is in playback
|
||||||
# mode, but in that case we never get this far in the
|
## # mode, but in that case we never get this far in the
|
||||||
# code, since we just create an empty
|
## # code, since we just create an empty
|
||||||
# SocketStreamRecorder without actually connecting to
|
## # SocketStreamRecorder without actually connecting to
|
||||||
# the gameserver.)
|
## # the gameserver.)
|
||||||
stream = SocketStreamRecorder(self.tcpConn, 1)
|
## stream = SocketStreamRecorder(self.tcpConn, 1)
|
||||||
self.recorder.addRecorder('gameserver', stream)
|
## self.recorder.addRecorder('gameserver', stream)
|
||||||
|
|
||||||
# In this case, we pass ownership of the original
|
## # In this case, we pass ownership of the original
|
||||||
# connection to the SocketStreamRecorder object.
|
## # connection to the SocketStreamRecorder object.
|
||||||
self.tcpConn.userManagesMemory = 0
|
## self.tcpConn.userManagesMemory = 0
|
||||||
self.tcpConn = stream
|
## self.tcpConn = stream
|
||||||
|
|
||||||
self.startReaderPollTask()
|
self.startReaderPollTask()
|
||||||
if successCallback:
|
if successCallback:
|
||||||
@ -334,68 +297,17 @@ class ConnectionRepository(DirectObject.DirectObject):
|
|||||||
return Task.cont
|
return Task.cont
|
||||||
|
|
||||||
def readerPollOnce(self):
|
def readerPollOnce(self):
|
||||||
# we simulate the network plug being pulled by setting tcpConn
|
if self.checkDatagram():
|
||||||
# to None; enforce that condition
|
dg = PyDatagram()
|
||||||
if not self.tcpConn:
|
self.getDatagram(dg)
|
||||||
return 0
|
self.handleDatagram(dg)
|
||||||
|
return 1
|
||||||
|
|
||||||
# Make sure any recently-sent datagrams are flushed when the
|
# Unable to receive a datagram: did we lose the connection?
|
||||||
# time expires, if we're in collect-tcp mode.
|
if not self.isConnected():
|
||||||
self.tcpConn.considerFlush()
|
self.stopReaderPollTask()
|
||||||
|
self.lostConnection()
|
||||||
if self.rsDoReport:
|
return 0
|
||||||
self.reportReaderStatistics()
|
|
||||||
|
|
||||||
if self.connectHttp:
|
|
||||||
datagram = PyDatagram()
|
|
||||||
if self.tcpConn.receiveDatagram(datagram):
|
|
||||||
if self.rsDoReport:
|
|
||||||
self.rsDatagramCount += 1
|
|
||||||
self.handleDatagram(datagram)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
# Unable to receive a datagram: did we lose the connection?
|
|
||||||
if self.tcpConn.isClosed():
|
|
||||||
self.tcpConn = None
|
|
||||||
self.stopReaderPollTask()
|
|
||||||
self.lostConnection()
|
|
||||||
return 0
|
|
||||||
|
|
||||||
else:
|
|
||||||
self.ensureValidConnection()
|
|
||||||
if self.qcr.dataAvailable():
|
|
||||||
datagram = NetDatagram()
|
|
||||||
if self.qcr.getData(datagram):
|
|
||||||
if self.rsDoReport:
|
|
||||||
self.rsDatagramCount += 1
|
|
||||||
self.handleDatagram(datagram)
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def flush(self):
|
|
||||||
# Ensure the latest has been sent to the server.
|
|
||||||
if self.tcpConn:
|
|
||||||
self.tcpConn.flush()
|
|
||||||
|
|
||||||
def ensureValidConnection(self):
|
|
||||||
# Was the connection reset?
|
|
||||||
if self.connectHttp:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
if self.qcm.resetConnectionAvailable():
|
|
||||||
resetConnectionPointer = PointerToConnection()
|
|
||||||
if self.qcm.getResetConnection(resetConnectionPointer):
|
|
||||||
resetConn = resetConnectionPointer.p()
|
|
||||||
self.qcm.closeConnection(resetConn)
|
|
||||||
# if we've simulated a network plug pull, restore the
|
|
||||||
# simulated plug
|
|
||||||
self.restoreNetworkPlug()
|
|
||||||
if self.tcpConn.this == resetConn.this:
|
|
||||||
self.tcpConn = None
|
|
||||||
self.stopReaderPollTask()
|
|
||||||
self.lostConnection()
|
|
||||||
else:
|
|
||||||
self.notify.warning("Lost unknown connection.")
|
|
||||||
|
|
||||||
def lostConnection(self):
|
def lostConnection(self):
|
||||||
# This should be overrided by a derived class to handle an
|
# This should be overrided by a derived class to handle an
|
||||||
@ -407,50 +319,22 @@ class ConnectionRepository(DirectObject.DirectObject):
|
|||||||
# inherit from it need to make their own handleDatagram method
|
# inherit from it need to make their own handleDatagram method
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def reportReaderStatistics(self):
|
|
||||||
now = globalClock.getRealTime()
|
|
||||||
if now - self.rsLastUpdate < self.rsUpdateInterval:
|
|
||||||
return
|
|
||||||
|
|
||||||
self.rsLastUpdate = now
|
|
||||||
self.notify.info("Received %s datagrams" % (self.rsDatagramCount))
|
|
||||||
if self.rsUpdateObjs:
|
|
||||||
self.notify.info("Updates: %s" % (self.rsUpdateObjs))
|
|
||||||
|
|
||||||
self.rsDatagramCount = 0
|
|
||||||
self.rsUpdateObjs = {}
|
|
||||||
|
|
||||||
def send(self, datagram):
|
def send(self, datagram):
|
||||||
#if self.notify.getDebug():
|
self.sendDatagram(datagram)
|
||||||
# print "ConnectionRepository sending datagram:"
|
|
||||||
# datagram.dumpHex(ostream)
|
|
||||||
|
|
||||||
if not self.tcpConn:
|
|
||||||
self.notify.warning("Unable to send message after connection is closed.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.connectHttp:
|
|
||||||
if not self.tcpConn.sendDatagram(datagram):
|
|
||||||
self.notify.warning("Could not send datagram.")
|
|
||||||
else:
|
|
||||||
self.cw.send(datagram, self.tcpConn)
|
|
||||||
|
|
||||||
|
|
||||||
# debugging funcs for simulating a network-plug-pull
|
# debugging funcs for simulating a network-plug-pull
|
||||||
def pullNetworkPlug(self):
|
def pullNetworkPlug(self):
|
||||||
self.restoreNetworkPlug()
|
|
||||||
self.notify.warning('*** SIMULATING A NETWORK-PLUG-PULL ***')
|
self.notify.warning('*** SIMULATING A NETWORK-PLUG-PULL ***')
|
||||||
self.hijackedTcpConn = self.tcpConn
|
self.setSimulatedDisconnect(1)
|
||||||
self.tcpConn = None
|
|
||||||
|
|
||||||
def networkPlugPulled(self):
|
def networkPlugPulled(self):
|
||||||
return hasattr(self, 'hijackedTcpConn')
|
return self.getSimulatedDisconnect()
|
||||||
|
|
||||||
def restoreNetworkPlug(self):
|
def restoreNetworkPlug(self):
|
||||||
if self.networkPlugPulled():
|
if self.networkPlugPulled():
|
||||||
self.notify.info('*** RESTORING SIMULATED PULLED-NETWORK-PLUG ***')
|
self.notify.info('*** RESTORING SIMULATED PULLED-NETWORK-PLUG ***')
|
||||||
self.tcpConn = self.hijackedTcpConn
|
self.setSimulatedDisconnect(0)
|
||||||
del self.hijackedTcpConn
|
|
||||||
|
|
||||||
def doFind(self, str):
|
def doFind(self, str):
|
||||||
""" returns list of distributed objects with matching str in value """
|
""" returns list of distributed objects with matching str in value """
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
"""ServerRepository module: contains the ServerRepository class"""
|
|
||||||
|
|
||||||
from PandaModules import *
|
|
||||||
from TaskManagerGlobal import *
|
|
||||||
from MsgTypes import *
|
|
||||||
import Task
|
|
||||||
import DirectNotifyGlobal
|
|
||||||
from PyDatagram import PyDatagram
|
|
||||||
from PyDatagramIterator import PyDatagramIterator
|
|
||||||
|
|
||||||
class ServerRepository:
|
|
||||||
|
|
||||||
def __init__(self, tcpPort, udpPort):
|
|
||||||
self.qcm = QueuedConnectionManager()
|
|
||||||
self.qcl = QueuedConnectionListener(self.qcm, 0)
|
|
||||||
self.qcr = QueuedConnectionReader(self.qcm, 0)
|
|
||||||
self.cw = ConnectionWriter(self.qcm,0)
|
|
||||||
self.tcpRendezvous = self.qcm.openTCPServerRendezvous(tcpPort, 10)
|
|
||||||
print self.tcpRendezvous
|
|
||||||
self.qcl.addConnection(self.tcpRendezvous)
|
|
||||||
self.startListenerPollTask()
|
|
||||||
self.startReaderPollTask()
|
|
||||||
self.startResetPollTask()
|
|
||||||
|
|
||||||
def startListenerPollTask(self):
|
|
||||||
taskMgr.add(self.listenerPoll, "serverListenerPollTask")
|
|
||||||
|
|
||||||
def listenerPoll(self, task):
|
|
||||||
if self.qcl.newConnectionAvailable():
|
|
||||||
print "New connection is available"
|
|
||||||
rendezvous = PointerToConnection()
|
|
||||||
netAddress = NetAddress()
|
|
||||||
newConnection = PointerToConnection()
|
|
||||||
retVal = self.qcl.getNewConnection(rendezvous, netAddress,
|
|
||||||
newConnection)
|
|
||||||
if retVal:
|
|
||||||
# Crazy dereferencing
|
|
||||||
newConnection=newConnection.p()
|
|
||||||
self.qcr.addConnection(newConnection)
|
|
||||||
print "Got a connection!"
|
|
||||||
self.lastConnection = newConnection
|
|
||||||
else:
|
|
||||||
ServerRepository.notify.warning(
|
|
||||||
"getNewConnection returned false")
|
|
||||||
return Task.cont
|
|
||||||
|
|
||||||
def startReaderPollTask(self):
|
|
||||||
taskMgr.add(self.readerPollUntilEmpty, "serverReaderPollTask")
|
|
||||||
|
|
||||||
def readerPollUntilEmpty(self, task):
|
|
||||||
while self.readerPollOnce():
|
|
||||||
pass
|
|
||||||
return Task.cont
|
|
||||||
|
|
||||||
def readerPollOnce(self):
|
|
||||||
availGetVal = self.qcr.dataAvailable()
|
|
||||||
if availGetVal:
|
|
||||||
datagram = NetDatagram()
|
|
||||||
readRetVal = self.qcr.getData(datagram)
|
|
||||||
if readRetVal:
|
|
||||||
self.handleDatagram(datagram)
|
|
||||||
else:
|
|
||||||
ClientRepository.notify.warning("getData returned false")
|
|
||||||
return availGetVal
|
|
||||||
|
|
||||||
def handleDatagram(self, datagram):
|
|
||||||
print "Server got a datagram!"
|
|
||||||
dgi = PyDatagramIterator(datagram)
|
|
||||||
print dgi.getUint16()
|
|
||||||
print dgi.getString()
|
|
||||||
print dgi.getUint32()
|
|
||||||
print dgi.getUint16()
|
|
||||||
|
|
||||||
newDatagram = PyDatagram()
|
|
||||||
newDatagram.addUint16(LOGIN_RESPONSE)
|
|
||||||
newDatagram.addUint8(ord('s'))
|
|
||||||
self.cw.send(newDatagram, self.lastConnection)
|
|
||||||
|
|
||||||
def sendAvatarGenerate(self):
|
|
||||||
datagram = PyDatagram()
|
|
||||||
# Message type is 1
|
|
||||||
datagram.addUint16(ALL_OBJECT_GENERATE_WITH_REQUIRED)
|
|
||||||
# Avatar class type is 2
|
|
||||||
datagram.addUint8(2)
|
|
||||||
# A sample id
|
|
||||||
datagram.addUint32(10)
|
|
||||||
# The only required field is the zone field
|
|
||||||
datagram.addUint32(999)
|
|
||||||
self.cw.send(datagram, self.lastConnection)
|
|
||||||
|
|
||||||
def startResetPollTask(self):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def resetPollUntilEmpty(self):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def resetPollOnce(self):
|
|
||||||
return None
|
|
||||||
|
|
@ -1,3 +1,18 @@
|
|||||||
// For now, since we are not installing Python files, this file can
|
#begin lib_target
|
||||||
// remain empty.
|
#define BUILD_TARGET $[HAVE_PYTHON]
|
||||||
|
|
||||||
|
#define TARGET distributed
|
||||||
|
#define LOCAL_LIBS \
|
||||||
|
directbase
|
||||||
|
#define OTHER_LIBS \
|
||||||
|
downloader:c net:c panda:m express:c pandaexpress:m \
|
||||||
|
interrogatedb:c dconfig:c dtoolconfig:m \
|
||||||
|
dtoolutil:c dtoolbase:c dtool:m
|
||||||
|
|
||||||
|
#define SOURCES \
|
||||||
|
config_distributed.cxx config_distributed.h \
|
||||||
|
cConnectionRepository.cxx cConnectionRepository.I \
|
||||||
|
cConnectionRepository.h
|
||||||
|
|
||||||
|
#define IGATESCAN all
|
||||||
|
#end lib_target
|
||||||
|
97
direct/src/distributed/cConnectionRepository.I
Normal file
97
direct/src/distributed/cConnectionRepository.I
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
// Filename: cConnectionRepository.I
|
||||||
|
// Created by: drose (17May04)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_NSPR
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::get_qcm
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the QueuedConnectionManager object associated
|
||||||
|
// with the repository.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE QueuedConnectionManager &CConnectionRepository::
|
||||||
|
get_qcm() {
|
||||||
|
return _qcm;
|
||||||
|
}
|
||||||
|
#endif // HAVE_NSPR
|
||||||
|
|
||||||
|
#ifdef HAVE_NSPR
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::get_cw
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the ConnectionWriter object associated
|
||||||
|
// with the repository.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE ConnectionWriter &CConnectionRepository::
|
||||||
|
get_cw() {
|
||||||
|
return _cw;
|
||||||
|
}
|
||||||
|
#endif // HAVE_NSPR
|
||||||
|
|
||||||
|
#ifdef HAVE_NSPR
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::get_qcr
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the QueuedConnectionReader object associated
|
||||||
|
// with the repository.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE QueuedConnectionReader &CConnectionRepository::
|
||||||
|
get_qcr() {
|
||||||
|
return _qcr;
|
||||||
|
}
|
||||||
|
#endif // HAVE_NSPR
|
||||||
|
|
||||||
|
INLINE ConnectionWriter &get_cw();
|
||||||
|
INLINE QueuedConnectionReader &get_qcr();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::get_datagram
|
||||||
|
// Access: Published
|
||||||
|
// Description: Fills the datagram object with the datagram most
|
||||||
|
// recently retrieved by check_datagram().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void CConnectionRepository::
|
||||||
|
get_datagram(Datagram &dg) {
|
||||||
|
dg = _dg;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::set_simulated_disconnect
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets the simulated disconnect flag. While this is
|
||||||
|
// true, no datagrams will be retrieved from or sent to
|
||||||
|
// the server. The idea is to simulate a temporary
|
||||||
|
// network outage.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void CConnectionRepository::
|
||||||
|
set_simulated_disconnect(bool simulated_disconnect) {
|
||||||
|
_simulated_disconnect = simulated_disconnect;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::get_simulated_disconnect
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the simulated disconnect flag. While this is
|
||||||
|
// true, no datagrams will be retrieved from or sent to
|
||||||
|
// the server. The idea is to simulate a temporary
|
||||||
|
// network outage.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool CConnectionRepository::
|
||||||
|
get_simulated_disconnect() const {
|
||||||
|
return _simulated_disconnect;
|
||||||
|
}
|
305
direct/src/distributed/cConnectionRepository.cxx
Normal file
305
direct/src/distributed/cConnectionRepository.cxx
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
// Filename: cConnectionRepository.cxx
|
||||||
|
// Created by: drose (17May04)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "cConnectionRepository.h"
|
||||||
|
#include "config_distributed.h"
|
||||||
|
#include "httpChannel.h"
|
||||||
|
#include "urlSpec.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::Constructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
CConnectionRepository::
|
||||||
|
CConnectionRepository() :
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
_http_conn(NULL),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NSPR
|
||||||
|
_cw(&_qcm, 0),
|
||||||
|
_qcr(&_qcm, 0),
|
||||||
|
#endif
|
||||||
|
_simulated_disconnect(false)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_NSPR
|
||||||
|
if (min_lag != 0.0 || max_lag != 0.0) {
|
||||||
|
_qcr.start_delay(min_lag, max_lag);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::Destructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
CConnectionRepository::
|
||||||
|
~CConnectionRepository() {
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::set_connection_http
|
||||||
|
// Access: Published
|
||||||
|
// Description: Once a connection has been established via the HTTP
|
||||||
|
// interface, gets the connection and uses it. The
|
||||||
|
// supplied HTTPChannel object must have a connection
|
||||||
|
// available via get_connection().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CConnectionRepository::
|
||||||
|
set_connection_http(HTTPChannel *channel) {
|
||||||
|
disconnect();
|
||||||
|
nassertv(channel->is_connection_ready());
|
||||||
|
_http_conn = channel->get_connection();
|
||||||
|
}
|
||||||
|
#endif // HAVE_SSL
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_NSPR
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::try_connect_nspr
|
||||||
|
// Access: Published
|
||||||
|
// Description: Uses NSPR to try to connect to the server and port
|
||||||
|
// named in the indicated URL. Returns true if
|
||||||
|
// successful, false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool CConnectionRepository::
|
||||||
|
try_connect_nspr(const URLSpec &url) {
|
||||||
|
disconnect();
|
||||||
|
|
||||||
|
_nspr_conn =
|
||||||
|
_qcm.open_TCP_client_connection(url.get_server(), url.get_port(),
|
||||||
|
game_server_timeout_ms);
|
||||||
|
|
||||||
|
if (_nspr_conn != (Connection *)NULL) {
|
||||||
|
_nspr_conn->set_no_delay(true);
|
||||||
|
_qcr.add_connection(_nspr_conn);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif // HAVE_NSPR
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::check_datagram
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns true if a new datagram is available, false
|
||||||
|
// otherwise. If the return value is true, the new
|
||||||
|
// datagram may be retrieved via get_datagram().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool CConnectionRepository::
|
||||||
|
check_datagram() {
|
||||||
|
if (_simulated_disconnect) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_check_datagram();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::is_connected
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns true if the connection to the gameserver is
|
||||||
|
// established and still good, false if we are not
|
||||||
|
// connected. A false value means either (a) we never
|
||||||
|
// successfully connected, (b) we explicitly called
|
||||||
|
// disconnect(), or (c) we were connected, but the
|
||||||
|
// connection was spontaneously lost.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool CConnectionRepository::
|
||||||
|
is_connected() {
|
||||||
|
#ifdef HAVE_NSPR
|
||||||
|
if (_nspr_conn) {
|
||||||
|
if (_qcm.reset_connection_available()) {
|
||||||
|
PT(Connection) reset_connection;
|
||||||
|
if (_qcm.get_reset_connection(reset_connection)) {
|
||||||
|
_qcm.close_connection(reset_connection);
|
||||||
|
if (reset_connection == _nspr_conn) {
|
||||||
|
// Whoops, lost our connection.
|
||||||
|
_nspr_conn = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif // HAVE_NSPR
|
||||||
|
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
if (_http_conn) {
|
||||||
|
if (!_http_conn->is_closed()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connection lost.
|
||||||
|
delete _http_conn;
|
||||||
|
_http_conn = NULL;
|
||||||
|
}
|
||||||
|
#endif // HAVE_SSL
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::send_datagram
|
||||||
|
// Access: Published
|
||||||
|
// Description: Queues the indicated datagram for sending to the
|
||||||
|
// server. It may not get send immediately if
|
||||||
|
// collect_tcp is in effect; call flush() to guarantee
|
||||||
|
// it is sent now.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool CConnectionRepository::
|
||||||
|
send_datagram(const Datagram &dg) {
|
||||||
|
if (_simulated_disconnect) {
|
||||||
|
distributed_cat.warning()
|
||||||
|
<< "Unable to send datagram during simulated disconnect.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_NSPR
|
||||||
|
if (_nspr_conn) {
|
||||||
|
_cw.send(dg, _nspr_conn);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif // HAVE_NSPR
|
||||||
|
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
if (_http_conn) {
|
||||||
|
if (!_http_conn->send_datagram(dg)) {
|
||||||
|
distributed_cat.warning()
|
||||||
|
<< "Could not send datagram.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif // HAVE_SSL
|
||||||
|
|
||||||
|
distributed_cat.warning()
|
||||||
|
<< "Unable to send datagram after connection is closed.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::consider_flush
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sends the most recently queued data if enough time
|
||||||
|
// has elapsed. This only has meaning if
|
||||||
|
// set_collect_tcp() has been set to true.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool CConnectionRepository::
|
||||||
|
consider_flush() {
|
||||||
|
if (_simulated_disconnect) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_NSPR
|
||||||
|
if (_nspr_conn) {
|
||||||
|
return _nspr_conn->consider_flush();
|
||||||
|
}
|
||||||
|
#endif // HAVE_NSPR
|
||||||
|
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
if (_http_conn) {
|
||||||
|
return _http_conn->consider_flush();
|
||||||
|
}
|
||||||
|
#endif // HAVE_SSL
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::flush
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sends the most recently queued data now. This only
|
||||||
|
// has meaning if set_collect_tcp() has been set to
|
||||||
|
// true.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool CConnectionRepository::
|
||||||
|
flush() {
|
||||||
|
if (_simulated_disconnect) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_NSPR
|
||||||
|
if (_nspr_conn) {
|
||||||
|
return _nspr_conn->flush();
|
||||||
|
}
|
||||||
|
#endif // HAVE_NSPR
|
||||||
|
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
if (_http_conn) {
|
||||||
|
return _http_conn->flush();
|
||||||
|
}
|
||||||
|
#endif // HAVE_SSL
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::disconnect
|
||||||
|
// Access: Published
|
||||||
|
// Description: Closes the connection to the server.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CConnectionRepository::
|
||||||
|
disconnect() {
|
||||||
|
#ifdef HAVE_NSPR
|
||||||
|
if (_nspr_conn) {
|
||||||
|
_qcm.close_connection(_nspr_conn);
|
||||||
|
_nspr_conn = NULL;
|
||||||
|
}
|
||||||
|
#endif // HAVE_NSPR
|
||||||
|
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
if (_http_conn) {
|
||||||
|
_http_conn->close();
|
||||||
|
delete _http_conn;
|
||||||
|
_http_conn = NULL;
|
||||||
|
}
|
||||||
|
#endif // HAVE_SSL
|
||||||
|
|
||||||
|
_simulated_disconnect = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CConnectionRepository::do_check_datagram
|
||||||
|
// Access: Private
|
||||||
|
// Description: The private implementation of check_datagram(), this
|
||||||
|
// gets one datagram if it is available.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool CConnectionRepository::
|
||||||
|
do_check_datagram() {
|
||||||
|
#ifdef HAVE_NSPR
|
||||||
|
if (_nspr_conn) {
|
||||||
|
_nspr_conn->consider_flush();
|
||||||
|
return (_qcr.data_available() && _qcr.get_data(_dg));
|
||||||
|
}
|
||||||
|
#endif // HAVE_NSPR
|
||||||
|
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
if (_http_conn) {
|
||||||
|
_http_conn->consider_flush();
|
||||||
|
return _http_conn->receive_datagram(_dg);
|
||||||
|
}
|
||||||
|
#endif // HAVE_SSL
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
101
direct/src/distributed/cConnectionRepository.h
Normal file
101
direct/src/distributed/cConnectionRepository.h
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// Filename: cConnectionRepository.h
|
||||||
|
// Created by: drose (17May04)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef CCONNECTIONREPOSITORY_H
|
||||||
|
#define CCONNECTIONREPOSITORY_H
|
||||||
|
|
||||||
|
#include "directbase.h"
|
||||||
|
#include "pointerTo.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_NSPR
|
||||||
|
#include "queuedConnectionManager.h"
|
||||||
|
#include "connectionWriter.h"
|
||||||
|
#include "queuedConnectionReader.h"
|
||||||
|
#include "connection.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class URLSpec;
|
||||||
|
class HTTPChannel;
|
||||||
|
class SocketStream;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : CConnectionRepository
|
||||||
|
// Description : This class implements the C++ side of the
|
||||||
|
// ConnectionRepository object. In particular, it
|
||||||
|
// manages the connection to the server once it has been
|
||||||
|
// opened (but does not open it directly). It manages
|
||||||
|
// reading and writing datagrams on the connection and
|
||||||
|
// monitoring for unexpected disconnects as well as
|
||||||
|
// handling intentional disconnects.
|
||||||
|
//
|
||||||
|
// Certain server messages, like field updates, are
|
||||||
|
// handled entirely within the C++ layer, while server
|
||||||
|
// messages that are not understood by the C++ layer are
|
||||||
|
// returned up to the Python layer for processing.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_DIRECT CConnectionRepository {
|
||||||
|
PUBLISHED:
|
||||||
|
CConnectionRepository();
|
||||||
|
~CConnectionRepository();
|
||||||
|
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
void set_connection_http(HTTPChannel *channel);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NSPR
|
||||||
|
bool try_connect_nspr(const URLSpec &url);
|
||||||
|
|
||||||
|
INLINE QueuedConnectionManager &get_qcm();
|
||||||
|
INLINE ConnectionWriter &get_cw();
|
||||||
|
INLINE QueuedConnectionReader &get_qcr();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool check_datagram();
|
||||||
|
INLINE void get_datagram(Datagram &dg);
|
||||||
|
bool is_connected();
|
||||||
|
|
||||||
|
bool send_datagram(const Datagram &dg);
|
||||||
|
|
||||||
|
bool consider_flush();
|
||||||
|
bool flush();
|
||||||
|
|
||||||
|
void disconnect();
|
||||||
|
|
||||||
|
INLINE void set_simulated_disconnect(bool simulated_disconnect);
|
||||||
|
INLINE bool get_simulated_disconnect() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool do_check_datagram();
|
||||||
|
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
SocketStream *_http_conn;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_NSPR
|
||||||
|
QueuedConnectionManager _qcm;
|
||||||
|
ConnectionWriter _cw;
|
||||||
|
QueuedConnectionReader _qcr;
|
||||||
|
PT(Connection) _nspr_conn;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Datagram _dg;
|
||||||
|
bool _simulated_disconnect;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "cConnectionRepository.I"
|
||||||
|
|
||||||
|
#endif // CCONNECTIONREPOSITORY_H
|
57
direct/src/distributed/config_distributed.cxx
Normal file
57
direct/src/distributed/config_distributed.cxx
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// Filename: config_distributed.cxx
|
||||||
|
// Created by: drose (19May04)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "config_distributed.h"
|
||||||
|
#include "dconfig.h"
|
||||||
|
|
||||||
|
Configure(config_distributed);
|
||||||
|
NotifyCategoryDef(distributed, "");
|
||||||
|
|
||||||
|
ConfigureFn(config_distributed) {
|
||||||
|
init_libdistributed();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This represents the amount of time to block waiting for the TCP
|
||||||
|
// connection to the game server. It is only used when the connection
|
||||||
|
// method is NSPR.
|
||||||
|
const int game_server_timeout_ms = config_distributed.GetInt("game-server-timeout-ms", 20000);
|
||||||
|
|
||||||
|
// These represent the time in seconds by which to artificially lag
|
||||||
|
// inbound messages. It is only used when the connection method is
|
||||||
|
// NSPR.
|
||||||
|
const double min_lag = config_distributed.GetDouble("min-lag", 0.0);
|
||||||
|
const double max_lag = config_distributed.GetDouble("max-lag", 0.0);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: init_libdistributed
|
||||||
|
// Description: Initializes the library. This must be called at
|
||||||
|
// least once before any of the functions or classes in
|
||||||
|
// this library can be used. Normally it will be
|
||||||
|
// called by the static initializers and need not be
|
||||||
|
// called explicitly, but special cases exist.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void
|
||||||
|
init_libdistributed() {
|
||||||
|
static bool initialized = false;
|
||||||
|
if (initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
initialized = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
35
direct/src/distributed/config_distributed.h
Normal file
35
direct/src/distributed/config_distributed.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Filename: config_distributed.h
|
||||||
|
// Created by: drose (19May04)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISTRIBUTED_H
|
||||||
|
#define CONFIG_DISTRIBUTED_H
|
||||||
|
|
||||||
|
#include "directbase.h"
|
||||||
|
#include "notifyCategoryProxy.h"
|
||||||
|
#include "dconfig.h"
|
||||||
|
|
||||||
|
NotifyCategoryDecl(distributed, EXPCL_DIRECT, EXPTP_DIRECT);
|
||||||
|
|
||||||
|
extern const int game_server_timeout_ms;
|
||||||
|
extern const double min_lag;
|
||||||
|
extern const double max_lag;
|
||||||
|
|
||||||
|
extern EXPCL_DIRECT void init_libdistributed();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user