-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathstart.py
166 lines (142 loc) · 4.27 KB
/
start.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
timeout = 1800 # 超过此时长游戏未继续进行则删除游戏进程,单位s
###############################################################################################
version = 1.3
###############################################################################################
import os
import argparse
import time
import json
import threading
from douzero.evaluation.simulation import init, next, env_list
from http.server import HTTPServer, BaseHTTPRequestHandler
lock = threading.Lock()
"""post data
{
action: "", #init/play
data: {}
#(init:){
"pid", # process_id
"three_landlord_cards",
"ai_amount": int,
"player_data":[
{
"model", #WP/ADP/...
"hand_cards",
"position_code"
},
{
"model", #WP/ADP/...
"hand_cards",
"position_code",
}
]
}
(play:){
"pid",
"player",
"cards"
}
}
"""
"""response data
{
type: "", # init/step
action: "", # receive/play
status: "", # ok/fail
msg: "", # status为fail时不为空
data: {} # status为fail时,如果能获取到pid则为{"pid"},否则为{}
#(receive:){
"pid": str,
"game_over": boolen
}
(play:){
"pid": pid,
"play": [
{
"cards": [],
"confidence": ""
},
{
"cards": [],
"confidence": ""
}
],
"game_over": boolen
}
}
"""
class Request(BaseHTTPRequestHandler):
timeout = 3
server_version = "Beta"
def do_GET(self):
self.send_response(200)
self.send_header("type", "get")
self.end_headers()
res = json.dumps(
{
"info": "DouZero API",
"version": version,
"link": [
"https://github.com/pineoncellar/DouZero_API",
"https://github.com/kwai/DouZero",
],
}
)
res = str(res).encode()
self.wfile.write(res)
def do_POST(self):
data = self.rfile.read(int(self.headers["content-length"]))
data = data.decode()
data = json.loads(data)
res = {}
print(f"get post data: {data}\n")
if data["action"] == "init": # 初始化阶段
print(f"get initialize request, initializing...")
res = init(data["data"])
elif data["action"] == "play": # 出牌阶段
res = next(data["data"])
self.send_response(200)
self.send_header("type", "post")
self.end_headers()
print(f"response:{res}\n")
res = json.dumps(res)
res = str(res).encode()
self.wfile.write(res)
class TimeCheck(threading.Thread):
def run(self):
while True:
global env_list
with lock:
timestamp = time.time()
tmp_env_list = dict(env_list.items())
for k, v in tmp_env_list.items():
existed_times = timestamp - v.timestamp
if existed_times > timeout:
del env_list[k]
print(f"pid:{k} game timeout, deleted.")
time.sleep(300)
if __name__ == "__main__":
print(f"DouZero_API . ver{version}")
# 才疏学浅,不知道这两行的用途与意义,暂且保留
os.environ["KMP_DUPLICATE_LIB_OK"] = "True"
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
time_check = TimeCheck()
time_check.start()
parser = argparse.ArgumentParser(description="Start script with port and host")
parser.add_argument(
"-H", "--host", type=str, help="Host address", default="0.0.0.0"
)
parser.add_argument("-p", "--port", type=int, help="Port number", default=24813)
args = parser.parse_args()
host = args.host
port = args.port
host = (host, port)
print(f"Douzero_API has been launched successfully.")
print(f"Server listening on {host[0]}:{port}.")
server = HTTPServer(host, Request)
try:
server.serve_forever() # 开启服务
except KeyboardInterrupt:
server.server_close()
print("Server closed.")
exit(0)