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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
| # encoding: utf-8
import requests
import re
import json
import os
from tqdm import tqdm
ClassName = {
"DREAM": "梦境",
"WHIZBANG": "威兹班"
}
TypeName = {
"ENCHANTMENT": "附魔",
"HERO_POWER": "英雄技能"
}
CardSetName = {
"TB": "TB乱斗模式",
"HERO_SKINS": "HERO英雄皮肤和技能",
"THE_BARRENS": "BAR贫瘠之地的锤炼",
'SCHOLOMANCE': "SCH通灵学园",
'BASIC': "CORE基本",
'BATTLEGROUNDS': "BGS酒馆战棋",
'BOOMSDAY': "BOT砰砰计划",
'BRM': "BRM黑石山的火焰",
'BLACK_TEMPLE': "BT外域的灰烬",
'DEMON_HUNTER_INITIATE': "BT恶魔猎手新兵",
'YEAR_OF_THE_DRAGON': "DRG巨龙降临",
"TGT": "AT冠军的试炼",
'GANGS': "CFM龙争虎斗加基森",
'CORE': "CORE基本",
'CREDITS': "CREDITS暴雪制作人员",
'EXPERT1': "EX经典",
'HOF': "HOF荣誉室",
'DALARAN': "DAL暗影崛起",
'DARKMOON_FAIRE': "DMF疯狂的暗月马戏团",
'DRAGONS': "DRG巨龙降临",
'NAXX': "NAX纳克萨玛斯",
'GILNEAS': "GIL女巫森林",
'GVG': "GVG地精大战侏儒",
'ICECROWN': "ICC冰封王座的骑士",
'UNGORO': "UNG勇闯安戈洛",
'LOOTAPALOOZA': "LOOT狗头人与地下世界",
'KARA': "KAR卡拉赞之夜",
'LOE': "LOE探险者协会",
'OG': "OG上古之神的低语",
'MISSIONS': "MISSIONS新手训练",
'TROLL': "TRL拉斯塔哈的大乱斗",
'TAVERNS_OF_TIME': "TOT时光酒馆",
'ULDUM': "ULD奥丹姆奇兵",
'VANILLA': "VAN经典模式"
}
file_list = requests.get("https://api.hearthstonejson.com/v1/").text
ver_list = re.findall("/v1/(\d+)/all/", file_list)
new_version = max(ver_list)
print(f"new_version: {new_version}")
print("loading global_json...")
global_json = requests.get('https://api.hearthstonejson.com/v1/strings/zhCN/GLOBAL.json').text
global_data = json.loads(global_json)
assert global_data is not None
for name in global_data:
if "GLOBAL_CLASS_" in name:
class_name = name.replace('GLOBAL_CLASS_', '')
if class_name not in ClassName:
ClassName[class_name] = global_data[name]
if "GLOBAL_CARD_SET_" in name:
card_set = name.replace('GLOBAL_CARD_SET_', '')
if card_set not in CardSetName:
CardSetName[card_set] = global_data[name]
elif "GLOBAL_CARDTYPE_" in name:
card_type = name.replace('GLOBAL_CARDTYPE_', '')
if card_type not in TypeName:
TypeName[card_type] = global_data[name]
print("loaded global_json successfully!")
print("loading card_data...")
cardJson_data = ""
cardJson_File = f'{new_version}.json'
if os.path.exists(cardJson_File):
print("--file mode")
with open(cardJson_File, "r", encoding='utf-8') as f:
cardJson_data = f.read()
assert cardJson_data != ""
else:
cardJson_url = f'https://api.hearthstonejson.com/v1/{new_version}/all/cards.json'
print(f"--online mode({cardJson_url})")
cardJson_req = requests.get(cardJson_url, stream=True)
cardJson_byte = b''
pbar = tqdm(total=-1, unit='B', unit_scale=True)
for chunk in cardJson_req.iter_content(chunk_size=1024):
assert chunk != None
cardJson_byte += chunk
pbar.update(1024)
pbar.close()
cardJson_data = cardJson_byte.decode()
assert cardJson_data != ""
with open(cardJson_File, "w", encoding='utf-8') as f:
f.write(cardJson_data)
cardData_temp = json.loads(cardJson_data)
assert cardData_temp is not None
print("loaded card_json successfully!")
cardData = {}
for c in cardData_temp:
cardData[c['id']] = c
sim_path = os.path.join(os.getcwd(), "cards")
print("loading sim_data from", sim_path)
Sim_Context = []
Sim_CardID = []
Sim_text_idx = {}
Sim_id_idx = {}
for root, dirs, files in os.walk(sim_path):
for file in files:
card_id = file.replace('Sim_', '').replace('.cs', '')
with open(os.path.join(root, file), "r", encoding='utf-8') as sim_file:
sim_content = sim_file.read()
if "public" not in sim_content:
continue
card_idx = len(Sim_Context)
Sim_Context.append(sim_content)
Sim_CardID.append(card_id)
Sim_id_idx[card_id] = card_idx
if card_id in cardData and 'text' in cardData[card_id]:
Sim_text_idx[cardData[card_id]['text']['zhCN']] = card_idx
print("loaded " + str(len(Sim_Context)) + " old_sim_data successfully!")
enum_data = ""
if not os.path.exists('sim'):
os.mkdir('sim')
print("Creating sim file and CardDB_cardIDEnum.cs")
for cardid, c in cardData.items():
sim_data = ""
basic = ""
if 'type' in c and 'name' in c and c['type'] in TypeName:
# create enum data
type = TypeName[c['type']]
name_cn = c['name']['zhCN']
name = c['name']['enUS']
card_set = c['set']
cardtext_cn = ""
cardtext = ""
if 'cardClass' in c and 'cost' in c:
if type == '法术':
basic = f"{ClassName[c['cardClass']]} 费用:{c['cost']}"
if type == '随从' and 'attack' in c and 'health' in c:
basic = f"{ClassName[c['cardClass']]} 费用:{c['cost']} 攻击力:{c['attack']} 生命值:{c['health']}"
if type == '武器' and 'attack' in c and 'durability' in c:
basic = f"{ClassName[c['cardClass']]} 费用:{c['cost']} 攻击力:{c['attack']} 耐久度:{c['durability']}"
if type == '英雄技能':
basic = f"{ClassName[c['cardClass']]} 费用:{c['cost']}"
enum_data += "/// <summary>\n"
enum_data += f"/// <para>{type} {basic}</para>\n"
enum_data += f"/// <para>{name}</para>\n"
enum_data += f"/// <para>{name_cn}</para>\n"
if 'text' in c:
cardtext_cn = c['text']['zhCN'].replace('\n', ' ')
cardtext = c['text']['enUS'].replace('\n', ' ')
enum_data += f"/// <para>{cardtext}</para>\n"
enum_data += f"/// <para>{cardtext_cn}</para>\n"
enum_data += "/// </summary>\n"
enum_data += f"{cardid} = {c['dbfId']},\n"
# create sim data
if type == '附魔':
continue
while True:
if cardid in Sim_id_idx:
sim_data = Sim_Context[Sim_id_idx[cardid]]
break
if 'text' in c and c['text']['zhCN'] in Sim_text_idx:
idx = Sim_text_idx[c['text']['zhCN']]
sim_id = Sim_CardID[idx]
if cardid not in sim_id:
sim_data = Sim_Context[idx]
# fix
sim_data = sim_data.replace(f'class Sim_{sim_id}', f'class Sim_{cardid}')
break
sim_data = "using System;\nusing System.Collections.Generic;\nusing System.Text;\n\n"
sim_data += "namespace HREngine.Bots\n{\n"
sim_data += f"\tclass Sim_{cardid} : SimTemplate //* {name_cn} {name}\n\t{{\n"
if cardtext != "":
sim_data += "\t\t//" + cardtext + "\n"
sim_data += "\t\t//" + cardtext_cn + "\n"
sim_data += "\t\t\n\t\t\n\t}\n}\n"
break
if card_set not in CardSetName:
print("check CardSetName:", cardid)
continue
# write sim data
sim_dir = f"sim\\{CardSetName[card_set]}"
if not os.path.exists(sim_dir):
os.mkdir(sim_dir)
with open(sim_dir + "\\Sim_" + cardid + ".cs", 'w', encoding='utf-8') as sim:
sim.write(sim_data)
print("Write sim_data to " + os.path.join(os.getcwd(), "sim") + " successfully!")
# write id_enum data
enum_path = os.path.join(os.getcwd(), "CardDB_cardIDEnum.cs")
enum_file_data = '''namespace HREngine.Bots
{
partial class CardDB
{
public enum cardIDEnum
{
None,
'''
enum_data = enum_data.split('\n')
for line in enum_data:
enum_file_data += f"\t\t\t{line}\n"
enum_file_data += ''' }
}
}
'''
with open(enum_path, "w", encoding="utf-8") as cardIDEnum:
cardIDEnum.write(enum_file_data)
print("Write CardDB_cardIDEnum.cs to " + enum_path + " successfully!")
print("all finish")
|