-
Notifications
You must be signed in to change notification settings - Fork 0
/
tcpclient.py
140 lines (112 loc) · 3.59 KB
/
tcpclient.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/env python
import time
import sys
import threading
import re
import string
import random
import subprocess
from socket import socket, AF_INET, SOCK_STREAM
def readline(sock):
s=""
while(sock):
c = sock.recv(1)
if ( not c ):
break
elif ( c=='\r' ):
continue
elif ( c=='\n' ):
break
else:
s += c
return s
def tcp(host, port, bot_command, user, options):
# spread out if in batch mode, to allow more random ordering on the server
time.sleep(5.0 * random.random())
# Start up the network connection
sock = socket(AF_INET, SOCK_STREAM)
sock.connect((host, port))
if sock:
sys.stderr.write("connected\n")
else:
print( "failed to connect to " + host + " on port " + str(port) )
return
# start bot
try:
bot = subprocess.Popen(bot_command,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
cwd=".")
except:
print( 'your bot ('+str(bot_command)+') failed to start!' )
return;
# send greetz and start the loop
sock.sendall("USER %s\n" % user)
while sock:
# get input, send it to bot
bot_input = ""
while sock:
line = readline(sock)
print( line )
if not line:
continue # bad connection, keep on trying
if line.startswith("INFO:"):
continue
bot_input += line + "\n"
if line.startswith("end"):
break
if line.startswith("ready"):
break
if line.startswith("go"):
break
if line.startswith("end"):
break
bot.stdin.write(bot_input)
bot.stdin.flush()
# get bot output, send to serv
client_mess=""
while 1:
answer = bot.stdout.readline()
if not answer: break
if answer.startswith("go"): break
client_mess += answer
# if there's no orders, send at least an empty line
if (client_mess==""):
client_mess="\r\n"
print( client_mess )
sock.sendall( client_mess )
try:
bot.kill()
except:
pass
def main():
usage="""
tcpclient.py host_or_ip port botpath player_nick [num_rounds]
if running on windows or if the botpath contains spaces,
you have to wrap the botpath with "", eg.: "java /x/y/MyBot", "e:\\ai\\bots\\mybot.exe"
player_nick may only contain ascii_letters, '_', and numbers
"""
if len(sys.argv) < 5:
print usage
return
host=sys.argv[1]
port=int(sys.argv[2])
botpath=sys.argv[3]
pname=sys.argv[4]
try:
rounds = int(sys.argv[5])
except:
rounds = 1
# json can't handle special chars, so weed that out before playing 2000 turns, and crashing then..
for l in pname:
if l in string.letters: continue
if l in string.digits : continue
if l =='_' : continue
print( "your botname (" + pname + ") contains invalid characters, please choose another one!" )
return
for i in range(rounds):
tcp(host, port, botpath, pname, {})
#~ # keep konsole window open (for debugging)
#~ sys.stdin.read()
if __name__ == "__main__":
main()