diff --git a/README.md b/README.md index 54f13d2..09af0b4 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ This procedure is mainly used for study and research, and shall not be used for 没有以下 We don't have: - 服务器安全性保证 Server security assurance +- 世界模式下的搭档升级、觉醒,以及某些奖励的获取 Partner upgrading, uncapping, and receiving some rewards in the world mode 可能有问题 There may be problems: - Recent 30 @@ -64,8 +65,12 @@ It is just so interesting. What it can do is under exploration. > Tips: When updating, please keep the original database in case of data loss. > Before using, please run **database_initialize.py** to get the initial database. -### Version 2.3.1 -- 适用于Arcaea 3.5.3版本 For Arcaea 3.5.3 +### Version 2.3.2 +- 适用于Arcaea 3.5.4版本 For Arcaea 3.5.4 +- 更新了歌曲数据库 Update the song database. +- 新增运行前关键性文件检查 Add checking critical files before running. +- 新增可下载数据的客户端校验更新 Add client verification update of downloadable data. +- 新增歌曲成绩的谱面校验 Add checking chart file when submitting the song score. - 修复了一些Bug Fix some bugs. ## 运行环境与依赖 Running environment and requirements diff --git a/latest version/database/arcsong.db b/latest version/database/arcsong.db index 9569088..ed25b7b 100644 Binary files a/latest version/database/arcsong.db and b/latest version/database/arcsong.db differ diff --git a/latest version/database/singles.json b/latest version/database/singles.json index b587177..ddefb98 100644 --- a/latest version/database/singles.json +++ b/latest version/database/singles.json @@ -12,10 +12,10 @@ "items": [{ "id": "dataerror", "type": "single", - "_id": "6046bab736651a07ebc537f3", + "_id": "606f9f5636651a07ebc541f3", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -24,10 +24,10 @@ "items": [{ "id": "yourvoiceso", "type": "single", - "_id": "6046bab736651a07ebc53800", + "_id": "606f9f5636651a07ebc54201", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -36,10 +36,10 @@ "items": [{ "id": "crosssoul", "type": "single", - "_id": "6046bab736651a07ebc5380d", + "_id": "606f9f5636651a07ebc5420e", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -48,10 +48,10 @@ "items": [{ "type": "single", "id": "impurebird", - "_id": "6046bab736651a07ebc53801", + "_id": "606f9f5636651a07ebc541f4", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -60,7 +60,7 @@ "items": [{ "type": "single", "id": "auxesia", - "_id": "6046bab736651a07ebc5380e", + "_id": "606f9f5636651a07ebc5420f", "is_available": true }], "price": 100, @@ -72,10 +72,10 @@ "items": [{ "type": "single", "id": "modelista", - "_id": "6046bab736651a07ebc537f4", + "_id": "606f9f5636651a07ebc54202", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -84,10 +84,10 @@ "items": [{ "type": "single", "id": "yozakurafubuki", - "_id": "6046bab736651a07ebc53802", + "_id": "606f9f5636651a07ebc541f5", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -96,10 +96,10 @@ "items": [{ "type": "single", "id": "surrender", - "_id": "6046bab736651a07ebc5380f", + "_id": "606f9f5636651a07ebc54210", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -108,7 +108,7 @@ "items": [{ "type": "single", "id": "metallicpunisher", - "_id": "6046bab736651a07ebc537f5", + "_id": "606f9f5636651a07ebc54203", "is_available": true }], "price": 100, @@ -118,7 +118,7 @@ "items": [{ "type": "single", "id": "carminescythe", - "_id": "6046bab736651a07ebc53803", + "_id": "606f9f5636651a07ebc541f6", "is_available": true }], "price": 100, @@ -128,10 +128,10 @@ "items": [{ "type": "single", "id": "bethere", - "_id": "6046bab736651a07ebc53810", + "_id": "606f9f5636651a07ebc54211", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -140,10 +140,10 @@ "items": [{ "type": "single", "id": "callmyname", - "_id": "6046bab736651a07ebc537e9", + "_id": "606f9f5636651a07ebc5421c", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -152,10 +152,10 @@ "items": [{ "type": "single", "id": "fallensquare", - "_id": "6046bab736651a07ebc537de", + "_id": "606f9f5636651a07ebc541e9", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -164,10 +164,10 @@ "items": [{ "type": "single", "id": "dropdead", - "_id": "6046bab736651a07ebc53804", + "_id": "606f9f5636651a07ebc541f7", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -176,10 +176,10 @@ "items": [{ "type": "single", "id": "alexandrite", - "_id": "6046bab736651a07ebc53811", + "_id": "606f9f5636651a07ebc54212", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -188,10 +188,10 @@ "items": [{ "type": "single", "id": "astraltale", - "_id": "6046bab736651a07ebc537f7", + "_id": "606f9f5636651a07ebc54205", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -200,7 +200,7 @@ "items": [{ "type": "single", "id": "phantasia", - "_id": "6046bab736651a07ebc537df", + "_id": "606f9f5636651a07ebc541ea", "is_available": true }], "price": 100, @@ -210,7 +210,7 @@ "items": [{ "type": "single", "id": "empireofwinter", - "_id": "6046bab736651a07ebc53805", + "_id": "606f9f5636651a07ebc541f8", "is_available": true }], "price": 100, @@ -220,10 +220,10 @@ "items": [{ "type": "single", "id": "libertas", - "_id": "6046bab736651a07ebc537eb", + "_id": "606f9f5636651a07ebc5421e", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -232,10 +232,10 @@ "items": [{ "type": "single", "id": "dottodot", - "_id": "6046bab736651a07ebc537e0", + "_id": "606f9f5636651a07ebc541eb", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -244,10 +244,10 @@ "items": [{ "type": "single", "id": "dreadnought", - "_id": "6046bab736651a07ebc537ec", + "_id": "606f9f5636651a07ebc5421f", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -256,10 +256,10 @@ "items": [{ "type": "single", "id": "mirzam", - "_id": "6046bab736651a07ebc537e1", + "_id": "606f9f5636651a07ebc541ec", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -268,10 +268,10 @@ "items": [{ "type": "single", "id": "heavenlycaress", - "_id": "6046bab736651a07ebc53807", + "_id": "606f9f5636651a07ebc541fa", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -280,10 +280,10 @@ "items": [{ "type": "single", "id": "filament", - "_id": "6046bab736651a07ebc53814", + "_id": "606f9f5636651a07ebc54215", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -292,7 +292,7 @@ "items": [{ "type": "single", "id": "avantraze", - "_id": "6046bab736651a07ebc537ed", + "_id": "606f9f5636651a07ebc54220", "is_available": true }], "price": 100, @@ -302,10 +302,10 @@ "items": [{ "type": "single", "id": "battlenoone", - "_id": "6046bab736651a07ebc537fa", + "_id": "606f9f5636651a07ebc54208", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -314,7 +314,7 @@ "items": [{ "type": "single", "id": "saikyostronger", - "_id": "6046bab736651a07ebc537e2", + "_id": "606f9f5636651a07ebc541ed", "is_available": true }], "price": 100, @@ -324,10 +324,10 @@ "items": [{ "type": "single", "id": "izana", - "_id": "6046bab736651a07ebc53808", + "_id": "606f9f5636651a07ebc541fb", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -336,10 +336,10 @@ "items": [{ "type": "single", "id": "einherjar", - "_id": "6046bab736651a07ebc53815", + "_id": "606f9f5636651a07ebc54216", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -348,10 +348,10 @@ "items": [{ "type": "single", "id": "laqryma", - "_id": "6046bab736651a07ebc537ee", + "_id": "606f9f5636651a07ebc54221", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -360,10 +360,10 @@ "items": [{ "type": "single", "id": "amygdata", - "_id": "6046bab736651a07ebc537fb", + "_id": "606f9f5636651a07ebc54209", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -372,10 +372,10 @@ "items": [{ "type": "single", "id": "altale", - "_id": "6046bab736651a07ebc537e3", + "_id": "606f9f5636651a07ebc541ee", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -384,10 +384,10 @@ "items": [{ "type": "single", "id": "feelssoright", - "_id": "6046bab736651a07ebc537ef", + "_id": "606f9f5636651a07ebc54222", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -396,7 +396,7 @@ "items": [{ "type": "single", "id": "scarletcage", - "_id": "6046bab736651a07ebc537fc", + "_id": "606f9f5636651a07ebc5420a", "is_available": true }], "price": 100, @@ -406,7 +406,7 @@ "items": [{ "type": "single", "id": "teriqma", - "_id": "6046bab736651a07ebc537e4", + "_id": "606f9f5636651a07ebc541ef", "is_available": true }], "price": 100, @@ -416,10 +416,10 @@ "items": [{ "type": "single", "id": "mahoroba", - "_id": "6046bab736651a07ebc5380a", + "_id": "606f9f5636651a07ebc541fd", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -428,10 +428,10 @@ "items": [{ "type": "single", "id": "badtek", - "_id": "6046bab736651a07ebc537f0", + "_id": "606f9f5636651a07ebc54223", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -440,7 +440,7 @@ "items": [{ "type": "single", "id": "maliciousmischance", - "_id": "6046bab736651a07ebc53817", + "_id": "606f9f5636651a07ebc54218", "is_available": true }], "price": 100, @@ -450,7 +450,7 @@ "items": [{ "type": "single", "id": "buchigireberserker", - "_id": "6046bab736651a07ebc537e5", + "_id": "606f9f5636651a07ebc541f0", "is_available": true }], "price": 100, @@ -460,10 +460,10 @@ "items": [{ "type": "single", "id": "galaxyfriends", - "_id": "6046bab736651a07ebc5380b", + "_id": "606f9f5636651a07ebc541fe", "is_available": true }], - "price": 50, + "price": 100, "orig_price": 100, "discount_from": 1615248000000, "discount_to": 1615852799000 @@ -472,7 +472,7 @@ "items": [{ "type": "single", "id": "xeraphinite", - "_id": "6046bab736651a07ebc53818", + "_id": "606f9f5636651a07ebc54219", "is_available": true }], "orig_price": 100, @@ -482,7 +482,7 @@ "items": [{ "type": "single", "id": "xanatos", - "_id": "6046bab736651a07ebc537f1", + "_id": "606f9f5636651a07ebc54224", "is_available": true }], "price": 100, @@ -492,7 +492,7 @@ "items": [{ "type": "single", "id": "attraqtia", - "_id": "6046bab736651a07ebc537ff", + "_id": "606f9f5636651a07ebc5420d", "is_available": true }], "orig_price": 100, @@ -502,7 +502,17 @@ "items": [{ "type": "single", "id": "gimmedablood", - "_id": "6046bab736651a07ebc537e7", + "_id": "606f9f5636651a07ebc541f2", + "is_available": true + }], + "orig_price": 100, + "price": 100 +}, { + "name": "bassline", + "items": [{ + "type": "single", + "id": "bassline", + "_id": "606f9f5636651a07ebc54200", "is_available": true }], "orig_price": 100, diff --git a/latest version/main.py b/latest version/main.py index 4734a7c..ce94606 100644 --- a/latest version/main.py +++ b/latest version/main.py @@ -13,6 +13,7 @@ import web.index import server.arcworld import server.arcdownload import server.arcpurchase +import server.init import os import sys @@ -570,6 +571,11 @@ def main(): dictConfig(log_dict) + if not server.init.check_before_run(app): + app.logger.error('Something wrong. The server will not run.') + input('Press ENTER key to exit.') + sys.exit() + app.logger.info("Start to initialize data in 'songfile' table...") try: error = server.arcdownload.initialize_songfile() diff --git a/latest version/server/arcdownload.py b/latest version/server/arcdownload.py index 59cc99d..4575351 100644 --- a/latest version/server/arcdownload.py +++ b/latest version/server/arcdownload.py @@ -42,7 +42,7 @@ def get_url(file_path, **kwargs): return url_for('download', file_path=file_path, t=t, _external=True) -def get_one_song(c, user_id, song_id, file_dir='./database/songs'): +def get_one_song(c, user_id, song_id, file_dir='./database/songs', url_flag=True): # 获取一首歌的下载链接,返回字典 dir_list = os.listdir(os.path.join(file_dir, song_id)) re = {} @@ -64,8 +64,12 @@ def get_one_song(c, user_id, song_id, file_dir='./database/songs'): else: checksum = get_file_md5(os.path.join( file_dir, song_id, 'base.ogg')) - re['audio'] = {"checksum": checksum, "url": get_url( - file_path=song_id+'/base.ogg', t=token)} + + if url_flag: + re['audio'] = {"checksum": checksum, "url": get_url( + file_path=song_id+'/base.ogg', t=token)} + else: + re['audio'] = {"checksum": checksum} else: if 'chart' not in re: re['chart'] = {} @@ -76,23 +80,28 @@ def get_one_song(c, user_id, song_id, file_dir='./database/songs'): checksum = x[0] else: checksum = get_file_md5(os.path.join(file_dir, song_id, i)) - re['chart'][i[0]] = {"checksum": checksum, "url": get_url( - file_path=song_id+'/'+i, t=token)} - c.execute('''insert into download_token values(:a,:b,:c,:d,:e)''', { - 'a': user_id, 'b': song_id, 'c': i, 'd': token, 'e': now}) + if url_flag: + re['chart'][i[0]] = {"checksum": checksum, "url": get_url( + file_path=song_id+'/'+i, t=token)} + else: + re['chart'][i[0]] = {"checksum": checksum} + + if url_flag: + c.execute('''insert into download_token values(:a,:b,:c,:d,:e)''', { + 'a': user_id, 'b': song_id, 'c': i, 'd': token, 'e': now}) return {song_id: re} -def get_all_songs(user_id, file_dir='./database/songs'): +def get_all_songs(user_id, file_dir='./database/songs', url_flag=True): # 获取所有歌的下载链接,返回字典 dir_list = os.listdir(file_dir) re = {} with Connect() as c: for i in dir_list: if os.path.isdir(os.path.join(file_dir, i)): - re.update(get_one_song(c, user_id, i, file_dir)) + re.update(get_one_song(c, user_id, i, file_dir, url_flag)) return re diff --git a/latest version/server/arcscore.py b/latest version/server/arcscore.py index e6085a3..3876c35 100644 --- a/latest version/server/arcscore.py +++ b/latest version/server/arcscore.py @@ -569,6 +569,14 @@ def arc_score_check(user_id, song_id, difficulty, score, shiny_perfect_count, pe if abs(ascore - score) >= 5: return False + with Connect() as c: # 歌曲谱面MD5检查,服务器没有谱面就不管了 + c.execute('''select md5 from songfile where song_id=:a and file_type=:b''', { + 'a': song_id, 'b': int(difficulty)}) + x = c.fetchone() + if x: + if x[0] != song_hash: + return False + x = song_token + song_hash + song_id + str(difficulty) + str(score) + str(shiny_perfect_count) + str( perfect_count) + str(near_count) + str(miss_count) + str(health) + str(modifier) + str(clear_type) y = str(user_id) + song_hash diff --git a/latest version/server/auth.py b/latest version/server/auth.py index 969407e..9d49d82 100644 --- a/latest version/server/auth.py +++ b/latest version/server/auth.py @@ -168,9 +168,10 @@ def auth_required(request): user_id = None with Connect() as c: headers = request.headers - token = headers['Authorization'] - token = token[7:] - user_id = token_get_id(token) + if 'Authorization' in headers: + token = headers['Authorization'] + token = token[7:] + user_id = token_get_id(token) if user_id is not None: return view(user_id, *args, **kwargs) diff --git a/latest version/server/info.py b/latest version/server/info.py index 0d0f186..06ec210 100644 --- a/latest version/server/info.py +++ b/latest version/server/info.py @@ -1,6 +1,7 @@ from server.sql import Connect import server.arcworld import server.arcpurchase +import server.arcdownload import time from setting import Config @@ -198,7 +199,7 @@ def get_value_0(c, user_id): "max_stamina_ts": 1586274871917, "stamina": 12, "world_unlocks": ["scenery_chap1", "scenery_chap2", "scenery_chap3", "scenery_chap4", "scenery_chap5"], - "world_songs": ["babaroque", "shadesoflight", "kanagawa", "lucifer", "anokumene", "ignotus", "rabbitintheblackroom", "qualia", "redandblue", "bookmaker", "darakunosono", "espebranch", "blacklotus", "givemeanightmare", "vividtheory", "onefr", "gekka", "vexaria3", "infinityheaven3", "fairytale3", "goodtek3", "suomi", "rugie", "faintlight", "harutopia", "goodtek", "dreaminattraction", "syro", "diode", "freefall", "grimheart", "blaster", "cyberneciacatharsis", "monochromeprincess", "revixy", "vector", "supernova", "nhelv", "purgatorium3", "dement3", "crossover", "guardina", "axiumcrisis", "worldvanquisher", "sheriruth", "pragmatism", "gloryroad", "etherstrike", "corpssansorganes", "lostdesire", "blrink", "essenceoftwilight", "lapis", "solitarydream", "lumia3", "purpleverse", "moonheart3", "glow", "enchantedlove", "take"], + "world_songs": ["babaroque", "shadesoflight", "kanagawa", "lucifer", "anokumene", "ignotus", "rabbitintheblackroom", "qualia", "redandblue", "bookmaker", "darakunosono", "espebranch", "blacklotus", "givemeanightmare", "vividtheory", "onefr", "gekka", "vexaria3", "infinityheaven3", "fairytale3", "goodtek3", "suomi", "rugie", "faintlight", "harutopia", "goodtek", "dreaminattraction", "syro", "diode", "freefall", "grimheart", "blaster", "cyberneciacatharsis", "monochromeprincess", "revixy", "vector", "supernova", "nhelv", "purgatorium3", "dement3", "crossover", "guardina", "axiumcrisis", "worldvanquisher", "sheriruth", "pragmatism", "gloryroad", "etherstrike", "corpssansorganes", "lostdesire", "blrink", "essenceoftwilight", "lapis", "solitarydream", "lumia3", "purpleverse", "moonheart3", "glow", "enchantedlove", "take", "lifeispiano"], "singles": get_user_singles(c, user_id), "packs": get_user_packs(c, user_id), "characters": characters, @@ -226,7 +227,7 @@ def arc_aggregate_small(user_id): def arc_aggregate_big(user_id): - # 返回用户数据和地图歌曲信息 + # 返回比较全的用户数据 r = {"success": False} with Connect() as c: r = {"success": True, @@ -238,7 +239,7 @@ def arc_aggregate_big(user_id): "value": server.arcpurchase.get_item(c, 'pack') }, { "id": 2, - "value": {} + "value": server.arcdownload.get_all_songs(user_id, url_flag=False) }, { "id": 3, "value": { diff --git a/latest version/server/init.py b/latest version/server/init.py new file mode 100644 index 0000000..639d52e --- /dev/null +++ b/latest version/server/init.py @@ -0,0 +1,29 @@ +import os + + +def check_before_run(app): + # 运行前检查关键文件,返回布尔值,其实是因为有人经常忘了 + + f = True + + if not os.path.exists('setting.py'): + app.logger.warning('File `setting.py` is missing.') + f = False + + if not os.path.exists('database'): + app.logger.warning('Folder `database` is missing.') + f = False + + if not os.path.exists('database/songs'): + app.logger.warning('Folder `database/songs` is missing.') + f = False + + if not os.path.exists('database/arcaea_database.db'): + app.logger.warning('File `database/arcaea_database.db` is missing.') + f = False + + if not os.path.exists('database/arcsong.db'): + app.logger.warning('File `database/arcsong.db` is missing.') + f = False + + return f diff --git a/latest version/setting.py b/latest version/setting.py index 9b310d0..36da3f9 100644 --- a/latest version/setting.py +++ b/latest version/setting.py @@ -125,7 +125,7 @@ class Config(): 是否强制使用全解锁云端存档 If forcing full unlocked cloud save is enabled ''' - SAVE_FULL_UNLOCK = True + SAVE_FULL_UNLOCK = False ''' -------------------- '''