def update_database(): # 将old数据库不存在数据加入到新数据库上,并删除old数据库 # 对于arcaea_datebase.db,更新一些表,并用character数据更新user_char_full # 对于arcsong.db,更新songs if os.path.isfile("database/old_arcaea_database.db") and os.path.isfile( "database/arcaea_database.db"): with Connect('./database/old_arcaea_database.db') as c1: with Connect() as c2: update_one_table(c1, c2, 'user') update_one_table(c1, c2, 'friend') update_one_table(c1, c2, 'best_score') update_one_table(c1, c2, 'recent30') update_one_table(c1, c2, 'user_world') update_one_table(c1, c2, 'item') update_one_table(c1, c2, 'user_item') update_one_table(c1, c2, 'purchase') update_one_table(c1, c2, 'purchase_item') update_one_table(c1, c2, 'user_save') update_one_table(c1, c2, 'login') update_one_table(c1, c2, 'present') update_one_table(c1, c2, 'user_present') update_one_table(c1, c2, 'present_item') update_one_table(c1, c2, 'redeem') update_one_table(c1, c2, 'user_redeem') update_one_table(c1, c2, 'redeem_item') update_one_table(c1, c2, 'role') update_one_table(c1, c2, 'user_role') update_one_table(c1, c2, 'power') update_one_table(c1, c2, 'role_power') update_one_table(c1, c2, 'api_auth') update_one_table(c1, c2, 'user_char') # ---You can comment this line by yourself, if you want to only keep newest official character data. update_one_table(c1, c2, 'character') # --- update_user_char(c2) # 更新user_char_full os.remove('database/old_arcaea_database.db') # songs if os.path.isfile("database/old_arcsong.db") and os.path.isfile( "database/arcsong.db"): with Connect('./database/old_arcsong.db') as c1: with Connect('./database/arcsong.db') as c2: update_one_table(c1, c2, 'songs') os.remove('database/old_arcsong.db')
def update_database(): # 将old数据库不存在数据加入到新数据库上,并删除old数据库 # 对于arcaea_datebase.db,更新一些表,并用character数据更新user_char_full # 对于arcsong.db,更新songs if os.path.isfile("database/old_arcaea_database.db") and os.path.isfile( "database/arcaea_database.db"): with Connect('./database/old_arcaea_database.db') as c1: with Connect() as c2: update_one_table(c1, c2, 'user') update_one_table(c1, c2, 'friend') update_one_table(c1, c2, 'best_score') update_one_table(c1, c2, 'recent30') update_one_table(c1, c2, 'user_world') update_one_table(c1, c2, 'item') update_one_table(c1, c2, 'user_item') update_one_table(c1, c2, 'purchase') update_one_table(c1, c2, 'purchase_item') update_one_table(c1, c2, 'user_save') update_one_table(c1, c2, 'login') update_one_table(c1, c2, 'present') update_one_table(c1, c2, 'user_present') update_one_table(c1, c2, 'present_item') update_one_table(c1, c2, 'redeem') update_one_table(c1, c2, 'user_redeem') update_one_table(c1, c2, 'redeem_item') update_one_table(c1, c2, 'role') update_one_table(c1, c2, 'user_role') update_one_table(c1, c2, 'power') update_one_table(c1, c2, 'role_power') update_one_table(c1, c2, 'api_login') update_one_table(c1, c2, 'user_char') if not Config.UPDATE_WITH_NEW_CHARACTER_DATA: update_one_table(c1, c2, 'character') update_user_char(c2) # 更新user_char_full os.remove('database/old_arcaea_database.db') # songs if os.path.isfile("database/old_arcsong.db") and os.path.isfile( "database/arcsong.db"): with Connect('./database/old_arcsong.db') as c1: with Connect('./database/arcsong.db') as c2: update_one_table(c1, c2, 'songs') os.remove('database/old_arcsong.db')
def change_purchase_delete(): # 删除购买信息 error = None try: purchase_name = request.form['purchase_name'] except: error = '数据错误 Wrong data.' flash(error) return redirect(url_for('index.change_purchase')) with Connect() as c: c.execute( '''select exists(select * from purchase where purchase_name=:a)''', {'a': purchase_name}) if c.fetchone() == (1, ): c.execute('''delete from purchase where purchase_name=?''', (purchase_name, )) c.execute('''delete from purchase_item where purchase_name=?''', (purchase_name, )) flash('购买信息删除成功 Successfully delete the purchase.') else: error = '购买信息不存在 The purchase does not exist.' if error: flash(error) return render_template('web/changepurchase.html')
def update_character(): # 更新角色数据 with Connect() as c: web.system.update_user_char(c) flash('数据更新成功 Success update data.') return redirect(url_for('index.change_character'))
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 x = None with Connect('./database/arcsong.db') as c: song_name = '%' + song_name + '%' c.execute( '''select sid, name_en from songs where sid like :a limit 1''', {'a': song_name}) x = c.fetchone() 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 delete_user_score(): # 删除用户所有成绩 error = None name = request.form['name'] user_code = request.form['user_code'] with Connect() as c: if name or user_code: 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() if user_id: user_id = user_id[0] web.system.clear_user_score(c, user_id) flash("用户成绩删除成功 Successfully delete the user's scores.") else: error = '玩家不存在 The player does not exist.' else: error = '输入为空 Null Input.' if error: flash(error) return redirect(url_for('index.ban_user'))
def one_redeem(code): # 某个兑换码的用户使用情况数据 error = None with Connect() as c: c.execute( '''select user_id, name, user_code from user where user_id in (select user_id from user_redeem where code=:a)''', {'a': code}) x = c.fetchall() if x: posts = [] for i in x: posts.append({ 'user_id': i[0], 'name': i[1], 'user_code': i[2] }) else: error = '没有数据 No data.' if error: flash(error) return render_template('web/redeem.html', code=code) else: return render_template('web/redeem.html', posts=posts, code=code)
def buy_thing(user_id, purchase_id): # 购买物品接口,返回字典 success_flag = False ticket = 0 packs = [] singles = [] characters = [] with Connect() as c: c.execute( '''select price, orig_price, discount_from, discount_to from purchase where purchase_name=:a''', {'a': purchase_id}) x = c.fetchone() price = 0 flag = False if x: price = x[0] orig_price = x[1] discount_from = x[2] discount_to = x[3] else: return {"success": False, "error_code": 501} c.execute( '''select item_id, type, amount from purchase_item where purchase_name=:a''', {'a': purchase_id}) x = c.fetchall() if x: now = int(time.time() * 1000) if not (discount_from <= now <= discount_to): price = orig_price flag, ticket = buy_item(c, user_id, price) if flag: for i in x: if i[2]: amount = i[2] else: amount = 1 server.item.claim_user_item(c, user_id, i[0], i[1], amount) success_flag = True else: return {"success": False, "error_code": 501} packs = server.item.get_user_items(c, user_id, 'pack') singles = server.item.get_user_items(c, user_id, 'single') characters = server.character.get_user_characters(c, user_id) return { "success": success_flag, "value": { 'user_id': user_id, 'ticket': ticket, 'packs': packs, 'singles': singles, 'characters': characters } }
def all_present(): # 所有奖励数据 error = None with Connect() as c: c.execute('''select * from present''') x = c.fetchall() if x: posts = [] for i in x: items = json.loads(i[2]) items_string = '' for j in items: items_string = items_string + '\n' + \ str(j['id']) + ': ' + str(j['amount']) posts.append({ 'present_id': i[0], 'expire_ts': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(i[1]) // 1000)), 'items': items_string, 'description': i[3] }) else: error = '没有奖励数据 No present data.' if error: flash(error) return render_template('web/allpresent.html') else: return render_template('web/allpresent.html', posts=posts)
def all_character(): # 所有角色数据 error = None with Connect() as c: c.execute('''select * from character''') x = c.fetchall() if x: posts = [] for i in x: posts.append({ 'character_id': i[0], 'name': i[1], 'level': i[2], 'frag': i[5], 'prog': i[6], 'overdrive': i[7], 'skill_id': i[8], 'skill_id_uncap': i[11], 'char_type': i[12], 'is_uncapped': i[14] == 1 }) else: error = '没有角色数据 No character data.' if error: flash(error) return render_template('web/allchar.html') else: return render_template('web/allchar.html', posts=posts)
def all_redeem(): # 所有兑换码数据 error = None with Connect() as c: c.execute('''select * from redeem''') x = c.fetchall() if x: posts = [] for i in x: items = json.loads(i[1]) items_string = '' for j in items: items_string = items_string + '\n' + \ str(j['id']) + ': ' + str(j['amount']) posts.append({ 'code': i[0], 'items': items_string, 'type': i[2] }) else: error = '没有兑换码数据 No redeem code data.' if error: flash(error) return render_template('web/allredeem.html') else: return render_template('web/allredeem.html', posts=posts)
def char_uncap(user_id, character_id): # 角色觉醒,返回user_id,core状态,角色状态的字典 r = None with Connect() as c: c.execute('''select * from char_item where character_id=?''', (character_id, )) x = c.fetchall() if not x: return None success = True for i in x: c.execute( '''select amount from user_item where user_id=? and item_id=? and type=?''', (user_id, i[1], i[2])) y = c.fetchone() if not y or i[3] > y[0]: success = False break if success: c.execute( '''update user_char set is_uncapped=1, is_uncapped_override=0 where user_id=? and character_id=?''', (user_id, character_id)) for i in x: server.item.claim_user_item(c, user_id, i[1], i[2], -i[3]) r = {'character': [get_one_character(c, user_id, character_id)]} r['cores'] = server.item.get_user_cores(c, user_id) r['user_id'] = user_id return r
def char_use_core(user_id, character_id, amount): # 以太之滴升级,返回user_id,core状态,角色状态的字典 r = None with Connect() as c: c.execute( '''select amount from user_item where user_id=? and item_id="core_generic" and type="core"''', (user_id, )) x = c.fetchone() if x: pre_amount = x[0] else: pre_amount = 0 if amount <= pre_amount: c.execute( '''select exp from user_char where user_id=? and character_id=?''', (user_id, character_id)) x = c.fetchone() if x: exp, level = calc_level_up(c, user_id, character_id, x[0], amount * Config.CORE_EXP) c.execute( '''update user_char set level=?, exp=? where user_id=? and character_id=?''', (level, exp, user_id, character_id)) server.item.claim_user_item(c, user_id, 'core_generic', 'core', -amount) r = {'character': [get_one_character(c, user_id, character_id)]} r['cores'] = server.item.get_user_cores(c, user_id) r['user_id'] = user_id return r
def change_char(user_id, character_id, skill_sealed): # 角色改变,包括技能封印的改变,返回成功与否的布尔值 re = False with Connect() as c: 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 }) re = True return re
def arc_sys_set(user_id, value, set_arg): # 三个设置,PTT隐藏、体力满通知、最爱角色,无返回 with Connect() as c: 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 }) return None
def buy_stamina_by_fragment(user_id): # 残片买体力,返回字典和错误码 r = {} with Connect() as c: c.execute('''select next_fragstam_ts from user where user_id=?''', (user_id, )) x = c.fetchone() if x: now = int(time.time() * 1000) next_fragstam_ts = x[0] if x[0] else 0 if now < next_fragstam_ts: return {}, 905 next_fragstam_ts = now + 24 * 3600 * 1000 max_stamina_ts, stamina = add_stamina(c, user_id, 6) c.execute( '''update user set next_fragstam_ts=?, max_stamina_ts=?, stamina=? where user_id=?''', (next_fragstam_ts, max_stamina_ts, stamina, user_id)) r = { "user_id": user_id, "stamina": stamina, "max_stamina_ts": max_stamina_ts, "next_fragstam_ts": next_fragstam_ts } return r, None
def get_single_purchase(): # main里面没开数据库,这里写一下代替 re = [] with Connect() as c: re = get_purchase(c, type='single') return re
def arc_score_top(song_id, difficulty, limit=20): # 得到top分数表,默认最多20个,如果是负数则全部查询 r = [] with Connect() as c: 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() 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) return r
def all_redeem(): # 所有兑换码数据 error = None with Connect() as c: c.execute('''select * from redeem''') x = c.fetchall() if x: posts = [] for i in x: items = [] c.execute('''select * from redeem_item where code=?''', (i[0], )) y = c.fetchall() for j in y: if j is not None: items.append({ 'item_id': j[1], 'type': j[2], 'amount': j[3] }) posts.append({'code': i[0], 'items': items, 'type': i[1]}) else: error = '没有兑换码数据 No redeem code data.' if error: flash(error) return render_template('web/allredeem.html') else: return render_template('web/allredeem.html', posts=posts)
def get_one_ptt(song_id, difficulty, score: int) -> float: # 单曲ptt计算,ptt为负说明没铺面定数数据 ptt = -10 with Connect('./database/arcsong.db') as c: 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 # 没在库里的全部当做定数-10 if x is not None and x != '': defnum = float(x[0]) / 10 if defnum <= 0: defnum = -10 # 缺少难度的当做定数-10 if score >= 10000000: ptt = defnum + 2 elif score < 9800000: ptt = defnum + (score - 9500000) / 300000 if ptt < 0 and defnum != -10: ptt = 0 else: ptt = defnum + 1 + (score - 9800000) / 200000 return ptt
def ban_user(): # 封禁用户 if request.method == 'GET': return render_template('web/banuser.html') error = None name = request.form['name'] user_code = request.form['user_code'] with Connect() as c: if name or user_code: 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() if user_id: user_id = user_id[0] web.system.ban_one_user(c, user_id) flash('用户封禁成功 Successfully ban the user.') else: error = '玩家不存在 The player does not exist.' else: error = '输入为空 Null Input.' if error: flash(error) return redirect(url_for('index.ban_user'))
def play_world_song(user_id, args): # 声明是世界模式的打歌,并且记录加成信息 with Connect() as c: stamina_multiply = 1 fragment_multiply = 100 prog_boost_multiply = 0 if 'stamina_multiply' in args: stamina_multiply = int(args['stamina_multiply']) if 'fragment_multiply' in args: fragment_multiply = int(args['fragment_multiply']) if 'prog_boost_multiply' in args: c.execute('''select prog_boost from user where user_id=:a''', {'a': user_id}) x = c.fetchone() if x and x[0] == 1: prog_boost_multiply = 300 c.execute( '''delete from world_songplay where user_id=:a and song_id=:b and difficulty=:c''', { 'a': user_id, 'b': args['song_id'], 'c': args['difficulty'] }) c.execute( '''insert into world_songplay values(:a,:b,:c,:d,:e,:f)''', { 'a': user_id, 'b': args['song_id'], 'c': args['difficulty'], 'd': stamina_multiply, 'e': fragment_multiply, 'f': prog_boost_multiply }) return None
def all_song(): # 所有歌曲数据 def defnum(x): # 定数转换 if x >= 0: return x / 10 else: return None error = None with Connect('./database/arcsong.db') as c: c.execute('''select * from songs''') x = c.fetchall() if x: posts = [] for i in x: posts.append({ 'song_id': i[0], 'name_en': i[1], 'rating_pst': defnum(i[13]), 'rating_prs': defnum(i[14]), 'rating_ftr': defnum(i[15]), 'rating_byn': defnum(i[16]) }) else: error = '没有铺面数据 No song data.' if error: flash(error) return render_template('web/allsong.html') else: return render_template('web/allsong.html', posts=posts)
def login(auth: str, ip: str): # 登录接口,返回字典和错误码 try: auth_decode = bytes.decode(base64.b64decode(auth)) except: return {}, -100 if not ':' in auth_decode: return {}, -100 name, password = auth_decode.split(':', 1) with Connect() as c: hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest() c.execute('''select user_id, password from user where name = :name''', {'name': name}) x = c.fetchone() if x is None: return {}, -201 if x[1] == '': return {}, -202 if hash_pwd != x[1]: return {}, -201 user_id = str(x[0]) now = int(time.time() * 1000) token = hashlib.sha256((user_id + str(random.randint(10000, 99999)) + str(now)).encode("utf8")).hexdigest() c.execute('''delete from api_login where user_id=?''', (user_id, )) c.execute('''insert into api_login values(?,?,?,?)''', (user_id, token, now, ip)) return {'token': token, 'user_id': user_id}, 0
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: with Connect() as c: 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.' else: error = '输入为空 Null Input.' if error: flash(error) else: return render_template('web/singleplayer.html', posts=posts) return render_template('web/singleplayer.html')
def get_user_world(user_id, map_id): # 获取用户图信息,返回字典 re = {} with Connect() as c: c.execute( '''select * from user_world where map_id = :a and user_id = :b''', { 'a': map_id, 'b': user_id }) x = c.fetchone() re = { "user_id": user_id, "curr_position": 0, "curr_capture": 0, "is_locked": True, "map_id": map_id } if x: re['curr_position'] = x[2] re['curr_capture'] = x[3] re['is_locked'] = int2b(x[4]) else: c.execute('''insert into user_world values(:a,:b,0,0,1)''', { 'a': user_id, 'b': map_id }) return re
def change_item_delete(): # 删除物品信息 error = None try: item_id = request.form['item_id'] item_type = request.form['type'] except: error = '数据错误 Wrong data.' flash(error) return redirect(url_for('index.change_item')) with Connect() as c: c.execute( '''select exists(select * from item where item_id=:a and type=:b)''', { 'a': item_id, 'b': item_type }) if c.fetchone() == (1, ): c.execute('''delete from item where item_id=? and type=?''', (item_id, item_type)) flash('物品删除成功 Successfully delete the item.') else: error = '物品不存在 The item does not exist.' if error: flash(error) return render_template('web/changeitem.html')
def unlock_user_world(user_id, map_id): # 解锁用户的图,返回成功与否布尔值 with Connect() as c: c.execute( '''select is_locked from user_world where map_id=? and user_id=?''', (map_id, user_id)) x = c.fetchone() if x: is_locked = x[0] else: is_locked = 1 c.execute('''insert into user_world values(:a,:b,0,0,1)''', { 'a': user_id, 'b': map_id }) if is_locked == 1: map_info = get_world_info(map_id) if 'require_type' in map_info and map_info['require_type'] != '': if map_info['require_type'] in ['pack', 'single']: c.execute( '''select exists(select * from user_item where user_id=? and item_id=? and type=?)''', (user_id, map_info['require_id'], map_info['require_type'])) if c.fetchone() == (0, ): return False c.execute( '''update user_world set is_locked=0 where user_id=? and map_id=?''', (user_id, map_id)) return True
def change_purchase_item_delete(): # 删除购买的物品信息 error = None try: purchase_name = request.form['purchase_name'] item_id = request.form['item_id'] item_type = request.form['type'] except: error = '数据错误 Wrong data.' flash(error) return redirect(url_for('index.change_purchase_item')) with Connect() as c: c.execute( '''select exists(select * from purchase_item where purchase_name=? and item_id=? and type=?)''', (purchase_name, item_id, item_type)) if c.fetchone() == (1, ): c.execute( '''delete from purchase_item where purchase_name=? and item_id=? and type=?''', (purchase_name, item_id, item_type)) flash('''购买项目的物品删除成功 Successfully delete the purchase's item.''') else: error = '''购买项目的物品不存在 The purchase's item does not exist.''' if error: flash(error) return render_template('web/changepurchaseitem.html')
def get_user_world_info(user_id, map_id): # 读取json文件内容,加上用户信息,返回字典 info = get_world_info(map_id) with Connect() as c: c.execute( '''select * from user_world where map_id = :a and user_id = :b''', { 'a': map_id, 'b': user_id }) x = c.fetchone() if x: info['curr_position'] = x[2] info['curr_capture'] = x[3] info['is_locked'] = int2b(x[4]) else: info['curr_position'] = 0 info['curr_capture'] = 0 info['is_locked'] = True c.execute('''insert into user_world values(:a,:b,0,0,1)''', { 'a': user_id, 'b': map_id }) return info