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:
|
finally:
|
||||||
s.close()
|
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):
|
def _encodeCString(string, buf_len):
|
||||||
# If we haven't got a string return an empty one
|
# If we haven't got a string return an empty one
|
||||||
if not string:
|
if not string:
|
||||||
|
@ -118,22 +137,17 @@ class BaseProtocol(object):
|
||||||
|
|
||||||
def check(self, game):
|
def check(self, game):
|
||||||
"""Check we can connect to the game's host."""
|
"""Check we can connect to the game's host."""
|
||||||
with _socket(socket.AF_INET6) as s:
|
try:
|
||||||
try:
|
logging.debug("Checking %s's vitality..." % game.host)
|
||||||
logging.debug("Checking %s's vitality..." % game.host)
|
with connection(game.host, self.gamePort) as s:
|
||||||
s.settimeout(10.0)
|
|
||||||
s.connect((game.host, self.gamePort))
|
|
||||||
return True
|
return True
|
||||||
except (socket.error, socket.herror, socket.gaierror, socket.timeout), e:
|
except (socket.error, socket.herror, socket.gaierror, socket.timeout), e:
|
||||||
logging.debug("%s did not respond: %s" % (game.host, e))
|
logging.debug("%s did not respond: %s" % (game.host, e))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def list(self, host):
|
def list(self, host):
|
||||||
"""Retrieve a list of games from the lobby server."""
|
"""Retrieve a list of games from the lobby server."""
|
||||||
with _socket(socket.AF_INET6) as s:
|
with connection(host, self.lobbyPort) as s:
|
||||||
s.settimeout(10.0)
|
|
||||||
s.connect((host, self.lobbyPort))
|
|
||||||
|
|
||||||
s.send("list\0")
|
s.send("list\0")
|
||||||
for game in self.decodeMultiple(s):
|
for game in self.decodeMultiple(s):
|
||||||
yield game
|
yield game
|
||||||
|
|
|
@ -40,7 +40,7 @@ import time
|
||||||
import struct
|
import struct
|
||||||
from game import *
|
from game import *
|
||||||
from protocol import *
|
from protocol import *
|
||||||
from protocol import _socket as socket
|
from protocol import connection
|
||||||
|
|
||||||
server="lobby.wz2100.net"
|
server="lobby.wz2100.net"
|
||||||
protocol = Protocol()
|
protocol = Protocol()
|
||||||
|
@ -84,10 +84,8 @@ def doAddGame():
|
||||||
g.future3 = 0
|
g.future3 = 0
|
||||||
g.future4 = 0
|
g.future4 = 0
|
||||||
|
|
||||||
with socket() as s:
|
logging.debug("connect to lobby")
|
||||||
logging.debug("connect to lobby")
|
with connection(server, protocol.lobbyPort) as s:
|
||||||
s.settimeout(10.0)
|
|
||||||
s.connect((server, protocol.lobbyPort))
|
|
||||||
s.send("addg\0")
|
s.send("addg\0")
|
||||||
protocol.encodeSingle(g, s)
|
protocol.encodeSingle(g, s)
|
||||||
#hold the game open for 10 seconds
|
#hold the game open for 10 seconds
|
||||||
|
|
Loading…
Reference in New Issue