Lobby utility library:
* Create another custom context manager (can be used in with-statement) for creating a connection to a given (host, port): "connection" - Perform manual name-resolution, using each returned entry until one can be succesfully connected to (allows IPv4 + IPv6 through the same function) * Use this context manager instead of connecting manually git-svn-id: https://warzone2100.svn.sourceforge.net/svnroot/warzone2100/trunk@7305 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
24cc8fda66
commit
7c49ed6628
|
@ -40,6 +40,25 @@ def _socket(family = socket.AF_INET, type = socket.SOCK_STREAM, proto = 0):
|
|||
finally:
|
||||
s.close()
|
||||
|
||||
@contextmanager
|
||||
def connection(host, port, family = socket.AF_UNSPEC, socktype = socket.SOCK_STREAM):
|
||||
addrs = socket.getaddrinfo(host, port, family, socktype)
|
||||
for i in xrange(len(addrs)):
|
||||
(family, socktype, proto, canonname, sockaddr) = addrs[i]
|
||||
with _socket(family, socktype, proto) as s:
|
||||
timeout = s.gettimeout()
|
||||
s.settimeout(10.0)
|
||||
try:
|
||||
s.connect(sockaddr)
|
||||
except socket.timeout:
|
||||
if i == (len(addrs) - 1):
|
||||
raise
|
||||
continue
|
||||
s.settimeout(timeout)
|
||||
|
||||
yield s
|
||||
return
|
||||
|
||||
def _encodeCString(string, buf_len):
|
||||
# If we haven't got a string return an empty one
|
||||
if not string:
|
||||
|
@ -118,22 +137,17 @@ class BaseProtocol(object):
|
|||
|
||||
def check(self, game):
|
||||
"""Check we can connect to the game's host."""
|
||||
with _socket(socket.AF_INET6) as s:
|
||||
try:
|
||||
logging.debug("Checking %s's vitality..." % game.host)
|
||||
s.settimeout(10.0)
|
||||
s.connect((game.host, self.gamePort))
|
||||
try:
|
||||
logging.debug("Checking %s's vitality..." % game.host)
|
||||
with connection(game.host, self.gamePort) as s:
|
||||
return True
|
||||
except (socket.error, socket.herror, socket.gaierror, socket.timeout), e:
|
||||
logging.debug("%s did not respond: %s" % (game.host, e))
|
||||
return False
|
||||
except (socket.error, socket.herror, socket.gaierror, socket.timeout), e:
|
||||
logging.debug("%s did not respond: %s" % (game.host, e))
|
||||
return False
|
||||
|
||||
def list(self, host):
|
||||
"""Retrieve a list of games from the lobby server."""
|
||||
with _socket(socket.AF_INET6) as s:
|
||||
s.settimeout(10.0)
|
||||
s.connect((host, self.lobbyPort))
|
||||
|
||||
with connection(host, self.lobbyPort) as s:
|
||||
s.send("list\0")
|
||||
for game in self.decodeMultiple(s):
|
||||
yield game
|
||||
|
|
|
@ -40,7 +40,7 @@ import time
|
|||
import struct
|
||||
from game import *
|
||||
from protocol import *
|
||||
from protocol import _socket as socket
|
||||
from protocol import connection
|
||||
|
||||
server="lobby.wz2100.net"
|
||||
protocol = Protocol()
|
||||
|
@ -84,10 +84,8 @@ def doAddGame():
|
|||
g.future3 = 0
|
||||
g.future4 = 0
|
||||
|
||||
with socket() as s:
|
||||
logging.debug("connect to lobby")
|
||||
s.settimeout(10.0)
|
||||
s.connect((server, protocol.lobbyPort))
|
||||
logging.debug("connect to lobby")
|
||||
with connection(server, protocol.lobbyPort) as s:
|
||||
s.send("addg\0")
|
||||
protocol.encodeSingle(g, s)
|
||||
#hold the game open for 10 seconds
|
||||
|
|
Loading…
Reference in New Issue