mirror of
https://github.com/abakh/nbsdgames
synced 2025-04-28 14:09:32 -04:00
171 lines
5.6 KiB
Python
171 lines
5.6 KiB
Python
#! /usr/bin/env python
|
|
|
|
# __________
|
|
import os, sys
|
|
if __name__ == '__main__':
|
|
LOCALDIR = sys.argv[0]
|
|
else:
|
|
LOCALDIR = __file__
|
|
try:
|
|
LOCALDIR = os.readlink(LOCALDIR)
|
|
except:
|
|
pass
|
|
LOCALDIR = os.path.dirname(os.path.abspath(LOCALDIR))
|
|
# ----------
|
|
|
|
sys.path.insert(0, os.path.dirname(LOCALDIR))
|
|
sys.path.insert(0, LOCALDIR)
|
|
import common
|
|
from . import pclient
|
|
from . import modes
|
|
|
|
|
|
UdpLookForServer = [
|
|
'127.0.0.1',
|
|
'<broadcast>',
|
|
]
|
|
|
|
def parse_cmdline(argv):
|
|
# parse command-line
|
|
def usage():
|
|
print('usage:', file=sys.stderr)
|
|
print(' python Client.py [-d#] [-s#] [extra options] [host[:port]]', file=sys.stderr)
|
|
print(file=sys.stderr)
|
|
print('options:', file=sys.stderr)
|
|
print(' host search for a game on the given machine', file=sys.stderr)
|
|
print(' host:port connect to the given game server', file=sys.stderr)
|
|
print(' (default search for any local server)', file=sys.stderr)
|
|
print(' -d# --display=# graphic driver (see below)', file=sys.stderr)
|
|
print(' -s# --sound=# sound driver (see below)', file=sys.stderr)
|
|
print(' --music=no disable background music', file=sys.stderr)
|
|
print(' -h --help display this text', file=sys.stderr)
|
|
print(' -m --metaserver connect with the help of the metaserver', file=sys.stderr)
|
|
print(' (list servers with Client.py -m)', file=sys.stderr)
|
|
print(' -t --tcp for slow or proxy connections', file=sys.stderr)
|
|
print(' -u --udp for fast direct connections', file=sys.stderr)
|
|
print(' (default is to autodetect tcp or udp)', file=sys.stderr)
|
|
print(' --port UDP=# or #:# fixed inbound udp port or host:port', file=sys.stderr)
|
|
print(' --port TCP=# fixed inbound tcp port (-m only)', file=sys.stderr)
|
|
print(file=sys.stderr)
|
|
print('graphic drivers:', file=sys.stderr)
|
|
for info in modes.graphicmodeslist():
|
|
info.printline(sys.stderr)
|
|
print(file=sys.stderr)
|
|
print('sound drivers:', file=sys.stderr)
|
|
for info in modes.soundmodeslist():
|
|
info.printline(sys.stderr)
|
|
print(file=sys.stderr)
|
|
sys.exit(2)
|
|
|
|
shortopts = 'd:s:htum'
|
|
longopts = ['display=', 'sound=', 'music=', 'help', 'tcp', 'udp',
|
|
'cfg=', 'metaserver', 'port=']
|
|
for info in modes.graphicmodeslist() + modes.soundmodeslist():
|
|
short, int = info.getformaloptions()
|
|
shortopts += short
|
|
longopts += int
|
|
try:
|
|
from getopt import gnu_getopt as getopt
|
|
except ImportError:
|
|
from getopt import getopt
|
|
from getopt import error
|
|
try:
|
|
opts, args = getopt(argv, shortopts, longopts)
|
|
except error as e:
|
|
print('Client.py: %s' % str(e), file=sys.stderr)
|
|
print(file=sys.stderr)
|
|
usage()
|
|
|
|
metaserver = 0
|
|
driver = sound = None
|
|
extraopts = {}
|
|
for key, value in opts:
|
|
if key in ('-d', '--display'):
|
|
driver = value
|
|
elif key in ('-s', '--sound'):
|
|
sound = value
|
|
elif key in ('-t', '--tcp'):
|
|
extraopts['udp_over_tcp'] = 1
|
|
elif key in ('-u', '--udp'):
|
|
extraopts['udp_over_tcp'] = 0
|
|
elif key in ('-m', '--metaserver'):
|
|
metaserver = 1
|
|
elif key == '--port':
|
|
import common.msgstruct
|
|
try:
|
|
portname, value = value.split('=')
|
|
if portname == 'UDP':
|
|
portname = 'CLIENT'
|
|
elif portname == 'TCP':
|
|
portname = 'BACK'
|
|
except ValueError:
|
|
portname = 'CLIENT'
|
|
if portname == 'CLIENT' and ':' in value:
|
|
udphostname, value = value.split(':')
|
|
common.msgstruct.PORTS['sendudpto'] = udphostname
|
|
common.msgstruct.PORTS[portname] = int(value)
|
|
elif key == '--cfg':
|
|
extraopts['cfgfile'] = value
|
|
elif key in ('-h', '--help'):
|
|
usage()
|
|
else:
|
|
extraopts[key] = value
|
|
mode = driver, sound, extraopts
|
|
|
|
if metaserver:
|
|
if len(args) == 0:
|
|
metalist()
|
|
sys.exit(0)
|
|
elif len(args) != 1 or ':' not in args[0]:
|
|
usage()
|
|
return metaconnect(args[0]), mode
|
|
|
|
if args:
|
|
if len(args) > 1:
|
|
usage()
|
|
hosts = args[0].split(':')
|
|
if len(hosts) == 1:
|
|
host, = hosts
|
|
from common import hostchooser
|
|
server = hostchooser.pick([host] * 5)
|
|
elif len(hosts) == 2:
|
|
host, port = hosts
|
|
try:
|
|
port = int(port)
|
|
except ValueError:
|
|
usage()
|
|
server = host, port
|
|
else:
|
|
usage()
|
|
return directconnect(server), mode
|
|
|
|
from common import hostchooser
|
|
server = hostchooser.pick(UdpLookForServer * 3)
|
|
return directconnect(server), mode
|
|
|
|
def directconnect(sockaddr):
|
|
print("connecting to %s:%d..." % sockaddr)
|
|
from socket import socket, AF_INET, SOCK_STREAM
|
|
s = socket(AF_INET, SOCK_STREAM)
|
|
s.connect(sockaddr)
|
|
return s, sockaddr
|
|
|
|
def metaconnect(metaaddr):
|
|
from metaserver import metaclient
|
|
import common.msgstruct
|
|
port = common.msgstruct.PORTS.get('BACK')
|
|
s = metaclient.meta_connect(metaaddr, port)
|
|
sockaddr = s.getpeername()
|
|
return s, sockaddr
|
|
|
|
def metalist():
|
|
from metaserver import metaclient
|
|
metaclient.print_server_list()
|
|
|
|
def main():
|
|
(s, sockaddr), mode = parse_cmdline(sys.argv[1:])
|
|
pclient.run(s, sockaddr, mode)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|