diff --git a/data/clean/31-4/data.sqlite3 b/data/clean/31-4/data.sqlite3 new file mode 100644 index 0000000..6653006 Binary files /dev/null and b/data/clean/31-4/data.sqlite3 differ diff --git a/data/convert/31-4/db.py b/data/convert/31-4/db.py new file mode 100755 index 0000000..21e4bea --- /dev/null +++ b/data/convert/31-4/db.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +# # -*- coding: utf-8 -*- + +from pony.orm import * + +db = Database() + + +class Melee(db.Entity): + name = Required(str) + description = Optional(str) + mechanism = Optional(str) + icon = Required(bytes) + stats = Required(int) + + +class Shield(db.Entity): + name = Required(str) + description = Optional(str) + mechanism = Optional(str) + icon = Required(bytes) + stats = Required(int) + + +class Ranged(db.Entity): + name = Required(str) + description = Optional(str) + mechanism = Optional(str) + icon = Required(bytes) + stats = Required(int) + + +class Outfit(db.Entity): + name = Required(str) + name_en = Required(str) + description = Optional(str) + icon = Required(bytes) + preview = Optional(bytes) + cell_cost = Required(int) + + +if __name__ == "__main__": + db.bind(provider="sqlite", filename="../../clean/31-4/data.sqlite3") + db.generate_mapping(create_tables=True) diff --git a/data/convert/31-4/melee.py b/data/convert/31-4/melee.py new file mode 100755 index 0000000..916f99a --- /dev/null +++ b/data/convert/31-4/melee.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +# # -*- coding: utf-8 -*- + +import json +import re +import io +from db import * +from PIL import Image + +with open("../../extraction/raw-31-4/data.cdb.json") as f: + raw = json.load(f) +with open("../../clean/31-4/main.zh.mo.json") as f: + trans = json.load(f) +img = Image.open("../../extraction/raw-31-4/cardIcons.png") + +db.bind(provider="sqlite", filename="../../clean/31-4/data.sqlite3") +db.generate_mapping() + +lines = raw["sheets"][1]["lines"] + +with db_session: + for i in lines: + if i["group"] == 4: + i["name"] = trans[i["name"]]["msgstr"][0] + if "ambiantDesc" in i: + i["ambiantDesc"] = trans[i["ambiantDesc"].strip()]["msgstr"][0] + else: + i["ambiantDesc"] = "" + if "gameplayDesc" in i: + i["gameplayDesc"] = trans[i["gameplayDesc"].strip()]["msgstr"][0] + if i["props"]: + + def replace_props(m): + prop_name = m.group(1) + result = i["props"][prop_name] + if prop_name.startswith("prct"): + result = int(result * 100) + if isinstance(result, list): + result = result[0] + if not isinstance(result, str): + result = str(result) + return result + + i["gameplayDesc"], _ = re.subn( + r"::\+?(.*?)::", replace_props, i["gameplayDesc"] + ) + else: + i["gameplayDesc"] = "" + x = i["icon"]["x"] * 24 + y = i["icon"]["y"] * 24 + box = (x, y, x + 24, y + 24) + region = img.crop(box) + region_arr = io.BytesIO() + region.save(region_arr, format="PNG") + + stats_map = {"Brutality": 1, "Survival": 2, "Tactic": 4} + stats = 0 + for t in ["tier1", "tier2"]: + if t in i: + stats += stats_map[i[t]] + + Melee( + name=i["name"], + description=i["ambiantDesc"], + mechanism=i["gameplayDesc"], + icon=region_arr.getbuffer().tobytes(), + stats=stats, + ) diff --git a/data/convert/31-4/outfits.py b/data/convert/31-4/outfits.py new file mode 100755 index 0000000..53e7f8d --- /dev/null +++ b/data/convert/31-4/outfits.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +# # -*- coding: utf-8 -*- + +import json +import re +import io +from db import * +from PIL import Image + +with open("../../extraction/raw-31-4/data.cdb.json") as f: + raw = json.load(f) +with open("../../clean/31-4/main.zh.mo.json") as f: + trans = json.load(f) +with open("../../clean/31-4/main.en.mo.json") as f: + trans_en = json.load(f) +img = Image.open("../../extraction/raw-31-4/cardIcons.png") + +db.bind(provider="sqlite", filename="../../clean/31-4/data.sqlite3") +db.generate_mapping() + +lines = raw["sheets"][1]["lines"] + +with db_session: + for i in lines: + if i["group"] == 13: + if not i["name"]: + continue + if i["id"] == "KingsHandBoss": + continue + raw_name = i["name"].strip() + i["name"] = trans[raw_name]["msgstr"][0] + i["name"] = re.sub(r"。", r"", i["name"]) + i["name_en"] = trans_en[raw_name]["msgstr"][0] + i["name_en"] = re.sub(r"outfit", r"Outfit", i["name_en"]) + i["gameplayDesc"] = trans[i["gameplayDesc"].strip()]["msgstr"][0] + x = i["icon"]["x"] * 24 + y = i["icon"]["y"] * 24 + box = (x, y, x + 24, y + 24) + region = img.crop(box) + region_arr = io.BytesIO() + region.save(region_arr, format="PNG") + + Outfit( + name=i["name"], + name_en=i["name_en"], + description=i["gameplayDesc"], + icon=region_arr.getbuffer().tobytes(), + cell_cost=i["cellCost"], + ) diff --git a/data/convert/31-4/ranged.py b/data/convert/31-4/ranged.py new file mode 100755 index 0000000..3cf7ba9 --- /dev/null +++ b/data/convert/31-4/ranged.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +# # -*- coding: utf-8 -*- + +import json +import re +import io +from db import * +from PIL import Image + +with open("../../extraction/raw-31-4/data.cdb.json") as f: + raw = json.load(f) +with open("../../clean/31-4/main.zh.mo.json") as f: + trans = json.load(f) +img = Image.open("../../extraction/raw-31-4/cardIcons.png") + +db.bind(provider="sqlite", filename="../../clean/31-4/data.sqlite3") +db.generate_mapping() + +lines = raw["sheets"][1]["lines"] + +with db_session: + for i in lines: + if i["group"] == 5: + i["name"] = trans[i["name"].strip()]["msgstr"][0] + if "ambiantDesc" in i: + i["ambiantDesc"] = trans[i["ambiantDesc"].strip()]["msgstr"][0] + else: + i["ambiantDesc"] = "" + if "gameplayDesc" in i: + i["gameplayDesc"] = trans[i["gameplayDesc"].strip()]["msgstr"][0] + if i["props"]: + + def replace_props(m): + prop_name = m.group(1) + if prop_name == "ShockAffectDuration": + prop_name = "duration" # 雷盾带电手动触发 + result = i["props"][prop_name] + if prop_name.startswith("prct"): + result = int(result * 100) + if isinstance(result, list): + result = result[0] + if not isinstance(result, str): + result = str(result) + return result + + i["gameplayDesc"], _ = re.subn( + r"::[\+|\*]?(.*?)::", replace_props, i["gameplayDesc"] + ) + else: + i["gameplayDesc"] = "" + x = i["icon"]["x"] * 24 + y = i["icon"]["y"] * 24 + box = (x, y, x + 24, y + 24) + region = img.crop(box) + region_arr = io.BytesIO() + region.save(region_arr, format="PNG") + + stats_map = {"Brutality": 1, "Survival": 2, "Tactic": 4} + stats = 0 + for t in ["tier1", "tier2"]: + if t in i: + stats += stats_map[i[t]] + + Ranged( + name=i["name"], + description=i["ambiantDesc"], + mechanism=i["gameplayDesc"], + icon=region_arr.getbuffer().tobytes(), + stats=stats, + ) diff --git a/data/convert/31-4/shield.py b/data/convert/31-4/shield.py new file mode 100755 index 0000000..7952087 --- /dev/null +++ b/data/convert/31-4/shield.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +# # -*- coding: utf-8 -*- + +import json +import re +import io +from db import * +from PIL import Image + +with open("../../extraction/raw-31-4/data.cdb.json") as f: + raw = json.load(f) +with open("../../clean/31-4/main.zh.mo.json") as f: + trans = json.load(f) +img = Image.open("../../extraction/raw-31-4/cardIcons.png") + +db.bind(provider="sqlite", filename="../../clean/31-4/data.sqlite3") +db.generate_mapping() + +lines = raw["sheets"][1]["lines"] + +with db_session: + for i in lines: + if i["group"] == 6: + i["name"] = trans[i["name"]]["msgstr"][0] + if "ambiantDesc" in i: + i["ambiantDesc"] = trans[i["ambiantDesc"].strip()]["msgstr"][0] + else: + i["ambiantDesc"] = "" + if "gameplayDesc" in i: + i["gameplayDesc"] = trans[i["gameplayDesc"].strip()]["msgstr"][0] + if i["props"]: + + def replace_props(m): + prop_name = m.group(1) + if prop_name == "ShockAffectDuration": + prop_name = "duration2" # 雷盾带电手动触发 + result = i["props"][prop_name] + if prop_name.startswith("prct"): + result = int(result * 100) + if isinstance(result, list): + result = result[0] + if not isinstance(result, str): + result = str(result) + return result + + i["gameplayDesc"], _ = re.subn( + r"::[\+|\*]?(.*?)::", replace_props, i["gameplayDesc"] + ) + else: + i["gameplayDesc"] = "" + x = i["icon"]["x"] * 24 + y = i["icon"]["y"] * 24 + box = (x, y, x + 24, y + 24) + region = img.crop(box) + region_arr = io.BytesIO() + region.save(region_arr, format="PNG") + + stats_map = {"Brutality": 1, "Survival": 2, "Tactic": 4} + stats = 0 + for t in ["tier1", "tier2"]: + if t in i: + stats += stats_map[i[t]] + + Shield( + name=i["name"], + description=i["ambiantDesc"], + mechanism=i["gameplayDesc"], + icon=region_arr.getbuffer().tobytes(), + stats=stats, + ) diff --git a/data/patch/31-4/outfits.py b/data/patch/31-4/outfits.py new file mode 100644 index 0000000..f06c0d6 --- /dev/null +++ b/data/patch/31-4/outfits.py @@ -0,0 +1,34 @@ +import scrapy +import sys +import requests +import io + +sys.path.append("../../convert/31-2") +from db import * + +db.bind(provider="sqlite", filename="../../clean/31-2/data.sqlite3") +db.generate_mapping() + + +class OutfitSpider(scrapy.Spider): + name = "outfits" + start_urls = [ + "https://deadcells.fandom.com/wiki/Outfits", + ] + + def parse(self, response): + for quote in response.css(".wikitable tbody tr"): + name_en = quote.css("td:nth-child(2) > span:last-child::text").get() + if not name_en: + print(name_en) + continue + preview = quote.css( + "td:nth-child(6) > span:last-child a::attr('href')" + ).get() + try: + r = requests.get(preview) + with db_session: + w = Outfit.select(name_en=name_en).first() + w.preview = io.BytesIO(r.content).getbuffer().tobytes() + except: + print("Preview not available.")