diff --git a/v1.0/arcscore.py b/v1.0/arcscore.py deleted file mode 100644 index a3bf2aa..0000000 --- a/v1.0/arcscore.py +++ /dev/null @@ -1,1242 +0,0 @@ -import sqlite3 -import time -import json - - -def b2int(x): - # int与布尔值转换 - if x: - return 1 - else: - return 0 - - -def int2b(x): - # int与布尔值转换 - if x is None or x == 0: - return False - else: - return True - - -def get_score(c, user_id, song_id, difficulty): - # 根据user_id、song_id、难度得到该曲目最好成绩,返回字典 - c.execute('''select * from best_score where user_id = :a and song_id = :b and difficulty = :c''', - {'a': user_id, 'b': song_id, 'c': difficulty}) - x = c.fetchone() - if x is not None: - c.execute('''select name, character_id, is_skill_sealed, is_char_uncapped from user where user_id = :a''', { - 'a': user_id}) - y = c.fetchone() - if y is not None: - return { - "user_id": x[0], - "song_id": x[1], - "difficulty": x[2], - "score": x[3], - "shiny_perfect_count": x[4], - "perfect_count": x[5], - "near_count": x[6], - "miss_count": x[7], - "health": x[8], - "modifier": x[9], - "time_played": x[10], - "best_clear_type": x[11], - "clear_type": x[12], - "name": y[0], - "character": y[1], - "is_skill_sealed": int2b(y[2]), - "is_char_uncapped": int2b(y[3]) - } - else: - return {} - else: - return {} - - -def arc_score_friend(user_id, song_id, difficulty, limit=50): - # 得到用户好友分数表,默认最大50个 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select user_id from best_score where user_id in (select :user_id union select user_id_other from friend where user_id_me = :user_id) and song_id = :song_id and difficulty = :difficulty order by score DESC, time_played DESC limit :limit''', { - 'user_id': user_id, 'song_id': song_id, 'difficulty': difficulty, 'limit': limit}) - x = c.fetchall() - r = [] - if x != []: - rank = 0 - for i in x: - rank += 1 - y = get_score(c, i[0], song_id, difficulty) - y['rank'] = rank - r.append(y) - - conn.commit() - conn.close() - return r - - -def arc_score_top(song_id, difficulty, limit=20): - # 得到top分数表,默认最多20个 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select user_id from best_score where song_id = :song_id and difficulty = :difficulty order by score DESC, time_played DESC limit :limit''', { - 'song_id': song_id, 'difficulty': difficulty, 'limit': limit}) - x = c.fetchall() - r = [] - if x != []: - rank = 0 - for i in x: - rank += 1 - y = get_score(c, i[0], song_id, difficulty) - y['rank'] = rank - r.append(y) - - conn.commit() - conn.close() - return r - - -def arc_score_me(user_id, song_id, difficulty, limit=20): - # 得到用户的排名,默认最大20个 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - r = [] - c.execute('''select exists(select * from best_score where user_id = :user_id and song_id = :song_id and difficulty = :difficulty)''', { - 'user_id': user_id, 'song_id': song_id, 'difficulty': difficulty}) - if c.fetchone() == (1,): - c.execute('''select count(*) from best_score where song_id = :song_id and difficulty = :difficulty and (score>(select score from best_score where user_id = :user_id and song_id = :song_id and difficulty = :difficulty) or (score>(select score from best_score where user_id = :user_id and song_id = :song_id and difficulty = :difficulty) and time_played > (select time_played from best_score where user_id = :user_id and song_id = :song_id and difficulty = :difficulty)) )''', { - 'user_id': user_id, 'song_id': song_id, 'difficulty': difficulty}) - x = c.fetchone() - myrank = int(x[0]) + 1 - if myrank <= 4: # 排名在前4 - conn.commit() - conn.close() - return arc_score_top(song_id, difficulty, limit) - elif myrank >= 5 and myrank <= 9999 - limit + 4: # 万名内,前面有4个人 - c.execute('''select user_id from best_score where song_id = :song_id and difficulty = :difficulty order by score DESC, time_played DESC limit :limit offset :offset''', { - 'song_id': song_id, 'difficulty': difficulty, 'limit': limit, 'offset': myrank - 5}) - x = c.fetchall() - if x != []: - rank = myrank - 5 - for i in x: - rank += 1 - y = get_score(c, i[0], song_id, difficulty) - y['rank'] = rank - r.append(y) - - elif myrank >= 10000: # 万名外 - c.execute('''select user_id from best_score where song_id = :song_id and difficulty = :difficulty order by score DESC, time_played DESC limit :limit offset :offset''', { - 'song_id': song_id, 'difficulty': difficulty, 'limit': limit - 1, 'offset': 9999-limit}) - x = c.fetchall() - if x != []: - rank = 9999 - limit - for i in x: - rank += 1 - y = get_score(c, i[0], song_id, difficulty) - y['rank'] = rank - r.append(y) - y = get_score(c, user_id, song_id, difficulty) - y['rank'] = -1 - r.append(y) - else: - c.execute('''select user_id from best_score where song_id = :song_id and difficulty = :difficulty order by score DESC, time_played DESC limit :limit offset :offset''', { - 'song_id': song_id, 'difficulty': difficulty, 'limit': limit, 'offset': 9998-limit}) - x = c.fetchall() - if x != []: - rank = 9998 - limit - for i in x: - rank += 1 - y = get_score(c, i[0], song_id, difficulty) - y['rank'] = rank - r.append(y) - - conn.commit() - conn.close() - return r - - -def get_one_ptt(song_id, difficulty, score: int) -> float: - # 单曲ptt计算 - conn = sqlite3.connect('./database/arcsong.db') - c = conn.cursor() - if difficulty == 0: - c.execute('''select rating_pst from songs where sid = :sid;''', { - 'sid': song_id}) - elif difficulty == 1: - c.execute('''select rating_prs from songs where sid = :sid;''', { - 'sid': song_id}) - elif difficulty == 2: - c.execute('''select rating_ftr from songs where sid = :sid;''', { - 'sid': song_id}) - elif difficulty == 3: - c.execute('''select rating_byn from songs where sid = :sid;''', { - 'sid': song_id}) - - x = c.fetchone() - defnum = 10.0 # 没在库里的全部当做定数10.0,不过要小心recent30表可能会被污染 - if x is not None and x != '': - defnum = float(x[0]) / 10 - if defnum <= 0: - defnum = 11.0 # 缺少难度的当做定数11.0 - - if score >= 10000000: - ptt = defnum + 2 - elif score < 9800000: - ptt = defnum + (score-9500000) / 300000 - if ptt < 0: - ptt = 0 - else: - ptt = defnum + 1 + (score-9800000) / 200000 - - conn.commit() - conn.close() - return ptt - - -def get_song_grade(x): - # 成绩转换评级 - if x >= 9900000: # EX+ - return 6 - elif x < 9900000 and x >= 9800000: # EX - return 5 - elif x < 9800000 and x >= 9500000: # AA - return 4 - elif x < 9500000 and x >= 9200000: # A - return 3 - elif x < 9200000 and x >= 8900000: # B - return 2 - elif x < 8900000 and x >= 8600000: # C - return 1 - else: - return 0 - - -def get_song_state(x): - # 返回成绩状态,便于比较 - if x == 3: # PM - return 5 - elif x == 2: # FC - return 4 - elif x == 5: # Hard Clear - return 3 - elif x == 1: # Clear - return 2 - elif x == 4: # Easy Clear - return 1 - else: # Track Lost - return 0 - - -def update_recent30(c, user_id, song_id, rating): - # 刷新r30,这里的判断方法存疑 - c.execute('''select * from recent30 where user_id = :a''', {'a': user_id}) - x = c.fetchone() - songs = [] - flag = True - for i in range(2, 61, 2): - if x[i] is None or x[i] == '': - r30_id = 29 - flag = False - break - if x[i] not in songs: - songs.append(x[i]) - if flag: - n = len(song_id) - if n >= 11: - r30_id = 29 - elif song_id not in songs and n == 10: - r30_id = 29 - elif song_id in songs and n == 10: - i = 29 - while x[i*2+2] == song_id: - i -= 1 - r30_id = i - elif song_id not in songs and n == 9: - i = 29 - while x[i*2+2] == song_id: - i -= 1 - r30_id = i - else: - r30_id = 29 - a = [] - b = [] - for i in range(1, 61, 2): - a.append(x[i]) - b.append(x[i+1]) - for i in range(r30_id, 0, -1): - a[i] = a[i-1] - b[i] = b[i-1] - a[0] = rating - b[0] = song_id - c.execute('''delete from recent30 where user_id = :a''', {'a': user_id}) - sql = 'insert into recent30 values(' + str(user_id) - for i in range(0, 30): - if a[i] is not None and b[i] is not None: - sql = sql + ',' + str(a[i]) + ',"' + b[i] + '"' - else: - sql = sql + ',0,""' - - sql = sql + ')' - c.execute(sql) - return None - - -def get_user_ptt(c, user_id) -> int: - # 总ptt计算 - sumr = 0 - c.execute('''select rating from best_score where user_id = :a order by rating DESC limit 30''', { - 'a': user_id}) - x = c.fetchall() - if x != []: - n = len(x) - for i in x: - sumr += float(i[0]) - c.execute('''select * from recent30 where user_id = :a''', {'a': user_id}) - x = c.fetchone() - if x is not None: - r30 = [] - s30 = [] - for i in range(1, 61, 2): - if x[i] is not None: - r30.append(float(x[i])) - s30.append(x[i+1]) - else: - r30.append(0) - s30.append('') - r30, s30 = (list(t) for t in zip(*sorted(zip(r30, s30), reverse=True))) - songs = [] - i = 0 - while len(songs) < 10 and i <= 29 and s30[i] != '' and s30[i] is not None: - if s30[i] not in songs: - sumr += r30[i] - songs.append(s30[i]) - i += 1 - - return int(sumr/40*100) - - -def arc_score_post(user_id, song_id, difficulty, score, shiny_perfect_count, perfect_count, near_count, miss_count, health, modifier, beyond_gauge, clear_type): - # 分数上传,返回变化后的ptt - # beyond_gauge是个什么呀?不管了,扔了 - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - rating = get_one_ptt(song_id, difficulty, score) - now = int(time.time() * 1000) - # recent 更新 - c.execute('''update user set song_id = :b, difficulty = :c, score = :d, shiny_perfect_count = :e, perfect_count = :f, near_count = :g, miss_count = :h, health = :i, modifier = :j, clear_type = :k, rating = :l, time_played = :m where user_id = :a''', { - 'a': user_id, 'b': song_id, 'c': difficulty, 'd': score, 'e': shiny_perfect_count, 'f': perfect_count, 'g': near_count, 'h': miss_count, 'i': health, 'j': modifier, 'k': clear_type, 'l': rating, 'm': now}) - # recent30 更新 - update_recent30(c, user_id, song_id, rating) - # 成绩录入 - c.execute('''select score, best_clear_type from best_score where user_id = :a and song_id = :b and difficulty = :c''', { - 'a': user_id, 'b': song_id, 'c': difficulty}) - x = c.fetchone() - if x is None: - c.execute('''insert into best_score values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n)''', { - 'a': user_id, 'b': song_id, 'c': difficulty, 'd': score, 'e': shiny_perfect_count, 'f': perfect_count, 'g': near_count, 'h': miss_count, 'i': health, 'j': modifier, 'k': now, 'l': clear_type, 'm': clear_type, 'n': rating}) - else: - if get_song_state(clear_type) > get_song_state(int(x[1])): # 状态更新 - c.execute('''update best_score set best_clear_type = :a where user_id = :b and song_id = :c and difficulty = :d''', { - 'a': clear_type, 'b': user_id, 'c': song_id, 'd': difficulty}) - if score >= int(x[0]): # 成绩更新 - c.execute('''update best_score set score = :d, shiny_perfect_count = :e, perfect_count = :f, near_count = :g, miss_count = :h, health = :i, modifier = :j, clear_type = :k, rating = :l, time_played = :m where user_id = :a and song_id = :b and difficulty = :c ''', { - 'a': user_id, 'b': song_id, 'c': difficulty, 'd': score, 'e': shiny_perfect_count, 'f': perfect_count, 'g': near_count, 'h': miss_count, 'i': health, 'j': modifier, 'k': clear_type, 'l': rating, 'm': now}) - # 总PTT更新 - ptt = get_user_ptt(c, user_id) - c.execute('''update user set rating_ptt = :a where user_id = :b''', { - 'a': ptt, 'b': user_id}) - conn.commit() - conn.close() - return ptt - - -def arc_all_post(user_id, scores_data, clearlamps_data): - # 向云端同步,无返回 - # 注意,best_score表不比较,直接覆盖 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - scores = json.loads(scores_data)[""] - clearlamps = json.loads(clearlamps_data)[""] - clear_song_id_difficulty = [] - clear_state = [] - for i in clearlamps: - clear_song_id_difficulty.append(i['song_id']+str(i['difficulty'])) - clear_state.append(i['clear_type']) - - for i in scores: - rating = get_one_ptt(i['song_id'], i['difficulty'], i['score']) - try: - index = clear_song_id_difficulty.index( - i['song_id'] + str(i['difficulty'])) - except: - index = -1 - if index != -1: - clear_type = clear_state[index] - else: - clear_type = 0 - c.execute('''delete from best_score where user_id = :a and song_id = :b and difficulty = :c''', { - 'a': user_id, 'b': i['song_id'], 'c': i['difficulty']}) - c.execute('''insert into best_score values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n)''', { - 'a': user_id, 'b': i['song_id'], 'c': i['difficulty'], 'd': i['score'], 'e': i['shiny_perfect_count'], 'f': i['perfect_count'], 'g': i['near_count'], 'h': i['miss_count'], 'i': i['health'], 'j': i['modifier'], 'k': i['time_played'], 'l': clear_type, 'm': clear_type, 'n': rating}) - - ptt = get_user_ptt(c, user_id) # 更新PTT - c.execute('''update user set rating_ptt = :a where user_id = :b''', {'a': ptt, 'b': user_id}) - conn.commit() - conn.close() - return None - - -def arc_all_get(user_id): - # 从云端同步,返回字典 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select * from best_score where user_id = :a''', - {'a': user_id}) - x = c.fetchall() - song_1 = [] - song_2 = [] - song_3 = [] - if x != []: - for i in x: - if i[11] != 0: - song_1.append({ - "grade": get_song_grade(i[3]), - "difficulty": i[2], - "song_id": i[1] - }) - song_2.append({ - "ct": 0, - "clear_type": i[11], - "difficulty": i[2], - "song_id": i[1] - }) - song_3.append({ - "ct": 0, - "time_played": i[10], - "modifier": i[9], - "health": i[8], - "miss_count": i[7], - "near_count": i[6], - "perfect_count": i[5], - "shiny_perfect_count": i[4], - "score": i[3], - "difficulty": i[2], - "version": 1, - "song_id": i[1] - }) - - conn.commit() - conn.close() - return { - "user_id": user_id, - "story": { - "": [{ - "r": True, - "c": True, - "mi": 1, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 7, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 8, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 9, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 7, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 8, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 9, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 100 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 100 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 100 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 100 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 100 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 7, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 8, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 7, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 8, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 6 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 6 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 6 - }] - }, - "devicemodelname": { - "val": "MopeMope" - }, - "installid": { - "val": "b5e064cf-1a3f-4e64-9636-fce4accc9011" - }, - "unlocklist": { - "": [{ - "complete": 0, - "unlock_key": "worldvanquisher|2|0" - }, { - "complete": 0, - "unlock_key": "worldvanquisher|1|0" - }, { - "complete": 0, - "unlock_key": "worldexecuteme|2|0" - }, { - "complete": 0, - "unlock_key": "viciousheroism|2|0" - }, { - "complete": 0, - "unlock_key": "vector|2|0" - }, { - "complete": 0, - "unlock_key": "valhallazero|2|0" - }, { - "complete": 0, - "unlock_key": "tiferet|1|0" - }, { - "complete": 0, - "unlock_key": "tiemedowngently|1|0" - }, { - "complete": 0, - "unlock_key": "tempestissimo|0|101" - }, { - "complete": 0, - "unlock_key": "syro|2|0" - }, { - "complete": 0, - "unlock_key": "suomi|1|0" - }, { - "complete": 0, - "unlock_key": "solitarydream|2|0" - }, { - "complete": 0, - "unlock_key": "snowwhite|2|0" - }, { - "complete": 0, - "unlock_key": "sheriruth|2|0" - }, { - "complete": 0, - "unlock_key": "senkyou|2|0" - }, { - "complete": 0, - "unlock_key": "senkyou|1|0" - }, { - "complete": 0, - "unlock_key": "scarletlance|2|0" - }, { - "complete": 0, - "unlock_key": "scarletlance|1|0" - }, { - "complete": 0, - "unlock_key": "rugie|2|0" - }, { - "complete": 0, - "unlock_key": "rugie|1|0" - }, { - "complete": 0, - "unlock_key": "rise|2|0" - }, { - "complete": 0, - "unlock_key": "revixy|2|0" - }, { - "complete": 0, - "unlock_key": "reinvent|2|0" - }, { - "complete": 0, - "unlock_key": "reinvent|1|0" - }, { - "complete": 0, - "unlock_key": "redandblue|2|0" - }, { - "complete": 0, - "unlock_key": "redandblue|1|0" - }, { - "complete": 0, - "unlock_key": "rabbitintheblackroom|2|0" - }, { - "complete": 0, - "unlock_key": "rabbitintheblackroom|1|0" - }, { - "complete": 0, - "unlock_key": "worldexecuteme|1|0" - }, { - "complete": 0, - "unlock_key": "ringedgenesis|2|0" - }, { - "complete": 0, - "unlock_key": "quon|1|0" - }, { - "complete": 0, - "unlock_key": "qualia|2|0" - }, { - "complete": 0, - "unlock_key": "purgatorium|2|0" - }, { - "complete": 0, - "unlock_key": "supernova|2|0" - }, { - "complete": 0, - "unlock_key": "saikyostronger|2|3|einherjar|2" - }, { - "complete": 0, - "unlock_key": "purgatorium|1|0" - }, { - "complete": 0, - "unlock_key": "pragmatism|2|0" - }, { - "complete": 0, - "unlock_key": "ouroboros|2|0" - }, { - "complete": 0, - "unlock_key": "ouroboros|1|0" - }, { - "complete": 0, - "unlock_key": "oracle|1|0" - }, { - "complete": 0, - "unlock_key": "onelastdrive|2|0" - }, { - "complete": 0, - "unlock_key": "onelastdrive|1|0" - }, { - "complete": 0, - "unlock_key": "oblivia|2|0" - }, { - "complete": 0, - "unlock_key": "memoryforest|1|0" - }, { - "complete": 0, - "unlock_key": "melodyoflove|2|0" - }, { - "complete": 0, - "unlock_key": "saikyostronger|2|3|laqryma|2" - }, { - "complete": 0, - "unlock_key": "melodyoflove|1|0" - }, { - "complete": 0, - "unlock_key": "lucifer|2|0" - }, { - "complete": 0, - "unlock_key": "saikyostronger|2|3|izana|2" - }, { - "complete": 0, - "unlock_key": "halcyon|1|0" - }, { - "complete": 0, - "unlock_key": "memoryforest|2|0" - }, { - "complete": 0, - "unlock_key": "tiemedowngently|2|0" - }, { - "complete": 0, - "unlock_key": "lostdesire|1|0" - }, { - "complete": 0, - "unlock_key": "viciousheroism|1|0" - }, { - "complete": 0, - "unlock_key": "flyburg|1|0" - }, { - "complete": 0, - "unlock_key": "lostcivilization|2|0" - }, { - "complete": 0, - "unlock_key": "infinityheaven|1|0" - }, { - "complete": 0, - "unlock_key": "lostdesire|2|0" - }, { - "complete": 0, - "unlock_key": "ignotus|2|0" - }, { - "complete": 0, - "unlock_key": "harutopia|2|0" - }, { - "complete": 0, - "unlock_key": "revixy|1|0" - }, { - "complete": 0, - "unlock_key": "aterlbus|1|0" - }, { - "complete": 0, - "unlock_key": "linearaccelerator|2|0" - }, { - "complete": 0, - "unlock_key": "guardina|2|0" - }, { - "complete": 0, - "unlock_key": "corpssansorganes|2|0" - }, { - "complete": 0, - "unlock_key": "linearaccelerator|1|0" - }, { - "complete": 0, - "unlock_key": "guardina|1|0" - }, { - "complete": 0, - "unlock_key": "saikyostronger|2|0" - }, { - "complete": 0, - "unlock_key": "guardina|0|0" - }, { - "complete": 0, - "unlock_key": "valhallazero|1|0" - }, { - "complete": 0, - "unlock_key": "grimheart|1|0" - }, { - "complete": 0, - "unlock_key": "blaster|2|0" - }, { - "complete": 0, - "unlock_key": "grievouslady|2|101" - }, { - "complete": 0, - "unlock_key": "partyvinyl|2|0" - }, { - "complete": 0, - "unlock_key": "darakunosono|1|0" - }, { - "complete": 0, - "unlock_key": "grievouslady|1|101" - }, { - "complete": 0, - "unlock_key": "goodtek|1|0" - }, { - "complete": 0, - "unlock_key": "tempestissimo|3|101" - }, { - "complete": 0, - "unlock_key": "chronostasis|2|0" - }, { - "complete": 0, - "unlock_key": "gloryroad|2|0" - }, { - "complete": 0, - "unlock_key": "supernova|1|0" - }, { - "complete": 0, - "unlock_key": "singularity|2|0" - }, { - "complete": 0, - "unlock_key": "gloryroad|0|0" - }, { - "complete": 0, - "unlock_key": "shadesoflight|1|0" - }, { - "complete": 0, - "unlock_key": "kanagawa|2|0" - }, { - "complete": 0, - "unlock_key": "genesis|1|0" - }, { - "complete": 0, - "unlock_key": "fractureray|1|101" - }, { - "complete": 0, - "unlock_key": "freefall|2|0" - }, { - "complete": 0, - "unlock_key": "babaroque|1|0" - }, { - "complete": 0, - "unlock_key": "monochromeprincess|2|0" - }, { - "complete": 0, - "unlock_key": "flyburg|2|0" - }, { - "complete": 0, - "unlock_key": "shadesoflight|2|0" - }, { - "complete": 0, - "unlock_key": "espebranch|2|0" - }, { - "complete": 0, - "unlock_key": "qualia|1|0" - }, { - "complete": 0, - "unlock_key": "etherstrike|2|0" - }, { - "complete": 0, - "unlock_key": "tempestissimo|1|101" - }, { - "complete": 0, - "unlock_key": "conflict|1|0" - }, { - "complete": 0, - "unlock_key": "nhelv|1|0" - }, { - "complete": 0, - "unlock_key": "etherstrike|1|0" - }, { - "complete": 0, - "unlock_key": "syro|1|0" - }, { - "complete": 0, - "unlock_key": "anokumene|2|0" - }, { - "complete": 0, - "unlock_key": "essenceoftwilight|2|0" - }, { - "complete": 0, - "unlock_key": "snowwhite|1|0" - }, { - "complete": 0, - "unlock_key": "partyvinyl|1|0" - }, { - "complete": 0, - "unlock_key": "axiumcrisis|1|0" - }, { - "complete": 0, - "unlock_key": "ifi|2|0" - }, { - "complete": 0, - "unlock_key": "espebranch|1|0" - }, { - "complete": 0, - "unlock_key": "lostcivilization|1|0" - }, { - "complete": 0, - "unlock_key": "goodtek|2|0" - }, { - "complete": 0, - "unlock_key": "dandelion|2|0" - }, { - "complete": 0, - "unlock_key": "suomi|2|0" - }, { - "complete": 0, - "unlock_key": "dandelion|1|0" - }, { - "complete": 0, - "unlock_key": "oblivia|1|0" - }, { - "complete": 0, - "unlock_key": "cyberneciacatharsis|1|0" - }, { - "complete": 0, - "unlock_key": "quon|2|0" - }, { - "complete": 0, - "unlock_key": "bookmaker|2|0" - }, { - "complete": 0, - "unlock_key": "chronostasis|1|0" - }, { - "complete": 0, - "unlock_key": "heavensdoor|1|0" - }, { - "complete": 0, - "unlock_key": "tempestissimo|2|101" - }, { - "complete": 0, - "unlock_key": "cyaegha|2|0" - }, { - "complete": 0, - "unlock_key": "axiumcrisis|2|0" - }, { - "complete": 0, - "unlock_key": "blrink|2|0" - }, { - "complete": 0, - "unlock_key": "rise|1|0" - }, { - "complete": 0, - "unlock_key": "cyanine|1|0" - }, { - "complete": 0, - "unlock_key": "ifi|1|0" - }, { - "complete": 0, - "unlock_key": "aterlbus|2|0" - }, { - "complete": 0, - "unlock_key": "dreaminattraction|2|0" - }, { - "complete": 0, - "unlock_key": "bookmaker|1|0" - }, { - "complete": 0, - "unlock_key": "lucifer|1|0" - }, { - "complete": 0, - "unlock_key": "solitarydream|1|0" - }, { - "complete": 0, - "unlock_key": "ringedgenesis|1|0" - }, { - "complete": 0, - "unlock_key": "corpssansorganes|1|0" - }, { - "complete": 0, - "unlock_key": "vector|1|0" - }, { - "complete": 0, - "unlock_key": "infinityheaven|2|0" - }, { - "complete": 0, - "unlock_key": "essenceoftwilight|1|0" - }, { - "complete": 0, - "unlock_key": "conflict|2|0" - }, { - "complete": 0, - "unlock_key": "singularity|1|0" - }, { - "complete": 0, - "unlock_key": "harutopia|1|0" - }, { - "complete": 0, - "unlock_key": "cyberneciacatharsis|2|0" - }, { - "complete": 0, - "unlock_key": "oracle|2|0" - }, { - "complete": 0, - "unlock_key": "clotho|2|0" - }, { - "complete": 0, - "unlock_key": "corpssansorganes|0|0" - }, { - "complete": 0, - "unlock_key": "ignotus|1|0" - }, { - "complete": 0, - "unlock_key": "monochromeprincess|1|0" - }, { - "complete": 0, - "unlock_key": "nirvluce|1|0" - }, { - "complete": 0, - "unlock_key": "lethaeus|1|0" - }, { - "complete": 0, - "unlock_key": "clotho|1|0" - }, { - "complete": 0, - "unlock_key": "blaster|1|0" - }, { - "complete": 0, - "unlock_key": "fractureray|0|101" - }, { - "complete": 0, - "unlock_key": "kanagawa|1|0" - }, { - "complete": 0, - "unlock_key": "darakunosono|2|0" - }, { - "complete": 0, - "unlock_key": "freefall|1|0" - }, { - "complete": 0, - "unlock_key": "nirvluce|2|0" - }, { - "complete": 0, - "unlock_key": "cyanine|2|0" - }, { - "complete": 0, - "unlock_key": "heavensdoor|2|0" - }, { - "complete": 0, - "unlock_key": "genesis|2|0" - }, { - "complete": 0, - "unlock_key": "pragmatism|1|0" - }, { - "complete": 0, - "unlock_key": "nhelv|2|0" - }, { - "complete": 0, - "unlock_key": "halcyon|2|0" - }, { - "complete": 0, - "unlock_key": "blrink|1|0" - }, { - "complete": 0, - "unlock_key": "fractureray|2|101" - }, { - "complete": 0, - "unlock_key": "lethaeus|2|0" - }, { - "complete": 0, - "unlock_key": "sheriruth|1|0" - }, { - "complete": 0, - "unlock_key": "babaroque|2|0" - }, { - "complete": 0, - "unlock_key": "tiferet|2|0" - }, { - "complete": 0, - "unlock_key": "grimheart|2|0" - }, { - "complete": 0, - "unlock_key": "cyaegha|1|0" - }, { - "complete": 0, - "unlock_key": "aiueoon|2|0" - }, { - "complete": 0, - "unlock_key": "gloryroad|1|0" - }, { - "complete": 0, - "unlock_key": "anokumene|1|0" - }, { - "complete": 0, - "unlock_key": "grievouslady|0|101" - }, { - "complete": 0, - "unlock_key": "dreaminattraction|1|0" - }] - }, "clearedsongs": { - "": song_1 - }, - "clearlamps": { - "": song_2 - }, - "scores": { - "": song_3 - }, - "version": { - "val": 1 - } - } diff --git a/v1.0/auth.py b/v1.0/auth.py deleted file mode 100644 index 13d7ada..0000000 --- a/v1.0/auth.py +++ /dev/null @@ -1,141 +0,0 @@ -import sqlite3 -import hashlib -import time - - -def arc_login(name: str, password: str) -> str: # 登录判断 - # 查询数据库中的user表,验证账号密码,返回并记录token - # token采用user_id和时间戳连接后hash生成(真的是瞎想的,没用bear) - # 密码和token的加密方式为 SHA-256 - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest() - c.execute('''select user_id from user where name = :name and password = :password''', { - 'name': name, 'password': hash_pwd}) - x = c.fetchone() - if x is not None: - user_id = str(x[0]) - now = int(time.time() * 1000) - token = hashlib.sha256((user_id + str(now)).encode("utf8")).hexdigest() - c.execute( - '''select exists(select * from login where user_id = :user_id)''', {"user_id": user_id}) - - if c.fetchone() == (1,): # 删掉多余token - c.execute('''delete from login where user_id = :user_id''', - {'user_id': user_id}) - - c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', { - 'user_id': user_id, 'access_token': token}) - conn.commit() - conn.close() - return token - - conn.commit() - conn.close() - return None - - -def arc_register(name: str, password: str): # 注册 - # 账号注册,只记录hash密码和用户名,生成user_id和user_code,自动登录返回token - # token和密码的处理同登录部分 - - def build_user_code(c): - # 生成9位的user_code,用的自然是随机 - import random - flag = True - while flag: - user_code = ''.join([str(random.randint(0, 9)) for i in range(9)]) - c.execute('''select exists(select * from user where user_code = :user_code)''', - {'user_code': user_code}) - if c.fetchone() == (0,): - flag = False - return user_code - - def build_user_id(c): - # 生成user_id,往后加1 - c.execute('''select max(user_id) from user''') - x = c.fetchone() - if x[0] is not None: - return x[0] + 1 - else: - return 2000001 - - def insert_user_char(c, user_id): - # 为用户添加所有可用角色 - for i in range(0, 38): - if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36]: - sql = 'insert into user_char values('+str(user_id)+','+str( - i)+''',30,25000,25000,90,90,90,'',0,0,'',0,1,1)''' - c.execute(sql) - else: - if i != 5: - sql = 'insert into user_char values('+str(user_id)+','+str( - i)+''',30,25000,25000,90,90,90,'',0,0,'',0,0,0)''' - c.execute(sql) - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest() - c.execute( - '''select exists(select * from user where name = :name)''', {'name': name}) - if c.fetchone() == (0,): - user_code = build_user_code(c) - user_id = build_user_id(c) - now = int(time.time() * 1000) - c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt, - character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled) - values(:user_id, :name, :password, :join_date, :user_code, 0, 0, 0, 0, 0, 0, -1, 0) - ''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd}) - c.execute('''insert into recent30(user_id) values(:user_id)''', { - 'user_id': user_id}) - - token = hashlib.sha256( - (str(user_id) + str(now)).encode("utf8")).hexdigest() - c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', { - 'user_id': user_id, 'access_token': token}) - - insert_user_char(c, user_id) - conn.commit() - conn.close() - return user_id, token, 0 - else: - conn.commit() - conn.close() - return None, None, 101 - - -def token_get_id(token: str): - # 用token获取id,没有考虑不同用户token相同情况,说不定会有bug - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select user_id from login where access_token = :token''', { - 'token': token}) - x = c.fetchone() - if x is not None: - conn.commit() - conn.close() - return x[0] - else: - conn.commit() - conn.close() - return None - - -def code_get_id(user_code): - # 用user_code获取id - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select user_id from user where user_code = :a''', - {'a': user_code}) - x = c.fetchone() - if x is not None: - conn.commit() - conn.close() - return x[0] - else: - conn.commit() - conn.close() - return None diff --git a/v1.0/database/arcaea_database.db b/v1.0/database/arcaea_database.db deleted file mode 100644 index d5c0465..0000000 Binary files a/v1.0/database/arcaea_database.db and /dev/null differ diff --git a/v1.0/database/arcsong.db b/v1.0/database/arcsong.db deleted file mode 100644 index eecd170..0000000 Binary files a/v1.0/database/arcsong.db and /dev/null differ diff --git a/v1.0/database/database_initialize.py b/v1.0/database/database_initialize.py deleted file mode 100644 index 8ce7c79..0000000 --- a/v1.0/database/database_initialize.py +++ /dev/null @@ -1,204 +0,0 @@ -import sqlite3 -import hashlib -import time -# 数据库初始化文件,删掉arcaea_database.db文件后运行即可,谨慎使用 - -conn = sqlite3.connect('arcaea_database.db') -c = conn.cursor() -c.execute('''create table if not exists user(user_id int primary key, -name text unique, -password text not null, -join_date char(20), -user_code char(10), -rating_ptt int, -character_id int, -is_skill_sealed int, -is_char_uncapped int, -is_char_uncapped_override int, -is_hide_rating int, -song_id text, -difficulty int, -score int, -shiny_perfect_count int, -perfect_count int, -near_count int, -miss_count int, -health int, -modifier int, -time_played int, -clear_type int, -rating real, -favorite_character int, -max_stamina_notification_enabled int -);''') -c.execute('''create table if not exists login(access_token text, -user_id int, -last_login_time int, -last_login_ip text, -last_login_device text -);''') -c.execute('''create table if not exists friend(user_id_me int, -user_id_other int, -primary key (user_id_me, user_id_other) -);''') -c.execute('''create table if not exists best_score(user_id int, -song_id text, -difficulty int, -score int, -shiny_perfect_count int, -perfect_count int, -near_count int, -miss_count int, -health int, -modifier int, -time_played int, -best_clear_type int, -clear_type int, -rating real, -primary key(user_id, song_id, difficulty) -);''') -c.execute('''create table if not exists user_char(user_id int, -character_id int, -level int, -exp real, -level_exp real, -frag int, -prog int, -overdrive int, -skill_id text, -skill_unlock_level int, -skill_requires_uncap int, -skill_id_uncap text, -char_type int, -is_uncapped int, -is_uncapped_override int, -primary key(user_id, character_id) -);''') -c.execute('''create table if not exists character(character_id int primary key, -name text -);''') -c.execute('''create table if not exists recent30(user_id int primary key, -r0 real, -song_id0 text, -r1 real, -song_id1 text, -r2 real, -song_id2 text, -r3 real, -song_id3 text, -r4 real, -song_id4 text, -r5 real, -song_id5 text, -r6 real, -song_id6 text, -r7 real, -song_id7 text, -r8 real, -song_id8 text, -r9 real, -song_id9 text, -r10 real, -song_id10 text, -r11 real, -song_id11 text, -r12 real, -song_id12 text, -r13 real, -song_id13 text, -r14 real, -song_id14 text, -r15 real, -song_id15 text, -r16 real, -song_id16 text, -r17 real, -song_id17 text, -r18 real, -song_id18 text, -r19 real, -song_id19 text, -r20 real, -song_id20 text, -r21 real, -song_id21 text, -r22 real, -song_id22 text, -r23 real, -song_id23 text, -r24 real, -song_id24 text, -r25 real, -song_id25 text, -r26 real, -song_id26 text, -r27 real, -song_id27 text, -r28 real, -song_id28 text, -r29 real, -song_id29 text -);''') - -char = ['Hikari','Tairitsu','Kou','Sapphire','Lethe','','Tairitsu(Axium)' -,'Tairitsu(Grievous Lady)','Stella','Hikari & Fisica','Ilith','Eto','Luna' -,'Shirabe','Hikari(Zero)','Hikari(Fracture)','Hikari(Summer)','Tairitsu(Summer)' -,'Tairitsu&Trin','Ayu','Eto&Luna','Yume','Seine & Hikari','Saya','Tairitsu & Chuni Penguin' -,'Chuni Penguin','Haruna','Nono','MTA-XXX','MDA-21','Kanae','Hikari(Fantasia)','Tairitsu(Sonata)','Sia','DORO*C' -,'Tairitsu(Tempest)','Brillante','Ilith(Summer)'] - -for i in range(0, 38): - c.execute("insert into character values("+str(i)+",'"+char[i]+"');") - - -conn.commit() -conn.close() - - - -def arc_register(name: str, password: str): - def build_user_code(c): - return '123456789' - - def build_user_id(c): - return 2000000 - - def insert_user_char(c, user_id): - for i in range(0, 38): - if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36]: - sql = 'insert into user_char values('+str(user_id)+','+str( - i)+''',30,25000,25000,90,90,90,'',0,0,'',0,1,1)''' - c.execute(sql) - else: - if i != 5: - sql = 'insert into user_char values('+str(user_id)+','+str( - i)+''',30,25000,25000,90,90,90,'',0,0,'',0,0,0)''' - c.execute(sql) - - conn = sqlite3.connect('arcaea_database.db') - c = conn.cursor() - hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest() - c.execute( - '''select exists(select * from user where name = :name)''', {'name': name}) - if c.fetchone() == (0,): - user_code = build_user_code(c) - user_id = build_user_id(c) - now = int(time.time() * 1000) - c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt, - character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled) - values(:user_id, :name, :password, :join_date, :user_code, 1250, 1, 0, 1, 0, 0, -1, 0) - ''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd}) - c.execute('''insert into recent30(user_id) values(:user_id)''', { - 'user_id': user_id}) - c.execute('''insert into best_score values(2000000,'vexaria',3,10000000,100,0,0,0,100,0,1599667200000,3,3,10.8)''') - insert_user_char(c, user_id) - conn.commit() - conn.close() - return None - else: - conn.commit() - conn.close() - return None - - -arc_register('admin', 'admin123') diff --git a/v1.0/info.py b/v1.0/info.py deleted file mode 100644 index 72958f6..0000000 --- a/v1.0/info.py +++ /dev/null @@ -1,4060 +0,0 @@ -import sqlite3 - - -def int2b(x): - # int与布尔值转换 - if x is None or x == 0: - return False - else: - return True - - -def get_recent_score(c, user_id): - # 得到用户最近一次的成绩,返回列表 - c.execute('''select * from user where user_id = :x''', {'x': user_id}) - x = c.fetchone() - if x is not None: - if x[11] is not None: - c.execute('''select best_clear_type from best_score where user_id=:u and song_id=:s and difficulty=:d''', { - 'u': user_id, 's': x[11], 'd': x[12]}) - y = c.fetchone() - if y is not None: - best_clear_type = y[0] - else: - best_clear_type = x[21] - - return [{ - "rating": x[22], - "modifier": x[19], - "time_played": x[20], - "health": x[18], - "best_clear_type": best_clear_type, - "clear_type": x[21], - "miss_count": x[17], - "near_count": x[16], - "perfect_count": x[15], - "shiny_perfect_count": x[14], - "score": x[13], - "difficulty": x[12], - "song_id": x[11] - }] - return [] - - -def get_user_character(c, user_id): - # 得到用户拥有的角色列表,返回列表 - c.execute('''select * from user_char where user_id = :user_id''', - {'user_id': user_id}) - x = c.fetchall() - if x != []: - s = [] - for i in x: - char_name = '' - c.execute( - '''select name from character where character_id = :x''', {'x': i[1]}) - y = c.fetchone() - if y is not None: - char_name = y[0] - s.append({ - "is_uncapped_override": int2b(i[14]), - "is_uncapped": int2b(i[13]), - "uncap_cores": [], - "char_type": i[12], - "skill_id_uncap": i[11], - "skill_requires_uncap": int2b(i[10]), - "skill_unlock_level": i[9], - "skill_id": i[8], - "overdrive": i[7], - "prog": i[6], - "frag": i[5], - "level_exp": i[4], - "exp": i[3], - "level": i[2], - "name": char_name, - "character_id": i[1] - }) - - return s - else: - return [] - - -def get_user_friend(c, user_id): - # 得到用户的朋友列表,返回列表 - c.execute('''select user_id_other from friend where user_id_me = :user_id''', { - 'user_id': user_id}) - x = c.fetchall() - s = [] - if x != [] and x[0][0] is not None: - - for i in x: - c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''', - {'x': i[0], 'y': user_id}) - if c.fetchone() == (1,): - is_mutual = True - else: - is_mutual = False - - c.execute('''select * from user where user_id = :x''', {'x': i[0]}) - y=c.fetchone() - if y is not None: - s.append({ - "is_mutual": is_mutual, - "is_char_uncapped_override": int2b(y[9]), - "is_char_uncapped": int2b(y[8]), - "is_skill_sealed": int2b(y[7]), - "rating": y[5], - "join_date": int(y[3]), - "character": y[6], - "recent_score": get_recent_score(c, i[0]), - "name": y[1], - "user_id": i[0] - }) - - return s - - -def get_value_0(c, user_id): - # 构造value id=0的数据,返回字典 - c.execute('''select * from user where user_id = :x''', {'x': user_id}) - x = c.fetchone() - r = {} - if x is not None: - r = {"is_aprilfools": False, - "curr_available_maps": [], - "character_stats": get_user_character(c, user_id), - "friends": get_user_friend(c, user_id), - "settings": { - "favorite_character": x[23], - "is_hide_rating": int2b(x[10]), - "max_stamina_notification_enabled": int2b(x[24]) - }, - "user_id": user_id, - "name": x[1], - "user_code": x[4], - "display_name": x[1], - "ticket": 114514, - "character": x[6], - "is_locked_name_duplicate": False, - "is_skill_sealed": int2b(x[7]), - "current_map": "", - "prog_boost": 0, - "next_fragstam_ts": -1, - "max_stamina_ts": 1586274871917, - "stamina": 0, - "world_unlocks": [], - "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"], - "singles": [], - "packs": [], - "characters":[0,1,2,3,4]+[x for x in range(6, 38)], - "cores": [], - "recent_score": get_recent_score(c, user_id), - "max_friend": 50, - "rating": x[5], - "join_date": int(x[3]) - } - - return r - - -def arc_aggregate_small(user_id): - # 返回用户数据 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - r = {"success": True, - "value": [{ - "id": 0, - "value": get_value_0(c, user_id) - }]} - - conn.commit() - conn.close() - return r - - -def arc_aggregate_big(user_id): - # 返回用户数据和地图歌曲信息 - # 因为没有整理地图和曲包数据(不需要世界模式),所以直接复制了 - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - r = {"success": True, - "value": [{ - "id": 0, - "value": get_value_0(c, user_id) - }, { - "id": 1, - "value": [{ - "name": "core", - "items": [{ - "id": "core", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "shiawase", - "items": [{ - "id": "shiawase", - "type": "pack", - "is_available": True - }, { - "id": "kou", - "type": "character", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1552089600000, - "discount_to": 1552694399000 - }, { - "name": "dynamix", - "items": [{ - "id": "dynamix", - "type": "pack", - "is_available": True - }, { - "id": "sapphire", - "type": "character", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "mirai", - "items": [{ - "id": "mirai", - "type": "pack", - "is_available": True - }, { - "id": "lethe", - "type": "character", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1552089600000, - "discount_to": 1552694399000 - }, { - "name": "yugamu", - "items": [{ - "id": "yugamu", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "lanota", - "items": [{ - "id": "lanota", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "nijuusei", - "items": [{ - "id": "nijuusei", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "rei", - "items": [{ - "id": "rei", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "tonesphere", - "items": [{ - "id": "tonesphere", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "groovecoaster", - "items": [{ - "id": "groovecoaster", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "zettai", - "items": [{ - "id": "zettai", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "chunithm", - "items": [{ - "id": "chunithm", - "type": "pack", - "is_available": True - }], - "price": 300, - "orig_price": 300 - }, { - "name": "prelude", - "items": [{ - "id": "prelude", - "type": "pack", - "is_available": True - }], - "price": 400, - "orig_price": 400 - }, { - "name": "omatsuri", - "items": [{ - "id": "omatsuri", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500 - }, { - "name": "vs", - "items": [{ - "id": "vs", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500 - }, { - "name": "extend", - "items": [{ - "id": "extend", - "type": "pack", - "is_available": True - }], - "price": 700, - "orig_price": 700 - }] - }, { - "id": 2, - "value": {} - }, { - "id": 3, - "value": { - "max_stamina": 12, - "stamina_recover_tick": 1800000, - "core_exp": 250, - "curr_ts": 1599547606825, - "level_steps": [{ - "level": 1, - "level_exp": 0 - }, { - "level": 2, - "level_exp": 50 - }, { - "level": 3, - "level_exp": 100 - }, { - "level": 4, - "level_exp": 150 - }, { - "level": 5, - "level_exp": 200 - }, { - "level": 6, - "level_exp": 300 - }, { - "level": 7, - "level_exp": 450 - }, { - "level": 8, - "level_exp": 650 - }, { - "level": 9, - "level_exp": 900 - }, { - "level": 10, - "level_exp": 1200 - }, { - "level": 11, - "level_exp": 1600 - }, { - "level": 12, - "level_exp": 2100 - }, { - "level": 13, - "level_exp": 2700 - }, { - "level": 14, - "level_exp": 3400 - }, { - "level": 15, - "level_exp": 4200 - }, { - "level": 16, - "level_exp": 5100 - }, { - "level": 17, - "level_exp": 6100 - }, { - "level": 18, - "level_exp": 7200 - }, { - "level": 19, - "level_exp": 8500 - }, { - "level": 20, - "level_exp": 10000 - }, { - "level": 21, - "level_exp": 11500 - }, { - "level": 22, - "level_exp": 13000 - }, { - "level": 23, - "level_exp": 14500 - }, { - "level": 24, - "level_exp": 16000 - }, { - "level": 25, - "level_exp": 17500 - }, { - "level": 26, - "level_exp": 19000 - }, { - "level": 27, - "level_exp": 20500 - }, { - "level": 28, - "level_exp": 22000 - }, { - "level": 29, - "level_exp": 23500 - }, { - "level": 30, - "level_exp": 25000 - }], - "world_ranking_enabled": False, - "is_byd_chapter_unlocked": True - } - }, { - "id": 4, - "value": [] - }, { - "id": 5, - "value": { - "user_id": user_id, - "current_map": "", - "maps": [{ - "map_id": "hikari_art", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "", - "require_value": 1, - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "-270,150", - "step_count": 91, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "babaroque", - "type": "world_song" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 27 - }, { - "items": [{ - "id": "shadesoflight", - "type": "world_song" - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 45 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 50 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 55 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 60 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 65 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 70 - }, { - "items": [{ - "id": "kanagawa", - "type": "world_song" - }], - "position": 75 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 80 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 85 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 90 - }] - }, { - "map_id": "hikari_happy", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "270,150", - "step_count": 136, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 5 - }, { - "items": [{ - "id": "harutopia", - "type": "world_song" - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 25 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 30 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 32 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 45 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 50 - }, { - "items": [{ - "id": "goodtek", - "type": "world_song" - }], - "position": 55 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 60 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 65 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 70 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 75 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 80 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 82 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 85 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 90 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 95 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 97 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 100 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 105 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 110 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 115 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 120 - }, { - "items": [{ - "id": "dreaminattraction", - "type": "world_song" - }], - "position": 125 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 135 - }] - }, { - "map_id": "tairitsu_arcs", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "-270,-150", - "step_count": 136, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 5 - }, { - "items": [{ - "id": "rabbitintheblackroom", - "type": "world_song" - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 25 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 30 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 32 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 45 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 50 - }, { - "items": [{ - "id": "qualia", - "type": "world_song" - }], - "position": 55 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 60 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 65 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 70 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 75 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 80 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 82 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 85 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 90 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 95 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 97 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 100 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 105 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 110 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 115 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 120 - }, { - "items": [{ - "id": "redandblue", - "type": "world_song" - }], - "position": 125 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 135 - }] - }, { - "map_id": "tairitsu_tech", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "", - "require_value": 1, - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "270,-150", - "step_count": 91, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "lucifer", - "type": "world_song" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 27 - }, { - "items": [{ - "id": "anokumene", - "type": "world_song" - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 45 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 50 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 55 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 60 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 65 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 70 - }, { - "items": [{ - "id": "ignotus", - "type": "world_song" - }], - "position": 75 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 80 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 85 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 90 - }] - }, { - "map_id": "eternal", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "core", - "require_type": "pack", - "require_value": 1, - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "-500,0", - "step_count": 66, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 10 - }, { - "items": [{ - "id": "essenceoftwilight", - "type": "world_song" - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 28 - }, { - "items": [{ - "type": "fragment", - "amount": 200 - }], - "position": 35 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 42 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 44 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 46 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 48 - }, { - "items": [{ - "id": "pragmatism", - "type": "world_song" - }], - "position": 50 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 52 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 54 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 56 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 58 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 60 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 62 - }, { - "items": [{ - "id": "sheriruth", - "type": "world_song" - }], - "position": 65 - }] - }, { - "map_id": "axiumcrisis", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "yugamu", - "require_type": "pack", - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "500,0", - "step_count": 61, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 5 - }, { - "items": [{ - "id": "axiumcrisis", - "type": "world_song" - }], - "position": 10 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 24 - }, { - "items": [{ - "type": "fragment", - "amount": 200 - }], - "position": 30 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 37 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 39 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 41 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 43 - }, { - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 45 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 51 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 53 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 55 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 57 - }, { - "items": [{ - "id": "6", - "type": "character" - }], - "position": 60 - }] - }, { - "map_id": "grievouslady", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "yugamu", - "require_type": "pack", - "require_localunlock_songid": "grievouslady", - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "0,-150", - "step_count": 21, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 300 - }], - "position": 18 - }, { - "items": [{ - "id": "7", - "type": "character" - }], - "position": 20 - }] - }, { - "map_id": "lanota", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "lanota", - "require_type": "pack", - "coordinate": "460,-160", - "step_count": 35, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 40 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 10 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 12 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 80 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 27 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 33 - }, { - "items": [{ - "id": "9", - "type": "character" - }], - "position": 34 - }] - }, { - "map_id": "nijuusei_light", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "nijuusei", - "require_type": "pack", - "coordinate": "-260,160", - "step_count": 22, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 175 - }], - "position": 10 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 178 - }], - "position": 20 - }, { - "items": [{ - "id": "11", - "type": "character" - }], - "position": 21 - }] - }, { - "map_id": "nijuusei_conflict", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "nijuusei", - "require_type": "pack", - "require_localunlock_challengeid": "singularity", - "coordinate": "260,160", - "step_count": 36, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 175 - }], - "position": 2 - }, { - "items": [{ - "type": "fragment", - "amount": 175 - }], - "position": 3 - }, { - "items": [{ - "type": "fragment", - "amount": 175 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 178 - }], - "position": 5 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 6 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 7 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 8 - }, { - "items": [{ - "id": "12", - "type": "character" - }], - "position": 35 - }] - }, { - "map_id": "extra_originals", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "", - "require_value": 1, - "coordinate": "0,-200", - "step_count": 101, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 29 - }, { - "items": [{ - "id": "syro", - "type": "world_song" - }], - "position": 30 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 31 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 80 - }], - "position": 45 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 50 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 55 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 59 - }, { - "items": [{ - "id": "blaster", - "type": "world_song" - }], - "position": 60 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 61 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 65 - }, { - "items": [{ - "type": "fragment", - "amount": 80 - }], - "position": 70 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 75 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 80 - }, { - "items": [{ - "type": "fragment", - "amount": 80 - }], - "position": 85 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 90 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 94 - }, { - "items": [{ - "id": "cyberneciacatharsis", - "type": "world_song" - }], - "position": 95 - }, { - "items": [{ - "type": "core", - "id": "core_crimson", - "amount": 5 - }], - "position": 98 - }, { - "items": [{ - "type": "core", - "id": "core_crimson", - "amount": 5 - }], - "position": 100 - }] - }, { - "map_id": "guardina", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "dynamix", - "require_type": "pack", - "coordinate": "-460,-160", - "step_count": 35, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 1 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 9 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 16 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 17 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 18 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 25 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 33 - }, { - "items": [{ - "id": "guardina", - "type": "world_song" - }], - "position": 34 - }] - }, { - "map_id": "etherstrike", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "rei", - "require_type": "pack", - "coordinate": "0,-40", - "step_count": 36, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 5 - }, { - "items": [{ - "id": "etherstrike", - "type": "world_song" - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 26 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 27 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 28 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 29 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 31 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 32 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 33 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 34 - }, { - "items": [{ - "id": "14", - "type": "character" - }], - "position": 35 - }] - }, { - "map_id": "fractureray", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "rei", - "require_type": "pack", - "require_localunlock_songid": "fractureray", - "coordinate": "0,160", - "step_count": 23, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 13 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 16 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 17 - }, { - "items": [{ - "type": "fragment", - "amount": 350 - }], - "position": 19 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 20 - }, { - "items": [{ - "id": "15", - "type": "character" - }], - "position": 22 - }] - }, { - "map_id": "chapter3_light", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-480,180", - "step_count": 76, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 144 - }], - "position": 10 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 13 - }, { - "items": [{ - "type": "fragment", - "amount": 169 - }], - "position": 20 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 23 - }, { - "items": [{ - "id": "suomi", - "type": "world_song" - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 225 - }], - "position": 40 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 43 - }, { - "items": [{ - "type": "fragment", - "amount": 256 - }], - "position": 50 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 53 - }, { - "items": [{ - "id": "rugie", - "type": "world_song" - }], - "position": 59 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 65 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 70 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 75 - }] - }, { - "map_id": "chapter3_conflict", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-360,0", - "step_count": 85, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 10 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 19 - }, { - "items": [{ - "type": "fragment", - "amount": 15 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 25 - }, { - "items": [{ - "id": "bookmaker", - "type": "world_song" - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 200 - }], - "position": 35 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 39 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 45 - }, { - "items": [{ - "id": "darakunosono", - "type": "world_song" - }], - "position": 49 - }, { - "items": [{ - "type": "fragment", - "amount": 30 - }], - "position": 50 - }, { - "items": [{ - "type": "fragment", - "amount": 300 - }], - "position": 55 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 3 - }], - "position": 59 - }, { - "items": [{ - "type": "fragment", - "amount": 40 - }], - "position": 60 - }, { - "items": [{ - "id": "espebranch", - "type": "world_song" - }], - "position": 62 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 70 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 75 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 84 - }] - }, { - "map_id": "chapter3_conflict_2", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-240,-180", - "step_count": 51, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 125 - }], - "position": 9 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 125 - }], - "position": 19 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 24 - }, { - "items": [{ - "type": "fragment", - "amount": 125 - }], - "position": 29 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 34 - }, { - "items": [{ - "type": "fragment", - "amount": 125 - }], - "position": 39 - }, { - "items": [{ - "id": "nhelv", - "type": "world_song" - }], - "position": 40 - }, { - "items": [{ - "type": "core", - "id": "core_ambivalent", - "amount": 5 - }], - "position": 45 - }, { - "items": [{ - "type": "core", - "id": "core_ambivalent", - "amount": 5 - }], - "position": 50 - }] - }, { - "map_id": "tonesphere", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "tonesphere", - "require_type": "pack", - "coordinate": "480,180", - "step_count": 38, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 4 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 22 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 28 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 32 - }, { - "items": [{ - "id": "18", - "type": "character" - }], - "position": 37 - }] - }, { - "map_id": "groovecoaster", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "groovecoaster", - "require_type": "pack", - "coordinate": "360,0", - "step_count": 46, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 55 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 66 - }], - "position": 23 - }, { - "items": [{ - "type": "fragment", - "amount": 77 - }], - "position": 29 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 88 - }], - "position": 34 - }, { - "items": [{ - "type": "fragment", - "amount": 99 - }], - "position": 39 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 40 - }, { - "items": [{ - "id": "22", - "type": "character" - }], - "position": 45 - }] - }, { - "map_id": "solitarydream", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 5, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "core", - "require_type": "pack", - "coordinate": "-250,0", - "step_count": 10, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "solitarydream", - "type": "world_song" - }], - "position": 9 - }] - }, { - "map_id": "zettai", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "zettai", - "require_type": "pack", - "coordinate": "-100,115", - "step_count": 26, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 20 - }, { - "items": [{ - "id": "23", - "type": "character" - }], - "position": 25 - }] - }, { - "map_id": "chapter4_ripples", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-280,-200", - "step_count": 51, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 170 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 170 - }], - "position": 12 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 16 - }, { - "items": [{ - "id": "grimheart", - "type": "world_song" - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 190 - }], - "position": 26 - }, { - "items": [{ - "type": "fragment", - "amount": 190 - }], - "position": 42 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 46 - }, { - "items": [{ - "id": "vector", - "type": "world_song" - }], - "position": 50 - }] - }, { - "map_id": "chapter4_waves", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-480,-200", - "step_count": 41, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 5 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 8 - }, { - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 18 - }, { - "items": [{ - "id": "revixy", - "type": "world_song" - }], - "position": 25 - }, { - "items": [{ - "type": "fragment", - "amount": 400 - }], - "position": 30 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 33 - }, { - "items": [{ - "id": "supernova", - "type": "world_song" - }], - "position": 40 - }] - }, { - "map_id": "chunithm", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "chunithm", - "require_type": "pack", - "coordinate": "480,200", - "step_count": 28, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 110 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 120 - }], - "position": 10 - }, { - "items": [{ - "id": "worldvanquisher", - "type": "world_song" - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 20 - }, { - "items": [{ - "id": "24", - "type": "character" - }], - "position": 27 - }] - }, { - "map_id": "omatsuri", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "omatsuri", - "require_type": "pack", - "coordinate": "280,200", - "step_count": 21, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 230 - }], - "position": 3 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 6 - }, { - "items": [{ - "type": "fragment", - "amount": 230 - }], - "position": 9 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 12 - }, { - "items": [{ - "id": "30", - "type": "character" - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 20 - }] - }, { - "map_id": "chapter4_the_calm", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-380,-30", - "step_count": 146, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 10 - }], - "position": 1 - }, { - "items": [{ - "type": "fragment", - "amount": 10 - }], - "position": 2 - }, { - "items": [{ - "type": "fragment", - "amount": 10 - }], - "position": 3 - }, { - "items": [{ - "type": "fragment", - "amount": 10 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 15 - }], - "position": 11 - }, { - "items": [{ - "type": "fragment", - "amount": 15 - }], - "position": 12 - }, { - "items": [{ - "type": "fragment", - "amount": 15 - }], - "position": 13 - }, { - "items": [{ - "type": "fragment", - "amount": 15 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 20 - }], - "position": 21 - }, { - "items": [{ - "type": "fragment", - "amount": 20 - }], - "position": 22 - }, { - "items": [{ - "type": "fragment", - "amount": 20 - }], - "position": 23 - }, { - "items": [{ - "type": "fragment", - "amount": 20 - }], - "position": 24 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 31 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 32 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 33 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 34 - }, { - "items": [{ - "type": "fragment", - "amount": 30 - }], - "position": 41 - }, { - "items": [{ - "type": "fragment", - "amount": 30 - }], - "position": 42 - }, { - "items": [{ - "type": "fragment", - "amount": 30 - }], - "position": 43 - }, { - "items": [{ - "type": "fragment", - "amount": 30 - }], - "position": 44 - }, { - "items": [{ - "type": "fragment", - "amount": 35 - }], - "position": 51 - }, { - "items": [{ - "type": "fragment", - "amount": 35 - }], - "position": 52 - }, { - "items": [{ - "type": "fragment", - "amount": 35 - }], - "position": 53 - }, { - "items": [{ - "id": "diode", - "type": "world_song" - }], - "position": 54 - }, { - "items": [{ - "type": "fragment", - "amount": 40 - }], - "position": 62 - }, { - "items": [{ - "type": "fragment", - "amount": 40 - }], - "position": 64 - }, { - "items": [{ - "type": "fragment", - "amount": 45 - }], - "position": 72 - }, { - "items": [{ - "type": "fragment", - "amount": 45 - }], - "position": 74 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 82 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 84 - }, { - "items": [{ - "type": "fragment", - "amount": 55 - }], - "position": 92 - }, { - "items": [{ - "id": "freefall", - "type": "world_song" - }], - "position": 94 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 102 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 104 - }, { - "items": [{ - "type": "fragment", - "amount": 65 - }], - "position": 112 - }, { - "items": [{ - "type": "fragment", - "amount": 65 - }], - "position": 114 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 122 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 124 - }, { - "items": [{ - "type": "fragment", - "amount": 75 - }], - "position": 132 - }, { - "items": [{ - "id": "monochromeprincess", - "type": "world_song" - }], - "position": 134 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 3 - }], - "position": 145 - }] - }, { - "map_id": "gloryroad", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "shiawase", - "require_type": "pack", - "coordinate": "380,30", - "step_count": 28, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 1 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 11 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 14 - }, { - "items": [{ - "id": "gloryroad", - "type": "world_song" - }], - "position": 20 - }, { - "items": [{ - "type": "core", - "id": "core_crimson", - "amount": 5 - }], - "position": 23 - }, { - "items": [{ - "type": "core", - "id": "core_crimson", - "amount": 5 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_crimson", - "amount": 5 - }], - "position": 27 - }] - }, { - "map_id": "blrink", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 5, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "prelude", - "require_type": "pack", - "coordinate": "250,0", - "step_count": 17, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "blrink", - "type": "world_song" - }], - "position": 16 - }] - }, { - "map_id": "corpssansorganes", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "mirai", - "require_type": "pack", - "coordinate": "0,200", - "step_count": 42, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 105 - }], - "position": 6 - }, { - "items": [{ - "type": "fragment", - "amount": 105 - }], - "position": 12 - }, { - "items": [{ - "type": "fragment", - "amount": 105 - }], - "position": 22 - }, { - "items": [{ - "type": "fragment", - "amount": 105 - }], - "position": 28 - }, { - "items": [{ - "id": "corpssansorganes", - "type": "world_song" - }], - "position": 31 - }, { - "items": [{ - "type": "core", - "id": "core_ambivalent", - "amount": 5 - }], - "position": 35 - }, { - "items": [{ - "type": "core", - "id": "core_ambivalent", - "amount": 5 - }], - "position": 38 - }, { - "items": [{ - "type": "core", - "id": "core_ambivalent", - "amount": 5 - }], - "position": 41 - }] - }, { - "map_id": "lostdesire", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 5, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "vs", - "require_type": "pack", - "coordinate": "0,0", - "step_count": 36, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "lostdesire", - "type": "world_song" - }], - "position": 5 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 35 - }] - }, { - "map_id": "tempestissimo", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 5, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "vs", - "require_type": "pack", - "require_localunlock_challengeid": "tempestissimo", - "coordinate": "0,160", - "step_count": 16, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "35", - "type": "character" - }], - "position": 3 - }, { - "items": [{ - "type": "fragment", - "amount": 1000 - }], - "position": 15 - }] - }, { - "map_id": "chapter_1_scenery", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": True, - "require_id": "", - "require_type": "chapter_step", - "require_value": 455, - "coordinate": "0,150", - "step_count": 51, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "world_unlock", - "id": "scenery_chap1" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 80 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 25 - }, { - "items": [{ - "type": "fragment", - "amount": 110 - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 120 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 130 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 50 - }] - }, { - "map_id": "chapter_2_scenery", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": True, - "require_id": "", - "require_type": "chapter_step", - "require_value": 105, - "coordinate": "0,-20", - "step_count": 51, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "world_unlock", - "id": "scenery_chap2" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 11 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 12 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 13 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 31 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 32 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 33 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 34 - }, { - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 50 - }] - }, { - "map_id": "chapter_3_scenery", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": True, - "require_id": "", - "require_type": "chapter_step", - "require_value": 205, - "coordinate": "240,-180", - "step_count": 17, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "world_unlock", - "id": "scenery_chap3" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 400 - }], - "position": 16 - }] - }, { - "map_id": "chapter_4_scenery", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": True, - "require_id": "", - "require_type": "chapter_step", - "require_value": 240, - "coordinate": "100,-115", - "step_count": 101, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "world_unlock", - "id": "scenery_chap4" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 2000 - }], - "position": 100 - }] - }, { - "map_id": "chapter_5_scenery", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 5, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": True, - "require_id": "", - "require_type": "chapter_step", - "require_value": 75, - "coordinate": "0,-160", - "step_count": 31, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "world_unlock", - "id": "scenery_chap5" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 500 - }], - "position": 30 - }] - }, { - "map_id": "byd_goodtek", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "goodtek2", - "require_type": "chart_unlock", - "coordinate": "900,650", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 250, - "character_affinity": [0, 1], - "affinity_multiplier": [2.5, 1.5], - "step_count": 6, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 2 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 10 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 24 - }, { - "items": [{ - "type": "fragment", - "amount": 275 - }], - "position": 31 - }, { - "items": [{ - "id": "goodtek3", - "type": "world_song" - }], - "position": 33 - }] - }, { - "map_id": "byd_vexaria", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "vexaria2", - "require_type": "chart_unlock", - "coordinate": "650,400", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 150, - "character_affinity": [0, 1], - "affinity_multiplier": [2.5, 1.5], - "step_count": 3, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 616 - }], - "position": 42 - }, { - "items": [{ - "id": "vexaria3", - "type": "world_song" - }], - "position": 46 - }] - }, { - "map_id": "byd_fairytale", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "fairytale2", - "require_type": "chart_unlock", - "coordinate": "400,650", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 200, - "character_affinity": [0, 1], - "affinity_multiplier": [2.5, 1.5], - "step_count": 3, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 4 - }], - "position": 20 - }, { - "items": [{ - "id": "fairytale3", - "type": "world_song" - }], - "position": 55 - }] - }, { - "map_id": "byd_infinityheaven", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "infinityheaven2", - "require_type": "chart_unlock", - "coordinate": "650,900", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 200, - "character_affinity": [0, 1], - "affinity_multiplier": [2.5, 1.5], - "step_count": 9, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 1 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 2 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 3 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 6 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 7 - }, { - "items": [{ - "id": "infinityheaven3", - "type": "world_song" - }], - "position": 8 - }] - }, { - "map_id": "byd_purgatorium", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "purgatorium2", - "require_type": "chart_unlock", - "coordinate": "-900,-650", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 200, - "character_affinity": [13, 1], - "affinity_multiplier": [2.6, 1.6], - "step_count": 5, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 2 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 14 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 30 - }, { - "items": [{ - "id": "purgatorium3", - "type": "world_song" - }], - "position": 37 - }] - }, { - "map_id": "byd_dement", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "dement2", - "require_type": "chart_unlock", - "coordinate": "-400,-650", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 250, - "character_affinity": [13, 1], - "affinity_multiplier": [2.6, 1.6], - "step_count": 4, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 19 - }, { - "items": [{ - "type": "fragment", - "amount": 1200 - }], - "position": 39 - }, { - "items": [{ - "id": "dement3", - "type": "world_song" - }], - "position": 43 - }] - }, { - "map_id": "maliciousmischance_event", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 0, - "available_from": 1599177600000, - "available_to": 1599836400000, - "is_repeatable": False, - "require_id": "maliciousmischance", - "require_type": "single", - "coordinate": "0,0", - "step_count": 87, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 62 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 63 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 67 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 68 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 72 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 73 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 77 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 78 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 82 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 83 - }, { - "items": [{ - "id": "37", - "type": "character" - }], - "position": 86 - }] - }] - }} - ]} - - conn.commit() - conn.close() - return r diff --git a/v1.0/main.py b/v1.0/main.py deleted file mode 100644 index d5fe3e8..0000000 --- a/v1.0/main.py +++ /dev/null @@ -1,418 +0,0 @@ -from flask import Flask, request, jsonify, make_response -import configparser -import base64 -import auth -import info -import setme -import arcscore - -app = Flask(__name__) -wsgi_app = app.wsgi_app - - -def error_return(error_code): # 错误返回 - # 100 无法在此ip地址下登录游戏 - # 101 用户名占用 - # 102 电子邮箱已注册 - # 103 已有一个账号由此设备创建 - # 104 用户名密码错误 - # 105 24小时内登入两台设备 - # 106 账户冻结 - # 107 你没有足够的体力 - # 401 用户不存在 - # 403 无法连接至服务器 - # 501 502 此物品目前无法获取 - # 504 无效的序列码 - # 505 此序列码已被使用 - # 506 你已拥有了此物品 - # 601 好友列表已满 - # 602 此用户已是好友 - # 604 你不能加自己为好友 - # 其它 发生未知错误 - return jsonify({ - "success": False, - "error_code": error_code - }) - - -@app.route('/') -def hello(): - return "Hello World!" - - -@app.route('/coffee/12/auth/login', methods=['POST']) # 登录接口 -def login(): - headers = request.headers - id_pwd = headers['Authorization'] - id_pwd = base64.b64decode(id_pwd[6:]).decode() - name, password = id_pwd.split(':', 1) - - try: - token = auth.arc_login(name, password) - if token is not None: - r = {"success": True, "token_type": "Bearer"} - r['access_token'] = token - return jsonify(r) - else: - return error_return(104) # 用户名或密码错误 - except: - return error_return(108) - - -@app.route('/coffee/12/user/', methods=['POST']) # 注册接口 -def register(): - name = request.form['name'] - password = request.form['password'] - try: - user_id, token, error_code = auth.arc_register(name, password) - if user_id is not None: - r = {"success": True, "value": { - 'user_id': user_id, 'access_token': token}} - return jsonify(r) - else: - return error_return(error_code) # 应该是101,用户名被占用,毕竟电子邮箱、设备号没记录 - except: - return error_return(108) - - -@app.route('/coffee/12/compose/aggregate', methods=['GET']) # 用户信息获取 -def aggregate(): - calls = request.args.get('calls') - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = auth.token_get_id(token) - if user_id is not None: - if calls == '[{ "endpoint": "/user/me", "id": 0 }]': # 极其沙雕的判断,我猜get的参数就两种 - r = info.arc_aggregate_small(user_id) - else: - r = info.arc_aggregate_big(user_id) - return jsonify(r) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/user/me/character', methods=['POST']) # 角色切换 -def character_change(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - character_id = request.form['character'] - skill_sealed = request.form['skill_sealed'] - try: - user_id = auth.token_get_id(token) - if user_id is not None: - flag = setme.change_char(user_id, character_id, skill_sealed) - if flag: - return jsonify({ - "success": True, - "value": { - "user_id": user_id, - "character": character_id - } - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee//toggle_uncap', methods=['POST']) # 角色觉醒切换 -def character_uncap(path): - character_id = int(path[22:]) - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = auth.token_get_id(token) - if user_id is not None: - r = setme.change_char_uncap(user_id, character_id) - if r is not None: - return jsonify({ - "success": True, - "value": { - "user_id": user_id, - "character": [r] - } - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/friend/me/add', methods=['POST']) # 加好友 -def add_friend(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - friend_code = request.form['friend_code'] - try: - user_id = auth.token_get_id(token) - friend_id = auth.code_get_id(friend_code) - if user_id is not None and friend_id is not None: - r = setme.arc_add_friend(user_id, friend_id) - if r is not None and r != 602 and r != 604: - return jsonify({ - "success": True, - "value": { - "user_id": user_id, - "updatedAt": "2020-09-07T07:32:12.740Z", - "createdAt": "2020-09-06T10:05:18.471Z", - "friends": r - } - }) - else: - if r is not None: - return error_return(r) - else: - return error_return(108) - else: - if friend_id is None: - return error_return(401) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/friend/me/delete', methods=['POST']) # 删好友 -def delete_friend(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - friend_id = int(request.form['friend_id']) - try: - user_id = auth.token_get_id(token) - if user_id is not None and friend_id is not None: - r = setme.arc_delete_friend(user_id, friend_id) - if r is not None: - return jsonify({ - "success": True, - "value": { - "user_id": user_id, - "updatedAt": "2020-09-07T07:32:12.740Z", - "createdAt": "2020-09-06T10:05:18.471Z", - "friends": r - } - }) - else: - return error_return(108) - else: - if friend_id is None: - return error_return(401) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/score/song/friend', methods=['GET']) # 好友排名,默认最多50 -def song_score_friend(): - song_id = request.args.get('song_id') - difficulty = request.args.get('difficulty') - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = auth.token_get_id(token) - if user_id is not None: - r = arcscore.arc_score_friend(user_id, song_id, difficulty) - if r is not None: - return jsonify({ - "success": True, - "value": r - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/score/song/me', methods=['GET']) # 我的排名,默认最多20 -def song_score_me(): - song_id = request.args.get('song_id') - difficulty = request.args.get('difficulty') - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = auth.token_get_id(token) - if user_id is not None: - r = arcscore.arc_score_me(user_id, song_id, difficulty) - if r is not None: - return jsonify({ - "success": True, - "value": r - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/score/song', methods=['GET']) # TOP20 -def song_score_top(): - song_id = request.args.get('song_id') - difficulty = request.args.get('difficulty') - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = auth.token_get_id(token) - if user_id is not None: - r = arcscore.arc_score_top(song_id, difficulty) - if r is not None: - return jsonify({ - "success": True, - "value": r - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/score/song', methods=['POST']) # 成绩上传 -def song_score_post(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - song_id = request.form['song_id'] - difficulty = int(request.form['difficulty']) - score = int(request.form['score']) - shiny_perfect_count = int(request.form['shiny_perfect_count']) - perfect_count = int(request.form['perfect_count']) - near_count = int(request.form['near_count']) - miss_count = int(request.form['miss_count']) - health = int(request.form['health']) - modifier = int(request.form['modifier']) - beyond_gauge = int(request.form['beyond_gauge']) - clear_type = int(request.form['clear_type']) - - try: - user_id = auth.token_get_id(token) - if user_id is not None: - r = arcscore.arc_score_post(user_id, song_id, difficulty, score, shiny_perfect_count, - perfect_count, near_count, miss_count, health, modifier, beyond_gauge, clear_type) - if r is not None: - return jsonify({ - "success": True, - "value": {"user_rating": r} - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/score/token', methods=['GET']) # 成绩上传所需的token,显然我不想验证 -def score_token(): - return jsonify({ - "success": True, - "value": { - "token": "1145141919810" - } - }) - - -@app.route('/coffee/12/user/me/save', methods=['GET']) # 从云端同步 -def cloud_get(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = auth.token_get_id(token) - if user_id is not None: - r = arcscore.arc_all_get(user_id) - if r is not None: - return jsonify({ - "success": True, - "value": r - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/user/me/save', methods=['POST']) # 向云端同步 -def cloud_post(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - scores_data = request.form['scores_data'] - clearlamps_data = request.form['clearlamps_data'] - try: - user_id = auth.token_get_id(token) - if user_id is not None: - arcscore.arc_all_post(user_id, scores_data, clearlamps_data) - return jsonify({ - "success": True, - "value": { - "user_id": user_id - } - }) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/purchase/me/redeem', methods=['POST']) # 兑换码,自然没有用 -def redeem(): - return error_return(504) - - -@app.route('/coffee/', methods=['POST']) # 三个设置,写在最后降低优先级 -def sys_set(path): - set_arg = path[10:] - headers = request.headers - token = headers['Authorization'] - token = token[7:] - value = request.form['value'] - - try: - user_id = auth.token_get_id(token) - if user_id is not None: - setme.arc_sys_set(user_id, value, set_arg) - r = info.arc_aggregate_small(user_id) - r['value'] = r['value'][0]['value'] - return jsonify(r) - else: - return error_return(108) - except: - return error_return(108) - - -def main(): - config = configparser.ConfigParser() - path = r'setting.ini' - config.read(path, encoding="utf-8") - HOST = config.get('CONFIG','HOST') - PORT = config.get('CONFIG','PORT') - app.run(HOST, PORT) - - -if __name__ == '__main__': - main() - - -## Made By Lost 2020.9.11 diff --git a/v1.0/run.bat b/v1.0/run.bat deleted file mode 100644 index 7a84f97..0000000 --- a/v1.0/run.bat +++ /dev/null @@ -1 +0,0 @@ -python main.py \ No newline at end of file diff --git a/v1.0/setme.py b/v1.0/setme.py deleted file mode 100644 index 4caace3..0000000 --- a/v1.0/setme.py +++ /dev/null @@ -1,155 +0,0 @@ -import sqlite3 -import info - - -def b2int(x): - # int与布尔值转换 - if x: - return 1 - else: - return 0 - - -def int2b(x): - # int与布尔值转换 - if x is None or x == 0: - return False - else: - return True - - -def change_char(user_id, character_id, skill_sealed): - # 角色改变,包括技能封印的改变,返回成功与否的布尔值 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id = :a and character_id = :b''', - {'a': user_id, 'b': character_id}) - x = c.fetchone() - if x is not None: - if skill_sealed == 'false': - skill_sealed = False - else: - skill_sealed = True - c.execute('''update user set is_skill_sealed = :a, character_id = :b, is_char_uncapped = :c, is_char_uncapped_override = :d where user_id = :e''', { - 'a': b2int(skill_sealed), 'b': character_id, 'c': x[0], 'd': x[1], 'e': user_id}) - - conn.commit() - conn.close() - return True - - conn.commit() - conn.close() - return False - - -def change_char_uncap(user_id, character_id): - # 角色觉醒改变,返回字典 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id = :a and character_id = :b''', - {'a': user_id, 'b': character_id}) - x = c.fetchone() - r = None - if x is not None and x[0] == 1: - c.execute('''update user set is_char_uncapped_override = :a where user_id = :b''', { - 'a': b2int(x[1] == 0), 'b': user_id}) - c.execute('''update user_char set is_uncapped_override = :a where user_id = :b and character_id = :c''', { - 'a': b2int(x[1] == 0), 'b': user_id, 'c': character_id}) - c.execute('''select * from user_char where user_id = :a and character_id = :b''', - {'a': user_id, 'b': character_id}) - y = c.fetchone() - c.execute( - '''select name from character where character_id = :x''', {'x': y[1]}) - z = c.fetchone() - if z is not None: - char_name = z[0] - if y is not None: - r = { - "is_uncapped_override": int2b(y[14]), - "is_uncapped": int2b(y[13]), - "uncap_cores": [], - "char_type": y[12], - "skill_id_uncap": y[11], - "skill_requires_uncap": int2b(y[10]), - "skill_unlock_level": y[9], - "skill_id": y[8], - "overdrive": y[7], - "prog": y[6], - "frag": y[5], - "level_exp": y[4], - "exp": y[3], - "level": y[2], - "name": char_name, - "character_id": y[1] - } - - conn.commit() - conn.close() - return r - - -def arc_sys_set(user_id, value, set_arg): - # 三个设置,PTT隐藏、体力满通知、最爱角色,无返回 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - if 'favorite_character' in set_arg: - value = int(value) - c.execute('''update user set favorite_character = :a where user_id = :b''', { - 'a': value, 'b': user_id}) - - else: - if value == 'false': - value = False - else: - value = True - - if 'is_hide_rating' in set_arg: - c.execute('''update user set is_hide_rating = :a where user_id = :b''', { - 'a': b2int(value), 'b': user_id}) - if 'max_stamina_notification_enabled' in set_arg: - c.execute('''update user set max_stamina_notification_enabled = :a where user_id = :b''', { - 'a': b2int(value), 'b': user_id}) - - conn.commit() - conn.close() - return None - - -def arc_add_friend(user_id, friend_id): - # 加好友,返回好友列表,或者是错误码602、604 - if user_id == friend_id: - return 604 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''', - {'x': user_id, 'y': friend_id}) - r = None - if c.fetchone() == (0,): - c.execute('''insert into friend values(:a, :b)''', - {'a': user_id, 'b': friend_id}) - r = info.get_user_friend(c, user_id) - - else: - return 602 - - conn.commit() - conn.close() - return r - - -def arc_delete_friend(user_id, friend_id): - # 删好友,返回好友列表 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''', - {'x': user_id, 'y': friend_id}) - r = None - if c.fetchone() == (1,): - c.execute('''delete from friend where user_id_me = :x and user_id_other = :y''', - {'x': user_id, 'y': friend_id}) - - r = info.get_user_friend(c, user_id) - - conn.commit() - conn.close() - return r diff --git a/v1.0/setting.ini b/v1.0/setting.ini deleted file mode 100644 index 474d095..0000000 --- a/v1.0/setting.ini +++ /dev/null @@ -1,3 +0,0 @@ -[CONFIG] -HOST = 192.168.1.112 -PORT = 80 \ No newline at end of file diff --git a/v1.1/arcscore.py b/v1.1/arcscore.py deleted file mode 100644 index 8f4fd8c..0000000 --- a/v1.1/arcscore.py +++ /dev/null @@ -1,1242 +0,0 @@ -import sqlite3 -import time -import json - - -def b2int(x): - # int与布尔值转换 - if x: - return 1 - else: - return 0 - - -def int2b(x): - # int与布尔值转换 - if x is None or x == 0: - return False - else: - return True - - -def get_score(c, user_id, song_id, difficulty): - # 根据user_id、song_id、难度得到该曲目最好成绩,返回字典 - c.execute('''select * from best_score where user_id = :a and song_id = :b and difficulty = :c''', - {'a': user_id, 'b': song_id, 'c': difficulty}) - x = c.fetchone() - if x is not None: - c.execute('''select name, character_id, is_skill_sealed, is_char_uncapped from user where user_id = :a''', { - 'a': user_id}) - y = c.fetchone() - if y is not None: - return { - "user_id": x[0], - "song_id": x[1], - "difficulty": x[2], - "score": x[3], - "shiny_perfect_count": x[4], - "perfect_count": x[5], - "near_count": x[6], - "miss_count": x[7], - "health": x[8], - "modifier": x[9], - "time_played": x[10], - "best_clear_type": x[11], - "clear_type": x[12], - "name": y[0], - "character": y[1], - "is_skill_sealed": int2b(y[2]), - "is_char_uncapped": int2b(y[3]) - } - else: - return {} - else: - return {} - - -def arc_score_friend(user_id, song_id, difficulty, limit=50): - # 得到用户好友分数表,默认最大50个 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select user_id from best_score where user_id in (select :user_id union select user_id_other from friend where user_id_me = :user_id) and song_id = :song_id and difficulty = :difficulty order by score DESC, time_played DESC limit :limit''', { - 'user_id': user_id, 'song_id': song_id, 'difficulty': difficulty, 'limit': limit}) - x = c.fetchall() - r = [] - if x != []: - rank = 0 - for i in x: - rank += 1 - y = get_score(c, i[0], song_id, difficulty) - y['rank'] = rank - r.append(y) - - conn.commit() - conn.close() - return r - - -def arc_score_top(song_id, difficulty, limit=20): - # 得到top分数表,默认最多20个 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select user_id from best_score where song_id = :song_id and difficulty = :difficulty order by score DESC, time_played DESC limit :limit''', { - 'song_id': song_id, 'difficulty': difficulty, 'limit': limit}) - x = c.fetchall() - r = [] - if x != []: - rank = 0 - for i in x: - rank += 1 - y = get_score(c, i[0], song_id, difficulty) - y['rank'] = rank - r.append(y) - - conn.commit() - conn.close() - return r - - -def arc_score_me(user_id, song_id, difficulty, limit=20): - # 得到用户的排名,默认最大20个 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - r = [] - c.execute('''select exists(select * from best_score where user_id = :user_id and song_id = :song_id and difficulty = :difficulty)''', { - 'user_id': user_id, 'song_id': song_id, 'difficulty': difficulty}) - if c.fetchone() == (1,): - c.execute('''select count(*) from best_score where song_id = :song_id and difficulty = :difficulty and (score>(select score from best_score where user_id = :user_id and song_id = :song_id and difficulty = :difficulty) or (score>(select score from best_score where user_id = :user_id and song_id = :song_id and difficulty = :difficulty) and time_played > (select time_played from best_score where user_id = :user_id and song_id = :song_id and difficulty = :difficulty)) )''', { - 'user_id': user_id, 'song_id': song_id, 'difficulty': difficulty}) - x = c.fetchone() - myrank = int(x[0]) + 1 - if myrank <= 4: # 排名在前4 - conn.commit() - conn.close() - return arc_score_top(song_id, difficulty, limit) - elif myrank >= 5 and myrank <= 9999 - limit + 4: # 万名内,前面有4个人 - c.execute('''select user_id from best_score where song_id = :song_id and difficulty = :difficulty order by score DESC, time_played DESC limit :limit offset :offset''', { - 'song_id': song_id, 'difficulty': difficulty, 'limit': limit, 'offset': myrank - 5}) - x = c.fetchall() - if x != []: - rank = myrank - 5 - for i in x: - rank += 1 - y = get_score(c, i[0], song_id, difficulty) - y['rank'] = rank - r.append(y) - - elif myrank >= 10000: # 万名外 - c.execute('''select user_id from best_score where song_id = :song_id and difficulty = :difficulty order by score DESC, time_played DESC limit :limit offset :offset''', { - 'song_id': song_id, 'difficulty': difficulty, 'limit': limit - 1, 'offset': 9999-limit}) - x = c.fetchall() - if x != []: - rank = 9999 - limit - for i in x: - rank += 1 - y = get_score(c, i[0], song_id, difficulty) - y['rank'] = rank - r.append(y) - y = get_score(c, user_id, song_id, difficulty) - y['rank'] = -1 - r.append(y) - else: - c.execute('''select user_id from best_score where song_id = :song_id and difficulty = :difficulty order by score DESC, time_played DESC limit :limit offset :offset''', { - 'song_id': song_id, 'difficulty': difficulty, 'limit': limit, 'offset': 9998-limit}) - x = c.fetchall() - if x != []: - rank = 9998 - limit - for i in x: - rank += 1 - y = get_score(c, i[0], song_id, difficulty) - y['rank'] = rank - r.append(y) - - conn.commit() - conn.close() - return r - - -def get_one_ptt(song_id, difficulty, score: int) -> float: - # 单曲ptt计算 - conn = sqlite3.connect('./database/arcsong.db') - c = conn.cursor() - if difficulty == 0: - c.execute('''select rating_pst from songs where sid = :sid;''', { - 'sid': song_id}) - elif difficulty == 1: - c.execute('''select rating_prs from songs where sid = :sid;''', { - 'sid': song_id}) - elif difficulty == 2: - c.execute('''select rating_ftr from songs where sid = :sid;''', { - 'sid': song_id}) - elif difficulty == 3: - c.execute('''select rating_byn from songs where sid = :sid;''', { - 'sid': song_id}) - - x = c.fetchone() - defnum = 10.0 # 没在库里的全部当做定数10.0,不过要小心recent30表可能会被污染 - if x is not None and x != '': - defnum = float(x[0]) / 10 - if defnum <= 0: - defnum = 11.0 # 缺少难度的当做定数11.0 - - if score >= 10000000: - ptt = defnum + 2 - elif score < 9800000: - ptt = defnum + (score-9500000) / 300000 - if ptt < 0: - ptt = 0 - else: - ptt = defnum + 1 + (score-9800000) / 200000 - - conn.commit() - conn.close() - return ptt - - -def get_song_grade(x): - # 成绩转换评级 - if x >= 9900000: # EX+ - return 6 - elif x < 9900000 and x >= 9800000: # EX - return 5 - elif x < 9800000 and x >= 9500000: # AA - return 4 - elif x < 9500000 and x >= 9200000: # A - return 3 - elif x < 9200000 and x >= 8900000: # B - return 2 - elif x < 8900000 and x >= 8600000: # C - return 1 - else: - return 0 - - -def get_song_state(x): - # 返回成绩状态,便于比较 - if x == 3: # PM - return 5 - elif x == 2: # FC - return 4 - elif x == 5: # Hard Clear - return 3 - elif x == 1: # Clear - return 2 - elif x == 4: # Easy Clear - return 1 - else: # Track Lost - return 0 - - -def update_recent30(c, user_id, song_id, rating): - # 刷新r30,这里的判断方法存疑 - c.execute('''select * from recent30 where user_id = :a''', {'a': user_id}) - x = c.fetchone() - songs = [] - flag = True - for i in range(2, 61, 2): - if x[i] is None or x[i] == '': - r30_id = 29 - flag = False - break - if x[i] not in songs: - songs.append(x[i]) - if flag: - n = len(song_id) - if n >= 11: - r30_id = 29 - elif song_id not in songs and n == 10: - r30_id = 29 - elif song_id in songs and n == 10: - i = 29 - while x[i*2+2] == song_id: - i -= 1 - r30_id = i - elif song_id not in songs and n == 9: - i = 29 - while x[i*2+2] == song_id: - i -= 1 - r30_id = i - else: - r30_id = 29 - a = [] - b = [] - for i in range(1, 61, 2): - a.append(x[i]) - b.append(x[i+1]) - for i in range(r30_id, 0, -1): - a[i] = a[i-1] - b[i] = b[i-1] - a[0] = rating - b[0] = song_id - c.execute('''delete from recent30 where user_id = :a''', {'a': user_id}) - sql = 'insert into recent30 values(' + str(user_id) - for i in range(0, 30): - if a[i] is not None and b[i] is not None: - sql = sql + ',' + str(a[i]) + ',"' + b[i] + '"' - else: - sql = sql + ',0,""' - - sql = sql + ')' - c.execute(sql) - return None - - -def get_user_ptt(c, user_id) -> int: - # 总ptt计算 - sumr = 0 - c.execute('''select rating from best_score where user_id = :a order by rating DESC limit 30''', { - 'a': user_id}) - x = c.fetchall() - if x != []: - n = len(x) - for i in x: - sumr += float(i[0]) - c.execute('''select * from recent30 where user_id = :a''', {'a': user_id}) - x = c.fetchone() - if x is not None: - r30 = [] - s30 = [] - for i in range(1, 61, 2): - if x[i] is not None: - r30.append(float(x[i])) - s30.append(x[i+1]) - else: - r30.append(0) - s30.append('') - r30, s30 = (list(t) for t in zip(*sorted(zip(r30, s30), reverse=True))) - songs = [] - i = 0 - while len(songs) < 10 and i <= 29 and s30[i] != '' and s30[i] is not None: - if s30[i] not in songs: - sumr += r30[i] - songs.append(s30[i]) - i += 1 - - return int(sumr/40*100) - - -def arc_score_post(user_id, song_id, difficulty, score, shiny_perfect_count, perfect_count, near_count, miss_count, health, modifier, beyond_gauge, clear_type): - # 分数上传,返回变化后的ptt - # beyond_gauge是个什么呀?不管了,扔了 - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - rating = get_one_ptt(song_id, difficulty, score) - now = int(time.time() * 1000) - # recent 更新 - c.execute('''update user set song_id = :b, difficulty = :c, score = :d, shiny_perfect_count = :e, perfect_count = :f, near_count = :g, miss_count = :h, health = :i, modifier = :j, clear_type = :k, rating = :l, time_played = :m where user_id = :a''', { - 'a': user_id, 'b': song_id, 'c': difficulty, 'd': score, 'e': shiny_perfect_count, 'f': perfect_count, 'g': near_count, 'h': miss_count, 'i': health, 'j': modifier, 'k': clear_type, 'l': rating, 'm': now}) - # recent30 更新 - update_recent30(c, user_id, song_id, rating) - # 成绩录入 - c.execute('''select score, best_clear_type from best_score where user_id = :a and song_id = :b and difficulty = :c''', { - 'a': user_id, 'b': song_id, 'c': difficulty}) - x = c.fetchone() - if x is None: - c.execute('''insert into best_score values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n)''', { - 'a': user_id, 'b': song_id, 'c': difficulty, 'd': score, 'e': shiny_perfect_count, 'f': perfect_count, 'g': near_count, 'h': miss_count, 'i': health, 'j': modifier, 'k': now, 'l': clear_type, 'm': clear_type, 'n': rating}) - else: - if get_song_state(clear_type) > get_song_state(int(x[1])): # 状态更新 - c.execute('''update best_score set best_clear_type = :a where user_id = :b and song_id = :c and difficulty = :d''', { - 'a': clear_type, 'b': user_id, 'c': song_id, 'd': difficulty}) - if score >= int(x[0]): # 成绩更新 - c.execute('''update best_score set score = :d, shiny_perfect_count = :e, perfect_count = :f, near_count = :g, miss_count = :h, health = :i, modifier = :j, clear_type = :k, rating = :l, time_played = :m where user_id = :a and song_id = :b and difficulty = :c ''', { - 'a': user_id, 'b': song_id, 'c': difficulty, 'd': score, 'e': shiny_perfect_count, 'f': perfect_count, 'g': near_count, 'h': miss_count, 'i': health, 'j': modifier, 'k': clear_type, 'l': rating, 'm': now}) - # 总PTT更新 - ptt = get_user_ptt(c, user_id) - c.execute('''update user set rating_ptt = :a where user_id = :b''', { - 'a': ptt, 'b': user_id}) - conn.commit() - conn.close() - return ptt - - -def arc_all_post(user_id, scores_data, clearlamps_data): - # 向云端同步,无返回 - # 注意,best_score表不比较,直接覆盖 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - scores = json.loads(scores_data)[""] - clearlamps = json.loads(clearlamps_data)[""] - clear_song_id_difficulty = [] - clear_state = [] - for i in clearlamps: - clear_song_id_difficulty.append(i['song_id']+str(i['difficulty'])) - clear_state.append(i['clear_type']) - - for i in scores: - rating = get_one_ptt(i['song_id'], i['difficulty'], i['score']) - try: - index = clear_song_id_difficulty.index( - i['song_id'] + str(i['difficulty'])) - except: - index = -1 - if index != -1: - clear_type = clear_state[index] - else: - clear_type = 0 - c.execute('''delete from best_score where user_id = :a and song_id = :b and difficulty = :c''', { - 'a': user_id, 'b': i['song_id'], 'c': i['difficulty']}) - c.execute('''insert into best_score values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n)''', { - 'a': user_id, 'b': i['song_id'], 'c': i['difficulty'], 'd': i['score'], 'e': i['shiny_perfect_count'], 'f': i['perfect_count'], 'g': i['near_count'], 'h': i['miss_count'], 'i': i['health'], 'j': i['modifier'], 'k': i['time_played'], 'l': clear_type, 'm': clear_type, 'n': rating}) - - ptt = get_user_ptt(c, user_id) # 更新PTT - c.execute('''update user set rating_ptt = :a where user_id = :b''', {'a': ptt, 'b': user_id}) - conn.commit() - conn.close() - return None - - -def arc_all_get(user_id): - # 从云端同步,返回字典 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select * from best_score where user_id = :a''', - {'a': user_id}) - x = c.fetchall() - song_1 = [] - song_2 = [] - song_3 = [] - if x != []: - for i in x: - if i[11] != 0: - song_1.append({ - "grade": get_song_grade(i[3]), - "difficulty": i[2], - "song_id": i[1] - }) - song_2.append({ - "ct": 0, - "clear_type": i[11], - "difficulty": i[2], - "song_id": i[1] - }) - song_3.append({ - "ct": 0, - "time_played": i[10], - "modifier": i[9], - "health": i[8], - "miss_count": i[7], - "near_count": i[6], - "perfect_count": i[5], - "shiny_perfect_count": i[4], - "score": i[3], - "difficulty": i[2], - "version": 1, - "song_id": i[1] - }) - - conn.commit() - conn.close() - return { - "user_id": user_id, - "story": { - "": [{ - "r": True, - "c": True, - "mi": 1, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 7, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 8, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 9, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 7, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 8, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 9, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 100 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 100 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 100 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 100 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 100 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 7, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 8, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 7, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 8, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 6 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 6 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 6 - }] - }, - "devicemodelname": { - "val": "MopeMope" - }, - "installid": { - "val": "b5e064cf-1a3f-4e64-9636-fce4accc9011" - }, - "unlocklist": { - "": [{ - "complete": 1, - "unlock_key": "worldvanquisher|2|0" - }, { - "complete": 1, - "unlock_key": "worldvanquisher|1|0" - }, { - "complete": 1, - "unlock_key": "worldexecuteme|2|0" - }, { - "complete": 1, - "unlock_key": "viciousheroism|2|0" - }, { - "complete": 1, - "unlock_key": "vector|2|0" - }, { - "complete": 1, - "unlock_key": "valhallazero|2|0" - }, { - "complete": 1, - "unlock_key": "tiferet|1|0" - }, { - "complete": 1, - "unlock_key": "tiemedowngently|1|0" - }, { - "complete": 1, - "unlock_key": "tempestissimo|0|101" - }, { - "complete": 1, - "unlock_key": "syro|2|0" - }, { - "complete": 1, - "unlock_key": "suomi|1|0" - }, { - "complete": 1, - "unlock_key": "solitarydream|2|0" - }, { - "complete": 1, - "unlock_key": "snowwhite|2|0" - }, { - "complete": 1, - "unlock_key": "sheriruth|2|0" - }, { - "complete": 1, - "unlock_key": "senkyou|2|0" - }, { - "complete": 1, - "unlock_key": "senkyou|1|0" - }, { - "complete": 1, - "unlock_key": "scarletlance|2|0" - }, { - "complete": 1, - "unlock_key": "scarletlance|1|0" - }, { - "complete": 1, - "unlock_key": "rugie|2|0" - }, { - "complete": 1, - "unlock_key": "rugie|1|0" - }, { - "complete": 1, - "unlock_key": "rise|2|0" - }, { - "complete": 1, - "unlock_key": "revixy|2|0" - }, { - "complete": 1, - "unlock_key": "reinvent|2|0" - }, { - "complete": 1, - "unlock_key": "reinvent|1|0" - }, { - "complete": 1, - "unlock_key": "redandblue|2|0" - }, { - "complete": 1, - "unlock_key": "redandblue|1|0" - }, { - "complete": 1, - "unlock_key": "rabbitintheblackroom|2|0" - }, { - "complete": 1, - "unlock_key": "rabbitintheblackroom|1|0" - }, { - "complete": 1, - "unlock_key": "worldexecuteme|1|0" - }, { - "complete": 1, - "unlock_key": "ringedgenesis|2|0" - }, { - "complete": 1, - "unlock_key": "quon|1|0" - }, { - "complete": 1, - "unlock_key": "qualia|2|0" - }, { - "complete": 1, - "unlock_key": "purgatorium|2|0" - }, { - "complete": 1, - "unlock_key": "supernova|2|0" - }, { - "complete": 1, - "unlock_key": "saikyostronger|2|3|einherjar|2" - }, { - "complete": 1, - "unlock_key": "purgatorium|1|0" - }, { - "complete": 1, - "unlock_key": "pragmatism|2|0" - }, { - "complete": 1, - "unlock_key": "ouroboros|2|0" - }, { - "complete": 1, - "unlock_key": "ouroboros|1|0" - }, { - "complete": 1, - "unlock_key": "oracle|1|0" - }, { - "complete": 1, - "unlock_key": "onelastdrive|2|0" - }, { - "complete": 1, - "unlock_key": "onelastdrive|1|0" - }, { - "complete": 1, - "unlock_key": "oblivia|2|0" - }, { - "complete": 1, - "unlock_key": "memoryforest|1|0" - }, { - "complete": 1, - "unlock_key": "melodyoflove|2|0" - }, { - "complete": 1, - "unlock_key": "saikyostronger|2|3|laqryma|2" - }, { - "complete": 1, - "unlock_key": "melodyoflove|1|0" - }, { - "complete": 1, - "unlock_key": "lucifer|2|0" - }, { - "complete": 1, - "unlock_key": "saikyostronger|2|3|izana|2" - }, { - "complete": 1, - "unlock_key": "halcyon|1|0" - }, { - "complete": 1, - "unlock_key": "memoryforest|2|0" - }, { - "complete": 1, - "unlock_key": "tiemedowngently|2|0" - }, { - "complete": 1, - "unlock_key": "lostdesire|1|0" - }, { - "complete": 1, - "unlock_key": "viciousheroism|1|0" - }, { - "complete": 1, - "unlock_key": "flyburg|1|0" - }, { - "complete": 1, - "unlock_key": "lostcivilization|2|0" - }, { - "complete": 1, - "unlock_key": "infinityheaven|1|0" - }, { - "complete": 1, - "unlock_key": "lostdesire|2|0" - }, { - "complete": 1, - "unlock_key": "ignotus|2|0" - }, { - "complete": 1, - "unlock_key": "harutopia|2|0" - }, { - "complete": 1, - "unlock_key": "revixy|1|0" - }, { - "complete": 1, - "unlock_key": "aterlbus|1|0" - }, { - "complete": 1, - "unlock_key": "linearaccelerator|2|0" - }, { - "complete": 1, - "unlock_key": "guardina|2|0" - }, { - "complete": 1, - "unlock_key": "corpssansorganes|2|0" - }, { - "complete": 1, - "unlock_key": "linearaccelerator|1|0" - }, { - "complete": 1, - "unlock_key": "guardina|1|0" - }, { - "complete": 1, - "unlock_key": "saikyostronger|2|0" - }, { - "complete": 1, - "unlock_key": "guardina|0|0" - }, { - "complete": 1, - "unlock_key": "valhallazero|1|0" - }, { - "complete": 1, - "unlock_key": "grimheart|1|0" - }, { - "complete": 1, - "unlock_key": "blaster|2|0" - }, { - "complete": 1, - "unlock_key": "grievouslady|2|101" - }, { - "complete": 1, - "unlock_key": "partyvinyl|2|0" - }, { - "complete": 1, - "unlock_key": "darakunosono|1|0" - }, { - "complete": 1, - "unlock_key": "grievouslady|1|101" - }, { - "complete": 1, - "unlock_key": "goodtek|1|0" - }, { - "complete": 1, - "unlock_key": "tempestissimo|3|101" - }, { - "complete": 1, - "unlock_key": "chronostasis|2|0" - }, { - "complete": 1, - "unlock_key": "gloryroad|2|0" - }, { - "complete": 1, - "unlock_key": "supernova|1|0" - }, { - "complete": 1, - "unlock_key": "singularity|2|0" - }, { - "complete": 1, - "unlock_key": "gloryroad|0|0" - }, { - "complete": 1, - "unlock_key": "shadesoflight|1|0" - }, { - "complete": 1, - "unlock_key": "kanagawa|2|0" - }, { - "complete": 1, - "unlock_key": "genesis|1|0" - }, { - "complete": 1, - "unlock_key": "fractureray|1|101" - }, { - "complete": 1, - "unlock_key": "freefall|2|0" - }, { - "complete": 1, - "unlock_key": "babaroque|1|0" - }, { - "complete": 1, - "unlock_key": "monochromeprincess|2|0" - }, { - "complete": 1, - "unlock_key": "flyburg|2|0" - }, { - "complete": 1, - "unlock_key": "shadesoflight|2|0" - }, { - "complete": 1, - "unlock_key": "espebranch|2|0" - }, { - "complete": 1, - "unlock_key": "qualia|1|0" - }, { - "complete": 1, - "unlock_key": "etherstrike|2|0" - }, { - "complete": 1, - "unlock_key": "tempestissimo|1|101" - }, { - "complete": 1, - "unlock_key": "conflict|1|0" - }, { - "complete": 1, - "unlock_key": "nhelv|1|0" - }, { - "complete": 1, - "unlock_key": "etherstrike|1|0" - }, { - "complete": 1, - "unlock_key": "syro|1|0" - }, { - "complete": 1, - "unlock_key": "anokumene|2|0" - }, { - "complete": 1, - "unlock_key": "essenceoftwilight|2|0" - }, { - "complete": 1, - "unlock_key": "snowwhite|1|0" - }, { - "complete": 1, - "unlock_key": "partyvinyl|1|0" - }, { - "complete": 1, - "unlock_key": "axiumcrisis|1|0" - }, { - "complete": 1, - "unlock_key": "ifi|2|0" - }, { - "complete": 1, - "unlock_key": "espebranch|1|0" - }, { - "complete": 1, - "unlock_key": "lostcivilization|1|0" - }, { - "complete": 1, - "unlock_key": "goodtek|2|0" - }, { - "complete": 1, - "unlock_key": "dandelion|2|0" - }, { - "complete": 1, - "unlock_key": "suomi|2|0" - }, { - "complete": 1, - "unlock_key": "dandelion|1|0" - }, { - "complete": 1, - "unlock_key": "oblivia|1|0" - }, { - "complete": 1, - "unlock_key": "cyberneciacatharsis|1|0" - }, { - "complete": 1, - "unlock_key": "quon|2|0" - }, { - "complete": 1, - "unlock_key": "bookmaker|2|0" - }, { - "complete": 1, - "unlock_key": "chronostasis|1|0" - }, { - "complete": 1, - "unlock_key": "heavensdoor|1|0" - }, { - "complete": 1, - "unlock_key": "tempestissimo|2|101" - }, { - "complete": 1, - "unlock_key": "cyaegha|2|0" - }, { - "complete": 1, - "unlock_key": "axiumcrisis|2|0" - }, { - "complete": 1, - "unlock_key": "blrink|2|0" - }, { - "complete": 1, - "unlock_key": "rise|1|0" - }, { - "complete": 1, - "unlock_key": "cyanine|1|0" - }, { - "complete": 1, - "unlock_key": "ifi|1|0" - }, { - "complete": 1, - "unlock_key": "aterlbus|2|0" - }, { - "complete": 1, - "unlock_key": "dreaminattraction|2|0" - }, { - "complete": 1, - "unlock_key": "bookmaker|1|0" - }, { - "complete": 1, - "unlock_key": "lucifer|1|0" - }, { - "complete": 1, - "unlock_key": "solitarydream|1|0" - }, { - "complete": 1, - "unlock_key": "ringedgenesis|1|0" - }, { - "complete": 1, - "unlock_key": "corpssansorganes|1|0" - }, { - "complete": 1, - "unlock_key": "vector|1|0" - }, { - "complete": 1, - "unlock_key": "infinityheaven|2|0" - }, { - "complete": 1, - "unlock_key": "essenceoftwilight|1|0" - }, { - "complete": 1, - "unlock_key": "conflict|2|0" - }, { - "complete": 1, - "unlock_key": "singularity|1|0" - }, { - "complete": 1, - "unlock_key": "harutopia|1|0" - }, { - "complete": 1, - "unlock_key": "cyberneciacatharsis|2|0" - }, { - "complete": 1, - "unlock_key": "oracle|2|0" - }, { - "complete": 1, - "unlock_key": "clotho|2|0" - }, { - "complete": 1, - "unlock_key": "corpssansorganes|0|0" - }, { - "complete": 1, - "unlock_key": "ignotus|1|0" - }, { - "complete": 1, - "unlock_key": "monochromeprincess|1|0" - }, { - "complete": 1, - "unlock_key": "nirvluce|1|0" - }, { - "complete": 1, - "unlock_key": "lethaeus|1|0" - }, { - "complete": 1, - "unlock_key": "clotho|1|0" - }, { - "complete": 1, - "unlock_key": "blaster|1|0" - }, { - "complete": 1, - "unlock_key": "fractureray|0|101" - }, { - "complete": 1, - "unlock_key": "kanagawa|1|0" - }, { - "complete": 1, - "unlock_key": "darakunosono|2|0" - }, { - "complete": 1, - "unlock_key": "freefall|1|0" - }, { - "complete": 1, - "unlock_key": "nirvluce|2|0" - }, { - "complete": 1, - "unlock_key": "cyanine|2|0" - }, { - "complete": 1, - "unlock_key": "heavensdoor|2|0" - }, { - "complete": 1, - "unlock_key": "genesis|2|0" - }, { - "complete": 1, - "unlock_key": "pragmatism|1|0" - }, { - "complete": 1, - "unlock_key": "nhelv|2|0" - }, { - "complete": 1, - "unlock_key": "halcyon|2|0" - }, { - "complete": 1, - "unlock_key": "blrink|1|0" - }, { - "complete": 1, - "unlock_key": "fractureray|2|101" - }, { - "complete": 1, - "unlock_key": "lethaeus|2|0" - }, { - "complete": 1, - "unlock_key": "sheriruth|1|0" - }, { - "complete": 1, - "unlock_key": "babaroque|2|0" - }, { - "complete": 1, - "unlock_key": "tiferet|2|0" - }, { - "complete": 1, - "unlock_key": "grimheart|2|0" - }, { - "complete": 1, - "unlock_key": "cyaegha|1|0" - }, { - "complete": 1, - "unlock_key": "aiueoon|2|0" - }, { - "complete": 1, - "unlock_key": "gloryroad|1|0" - }, { - "complete": 1, - "unlock_key": "anokumene|1|0" - }, { - "complete": 1, - "unlock_key": "grievouslady|0|101" - }, { - "complete": 1, - "unlock_key": "dreaminattraction|1|0" - }] - }, "clearedsongs": { - "": song_1 - }, - "clearlamps": { - "": song_2 - }, - "scores": { - "": song_3 - }, - "version": { - "val": 1 - } - } diff --git a/v1.1/auth.py b/v1.1/auth.py deleted file mode 100644 index e438a69..0000000 --- a/v1.1/auth.py +++ /dev/null @@ -1,141 +0,0 @@ -import sqlite3 -import hashlib -import time - - -def arc_login(name: str, password: str) -> str: # 登录判断 - # 查询数据库中的user表,验证账号密码,返回并记录token - # token采用user_id和时间戳连接后hash生成(真的是瞎想的,没用bear) - # 密码和token的加密方式为 SHA-256 - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest() - c.execute('''select user_id from user where name = :name and password = :password''', { - 'name': name, 'password': hash_pwd}) - x = c.fetchone() - if x is not None: - user_id = str(x[0]) - now = int(time.time() * 1000) - token = hashlib.sha256((user_id + str(now)).encode("utf8")).hexdigest() - c.execute( - '''select exists(select * from login where user_id = :user_id)''', {"user_id": user_id}) - - if c.fetchone() == (1,): # 删掉多余token - c.execute('''delete from login where user_id = :user_id''', - {'user_id': user_id}) - - c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', { - 'user_id': user_id, 'access_token': token}) - conn.commit() - conn.close() - return token - - conn.commit() - conn.close() - return None - - -def arc_register(name: str, password: str): # 注册 - # 账号注册,只记录hash密码和用户名,生成user_id和user_code,自动登录返回token - # token和密码的处理同登录部分 - - def build_user_code(c): - # 生成9位的user_code,用的自然是随机 - import random - flag = True - while flag: - user_code = ''.join([str(random.randint(0, 9)) for i in range(9)]) - c.execute('''select exists(select * from user where user_code = :user_code)''', - {'user_code': user_code}) - if c.fetchone() == (0,): - flag = False - return user_code - - def build_user_id(c): - # 生成user_id,往后加1 - c.execute('''select max(user_id) from user''') - x = c.fetchone() - if x[0] is not None: - return x[0] + 1 - else: - return 2000001 - - def insert_user_char(c, user_id): - # 为用户添加所有可用角色 - for i in range(0, 38): - if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]: - sql = 'insert into user_char values('+str(user_id)+','+str( - i)+''',30,25000,25000,90,90,90,'',0,0,'',0,1,1)''' - c.execute(sql) - else: - if i != 5: - sql = 'insert into user_char values('+str(user_id)+','+str( - i)+''',30,25000,25000,90,90,90,'',0,0,'',0,0,0)''' - c.execute(sql) - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest() - c.execute( - '''select exists(select * from user where name = :name)''', {'name': name}) - if c.fetchone() == (0,): - user_code = build_user_code(c) - user_id = build_user_id(c) - now = int(time.time() * 1000) - c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt, - character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled) - values(:user_id, :name, :password, :join_date, :user_code, 0, 0, 0, 0, 0, 0, -1, 0) - ''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd}) - c.execute('''insert into recent30(user_id) values(:user_id)''', { - 'user_id': user_id}) - - token = hashlib.sha256( - (str(user_id) + str(now)).encode("utf8")).hexdigest() - c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', { - 'user_id': user_id, 'access_token': token}) - - insert_user_char(c, user_id) - conn.commit() - conn.close() - return user_id, token, 0 - else: - conn.commit() - conn.close() - return None, None, 101 - - -def token_get_id(token: str): - # 用token获取id,没有考虑不同用户token相同情况,说不定会有bug - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select user_id from login where access_token = :token''', { - 'token': token}) - x = c.fetchone() - if x is not None: - conn.commit() - conn.close() - return x[0] - else: - conn.commit() - conn.close() - return None - - -def code_get_id(user_code): - # 用user_code获取id - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select user_id from user where user_code = :a''', - {'a': user_code}) - x = c.fetchone() - if x is not None: - conn.commit() - conn.close() - return x[0] - else: - conn.commit() - conn.close() - return None diff --git a/v1.1/database/arcaea_database.db b/v1.1/database/arcaea_database.db deleted file mode 100644 index 08dca13..0000000 Binary files a/v1.1/database/arcaea_database.db and /dev/null differ diff --git a/v1.1/database/arcsong.db b/v1.1/database/arcsong.db deleted file mode 100644 index 3cdde3a..0000000 Binary files a/v1.1/database/arcsong.db and /dev/null differ diff --git a/v1.1/database/database_initialize.py b/v1.1/database/database_initialize.py deleted file mode 100644 index d7ac2e7..0000000 --- a/v1.1/database/database_initialize.py +++ /dev/null @@ -1,204 +0,0 @@ -import sqlite3 -import hashlib -import time -# 数据库初始化文件,删掉arcaea_database.db文件后运行即可,谨慎使用 - -conn = sqlite3.connect('arcaea_database.db') -c = conn.cursor() -c.execute('''create table if not exists user(user_id int primary key, -name text unique, -password text not null, -join_date char(20), -user_code char(10), -rating_ptt int, -character_id int, -is_skill_sealed int, -is_char_uncapped int, -is_char_uncapped_override int, -is_hide_rating int, -song_id text, -difficulty int, -score int, -shiny_perfect_count int, -perfect_count int, -near_count int, -miss_count int, -health int, -modifier int, -time_played int, -clear_type int, -rating real, -favorite_character int, -max_stamina_notification_enabled int -);''') -c.execute('''create table if not exists login(access_token text, -user_id int, -last_login_time int, -last_login_ip text, -last_login_device text -);''') -c.execute('''create table if not exists friend(user_id_me int, -user_id_other int, -primary key (user_id_me, user_id_other) -);''') -c.execute('''create table if not exists best_score(user_id int, -song_id text, -difficulty int, -score int, -shiny_perfect_count int, -perfect_count int, -near_count int, -miss_count int, -health int, -modifier int, -time_played int, -best_clear_type int, -clear_type int, -rating real, -primary key(user_id, song_id, difficulty) -);''') -c.execute('''create table if not exists user_char(user_id int, -character_id int, -level int, -exp real, -level_exp real, -frag int, -prog int, -overdrive int, -skill_id text, -skill_unlock_level int, -skill_requires_uncap int, -skill_id_uncap text, -char_type int, -is_uncapped int, -is_uncapped_override int, -primary key(user_id, character_id) -);''') -c.execute('''create table if not exists character(character_id int primary key, -name text -);''') -c.execute('''create table if not exists recent30(user_id int primary key, -r0 real, -song_id0 text, -r1 real, -song_id1 text, -r2 real, -song_id2 text, -r3 real, -song_id3 text, -r4 real, -song_id4 text, -r5 real, -song_id5 text, -r6 real, -song_id6 text, -r7 real, -song_id7 text, -r8 real, -song_id8 text, -r9 real, -song_id9 text, -r10 real, -song_id10 text, -r11 real, -song_id11 text, -r12 real, -song_id12 text, -r13 real, -song_id13 text, -r14 real, -song_id14 text, -r15 real, -song_id15 text, -r16 real, -song_id16 text, -r17 real, -song_id17 text, -r18 real, -song_id18 text, -r19 real, -song_id19 text, -r20 real, -song_id20 text, -r21 real, -song_id21 text, -r22 real, -song_id22 text, -r23 real, -song_id23 text, -r24 real, -song_id24 text, -r25 real, -song_id25 text, -r26 real, -song_id26 text, -r27 real, -song_id27 text, -r28 real, -song_id28 text, -r29 real, -song_id29 text -);''') - -char = ['Hikari','Tairitsu','Kou','Sapphire','Lethe','','Tairitsu(Axium)' -,'Tairitsu(Grievous Lady)','Stella','Hikari & Fisica','Ilith','Eto','Luna' -,'Shirabe','Hikari(Zero)','Hikari(Fracture)','Hikari(Summer)','Tairitsu(Summer)' -,'Tairitsu&Trin','Ayu','Eto&Luna','Yume','Seine & Hikari','Saya','Tairitsu & Chuni Penguin' -,'Chuni Penguin','Haruna','Nono','MTA-XXX','MDA-21','Kanae','Hikari(Fantasia)','Tairitsu(Sonata)','Sia','DORO*C' -,'Tairitsu(Tempest)','Brillante','Ilith(Summer)'] - -for i in range(0, 38): - c.execute("insert into character values("+str(i)+",'"+char[i]+"');") - - -conn.commit() -conn.close() - - - -def arc_register(name: str, password: str): - def build_user_code(c): - return '123456789' - - def build_user_id(c): - return 2000000 - - def insert_user_char(c, user_id): - for i in range(0, 38): - if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]: - sql = 'insert into user_char values('+str(user_id)+','+str( - i)+''',30,25000,25000,90,90,90,'',0,0,'',0,1,1)''' - c.execute(sql) - else: - if i != 5: - sql = 'insert into user_char values('+str(user_id)+','+str( - i)+''',30,25000,25000,90,90,90,'',0,0,'',0,0,0)''' - c.execute(sql) - - conn = sqlite3.connect('arcaea_database.db') - c = conn.cursor() - hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest() - c.execute( - '''select exists(select * from user where name = :name)''', {'name': name}) - if c.fetchone() == (0,): - user_code = build_user_code(c) - user_id = build_user_id(c) - now = int(time.time() * 1000) - c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt, - character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled) - values(:user_id, :name, :password, :join_date, :user_code, 1250, 1, 0, 1, 0, 0, -1, 0) - ''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd}) - c.execute('''insert into recent30(user_id) values(:user_id)''', { - 'user_id': user_id}) - c.execute('''insert into best_score values(2000000,'vexaria',3,10000000,100,0,0,0,100,0,1599667200000,3,3,10.8)''') - insert_user_char(c, user_id) - conn.commit() - conn.close() - return None - else: - conn.commit() - conn.close() - return None - - -arc_register('admin', 'admin123') diff --git a/v1.1/info.py b/v1.1/info.py deleted file mode 100644 index 72958f6..0000000 --- a/v1.1/info.py +++ /dev/null @@ -1,4060 +0,0 @@ -import sqlite3 - - -def int2b(x): - # int与布尔值转换 - if x is None or x == 0: - return False - else: - return True - - -def get_recent_score(c, user_id): - # 得到用户最近一次的成绩,返回列表 - c.execute('''select * from user where user_id = :x''', {'x': user_id}) - x = c.fetchone() - if x is not None: - if x[11] is not None: - c.execute('''select best_clear_type from best_score where user_id=:u and song_id=:s and difficulty=:d''', { - 'u': user_id, 's': x[11], 'd': x[12]}) - y = c.fetchone() - if y is not None: - best_clear_type = y[0] - else: - best_clear_type = x[21] - - return [{ - "rating": x[22], - "modifier": x[19], - "time_played": x[20], - "health": x[18], - "best_clear_type": best_clear_type, - "clear_type": x[21], - "miss_count": x[17], - "near_count": x[16], - "perfect_count": x[15], - "shiny_perfect_count": x[14], - "score": x[13], - "difficulty": x[12], - "song_id": x[11] - }] - return [] - - -def get_user_character(c, user_id): - # 得到用户拥有的角色列表,返回列表 - c.execute('''select * from user_char where user_id = :user_id''', - {'user_id': user_id}) - x = c.fetchall() - if x != []: - s = [] - for i in x: - char_name = '' - c.execute( - '''select name from character where character_id = :x''', {'x': i[1]}) - y = c.fetchone() - if y is not None: - char_name = y[0] - s.append({ - "is_uncapped_override": int2b(i[14]), - "is_uncapped": int2b(i[13]), - "uncap_cores": [], - "char_type": i[12], - "skill_id_uncap": i[11], - "skill_requires_uncap": int2b(i[10]), - "skill_unlock_level": i[9], - "skill_id": i[8], - "overdrive": i[7], - "prog": i[6], - "frag": i[5], - "level_exp": i[4], - "exp": i[3], - "level": i[2], - "name": char_name, - "character_id": i[1] - }) - - return s - else: - return [] - - -def get_user_friend(c, user_id): - # 得到用户的朋友列表,返回列表 - c.execute('''select user_id_other from friend where user_id_me = :user_id''', { - 'user_id': user_id}) - x = c.fetchall() - s = [] - if x != [] and x[0][0] is not None: - - for i in x: - c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''', - {'x': i[0], 'y': user_id}) - if c.fetchone() == (1,): - is_mutual = True - else: - is_mutual = False - - c.execute('''select * from user where user_id = :x''', {'x': i[0]}) - y=c.fetchone() - if y is not None: - s.append({ - "is_mutual": is_mutual, - "is_char_uncapped_override": int2b(y[9]), - "is_char_uncapped": int2b(y[8]), - "is_skill_sealed": int2b(y[7]), - "rating": y[5], - "join_date": int(y[3]), - "character": y[6], - "recent_score": get_recent_score(c, i[0]), - "name": y[1], - "user_id": i[0] - }) - - return s - - -def get_value_0(c, user_id): - # 构造value id=0的数据,返回字典 - c.execute('''select * from user where user_id = :x''', {'x': user_id}) - x = c.fetchone() - r = {} - if x is not None: - r = {"is_aprilfools": False, - "curr_available_maps": [], - "character_stats": get_user_character(c, user_id), - "friends": get_user_friend(c, user_id), - "settings": { - "favorite_character": x[23], - "is_hide_rating": int2b(x[10]), - "max_stamina_notification_enabled": int2b(x[24]) - }, - "user_id": user_id, - "name": x[1], - "user_code": x[4], - "display_name": x[1], - "ticket": 114514, - "character": x[6], - "is_locked_name_duplicate": False, - "is_skill_sealed": int2b(x[7]), - "current_map": "", - "prog_boost": 0, - "next_fragstam_ts": -1, - "max_stamina_ts": 1586274871917, - "stamina": 0, - "world_unlocks": [], - "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"], - "singles": [], - "packs": [], - "characters":[0,1,2,3,4]+[x for x in range(6, 38)], - "cores": [], - "recent_score": get_recent_score(c, user_id), - "max_friend": 50, - "rating": x[5], - "join_date": int(x[3]) - } - - return r - - -def arc_aggregate_small(user_id): - # 返回用户数据 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - r = {"success": True, - "value": [{ - "id": 0, - "value": get_value_0(c, user_id) - }]} - - conn.commit() - conn.close() - return r - - -def arc_aggregate_big(user_id): - # 返回用户数据和地图歌曲信息 - # 因为没有整理地图和曲包数据(不需要世界模式),所以直接复制了 - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - r = {"success": True, - "value": [{ - "id": 0, - "value": get_value_0(c, user_id) - }, { - "id": 1, - "value": [{ - "name": "core", - "items": [{ - "id": "core", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "shiawase", - "items": [{ - "id": "shiawase", - "type": "pack", - "is_available": True - }, { - "id": "kou", - "type": "character", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1552089600000, - "discount_to": 1552694399000 - }, { - "name": "dynamix", - "items": [{ - "id": "dynamix", - "type": "pack", - "is_available": True - }, { - "id": "sapphire", - "type": "character", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "mirai", - "items": [{ - "id": "mirai", - "type": "pack", - "is_available": True - }, { - "id": "lethe", - "type": "character", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1552089600000, - "discount_to": 1552694399000 - }, { - "name": "yugamu", - "items": [{ - "id": "yugamu", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "lanota", - "items": [{ - "id": "lanota", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "nijuusei", - "items": [{ - "id": "nijuusei", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "rei", - "items": [{ - "id": "rei", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "tonesphere", - "items": [{ - "id": "tonesphere", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "groovecoaster", - "items": [{ - "id": "groovecoaster", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "zettai", - "items": [{ - "id": "zettai", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "chunithm", - "items": [{ - "id": "chunithm", - "type": "pack", - "is_available": True - }], - "price": 300, - "orig_price": 300 - }, { - "name": "prelude", - "items": [{ - "id": "prelude", - "type": "pack", - "is_available": True - }], - "price": 400, - "orig_price": 400 - }, { - "name": "omatsuri", - "items": [{ - "id": "omatsuri", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500 - }, { - "name": "vs", - "items": [{ - "id": "vs", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500 - }, { - "name": "extend", - "items": [{ - "id": "extend", - "type": "pack", - "is_available": True - }], - "price": 700, - "orig_price": 700 - }] - }, { - "id": 2, - "value": {} - }, { - "id": 3, - "value": { - "max_stamina": 12, - "stamina_recover_tick": 1800000, - "core_exp": 250, - "curr_ts": 1599547606825, - "level_steps": [{ - "level": 1, - "level_exp": 0 - }, { - "level": 2, - "level_exp": 50 - }, { - "level": 3, - "level_exp": 100 - }, { - "level": 4, - "level_exp": 150 - }, { - "level": 5, - "level_exp": 200 - }, { - "level": 6, - "level_exp": 300 - }, { - "level": 7, - "level_exp": 450 - }, { - "level": 8, - "level_exp": 650 - }, { - "level": 9, - "level_exp": 900 - }, { - "level": 10, - "level_exp": 1200 - }, { - "level": 11, - "level_exp": 1600 - }, { - "level": 12, - "level_exp": 2100 - }, { - "level": 13, - "level_exp": 2700 - }, { - "level": 14, - "level_exp": 3400 - }, { - "level": 15, - "level_exp": 4200 - }, { - "level": 16, - "level_exp": 5100 - }, { - "level": 17, - "level_exp": 6100 - }, { - "level": 18, - "level_exp": 7200 - }, { - "level": 19, - "level_exp": 8500 - }, { - "level": 20, - "level_exp": 10000 - }, { - "level": 21, - "level_exp": 11500 - }, { - "level": 22, - "level_exp": 13000 - }, { - "level": 23, - "level_exp": 14500 - }, { - "level": 24, - "level_exp": 16000 - }, { - "level": 25, - "level_exp": 17500 - }, { - "level": 26, - "level_exp": 19000 - }, { - "level": 27, - "level_exp": 20500 - }, { - "level": 28, - "level_exp": 22000 - }, { - "level": 29, - "level_exp": 23500 - }, { - "level": 30, - "level_exp": 25000 - }], - "world_ranking_enabled": False, - "is_byd_chapter_unlocked": True - } - }, { - "id": 4, - "value": [] - }, { - "id": 5, - "value": { - "user_id": user_id, - "current_map": "", - "maps": [{ - "map_id": "hikari_art", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "", - "require_value": 1, - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "-270,150", - "step_count": 91, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "babaroque", - "type": "world_song" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 27 - }, { - "items": [{ - "id": "shadesoflight", - "type": "world_song" - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 45 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 50 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 55 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 60 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 65 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 70 - }, { - "items": [{ - "id": "kanagawa", - "type": "world_song" - }], - "position": 75 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 80 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 85 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 90 - }] - }, { - "map_id": "hikari_happy", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "270,150", - "step_count": 136, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 5 - }, { - "items": [{ - "id": "harutopia", - "type": "world_song" - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 25 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 30 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 32 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 45 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 50 - }, { - "items": [{ - "id": "goodtek", - "type": "world_song" - }], - "position": 55 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 60 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 65 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 70 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 75 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 80 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 82 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 85 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 90 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 95 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 97 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 100 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 105 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 110 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 115 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 120 - }, { - "items": [{ - "id": "dreaminattraction", - "type": "world_song" - }], - "position": 125 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 135 - }] - }, { - "map_id": "tairitsu_arcs", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "-270,-150", - "step_count": 136, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 5 - }, { - "items": [{ - "id": "rabbitintheblackroom", - "type": "world_song" - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 25 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 30 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 32 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 45 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 50 - }, { - "items": [{ - "id": "qualia", - "type": "world_song" - }], - "position": 55 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 60 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 65 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 70 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 75 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 80 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 82 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 85 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 90 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 95 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 97 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 100 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 105 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 110 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 115 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 120 - }, { - "items": [{ - "id": "redandblue", - "type": "world_song" - }], - "position": 125 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 135 - }] - }, { - "map_id": "tairitsu_tech", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "", - "require_value": 1, - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "270,-150", - "step_count": 91, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "lucifer", - "type": "world_song" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 27 - }, { - "items": [{ - "id": "anokumene", - "type": "world_song" - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 45 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 50 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 55 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 60 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 65 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 70 - }, { - "items": [{ - "id": "ignotus", - "type": "world_song" - }], - "position": 75 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 80 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 85 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 90 - }] - }, { - "map_id": "eternal", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "core", - "require_type": "pack", - "require_value": 1, - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "-500,0", - "step_count": 66, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 10 - }, { - "items": [{ - "id": "essenceoftwilight", - "type": "world_song" - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 28 - }, { - "items": [{ - "type": "fragment", - "amount": 200 - }], - "position": 35 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 42 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 44 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 46 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 48 - }, { - "items": [{ - "id": "pragmatism", - "type": "world_song" - }], - "position": 50 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 52 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 54 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 56 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 58 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 60 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 62 - }, { - "items": [{ - "id": "sheriruth", - "type": "world_song" - }], - "position": 65 - }] - }, { - "map_id": "axiumcrisis", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "yugamu", - "require_type": "pack", - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "500,0", - "step_count": 61, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 5 - }, { - "items": [{ - "id": "axiumcrisis", - "type": "world_song" - }], - "position": 10 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 24 - }, { - "items": [{ - "type": "fragment", - "amount": 200 - }], - "position": 30 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 37 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 39 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 41 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 43 - }, { - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 45 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 51 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 53 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 55 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 57 - }, { - "items": [{ - "id": "6", - "type": "character" - }], - "position": 60 - }] - }, { - "map_id": "grievouslady", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "yugamu", - "require_type": "pack", - "require_localunlock_songid": "grievouslady", - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "0,-150", - "step_count": 21, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 300 - }], - "position": 18 - }, { - "items": [{ - "id": "7", - "type": "character" - }], - "position": 20 - }] - }, { - "map_id": "lanota", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "lanota", - "require_type": "pack", - "coordinate": "460,-160", - "step_count": 35, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 40 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 10 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 12 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 80 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 27 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 33 - }, { - "items": [{ - "id": "9", - "type": "character" - }], - "position": 34 - }] - }, { - "map_id": "nijuusei_light", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "nijuusei", - "require_type": "pack", - "coordinate": "-260,160", - "step_count": 22, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 175 - }], - "position": 10 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 178 - }], - "position": 20 - }, { - "items": [{ - "id": "11", - "type": "character" - }], - "position": 21 - }] - }, { - "map_id": "nijuusei_conflict", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "nijuusei", - "require_type": "pack", - "require_localunlock_challengeid": "singularity", - "coordinate": "260,160", - "step_count": 36, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 175 - }], - "position": 2 - }, { - "items": [{ - "type": "fragment", - "amount": 175 - }], - "position": 3 - }, { - "items": [{ - "type": "fragment", - "amount": 175 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 178 - }], - "position": 5 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 6 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 7 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 8 - }, { - "items": [{ - "id": "12", - "type": "character" - }], - "position": 35 - }] - }, { - "map_id": "extra_originals", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "", - "require_value": 1, - "coordinate": "0,-200", - "step_count": 101, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 29 - }, { - "items": [{ - "id": "syro", - "type": "world_song" - }], - "position": 30 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 31 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 80 - }], - "position": 45 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 50 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 55 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 59 - }, { - "items": [{ - "id": "blaster", - "type": "world_song" - }], - "position": 60 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 61 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 65 - }, { - "items": [{ - "type": "fragment", - "amount": 80 - }], - "position": 70 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 75 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 80 - }, { - "items": [{ - "type": "fragment", - "amount": 80 - }], - "position": 85 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 90 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 94 - }, { - "items": [{ - "id": "cyberneciacatharsis", - "type": "world_song" - }], - "position": 95 - }, { - "items": [{ - "type": "core", - "id": "core_crimson", - "amount": 5 - }], - "position": 98 - }, { - "items": [{ - "type": "core", - "id": "core_crimson", - "amount": 5 - }], - "position": 100 - }] - }, { - "map_id": "guardina", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "dynamix", - "require_type": "pack", - "coordinate": "-460,-160", - "step_count": 35, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 1 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 9 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 16 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 17 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 18 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 25 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 33 - }, { - "items": [{ - "id": "guardina", - "type": "world_song" - }], - "position": 34 - }] - }, { - "map_id": "etherstrike", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "rei", - "require_type": "pack", - "coordinate": "0,-40", - "step_count": 36, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 5 - }, { - "items": [{ - "id": "etherstrike", - "type": "world_song" - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 26 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 27 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 28 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 29 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 31 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 32 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 33 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 34 - }, { - "items": [{ - "id": "14", - "type": "character" - }], - "position": 35 - }] - }, { - "map_id": "fractureray", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "rei", - "require_type": "pack", - "require_localunlock_songid": "fractureray", - "coordinate": "0,160", - "step_count": 23, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 13 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 16 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 17 - }, { - "items": [{ - "type": "fragment", - "amount": 350 - }], - "position": 19 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 20 - }, { - "items": [{ - "id": "15", - "type": "character" - }], - "position": 22 - }] - }, { - "map_id": "chapter3_light", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-480,180", - "step_count": 76, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 144 - }], - "position": 10 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 13 - }, { - "items": [{ - "type": "fragment", - "amount": 169 - }], - "position": 20 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 23 - }, { - "items": [{ - "id": "suomi", - "type": "world_song" - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 225 - }], - "position": 40 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 43 - }, { - "items": [{ - "type": "fragment", - "amount": 256 - }], - "position": 50 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 53 - }, { - "items": [{ - "id": "rugie", - "type": "world_song" - }], - "position": 59 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 65 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 70 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 75 - }] - }, { - "map_id": "chapter3_conflict", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-360,0", - "step_count": 85, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 10 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 19 - }, { - "items": [{ - "type": "fragment", - "amount": 15 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 25 - }, { - "items": [{ - "id": "bookmaker", - "type": "world_song" - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 200 - }], - "position": 35 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 39 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 45 - }, { - "items": [{ - "id": "darakunosono", - "type": "world_song" - }], - "position": 49 - }, { - "items": [{ - "type": "fragment", - "amount": 30 - }], - "position": 50 - }, { - "items": [{ - "type": "fragment", - "amount": 300 - }], - "position": 55 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 3 - }], - "position": 59 - }, { - "items": [{ - "type": "fragment", - "amount": 40 - }], - "position": 60 - }, { - "items": [{ - "id": "espebranch", - "type": "world_song" - }], - "position": 62 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 70 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 75 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 84 - }] - }, { - "map_id": "chapter3_conflict_2", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-240,-180", - "step_count": 51, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 125 - }], - "position": 9 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 125 - }], - "position": 19 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 24 - }, { - "items": [{ - "type": "fragment", - "amount": 125 - }], - "position": 29 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 34 - }, { - "items": [{ - "type": "fragment", - "amount": 125 - }], - "position": 39 - }, { - "items": [{ - "id": "nhelv", - "type": "world_song" - }], - "position": 40 - }, { - "items": [{ - "type": "core", - "id": "core_ambivalent", - "amount": 5 - }], - "position": 45 - }, { - "items": [{ - "type": "core", - "id": "core_ambivalent", - "amount": 5 - }], - "position": 50 - }] - }, { - "map_id": "tonesphere", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "tonesphere", - "require_type": "pack", - "coordinate": "480,180", - "step_count": 38, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 4 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 22 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 28 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 32 - }, { - "items": [{ - "id": "18", - "type": "character" - }], - "position": 37 - }] - }, { - "map_id": "groovecoaster", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "groovecoaster", - "require_type": "pack", - "coordinate": "360,0", - "step_count": 46, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 55 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 66 - }], - "position": 23 - }, { - "items": [{ - "type": "fragment", - "amount": 77 - }], - "position": 29 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 88 - }], - "position": 34 - }, { - "items": [{ - "type": "fragment", - "amount": 99 - }], - "position": 39 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 40 - }, { - "items": [{ - "id": "22", - "type": "character" - }], - "position": 45 - }] - }, { - "map_id": "solitarydream", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 5, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "core", - "require_type": "pack", - "coordinate": "-250,0", - "step_count": 10, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "solitarydream", - "type": "world_song" - }], - "position": 9 - }] - }, { - "map_id": "zettai", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "zettai", - "require_type": "pack", - "coordinate": "-100,115", - "step_count": 26, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 20 - }, { - "items": [{ - "id": "23", - "type": "character" - }], - "position": 25 - }] - }, { - "map_id": "chapter4_ripples", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-280,-200", - "step_count": 51, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 170 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 170 - }], - "position": 12 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 16 - }, { - "items": [{ - "id": "grimheart", - "type": "world_song" - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 190 - }], - "position": 26 - }, { - "items": [{ - "type": "fragment", - "amount": 190 - }], - "position": 42 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 46 - }, { - "items": [{ - "id": "vector", - "type": "world_song" - }], - "position": 50 - }] - }, { - "map_id": "chapter4_waves", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-480,-200", - "step_count": 41, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 5 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 8 - }, { - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 18 - }, { - "items": [{ - "id": "revixy", - "type": "world_song" - }], - "position": 25 - }, { - "items": [{ - "type": "fragment", - "amount": 400 - }], - "position": 30 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 33 - }, { - "items": [{ - "id": "supernova", - "type": "world_song" - }], - "position": 40 - }] - }, { - "map_id": "chunithm", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "chunithm", - "require_type": "pack", - "coordinate": "480,200", - "step_count": 28, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 110 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 120 - }], - "position": 10 - }, { - "items": [{ - "id": "worldvanquisher", - "type": "world_song" - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 20 - }, { - "items": [{ - "id": "24", - "type": "character" - }], - "position": 27 - }] - }, { - "map_id": "omatsuri", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "omatsuri", - "require_type": "pack", - "coordinate": "280,200", - "step_count": 21, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 230 - }], - "position": 3 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 6 - }, { - "items": [{ - "type": "fragment", - "amount": 230 - }], - "position": 9 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 12 - }, { - "items": [{ - "id": "30", - "type": "character" - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 20 - }] - }, { - "map_id": "chapter4_the_calm", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-380,-30", - "step_count": 146, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 10 - }], - "position": 1 - }, { - "items": [{ - "type": "fragment", - "amount": 10 - }], - "position": 2 - }, { - "items": [{ - "type": "fragment", - "amount": 10 - }], - "position": 3 - }, { - "items": [{ - "type": "fragment", - "amount": 10 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 15 - }], - "position": 11 - }, { - "items": [{ - "type": "fragment", - "amount": 15 - }], - "position": 12 - }, { - "items": [{ - "type": "fragment", - "amount": 15 - }], - "position": 13 - }, { - "items": [{ - "type": "fragment", - "amount": 15 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 20 - }], - "position": 21 - }, { - "items": [{ - "type": "fragment", - "amount": 20 - }], - "position": 22 - }, { - "items": [{ - "type": "fragment", - "amount": 20 - }], - "position": 23 - }, { - "items": [{ - "type": "fragment", - "amount": 20 - }], - "position": 24 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 31 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 32 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 33 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 34 - }, { - "items": [{ - "type": "fragment", - "amount": 30 - }], - "position": 41 - }, { - "items": [{ - "type": "fragment", - "amount": 30 - }], - "position": 42 - }, { - "items": [{ - "type": "fragment", - "amount": 30 - }], - "position": 43 - }, { - "items": [{ - "type": "fragment", - "amount": 30 - }], - "position": 44 - }, { - "items": [{ - "type": "fragment", - "amount": 35 - }], - "position": 51 - }, { - "items": [{ - "type": "fragment", - "amount": 35 - }], - "position": 52 - }, { - "items": [{ - "type": "fragment", - "amount": 35 - }], - "position": 53 - }, { - "items": [{ - "id": "diode", - "type": "world_song" - }], - "position": 54 - }, { - "items": [{ - "type": "fragment", - "amount": 40 - }], - "position": 62 - }, { - "items": [{ - "type": "fragment", - "amount": 40 - }], - "position": 64 - }, { - "items": [{ - "type": "fragment", - "amount": 45 - }], - "position": 72 - }, { - "items": [{ - "type": "fragment", - "amount": 45 - }], - "position": 74 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 82 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 84 - }, { - "items": [{ - "type": "fragment", - "amount": 55 - }], - "position": 92 - }, { - "items": [{ - "id": "freefall", - "type": "world_song" - }], - "position": 94 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 102 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 104 - }, { - "items": [{ - "type": "fragment", - "amount": 65 - }], - "position": 112 - }, { - "items": [{ - "type": "fragment", - "amount": 65 - }], - "position": 114 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 122 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 124 - }, { - "items": [{ - "type": "fragment", - "amount": 75 - }], - "position": 132 - }, { - "items": [{ - "id": "monochromeprincess", - "type": "world_song" - }], - "position": 134 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 3 - }], - "position": 145 - }] - }, { - "map_id": "gloryroad", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "shiawase", - "require_type": "pack", - "coordinate": "380,30", - "step_count": 28, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 1 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 11 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 14 - }, { - "items": [{ - "id": "gloryroad", - "type": "world_song" - }], - "position": 20 - }, { - "items": [{ - "type": "core", - "id": "core_crimson", - "amount": 5 - }], - "position": 23 - }, { - "items": [{ - "type": "core", - "id": "core_crimson", - "amount": 5 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_crimson", - "amount": 5 - }], - "position": 27 - }] - }, { - "map_id": "blrink", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 5, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "prelude", - "require_type": "pack", - "coordinate": "250,0", - "step_count": 17, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "blrink", - "type": "world_song" - }], - "position": 16 - }] - }, { - "map_id": "corpssansorganes", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "mirai", - "require_type": "pack", - "coordinate": "0,200", - "step_count": 42, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 105 - }], - "position": 6 - }, { - "items": [{ - "type": "fragment", - "amount": 105 - }], - "position": 12 - }, { - "items": [{ - "type": "fragment", - "amount": 105 - }], - "position": 22 - }, { - "items": [{ - "type": "fragment", - "amount": 105 - }], - "position": 28 - }, { - "items": [{ - "id": "corpssansorganes", - "type": "world_song" - }], - "position": 31 - }, { - "items": [{ - "type": "core", - "id": "core_ambivalent", - "amount": 5 - }], - "position": 35 - }, { - "items": [{ - "type": "core", - "id": "core_ambivalent", - "amount": 5 - }], - "position": 38 - }, { - "items": [{ - "type": "core", - "id": "core_ambivalent", - "amount": 5 - }], - "position": 41 - }] - }, { - "map_id": "lostdesire", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 5, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "vs", - "require_type": "pack", - "coordinate": "0,0", - "step_count": 36, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "lostdesire", - "type": "world_song" - }], - "position": 5 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 35 - }] - }, { - "map_id": "tempestissimo", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 5, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "vs", - "require_type": "pack", - "require_localunlock_challengeid": "tempestissimo", - "coordinate": "0,160", - "step_count": 16, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "35", - "type": "character" - }], - "position": 3 - }, { - "items": [{ - "type": "fragment", - "amount": 1000 - }], - "position": 15 - }] - }, { - "map_id": "chapter_1_scenery", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": True, - "require_id": "", - "require_type": "chapter_step", - "require_value": 455, - "coordinate": "0,150", - "step_count": 51, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "world_unlock", - "id": "scenery_chap1" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 80 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 25 - }, { - "items": [{ - "type": "fragment", - "amount": 110 - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 120 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 130 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 50 - }] - }, { - "map_id": "chapter_2_scenery", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": True, - "require_id": "", - "require_type": "chapter_step", - "require_value": 105, - "coordinate": "0,-20", - "step_count": 51, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "world_unlock", - "id": "scenery_chap2" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 11 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 12 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 13 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 31 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 32 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 33 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 34 - }, { - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 50 - }] - }, { - "map_id": "chapter_3_scenery", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": True, - "require_id": "", - "require_type": "chapter_step", - "require_value": 205, - "coordinate": "240,-180", - "step_count": 17, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "world_unlock", - "id": "scenery_chap3" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 400 - }], - "position": 16 - }] - }, { - "map_id": "chapter_4_scenery", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": True, - "require_id": "", - "require_type": "chapter_step", - "require_value": 240, - "coordinate": "100,-115", - "step_count": 101, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "world_unlock", - "id": "scenery_chap4" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 2000 - }], - "position": 100 - }] - }, { - "map_id": "chapter_5_scenery", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 5, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": True, - "require_id": "", - "require_type": "chapter_step", - "require_value": 75, - "coordinate": "0,-160", - "step_count": 31, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "world_unlock", - "id": "scenery_chap5" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 500 - }], - "position": 30 - }] - }, { - "map_id": "byd_goodtek", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "goodtek2", - "require_type": "chart_unlock", - "coordinate": "900,650", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 250, - "character_affinity": [0, 1], - "affinity_multiplier": [2.5, 1.5], - "step_count": 6, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 2 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 10 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 24 - }, { - "items": [{ - "type": "fragment", - "amount": 275 - }], - "position": 31 - }, { - "items": [{ - "id": "goodtek3", - "type": "world_song" - }], - "position": 33 - }] - }, { - "map_id": "byd_vexaria", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "vexaria2", - "require_type": "chart_unlock", - "coordinate": "650,400", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 150, - "character_affinity": [0, 1], - "affinity_multiplier": [2.5, 1.5], - "step_count": 3, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 616 - }], - "position": 42 - }, { - "items": [{ - "id": "vexaria3", - "type": "world_song" - }], - "position": 46 - }] - }, { - "map_id": "byd_fairytale", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "fairytale2", - "require_type": "chart_unlock", - "coordinate": "400,650", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 200, - "character_affinity": [0, 1], - "affinity_multiplier": [2.5, 1.5], - "step_count": 3, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 4 - }], - "position": 20 - }, { - "items": [{ - "id": "fairytale3", - "type": "world_song" - }], - "position": 55 - }] - }, { - "map_id": "byd_infinityheaven", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "infinityheaven2", - "require_type": "chart_unlock", - "coordinate": "650,900", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 200, - "character_affinity": [0, 1], - "affinity_multiplier": [2.5, 1.5], - "step_count": 9, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 1 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 2 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 3 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 6 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 7 - }, { - "items": [{ - "id": "infinityheaven3", - "type": "world_song" - }], - "position": 8 - }] - }, { - "map_id": "byd_purgatorium", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "purgatorium2", - "require_type": "chart_unlock", - "coordinate": "-900,-650", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 200, - "character_affinity": [13, 1], - "affinity_multiplier": [2.6, 1.6], - "step_count": 5, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 2 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 14 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 30 - }, { - "items": [{ - "id": "purgatorium3", - "type": "world_song" - }], - "position": 37 - }] - }, { - "map_id": "byd_dement", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "dement2", - "require_type": "chart_unlock", - "coordinate": "-400,-650", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 250, - "character_affinity": [13, 1], - "affinity_multiplier": [2.6, 1.6], - "step_count": 4, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 19 - }, { - "items": [{ - "type": "fragment", - "amount": 1200 - }], - "position": 39 - }, { - "items": [{ - "id": "dement3", - "type": "world_song" - }], - "position": 43 - }] - }, { - "map_id": "maliciousmischance_event", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 0, - "available_from": 1599177600000, - "available_to": 1599836400000, - "is_repeatable": False, - "require_id": "maliciousmischance", - "require_type": "single", - "coordinate": "0,0", - "step_count": 87, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 62 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 63 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 67 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 68 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 72 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 73 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 77 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 78 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 82 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 83 - }, { - "items": [{ - "id": "37", - "type": "character" - }], - "position": 86 - }] - }] - }} - ]} - - conn.commit() - conn.close() - return r diff --git a/v1.1/main.py b/v1.1/main.py deleted file mode 100644 index d5fe3e8..0000000 --- a/v1.1/main.py +++ /dev/null @@ -1,418 +0,0 @@ -from flask import Flask, request, jsonify, make_response -import configparser -import base64 -import auth -import info -import setme -import arcscore - -app = Flask(__name__) -wsgi_app = app.wsgi_app - - -def error_return(error_code): # 错误返回 - # 100 无法在此ip地址下登录游戏 - # 101 用户名占用 - # 102 电子邮箱已注册 - # 103 已有一个账号由此设备创建 - # 104 用户名密码错误 - # 105 24小时内登入两台设备 - # 106 账户冻结 - # 107 你没有足够的体力 - # 401 用户不存在 - # 403 无法连接至服务器 - # 501 502 此物品目前无法获取 - # 504 无效的序列码 - # 505 此序列码已被使用 - # 506 你已拥有了此物品 - # 601 好友列表已满 - # 602 此用户已是好友 - # 604 你不能加自己为好友 - # 其它 发生未知错误 - return jsonify({ - "success": False, - "error_code": error_code - }) - - -@app.route('/') -def hello(): - return "Hello World!" - - -@app.route('/coffee/12/auth/login', methods=['POST']) # 登录接口 -def login(): - headers = request.headers - id_pwd = headers['Authorization'] - id_pwd = base64.b64decode(id_pwd[6:]).decode() - name, password = id_pwd.split(':', 1) - - try: - token = auth.arc_login(name, password) - if token is not None: - r = {"success": True, "token_type": "Bearer"} - r['access_token'] = token - return jsonify(r) - else: - return error_return(104) # 用户名或密码错误 - except: - return error_return(108) - - -@app.route('/coffee/12/user/', methods=['POST']) # 注册接口 -def register(): - name = request.form['name'] - password = request.form['password'] - try: - user_id, token, error_code = auth.arc_register(name, password) - if user_id is not None: - r = {"success": True, "value": { - 'user_id': user_id, 'access_token': token}} - return jsonify(r) - else: - return error_return(error_code) # 应该是101,用户名被占用,毕竟电子邮箱、设备号没记录 - except: - return error_return(108) - - -@app.route('/coffee/12/compose/aggregate', methods=['GET']) # 用户信息获取 -def aggregate(): - calls = request.args.get('calls') - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = auth.token_get_id(token) - if user_id is not None: - if calls == '[{ "endpoint": "/user/me", "id": 0 }]': # 极其沙雕的判断,我猜get的参数就两种 - r = info.arc_aggregate_small(user_id) - else: - r = info.arc_aggregate_big(user_id) - return jsonify(r) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/user/me/character', methods=['POST']) # 角色切换 -def character_change(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - character_id = request.form['character'] - skill_sealed = request.form['skill_sealed'] - try: - user_id = auth.token_get_id(token) - if user_id is not None: - flag = setme.change_char(user_id, character_id, skill_sealed) - if flag: - return jsonify({ - "success": True, - "value": { - "user_id": user_id, - "character": character_id - } - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee//toggle_uncap', methods=['POST']) # 角色觉醒切换 -def character_uncap(path): - character_id = int(path[22:]) - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = auth.token_get_id(token) - if user_id is not None: - r = setme.change_char_uncap(user_id, character_id) - if r is not None: - return jsonify({ - "success": True, - "value": { - "user_id": user_id, - "character": [r] - } - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/friend/me/add', methods=['POST']) # 加好友 -def add_friend(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - friend_code = request.form['friend_code'] - try: - user_id = auth.token_get_id(token) - friend_id = auth.code_get_id(friend_code) - if user_id is not None and friend_id is not None: - r = setme.arc_add_friend(user_id, friend_id) - if r is not None and r != 602 and r != 604: - return jsonify({ - "success": True, - "value": { - "user_id": user_id, - "updatedAt": "2020-09-07T07:32:12.740Z", - "createdAt": "2020-09-06T10:05:18.471Z", - "friends": r - } - }) - else: - if r is not None: - return error_return(r) - else: - return error_return(108) - else: - if friend_id is None: - return error_return(401) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/friend/me/delete', methods=['POST']) # 删好友 -def delete_friend(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - friend_id = int(request.form['friend_id']) - try: - user_id = auth.token_get_id(token) - if user_id is not None and friend_id is not None: - r = setme.arc_delete_friend(user_id, friend_id) - if r is not None: - return jsonify({ - "success": True, - "value": { - "user_id": user_id, - "updatedAt": "2020-09-07T07:32:12.740Z", - "createdAt": "2020-09-06T10:05:18.471Z", - "friends": r - } - }) - else: - return error_return(108) - else: - if friend_id is None: - return error_return(401) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/score/song/friend', methods=['GET']) # 好友排名,默认最多50 -def song_score_friend(): - song_id = request.args.get('song_id') - difficulty = request.args.get('difficulty') - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = auth.token_get_id(token) - if user_id is not None: - r = arcscore.arc_score_friend(user_id, song_id, difficulty) - if r is not None: - return jsonify({ - "success": True, - "value": r - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/score/song/me', methods=['GET']) # 我的排名,默认最多20 -def song_score_me(): - song_id = request.args.get('song_id') - difficulty = request.args.get('difficulty') - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = auth.token_get_id(token) - if user_id is not None: - r = arcscore.arc_score_me(user_id, song_id, difficulty) - if r is not None: - return jsonify({ - "success": True, - "value": r - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/score/song', methods=['GET']) # TOP20 -def song_score_top(): - song_id = request.args.get('song_id') - difficulty = request.args.get('difficulty') - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = auth.token_get_id(token) - if user_id is not None: - r = arcscore.arc_score_top(song_id, difficulty) - if r is not None: - return jsonify({ - "success": True, - "value": r - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/score/song', methods=['POST']) # 成绩上传 -def song_score_post(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - song_id = request.form['song_id'] - difficulty = int(request.form['difficulty']) - score = int(request.form['score']) - shiny_perfect_count = int(request.form['shiny_perfect_count']) - perfect_count = int(request.form['perfect_count']) - near_count = int(request.form['near_count']) - miss_count = int(request.form['miss_count']) - health = int(request.form['health']) - modifier = int(request.form['modifier']) - beyond_gauge = int(request.form['beyond_gauge']) - clear_type = int(request.form['clear_type']) - - try: - user_id = auth.token_get_id(token) - if user_id is not None: - r = arcscore.arc_score_post(user_id, song_id, difficulty, score, shiny_perfect_count, - perfect_count, near_count, miss_count, health, modifier, beyond_gauge, clear_type) - if r is not None: - return jsonify({ - "success": True, - "value": {"user_rating": r} - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/score/token', methods=['GET']) # 成绩上传所需的token,显然我不想验证 -def score_token(): - return jsonify({ - "success": True, - "value": { - "token": "1145141919810" - } - }) - - -@app.route('/coffee/12/user/me/save', methods=['GET']) # 从云端同步 -def cloud_get(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = auth.token_get_id(token) - if user_id is not None: - r = arcscore.arc_all_get(user_id) - if r is not None: - return jsonify({ - "success": True, - "value": r - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/user/me/save', methods=['POST']) # 向云端同步 -def cloud_post(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - scores_data = request.form['scores_data'] - clearlamps_data = request.form['clearlamps_data'] - try: - user_id = auth.token_get_id(token) - if user_id is not None: - arcscore.arc_all_post(user_id, scores_data, clearlamps_data) - return jsonify({ - "success": True, - "value": { - "user_id": user_id - } - }) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/purchase/me/redeem', methods=['POST']) # 兑换码,自然没有用 -def redeem(): - return error_return(504) - - -@app.route('/coffee/', methods=['POST']) # 三个设置,写在最后降低优先级 -def sys_set(path): - set_arg = path[10:] - headers = request.headers - token = headers['Authorization'] - token = token[7:] - value = request.form['value'] - - try: - user_id = auth.token_get_id(token) - if user_id is not None: - setme.arc_sys_set(user_id, value, set_arg) - r = info.arc_aggregate_small(user_id) - r['value'] = r['value'][0]['value'] - return jsonify(r) - else: - return error_return(108) - except: - return error_return(108) - - -def main(): - config = configparser.ConfigParser() - path = r'setting.ini' - config.read(path, encoding="utf-8") - HOST = config.get('CONFIG','HOST') - PORT = config.get('CONFIG','PORT') - app.run(HOST, PORT) - - -if __name__ == '__main__': - main() - - -## Made By Lost 2020.9.11 diff --git a/v1.1/run.bat b/v1.1/run.bat deleted file mode 100644 index 7a84f97..0000000 --- a/v1.1/run.bat +++ /dev/null @@ -1 +0,0 @@ -python main.py \ No newline at end of file diff --git a/v1.1/setme.py b/v1.1/setme.py deleted file mode 100644 index 4caace3..0000000 --- a/v1.1/setme.py +++ /dev/null @@ -1,155 +0,0 @@ -import sqlite3 -import info - - -def b2int(x): - # int与布尔值转换 - if x: - return 1 - else: - return 0 - - -def int2b(x): - # int与布尔值转换 - if x is None or x == 0: - return False - else: - return True - - -def change_char(user_id, character_id, skill_sealed): - # 角色改变,包括技能封印的改变,返回成功与否的布尔值 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id = :a and character_id = :b''', - {'a': user_id, 'b': character_id}) - x = c.fetchone() - if x is not None: - if skill_sealed == 'false': - skill_sealed = False - else: - skill_sealed = True - c.execute('''update user set is_skill_sealed = :a, character_id = :b, is_char_uncapped = :c, is_char_uncapped_override = :d where user_id = :e''', { - 'a': b2int(skill_sealed), 'b': character_id, 'c': x[0], 'd': x[1], 'e': user_id}) - - conn.commit() - conn.close() - return True - - conn.commit() - conn.close() - return False - - -def change_char_uncap(user_id, character_id): - # 角色觉醒改变,返回字典 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id = :a and character_id = :b''', - {'a': user_id, 'b': character_id}) - x = c.fetchone() - r = None - if x is not None and x[0] == 1: - c.execute('''update user set is_char_uncapped_override = :a where user_id = :b''', { - 'a': b2int(x[1] == 0), 'b': user_id}) - c.execute('''update user_char set is_uncapped_override = :a where user_id = :b and character_id = :c''', { - 'a': b2int(x[1] == 0), 'b': user_id, 'c': character_id}) - c.execute('''select * from user_char where user_id = :a and character_id = :b''', - {'a': user_id, 'b': character_id}) - y = c.fetchone() - c.execute( - '''select name from character where character_id = :x''', {'x': y[1]}) - z = c.fetchone() - if z is not None: - char_name = z[0] - if y is not None: - r = { - "is_uncapped_override": int2b(y[14]), - "is_uncapped": int2b(y[13]), - "uncap_cores": [], - "char_type": y[12], - "skill_id_uncap": y[11], - "skill_requires_uncap": int2b(y[10]), - "skill_unlock_level": y[9], - "skill_id": y[8], - "overdrive": y[7], - "prog": y[6], - "frag": y[5], - "level_exp": y[4], - "exp": y[3], - "level": y[2], - "name": char_name, - "character_id": y[1] - } - - conn.commit() - conn.close() - return r - - -def arc_sys_set(user_id, value, set_arg): - # 三个设置,PTT隐藏、体力满通知、最爱角色,无返回 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - if 'favorite_character' in set_arg: - value = int(value) - c.execute('''update user set favorite_character = :a where user_id = :b''', { - 'a': value, 'b': user_id}) - - else: - if value == 'false': - value = False - else: - value = True - - if 'is_hide_rating' in set_arg: - c.execute('''update user set is_hide_rating = :a where user_id = :b''', { - 'a': b2int(value), 'b': user_id}) - if 'max_stamina_notification_enabled' in set_arg: - c.execute('''update user set max_stamina_notification_enabled = :a where user_id = :b''', { - 'a': b2int(value), 'b': user_id}) - - conn.commit() - conn.close() - return None - - -def arc_add_friend(user_id, friend_id): - # 加好友,返回好友列表,或者是错误码602、604 - if user_id == friend_id: - return 604 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''', - {'x': user_id, 'y': friend_id}) - r = None - if c.fetchone() == (0,): - c.execute('''insert into friend values(:a, :b)''', - {'a': user_id, 'b': friend_id}) - r = info.get_user_friend(c, user_id) - - else: - return 602 - - conn.commit() - conn.close() - return r - - -def arc_delete_friend(user_id, friend_id): - # 删好友,返回好友列表 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''', - {'x': user_id, 'y': friend_id}) - r = None - if c.fetchone() == (1,): - c.execute('''delete from friend where user_id_me = :x and user_id_other = :y''', - {'x': user_id, 'y': friend_id}) - - r = info.get_user_friend(c, user_id) - - conn.commit() - conn.close() - return r diff --git a/v1.1/setting.ini b/v1.1/setting.ini deleted file mode 100644 index 3d109b5..0000000 --- a/v1.1/setting.ini +++ /dev/null @@ -1,3 +0,0 @@ -[CONFIG] -HOST = 192.168.1.113 -PORT = 80 \ No newline at end of file diff --git a/v1.2/database/arcaea_database.db b/v1.2/database/arcaea_database.db deleted file mode 100644 index 18b28cf..0000000 Binary files a/v1.2/database/arcaea_database.db and /dev/null differ diff --git a/v1.2/database/arcsong.db b/v1.2/database/arcsong.db deleted file mode 100644 index 2a7629d..0000000 Binary files a/v1.2/database/arcsong.db and /dev/null differ diff --git a/v1.2/database/database_initialize.py b/v1.2/database/database_initialize.py deleted file mode 100644 index cb754c3..0000000 --- a/v1.2/database/database_initialize.py +++ /dev/null @@ -1,233 +0,0 @@ -import sqlite3 -import hashlib -import time -# 数据库初始化文件,删掉arcaea_database.db文件后运行即可,谨慎使用 - -conn = sqlite3.connect('arcaea_database.db') -c = conn.cursor() -c.execute('''create table if not exists user(user_id int primary key, -name text unique, -password text not null, -join_date char(20), -user_code char(10), -rating_ptt int, -character_id int, -is_skill_sealed int, -is_char_uncapped int, -is_char_uncapped_override int, -is_hide_rating int, -song_id text, -difficulty int, -score int, -shiny_perfect_count int, -perfect_count int, -near_count int, -miss_count int, -health int, -modifier int, -time_played int, -clear_type int, -rating real, -favorite_character int, -max_stamina_notification_enabled int -);''') -c.execute('''create table if not exists login(access_token text, -user_id int, -last_login_time int, -last_login_ip text, -last_login_device text -);''') -c.execute('''create table if not exists friend(user_id_me int, -user_id_other int, -primary key (user_id_me, user_id_other) -);''') -c.execute('''create table if not exists best_score(user_id int, -song_id text, -difficulty int, -score int, -shiny_perfect_count int, -perfect_count int, -near_count int, -miss_count int, -health int, -modifier int, -time_played int, -best_clear_type int, -clear_type int, -rating real, -primary key(user_id, song_id, difficulty) -);''') -c.execute('''create table if not exists user_char(user_id int, -character_id int, -level int, -exp real, -level_exp real, -frag int, -prog int, -overdrive int, -skill_id text, -skill_unlock_level int, -skill_requires_uncap int, -skill_id_uncap text, -char_type int, -is_uncapped int, -is_uncapped_override int, -primary key(user_id, character_id) -);''') -c.execute('''create table if not exists character(character_id int primary key, -name text, -level int, -exp real, -level_exp real, -frag int, -prog int, -overdrive int, -skill_id text, -skill_unlock_level int, -skill_requires_uncap int, -skill_id_uncap text, -char_type int, -uncap_cores text, -is_uncapped int, -is_uncapped_override int -);''') -c.execute('''create table if not exists recent30(user_id int primary key, -r0 real, -song_id0 text, -r1 real, -song_id1 text, -r2 real, -song_id2 text, -r3 real, -song_id3 text, -r4 real, -song_id4 text, -r5 real, -song_id5 text, -r6 real, -song_id6 text, -r7 real, -song_id7 text, -r8 real, -song_id8 text, -r9 real, -song_id9 text, -r10 real, -song_id10 text, -r11 real, -song_id11 text, -r12 real, -song_id12 text, -r13 real, -song_id13 text, -r14 real, -song_id14 text, -r15 real, -song_id15 text, -r16 real, -song_id16 text, -r17 real, -song_id17 text, -r18 real, -song_id18 text, -r19 real, -song_id19 text, -r20 real, -song_id20 text, -r21 real, -song_id21 text, -r22 real, -song_id22 text, -r23 real, -song_id23 text, -r24 real, -song_id24 text, -r25 real, -song_id25 text, -r26 real, -song_id26 text, -r27 real, -song_id27 text, -r28 real, -song_id28 text, -r29 real, -song_id29 text -);''') - -char = ['Hikari','Tairitsu','Kou','Sapphire','Lethe','','Tairitsu(Axium)' -,'Tairitsu(Grievous Lady)','Stella','Hikari & Fisica','Ilith','Eto','Luna' -,'Shirabe','Hikari(Zero)','Hikari(Fracture)','Hikari(Summer)','Tairitsu(Summer)' -,'Tairitsu&Trin','Ayu','Eto&Luna','Yume','Seine & Hikari','Saya','Tairitsu & Chuni Penguin' -,'Chuni Penguin','Haruna','Nono','MTA-XXX','MDA-21','Kanae','Hikari(Fantasia)','Tairitsu(Sonata)','Sia','DORO*C' -,'Tairitsu(Tempest)','Brillante','Ilith(Summer)'] - -for i in range(0, 38): - if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]: - sql = 'insert into character values('+str(i)+',"'+char[i]+'''",30,25000,25000,90,90,90,'',0,0,'',0,'',1,1)''' - c.execute(sql) - else: - if i != 5: - sql = 'insert into character values('+str(i)+',"'+char[i]+'''",30,25000,25000,90,90,90,'',0,0,'',0,'',0,0)''' - c.execute(sql) - - - -conn.commit() -conn.close() - - - -def arc_register(name: str, password: str): - def build_user_code(c): - return '123456789' - - def build_user_id(c): - return 2000000 - -## def insert_user_char(c, user_id): -## for i in range(0, 38): -## if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]: -## sql = 'insert into user_char values('+str(user_id)+','+str( -## i)+''',30,25000,25000,90,90,90,'',0,0,'',0,1,1)''' -## c.execute(sql) -## else: -## if i != 5: -## sql = 'insert into user_char values('+str(user_id)+','+str( -## i)+''',30,25000,25000,90,90,90,'',0,0,'',0,0,0)''' -## c.execute(sql) - def insert_user_char(c, user_id): - # 为用户添加所有可用角色 - c.execute('''select * from character''') - x = c.fetchall() - if x != []: - for i in x: - c.execute('''insert into user_char values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n,:o)''', { - 'a': user_id, 'b': i[0], 'c': i[2], 'd': i[3], 'e': i[4], 'f': i[5], 'g': i[6], 'h': i[7], 'i': i[8], 'j': i[9], 'k': i[10], 'l': i[11], 'm': i[12], 'n': i[14], 'o': i[15]}) - - conn = sqlite3.connect('arcaea_database.db') - c = conn.cursor() - hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest() - c.execute( - '''select exists(select * from user where name = :name)''', {'name': name}) - if c.fetchone() == (0,): - user_code = build_user_code(c) - user_id = build_user_id(c) - now = int(time.time() * 1000) - c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt, - character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled) - values(:user_id, :name, :password, :join_date, :user_code, 1250, 1, 0, 1, 0, 0, -1, 0) - ''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd}) - c.execute('''insert into recent30(user_id) values(:user_id)''', { - 'user_id': user_id}) - c.execute('''insert into best_score values(2000000,'vexaria',3,10000000,100,0,0,0,100,0,1599667200,3,3,10.8)''') - insert_user_char(c, user_id) - conn.commit() - conn.close() - return None - else: - conn.commit() - conn.close() - return None - - -arc_register('admin', 'admin123') diff --git a/v1.2/main.py b/v1.2/main.py deleted file mode 100644 index a3c1d1e..0000000 --- a/v1.2/main.py +++ /dev/null @@ -1,425 +0,0 @@ -from flask import Flask, request, jsonify, make_response -import configparser -import base64 -import server.auth -import server.info -import server.setme -import server.arcscore -import web.login -import web.index - -app = Flask(__name__) -wsgi_app = app.wsgi_app - - -def error_return(error_code): # 错误返回 - # 100 无法在此ip地址下登录游戏 - # 101 用户名占用 - # 102 电子邮箱已注册 - # 103 已有一个账号由此设备创建 - # 104 用户名密码错误 - # 105 24小时内登入两台设备 - # 106 账户冻结 - # 107 你没有足够的体力 - # 401 用户不存在 - # 403 无法连接至服务器 - # 501 502 此物品目前无法获取 - # 504 无效的序列码 - # 505 此序列码已被使用 - # 506 你已拥有了此物品 - # 601 好友列表已满 - # 602 此用户已是好友 - # 604 你不能加自己为好友 - # 其它 发生未知错误 - return jsonify({ - "success": False, - "error_code": error_code - }) - - -@app.route('/') -def hello(): - return "Hello World!" - - -@app.route('/coffee/12/auth/login', methods=['POST']) # 登录接口 -def login(): - headers = request.headers - id_pwd = headers['Authorization'] - id_pwd = base64.b64decode(id_pwd[6:]).decode() - name, password = id_pwd.split(':', 1) - - try: - token = server.auth.arc_login(name, password) - if token is not None: - r = {"success": True, "token_type": "Bearer"} - r['access_token'] = token - return jsonify(r) - else: - return error_return(104) # 用户名或密码错误 - except: - return error_return(108) - - -@app.route('/coffee/12/user/', methods=['POST']) # 注册接口 -def register(): - name = request.form['name'] - password = request.form['password'] - try: - user_id, token, error_code = server.auth.arc_register(name, password) - if user_id is not None: - r = {"success": True, "value": { - 'user_id': user_id, 'access_token': token}} - return jsonify(r) - else: - return error_return(error_code) # 应该是101,用户名被占用,毕竟电子邮箱、设备号没记录 - except: - return error_return(108) - - -@app.route('/coffee/12/compose/aggregate', methods=['GET']) # 用户信息获取 -def aggregate(): - calls = request.args.get('calls') - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = server.auth.token_get_id(token) - if user_id is not None: - if calls == '[{ "endpoint": "/user/me", "id": 0 }]': # 极其沙雕的判断,我猜get的参数就两种 - r = server.info.arc_aggregate_small(user_id) - else: - r = server.info.arc_aggregate_big(user_id) - return jsonify(r) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/user/me/character', methods=['POST']) # 角色切换 -def character_change(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - character_id = request.form['character'] - skill_sealed = request.form['skill_sealed'] - try: - user_id = server.auth.token_get_id(token) - if user_id is not None: - flag = server.setme.change_char( - user_id, character_id, skill_sealed) - if flag: - return jsonify({ - "success": True, - "value": { - "user_id": user_id, - "character": character_id - } - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee//toggle_uncap', methods=['POST']) # 角色觉醒切换 -def character_uncap(path): - character_id = int(path[22:]) - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = server.auth.token_get_id(token) - if user_id is not None: - r = server.setme.change_char_uncap(user_id, character_id) - if r is not None: - return jsonify({ - "success": True, - "value": { - "user_id": user_id, - "character": [r] - } - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/friend/me/add', methods=['POST']) # 加好友 -def add_friend(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - friend_code = request.form['friend_code'] - try: - user_id = server.auth.token_get_id(token) - friend_id = server.auth.code_get_id(friend_code) - if user_id is not None and friend_id is not None: - r = server.setme.arc_add_friend(user_id, friend_id) - if r is not None and r != 602 and r != 604: - return jsonify({ - "success": True, - "value": { - "user_id": user_id, - "updatedAt": "2020-09-07T07:32:12.740Z", - "createdAt": "2020-09-06T10:05:18.471Z", - "friends": r - } - }) - else: - if r is not None: - return error_return(r) - else: - return error_return(108) - else: - if friend_id is None: - return error_return(401) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/friend/me/delete', methods=['POST']) # 删好友 -def delete_friend(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - friend_id = int(request.form['friend_id']) - try: - user_id = server.auth.token_get_id(token) - if user_id is not None and friend_id is not None: - r = server.setme.arc_delete_friend(user_id, friend_id) - if r is not None: - return jsonify({ - "success": True, - "value": { - "user_id": user_id, - "updatedAt": "2020-09-07T07:32:12.740Z", - "createdAt": "2020-09-06T10:05:18.471Z", - "friends": r - } - }) - else: - return error_return(108) - else: - if friend_id is None: - return error_return(401) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/score/song/friend', methods=['GET']) # 好友排名,默认最多50 -def song_score_friend(): - song_id = request.args.get('song_id') - difficulty = request.args.get('difficulty') - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = server.auth.token_get_id(token) - if user_id is not None: - r = server.arcscore.arc_score_friend(user_id, song_id, difficulty) - if r is not None: - return jsonify({ - "success": True, - "value": r - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/score/song/me', methods=['GET']) # 我的排名,默认最多20 -def song_score_me(): - song_id = request.args.get('song_id') - difficulty = request.args.get('difficulty') - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = server.auth.token_get_id(token) - if user_id is not None: - r = server.arcscore.arc_score_me(user_id, song_id, difficulty) - if r is not None: - return jsonify({ - "success": True, - "value": r - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/score/song', methods=['GET']) # TOP20 -def song_score_top(): - song_id = request.args.get('song_id') - difficulty = request.args.get('difficulty') - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = server.auth.token_get_id(token) - if user_id is not None: - r = server.arcscore.arc_score_top(song_id, difficulty) - if r is not None: - return jsonify({ - "success": True, - "value": r - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/score/song', methods=['POST']) # 成绩上传 -def song_score_post(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - song_id = request.form['song_id'] - difficulty = int(request.form['difficulty']) - score = int(request.form['score']) - shiny_perfect_count = int(request.form['shiny_perfect_count']) - perfect_count = int(request.form['perfect_count']) - near_count = int(request.form['near_count']) - miss_count = int(request.form['miss_count']) - health = int(request.form['health']) - modifier = int(request.form['modifier']) - beyond_gauge = int(request.form['beyond_gauge']) - clear_type = int(request.form['clear_type']) - - try: - user_id = server.auth.token_get_id(token) - if user_id is not None: - r = server.arcscore.arc_score_post(user_id, song_id, difficulty, score, shiny_perfect_count, - perfect_count, near_count, miss_count, health, modifier, beyond_gauge, clear_type) - if r is not None: - return jsonify({ - "success": True, - "value": {"user_rating": r} - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/score/token', methods=['GET']) # 成绩上传所需的token,显然我不想验证 -def score_token(): - return jsonify({ - "success": True, - "value": { - "token": "1145141919810" - } - }) - - -@app.route('/coffee/12/user/me/save', methods=['GET']) # 从云端同步 -def cloud_get(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - try: - user_id = server.auth.token_get_id(token) - if user_id is not None: - r = server.arcscore.arc_all_get(user_id) - if r is not None: - return jsonify({ - "success": True, - "value": r - }) - else: - return error_return(108) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/user/me/save', methods=['POST']) # 向云端同步 -def cloud_post(): - headers = request.headers - token = headers['Authorization'] - token = token[7:] - scores_data = request.form['scores_data'] - clearlamps_data = request.form['clearlamps_data'] - try: - user_id = server.auth.token_get_id(token) - if user_id is not None: - server.arcscore.arc_all_post(user_id, scores_data, clearlamps_data) - return jsonify({ - "success": True, - "value": { - "user_id": user_id - } - }) - else: - return error_return(108) - except: - return error_return(108) - - -@app.route('/coffee/12/purchase/me/redeem', methods=['POST']) # 兑换码,自然没有用 -def redeem(): - return error_return(504) - - -@app.route('/coffee/', methods=['POST']) # 三个设置,写在最后降低优先级 -def sys_set(path): - set_arg = path[10:] - headers = request.headers - token = headers['Authorization'] - token = token[7:] - value = request.form['value'] - - try: - user_id = server.auth.token_get_id(token) - if user_id is not None: - server.setme.arc_sys_set(user_id, value, set_arg) - r = server.info.arc_aggregate_small(user_id) - r['value'] = r['value'][0]['value'] - return jsonify(r) - else: - return error_return(108) - except: - return error_return(108) - - -def main(): - config = configparser.ConfigParser() - path = r'setting.ini' - config.read(path, encoding="utf-8") - HOST = config.get('CONFIG', 'HOST') - PORT = config.get('CONFIG', 'PORT') - app.config.from_mapping(SECRET_KEY='1145141919810') - app.register_blueprint(web.login.bp) - app.register_blueprint(web.index.bp) - - app.run(HOST, PORT) - - -if __name__ == '__main__': - main() - - -# Made By Lost 2020.9.11 diff --git a/v1.2/run.bat b/v1.2/run.bat deleted file mode 100644 index 7a84f97..0000000 --- a/v1.2/run.bat +++ /dev/null @@ -1 +0,0 @@ -python main.py \ No newline at end of file diff --git a/v1.2/server/arcscore.py b/v1.2/server/arcscore.py deleted file mode 100644 index fd5e11b..0000000 --- a/v1.2/server/arcscore.py +++ /dev/null @@ -1,1248 +0,0 @@ -import sqlite3 -import time -import json - - -def b2int(x): - # int与布尔值转换 - if x: - return 1 - else: - return 0 - - -def int2b(x): - # int与布尔值转换 - if x is None or x == 0: - return False - else: - return True - - -def get_score(c, user_id, song_id, difficulty): - # 根据user_id、song_id、难度得到该曲目最好成绩,返回字典 - c.execute('''select * from best_score where user_id = :a and song_id = :b and difficulty = :c''', - {'a': user_id, 'b': song_id, 'c': difficulty}) - x = c.fetchone() - if x is not None: - c.execute('''select name, character_id, is_skill_sealed, is_char_uncapped from user where user_id = :a''', { - 'a': user_id}) - y = c.fetchone() - if y is not None: - return { - "user_id": x[0], - "song_id": x[1], - "difficulty": x[2], - "score": x[3], - "shiny_perfect_count": x[4], - "perfect_count": x[5], - "near_count": x[6], - "miss_count": x[7], - "health": x[8], - "modifier": x[9], - "time_played": x[10], - "best_clear_type": x[11], - "clear_type": x[12], - "name": y[0], - "character": y[1], - "is_skill_sealed": int2b(y[2]), - "is_char_uncapped": int2b(y[3]) - } - else: - return {} - else: - return {} - - -def arc_score_friend(user_id, song_id, difficulty, limit=50): - # 得到用户好友分数表,默认最大50个 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select user_id from best_score where user_id in (select :user_id union select user_id_other from friend where user_id_me = :user_id) and song_id = :song_id and difficulty = :difficulty order by score DESC, time_played DESC limit :limit''', { - 'user_id': user_id, 'song_id': song_id, 'difficulty': difficulty, 'limit': limit}) - x = c.fetchall() - r = [] - if x != []: - rank = 0 - for i in x: - rank += 1 - y = get_score(c, i[0], song_id, difficulty) - y['rank'] = rank - r.append(y) - - conn.commit() - conn.close() - return r - - -def arc_score_top(song_id, difficulty, limit=20): - # 得到top分数表,默认最多20个,如果是负数则全部查询 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - if limit >= 0: - c.execute('''select user_id from best_score where song_id = :song_id and difficulty = :difficulty order by score DESC, time_played DESC limit :limit''', { - 'song_id': song_id, 'difficulty': difficulty, 'limit': limit}) - else: - c.execute('''select user_id from best_score where song_id = :song_id and difficulty = :difficulty order by score DESC, time_played DESC''', { - 'song_id': song_id, 'difficulty': difficulty}) - x = c.fetchall() - r = [] - if x != []: - rank = 0 - for i in x: - rank += 1 - y = get_score(c, i[0], song_id, difficulty) - y['rank'] = rank - r.append(y) - - conn.commit() - conn.close() - return r - - -def arc_score_me(user_id, song_id, difficulty, limit=20): - # 得到用户的排名,默认最大20个 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - r = [] - c.execute('''select exists(select * from best_score where user_id = :user_id and song_id = :song_id and difficulty = :difficulty)''', { - 'user_id': user_id, 'song_id': song_id, 'difficulty': difficulty}) - if c.fetchone() == (1,): - c.execute('''select count(*) from best_score where song_id = :song_id and difficulty = :difficulty and (score>(select score from best_score where user_id = :user_id and song_id = :song_id and difficulty = :difficulty) or (score>(select score from best_score where user_id = :user_id and song_id = :song_id and difficulty = :difficulty) and time_played > (select time_played from best_score where user_id = :user_id and song_id = :song_id and difficulty = :difficulty)) )''', { - 'user_id': user_id, 'song_id': song_id, 'difficulty': difficulty}) - x = c.fetchone() - myrank = int(x[0]) + 1 - if myrank <= 4: # 排名在前4 - conn.commit() - conn.close() - return arc_score_top(song_id, difficulty, limit) - elif myrank >= 5 and myrank <= 9999 - limit + 4: # 万名内,前面有4个人 - c.execute('''select user_id from best_score where song_id = :song_id and difficulty = :difficulty order by score DESC, time_played DESC limit :limit offset :offset''', { - 'song_id': song_id, 'difficulty': difficulty, 'limit': limit, 'offset': myrank - 5}) - x = c.fetchall() - if x != []: - rank = myrank - 5 - for i in x: - rank += 1 - y = get_score(c, i[0], song_id, difficulty) - y['rank'] = rank - r.append(y) - - elif myrank >= 10000: # 万名外 - c.execute('''select user_id from best_score where song_id = :song_id and difficulty = :difficulty order by score DESC, time_played DESC limit :limit offset :offset''', { - 'song_id': song_id, 'difficulty': difficulty, 'limit': limit - 1, 'offset': 9999-limit}) - x = c.fetchall() - if x != []: - rank = 9999 - limit - for i in x: - rank += 1 - y = get_score(c, i[0], song_id, difficulty) - y['rank'] = rank - r.append(y) - y = get_score(c, user_id, song_id, difficulty) - y['rank'] = -1 - r.append(y) - else: - c.execute('''select user_id from best_score where song_id = :song_id and difficulty = :difficulty order by score DESC, time_played DESC limit :limit offset :offset''', { - 'song_id': song_id, 'difficulty': difficulty, 'limit': limit, 'offset': 9998-limit}) - x = c.fetchall() - if x != []: - rank = 9998 - limit - for i in x: - rank += 1 - y = get_score(c, i[0], song_id, difficulty) - y['rank'] = rank - r.append(y) - - conn.commit() - conn.close() - return r - - -def get_one_ptt(song_id, difficulty, score: int) -> float: - # 单曲ptt计算 - conn = sqlite3.connect('./database/arcsong.db') - c = conn.cursor() - if difficulty == 0: - c.execute('''select rating_pst from songs where sid = :sid;''', { - 'sid': song_id}) - elif difficulty == 1: - c.execute('''select rating_prs from songs where sid = :sid;''', { - 'sid': song_id}) - elif difficulty == 2: - c.execute('''select rating_ftr from songs where sid = :sid;''', { - 'sid': song_id}) - elif difficulty == 3: - c.execute('''select rating_byn from songs where sid = :sid;''', { - 'sid': song_id}) - - x = c.fetchone() - defnum = 10.0 # 没在库里的全部当做定数10.0,不过要小心recent30表可能会被污染 - if x is not None and x != '': - defnum = float(x[0]) / 10 - if defnum <= 0: - defnum = 11.0 # 缺少难度的当做定数11.0 - - if score >= 10000000: - ptt = defnum + 2 - elif score < 9800000: - ptt = defnum + (score-9500000) / 300000 - if ptt < 0: - ptt = 0 - else: - ptt = defnum + 1 + (score-9800000) / 200000 - - conn.commit() - conn.close() - return ptt - - -def get_song_grade(x): - # 成绩转换评级 - if x >= 9900000: # EX+ - return 6 - elif x < 9900000 and x >= 9800000: # EX - return 5 - elif x < 9800000 and x >= 9500000: # AA - return 4 - elif x < 9500000 and x >= 9200000: # A - return 3 - elif x < 9200000 and x >= 8900000: # B - return 2 - elif x < 8900000 and x >= 8600000: # C - return 1 - else: - return 0 - - -def get_song_state(x): - # 返回成绩状态,便于比较 - if x == 3: # PM - return 5 - elif x == 2: # FC - return 4 - elif x == 5: # Hard Clear - return 3 - elif x == 1: # Clear - return 2 - elif x == 4: # Easy Clear - return 1 - else: # Track Lost - return 0 - - -def update_recent30(c, user_id, song_id, rating): - # 刷新r30,这里的判断方法存疑 - c.execute('''select * from recent30 where user_id = :a''', {'a': user_id}) - x = c.fetchone() - songs = [] - flag = True - for i in range(2, 61, 2): - if x[i] is None or x[i] == '': - r30_id = 29 - flag = False - break - if x[i] not in songs: - songs.append(x[i]) - if flag: - n = len(song_id) - if n >= 11: - r30_id = 29 - elif song_id not in songs and n == 10: - r30_id = 29 - elif song_id in songs and n == 10: - i = 29 - while x[i*2+2] == song_id: - i -= 1 - r30_id = i - elif song_id not in songs and n == 9: - i = 29 - while x[i*2+2] == song_id: - i -= 1 - r30_id = i - else: - r30_id = 29 - a = [] - b = [] - for i in range(1, 61, 2): - a.append(x[i]) - b.append(x[i+1]) - for i in range(r30_id, 0, -1): - a[i] = a[i-1] - b[i] = b[i-1] - a[0] = rating - b[0] = song_id - c.execute('''delete from recent30 where user_id = :a''', {'a': user_id}) - sql = 'insert into recent30 values(' + str(user_id) - for i in range(0, 30): - if a[i] is not None and b[i] is not None: - sql = sql + ',' + str(a[i]) + ',"' + b[i] + '"' - else: - sql = sql + ',0,""' - - sql = sql + ')' - c.execute(sql) - return None - - -def get_user_ptt(c, user_id) -> int: - # 总ptt计算 - sumr = 0 - c.execute('''select rating from best_score where user_id = :a order by rating DESC limit 30''', { - 'a': user_id}) - x = c.fetchall() - if x != []: - n = len(x) - for i in x: - sumr += float(i[0]) - c.execute('''select * from recent30 where user_id = :a''', {'a': user_id}) - x = c.fetchone() - if x is not None: - r30 = [] - s30 = [] - for i in range(1, 61, 2): - if x[i] is not None: - r30.append(float(x[i])) - s30.append(x[i+1]) - else: - r30.append(0) - s30.append('') - r30, s30 = (list(t) for t in zip(*sorted(zip(r30, s30), reverse=True))) - songs = [] - i = 0 - while len(songs) < 10 and i <= 29 and s30[i] != '' and s30[i] is not None: - if s30[i] not in songs: - sumr += r30[i] - songs.append(s30[i]) - i += 1 - - return int(sumr/40*100) - - -def arc_score_post(user_id, song_id, difficulty, score, shiny_perfect_count, perfect_count, near_count, miss_count, health, modifier, beyond_gauge, clear_type): - # 分数上传,返回变化后的ptt - # beyond_gauge是个什么呀?不管了,扔了 - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - rating = get_one_ptt(song_id, difficulty, score) - now = int(time.time() * 1000) - # recent 更新 - c.execute('''update user set song_id = :b, difficulty = :c, score = :d, shiny_perfect_count = :e, perfect_count = :f, near_count = :g, miss_count = :h, health = :i, modifier = :j, clear_type = :k, rating = :l, time_played = :m where user_id = :a''', { - 'a': user_id, 'b': song_id, 'c': difficulty, 'd': score, 'e': shiny_perfect_count, 'f': perfect_count, 'g': near_count, 'h': miss_count, 'i': health, 'j': modifier, 'k': clear_type, 'l': rating, 'm': now}) - # recent30 更新 - update_recent30(c, user_id, song_id+str(difficulty), rating) - # 成绩录入 - c.execute('''select score, best_clear_type from best_score where user_id = :a and song_id = :b and difficulty = :c''', { - 'a': user_id, 'b': song_id, 'c': difficulty}) - now = int(now // 1000) - x = c.fetchone() - if x is None: - c.execute('''insert into best_score values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n)''', { - 'a': user_id, 'b': song_id, 'c': difficulty, 'd': score, 'e': shiny_perfect_count, 'f': perfect_count, 'g': near_count, 'h': miss_count, 'i': health, 'j': modifier, 'k': now, 'l': clear_type, 'm': clear_type, 'n': rating}) - else: - if get_song_state(clear_type) > get_song_state(int(x[1])): # 状态更新 - c.execute('''update best_score set best_clear_type = :a where user_id = :b and song_id = :c and difficulty = :d''', { - 'a': clear_type, 'b': user_id, 'c': song_id, 'd': difficulty}) - if score >= int(x[0]): # 成绩更新 - c.execute('''update best_score set score = :d, shiny_perfect_count = :e, perfect_count = :f, near_count = :g, miss_count = :h, health = :i, modifier = :j, clear_type = :k, rating = :l, time_played = :m where user_id = :a and song_id = :b and difficulty = :c ''', { - 'a': user_id, 'b': song_id, 'c': difficulty, 'd': score, 'e': shiny_perfect_count, 'f': perfect_count, 'g': near_count, 'h': miss_count, 'i': health, 'j': modifier, 'k': clear_type, 'l': rating, 'm': now}) - # 总PTT更新 - ptt = get_user_ptt(c, user_id) - c.execute('''update user set rating_ptt = :a where user_id = :b''', { - 'a': ptt, 'b': user_id}) - conn.commit() - conn.close() - return ptt - - -def arc_all_post(user_id, scores_data, clearlamps_data): - # 向云端同步,无返回 - # 注意,best_score表不比较,直接覆盖 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - scores = json.loads(scores_data)[""] - clearlamps = json.loads(clearlamps_data)[""] - clear_song_id_difficulty = [] - clear_state = [] - for i in clearlamps: - clear_song_id_difficulty.append(i['song_id']+str(i['difficulty'])) - clear_state.append(i['clear_type']) - - for i in scores: - rating = get_one_ptt(i['song_id'], i['difficulty'], i['score']) - try: - index = clear_song_id_difficulty.index( - i['song_id'] + str(i['difficulty'])) - except: - index = -1 - if index != -1: - clear_type = clear_state[index] - else: - clear_type = 0 - c.execute('''delete from best_score where user_id = :a and song_id = :b and difficulty = :c''', { - 'a': user_id, 'b': i['song_id'], 'c': i['difficulty']}) - c.execute('''insert into best_score values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n)''', { - 'a': user_id, 'b': i['song_id'], 'c': i['difficulty'], 'd': i['score'], 'e': i['shiny_perfect_count'], 'f': i['perfect_count'], 'g': i['near_count'], 'h': i['miss_count'], 'i': i['health'], 'j': i['modifier'], 'k': i['time_played'], 'l': clear_type, 'm': clear_type, 'n': rating}) - - ptt = get_user_ptt(c, user_id) # 更新PTT - c.execute('''update user set rating_ptt = :a where user_id = :b''', { - 'a': ptt, 'b': user_id}) - conn.commit() - conn.close() - return None - - -def arc_all_get(user_id): - # 从云端同步,返回字典 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select * from best_score where user_id = :a''', - {'a': user_id}) - x = c.fetchall() - song_1 = [] - song_2 = [] - song_3 = [] - if x != []: - for i in x: - if i[11] != 0: - song_1.append({ - "grade": get_song_grade(i[3]), - "difficulty": i[2], - "song_id": i[1] - }) - song_2.append({ - "ct": 0, - "clear_type": i[11], - "difficulty": i[2], - "song_id": i[1] - }) - song_3.append({ - "ct": 0, - "time_played": i[10], - "modifier": i[9], - "health": i[8], - "miss_count": i[7], - "near_count": i[6], - "perfect_count": i[5], - "shiny_perfect_count": i[4], - "score": i[3], - "difficulty": i[2], - "version": 1, - "song_id": i[1] - }) - - conn.commit() - conn.close() - return { - "user_id": user_id, - "story": { - "": [{ - "r": True, - "c": True, - "mi": 1, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 7, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 8, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 9, - "ma": 1 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 7, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 8, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 9, - "ma": 2 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 100 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 100 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 100 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 100 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 100 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 7, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 8, - "ma": 101 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 3 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 7, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 8, - "ma": 4 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 4, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 5, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 6, - "ma": 5 - }, { - "r": True, - "c": True, - "mi": 1, - "ma": 6 - }, { - "r": True, - "c": True, - "mi": 2, - "ma": 6 - }, { - "r": True, - "c": True, - "mi": 3, - "ma": 6 - }] - }, - "devicemodelname": { - "val": "MopeMope" - }, - "installid": { - "val": "b5e064cf-1a3f-4e64-9636-fce4accc9011" - }, - "unlocklist": { - "": [{ - "complete": 1, - "unlock_key": "worldvanquisher|2|0" - }, { - "complete": 1, - "unlock_key": "worldvanquisher|1|0" - }, { - "complete": 1, - "unlock_key": "worldexecuteme|2|0" - }, { - "complete": 1, - "unlock_key": "viciousheroism|2|0" - }, { - "complete": 1, - "unlock_key": "vector|2|0" - }, { - "complete": 1, - "unlock_key": "valhallazero|2|0" - }, { - "complete": 1, - "unlock_key": "tiferet|1|0" - }, { - "complete": 1, - "unlock_key": "tiemedowngently|1|0" - }, { - "complete": 1, - "unlock_key": "tempestissimo|0|101" - }, { - "complete": 1, - "unlock_key": "syro|2|0" - }, { - "complete": 1, - "unlock_key": "suomi|1|0" - }, { - "complete": 1, - "unlock_key": "solitarydream|2|0" - }, { - "complete": 1, - "unlock_key": "snowwhite|2|0" - }, { - "complete": 1, - "unlock_key": "sheriruth|2|0" - }, { - "complete": 1, - "unlock_key": "senkyou|2|0" - }, { - "complete": 1, - "unlock_key": "senkyou|1|0" - }, { - "complete": 1, - "unlock_key": "scarletlance|2|0" - }, { - "complete": 1, - "unlock_key": "scarletlance|1|0" - }, { - "complete": 1, - "unlock_key": "rugie|2|0" - }, { - "complete": 1, - "unlock_key": "rugie|1|0" - }, { - "complete": 1, - "unlock_key": "rise|2|0" - }, { - "complete": 1, - "unlock_key": "revixy|2|0" - }, { - "complete": 1, - "unlock_key": "reinvent|2|0" - }, { - "complete": 1, - "unlock_key": "reinvent|1|0" - }, { - "complete": 1, - "unlock_key": "redandblue|2|0" - }, { - "complete": 1, - "unlock_key": "redandblue|1|0" - }, { - "complete": 1, - "unlock_key": "rabbitintheblackroom|2|0" - }, { - "complete": 1, - "unlock_key": "rabbitintheblackroom|1|0" - }, { - "complete": 1, - "unlock_key": "worldexecuteme|1|0" - }, { - "complete": 1, - "unlock_key": "ringedgenesis|2|0" - }, { - "complete": 1, - "unlock_key": "quon|1|0" - }, { - "complete": 1, - "unlock_key": "qualia|2|0" - }, { - "complete": 1, - "unlock_key": "purgatorium|2|0" - }, { - "complete": 1, - "unlock_key": "supernova|2|0" - }, { - "complete": 1, - "unlock_key": "saikyostronger|2|3|einherjar|2" - }, { - "complete": 1, - "unlock_key": "purgatorium|1|0" - }, { - "complete": 1, - "unlock_key": "pragmatism|2|0" - }, { - "complete": 1, - "unlock_key": "ouroboros|2|0" - }, { - "complete": 1, - "unlock_key": "ouroboros|1|0" - }, { - "complete": 1, - "unlock_key": "oracle|1|0" - }, { - "complete": 1, - "unlock_key": "onelastdrive|2|0" - }, { - "complete": 1, - "unlock_key": "onelastdrive|1|0" - }, { - "complete": 1, - "unlock_key": "oblivia|2|0" - }, { - "complete": 1, - "unlock_key": "memoryforest|1|0" - }, { - "complete": 1, - "unlock_key": "melodyoflove|2|0" - }, { - "complete": 1, - "unlock_key": "saikyostronger|2|3|laqryma|2" - }, { - "complete": 1, - "unlock_key": "melodyoflove|1|0" - }, { - "complete": 1, - "unlock_key": "lucifer|2|0" - }, { - "complete": 1, - "unlock_key": "saikyostronger|2|3|izana|2" - }, { - "complete": 1, - "unlock_key": "halcyon|1|0" - }, { - "complete": 1, - "unlock_key": "memoryforest|2|0" - }, { - "complete": 1, - "unlock_key": "tiemedowngently|2|0" - }, { - "complete": 1, - "unlock_key": "lostdesire|1|0" - }, { - "complete": 1, - "unlock_key": "viciousheroism|1|0" - }, { - "complete": 1, - "unlock_key": "flyburg|1|0" - }, { - "complete": 1, - "unlock_key": "lostcivilization|2|0" - }, { - "complete": 1, - "unlock_key": "infinityheaven|1|0" - }, { - "complete": 1, - "unlock_key": "lostdesire|2|0" - }, { - "complete": 1, - "unlock_key": "ignotus|2|0" - }, { - "complete": 1, - "unlock_key": "harutopia|2|0" - }, { - "complete": 1, - "unlock_key": "revixy|1|0" - }, { - "complete": 1, - "unlock_key": "aterlbus|1|0" - }, { - "complete": 1, - "unlock_key": "linearaccelerator|2|0" - }, { - "complete": 1, - "unlock_key": "guardina|2|0" - }, { - "complete": 1, - "unlock_key": "corpssansorganes|2|0" - }, { - "complete": 1, - "unlock_key": "linearaccelerator|1|0" - }, { - "complete": 1, - "unlock_key": "guardina|1|0" - }, { - "complete": 1, - "unlock_key": "saikyostronger|2|0" - }, { - "complete": 1, - "unlock_key": "guardina|0|0" - }, { - "complete": 1, - "unlock_key": "valhallazero|1|0" - }, { - "complete": 1, - "unlock_key": "grimheart|1|0" - }, { - "complete": 1, - "unlock_key": "blaster|2|0" - }, { - "complete": 1, - "unlock_key": "grievouslady|2|101" - }, { - "complete": 1, - "unlock_key": "partyvinyl|2|0" - }, { - "complete": 1, - "unlock_key": "darakunosono|1|0" - }, { - "complete": 1, - "unlock_key": "grievouslady|1|101" - }, { - "complete": 1, - "unlock_key": "goodtek|1|0" - }, { - "complete": 1, - "unlock_key": "tempestissimo|3|101" - }, { - "complete": 1, - "unlock_key": "chronostasis|2|0" - }, { - "complete": 1, - "unlock_key": "gloryroad|2|0" - }, { - "complete": 1, - "unlock_key": "supernova|1|0" - }, { - "complete": 1, - "unlock_key": "singularity|2|0" - }, { - "complete": 1, - "unlock_key": "gloryroad|0|0" - }, { - "complete": 1, - "unlock_key": "shadesoflight|1|0" - }, { - "complete": 1, - "unlock_key": "kanagawa|2|0" - }, { - "complete": 1, - "unlock_key": "genesis|1|0" - }, { - "complete": 1, - "unlock_key": "fractureray|1|101" - }, { - "complete": 1, - "unlock_key": "freefall|2|0" - }, { - "complete": 1, - "unlock_key": "babaroque|1|0" - }, { - "complete": 1, - "unlock_key": "monochromeprincess|2|0" - }, { - "complete": 1, - "unlock_key": "flyburg|2|0" - }, { - "complete": 1, - "unlock_key": "shadesoflight|2|0" - }, { - "complete": 1, - "unlock_key": "espebranch|2|0" - }, { - "complete": 1, - "unlock_key": "qualia|1|0" - }, { - "complete": 1, - "unlock_key": "etherstrike|2|0" - }, { - "complete": 1, - "unlock_key": "tempestissimo|1|101" - }, { - "complete": 1, - "unlock_key": "conflict|1|0" - }, { - "complete": 1, - "unlock_key": "nhelv|1|0" - }, { - "complete": 1, - "unlock_key": "etherstrike|1|0" - }, { - "complete": 1, - "unlock_key": "syro|1|0" - }, { - "complete": 1, - "unlock_key": "anokumene|2|0" - }, { - "complete": 1, - "unlock_key": "essenceoftwilight|2|0" - }, { - "complete": 1, - "unlock_key": "snowwhite|1|0" - }, { - "complete": 1, - "unlock_key": "partyvinyl|1|0" - }, { - "complete": 1, - "unlock_key": "axiumcrisis|1|0" - }, { - "complete": 1, - "unlock_key": "ifi|2|0" - }, { - "complete": 1, - "unlock_key": "espebranch|1|0" - }, { - "complete": 1, - "unlock_key": "lostcivilization|1|0" - }, { - "complete": 1, - "unlock_key": "goodtek|2|0" - }, { - "complete": 1, - "unlock_key": "dandelion|2|0" - }, { - "complete": 1, - "unlock_key": "suomi|2|0" - }, { - "complete": 1, - "unlock_key": "dandelion|1|0" - }, { - "complete": 1, - "unlock_key": "oblivia|1|0" - }, { - "complete": 1, - "unlock_key": "cyberneciacatharsis|1|0" - }, { - "complete": 1, - "unlock_key": "quon|2|0" - }, { - "complete": 1, - "unlock_key": "bookmaker|2|0" - }, { - "complete": 1, - "unlock_key": "chronostasis|1|0" - }, { - "complete": 1, - "unlock_key": "heavensdoor|1|0" - }, { - "complete": 1, - "unlock_key": "tempestissimo|2|101" - }, { - "complete": 1, - "unlock_key": "cyaegha|2|0" - }, { - "complete": 1, - "unlock_key": "axiumcrisis|2|0" - }, { - "complete": 1, - "unlock_key": "blrink|2|0" - }, { - "complete": 1, - "unlock_key": "rise|1|0" - }, { - "complete": 1, - "unlock_key": "cyanine|1|0" - }, { - "complete": 1, - "unlock_key": "ifi|1|0" - }, { - "complete": 1, - "unlock_key": "aterlbus|2|0" - }, { - "complete": 1, - "unlock_key": "dreaminattraction|2|0" - }, { - "complete": 1, - "unlock_key": "bookmaker|1|0" - }, { - "complete": 1, - "unlock_key": "lucifer|1|0" - }, { - "complete": 1, - "unlock_key": "solitarydream|1|0" - }, { - "complete": 1, - "unlock_key": "ringedgenesis|1|0" - }, { - "complete": 1, - "unlock_key": "corpssansorganes|1|0" - }, { - "complete": 1, - "unlock_key": "vector|1|0" - }, { - "complete": 1, - "unlock_key": "infinityheaven|2|0" - }, { - "complete": 1, - "unlock_key": "essenceoftwilight|1|0" - }, { - "complete": 1, - "unlock_key": "conflict|2|0" - }, { - "complete": 1, - "unlock_key": "singularity|1|0" - }, { - "complete": 1, - "unlock_key": "harutopia|1|0" - }, { - "complete": 1, - "unlock_key": "cyberneciacatharsis|2|0" - }, { - "complete": 1, - "unlock_key": "oracle|2|0" - }, { - "complete": 1, - "unlock_key": "clotho|2|0" - }, { - "complete": 1, - "unlock_key": "corpssansorganes|0|0" - }, { - "complete": 1, - "unlock_key": "ignotus|1|0" - }, { - "complete": 1, - "unlock_key": "monochromeprincess|1|0" - }, { - "complete": 1, - "unlock_key": "nirvluce|1|0" - }, { - "complete": 1, - "unlock_key": "lethaeus|1|0" - }, { - "complete": 1, - "unlock_key": "clotho|1|0" - }, { - "complete": 1, - "unlock_key": "blaster|1|0" - }, { - "complete": 1, - "unlock_key": "fractureray|0|101" - }, { - "complete": 1, - "unlock_key": "kanagawa|1|0" - }, { - "complete": 1, - "unlock_key": "darakunosono|2|0" - }, { - "complete": 1, - "unlock_key": "freefall|1|0" - }, { - "complete": 1, - "unlock_key": "nirvluce|2|0" - }, { - "complete": 1, - "unlock_key": "cyanine|2|0" - }, { - "complete": 1, - "unlock_key": "heavensdoor|2|0" - }, { - "complete": 1, - "unlock_key": "genesis|2|0" - }, { - "complete": 1, - "unlock_key": "pragmatism|1|0" - }, { - "complete": 1, - "unlock_key": "nhelv|2|0" - }, { - "complete": 1, - "unlock_key": "halcyon|2|0" - }, { - "complete": 1, - "unlock_key": "blrink|1|0" - }, { - "complete": 1, - "unlock_key": "fractureray|2|101" - }, { - "complete": 1, - "unlock_key": "lethaeus|2|0" - }, { - "complete": 1, - "unlock_key": "sheriruth|1|0" - }, { - "complete": 1, - "unlock_key": "babaroque|2|0" - }, { - "complete": 1, - "unlock_key": "tiferet|2|0" - }, { - "complete": 1, - "unlock_key": "grimheart|2|0" - }, { - "complete": 1, - "unlock_key": "cyaegha|1|0" - }, { - "complete": 1, - "unlock_key": "aiueoon|2|0" - }, { - "complete": 1, - "unlock_key": "gloryroad|1|0" - }, { - "complete": 1, - "unlock_key": "anokumene|1|0" - }, { - "complete": 1, - "unlock_key": "grievouslady|0|101" - }, { - "complete": 1, - "unlock_key": "dreaminattraction|1|0" - }] - }, "clearedsongs": { - "": song_1 - }, - "clearlamps": { - "": song_2 - }, - "scores": { - "": song_3 - }, - "version": { - "val": 1 - } - } diff --git a/v1.2/server/auth.py b/v1.2/server/auth.py deleted file mode 100644 index 22fe96e..0000000 --- a/v1.2/server/auth.py +++ /dev/null @@ -1,149 +0,0 @@ -import sqlite3 -import hashlib -import time - - -def arc_login(name: str, password: str) -> str: # 登录判断 - # 查询数据库中的user表,验证账号密码,返回并记录token - # token采用user_id和时间戳连接后hash生成(真的是瞎想的,没用bear) - # 密码和token的加密方式为 SHA-256 - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest() - c.execute('''select user_id from user where name = :name and password = :password''', { - 'name': name, 'password': hash_pwd}) - x = c.fetchone() - if x is not None: - user_id = str(x[0]) - now = int(time.time() * 1000) - token = hashlib.sha256((user_id + str(now)).encode("utf8")).hexdigest() - c.execute( - '''select exists(select * from login where user_id = :user_id)''', {"user_id": user_id}) - - if c.fetchone() == (1,): # 删掉多余token - c.execute('''delete from login where user_id = :user_id''', - {'user_id': user_id}) - - c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', { - 'user_id': user_id, 'access_token': token}) - conn.commit() - conn.close() - return token - - conn.commit() - conn.close() - return None - - -def arc_register(name: str, password: str): # 注册 - # 账号注册,只记录hash密码和用户名,生成user_id和user_code,自动登录返回token - # token和密码的处理同登录部分 - - def build_user_code(c): - # 生成9位的user_code,用的自然是随机 - import random - flag = True - while flag: - user_code = ''.join([str(random.randint(0, 9)) for i in range(9)]) - c.execute('''select exists(select * from user where user_code = :user_code)''', - {'user_code': user_code}) - if c.fetchone() == (0,): - flag = False - return user_code - - def build_user_id(c): - # 生成user_id,往后加1 - c.execute('''select max(user_id) from user''') - x = c.fetchone() - if x[0] is not None: - return x[0] + 1 - else: - return 2000001 - - # def insert_user_char(c, user_id): - # # 为用户添加所有可用角色 - # for i in range(0, 38): - # if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21]: - # sql = 'insert into user_char values('+str(user_id)+','+str( - # i)+''',30,25000,25000,90,90,90,'',0,0,'',0,1,1)''' - # c.execute(sql) - # else: - # if i != 5: - # sql = 'insert into user_char values('+str(user_id)+','+str( - # i)+''',30,25000,25000,90,90,90,'',0,0,'',0,0,0)''' - # c.execute(sql) - def insert_user_char(c, user_id): - # 为用户添加所有可用角色 - c.execute('''select * from character''') - x = c.fetchall() - if x != []: - for i in x: - c.execute('''insert into user_char values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n,:o)''', { - 'a': user_id, 'b': i[0], 'c': i[2], 'd': i[3], 'e': i[4], 'f': i[5], 'g': i[6], 'h': i[7], 'i': i[8], 'j': i[9], 'k': i[10], 'l': i[11], 'm': i[12], 'n': i[14], 'o': i[15]}) - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest() - c.execute( - '''select exists(select * from user where name = :name)''', {'name': name}) - if c.fetchone() == (0,): - user_code = build_user_code(c) - user_id = build_user_id(c) - now = int(time.time() * 1000) - c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt, - character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled) - values(:user_id, :name, :password, :join_date, :user_code, 0, 0, 0, 0, 0, 0, -1, 0) - ''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd}) - c.execute('''insert into recent30(user_id) values(:user_id)''', { - 'user_id': user_id}) - - token = hashlib.sha256( - (str(user_id) + str(now)).encode("utf8")).hexdigest() - c.execute('''insert into login(access_token, user_id) values(:access_token, :user_id)''', { - 'user_id': user_id, 'access_token': token}) - - insert_user_char(c, user_id) - conn.commit() - conn.close() - return user_id, token, 0 - else: - conn.commit() - conn.close() - return None, None, 101 - - -def token_get_id(token: str): - # 用token获取id,没有考虑不同用户token相同情况,说不定会有bug - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select user_id from login where access_token = :token''', { - 'token': token}) - x = c.fetchone() - if x is not None: - conn.commit() - conn.close() - return x[0] - else: - conn.commit() - conn.close() - return None - - -def code_get_id(user_code): - # 用user_code获取id - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select user_id from user where user_code = :a''', - {'a': user_code}) - x = c.fetchone() - if x is not None: - conn.commit() - conn.close() - return x[0] - else: - conn.commit() - conn.close() - return None diff --git a/v1.2/server/info.py b/v1.2/server/info.py deleted file mode 100644 index 72958f6..0000000 --- a/v1.2/server/info.py +++ /dev/null @@ -1,4060 +0,0 @@ -import sqlite3 - - -def int2b(x): - # int与布尔值转换 - if x is None or x == 0: - return False - else: - return True - - -def get_recent_score(c, user_id): - # 得到用户最近一次的成绩,返回列表 - c.execute('''select * from user where user_id = :x''', {'x': user_id}) - x = c.fetchone() - if x is not None: - if x[11] is not None: - c.execute('''select best_clear_type from best_score where user_id=:u and song_id=:s and difficulty=:d''', { - 'u': user_id, 's': x[11], 'd': x[12]}) - y = c.fetchone() - if y is not None: - best_clear_type = y[0] - else: - best_clear_type = x[21] - - return [{ - "rating": x[22], - "modifier": x[19], - "time_played": x[20], - "health": x[18], - "best_clear_type": best_clear_type, - "clear_type": x[21], - "miss_count": x[17], - "near_count": x[16], - "perfect_count": x[15], - "shiny_perfect_count": x[14], - "score": x[13], - "difficulty": x[12], - "song_id": x[11] - }] - return [] - - -def get_user_character(c, user_id): - # 得到用户拥有的角色列表,返回列表 - c.execute('''select * from user_char where user_id = :user_id''', - {'user_id': user_id}) - x = c.fetchall() - if x != []: - s = [] - for i in x: - char_name = '' - c.execute( - '''select name from character where character_id = :x''', {'x': i[1]}) - y = c.fetchone() - if y is not None: - char_name = y[0] - s.append({ - "is_uncapped_override": int2b(i[14]), - "is_uncapped": int2b(i[13]), - "uncap_cores": [], - "char_type": i[12], - "skill_id_uncap": i[11], - "skill_requires_uncap": int2b(i[10]), - "skill_unlock_level": i[9], - "skill_id": i[8], - "overdrive": i[7], - "prog": i[6], - "frag": i[5], - "level_exp": i[4], - "exp": i[3], - "level": i[2], - "name": char_name, - "character_id": i[1] - }) - - return s - else: - return [] - - -def get_user_friend(c, user_id): - # 得到用户的朋友列表,返回列表 - c.execute('''select user_id_other from friend where user_id_me = :user_id''', { - 'user_id': user_id}) - x = c.fetchall() - s = [] - if x != [] and x[0][0] is not None: - - for i in x: - c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''', - {'x': i[0], 'y': user_id}) - if c.fetchone() == (1,): - is_mutual = True - else: - is_mutual = False - - c.execute('''select * from user where user_id = :x''', {'x': i[0]}) - y=c.fetchone() - if y is not None: - s.append({ - "is_mutual": is_mutual, - "is_char_uncapped_override": int2b(y[9]), - "is_char_uncapped": int2b(y[8]), - "is_skill_sealed": int2b(y[7]), - "rating": y[5], - "join_date": int(y[3]), - "character": y[6], - "recent_score": get_recent_score(c, i[0]), - "name": y[1], - "user_id": i[0] - }) - - return s - - -def get_value_0(c, user_id): - # 构造value id=0的数据,返回字典 - c.execute('''select * from user where user_id = :x''', {'x': user_id}) - x = c.fetchone() - r = {} - if x is not None: - r = {"is_aprilfools": False, - "curr_available_maps": [], - "character_stats": get_user_character(c, user_id), - "friends": get_user_friend(c, user_id), - "settings": { - "favorite_character": x[23], - "is_hide_rating": int2b(x[10]), - "max_stamina_notification_enabled": int2b(x[24]) - }, - "user_id": user_id, - "name": x[1], - "user_code": x[4], - "display_name": x[1], - "ticket": 114514, - "character": x[6], - "is_locked_name_duplicate": False, - "is_skill_sealed": int2b(x[7]), - "current_map": "", - "prog_boost": 0, - "next_fragstam_ts": -1, - "max_stamina_ts": 1586274871917, - "stamina": 0, - "world_unlocks": [], - "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"], - "singles": [], - "packs": [], - "characters":[0,1,2,3,4]+[x for x in range(6, 38)], - "cores": [], - "recent_score": get_recent_score(c, user_id), - "max_friend": 50, - "rating": x[5], - "join_date": int(x[3]) - } - - return r - - -def arc_aggregate_small(user_id): - # 返回用户数据 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - r = {"success": True, - "value": [{ - "id": 0, - "value": get_value_0(c, user_id) - }]} - - conn.commit() - conn.close() - return r - - -def arc_aggregate_big(user_id): - # 返回用户数据和地图歌曲信息 - # 因为没有整理地图和曲包数据(不需要世界模式),所以直接复制了 - - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - r = {"success": True, - "value": [{ - "id": 0, - "value": get_value_0(c, user_id) - }, { - "id": 1, - "value": [{ - "name": "core", - "items": [{ - "id": "core", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "shiawase", - "items": [{ - "id": "shiawase", - "type": "pack", - "is_available": True - }, { - "id": "kou", - "type": "character", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1552089600000, - "discount_to": 1552694399000 - }, { - "name": "dynamix", - "items": [{ - "id": "dynamix", - "type": "pack", - "is_available": True - }, { - "id": "sapphire", - "type": "character", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "mirai", - "items": [{ - "id": "mirai", - "type": "pack", - "is_available": True - }, { - "id": "lethe", - "type": "character", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1552089600000, - "discount_to": 1552694399000 - }, { - "name": "yugamu", - "items": [{ - "id": "yugamu", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "lanota", - "items": [{ - "id": "lanota", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "nijuusei", - "items": [{ - "id": "nijuusei", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "rei", - "items": [{ - "id": "rei", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "tonesphere", - "items": [{ - "id": "tonesphere", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "groovecoaster", - "items": [{ - "id": "groovecoaster", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "zettai", - "items": [{ - "id": "zettai", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500, - "discount_from": 1583712000000, - "discount_to": 1584316799000 - }, { - "name": "chunithm", - "items": [{ - "id": "chunithm", - "type": "pack", - "is_available": True - }], - "price": 300, - "orig_price": 300 - }, { - "name": "prelude", - "items": [{ - "id": "prelude", - "type": "pack", - "is_available": True - }], - "price": 400, - "orig_price": 400 - }, { - "name": "omatsuri", - "items": [{ - "id": "omatsuri", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500 - }, { - "name": "vs", - "items": [{ - "id": "vs", - "type": "pack", - "is_available": True - }], - "price": 500, - "orig_price": 500 - }, { - "name": "extend", - "items": [{ - "id": "extend", - "type": "pack", - "is_available": True - }], - "price": 700, - "orig_price": 700 - }] - }, { - "id": 2, - "value": {} - }, { - "id": 3, - "value": { - "max_stamina": 12, - "stamina_recover_tick": 1800000, - "core_exp": 250, - "curr_ts": 1599547606825, - "level_steps": [{ - "level": 1, - "level_exp": 0 - }, { - "level": 2, - "level_exp": 50 - }, { - "level": 3, - "level_exp": 100 - }, { - "level": 4, - "level_exp": 150 - }, { - "level": 5, - "level_exp": 200 - }, { - "level": 6, - "level_exp": 300 - }, { - "level": 7, - "level_exp": 450 - }, { - "level": 8, - "level_exp": 650 - }, { - "level": 9, - "level_exp": 900 - }, { - "level": 10, - "level_exp": 1200 - }, { - "level": 11, - "level_exp": 1600 - }, { - "level": 12, - "level_exp": 2100 - }, { - "level": 13, - "level_exp": 2700 - }, { - "level": 14, - "level_exp": 3400 - }, { - "level": 15, - "level_exp": 4200 - }, { - "level": 16, - "level_exp": 5100 - }, { - "level": 17, - "level_exp": 6100 - }, { - "level": 18, - "level_exp": 7200 - }, { - "level": 19, - "level_exp": 8500 - }, { - "level": 20, - "level_exp": 10000 - }, { - "level": 21, - "level_exp": 11500 - }, { - "level": 22, - "level_exp": 13000 - }, { - "level": 23, - "level_exp": 14500 - }, { - "level": 24, - "level_exp": 16000 - }, { - "level": 25, - "level_exp": 17500 - }, { - "level": 26, - "level_exp": 19000 - }, { - "level": 27, - "level_exp": 20500 - }, { - "level": 28, - "level_exp": 22000 - }, { - "level": 29, - "level_exp": 23500 - }, { - "level": 30, - "level_exp": 25000 - }], - "world_ranking_enabled": False, - "is_byd_chapter_unlocked": True - } - }, { - "id": 4, - "value": [] - }, { - "id": 5, - "value": { - "user_id": user_id, - "current_map": "", - "maps": [{ - "map_id": "hikari_art", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "", - "require_value": 1, - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "-270,150", - "step_count": 91, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "babaroque", - "type": "world_song" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 27 - }, { - "items": [{ - "id": "shadesoflight", - "type": "world_song" - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 45 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 50 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 55 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 60 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 65 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 70 - }, { - "items": [{ - "id": "kanagawa", - "type": "world_song" - }], - "position": 75 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 80 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 85 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 90 - }] - }, { - "map_id": "hikari_happy", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "270,150", - "step_count": 136, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 5 - }, { - "items": [{ - "id": "harutopia", - "type": "world_song" - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 25 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 30 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 32 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 45 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 50 - }, { - "items": [{ - "id": "goodtek", - "type": "world_song" - }], - "position": 55 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 60 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 65 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 70 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 75 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 80 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 82 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 85 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 90 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 95 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 97 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 100 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 105 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 110 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 115 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 120 - }, { - "items": [{ - "id": "dreaminattraction", - "type": "world_song" - }], - "position": 125 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 135 - }] - }, { - "map_id": "tairitsu_arcs", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "-270,-150", - "step_count": 136, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 5 - }, { - "items": [{ - "id": "rabbitintheblackroom", - "type": "world_song" - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 25 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 30 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 32 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 45 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 50 - }, { - "items": [{ - "id": "qualia", - "type": "world_song" - }], - "position": 55 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 60 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 65 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 70 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 75 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 80 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 82 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 85 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 90 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 95 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 97 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 100 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 105 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 110 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 115 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 120 - }, { - "items": [{ - "id": "redandblue", - "type": "world_song" - }], - "position": 125 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 135 - }] - }, { - "map_id": "tairitsu_tech", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "", - "require_value": 1, - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "270,-150", - "step_count": 91, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "lucifer", - "type": "world_song" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 27 - }, { - "items": [{ - "id": "anokumene", - "type": "world_song" - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 45 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 50 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 55 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 60 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 65 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 70 - }, { - "items": [{ - "id": "ignotus", - "type": "world_song" - }], - "position": 75 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 80 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 85 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 90 - }] - }, { - "map_id": "eternal", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "core", - "require_type": "pack", - "require_value": 1, - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "-500,0", - "step_count": 66, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 10 - }, { - "items": [{ - "id": "essenceoftwilight", - "type": "world_song" - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 28 - }, { - "items": [{ - "type": "fragment", - "amount": 200 - }], - "position": 35 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 42 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 44 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 46 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 48 - }, { - "items": [{ - "id": "pragmatism", - "type": "world_song" - }], - "position": 50 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 52 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 54 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 56 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 58 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 60 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 62 - }, { - "items": [{ - "id": "sheriruth", - "type": "world_song" - }], - "position": 65 - }] - }, { - "map_id": "axiumcrisis", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "yugamu", - "require_type": "pack", - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "500,0", - "step_count": 61, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 5 - }, { - "items": [{ - "id": "axiumcrisis", - "type": "world_song" - }], - "position": 10 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 24 - }, { - "items": [{ - "type": "fragment", - "amount": 200 - }], - "position": 30 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 37 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 39 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 41 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 43 - }, { - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 45 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 51 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 53 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 55 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 57 - }, { - "items": [{ - "id": "6", - "type": "character" - }], - "position": 60 - }] - }, { - "map_id": "grievouslady", - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "yugamu", - "require_type": "pack", - "require_localunlock_songid": "grievouslady", - "is_legacy": True, - "stamina_cost": 1, - "coordinate": "0,-150", - "step_count": 21, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 300 - }], - "position": 18 - }, { - "items": [{ - "id": "7", - "type": "character" - }], - "position": 20 - }] - }, { - "map_id": "lanota", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "lanota", - "require_type": "pack", - "coordinate": "460,-160", - "step_count": 35, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 40 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 10 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 12 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 80 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 27 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 33 - }, { - "items": [{ - "id": "9", - "type": "character" - }], - "position": 34 - }] - }, { - "map_id": "nijuusei_light", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "nijuusei", - "require_type": "pack", - "coordinate": "-260,160", - "step_count": 22, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 175 - }], - "position": 10 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 178 - }], - "position": 20 - }, { - "items": [{ - "id": "11", - "type": "character" - }], - "position": 21 - }] - }, { - "map_id": "nijuusei_conflict", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "nijuusei", - "require_type": "pack", - "require_localunlock_challengeid": "singularity", - "coordinate": "260,160", - "step_count": 36, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 175 - }], - "position": 2 - }, { - "items": [{ - "type": "fragment", - "amount": 175 - }], - "position": 3 - }, { - "items": [{ - "type": "fragment", - "amount": 175 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 178 - }], - "position": 5 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 6 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 7 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 8 - }, { - "items": [{ - "id": "12", - "type": "character" - }], - "position": 35 - }] - }, { - "map_id": "extra_originals", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "", - "require_value": 1, - "coordinate": "0,-200", - "step_count": 101, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 29 - }, { - "items": [{ - "id": "syro", - "type": "world_song" - }], - "position": 30 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 31 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 80 - }], - "position": 45 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 50 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 55 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 59 - }, { - "items": [{ - "id": "blaster", - "type": "world_song" - }], - "position": 60 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 61 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 65 - }, { - "items": [{ - "type": "fragment", - "amount": 80 - }], - "position": 70 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 75 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 80 - }, { - "items": [{ - "type": "fragment", - "amount": 80 - }], - "position": 85 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 90 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 94 - }, { - "items": [{ - "id": "cyberneciacatharsis", - "type": "world_song" - }], - "position": 95 - }, { - "items": [{ - "type": "core", - "id": "core_crimson", - "amount": 5 - }], - "position": 98 - }, { - "items": [{ - "type": "core", - "id": "core_crimson", - "amount": 5 - }], - "position": 100 - }] - }, { - "map_id": "guardina", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "dynamix", - "require_type": "pack", - "coordinate": "-460,-160", - "step_count": 35, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 1 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 9 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 16 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 17 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 18 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 25 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 33 - }, { - "items": [{ - "id": "guardina", - "type": "world_song" - }], - "position": 34 - }] - }, { - "map_id": "etherstrike", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "rei", - "require_type": "pack", - "coordinate": "0,-40", - "step_count": 36, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 5 - }, { - "items": [{ - "id": "etherstrike", - "type": "world_song" - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 26 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 27 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 28 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 29 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 31 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 32 - }, { - "items": [{ - "type": "fragment", - "amount": 0 - }], - "position": 33 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 34 - }, { - "items": [{ - "id": "14", - "type": "character" - }], - "position": 35 - }] - }, { - "map_id": "fractureray", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "rei", - "require_type": "pack", - "require_localunlock_songid": "fractureray", - "coordinate": "0,160", - "step_count": 23, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 13 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 16 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 17 - }, { - "items": [{ - "type": "fragment", - "amount": 350 - }], - "position": 19 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 20 - }, { - "items": [{ - "id": "15", - "type": "character" - }], - "position": 22 - }] - }, { - "map_id": "chapter3_light", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-480,180", - "step_count": 76, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 144 - }], - "position": 10 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 13 - }, { - "items": [{ - "type": "fragment", - "amount": 169 - }], - "position": 20 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 23 - }, { - "items": [{ - "id": "suomi", - "type": "world_song" - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 225 - }], - "position": 40 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 43 - }, { - "items": [{ - "type": "fragment", - "amount": 256 - }], - "position": 50 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 53 - }, { - "items": [{ - "id": "rugie", - "type": "world_song" - }], - "position": 59 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 65 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 70 - }, { - "items": [{ - "type": "core", - "id": "core_hollow", - "amount": 5 - }], - "position": 75 - }] - }, { - "map_id": "chapter3_conflict", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-360,0", - "step_count": 85, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 10 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 19 - }, { - "items": [{ - "type": "fragment", - "amount": 15 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 25 - }, { - "items": [{ - "id": "bookmaker", - "type": "world_song" - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 200 - }], - "position": 35 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 39 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 45 - }, { - "items": [{ - "id": "darakunosono", - "type": "world_song" - }], - "position": 49 - }, { - "items": [{ - "type": "fragment", - "amount": 30 - }], - "position": 50 - }, { - "items": [{ - "type": "fragment", - "amount": 300 - }], - "position": 55 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 3 - }], - "position": 59 - }, { - "items": [{ - "type": "fragment", - "amount": 40 - }], - "position": 60 - }, { - "items": [{ - "id": "espebranch", - "type": "world_song" - }], - "position": 62 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 70 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 75 - }, { - "items": [{ - "type": "core", - "id": "core_desolate", - "amount": 5 - }], - "position": 84 - }] - }, { - "map_id": "chapter3_conflict_2", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-240,-180", - "step_count": 51, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 125 - }], - "position": 9 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 125 - }], - "position": 19 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 24 - }, { - "items": [{ - "type": "fragment", - "amount": 125 - }], - "position": 29 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 34 - }, { - "items": [{ - "type": "fragment", - "amount": 125 - }], - "position": 39 - }, { - "items": [{ - "id": "nhelv", - "type": "world_song" - }], - "position": 40 - }, { - "items": [{ - "type": "core", - "id": "core_ambivalent", - "amount": 5 - }], - "position": 45 - }, { - "items": [{ - "type": "core", - "id": "core_ambivalent", - "amount": 5 - }], - "position": 50 - }] - }, { - "map_id": "tonesphere", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "tonesphere", - "require_type": "pack", - "coordinate": "480,180", - "step_count": 38, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 4 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 22 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 28 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 32 - }, { - "items": [{ - "id": "18", - "type": "character" - }], - "position": 37 - }] - }, { - "map_id": "groovecoaster", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "groovecoaster", - "require_type": "pack", - "coordinate": "360,0", - "step_count": 46, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 55 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 66 - }], - "position": 23 - }, { - "items": [{ - "type": "fragment", - "amount": 77 - }], - "position": 29 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 88 - }], - "position": 34 - }, { - "items": [{ - "type": "fragment", - "amount": 99 - }], - "position": 39 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 40 - }, { - "items": [{ - "id": "22", - "type": "character" - }], - "position": 45 - }] - }, { - "map_id": "solitarydream", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 5, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "core", - "require_type": "pack", - "coordinate": "-250,0", - "step_count": 10, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "solitarydream", - "type": "world_song" - }], - "position": 9 - }] - }, { - "map_id": "zettai", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "zettai", - "require_type": "pack", - "coordinate": "-100,115", - "step_count": 26, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 20 - }, { - "items": [{ - "id": "23", - "type": "character" - }], - "position": 25 - }] - }, { - "map_id": "chapter4_ripples", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-280,-200", - "step_count": 51, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 170 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 170 - }], - "position": 12 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 16 - }, { - "items": [{ - "id": "grimheart", - "type": "world_song" - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 190 - }], - "position": 26 - }, { - "items": [{ - "type": "fragment", - "amount": 190 - }], - "position": 42 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 46 - }, { - "items": [{ - "id": "vector", - "type": "world_song" - }], - "position": 50 - }] - }, { - "map_id": "chapter4_waves", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-480,-200", - "step_count": 41, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 5 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 8 - }, { - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 18 - }, { - "items": [{ - "id": "revixy", - "type": "world_song" - }], - "position": 25 - }, { - "items": [{ - "type": "fragment", - "amount": 400 - }], - "position": 30 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 33 - }, { - "items": [{ - "id": "supernova", - "type": "world_song" - }], - "position": 40 - }] - }, { - "map_id": "chunithm", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "chunithm", - "require_type": "pack", - "coordinate": "480,200", - "step_count": 28, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 110 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 120 - }], - "position": 10 - }, { - "items": [{ - "id": "worldvanquisher", - "type": "world_song" - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 20 - }, { - "items": [{ - "id": "24", - "type": "character" - }], - "position": 27 - }] - }, { - "map_id": "omatsuri", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "omatsuri", - "require_type": "pack", - "coordinate": "280,200", - "step_count": 21, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 230 - }], - "position": 3 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 6 - }, { - "items": [{ - "type": "fragment", - "amount": 230 - }], - "position": 9 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 12 - }, { - "items": [{ - "id": "30", - "type": "character" - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 20 - }] - }, { - "map_id": "chapter4_the_calm", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "", - "require_type": "fragment", - "require_value": 200, - "coordinate": "-380,-30", - "step_count": 146, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 10 - }], - "position": 1 - }, { - "items": [{ - "type": "fragment", - "amount": 10 - }], - "position": 2 - }, { - "items": [{ - "type": "fragment", - "amount": 10 - }], - "position": 3 - }, { - "items": [{ - "type": "fragment", - "amount": 10 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 15 - }], - "position": 11 - }, { - "items": [{ - "type": "fragment", - "amount": 15 - }], - "position": 12 - }, { - "items": [{ - "type": "fragment", - "amount": 15 - }], - "position": 13 - }, { - "items": [{ - "type": "fragment", - "amount": 15 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 20 - }], - "position": 21 - }, { - "items": [{ - "type": "fragment", - "amount": 20 - }], - "position": 22 - }, { - "items": [{ - "type": "fragment", - "amount": 20 - }], - "position": 23 - }, { - "items": [{ - "type": "fragment", - "amount": 20 - }], - "position": 24 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 31 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 32 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 33 - }, { - "items": [{ - "type": "fragment", - "amount": 25 - }], - "position": 34 - }, { - "items": [{ - "type": "fragment", - "amount": 30 - }], - "position": 41 - }, { - "items": [{ - "type": "fragment", - "amount": 30 - }], - "position": 42 - }, { - "items": [{ - "type": "fragment", - "amount": 30 - }], - "position": 43 - }, { - "items": [{ - "type": "fragment", - "amount": 30 - }], - "position": 44 - }, { - "items": [{ - "type": "fragment", - "amount": 35 - }], - "position": 51 - }, { - "items": [{ - "type": "fragment", - "amount": 35 - }], - "position": 52 - }, { - "items": [{ - "type": "fragment", - "amount": 35 - }], - "position": 53 - }, { - "items": [{ - "id": "diode", - "type": "world_song" - }], - "position": 54 - }, { - "items": [{ - "type": "fragment", - "amount": 40 - }], - "position": 62 - }, { - "items": [{ - "type": "fragment", - "amount": 40 - }], - "position": 64 - }, { - "items": [{ - "type": "fragment", - "amount": 45 - }], - "position": 72 - }, { - "items": [{ - "type": "fragment", - "amount": 45 - }], - "position": 74 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 82 - }, { - "items": [{ - "type": "fragment", - "amount": 50 - }], - "position": 84 - }, { - "items": [{ - "type": "fragment", - "amount": 55 - }], - "position": 92 - }, { - "items": [{ - "id": "freefall", - "type": "world_song" - }], - "position": 94 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 102 - }, { - "items": [{ - "type": "fragment", - "amount": 60 - }], - "position": 104 - }, { - "items": [{ - "type": "fragment", - "amount": 65 - }], - "position": 112 - }, { - "items": [{ - "type": "fragment", - "amount": 65 - }], - "position": 114 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 122 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 124 - }, { - "items": [{ - "type": "fragment", - "amount": 75 - }], - "position": 132 - }, { - "items": [{ - "id": "monochromeprincess", - "type": "world_song" - }], - "position": 134 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 3 - }], - "position": 145 - }] - }, { - "map_id": "gloryroad", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "shiawase", - "require_type": "pack", - "coordinate": "380,30", - "step_count": 28, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 1 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 11 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 14 - }, { - "items": [{ - "id": "gloryroad", - "type": "world_song" - }], - "position": 20 - }, { - "items": [{ - "type": "core", - "id": "core_crimson", - "amount": 5 - }], - "position": 23 - }, { - "items": [{ - "type": "core", - "id": "core_crimson", - "amount": 5 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_crimson", - "amount": 5 - }], - "position": 27 - }] - }, { - "map_id": "blrink", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 5, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "prelude", - "require_type": "pack", - "coordinate": "250,0", - "step_count": 17, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "blrink", - "type": "world_song" - }], - "position": 16 - }] - }, { - "map_id": "corpssansorganes", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 2106124800000, - "is_repeatable": False, - "require_id": "mirai", - "require_type": "pack", - "coordinate": "0,200", - "step_count": 42, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 105 - }], - "position": 6 - }, { - "items": [{ - "type": "fragment", - "amount": 105 - }], - "position": 12 - }, { - "items": [{ - "type": "fragment", - "amount": 105 - }], - "position": 22 - }, { - "items": [{ - "type": "fragment", - "amount": 105 - }], - "position": 28 - }, { - "items": [{ - "id": "corpssansorganes", - "type": "world_song" - }], - "position": 31 - }, { - "items": [{ - "type": "core", - "id": "core_ambivalent", - "amount": 5 - }], - "position": 35 - }, { - "items": [{ - "type": "core", - "id": "core_ambivalent", - "amount": 5 - }], - "position": 38 - }, { - "items": [{ - "type": "core", - "id": "core_ambivalent", - "amount": 5 - }], - "position": 41 - }] - }, { - "map_id": "lostdesire", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 5, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "vs", - "require_type": "pack", - "coordinate": "0,0", - "step_count": 36, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "lostdesire", - "type": "world_song" - }], - "position": 5 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 15 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 25 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 35 - }] - }, { - "map_id": "tempestissimo", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 5, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "vs", - "require_type": "pack", - "require_localunlock_challengeid": "tempestissimo", - "coordinate": "0,160", - "step_count": 16, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "id": "35", - "type": "character" - }], - "position": 3 - }, { - "items": [{ - "type": "fragment", - "amount": 1000 - }], - "position": 15 - }] - }, { - "map_id": "chapter_1_scenery", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 1, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": True, - "require_id": "", - "require_type": "chapter_step", - "require_value": 455, - "coordinate": "0,150", - "step_count": 51, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "world_unlock", - "id": "scenery_chap1" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 70 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 80 - }], - "position": 15 - }, { - "items": [{ - "type": "fragment", - "amount": 90 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 25 - }, { - "items": [{ - "type": "fragment", - "amount": 110 - }], - "position": 30 - }, { - "items": [{ - "type": "fragment", - "amount": 120 - }], - "position": 35 - }, { - "items": [{ - "type": "fragment", - "amount": 130 - }], - "position": 40 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 50 - }] - }, { - "map_id": "chapter_2_scenery", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 2, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": True, - "require_id": "", - "require_type": "chapter_step", - "require_value": 105, - "coordinate": "0,-20", - "step_count": 51, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "world_unlock", - "id": "scenery_chap2" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 11 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 12 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 13 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 14 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 31 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 32 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 33 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 34 - }, { - "items": [{ - "type": "fragment", - "amount": 150 - }], - "position": 50 - }] - }, { - "map_id": "chapter_3_scenery", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 3, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": True, - "require_id": "", - "require_type": "chapter_step", - "require_value": 205, - "coordinate": "240,-180", - "step_count": 17, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "world_unlock", - "id": "scenery_chap3" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 400 - }], - "position": 16 - }] - }, { - "map_id": "chapter_4_scenery", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 4, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": True, - "require_id": "", - "require_type": "chapter_step", - "require_value": 240, - "coordinate": "100,-115", - "step_count": 101, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "world_unlock", - "id": "scenery_chap4" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 2000 - }], - "position": 100 - }] - }, { - "map_id": "chapter_5_scenery", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 5, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": True, - "require_id": "", - "require_type": "chapter_step", - "require_value": 75, - "coordinate": "0,-160", - "step_count": 31, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "world_unlock", - "id": "scenery_chap5" - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 10 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 20 - }, { - "items": [{ - "type": "fragment", - "amount": 500 - }], - "position": 30 - }] - }, { - "map_id": "byd_goodtek", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "goodtek2", - "require_type": "chart_unlock", - "coordinate": "900,650", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 250, - "character_affinity": [0, 1], - "affinity_multiplier": [2.5, 1.5], - "step_count": 6, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 2 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 10 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 24 - }, { - "items": [{ - "type": "fragment", - "amount": 275 - }], - "position": 31 - }, { - "items": [{ - "id": "goodtek3", - "type": "world_song" - }], - "position": 33 - }] - }, { - "map_id": "byd_vexaria", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "vexaria2", - "require_type": "chart_unlock", - "coordinate": "650,400", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 150, - "character_affinity": [0, 1], - "affinity_multiplier": [2.5, 1.5], - "step_count": 3, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 616 - }], - "position": 42 - }, { - "items": [{ - "id": "vexaria3", - "type": "world_song" - }], - "position": 46 - }] - }, { - "map_id": "byd_fairytale", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "fairytale2", - "require_type": "chart_unlock", - "coordinate": "400,650", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 200, - "character_affinity": [0, 1], - "affinity_multiplier": [2.5, 1.5], - "step_count": 3, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 4 - }], - "position": 20 - }, { - "items": [{ - "id": "fairytale3", - "type": "world_song" - }], - "position": 55 - }] - }, { - "map_id": "byd_infinityheaven", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "infinityheaven2", - "require_type": "chart_unlock", - "coordinate": "650,900", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 200, - "character_affinity": [0, 1], - "affinity_multiplier": [2.5, 1.5], - "step_count": 9, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 1 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 2 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 3 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 4 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 5 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 6 - }, { - "items": [{ - "type": "fragment", - "amount": 100 - }], - "position": 7 - }, { - "items": [{ - "id": "infinityheaven3", - "type": "world_song" - }], - "position": 8 - }] - }, { - "map_id": "byd_purgatorium", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "purgatorium2", - "require_type": "chart_unlock", - "coordinate": "-900,-650", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 200, - "character_affinity": [13, 1], - "affinity_multiplier": [2.6, 1.6], - "step_count": 5, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 2 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 14 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 30 - }, { - "items": [{ - "id": "purgatorium3", - "type": "world_song" - }], - "position": 37 - }] - }, { - "map_id": "byd_dement", - "is_legacy": False, - "chapter": 1001, - "available_from": -1, - "available_to": 9999999999999, - "is_repeatable": False, - "require_id": "dement2", - "require_type": "chart_unlock", - "coordinate": "-400,-650", - "is_beyond": True, - "stamina_cost": 3, - "beyond_health": 250, - "character_affinity": [13, 1], - "affinity_multiplier": [2.6, 1.6], - "step_count": 4, - "custom_bg": "", - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 1 - }], - "position": 19 - }, { - "items": [{ - "type": "fragment", - "amount": 1200 - }], - "position": 39 - }, { - "items": [{ - "id": "dement3", - "type": "world_song" - }], - "position": 43 - }] - }, { - "map_id": "maliciousmischance_event", - "is_legacy": False, - "is_beyond": False, - "beyond_health": 100, - "character_affinity": [], - "affinity_multiplier": [], - "chapter": 0, - "available_from": 1599177600000, - "available_to": 1599836400000, - "is_repeatable": False, - "require_id": "maliciousmischance", - "require_type": "single", - "coordinate": "0,0", - "step_count": 87, - "custom_bg": "", - "stamina_cost": 2, - "curr_position": 0, - "curr_capture": 0, - "is_locked": True, - "rewards": [{ - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 62 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 63 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 67 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 68 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 72 - }, { - "items": [{ - "type": "core", - "id": "core_generic", - "amount": 2 - }], - "position": 73 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 77 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 78 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 82 - }, { - "items": [{ - "type": "fragment", - "amount": 250 - }], - "position": 83 - }, { - "items": [{ - "id": "37", - "type": "character" - }], - "position": 86 - }] - }] - }} - ]} - - conn.commit() - conn.close() - return r diff --git a/v1.2/server/setme.py b/v1.2/server/setme.py deleted file mode 100644 index 0891803..0000000 --- a/v1.2/server/setme.py +++ /dev/null @@ -1,155 +0,0 @@ -import sqlite3 -import server.info - - -def b2int(x): - # int与布尔值转换 - if x: - return 1 - else: - return 0 - - -def int2b(x): - # int与布尔值转换 - if x is None or x == 0: - return False - else: - return True - - -def change_char(user_id, character_id, skill_sealed): - # 角色改变,包括技能封印的改变,返回成功与否的布尔值 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id = :a and character_id = :b''', - {'a': user_id, 'b': character_id}) - x = c.fetchone() - if x is not None: - if skill_sealed == 'false': - skill_sealed = False - else: - skill_sealed = True - c.execute('''update user set is_skill_sealed = :a, character_id = :b, is_char_uncapped = :c, is_char_uncapped_override = :d where user_id = :e''', { - 'a': b2int(skill_sealed), 'b': character_id, 'c': x[0], 'd': x[1], 'e': user_id}) - - conn.commit() - conn.close() - return True - - conn.commit() - conn.close() - return False - - -def change_char_uncap(user_id, character_id): - # 角色觉醒改变,返回字典 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select is_uncapped, is_uncapped_override from user_char where user_id = :a and character_id = :b''', - {'a': user_id, 'b': character_id}) - x = c.fetchone() - r = None - if x is not None and x[0] == 1: - c.execute('''update user set is_char_uncapped_override = :a where user_id = :b''', { - 'a': b2int(x[1] == 0), 'b': user_id}) - c.execute('''update user_char set is_uncapped_override = :a where user_id = :b and character_id = :c''', { - 'a': b2int(x[1] == 0), 'b': user_id, 'c': character_id}) - c.execute('''select * from user_char where user_id = :a and character_id = :b''', - {'a': user_id, 'b': character_id}) - y = c.fetchone() - c.execute( - '''select name from character where character_id = :x''', {'x': y[1]}) - z = c.fetchone() - if z is not None: - char_name = z[0] - if y is not None: - r = { - "is_uncapped_override": int2b(y[14]), - "is_uncapped": int2b(y[13]), - "uncap_cores": [], - "char_type": y[12], - "skill_id_uncap": y[11], - "skill_requires_uncap": int2b(y[10]), - "skill_unlock_level": y[9], - "skill_id": y[8], - "overdrive": y[7], - "prog": y[6], - "frag": y[5], - "level_exp": y[4], - "exp": y[3], - "level": y[2], - "name": char_name, - "character_id": y[1] - } - - conn.commit() - conn.close() - return r - - -def arc_sys_set(user_id, value, set_arg): - # 三个设置,PTT隐藏、体力满通知、最爱角色,无返回 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - if 'favorite_character' in set_arg: - value = int(value) - c.execute('''update user set favorite_character = :a where user_id = :b''', { - 'a': value, 'b': user_id}) - - else: - if value == 'false': - value = False - else: - value = True - - if 'is_hide_rating' in set_arg: - c.execute('''update user set is_hide_rating = :a where user_id = :b''', { - 'a': b2int(value), 'b': user_id}) - if 'max_stamina_notification_enabled' in set_arg: - c.execute('''update user set max_stamina_notification_enabled = :a where user_id = :b''', { - 'a': b2int(value), 'b': user_id}) - - conn.commit() - conn.close() - return None - - -def arc_add_friend(user_id, friend_id): - # 加好友,返回好友列表,或者是错误码602、604 - if user_id == friend_id: - return 604 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''', - {'x': user_id, 'y': friend_id}) - r = None - if c.fetchone() == (0,): - c.execute('''insert into friend values(:a, :b)''', - {'a': user_id, 'b': friend_id}) - r = server.info.get_user_friend(c, user_id) - - else: - return 602 - - conn.commit() - conn.close() - return r - - -def arc_delete_friend(user_id, friend_id): - # 删好友,返回好友列表 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select exists(select * from friend where user_id_me = :x and user_id_other = :y)''', - {'x': user_id, 'y': friend_id}) - r = None - if c.fetchone() == (1,): - c.execute('''delete from friend where user_id_me = :x and user_id_other = :y''', - {'x': user_id, 'y': friend_id}) - - r = server.info.get_user_friend(c, user_id) - - conn.commit() - conn.close() - return r diff --git a/v1.2/setting.ini b/v1.2/setting.ini deleted file mode 100644 index 3d109b5..0000000 --- a/v1.2/setting.ini +++ /dev/null @@ -1,3 +0,0 @@ -[CONFIG] -HOST = 192.168.1.113 -PORT = 80 \ No newline at end of file diff --git a/v1.2/static/style.css b/v1.2/static/style.css deleted file mode 100644 index c486e03..0000000 --- a/v1.2/static/style.css +++ /dev/null @@ -1,217 +0,0 @@ -html { - font-family: sans-serif; - background: #eee; - padding: 1rem; -} - -body { - max-width: 960px; - margin: 0 auto; - background: white; -} - -h1 { - font-family: serif; - color: #377ba8; - margin: 1rem 0; -} - -a { - text-decoration: none; - color: #377ba8; -} - -hr { - border: none; - border-top: 1px solid lightgray; -} - -nav { - background: lightgray; - display: flex; - align-items: center; - padding: 0 0.5rem; -} - -nav h1 { - flex: auto; - margin: 0; -} - -nav h1 a { - text-decoration: none; - padding: 0.25rem 0.5rem; -} - -nav ul { - display: flex; - list-style: none; - margin: 0; - padding: 0; -} - -nav ul li a, -nav ul li span, -header .action { - display: block; - padding: 0.5rem; -} - -.content { - padding: 0 1rem 1rem; -} - -.content>header { - border-bottom: 1px solid lightgray; - display: flex; - align-items: flex-end; -} - -.content>header h1 { - flex: auto; - margin: 1rem 0 0.25rem 0; -} - -.flash { - margin: 1em 0; - padding: 1em; - background: #cae6f6; - border: 1px solid #377ba8; -} - -.post>header { - display: flex; - align-items: flex-end; - font-size: 0.85em; -} - -.post>header>div:first-of-type { - flex: auto; -} - -.post>header h1 { - font-size: 1.5em; - margin-bottom: 0; -} - -.post .about { - color: slategray; - font-style: italic; -} - -.post .body { - white-space: pre-line; -} - -.content:last-child { - margin-bottom: 0; -} - -.content form { - margin: 1em 0; - display: flex; - flex-direction: column; -} - -.content label { - font-weight: bold; - margin-bottom: 0.5em; -} - -.content input, -.content textarea { - margin-bottom: 1em; -} - -.content textarea { - min-height: 12em; - resize: vertical; -} - -input.danger { - color: #cc2f2e; -} - -input[type=submit] { - align-self: start; - min-width: 10em; -} - - -.score-item { - margin-bottom: 10px; - clear: both; -} - -.song-title { - font-size: 1.3em; - font-weight: bold; - display: inline-block; -} - -.difficulty_pst { - font-size: 0.9em; - background-color: rgb(10, 130, 190); - color: white; -} - -.difficulty_prs { - font-size: 0.9em; - background-color: rgb(100, 140, 60); - color: white; -} - -.difficulty_ftr { - font-size: 0.9em; - background-color: rgb(80, 25, 75); - color: white; -} - -.difficulty_byd { - font-size: 0.9em; - background-color: rgb(130, 35, 40); - color: white; -} - -.rank { - font-size: 0.8em; - margin-left: 4px; - padding: 0 4px; -} - -.rank_big { - font-size: 1.2em; - margin-left: 4px; - padding: 0 4px; -} - -.song-detail { - font-size: 0.8em; - float: right; - text-align: right; -} - -.song-score { - font-size: 1.375em; - font-family: Arial; -} - -.song-clear-type { - font-size: 0.875em; - padding-left: 0.625em; -} - -.title { - font-size: 1.375em; -} - -.name { - font-size: 1.12em; - font-weight: bold; -} - -.footer{ - font-size: 0.5em; - color: grey; - text-align: center; -} \ No newline at end of file diff --git a/v1.2/templates/base.html b/v1.2/templates/base.html deleted file mode 100644 index 160c5d0..0000000 --- a/v1.2/templates/base.html +++ /dev/null @@ -1,23 +0,0 @@ - -{% block title %}{% endblock %} - Arcaea Server - - -
-
- {% block header %}{% endblock %} -
- {% for message in get_flashed_messages() %} -
{{ message }}
- {% endfor %} {% block content %}{% endblock %} -
- -
Made by Lost@2020
\ No newline at end of file diff --git a/v1.2/templates/web/allplayer.html b/v1.2/templates/web/allplayer.html deleted file mode 100644 index 9dd4437..0000000 --- a/v1.2/templates/web/allplayer.html +++ /dev/null @@ -1,81 +0,0 @@ -{% extends 'base.html' %} -{% block header %} -

{% block title %}All players{% endblock %}

-{% endblock %} - -{% block content %} -{% if posts %} -{% for user in posts %} - -
-
{{user['name']}} - UID: {{user['user_id']}} - User code: {{user['user_code']}} -
-
注册于 Registered in: {{user['join_date']}}
-
PTT: {{user['rating_ptt']//100 ~ '.' ~ user['rating_ptt']%100}}
-
-
Recent plays:
-
-
- - {{user['song_id']}} - - {% if user['difficulty'] == 0 %} - PST - {% elif user['difficulty'] == 1 %} - PRS - {% elif user['difficulty'] == 2 %} - FTR - {% else %} - BYD - {% endif %} - -
-
- - - - - - - - - - - - - - - - - - -
PURE: {{user['perfect_count']}} {{'(' ~ user['shiny_perfect_count'] ~ ')'}}
FAR: {{user['near_count']}}
LOST: {{user['miss_count']}}
-
-
{{user['score']}}
-
- {% if user['clear_type'] == 3 %}Pure Memory - {% elif user['clear_type'] == 2 %}Full Recall - {% elif user['clear_type'] == 5 %}Hard Clear - {% elif user['clear_type'] == 1 %}Normal Clear - {% elif user['clear_type'] == 4 %}Easy Clear - {% else%}Track Lost - {% endif %} -
-
成绩评价 Rating: {{user['rating']}}
-
日期 Date: - {{user['time_played']}} -
-
-
-
-
-{% if not loop.last %} -
-
-{% endif %} -{% endfor %} - -{% endif %} -{% endblock %} \ No newline at end of file diff --git a/v1.2/templates/web/allsong.html b/v1.2/templates/web/allsong.html deleted file mode 100644 index 4aab965..0000000 --- a/v1.2/templates/web/allsong.html +++ /dev/null @@ -1,48 +0,0 @@ -{% extends 'base.html' %} -{% block header %} -

{% block title %}All songs{% endblock %}

-{% endblock %} - -{% block content %} -{% if posts %}
-{% for song in posts %} - -
- Sid: - {{song['song_id']}} -
- Name_en: - {{song['name_en']}} -
-
铺面定数 Chart const:
- {% if song['rating_pst'] %} - PST - {{song['rating_pst']}} - {% endif %} -
- {% if song['rating_prs'] %} - PRS - {{song['rating_prs']}} - {% endif %} -
- {% if song['rating_ftr'] %} - FTR - {{song['rating_ftr']}} - {% endif %} -
- {% if song['rating_byn'] %} - BYD - {{song['rating_byn']}} - {% endif %} - - -
-{% if not loop.last %} -
-
-
-{% endif %} -{% endfor %} - -{% endif %} -{% endblock %} \ No newline at end of file diff --git a/v1.2/templates/web/changesong.html b/v1.2/templates/web/changesong.html deleted file mode 100644 index e03eb5a..0000000 --- a/v1.2/templates/web/changesong.html +++ /dev/null @@ -1,35 +0,0 @@ -{% extends 'base.html' %} -{% block header %} -

{% block title %}Change the songs{% endblock %}

-{% endblock %} - -{% block content %} -
-
Add the song
- - - - - - - - - - - - - -
如果没有某个铺面,应该填入-1。
-
If there is no some chart, fill in -1 please.
- -
-
-
-
-
Delete the song
- - - - -
-{% endblock %} \ No newline at end of file diff --git a/v1.2/templates/web/index.html b/v1.2/templates/web/index.html deleted file mode 100644 index bd62a7e..0000000 --- a/v1.2/templates/web/index.html +++ /dev/null @@ -1,24 +0,0 @@ -{% extends 'base.html' %} -{% block header %} -

{% block title %}Index{% endblock %}

-{% endblock %} - -{% block content %} -

说明 Statement

-

这是Arcaea Server的后台管理协助系统,可以进行一些简单的操作
- This is the background management assistance system of Arcaea Server, which can be used to do some simple - operations. -

-

游戏方面 Game

-单个玩家成绩查询 Single player score

-单个玩家PTT详情查询 Single player ptt

-所有玩家信息查询 All players

-铺面信息查询 All songs

-单个铺面排行榜查询 Single song chart tops -
-

系统方面 System

-数据库更新 Update databases

-歌曲修改 Change the songs - - -{% endblock %} \ No newline at end of file diff --git a/v1.2/templates/web/login.html b/v1.2/templates/web/login.html deleted file mode 100644 index b8ee233..0000000 --- a/v1.2/templates/web/login.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends 'base.html' %} -{% block header %} -

{% block title %}Log In{% endblock %}

-{% endblock %} - -{% block content %} -
- - - - - -
-{% endblock %} \ No newline at end of file diff --git a/v1.2/templates/web/singlecharttop.html b/v1.2/templates/web/singlecharttop.html deleted file mode 100644 index 9e6a10a..0000000 --- a/v1.2/templates/web/singlecharttop.html +++ /dev/null @@ -1,108 +0,0 @@ -{% extends 'base.html' %} -{% block header %} -

{% block title %}Single chart top{% endblock %}

-{% endblock %} - -{% block content %} -
- - 模糊查询,只返回第一个 - Fuzzy query,and only return the first one. - - - -
- -
-
-
- {% if song_id %} -
- - {{song_id}} - - - {% if difficulty == 0 %} - PST - {% elif difficulty == 1 %} - PRS - {% elif difficulty == 2 %} - FTR - {% else %} - BYD - - {% endif %} -
-
- {{song_name_en}} -
-
- {% endif %} -
-
- {% for post in posts %} -
-
- {{'#' ~ post['rank']}} - - {{post['name']}} - - UID: {{post['user_id']}} -
- -
- - - - - - - - - - - - - - - - - - -
PURE: {{post['perfect_count']}} {{'(' ~ post['shiny_perfect_count'] ~ ')'}}
FAR: {{post['near_count']}}
LOST: {{post['miss_count']}}
-
-
{{post['score']}}
-
- {% if post['clear_type'] == 3 %}Pure Memory - {% elif post['clear_type'] == 2 %}Full Recall - {% elif post['clear_type'] == 5 %}Hard Clear - {% elif post['clear_type'] == 1 %}Normal Clear - {% elif post['clear_type'] == 4 %}Easy Clear - {% else%}Track Lost - {% endif %} - - {% if post['best_clear_type'] == 3 %}(Pure Memory) - {% elif post['best_clear_type'] == 2 %}(Full Recall) - {% elif post['best_clear_type'] == 5 %}(Hard Clear) - {% elif post['best_clear_type'] == 1 %}(Normal Clear) - {% elif post['best_clear_type'] == 4 %}(Easy Clear) - {% else%}(Track Lost) - {% endif %} - -
-
日期 Date: - {{post['time_played']}} -
-
- - {% if not loop.last %} -
- {% endif %} - {% endfor %} -
-{% endblock %} \ No newline at end of file diff --git a/v1.2/templates/web/singleplayer.html b/v1.2/templates/web/singleplayer.html deleted file mode 100644 index 5289745..0000000 --- a/v1.2/templates/web/singleplayer.html +++ /dev/null @@ -1,85 +0,0 @@ -{% extends 'base.html' %} -{% block header %} -

{% block title %}Single player score{% endblock %}

-{% endblock %} - -{% block content %} -
- - - or
- - - -
-
-
- {% for post in posts %} -
- - {{post['song_id']}} - - {% if post['difficulty'] == 0 %} - PST - {% elif post['difficulty'] == 1 %} - PRS - {% elif post['difficulty'] == 2 %} - FTR - {% else %} - BYD - {% endif %} - {{'#' ~ post['rank']}} - -
-
- - - - - - - - - - - - - - - - - - -
PURE: {{post['perfect_count']}} {{'(' ~ post['shiny_perfect_count'] ~ ')'}}
FAR: {{post['near_count']}}
LOST: {{post['miss_count']}}
-
-
{{post['score']}}
-
- {% if post['clear_type'] == 3 %}Pure Memory - {% elif post['clear_type'] == 2 %}Full Recall - {% elif post['clear_type'] == 5 %}Hard Clear - {% elif post['clear_type'] == 1 %}Normal Clear - {% elif post['clear_type'] == 4 %}Easy Clear - {% else%}Track Lost - {% endif %} - - {% if post['best_clear_type'] == 3 %}(Pure Memory) - {% elif post['best_clear_type'] == 2 %}(Full Recall) - {% elif post['best_clear_type'] == 5 %}(Hard Clear) - {% elif post['best_clear_type'] == 1 %}(Normal Clear) - {% elif post['best_clear_type'] == 4 %}(Easy Clear) - {% else%}(Track Lost) - {% endif %} - -
-
成绩评价 Rating: {{post['rating']}}
-
日期 Date: - {{post['time_played']}} -
-
- - {% if not loop.last %} -
- {% endif %} - {% endfor %} -
-{% endblock %} \ No newline at end of file diff --git a/v1.2/templates/web/singleplayerptt.html b/v1.2/templates/web/singleplayerptt.html deleted file mode 100644 index 5ce15b1..0000000 --- a/v1.2/templates/web/singleplayerptt.html +++ /dev/null @@ -1,191 +0,0 @@ -{% extends 'base.html' %} -{% block header %} -

{% block title %}Single player ptt{% endblock %}

-{% endblock %} - -{% block content %} -
- - - or
- - - -
-
-
- {% if user %} -
- -
-
玩家信息 Player information
-
{{user['name']}} - UID: {{user['user_id']}} - User code: {{user['user_code']}} -
-
注册于 Registered in: {{user['join_date']}}
-
PTT: {{user['rating_ptt']//100 ~ '.' ~ user['rating_ptt']%100}}
-
Best 30 PTT: {{bestptt}}
-
Recent 10 PTT: {{recentptt}}
-
-
Recent plays:
-
-
- - {{user['song_id']}} - - {% if user['difficulty'] == 0 %} - PST - {% elif user['difficulty'] == 1 %} - PRS - {% elif user['difficulty'] == 2 %} - FTR - {% else %} - BYD - {% endif %} - -
-
- - - - - - - - - - - - - - - - - - -
PURE: {{user['perfect_count']}} {{'(' ~ user['shiny_perfect_count'] ~ ')'}}
FAR: {{user['near_count']}}
LOST: {{user['miss_count']}}
-
-
{{user['score']}}
-
- {% if user['clear_type'] == 3 %}Pure Memory - {% elif user['clear_type'] == 2 %}Full Recall - {% elif user['clear_type'] == 5 %}Hard Clear - {% elif user['clear_type'] == 1 %}Normal Clear - {% elif user['clear_type'] == 4 %}Easy Clear - {% else%}Track Lost - {% endif %} -
-
成绩评价 Rating: {{user['rating']}}
-
日期 Date: - {{user['time_played']}} -
-
-
-
-
-
- {% if posts %} -
Best 30
- {% endif %} - {% for post in posts %} -
- - {{post['song_id']}} - - {% if post['difficulty'] == 0 %} - PST - {% elif post['difficulty'] == 1 %} - PRS - {% elif post['difficulty'] == 2 %} - FTR - {% else %} - BYD - {% endif %} - {{'#' ~ post['rank']}} - -
-
- - - - - - - - - - - - - - - - - - -
PURE: {{post['perfect_count']}} {{'(' ~ post['shiny_perfect_count'] ~ ')'}}
FAR: {{post['near_count']}}
LOST: {{post['miss_count']}}
-
-
{{post['score']}}
-
- {% if post['clear_type'] == 3 %}Pure Memory - {% elif post['clear_type'] == 2 %}Full Recall - {% elif post['clear_type'] == 5 %}Hard Clear - {% elif post['clear_type'] == 1 %}Normal Clear - {% elif post['clear_type'] == 4 %}Easy Clear - {% else%}Track Lost - {% endif %} - - {% if post['best_clear_type'] == 3 %}(Pure Memory) - {% elif post['best_clear_type'] == 2 %}(Full Recall) - {% elif post['best_clear_type'] == 5 %}(Hard Clear) - {% elif post['best_clear_type'] == 1 %}(Normal Clear) - {% elif post['best_clear_type'] == 4 %}(Easy Clear) - {% else%}(Track Lost) - {% endif %} - -
-
成绩评价 Rating: {{post['rating']}}
-
日期 Date: - {{post['time_played']}} -
-
- - {% if not loop.last %} -
- {% endif %} - {% endfor %} -
- - {% if recent %} -
Recent 30
- {% set rank = 0 %} - {% for i in recent %} - {% if i %} - {% set rank = rank + 1 %} -
- - {{i['song_id']}} - - {% if i['difficulty'] == 0 %} - PST - {% elif i['difficulty'] == 1 %} - PRS - {% elif i['difficulty'] == 2 %} - FTR - {% else %} - BYD - {% endif %} - {{rank}} -
成绩评价 Rating: {{i['rating']}}
-
- - {% if not loop.last %} -
- {% endif %} - {% endif %} - {% endfor %} - {% endif %} - {% endif %} -
-{% endblock %} \ No newline at end of file diff --git a/v1.2/templates/web/updatedatabase.html b/v1.2/templates/web/updatedatabase.html deleted file mode 100644 index ea47675..0000000 --- a/v1.2/templates/web/updatedatabase.html +++ /dev/null @@ -1,21 +0,0 @@ -{% extends 'base.html' %} -{% block header %} -

{% block title %}Update databases{% endblock %}

-{% endblock %} - -{% block content %} -
- - - -
-
- 这里可以将旧版本的数据库同步到新版本的数据库,并刷新用户拥有的角色列表。
- 可上传文件: arcaea_database.db和arcsong.db
- 新数据库不存在的数据会被添加,存在的数据将不会被改变。

- Here you can synchronize the old version of the database to the new version of the database and refresh the list of - characters owned by players.
- Uploadable files: arcaea_database.db & arcsong.db
- Data that does not exist in the new database will be added and the existing data will not be changed. -
-{% endblock %} \ No newline at end of file diff --git a/v1.2/web/index.py b/v1.2/web/index.py deleted file mode 100644 index aa9623d..0000000 --- a/v1.2/web/index.py +++ /dev/null @@ -1,357 +0,0 @@ -from flask import ( - Blueprint, flash, g, redirect, render_template, request, url_for -) -from web.login import login_required -from werkzeug.utils import secure_filename -import sqlite3 -import web.webscore -import web.system -import time -import server.arcscore -import os - -UPLOAD_FOLDER = 'database' -ALLOWED_EXTENSIONS = {'db'} - -bp = Blueprint('index', __name__, url_prefix='/web') - - -def is_number(s): - try: # 判断字符串s是浮点数 - float(s) - return True - except ValueError: - pass - return False - - -@bp.route('/index') -@bp.route('/') -@login_required -def index(): - # 主页 - return render_template('web/index.html') - - -@bp.route('/singleplayer', methods=['POST', 'GET']) -@login_required -def single_player_score(): - # 单个玩家分数查询 - if request.method == 'POST': - name = request.form['name'] - user_code = request.form['user_code'] - error = None - if name or user_code: - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - if user_code: - c.execute('''select user_id from user where user_code=:a''', { - 'a': user_code}) - else: - c.execute( - '''select user_id from user where name=:a''', {'a': name}) - - user_id = c.fetchone() - posts = [] - if user_id: - user_id = user_id[0] - posts = web.webscore.get_user_score(c, user_id) - if not posts: - error = '无成绩 No score.' - else: - error = '玩家不存在 The player does not exist.' - conn.commit() - conn.close() - - else: - error = '输入为空 Null Input.' - - if error: - flash(error) - else: - return render_template('web/singleplayer.html', posts=posts) - - return render_template('web/singleplayer.html') - - -@bp.route('/singleplayerptt', methods=['POST', 'GET']) -@login_required -def single_player_ptt(): - # 单个玩家PTT详情查询 - if request.method == 'POST': - name = request.form['name'] - user_code = request.form['user_code'] - error = None - if name or user_code: - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - if user_code: - c.execute('''select user_id from user where user_code=:a''', { - 'a': user_code}) - else: - c.execute( - '''select user_id from user where name=:a''', {'a': name}) - - user_id = c.fetchone() - posts = [] - if user_id: - user_id = user_id[0] - user = web.webscore.get_user(c, user_id) - posts = web.webscore.get_user_score(c, user_id, 30) - recent, recentptt = web.webscore.get_user_recent30(c, user_id) - if not posts: - error = '无成绩 No score.' - else: - bestptt = 0 - for i in posts: - if i['rating']: - bestptt += i['rating'] - bestptt = bestptt / 30 - else: - error = '玩家不存在 The player does not exist.' - - conn.commit() - conn.close() - else: - error = '输入为空 Null Input.' - - if error: - flash(error) - else: - return render_template('web/singleplayerptt.html', posts=posts, user=user, recent=recent, recentptt=recentptt, bestptt=bestptt) - - return render_template('web/singleplayerptt.html') - - -@bp.route('/allplayer', methods=['GET']) -@login_required -def all_player(): - # 所有玩家数据,按照ptt排序 - conn = sqlite3.connect('./database/arcaea_database.db') - c = conn.cursor() - c.execute('''select * from user order by rating_ptt DESC''') - x = c.fetchall() - error = None - if x: - posts = [] - for i in x: - join_data = None - time_played = None - if i[3]: - join_date = time.strftime('%Y-%m-%d %H:%M:%S', - time.localtime(int(i[3])//1000)) - if i[20]: - time_played = time.strftime('%Y-%m-%d %H:%M:%S', - time.localtime(int(i[20])//1000)) - posts.append({'name': i[1], - 'user_id': i[0], - 'join_date': join_date, - 'user_code': i[4], - 'rating_ptt': i[5], - 'song_id': i[11], - 'difficulty': i[12], - 'score': i[13], - 'shiny_perfect_count': i[14], - 'perfect_count': i[15], - 'near_count': i[16], - 'miss_count': i[17], - 'time_played': time_played, - 'clear_type': i[21], - 'rating': i[22] - }) - else: - error = '没有玩家数据 No player data.' - - conn.commit() - conn.close() - if error: - flash(error) - return render_template('web/allplayer.html') - else: - return render_template('web/allplayer.html', posts=posts) - - -@bp.route('/allsong', methods=['GET']) -@login_required -def all_song(): - # 所有歌曲数据 - def defnum(x): - # 定数转换 - if x >= 0: - return x / 10 - else: - return None - - conn = sqlite3.connect('./database/arcsong.db') - c = conn.cursor() - c.execute('''select * from songs''') - x = c.fetchall() - error = None - if x: - posts = [] - for i in x: - posts.append({'song_id': i[0], - 'name_en': i[1], - 'rating_pst': defnum(i[12]), - 'rating_prs': defnum(i[13]), - 'rating_ftr': defnum(i[14]), - 'rating_byn': defnum(i[15]) - }) - else: - error = '没有铺面数据 No song data.' - - conn.commit() - conn.close() - if error: - flash(error) - return render_template('web/allsong.html') - else: - return render_template('web/allsong.html', posts=posts) - - -@bp.route('/singlecharttop', methods=['GET', 'POST']) -@login_required -def single_chart_top(): - # 歌曲排行榜 - if request.method == 'POST': - song_name = request.form['sid'] - difficulty = request.form['difficulty'] - if difficulty.isdigit(): - difficulty = int(difficulty) - error = None - conn = sqlite3.connect('./database/arcsong.db') - c = conn.cursor() - song_name = '%'+song_name+'%' - c.execute('''select sid, name_en from songs where sid like :a limit 1''', - {'a': song_name}) - x = c.fetchone() - conn.commit() - conn.close() - print(x) - if x: - song_id = x[0] - posts = server.arcscore.arc_score_top(song_id, difficulty, -1) - for i in posts: - i['time_played'] = time.strftime('%Y-%m-%d %H:%M:%S', - time.localtime(i['time_played'])) - else: - error = '查询为空 No song.' - - if not error: - return render_template('web/singlecharttop.html', posts=posts, song_name_en=x[1], song_id=song_id, difficulty=difficulty) - else: - flash(error) - - return render_template('web/singlecharttop.html') - - -def allowed_file(filename): - return '.' in filename and \ - filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS - - -@bp.route('/updatedatabase', methods=['GET', 'POST']) -@login_required -def update_database(): - # 更新数据库 - error = None - if request.method == 'POST': - if 'file' not in request.files: - flash('无文件 No file part.') - return redirect(request.url) - file = request.files['file'] - if file.filename == '': - flash('未选择文件 No selected file.') - return redirect(request.url) - - if file and allowed_file(file.filename): - filename = 'old_' + secure_filename(file.filename) - file.save(os.path.join(UPLOAD_FOLDER, filename)) - flash('上传成功 Success upload.') - web.system.update_database() - flash('数据更新成功 Success update data.') - else: - error = '上传失败 Upload error.' - - if error: - flash(error) - - return render_template('web/updatedatabase.html') - - -@bp.route('/changesong', methods=['GET']) -@login_required -def change_song(): - # 修改歌曲数据 - return render_template('web/changesong.html') - - -@bp.route('/changesong/addsong', methods=['POST']) -@login_required -def add_song(): - # 添加歌曲数据 - def get_rating(x): - # 换算定数 - if is_number(x): - x = float(x) - if x >= 0: - return int(x*10) - else: - return -1 - else: - return -1 - - error = None - song_id = request.form['sid'] - name_en = request.form['name_en'] - rating_pst = get_rating(request.form['rating_pst']) - rating_prs = get_rating(request.form['rating_prs']) - rating_ftr = get_rating(request.form['rating_ftr']) - rating_byd = get_rating(request.form['rating_byd']) - if len(song_id) >= 256: - song_id = song_id[:200] - if len(name_en) >= 256: - name_en = name_en[:200] - conn = sqlite3.connect('./database/arcsong.db') - c = conn.cursor() - c.execute( - '''select exists(select * from songs where sid=:a)''', {'a': song_id}) - if c.fetchone() == (0,): - c.execute('''insert into songs(sid,name_en,rating_pst,rating_prs,rating_ftr,rating_byn) values(:a,:b,:c,:d,:e,:f)''', { - 'a': song_id, 'b': name_en, 'c': rating_pst, 'd': rating_prs, 'e': rating_ftr, 'f': rating_byd}) - flash('歌曲添加成功 Successfully add the song.') - else: - error = '歌曲已存在 The song exists.' - - conn.commit() - conn.close() - - if error: - flash(error) - - return redirect(url_for('index.change_song')) - - -@bp.route('/changesong/deletesong', methods=['POST']) -@login_required -def delete_song(): - # 删除歌曲数据 - - error = None - song_id = request.form['sid'] - conn = sqlite3.connect('./database/arcsong.db') - c = conn.cursor() - c.execute( - '''select exists(select * from songs where sid=:a)''', {'a': song_id}) - if c.fetchone() == (1,): - c.execute('''delete from songs where sid=:a''', {'a': song_id}) - flash('歌曲删除成功 Successfully delete the song.') - else: - error = "歌曲不存在 The song doesn't exist." - - conn.commit() - conn.close() - if error: - flash(error) - - return redirect(url_for('index.change_song')) diff --git a/v1.2/web/login.py b/v1.2/web/login.py deleted file mode 100644 index 5c8e007..0000000 --- a/v1.2/web/login.py +++ /dev/null @@ -1,50 +0,0 @@ -#import sqlite3 -from flask import (Blueprint, flash, g, redirect, - render_template, request, session, url_for) -import functools - -bp = Blueprint('login', __name__, url_prefix='/web') - - -@bp.route('/login', methods=('GET', 'POST')) -def login(): - # 登录 - if request.method == 'POST': - username = request.form['username'] - password = request.form['password'] - error = None - - if username != 'admin' and password != 'admin': - error = '错误的用户名或密码 Incorrect username or password.' - - if error is None: - session.clear() - session['user_id'] = 'admin' - return redirect(url_for('index.index')) - - flash(error) - - return render_template('web/login.html') - - -@bp.route('/logout') -def logout(): - # 登出 - session.clear() - flash('成功登出 Successfully log out.') - return redirect(url_for('index.index')) - - -def login_required(view): - # 登录验证,写成了修饰器 - @functools.wraps(view) - def wrapped_view(**kwargs): - x = session.get('user_id') - # 少用户存在验证 - if x is None: - return redirect(url_for('login.login')) - - g.user = {'user_id': x, 'username': 'admin'} - return view(**kwargs) - - return wrapped_view diff --git a/v1.2/web/system.py b/v1.2/web/system.py deleted file mode 100644 index 4b228a8..0000000 --- a/v1.2/web/system.py +++ /dev/null @@ -1,102 +0,0 @@ -import os -import sqlite3 - - -def update_user_char(c): - # 用character数据更新user_char - c.execute('''select * from character''') - x = c.fetchall() - c.execute('''select user_id from user''') - y = c.fetchall() - if x and y: - for j in y: - for i in x: - c.execute('''delete from user_char where user_id=:a and character_id=:b''', { - 'a': j[0], 'b': i[0]}) - c.execute('''insert into user_char values(:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n,:o)''', { - 'a': j[0], 'b': i[0], 'c': i[2], 'd': i[3], 'e': i[4], 'f': i[5], 'g': i[6], 'h': i[7], 'i': i[8], 'j': i[9], 'k': i[10], 'l': i[11], 'm': i[12], 'n': i[14], 'o': i[15]}) - - -def update_database(): - # 将old数据库不存在数据加入到新数据库上,并删除old数据库 - # 对于arcaea_datebase.db,更新best_score,friend,recent30,user,并用character数据更新user_char - # 对于arcsong.db,更新songs - if os.path.isfile("database/old_arcaea_database.db") and os.path.isfile("database/arcaea_database.db"): - conn1 = sqlite3.connect('./database/old_arcaea_database.db') - c1 = conn1.cursor() - conn2 = sqlite3.connect('./database/arcaea_database.db') - c2 = conn2.cursor() - - # user - c1.execute('''select * from user''') - x = c1.fetchall() - if x: - for i in x: - c2.execute( - '''select exists(select * from user where user_id=:a)''', {'a': i[0]}) - if c2.fetchone() == (0,): - c2.execute('''insert into user values(:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13,:a14,:a15,:a16,:a17,:a18,:a19,:a20,:a21,:a22,:a23,:a24)''', { - 'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4], 'a5': i[5], 'a6': i[6], 'a7': i[7], 'a8': i[8], 'a9': i[9], 'a10': i[10], 'a11': i[11], 'a12': i[12], 'a13': i[13], 'a14': i[14], 'a15': i[15], 'a16': i[16], 'a17': i[17], 'a18': i[18], 'a19': i[19], 'a20': i[20], 'a21': i[21], 'a22': i[22], 'a23': i[23], 'a24': i[24]}) - - # friend - c1.execute('''select * from friend''') - x = c1.fetchall() - if x: - for i in x: - c2.execute( - '''select exists(select * from friend where user_id_me=:a and user_id_other=:b)''', {'a': i[0], 'b': i[1]}) - if c2.fetchone() == (0,): - c2.execute('''insert into friend values(:a,:b)''', { - 'a': i[0], 'b': i[1]}) - - # best_score - c1.execute('''select * from best_score''') - x = c1.fetchall() - if x: - for i in x: - c2.execute('''select exists(select * from best_score where user_id=:a and song_id=:b and difficulty=:c)''', { - 'a': i[0], 'b': i[1], 'c': i[2]}) - if c2.fetchone() == (0,): - c2.execute('''insert into best_score values(:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13)''', { - 'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4], 'a5': i[5], 'a6': i[6], 'a7': i[7], 'a8': i[8], 'a9': i[9], 'a10': i[10], 'a11': i[11], 'a12': i[12], 'a13': i[13]}) - - # recent30 - c1.execute('''select * from recent30''') - x = c1.fetchall() - if x: - for i in x: - c2.execute( - '''select exists(select * from recent30 where user_id=:a)''', {'a': i[0]}) - if c2.fetchone() == (0,): - c2.execute('''insert into recent30 values(:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13,:a14,:a15,:a16,:a17,:a18,:a19,:a20,:a21,:a22,:a23,:a24,:a25,:a26,:a27,:a28,:a29,:a30,:a31,:a32,:a33,:a34,:a35,:a36,:a37,:a38,:a39,:a40,:a41,:a42,:a43,:a44,:a45,:a46,:a47,:a48,:a49,:a50,:a51,:a52,:a53,:a54,:a55,:a56,:a57,:a58,:a59,:a60)''', {'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4], 'a5': i[5], 'a6': i[6], 'a7': i[7], 'a8': i[8], 'a9': i[9], 'a10': i[10], 'a11': i[11], 'a12': i[12], 'a13': i[13], 'a14': i[14], 'a15': i[15], 'a16': i[16], 'a17': i[17], 'a18': i[ - 18], 'a19': i[19], 'a20': i[20], 'a21': i[21], 'a22': i[22], 'a23': i[23], 'a24': i[24], 'a25': i[25], 'a26': i[26], 'a27': i[27], 'a28': i[28], 'a29': i[29], 'a30': i[30], 'a31': i[31], 'a32': i[32], 'a33': i[33], 'a34': i[34], 'a35': i[35], 'a36': i[36], 'a37': i[37], 'a38': i[38], 'a39': i[39], 'a40': i[40], 'a41': i[41], 'a42': i[42], 'a43': i[43], 'a44': i[44], 'a45': i[45], 'a46': i[46], 'a47': i[47], 'a48': i[48], 'a49': i[49], 'a50': i[50], 'a51': i[51], 'a52': i[52], 'a53': i[53], 'a54': i[54], 'a55': i[55], 'a56': i[56], 'a57': i[57], 'a58': i[58], 'a59': i[59], 'a60': i[60]}) - - update_user_char(c2) - conn1.commit() - conn1.close() - conn2.commit() - conn2.close() - os.remove('database/old_arcaea_database.db') - - # songs - if os.path.isfile("database/old_arcsong.db") and os.path.isfile("database/arcsong.db"): - conn1 = sqlite3.connect('./database/old_arcsong.db') - c1 = conn1.cursor() - conn2 = sqlite3.connect('./database/arcsong.db') - c2 = conn2.cursor() - - c1.execute('''select * from songs''') - x = c1.fetchall() - if x: - for i in x: - c2.execute( - '''select exists(select * from songs where sid=:a)''', {'a': i[0]}) - if c2.fetchone() == (0,): - c2.execute('''insert into songs values(:a0,:a1,:a2,:a3,:a4,:a5,:a6,:a7,:a8,:a9,:a10,:a11,:a12,:a13,:a14,:a15,:a16,:a17,:a18,:a19,:a20,:a21,:a22,:a23,:a24,:a25,:a26,:a27)''', {'a0': i[0], 'a1': i[1], 'a2': i[2], 'a3': i[3], 'a4': i[4], 'a5': i[5], 'a6': i[6], 'a7': i[7], 'a8': i[ - 8], 'a9': i[9], 'a10': i[10], 'a11': i[11], 'a12': i[12], 'a13': i[13], 'a14': i[14], 'a15': i[15], 'a16': i[16], 'a17': i[17], 'a18': i[18], 'a19': i[19], 'a20': i[20], 'a21': i[21], 'a22': i[22], 'a23': i[23], 'a24': i[24], 'a25': i[25], 'a26': i[26], 'a27': i[27]}) - - conn1.commit() - conn1.close() - conn2.commit() - conn2.close() - os.remove('database/old_arcsong.db') diff --git a/v1.2/web/webscore.py b/v1.2/web/webscore.py deleted file mode 100644 index cc99365..0000000 --- a/v1.2/web/webscore.py +++ /dev/null @@ -1,104 +0,0 @@ -import time - - -def get_user_score(c, user_id, limit=-1): - # 返回用户的所有歌曲数据,带排名,返回字典列表 - if limit >= 0: - c.execute('''select * from best_score where user_id =:a order by rating DESC limit :b''', - {'a': user_id, 'b': limit}) - else: - c.execute( - '''select * from best_score where user_id =:a order by rating DESC''', {'a': user_id}) - x = c.fetchall() - r = [] - if x: - rank = 0 - for i in x: - rank += 1 - r.append({ - "song_id": i[1], - "difficulty": i[2], - "score": i[3], - "shiny_perfect_count": i[4], - "perfect_count": i[5], - "near_count": i[6], - "miss_count": i[7], - "health": i[8], - "modifier": i[9], - "time_played": time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(i[10])), - "best_clear_type": i[11], - "clear_type": i[12], - "rating": i[13], - "rank": rank - }) - - return r - - -def get_user(c, user_id): - # 得到user表部分用户信息,返回字典 - c.execute('''select * from user where user_id = :a''', {'a': user_id}) - x = c.fetchone() - r = None - if x: - join_date = None - time_played = None - if x[3]: - join_date = time.strftime('%Y-%m-%d %H:%M:%S', - time.localtime(int(x[3])//1000)) - if x[20]: - time_played = time.strftime('%Y-%m-%d %H:%M:%S', - time.localtime(int(x[20])//1000)) - - r = {'name': x[1], - 'user_id': user_id, - 'join_date': join_date, - 'user_code': x[4], - 'rating_ptt': x[5], - 'song_id': x[11], - 'difficulty': x[12], - 'score': x[13], - 'shiny_perfect_count': x[14], - 'perfect_count': x[15], - 'near_count': x[16], - 'miss_count': x[17], - 'time_played': time_played, - 'clear_type': x[21], - 'rating': x[22] - } - - return r - - -def get_user_recent30(c, user_id): - # 获取玩家recent30信息并计算这一部分的ptt,返回字典列表和一个值 - c.execute('''select * from recent30 where user_id=:a''', {'a': user_id}) - sumr = 0 - x = c.fetchone() - r = [] - if x is not None: - r30 = [] - s30 = [] - for i in range(1, 61, 2): - if x[i] is not None: - r30.append(float(x[i])) - s30.append(x[i+1]) - else: - r30.append(0) - s30.append('') - r30, s30 = (list(t) for t in zip(*sorted(zip(r30, s30), reverse=True))) - songs = [] - i = 0 - while len(songs) < 10 and i <= 29 and s30[i] != '' and s30[i] is not None: - if s30[i] not in songs: - sumr += r30[i] - songs.append(s30[i]) - i += 1 - for i in range(0, 30): - if s30[i]: - r.append({ - 'song_id': s30[i][:-1], - 'difficulty': int(s30[i][-1]), - 'rating': r30[i] - }) - return r, sumr / 10