mirror of
https://github.com/Lost-MSth/Arcaea-server.git
synced 2025-12-14 08:06:23 +08:00
Waiting for updating
+ new character + new byd map + new items + some new configs + two new operations in background + record email while registering + record ip while logging in + checking something before running and updating database automatically building something about API fix bugs: about purchasing system about hiding ptt about login different accounts with same device about some details This is only a pre updating. Many things have been changed. It takes time to find some ways.
This commit is contained in:
119
latest version/api/api_auth.py
Normal file
119
latest version/api/api_auth.py
Normal file
@@ -0,0 +1,119 @@
|
||||
import hashlib
|
||||
import time
|
||||
from server.sql import Connect
|
||||
import functools
|
||||
from setting import Config
|
||||
from flask import jsonify
|
||||
|
||||
|
||||
class User():
|
||||
# 用户类,当数据类型用
|
||||
def __init__(self, user_id=None, role='', power=[]):
|
||||
self.user_id = user_id
|
||||
self.role = role
|
||||
self.power = power
|
||||
|
||||
|
||||
def login():
|
||||
# 登录接口
|
||||
return {'token': 1}, 0
|
||||
|
||||
|
||||
def logout():
|
||||
# 登出接口
|
||||
pass
|
||||
|
||||
|
||||
def id_get_role_id(c, user_id):
|
||||
# user_id获取role_id
|
||||
role_id = 1
|
||||
c.execute('''select role_id from user_role where user_id = :a''',
|
||||
{'a': user_id})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
role_id = int(x[0])
|
||||
|
||||
return role_id
|
||||
|
||||
|
||||
def role_id_get_role(c, role_id):
|
||||
# role_id获取role
|
||||
role = ''
|
||||
c.execute('''select role_name from role where role_id = :a''',
|
||||
{'a': role_id})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
role = x[0]
|
||||
|
||||
return role
|
||||
|
||||
|
||||
def api_token_get_id(c, token):
|
||||
# api的token获取user_id
|
||||
user_id = None
|
||||
c.execute('''select user_id from api_login where token = :token''', {
|
||||
'token': token})
|
||||
x = c.fetchone()
|
||||
if x is not None:
|
||||
user_id = x[0]
|
||||
|
||||
return user_id
|
||||
|
||||
|
||||
def get_role_power(c, role_id):
|
||||
# 获取role_id对应power,返回列表
|
||||
|
||||
role_power = []
|
||||
|
||||
c.execute('''select power_name from power where power_id in (select power_id from role_power where role_id=:a)''', {
|
||||
'a': role_id})
|
||||
x = c.fetchall()
|
||||
for i in x:
|
||||
role_power.append(i[0])
|
||||
|
||||
return role_power
|
||||
|
||||
|
||||
def role_required(request, power=[]):
|
||||
# api token验证,写成了修饰器
|
||||
def decorator(view):
|
||||
@functools.wraps(view)
|
||||
def wrapped_view(*args, **kwargs):
|
||||
|
||||
try:
|
||||
request.json # 检查请求json格式
|
||||
except:
|
||||
return jsonify({'status': 400, 'code': -1, 'data': {}, 'msg': 'Payload must be a valid json'})
|
||||
|
||||
if not 'Token' in request.headers:
|
||||
return jsonify({'status': 401, 'code': -1, 'data': {}, 'msg': 'No Token'})
|
||||
|
||||
user = User()
|
||||
if power == []:
|
||||
if Config.API_TOKEN == request.headers['Token'] and Config.API_TOKEN != '':
|
||||
user.user_id = 0
|
||||
else:
|
||||
return jsonify({'status': 403, 'code': -1, 'data': {}, 'msg': 'No permission'})
|
||||
else:
|
||||
with Connect() as c:
|
||||
user.user_id = api_token_get_id(
|
||||
c, request.headers['Token'])
|
||||
if user.user_id is None:
|
||||
return jsonify({'status': 404, 'code': -1, 'data': {}, 'msg': ''})
|
||||
|
||||
role_id = id_get_role_id(c, user.user_id)
|
||||
user.role = role_id_get_role(c, role_id)
|
||||
user.role_power = get_role_power(c, role_id)
|
||||
|
||||
f = False
|
||||
for i in power:
|
||||
if i in user.role_power:
|
||||
f = True
|
||||
break
|
||||
if not f:
|
||||
return jsonify({'status': 403, 'code': -1, 'data': {}, 'msg': 'No permission'})
|
||||
|
||||
return view(user, *args, **kwargs)
|
||||
|
||||
return wrapped_view
|
||||
return decorator
|
||||
15
latest version/api/api_code.py
Normal file
15
latest version/api/api_code.py
Normal file
@@ -0,0 +1,15 @@
|
||||
def code_get_msg(code):
|
||||
# api接口code获取msg,返回字符串
|
||||
msg = {
|
||||
'0': '',
|
||||
'-1': 'See status code',
|
||||
'-2': 'No data',
|
||||
'-3': 'No data or user',
|
||||
'-4': 'No user_id',
|
||||
'-101': 'Wrong data type',
|
||||
'-102': 'Wrong query parameter',
|
||||
'-103': 'Wrong sort parameter',
|
||||
'-104': 'Wrong sort order parameter'
|
||||
}
|
||||
|
||||
return msg[str(code)]
|
||||
223
latest version/api/api_main.py
Normal file
223
latest version/api/api_main.py
Normal file
@@ -0,0 +1,223 @@
|
||||
from flask import (
|
||||
Blueprint, request, jsonify
|
||||
)
|
||||
import api.api_auth
|
||||
import api.users
|
||||
import api.songs
|
||||
from api.api_code import code_get_msg
|
||||
|
||||
|
||||
bp = Blueprint('api', __name__, url_prefix='/api/v1')
|
||||
|
||||
|
||||
def get_query_parameter(request, query_able=[], sort_able=[]):
|
||||
# 提取查询请求参数,返回四个参数和code
|
||||
|
||||
limit = -1
|
||||
offset = 0
|
||||
query = {} # {'name': 'admin'}
|
||||
sort = [] # [{'column': 'user_id', 'order': 'ASC'}, ...]
|
||||
|
||||
if 'limit' in request.json:
|
||||
try:
|
||||
limit = int(request.json['limit'])
|
||||
except:
|
||||
return -1, 0, {}, {}, -101
|
||||
if 'offset' in request.json:
|
||||
try:
|
||||
offset = int(request.json['offset'])
|
||||
except:
|
||||
return -1, 0, {}, {}, -101
|
||||
if 'query' in request.json:
|
||||
query = request.json['query']
|
||||
for i in query:
|
||||
if i not in query_able:
|
||||
return -1, 0, {}, {}, -102
|
||||
if 'sort' in request.json:
|
||||
sort = request.json['sort']
|
||||
for i in sort:
|
||||
if 'column' not in i or i['column'] not in sort_able:
|
||||
return -1, 0, {}, {}, -103
|
||||
if not 'order' in i:
|
||||
i['order'] = 'ASC'
|
||||
else:
|
||||
if i['order'] not in ['ASC', 'DESC']:
|
||||
return -1, 0, {}, {}, -104
|
||||
|
||||
return limit, offset, query, sort, 0
|
||||
|
||||
|
||||
@bp.route('/')
|
||||
def ping():
|
||||
return jsonify({'status': 200, 'code': 0, 'data': {}, 'msg': ''})
|
||||
|
||||
|
||||
@bp.route('/token', methods=['POST'])
|
||||
def token_post():
|
||||
# 登录,获取token
|
||||
|
||||
if 'auth' in request.json:
|
||||
data, code = api.api_auth.login(
|
||||
request.json['auth'], request.remote_addr)
|
||||
if code < 0:
|
||||
return jsonify({'status': 200, 'code': code, 'data': {}, 'msg': code_get_msg(code)})
|
||||
else:
|
||||
return jsonify({'status': 200, 'code': 0, 'data': data, 'msg': ''})
|
||||
else:
|
||||
return jsonify({'status': 401, 'code': -1, 'data': {}, 'msg': 'No authentication'})
|
||||
|
||||
|
||||
@bp.route('/token', methods=['GET'])
|
||||
@api.api_auth.role_required(request, ['select_me', 'select'])
|
||||
def token_get(user):
|
||||
# 判断登录有效性
|
||||
return jsonify({'status': 200, 'code': 0, 'data': {}, 'msg': ''})
|
||||
|
||||
|
||||
@bp.route('/token', methods=['DELETE'])
|
||||
@api.api_auth.role_required(request, ['change_me', 'select_me', 'select'])
|
||||
def token_delete(user):
|
||||
# 登出
|
||||
return jsonify({'status': 200, 'code': 0, 'data': {}, 'msg': ''})
|
||||
|
||||
|
||||
@bp.route('/users', methods=['GET'])
|
||||
@api.api_auth.role_required(request, ['select'])
|
||||
def users_get(user):
|
||||
# 查询全用户信息
|
||||
|
||||
limit, offset, query, sort, code = get_query_parameter(request, ['user_id', 'name', 'user_code'], [
|
||||
'user_id', 'name', 'user_code', 'join_date', 'rating_ptt', 'time_played', 'ticket'])
|
||||
if code < 0:
|
||||
return jsonify({'status': 200, 'code': code, 'data': {}, 'msg': code_get_msg(code)})
|
||||
|
||||
data = api.users.get_users(limit, offset, query, sort)
|
||||
|
||||
if not data:
|
||||
return jsonify({'status': 200, 'code': -2, 'data': {}, 'msg': code_get_msg(-2)})
|
||||
|
||||
return jsonify({'status': 200, 'code': 0, 'data': data, 'msg': ''})
|
||||
|
||||
|
||||
@bp.route('/users/<int:user_id>', methods=['GET'])
|
||||
@api.api_auth.role_required(request, ['select', 'select_me'])
|
||||
def users_user_get(user, user_id):
|
||||
# 查询用户信息
|
||||
|
||||
if user_id == 'me':
|
||||
user_id = user.user_id
|
||||
|
||||
if user_id <= 0:
|
||||
return jsonify({'status': 200, 'code': -4, 'data': {}, 'msg': code_get_msg(-4)})
|
||||
|
||||
if user_id != user.user_id and not 'select' in user.power and user.user_id != 0: # 查别人需要select权限
|
||||
return jsonify({'status': 403, 'code': -1, 'data': {}, 'msg': 'No permission'})
|
||||
|
||||
data = api.users.get_user_info(user_id)
|
||||
|
||||
if not data:
|
||||
return jsonify({'status': 200, 'code': -3, 'data': {}, 'msg': code_get_msg(-3)})
|
||||
|
||||
return jsonify({'status': 200, 'code': 0, 'data': data, 'msg': ''})
|
||||
|
||||
|
||||
@bp.route('/users/<int:user_id>/b30', methods=['GET'])
|
||||
@api.api_auth.role_required(request, ['select', 'select_me'])
|
||||
def users_user_b30_get(user, user_id):
|
||||
# 查询用户b30
|
||||
|
||||
if user_id == 'me':
|
||||
user_id = user.user_id
|
||||
|
||||
if user_id <= 0:
|
||||
return jsonify({'status': 200, 'code': -4, 'data': {}, 'msg': code_get_msg(-4)})
|
||||
|
||||
if user_id != user.user_id and not 'select' in user.power and user.user_id != 0: # 查别人需要select权限
|
||||
return jsonify({'status': 403, 'code': -1, 'data': {}, 'msg': 'No permission'})
|
||||
|
||||
data = api.users.get_user_b30(user_id)
|
||||
|
||||
if data['data'] == []:
|
||||
return jsonify({'status': 200, 'code': -3, 'data': {}, 'msg': code_get_msg(-3)})
|
||||
|
||||
return jsonify({'status': 200, 'code': 0, 'data': data, 'msg': ''})
|
||||
|
||||
|
||||
@bp.route('/users/<int:user_id>/best', methods=['GET'])
|
||||
@api.api_auth.role_required(request, ['select', 'select_me'])
|
||||
def users_user_best_get(user, user_id):
|
||||
# 查询用户所有best成绩
|
||||
|
||||
if user_id == 'me':
|
||||
user_id = user.user_id
|
||||
|
||||
if user_id <= 0:
|
||||
return jsonify({'status': 200, 'code': -4, 'data': {}, 'msg': code_get_msg(-4)})
|
||||
|
||||
if user_id != user.user_id and not 'select' in user.power and user.user_id != 0: # 查别人需要select权限
|
||||
return jsonify({'status': 403, 'code': -1, 'data': {}, 'msg': 'No permission'})
|
||||
|
||||
limit, offset, query, sort, code = get_query_parameter(request, ['song_id', 'difficulty'], [
|
||||
'song_id', 'difficulty', 'score', 'time_played', 'rating'])
|
||||
if code < 0:
|
||||
return jsonify({'status': 200, 'code': code, 'data': {}, 'msg': code_get_msg(code)})
|
||||
|
||||
data = api.users.get_user_best(user_id, limit, offset, query, sort)
|
||||
|
||||
if data['data'] == []:
|
||||
return jsonify({'status': 200, 'code': -3, 'data': {}, 'msg': code_get_msg(-3)})
|
||||
|
||||
return jsonify({'status': 200, 'code': 0, 'data': data, 'msg': ''})
|
||||
|
||||
|
||||
@bp.route('/users/<int:user_id>/r30', methods=['GET'])
|
||||
@api.api_auth.role_required(request, ['select', 'select_me'])
|
||||
def users_user_r30_get(user, user_id):
|
||||
# 查询用户r30
|
||||
|
||||
if user_id == 'me':
|
||||
user_id = user.user_id
|
||||
|
||||
if user_id <= 0:
|
||||
return jsonify({'status': 200, 'code': -4, 'data': {}, 'msg': code_get_msg(-4)})
|
||||
|
||||
if user_id != user.user_id and not 'select' in user.power and user.user_id != 0: # 查别人需要select权限
|
||||
return jsonify({'status': 403, 'code': -1, 'data': {}, 'msg': 'No permission'})
|
||||
|
||||
data = api.users.get_user_r30(user_id)
|
||||
|
||||
if data['data'] == []:
|
||||
return jsonify({'status': 200, 'code': -3, 'data': {}, 'msg': code_get_msg(-3)})
|
||||
|
||||
return jsonify({'status': 200, 'code': 0, 'data': data, 'msg': ''})
|
||||
|
||||
|
||||
@bp.route('/songs/<string:song_id>', methods=['GET'])
|
||||
@api.api_auth.role_required(request, ['select', 'select_song_info'])
|
||||
def songs_song_get(user, song_id):
|
||||
# 查询歌曲信息
|
||||
|
||||
data = api.songs.get_song_info(song_id)
|
||||
|
||||
if not data:
|
||||
return jsonify({'status': 200, 'code': -2, 'data': {}, 'msg': code_get_msg(-2)})
|
||||
|
||||
return jsonify({'status': 200, 'code': 0, 'data': data, 'msg': ''})
|
||||
|
||||
|
||||
@bp.route('/songs', methods=['GET'])
|
||||
@api.api_auth.role_required(request, ['select', 'select_song_info'])
|
||||
def songs_get(user):
|
||||
# 查询全歌曲信息
|
||||
|
||||
limit, offset, query, sort, code = get_query_parameter(request, ['sid', 'name_en', 'name_jp', 'pakset', 'artist'], [
|
||||
'sid', 'name_en', 'name_jp', 'pakset', 'artist', 'date', 'rating_pst', 'rating_prs', 'rating_ftr', 'rating_byn'])
|
||||
if code < 0:
|
||||
return jsonify({'status': 200, 'code': code, 'data': {}, 'msg': code_get_msg(code)})
|
||||
|
||||
data = api.songs.get_songs(limit, offset, query, sort)
|
||||
|
||||
if not data:
|
||||
return jsonify({'status': 200, 'code': -2, 'data': {}, 'msg': code_get_msg(-2)})
|
||||
|
||||
return jsonify({'status': 200, 'code': 0, 'data': data, 'msg': ''})
|
||||
58
latest version/api/songs.py
Normal file
58
latest version/api/songs.py
Normal file
@@ -0,0 +1,58 @@
|
||||
from server.sql import Connect
|
||||
from server.sql import Sql
|
||||
import time
|
||||
|
||||
|
||||
def get_song_info(song_id):
|
||||
# 查询指定歌曲信息,返回字典
|
||||
r = {}
|
||||
|
||||
with Connect('./database/arcsong.db') as c:
|
||||
c.execute('''select * from songs where sid=:a''', {'a': song_id})
|
||||
x = c.fetchone()
|
||||
if x:
|
||||
r = {'song_id': x[0],
|
||||
'name': {'name_en': x[1],
|
||||
'name_jp': x[2]},
|
||||
'pakset': x[5],
|
||||
'artist': x[6],
|
||||
'date': x[9],
|
||||
'rating_pst': x[12]/10,
|
||||
'rating_prs': x[13]/10,
|
||||
'rating_ftr': x[14]/10,
|
||||
'rating_byn': x[15]/10,
|
||||
'difficultly_pst': x[16]/2,
|
||||
'difficultly_prs': x[17]/2,
|
||||
'difficultly_ftr': x[18]/2,
|
||||
'difficultly_byn': x[19]/2
|
||||
}
|
||||
|
||||
return r
|
||||
|
||||
|
||||
def get_songs(limit=-1, offset=0, query={}, sort=[]):
|
||||
# 查询全部歌曲信息,返回字典列表
|
||||
r = []
|
||||
|
||||
with Connect('./database/arcsong.db') as c:
|
||||
x = Sql.select(c, 'songs', [], limit, offset, query, sort)
|
||||
|
||||
if x:
|
||||
for i in x:
|
||||
r.append({'sid': i[0],
|
||||
'name': {'name_en': i[1],
|
||||
'name_jp': i[2]},
|
||||
'pakset': i[5],
|
||||
'artist': i[6],
|
||||
'date': i[9],
|
||||
'rating_pst': i[12]/10,
|
||||
'rating_prs': i[13]/10,
|
||||
'rating_ftr': i[14]/10,
|
||||
'rating_byn': i[15]/10,
|
||||
'difficultly_pst': i[16]/2,
|
||||
'difficultly_prs': i[17]/2,
|
||||
'difficultly_ftr': i[18]/2,
|
||||
'difficultly_byn': i[19]/2
|
||||
})
|
||||
|
||||
return r
|
||||
99
latest version/api/users.py
Normal file
99
latest version/api/users.py
Normal file
@@ -0,0 +1,99 @@
|
||||
from server.sql import Connect
|
||||
from server.sql import Sql
|
||||
import time
|
||||
import web.webscore
|
||||
import server.info
|
||||
|
||||
|
||||
def get_users(limit=-1, offset=0, query={}, sort=[]):
|
||||
# 获取全用户信息,返回字典列表
|
||||
|
||||
r = []
|
||||
with Connect() as c:
|
||||
x = Sql.select(c, 'user', [], limit, offset, query, sort)
|
||||
|
||||
if x:
|
||||
for i in x:
|
||||
if i[23] != -1:
|
||||
character_id = i[23]
|
||||
else:
|
||||
character_id = i[6]
|
||||
r.append({
|
||||
'user_id': i[0],
|
||||
'name': i[1],
|
||||
'join_date': i[3],
|
||||
'user_code': i[4],
|
||||
'rating_ptt': i[5]/100,
|
||||
'character_id': character_id,
|
||||
'is_char_uncapped': i[8] == 1,
|
||||
'is_char_uncapped_override': i[9] == 1,
|
||||
'is_hide_rating': i[10],
|
||||
'ticket': i[26]
|
||||
})
|
||||
|
||||
return r
|
||||
|
||||
|
||||
def get_user_info(user_id):
|
||||
# 获取用户信息,返回字典,其实就是调用user/me信息
|
||||
|
||||
r = {}
|
||||
with Connect() as c:
|
||||
r = server.info.get_user_me(c, user_id)
|
||||
|
||||
return r
|
||||
|
||||
|
||||
def get_user_b30(user_id):
|
||||
# 获取用户b30信息,返回字典
|
||||
|
||||
r = []
|
||||
with Connect() as c:
|
||||
r = web.webscore.get_user_score(c, user_id, 30)
|
||||
|
||||
bestptt = 0
|
||||
for i in r:
|
||||
if i['rating']:
|
||||
bestptt += i['rating']
|
||||
if 'time_played' in i:
|
||||
i['time_played'] = int(time.mktime(time.strptime(
|
||||
i['time_played'], '%Y-%m-%d %H:%M:%S')))
|
||||
|
||||
return {'user_id': user_id, 'b30_ptt': bestptt / 30, 'data': r}
|
||||
|
||||
|
||||
def get_user_best(user_id, limit=-1, offset=0, query={}, sort=[]):
|
||||
# 获取用户b30信息,返回字典
|
||||
|
||||
r = []
|
||||
with Connect() as c:
|
||||
x = Sql.select(c, 'best_score', [], limit, offset, query, sort)
|
||||
if x:
|
||||
for i in x:
|
||||
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": i[10],
|
||||
"best_clear_type": i[11],
|
||||
"clear_type": i[12],
|
||||
"rating": i[13]
|
||||
})
|
||||
|
||||
return {'user_id': user_id, 'data': r}
|
||||
|
||||
|
||||
def get_user_r30(user_id):
|
||||
# 获取用户r30信息,返回字典
|
||||
|
||||
r = []
|
||||
with Connect() as c:
|
||||
r, r10_ptt = web.webscore.get_user_recent30(c, user_id)
|
||||
|
||||
return {'user_id': user_id, 'r10_ptt': r10_ptt, 'data': r}
|
||||
@@ -5,372 +5,430 @@ import json
|
||||
|
||||
# 数据库初始化文件,删掉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,
|
||||
current_map text,
|
||||
ticket int,
|
||||
prog_boost int
|
||||
);''')
|
||||
c.execute('''create table if not exists login(access_token text,
|
||||
user_id int,
|
||||
login_time int,
|
||||
login_ip text,
|
||||
login_device text,
|
||||
primary key(access_token, user_id)
|
||||
);''')
|
||||
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 real,
|
||||
prog real,
|
||||
overdrive real,
|
||||
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 real,
|
||||
prog real,
|
||||
overdrive real,
|
||||
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
|
||||
);''')
|
||||
c.execute('''create table if not exists user_world(user_id int,
|
||||
map_id text,
|
||||
curr_position int,
|
||||
curr_capture real,
|
||||
is_locked int,
|
||||
primary key(user_id, map_id)
|
||||
);''')
|
||||
c.execute('''create table if not exists world_songplay(user_id int,
|
||||
song_id text,
|
||||
difficulty int,
|
||||
stamina_multiply int,
|
||||
fragment_multiply int,
|
||||
prog_boost_multiply int,
|
||||
primary key(user_id, song_id, difficulty)
|
||||
);''')
|
||||
c.execute('''create table if not exists download_token(user_id int,
|
||||
song_id text,
|
||||
file_name text,
|
||||
token text,
|
||||
time int,
|
||||
primary key(user_id, song_id, file_name)
|
||||
);''')
|
||||
c.execute('''create table if not exists user_download(user_id int,
|
||||
token text,
|
||||
time int,
|
||||
primary key(user_id, token, time)
|
||||
);''')
|
||||
c.execute('''create table if not exists item(item_id text,
|
||||
type text,
|
||||
is_available int,
|
||||
price int,
|
||||
orig_price int,
|
||||
discount_from int,
|
||||
discount_to int,
|
||||
_id text,
|
||||
primary key(item_id, type)
|
||||
);''')
|
||||
c.execute('''create table if not exists user_item(user_id int,
|
||||
item_id text,
|
||||
type text,
|
||||
primary key(user_id, item_id, type)
|
||||
);''')
|
||||
c.execute('''create table if not exists user_save(user_id int primary key,
|
||||
scores_data text,
|
||||
clearlamps_data text,
|
||||
clearedsongs_data text,
|
||||
unlocklist_data text,
|
||||
installid_data text,
|
||||
devicemodelname_data text,
|
||||
story_data text,
|
||||
createdAt int
|
||||
);''')
|
||||
c.execute('''create table if not exists present(present_id text primary key,
|
||||
expire_ts int,
|
||||
items text,
|
||||
description text
|
||||
);''')
|
||||
c.execute('''create table if not exists user_present(user_id int,
|
||||
present_id text,
|
||||
primary key(user_id, present_id)
|
||||
);''')
|
||||
c.execute('''create table if not exists songfile(song_id text,
|
||||
file_type int,
|
||||
md5 text,
|
||||
primary key(song_id, file_type)
|
||||
);''')
|
||||
c.execute('''create table if not exists redeem(code text primary key,
|
||||
items text,
|
||||
type int
|
||||
);''')
|
||||
c.execute('''create table if not exists user_redeem(user_id int,
|
||||
code text,
|
||||
primary key(user_id, code)
|
||||
);''')
|
||||
ARCAEA_SERVER_VERSION = 'v2.4'
|
||||
|
||||
|
||||
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)', 'Etude', 'Alice & Tenniel', 'Luna & Mia', 'Areus', 'Seele', 'Isabelle', 'Mir']
|
||||
def main(path='./'):
|
||||
conn = sqlite3.connect(path+'arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''create table if not exists config(id text primary key,
|
||||
value text
|
||||
);''')
|
||||
c.execute('''insert into config values("version", :a);''',
|
||||
{'a': ARCAEA_SERVER_VERSION})
|
||||
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,
|
||||
current_map text,
|
||||
ticket int,
|
||||
prog_boost int,
|
||||
email text
|
||||
);''')
|
||||
c.execute('''create table if not exists login(access_token text,
|
||||
user_id int,
|
||||
login_time int,
|
||||
login_ip text,
|
||||
login_device text,
|
||||
primary key(access_token, user_id)
|
||||
);''')
|
||||
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 real,
|
||||
prog real,
|
||||
overdrive real,
|
||||
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 real,
|
||||
prog real,
|
||||
overdrive real,
|
||||
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
|
||||
);''')
|
||||
c.execute('''create table if not exists user_world(user_id int,
|
||||
map_id text,
|
||||
curr_position int,
|
||||
curr_capture real,
|
||||
is_locked int,
|
||||
primary key(user_id, map_id)
|
||||
);''')
|
||||
c.execute('''create table if not exists world_songplay(user_id int,
|
||||
song_id text,
|
||||
difficulty int,
|
||||
stamina_multiply int,
|
||||
fragment_multiply int,
|
||||
prog_boost_multiply int,
|
||||
primary key(user_id, song_id, difficulty)
|
||||
);''')
|
||||
c.execute('''create table if not exists download_token(user_id int,
|
||||
song_id text,
|
||||
file_name text,
|
||||
token text,
|
||||
time int,
|
||||
primary key(user_id, song_id, file_name)
|
||||
);''')
|
||||
c.execute('''create table if not exists user_download(user_id int,
|
||||
token text,
|
||||
time int,
|
||||
primary key(user_id, token, time)
|
||||
);''')
|
||||
c.execute('''create table if not exists item(item_id text,
|
||||
type text,
|
||||
is_available int,
|
||||
price int,
|
||||
orig_price int,
|
||||
discount_from int,
|
||||
discount_to int,
|
||||
_id text,
|
||||
primary key(item_id, type)
|
||||
);''')
|
||||
c.execute('''create table if not exists user_item(user_id int,
|
||||
item_id text,
|
||||
type text,
|
||||
primary key(user_id, item_id, type)
|
||||
);''')
|
||||
c.execute('''create table if not exists user_save(user_id int primary key,
|
||||
scores_data text,
|
||||
clearlamps_data text,
|
||||
clearedsongs_data text,
|
||||
unlocklist_data text,
|
||||
installid_data text,
|
||||
devicemodelname_data text,
|
||||
story_data text,
|
||||
createdAt int
|
||||
);''')
|
||||
c.execute('''create table if not exists present(present_id text primary key,
|
||||
expire_ts int,
|
||||
items text,
|
||||
description text
|
||||
);''')
|
||||
c.execute('''create table if not exists user_present(user_id int,
|
||||
present_id text,
|
||||
primary key(user_id, present_id)
|
||||
);''')
|
||||
c.execute('''create table if not exists songfile(song_id text,
|
||||
file_type int,
|
||||
md5 text,
|
||||
primary key(song_id, file_type)
|
||||
);''')
|
||||
c.execute('''create table if not exists redeem(code text primary key,
|
||||
items text,
|
||||
type int
|
||||
);''')
|
||||
c.execute('''create table if not exists user_redeem(user_id int,
|
||||
code text,
|
||||
primary key(user_id, code)
|
||||
);''')
|
||||
|
||||
skill_id = ['gauge_easy', '', '', '', 'note_mirror', '', '', 'gauge_hard', 'frag_plus_10_pack_stellights', 'gauge_easy|frag_plus_15_pst&prs', 'gauge_hard|fail_frag_minus_100', 'frag_plus_5_side_light', 'visual_hide_hp', 'frag_plus_5_side_conflict', 'challenge_fullcombo_0gauge', 'gauge_overflow', 'gauge_easy|note_mirror', 'note_mirror', 'visual_tomato_pack_tonesphere',
|
||||
'frag_rng_ayu', 'gaugestart_30|gaugegain_70', 'combo_100-frag_1', 'audio_gcemptyhit_pack_groovecoaster', 'gauge_saya', 'gauge_chuni', 'kantandeshou', 'gauge_haruna', 'frags_nono', 'gauge_pandora', 'gauge_regulus', 'omatsuri_daynight', '', '', 'sometimes(note_mirror|frag_plus_5)', 'scoreclear_aa|visual_scoregauge', 'gauge_tempest', 'gauge_hard', 'gauge_ilith_summer', '', 'note_mirror|visual_hide_far', 'frags_ongeki', 'gauge_areus', 'gauge_seele', 'gauge_isabelle', 'gauge_exhaustion']
|
||||
c.execute('''create table if not exists role(role_id int primary key,
|
||||
role_name text,
|
||||
caption text
|
||||
);''')
|
||||
c.execute('''create table if not exists user_role(user_id int,
|
||||
role_id int,
|
||||
primary key(user_id, role_id)
|
||||
);''')
|
||||
c.execute('''create table if not exists power(power_id int primary key,
|
||||
power_name text,
|
||||
caption text
|
||||
);''')
|
||||
c.execute('''create table if not exists role_power(role_id int,
|
||||
power_id int,
|
||||
primary key(role_id, power_id)
|
||||
);''')
|
||||
c.execute('''create table if not exists api_login(user_id int,
|
||||
token text,
|
||||
login_time int,
|
||||
login_ip text,
|
||||
primary key(user_id, token)
|
||||
);''')
|
||||
|
||||
skill_id_uncap = ['', '', 'frags_kou', '', 'visual_ink', '', '', '', '', '', '', '', '', 'shirabe_entry_fee',
|
||||
'', '', '', '', '', '', '', 'frags_yume', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
|
||||
# 搭档初始化
|
||||
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)', 'Etude', 'Alice & Tenniel', 'Luna & Mia', 'Areus', 'Seele', 'Isabelle', 'Mir', 'Lagrange']
|
||||
|
||||
frag = [88, 90, 100, 75, 80, 0, 70, 79, 65, 40, 50, 80, 90, 92, 0, 61, 67, 92, 85, 50, 86, 62,
|
||||
65, 85, 67, 88, 74, 0.5, 105, 80, 95, 50, 80, 87, 71, 50, 95, 0, 80, 75, 50, 70, 80, 100, 65]
|
||||
skill_id = ['gauge_easy', '', '', '', 'note_mirror', '', '', 'gauge_hard', 'frag_plus_10_pack_stellights', 'gauge_easy|frag_plus_15_pst&prs', 'gauge_hard|fail_frag_minus_100', 'frag_plus_5_side_light', 'visual_hide_hp', 'frag_plus_5_side_conflict', 'challenge_fullcombo_0gauge', 'gauge_overflow', 'gauge_easy|note_mirror', 'note_mirror', 'visual_tomato_pack_tonesphere',
|
||||
'frag_rng_ayu', 'gaugestart_30|gaugegain_70', 'combo_100-frag_1', 'audio_gcemptyhit_pack_groovecoaster', 'gauge_saya', 'gauge_chuni', 'kantandeshou', 'gauge_haruna', 'frags_nono', 'gauge_pandora', 'gauge_regulus', 'omatsuri_daynight', '', '', 'sometimes(note_mirror|frag_plus_5)', 'scoreclear_aa|visual_scoregauge', 'gauge_tempest', 'gauge_hard', 'gauge_ilith_summer', '', 'note_mirror|visual_hide_far', 'frags_ongeki', 'gauge_areus', 'gauge_seele', 'gauge_isabelle', 'gauge_exhaustion', 'skill_lagrange']
|
||||
|
||||
prog = [71, 90, 80, 75, 100, 0, 90, 102, 84, 78, 105, 67, 63, 78, 0, 99, 80, 66, 46, 83, 40, 83,
|
||||
80, 90, 93, 50, 96, 88, 99, 108, 75, 80, 50, 64, 55, 100, 100, 110, 80, 50, 74, 90, 80, 80, 56]
|
||||
skill_id_uncap = ['', '', 'frags_kou', '', 'visual_ink', '', '', '', '', '', '', '', '', 'shirabe_entry_fee',
|
||||
'', '', '', '', '', '', '', 'frags_yume', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
|
||||
|
||||
overdrive = [71, 90, 57, 75, 80, 0, 95, 79, 65, 31, 50, 59, 90, 68, 0, 78, 50, 70, 62, 49, 64,
|
||||
56, 73, 95, 67, 84, 80, 88, 79, 80, 50, 80, 80, 63, 25, 50, 82, 55, 50, 95, 55, 70, 100, 80, 90]
|
||||
frag = [88, 90, 100, 75, 80, 0, 70, 79, 65, 40, 50, 80, 90, 92, 0, 61, 67, 92, 85, 50, 86, 62,
|
||||
65, 85, 67, 88, 74, 0.5, 105, 80, 95, 50, 80, 87, 71, 50, 95, 0, 80, 75, 50, 70, 80, 100, 65, 90]
|
||||
|
||||
char_type = [1, 0, 0, 0, 0, 0, 0, 2, 0, 1, 2, 0, 0, 0, 2, 3, 1, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 2, 2, 1]
|
||||
prog = [71, 90, 80, 75, 100, 0, 90, 102, 84, 78, 105, 67, 63, 78, 0, 99, 80, 66, 46, 83, 40, 83,
|
||||
80, 90, 93, 50, 96, 88, 99, 108, 75, 80, 50, 64, 55, 100, 100, 110, 80, 50, 74, 90, 80, 80, 56, 90]
|
||||
|
||||
print(len(char))
|
||||
print(len(skill_id))
|
||||
print(len(skill_id_uncap))
|
||||
print(len(frag))
|
||||
print(len(prog))
|
||||
print(len(overdrive))
|
||||
print(len(char_type))
|
||||
overdrive = [71, 90, 57, 75, 80, 0, 95, 79, 65, 31, 50, 59, 90, 68, 0, 78, 50, 70, 62, 49, 64,
|
||||
56, 73, 95, 67, 84, 80, 88, 79, 80, 50, 80, 80, 63, 25, 50, 82, 55, 50, 95, 55, 70, 100, 80, 90, 90]
|
||||
|
||||
for i in range(0, 45):
|
||||
if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21, 42, 43]:
|
||||
sql = '''insert into character values(:a,:b,30,25000,25000,:c,:d,:e,:f,0,0,:g,:h,'',1,1)'''
|
||||
c.execute(sql, {'a': i, 'b': char[i], 'c': frag[i], 'd': prog[i],
|
||||
'e': overdrive[i], 'f': skill_id[i], 'g': skill_id_uncap[i], 'h': char_type[i]})
|
||||
else:
|
||||
if i != 5:
|
||||
sql = '''insert into character values(:a,:b,20,10000,10000,:c,:d,:e,:f,0,0,:g,:h,'',0,0)'''
|
||||
char_type = [1, 0, 0, 0, 0, 0, 0, 2, 0, 1, 2, 0, 0, 0, 2, 3, 1, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 2, 2, 1, 0]
|
||||
|
||||
# print(len(char))
|
||||
# print(len(skill_id))
|
||||
# print(len(skill_id_uncap))
|
||||
# print(len(frag))
|
||||
# print(len(prog))
|
||||
# print(len(overdrive))
|
||||
# print(len(char_type))
|
||||
|
||||
for i in range(0, 46):
|
||||
if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21, 42, 43]:
|
||||
sql = '''insert into character values(:a,:b,30,25000,25000,:c,:d,:e,:f,0,0,:g,:h,'',1,1)'''
|
||||
c.execute(sql, {'a': i, 'b': char[i], 'c': frag[i], 'd': prog[i],
|
||||
'e': overdrive[i], 'f': skill_id[i], 'g': skill_id_uncap[i], 'h': char_type[i]})
|
||||
|
||||
|
||||
def b2int(x):
|
||||
# int与布尔值转换
|
||||
if x:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def insert_items(c, items):
|
||||
# 物品数据导入
|
||||
for i in items:
|
||||
if 'discount_from' not in i:
|
||||
discount_from = -1
|
||||
else:
|
||||
discount_from = i['discount_from']
|
||||
if 'discount_to' not in i:
|
||||
discount_to = -1
|
||||
if i != 5:
|
||||
sql = '''insert into character values(:a,:b,20,10000,10000,:c,:d,:e,:f,0,0,:g,:h,'',0,0)'''
|
||||
c.execute(sql, {'a': i, 'b': char[i], 'c': frag[i], 'd': prog[i],
|
||||
'e': overdrive[i], 'f': skill_id[i], 'g': skill_id_uncap[i], 'h': char_type[i]})
|
||||
|
||||
def b2int(x):
|
||||
# int与布尔值转换
|
||||
if x:
|
||||
return 1
|
||||
else:
|
||||
discount_to = i['discount_to']
|
||||
for j in i['items']:
|
||||
if "_id" not in j:
|
||||
_id = ''
|
||||
return 0
|
||||
|
||||
def insert_items(c, items):
|
||||
# 物品数据导入
|
||||
for i in items:
|
||||
if 'discount_from' not in i:
|
||||
discount_from = -1
|
||||
else:
|
||||
_id = j['_id']
|
||||
if j['type'] != 'character':
|
||||
c.execute('''insert into item(item_id, type, is_available, price, orig_price, discount_from, discount_to, _id) values(:a,:b,:c,:d,:e,:f,:g,:h)''', {
|
||||
'a': j['id'], 'b': j['type'], 'c': b2int(j['is_available']), 'd': i['price'], 'e': i['orig_price'], 'f': discount_from, 'g': discount_to, 'h': _id})
|
||||
discount_from = i['discount_from']
|
||||
if 'discount_to' not in i:
|
||||
discount_to = -1
|
||||
else:
|
||||
discount_to = i['discount_to']
|
||||
for j in i['items']:
|
||||
if "_id" not in j:
|
||||
_id = ''
|
||||
else:
|
||||
_id = j['_id']
|
||||
if j['type'] != 'character':
|
||||
c.execute('''insert into item(item_id, type, is_available, price, orig_price, discount_from, discount_to, _id) values(:a,:b,:c,:d,:e,:f,:g,:h)''', {
|
||||
'a': j['id'], 'b': j['type'], 'c': b2int(j['is_available']), 'd': i['price'], 'e': i['orig_price'], 'f': discount_from, 'g': discount_to, 'h': _id})
|
||||
|
||||
# item初始化
|
||||
f = open(path+'singles.json', 'r')
|
||||
singles = json.load(f)
|
||||
f.close()
|
||||
insert_items(c, singles)
|
||||
|
||||
f = open('singles.json', 'r')
|
||||
singles = json.load(f)
|
||||
f.close()
|
||||
insert_items(c, singles)
|
||||
f = open(path+'packs.json', 'r')
|
||||
packs = json.load(f)
|
||||
f.close()
|
||||
insert_items(c, packs)
|
||||
|
||||
f = open('packs.json', 'r')
|
||||
packs = json.load(f)
|
||||
f.close()
|
||||
insert_items(c, packs)
|
||||
# api权限与权限组初始化
|
||||
role = ['admin', 'user', 'selecter']
|
||||
role_caption = ['管理员', '用户', '查询接口']
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
power = ['select', 'select_me', 'change', 'change_me', 'grant',
|
||||
'grant_inf', 'select_song_rank', 'select_song_info']
|
||||
power_caption = ['总体查询权限', '自我查询权限', '总体修改权限',
|
||||
'自我修改权限', '授权权限', '下级授权权限', '歌曲排行榜查询权限', '歌曲信息查询权限']
|
||||
|
||||
role_power = {'0': [0, 1, 3, 5, 6, 7],
|
||||
'1': [1, 3, 6, 7],
|
||||
'2': [0]
|
||||
}
|
||||
|
||||
def arc_register(name: str, password: str):
|
||||
def build_user_code(c):
|
||||
return '123456789'
|
||||
for i in range(0, len(role)):
|
||||
c.execute('''insert into role values(:a,:b,:c)''', {
|
||||
'a': i, 'b': role[i], 'c': role_caption[i]})
|
||||
for i in range(0, len(power)):
|
||||
c.execute('''insert into power values(:a,:b,:c)''', {
|
||||
'a': i, 'b': power[i], 'c': power_caption[i]})
|
||||
for i in role_power:
|
||||
for j in role_power[i]:
|
||||
c.execute('''insert into role_power values(:a,:b)''',
|
||||
{'a': int(i), 'b': j})
|
||||
|
||||
def build_user_id(c):
|
||||
return 2000000
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
# 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]})
|
||||
def arc_register(name: str, password: str):
|
||||
def build_user_code(c):
|
||||
return '123456789'
|
||||
|
||||
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, current_map, ticket)
|
||||
values(:user_id, :name, :password, :join_date, :user_code, 1250, 1, 0, 1, 0, 0, -1, 0, '', 114514)
|
||||
''', {'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})
|
||||
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(path+'arcaea_database.db')
|
||||
c = conn.cursor()
|
||||
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
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
|
||||
'''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, current_map, ticket)
|
||||
values(:user_id, :name, :password, :join_date, :user_code, 1250, 1, 0, 1, 0, 0, -1, 0, '', 114514)
|
||||
''', {'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')
|
||||
|
||||
|
||||
arc_register('admin', 'admin123')
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
78
latest version/database/map/byd_lostcivilization.json
Normal file
78
latest version/database/map/byd_lostcivilization.json
Normal file
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"map_id": "byd_lostcivilization",
|
||||
"is_legacy": false,
|
||||
"chapter": 1001,
|
||||
"available_from": -1,
|
||||
"available_to": 9999999999999,
|
||||
"is_repeatable": false,
|
||||
"require_id": "lostcivilization2",
|
||||
"require_type": "chart_unlock",
|
||||
"coordinate": "-650,-900",
|
||||
"is_beyond": true,
|
||||
"stamina_cost": 3,
|
||||
"beyond_health": 250,
|
||||
"character_affinity": [0, 1],
|
||||
"affinity_multiplier": [1.9, 1.9],
|
||||
"step_count": 7,
|
||||
"custom_bg": "",
|
||||
"curr_position": 0,
|
||||
"curr_capture": 0,
|
||||
"is_locked": false,
|
||||
"steps": [{
|
||||
"map_id": "byd_lostcivilization",
|
||||
"position": 0,
|
||||
"capture": 85
|
||||
}, {
|
||||
"map_id": "byd_lostcivilization",
|
||||
"position": 1,
|
||||
"capture": 5,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_lostcivilization",
|
||||
"position": 2,
|
||||
"capture": 5,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_lostcivilization",
|
||||
"position": 3,
|
||||
"capture": 5,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_lostcivilization",
|
||||
"position": 4,
|
||||
"capture": 100,
|
||||
"items": [{
|
||||
"type": "core",
|
||||
"id": "core_generic",
|
||||
"amount": 1
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_lostcivilization",
|
||||
"position": 5,
|
||||
"capture": 50,
|
||||
"items": [{
|
||||
"type": "fragment",
|
||||
"amount": 525
|
||||
}]
|
||||
}, {
|
||||
"map_id": "byd_lostcivilization",
|
||||
"position": 6,
|
||||
"capture": 0,
|
||||
"items": [{
|
||||
"id": "lostcivilization3",
|
||||
"type": "world_song"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
@@ -3,10 +3,9 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "core",
|
||||
"_id": "6046bab736651a07ebc537db",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 400,
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1615248000000,
|
||||
"discount_to": 1615852799000
|
||||
@@ -15,15 +14,13 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "shiawase",
|
||||
"_id": "6046bab736651a07ebc53823",
|
||||
"is_available": true
|
||||
}, {
|
||||
"type": "character",
|
||||
"id": "kou",
|
||||
"_id": "6046bab736651a07ebc53822",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 250,
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1615248000000,
|
||||
"discount_to": 1615852799000
|
||||
@@ -32,15 +29,13 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "dynamix",
|
||||
"_id": "6046bab736651a07ebc53827",
|
||||
"is_available": true
|
||||
}, {
|
||||
"type": "character",
|
||||
"id": "sapphire",
|
||||
"_id": "6046bab736651a07ebc53826",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 250,
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1615248000000,
|
||||
"discount_to": 1615852799000
|
||||
@@ -49,15 +44,13 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "mirai",
|
||||
"_id": "6046bab736651a07ebc5381d",
|
||||
"is_available": true
|
||||
}, {
|
||||
"type": "character",
|
||||
"id": "lethe",
|
||||
"_id": "6046bab736651a07ebc5381c",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 250,
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1615248000000,
|
||||
"discount_to": 1615852799000
|
||||
@@ -66,10 +59,9 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "yugamu",
|
||||
"_id": "6046bab736651a07ebc537dc",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 400,
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1615248000000,
|
||||
"discount_to": 1615852799000
|
||||
@@ -78,10 +70,9 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "lanota",
|
||||
"_id": "6046bab736651a07ebc537e8",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 250,
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1615248000000,
|
||||
"discount_to": 1615852799000
|
||||
@@ -90,10 +81,9 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "nijuusei",
|
||||
"_id": "6046bab736651a07ebc537dd",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 250,
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1615248000000,
|
||||
"discount_to": 1615852799000
|
||||
@@ -102,10 +92,9 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "rei",
|
||||
"_id": "6046bab736651a07ebc537f6",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 400,
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1615248000000,
|
||||
"discount_to": 1615852799000
|
||||
@@ -114,10 +103,9 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "tonesphere",
|
||||
"_id": "6046bab736651a07ebc537ea",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 250,
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1615248000000,
|
||||
"discount_to": 1615852799000
|
||||
@@ -126,10 +114,9 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "groovecoaster",
|
||||
"_id": "6046bab736651a07ebc53812",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 250,
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1615248000000,
|
||||
"discount_to": 1615852799000
|
||||
@@ -138,10 +125,9 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "zettai",
|
||||
"_id": "6046bab736651a07ebc537f8",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 250,
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1615248000000,
|
||||
"discount_to": 1615852799000
|
||||
@@ -150,7 +136,6 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "chunithm",
|
||||
"_id": "6046bab736651a07ebc53806",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 300,
|
||||
@@ -160,10 +145,9 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "prelude",
|
||||
"_id": "6046bab736651a07ebc53813",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 250,
|
||||
"price": 400,
|
||||
"orig_price": 400,
|
||||
"discount_from": 1615248000000,
|
||||
"discount_to": 1615852799000
|
||||
@@ -172,10 +156,9 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "omatsuri",
|
||||
"_id": "6046bab736651a07ebc537f9",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 250,
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1615248000000,
|
||||
"discount_to": 1615852799000
|
||||
@@ -184,10 +167,9 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "vs",
|
||||
"_id": "6046bab736651a07ebc53809",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 400,
|
||||
"price": 500,
|
||||
"orig_price": 500,
|
||||
"discount_from": 1615248000000,
|
||||
"discount_to": 1615852799000
|
||||
@@ -196,10 +178,9 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "extend",
|
||||
"_id": "6046bab736651a07ebc53816",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 500,
|
||||
"price": 700,
|
||||
"orig_price": 700,
|
||||
"discount_from": 1615248000000,
|
||||
"discount_to": 1615852799000
|
||||
@@ -208,7 +189,6 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "alice",
|
||||
"_id": "6046bab736651a07ebc537fe",
|
||||
"is_available": true
|
||||
}],
|
||||
"orig_price": 500,
|
||||
@@ -218,7 +198,6 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "alice_append_1",
|
||||
"_id": "6046bab736651a07ebc537e6",
|
||||
"is_available": true
|
||||
}],
|
||||
"orig_price": 300,
|
||||
@@ -228,7 +207,6 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "ongeki",
|
||||
"_id": "6046bab736651a07ebc5380c",
|
||||
"is_available": true
|
||||
}],
|
||||
"orig_price": 400,
|
||||
@@ -238,7 +216,6 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "maimai",
|
||||
"_id": "6046bab736651a07ebc53819",
|
||||
"is_available": true
|
||||
}],
|
||||
"orig_price": 400,
|
||||
@@ -248,9 +225,26 @@
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "chunithm_append_1",
|
||||
"_id": "6046bab736651a07ebc537f2",
|
||||
"is_available": true
|
||||
}],
|
||||
"orig_price": 300,
|
||||
"price": 300
|
||||
}, {
|
||||
"name": "observer_append_1",
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "observer_append_1",
|
||||
"is_available": true
|
||||
}],
|
||||
"orig_price": 300,
|
||||
"price": 300
|
||||
}, {
|
||||
"name": "observer",
|
||||
"items": [{
|
||||
"type": "pack",
|
||||
"id": "observer",
|
||||
"is_available": true
|
||||
}],
|
||||
"orig_price": 500,
|
||||
"price": 500
|
||||
}]
|
||||
@@ -12,7 +12,6 @@
|
||||
"items": [{
|
||||
"id": "dataerror",
|
||||
"type": "single",
|
||||
"_id": "606f9f5636651a07ebc541f3",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -24,7 +23,6 @@
|
||||
"items": [{
|
||||
"id": "yourvoiceso",
|
||||
"type": "single",
|
||||
"_id": "606f9f5636651a07ebc54201",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -36,7 +34,6 @@
|
||||
"items": [{
|
||||
"id": "crosssoul",
|
||||
"type": "single",
|
||||
"_id": "606f9f5636651a07ebc5420e",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -48,7 +45,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "impurebird",
|
||||
"_id": "606f9f5636651a07ebc541f4",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -60,7 +56,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "auxesia",
|
||||
"_id": "606f9f5636651a07ebc5420f",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -72,7 +67,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "modelista",
|
||||
"_id": "606f9f5636651a07ebc54202",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -84,7 +78,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "yozakurafubuki",
|
||||
"_id": "606f9f5636651a07ebc541f5",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -96,7 +89,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "surrender",
|
||||
"_id": "606f9f5636651a07ebc54210",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -108,7 +100,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "metallicpunisher",
|
||||
"_id": "606f9f5636651a07ebc54203",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -118,7 +109,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "carminescythe",
|
||||
"_id": "606f9f5636651a07ebc541f6",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -128,7 +118,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "bethere",
|
||||
"_id": "606f9f5636651a07ebc54211",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -140,7 +129,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "callmyname",
|
||||
"_id": "606f9f5636651a07ebc5421c",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -152,7 +140,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "fallensquare",
|
||||
"_id": "606f9f5636651a07ebc541e9",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -164,7 +151,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "dropdead",
|
||||
"_id": "606f9f5636651a07ebc541f7",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -176,7 +162,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "alexandrite",
|
||||
"_id": "606f9f5636651a07ebc54212",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -188,7 +173,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "astraltale",
|
||||
"_id": "606f9f5636651a07ebc54205",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -200,7 +184,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "phantasia",
|
||||
"_id": "606f9f5636651a07ebc541ea",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -210,7 +193,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "empireofwinter",
|
||||
"_id": "606f9f5636651a07ebc541f8",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -220,7 +202,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "libertas",
|
||||
"_id": "606f9f5636651a07ebc5421e",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -232,7 +213,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "dottodot",
|
||||
"_id": "606f9f5636651a07ebc541eb",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -244,7 +224,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "dreadnought",
|
||||
"_id": "606f9f5636651a07ebc5421f",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -256,7 +235,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "mirzam",
|
||||
"_id": "606f9f5636651a07ebc541ec",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -268,7 +246,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "heavenlycaress",
|
||||
"_id": "606f9f5636651a07ebc541fa",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -280,7 +257,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "filament",
|
||||
"_id": "606f9f5636651a07ebc54215",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -292,7 +268,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "avantraze",
|
||||
"_id": "606f9f5636651a07ebc54220",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -302,7 +277,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "battlenoone",
|
||||
"_id": "606f9f5636651a07ebc54208",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -314,7 +288,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "saikyostronger",
|
||||
"_id": "606f9f5636651a07ebc541ed",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -324,7 +297,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "izana",
|
||||
"_id": "606f9f5636651a07ebc541fb",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -336,7 +308,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "einherjar",
|
||||
"_id": "606f9f5636651a07ebc54216",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -348,7 +319,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "laqryma",
|
||||
"_id": "606f9f5636651a07ebc54221",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -360,7 +330,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "amygdata",
|
||||
"_id": "606f9f5636651a07ebc54209",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -372,7 +341,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "altale",
|
||||
"_id": "606f9f5636651a07ebc541ee",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -384,7 +352,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "feelssoright",
|
||||
"_id": "606f9f5636651a07ebc54222",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -396,7 +363,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "scarletcage",
|
||||
"_id": "606f9f5636651a07ebc5420a",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -406,7 +372,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "teriqma",
|
||||
"_id": "606f9f5636651a07ebc541ef",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -416,7 +381,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "mahoroba",
|
||||
"_id": "606f9f5636651a07ebc541fd",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -428,7 +392,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "badtek",
|
||||
"_id": "606f9f5636651a07ebc54223",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -440,7 +403,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "maliciousmischance",
|
||||
"_id": "606f9f5636651a07ebc54218",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -450,7 +412,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "buchigireberserker",
|
||||
"_id": "606f9f5636651a07ebc541f0",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -460,7 +421,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "galaxyfriends",
|
||||
"_id": "606f9f5636651a07ebc541fe",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -472,7 +432,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "xeraphinite",
|
||||
"_id": "606f9f5636651a07ebc54219",
|
||||
"is_available": true
|
||||
}],
|
||||
"orig_price": 100,
|
||||
@@ -482,7 +441,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "xanatos",
|
||||
"_id": "606f9f5636651a07ebc54224",
|
||||
"is_available": true
|
||||
}],
|
||||
"price": 100,
|
||||
@@ -492,7 +450,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "attraqtia",
|
||||
"_id": "606f9f5636651a07ebc5420d",
|
||||
"is_available": true
|
||||
}],
|
||||
"orig_price": 100,
|
||||
@@ -502,7 +459,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "gimmedablood",
|
||||
"_id": "606f9f5636651a07ebc541f2",
|
||||
"is_available": true
|
||||
}],
|
||||
"orig_price": 100,
|
||||
@@ -512,7 +468,6 @@
|
||||
"items": [{
|
||||
"type": "single",
|
||||
"id": "bassline",
|
||||
"_id": "606f9f5636651a07ebc54200",
|
||||
"is_available": true
|
||||
}],
|
||||
"orig_price": 100,
|
||||
|
||||
@@ -10,6 +10,7 @@ import server.setme
|
||||
import server.arcscore
|
||||
import web.login
|
||||
import web.index
|
||||
import api.api_main
|
||||
import server.arcworld
|
||||
import server.arcdownload
|
||||
import server.arcpurchase
|
||||
@@ -21,6 +22,95 @@ import sys
|
||||
app = Flask(__name__)
|
||||
wsgi_app = app.wsgi_app
|
||||
|
||||
os.chdir(sys.path[0]) # 更改工作路径,以便于愉快使用相对路径
|
||||
|
||||
app.config.from_mapping(SECRET_KEY=Config.SECRET_KEY)
|
||||
app.config['SESSION_TYPE'] = 'filesystem'
|
||||
app.register_blueprint(web.login.bp)
|
||||
app.register_blueprint(web.index.bp)
|
||||
app.register_blueprint(api.api_main.bp)
|
||||
|
||||
log_dict = {
|
||||
'version': 1,
|
||||
'root': {
|
||||
'level': 'INFO',
|
||||
'handlers': ['wsgi', 'error_file']
|
||||
},
|
||||
'handlers': {
|
||||
'wsgi': {
|
||||
'class': 'logging.StreamHandler',
|
||||
'stream': 'ext://flask.logging.wsgi_errors_stream',
|
||||
'formatter': 'default'
|
||||
},
|
||||
"error_file": {
|
||||
"class": "logging.handlers.RotatingFileHandler",
|
||||
"maxBytes": 1024 * 1024,
|
||||
"backupCount": 1,
|
||||
"encoding": "utf-8",
|
||||
"level": "ERROR",
|
||||
"formatter": "default",
|
||||
"filename": "./log/error.log"
|
||||
}
|
||||
},
|
||||
'formatters': {
|
||||
'default': {
|
||||
'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
|
||||
}
|
||||
}
|
||||
}
|
||||
if Config.ALLOW_LOG_INFO:
|
||||
log_dict['root']['handlers'] = ['wsgi', 'info_file', 'error_file']
|
||||
log_dict['handlers']['info_file'] = {
|
||||
"class": "logging.handlers.RotatingFileHandler",
|
||||
"maxBytes": 1024 * 1024,
|
||||
"backupCount": 1,
|
||||
"encoding": "utf-8",
|
||||
"level": "INFO",
|
||||
"formatter": "default",
|
||||
"filename": "./log/info.log"
|
||||
}
|
||||
|
||||
dictConfig(log_dict)
|
||||
|
||||
if not server.init.check_before_run(app):
|
||||
app.logger.error('Something wrong. The server will not run.')
|
||||
input('Press ENTER key to exit.')
|
||||
sys.exit()
|
||||
|
||||
app.logger.info("Start to initialize data in 'songfile' table...")
|
||||
try:
|
||||
error = server.arcdownload.initialize_songfile()
|
||||
except:
|
||||
error = 'Something wrong.'
|
||||
if error:
|
||||
app.logger.warning(error)
|
||||
else:
|
||||
app.logger.info('Complete!')
|
||||
|
||||
|
||||
def add_url_prefix(url, strange_flag=False):
|
||||
# 给url加前缀,返回字符串
|
||||
if not url or not Config.GAME_API_PREFIX:
|
||||
return Config.GAME_API_PREFIX + url
|
||||
|
||||
prefix = Config.GAME_API_PREFIX
|
||||
if prefix[0] != '/':
|
||||
prefix = '/' + prefix
|
||||
if prefix[-1] == '/':
|
||||
prefix = prefix[:-1]
|
||||
|
||||
if url[0] != '/':
|
||||
r = '/' + url
|
||||
else:
|
||||
r = url
|
||||
|
||||
if strange_flag and prefix.count('/') >= 1: # 为了方便处理双斜杠
|
||||
t = prefix[::-1]
|
||||
t = t[t.find('/')+1:]
|
||||
prefix = t[::-1]
|
||||
|
||||
return prefix + r
|
||||
|
||||
|
||||
def error_return(error_code): # 错误返回
|
||||
# -7 处理交易时发生了错误
|
||||
@@ -74,6 +164,7 @@ def error_return(error_code): # 错误返回
|
||||
@app.route('/')
|
||||
def hello():
|
||||
return "Hello World!"
|
||||
# 自定义路径
|
||||
|
||||
|
||||
@app.route('/favicon.ico', methods=['GET']) # 图标
|
||||
@@ -85,7 +176,7 @@ def favicon():
|
||||
return app.send_static_file('favicon.ico')
|
||||
|
||||
|
||||
@app.route('/latte/13/auth/login', methods=['POST']) # 登录接口
|
||||
@app.route(add_url_prefix('/auth/login'), methods=['POST']) # 登录接口
|
||||
def login():
|
||||
headers = request.headers
|
||||
id_pwd = headers['Authorization']
|
||||
@@ -96,7 +187,8 @@ def login():
|
||||
else:
|
||||
device_id = 'low_version'
|
||||
|
||||
token, error_code = server.auth.arc_login(name, password, device_id)
|
||||
token, error_code = server.auth.arc_login(
|
||||
name, password, device_id, request.remote_addr)
|
||||
if not error_code:
|
||||
r = {"success": True, "token_type": "Bearer"}
|
||||
r['access_token'] = token
|
||||
@@ -105,27 +197,28 @@ def login():
|
||||
return error_return(error_code)
|
||||
|
||||
|
||||
@app.route('/latte/13/user/', methods=['POST']) # 注册接口
|
||||
@app.route(add_url_prefix('/user/'), methods=['POST']) # 注册接口
|
||||
def register():
|
||||
name = request.form['name']
|
||||
password = request.form['password']
|
||||
email = request.form['email']
|
||||
if 'device_id' in request.form:
|
||||
device_id = request.form['device_id']
|
||||
else:
|
||||
device_id = 'low_version'
|
||||
|
||||
user_id, token, error_code = server.auth.arc_register(
|
||||
name, password, device_id)
|
||||
name, password, device_id, email, request.remote_addr)
|
||||
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,用户名被占用,毕竟电子邮箱没记录
|
||||
return error_return(error_code)
|
||||
|
||||
|
||||
# 集成式请求,没想到什么好办法处理,就先这样写着
|
||||
@app.route('/latte/13/compose/aggregate', methods=['GET'])
|
||||
@app.route(add_url_prefix('/compose/aggregate'), methods=['GET'])
|
||||
@server.auth.auth_required(request)
|
||||
def aggregate(user_id):
|
||||
calls = request.args.get('calls')
|
||||
@@ -136,7 +229,7 @@ def aggregate(user_id):
|
||||
return jsonify(r)
|
||||
|
||||
|
||||
@app.route('/latte/13/user/me/character', methods=['POST']) # 角色切换
|
||||
@app.route(add_url_prefix('/user/me/character'), methods=['POST']) # 角色切换
|
||||
@server.auth.auth_required(request)
|
||||
def character_change(user_id):
|
||||
character_id = request.form['character']
|
||||
@@ -155,7 +248,8 @@ def character_change(user_id):
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/latte/<path:path>/toggle_uncap', methods=['POST']) # 角色觉醒切换
|
||||
# 角色觉醒切换
|
||||
@app.route(add_url_prefix('/<path:path>/toggle_uncap', True), methods=['POST'])
|
||||
@server.auth.auth_required(request)
|
||||
def character_uncap(user_id, path):
|
||||
while '//' in path:
|
||||
@@ -174,7 +268,7 @@ def character_uncap(user_id, path):
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/latte/13/friend/me/add', methods=['POST']) # 加好友
|
||||
@app.route(add_url_prefix('/friend/me/add'), methods=['POST']) # 加好友
|
||||
@server.auth.auth_required(request)
|
||||
def add_friend(user_id):
|
||||
friend_code = request.form['friend_code']
|
||||
@@ -200,7 +294,7 @@ def add_friend(user_id):
|
||||
return error_return(401)
|
||||
|
||||
|
||||
@app.route('/latte/13/friend/me/delete', methods=['POST']) # 删好友
|
||||
@app.route(add_url_prefix('/friend/me/delete'), methods=['POST']) # 删好友
|
||||
@server.auth.auth_required(request)
|
||||
def delete_friend(user_id):
|
||||
friend_id = int(request.form['friend_id'])
|
||||
@@ -222,7 +316,8 @@ def delete_friend(user_id):
|
||||
return error_return(401)
|
||||
|
||||
|
||||
@app.route('/latte/13/score/song/friend', methods=['GET']) # 好友排名,默认最多50
|
||||
# 好友排名,默认最多50
|
||||
@app.route(add_url_prefix('/score/song/friend'), methods=['GET'])
|
||||
@server.auth.auth_required(request)
|
||||
def song_score_friend(user_id):
|
||||
song_id = request.args.get('song_id')
|
||||
@@ -237,7 +332,7 @@ def song_score_friend(user_id):
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/latte/13/score/song/me', methods=['GET']) # 我的排名,默认最多20
|
||||
@app.route(add_url_prefix('/score/song/me'), methods=['GET']) # 我的排名,默认最多20
|
||||
@server.auth.auth_required(request)
|
||||
def song_score_me(user_id):
|
||||
song_id = request.args.get('song_id')
|
||||
@@ -252,7 +347,7 @@ def song_score_me(user_id):
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/latte/13/score/song', methods=['GET']) # TOP20
|
||||
@app.route(add_url_prefix('/score/song'), methods=['GET']) # TOP20
|
||||
@server.auth.auth_required(request)
|
||||
def song_score_top(user_id):
|
||||
song_id = request.args.get('song_id')
|
||||
@@ -267,7 +362,7 @@ def song_score_top(user_id):
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/latte/13/score/song', methods=['POST']) # 成绩上传
|
||||
@app.route(add_url_prefix('/score/song'), methods=['POST']) # 成绩上传
|
||||
@server.auth.auth_required(request)
|
||||
def song_score_post(user_id):
|
||||
song_token = request.form['song_token']
|
||||
@@ -306,7 +401,8 @@ def song_score_post(user_id):
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/latte/13/score/token', methods=['GET']) # 成绩上传所需的token,显然我不想验证
|
||||
# 成绩上传所需的token,显然我不想验证
|
||||
@app.route(add_url_prefix('/score/token'), methods=['GET'])
|
||||
def score_token():
|
||||
return jsonify({
|
||||
"success": True,
|
||||
@@ -317,7 +413,7 @@ def score_token():
|
||||
|
||||
|
||||
# 世界模式成绩上传所需的token,无验证
|
||||
@app.route('/latte/13/score/token/world', methods=['GET'])
|
||||
@app.route(add_url_prefix('/score/token/world'), methods=['GET'])
|
||||
@server.auth.auth_required(request)
|
||||
def score_token_world(user_id):
|
||||
args = request.args
|
||||
@@ -332,7 +428,7 @@ def score_token_world(user_id):
|
||||
})
|
||||
|
||||
|
||||
@app.route('/latte/13/user/me/save', methods=['GET']) # 从云端同步
|
||||
@app.route(add_url_prefix('/user/me/save'), methods=['GET']) # 从云端同步
|
||||
@server.auth.auth_required(request)
|
||||
def cloud_get(user_id):
|
||||
r = server.arcscore.arc_all_get(user_id)
|
||||
@@ -345,7 +441,7 @@ def cloud_get(user_id):
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/latte/13/user/me/save', methods=['POST']) # 向云端同步
|
||||
@app.route(add_url_prefix('/user/me/save'), methods=['POST']) # 向云端同步
|
||||
@server.auth.auth_required(request)
|
||||
def cloud_post(user_id):
|
||||
scores_data = request.form['scores_data']
|
||||
@@ -366,7 +462,7 @@ def cloud_post(user_id):
|
||||
})
|
||||
|
||||
|
||||
@app.route('/latte/13/purchase/me/redeem', methods=['POST']) # 兑换码
|
||||
@app.route(add_url_prefix('/purchase/me/redeem'), methods=['POST']) # 兑换码
|
||||
@server.auth.auth_required(request)
|
||||
def redeem(user_id):
|
||||
code = request.form['code']
|
||||
@@ -388,7 +484,7 @@ def redeem(user_id):
|
||||
|
||||
|
||||
# 礼物确认
|
||||
@app.route('/latte/13/present/me/claim/<present_id>', methods=['POST'])
|
||||
@app.route(add_url_prefix('/present/me/claim/<present_id>'), methods=['POST'])
|
||||
@server.auth.auth_required(request)
|
||||
def claim_present(user_id, present_id):
|
||||
flag = server.arcpurchase.claim_user_present(user_id, present_id)
|
||||
@@ -400,7 +496,8 @@ def claim_present(user_id, present_id):
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/latte/13/purchase/me/item', methods=['POST']) # 购买,world模式boost
|
||||
# 购买,world模式boost
|
||||
@app.route(add_url_prefix('/purchase/me/item'), methods=['POST'])
|
||||
@server.auth.auth_required(request)
|
||||
def prog_boost(user_id):
|
||||
re = {"success": False}
|
||||
@@ -417,20 +514,19 @@ def prog_boost(user_id):
|
||||
return jsonify(re)
|
||||
|
||||
|
||||
@app.route('/latte/13/purchase/me/pack', methods=['POST']) # 曲包和单曲购买
|
||||
@app.route(add_url_prefix('/purchase/me/pack'), methods=['POST']) # 曲包和单曲购买
|
||||
@server.auth.auth_required(request)
|
||||
def pack(user_id):
|
||||
if 'pack_id' in request.form:
|
||||
return jsonify(server.arcpurchase.buy_pack(user_id, request.form['pack_id']))
|
||||
return jsonify(server.arcpurchase.buy_thing(user_id, request.form['pack_id'], 'pack'))
|
||||
if 'single_id' in request.form:
|
||||
return jsonify(server.arcpurchase.buy_single(user_id, request.form['single_id']))
|
||||
return jsonify(server.arcpurchase.buy_thing(user_id, request.form['single_id'], 'single'))
|
||||
|
||||
return jsonify({
|
||||
"success": True
|
||||
})
|
||||
return jsonify({"success": True})
|
||||
|
||||
|
||||
@app.route('/latte/13/purchase/bundle/single', methods=['GET']) # 单曲购买信息获取
|
||||
# 单曲购买信息获取
|
||||
@app.route(add_url_prefix('/purchase/bundle/single'), methods=['GET'])
|
||||
def single():
|
||||
return jsonify({
|
||||
"success": True,
|
||||
@@ -438,7 +534,7 @@ def single():
|
||||
})
|
||||
|
||||
|
||||
@app.route('/latte/13/world/map/me', methods=['GET']) # 获得世界模式信息,所有地图
|
||||
@app.route(add_url_prefix('/world/map/me'), methods=['GET']) # 获得世界模式信息,所有地图
|
||||
@server.auth.auth_required(request)
|
||||
def world_all(user_id):
|
||||
return jsonify({
|
||||
@@ -451,7 +547,7 @@ def world_all(user_id):
|
||||
})
|
||||
|
||||
|
||||
@app.route('/latte/13/world/map/me/', methods=['POST']) # 进入地图
|
||||
@app.route(add_url_prefix('/world/map/me/'), methods=['POST']) # 进入地图
|
||||
@server.auth.auth_required(request)
|
||||
def world_in(user_id):
|
||||
map_id = request.form['map_id']
|
||||
@@ -461,7 +557,8 @@ def world_in(user_id):
|
||||
})
|
||||
|
||||
|
||||
@app.route('/latte/13/world/map/me/<map_id>', methods=['GET']) # 获得单个地图完整信息
|
||||
# 获得单个地图完整信息
|
||||
@app.route(add_url_prefix('/world/map/me/<map_id>'), methods=['GET'])
|
||||
@server.auth.auth_required(request)
|
||||
def world_one(user_id, map_id):
|
||||
server.arcworld.change_user_current_map(user_id, map_id)
|
||||
@@ -475,7 +572,7 @@ def world_one(user_id, map_id):
|
||||
})
|
||||
|
||||
|
||||
@app.route('/latte/13/serve/download/me/song', methods=['GET']) # 歌曲下载
|
||||
@app.route(add_url_prefix('/serve/download/me/song'), methods=['GET']) # 歌曲下载
|
||||
@server.auth.auth_required(request)
|
||||
def download_song(user_id):
|
||||
song_ids = request.args.getlist('sid')
|
||||
@@ -511,7 +608,8 @@ def download(file_path):
|
||||
return error_return(108)
|
||||
|
||||
|
||||
@app.route('/latte/<path:path>', methods=['POST']) # 三个设置,写在最后降低优先级
|
||||
# 三个设置,写在最后降低优先级
|
||||
@app.route(add_url_prefix('/<path:path>', True), methods=['POST'])
|
||||
@server.auth.auth_required(request)
|
||||
def sys_set(user_id, path):
|
||||
set_arg = path[10:]
|
||||
@@ -523,69 +621,6 @@ def sys_set(user_id, path):
|
||||
|
||||
|
||||
def main():
|
||||
os.chdir(sys.path[0]) # 更改工作路径,以便于愉快使用相对路径
|
||||
app.config.from_mapping(SECRET_KEY=Config.SECRET_KEY)
|
||||
app.config['SESSION_TYPE'] = 'filesystem'
|
||||
app.register_blueprint(web.login.bp)
|
||||
app.register_blueprint(web.index.bp)
|
||||
|
||||
log_dict = {
|
||||
'version': 1,
|
||||
'root': {
|
||||
'level': 'INFO',
|
||||
'handlers': ['wsgi', 'error_file']
|
||||
},
|
||||
'handlers': {
|
||||
'wsgi': {
|
||||
'class': 'logging.StreamHandler',
|
||||
'stream': 'ext://flask.logging.wsgi_errors_stream',
|
||||
'formatter': 'default'
|
||||
},
|
||||
"error_file": {
|
||||
"class": "logging.handlers.RotatingFileHandler",
|
||||
"maxBytes": 1024 * 1024,
|
||||
"backupCount": 1,
|
||||
"encoding": "utf-8",
|
||||
"level": "ERROR",
|
||||
"formatter": "default",
|
||||
"filename": "./log/error.log"
|
||||
}
|
||||
},
|
||||
'formatters': {
|
||||
'default': {
|
||||
'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
|
||||
}
|
||||
}
|
||||
}
|
||||
if Config.ALLOW_LOG_INFO:
|
||||
log_dict['root']['handlers'] = ['wsgi', 'info_file', 'error_file']
|
||||
log_dict['handlers']['info_file'] = {
|
||||
"class": "logging.handlers.RotatingFileHandler",
|
||||
"maxBytes": 1024 * 1024,
|
||||
"backupCount": 1,
|
||||
"encoding": "utf-8",
|
||||
"level": "INFO",
|
||||
"formatter": "default",
|
||||
"filename": "./log/info.log"
|
||||
}
|
||||
|
||||
dictConfig(log_dict)
|
||||
|
||||
if not server.init.check_before_run(app):
|
||||
app.logger.error('Something wrong. The server will not run.')
|
||||
input('Press ENTER key to exit.')
|
||||
sys.exit()
|
||||
|
||||
app.logger.info("Start to initialize data in 'songfile' table...")
|
||||
try:
|
||||
error = server.arcdownload.initialize_songfile()
|
||||
except:
|
||||
error = 'Something wrong.'
|
||||
if error:
|
||||
app.logger.warning(error)
|
||||
else:
|
||||
app.logger.info('Complete!')
|
||||
|
||||
if Config.SSL_CERT and Config.SSL_KEY:
|
||||
app.run(Config.HOST, Config.PORT, ssl_context=(
|
||||
Config.SSL_CERT, Config.SSL_KEY))
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from server.sql import Connect
|
||||
import server.info
|
||||
import time
|
||||
import json
|
||||
|
||||
@@ -67,49 +68,55 @@ def buy_item(c, user_id, price):
|
||||
return True, ticket - price
|
||||
|
||||
|
||||
def buy_pack(user_id, pack_id):
|
||||
# 曲包购买,返回字典
|
||||
re = {"success": False}
|
||||
with Connect() as c:
|
||||
c.execute('''select price from item where item_id = :a''',
|
||||
{'a': pack_id})
|
||||
price = c.fetchone()
|
||||
if price:
|
||||
price = price[0]
|
||||
else:
|
||||
price = 0
|
||||
def buy_thing(user_id, item_id, item_type):
|
||||
# 购买物品接口,返回字典
|
||||
success_flag = False
|
||||
ticket = 0
|
||||
packs = []
|
||||
singles = []
|
||||
characters = []
|
||||
|
||||
flag, ticket = buy_item(c, user_id, price)
|
||||
with Connect() as c:
|
||||
c.execute('''select is_available, price, orig_price, discount_from, discount_to from item where item_id=:a and type=:b''',
|
||||
{'a': item_id, 'b': item_type})
|
||||
x = c.fetchone()
|
||||
price = 0
|
||||
flag = False
|
||||
if x:
|
||||
is_available = x[0]
|
||||
price = x[1]
|
||||
orig_price = x[2]
|
||||
discount_from = x[3]
|
||||
discount_to = x[4]
|
||||
|
||||
if not is_available:
|
||||
return False
|
||||
|
||||
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:
|
||||
c.execute('''insert into user_item values(:a,:b,'pack')''',
|
||||
{'a': user_id, 'b': pack_id})
|
||||
c.execute('''insert into user_item values(:a,:b,:c)''',
|
||||
{'a': user_id, 'b': item_id, 'c': item_type})
|
||||
|
||||
re = {"success": True}
|
||||
success_flag = True
|
||||
|
||||
return re
|
||||
packs = server.info.get_user_packs(c, user_id)
|
||||
singles = server.info.get_user_singles(c, user_id)
|
||||
characters = server.info.get_user_characters(c, user_id)
|
||||
|
||||
|
||||
def buy_single(user_id, single_id):
|
||||
# 单曲购买,返回字典
|
||||
re = {"success": False}
|
||||
with Connect() as c:
|
||||
c.execute('''select price from item where item_id = :a''',
|
||||
{'a': single_id})
|
||||
price = c.fetchone()
|
||||
if price:
|
||||
price = price[0]
|
||||
else:
|
||||
price = 0
|
||||
|
||||
flag, ticket = buy_item(c, user_id, price)
|
||||
|
||||
if flag:
|
||||
c.execute('''insert into user_item values(:a,:b,'single')''',
|
||||
{'a': user_id, 'b': single_id})
|
||||
re = {"success": True}
|
||||
|
||||
return re
|
||||
return {
|
||||
"success": success_flag,
|
||||
"value": {'user_id': user_id,
|
||||
'ticket': ticket,
|
||||
'packs': packs,
|
||||
'singles': singles,
|
||||
'characters': characters
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def get_prog_boost(user_id):
|
||||
|
||||
@@ -188,8 +188,22 @@ def arc_score_me(user_id, song_id, difficulty, limit=20):
|
||||
return r
|
||||
|
||||
|
||||
def calculate_rating(defnum, score):
|
||||
# 计算rating
|
||||
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 get_one_ptt(song_id, difficulty, score: int) -> float:
|
||||
# 单曲ptt计算,ptt为负说明没铺面定数数据
|
||||
# 单曲ptt计算,ptt为负说明没谱面定数数据
|
||||
ptt = -10
|
||||
with Connect('./database/arcsong.db') as c:
|
||||
if difficulty == 0:
|
||||
@@ -212,14 +226,7 @@ def get_one_ptt(song_id, difficulty, score: int) -> float:
|
||||
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
|
||||
ptt = calculate_rating(defnum, score)
|
||||
|
||||
return ptt
|
||||
|
||||
@@ -299,7 +306,7 @@ def get_user_ptt(c, user_id) -> int:
|
||||
|
||||
|
||||
def update_recent30(c, user_id, song_id, rating, is_protected):
|
||||
# 刷新r30,这里的判断方法存疑
|
||||
# 刷新r30,这里的判断方法存疑,这里的song_id结尾包含难度数字
|
||||
def insert_r30table(c, user_id, a, b):
|
||||
# 更新r30表
|
||||
c.execute('''delete from recent30 where user_id = :a''',
|
||||
@@ -587,6 +594,49 @@ def arc_score_check(user_id, song_id, difficulty, score, shiny_perfect_count, pe
|
||||
return True
|
||||
|
||||
|
||||
def refresh_all_score_rating():
|
||||
# 刷新所有best成绩的rating
|
||||
error = 'Unknown error.'
|
||||
song_data = []
|
||||
|
||||
with Connect('./database/arcsong.db') as c:
|
||||
with Connect() as c2:
|
||||
c.execute(
|
||||
'''select sid, rating_pst, rating_prs, rating_ftr, rating_byn from songs''')
|
||||
x = c.fetchall()
|
||||
|
||||
if x:
|
||||
song_list = [i[0] for i in song_data]
|
||||
with Connect() as c:
|
||||
c.execute('''update best_score set rating=0 where song_id not in ({0})'''.format(
|
||||
','.join(['?']*len(song_list))), tuple(song_list))
|
||||
for i in x:
|
||||
for j in range(0, 4):
|
||||
defnum = -10 # 没在库里的全部当做定数-10
|
||||
if i is not None:
|
||||
defnum = float(i[j+1]) / 10
|
||||
if defnum <= 0:
|
||||
defnum = -10 # 缺少难度的当做定数-10
|
||||
|
||||
c.execute('''select user_id, score from best_score where song_id=:a and difficulty=:b''', {
|
||||
'a': i[0], 'b': j})
|
||||
y = c.fetchall()
|
||||
if y:
|
||||
for k in y:
|
||||
ptt = calculate_rating(defnum, k[1])
|
||||
if ptt < 0:
|
||||
ptt = 0
|
||||
|
||||
c.execute('''update best_score set rating=:a where user_id=:b and song_id=:c and difficulty=:d''', {
|
||||
'a': ptt, 'b': k[0], 'c': i[0], 'd': j})
|
||||
error = None
|
||||
|
||||
else:
|
||||
error = 'No song data.'
|
||||
|
||||
return error
|
||||
|
||||
|
||||
def arc_all_post(user_id, scores_data, clearlamps_data, clearedsongs_data, unlocklist_data, installid_data, devicemodelname_data, story_data):
|
||||
# 向云端同步,无返回
|
||||
with Connect() as c:
|
||||
@@ -882,6 +932,36 @@ def arc_all_get(user_id):
|
||||
"mi": 6,
|
||||
"c": True,
|
||||
"r": True
|
||||
}, {
|
||||
"ma": 9,
|
||||
"mi": 1,
|
||||
"c": True,
|
||||
"r": True
|
||||
}, {
|
||||
"ma": 9,
|
||||
"mi": 2,
|
||||
"c": True,
|
||||
"r": True
|
||||
}, {
|
||||
"ma": 9,
|
||||
"mi": 3,
|
||||
"c": True,
|
||||
"r": True
|
||||
}, {
|
||||
"ma": 9,
|
||||
"mi": 4,
|
||||
"c": True,
|
||||
"r": True
|
||||
}, {
|
||||
"ma": 9,
|
||||
"mi": 5,
|
||||
"c": True,
|
||||
"r": True
|
||||
}, {
|
||||
"ma": 9,
|
||||
"mi": 6,
|
||||
"c": True,
|
||||
"r": True
|
||||
}, {
|
||||
"ma": 6,
|
||||
"mi": 1,
|
||||
@@ -944,9 +1024,6 @@ def arc_all_get(user_id):
|
||||
"r": True
|
||||
}]
|
||||
unlocklist_data = [{
|
||||
"unlock_key": "worldvanquisher|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "worldvanquisher|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
@@ -955,42 +1032,48 @@ def arc_all_get(user_id):
|
||||
}, {
|
||||
"unlock_key": "viyellastears|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "viyellastears|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "viciousheroism|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "loschen|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "vector|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "corpssansorganes|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "valhallazero|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "tiferet|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "ouroboros|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "tiemedowngently|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "aegleseeker|2|3|crystalgravity|2",
|
||||
"complete": 10
|
||||
}, {
|
||||
"unlock_key": "tempestissimo|0|101",
|
||||
"complete": 100
|
||||
}, {
|
||||
"unlock_key": "syro|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "ringedgenesis|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
|
||||
@@ -1000,9 +1083,15 @@ def arc_all_get(user_id):
|
||||
}, {
|
||||
"unlock_key": "scarletlance|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "toaliceliddell|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "scarletlance|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "aterlbus|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "rugie|2|0",
|
||||
"complete": 1
|
||||
@@ -1018,24 +1107,33 @@ def arc_all_get(user_id):
|
||||
}, {
|
||||
"unlock_key": "reinvent|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "essenceoftwilight|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "redandblue|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "espebranch|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "redandblue|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "lostcivilization|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "supernova|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "rabbitintheblackroom|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "pragmatism|1|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
|
||||
@@ -1048,8 +1146,17 @@ def arc_all_get(user_id):
|
||||
}, {
|
||||
"unlock_key": "supernova|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "halcyon|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "saikyostronger|2|3|einherjar|2",
|
||||
"complete": 3
|
||||
}, {
|
||||
"unlock_key": "cyanine|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "saikyostronger|2|3|laqryma|2",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "purgatorium|1|0",
|
||||
@@ -1058,17 +1165,23 @@ def arc_all_get(user_id):
|
||||
"unlock_key": "pragmatism|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "ouroboros|2|0",
|
||||
"unlock_key": "ringedgenesis|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "ouroboros|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "partyvinyl|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "oracle|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "onelastdrive|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "nirvluce|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "onelastdrive|1|0",
|
||||
"complete": 1
|
||||
@@ -1076,10 +1189,13 @@ def arc_all_get(user_id):
|
||||
"unlock_key": "omegafour|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "oblivia|2|0",
|
||||
"unlock_key": "harutopia|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "pragmatism|1|0",
|
||||
"unlock_key": "anokumene|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "oblivia|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "nhelv|2|0",
|
||||
@@ -1090,9 +1206,6 @@ def arc_all_get(user_id):
|
||||
}, {
|
||||
"unlock_key": "melodyoflove|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "saikyostronger|2|3|laqryma|2",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "omegafour|2|0",
|
||||
"complete": 1
|
||||
@@ -1102,6 +1215,12 @@ def arc_all_get(user_id):
|
||||
}, {
|
||||
"unlock_key": "lucifer|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "gloryroad|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "babaroque|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "lucifer|1|0",
|
||||
"complete": 1
|
||||
@@ -1111,21 +1230,36 @@ def arc_all_get(user_id):
|
||||
}, {
|
||||
"unlock_key": "tiemedowngently|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "solitarydream|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "lostdesire|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "viciousheroism|1|0",
|
||||
"unlock_key": "lostcivilization|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "flyburg|1|0",
|
||||
"unlock_key": "loschen|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "lostcivilization|2|0",
|
||||
"unlock_key": "shadesoflight|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "kanagawa|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "grievouslady|1|101",
|
||||
"complete": 100
|
||||
}, {
|
||||
"unlock_key": "infinityheaven|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "worldvanquisher|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "bookmaker|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "ignotus|2|0",
|
||||
"complete": 1
|
||||
@@ -1135,39 +1269,39 @@ def arc_all_get(user_id):
|
||||
}, {
|
||||
"unlock_key": "partyvinyl|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "viciousheroism|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "gloryroad|0|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "axiumcrisis|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "kanagawa|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "ifi|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "jump|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "nhelv|1|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": "lethaeus|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "saikyostronger|2|0",
|
||||
"complete": 1
|
||||
@@ -1180,21 +1314,18 @@ def arc_all_get(user_id):
|
||||
}, {
|
||||
"unlock_key": "oshamascramble|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "aiueoon|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "blaster|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "grievouslady|2|101",
|
||||
"complete": 100
|
||||
}, {
|
||||
"unlock_key": "partyvinyl|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "darakunosono|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "grievouslady|1|101",
|
||||
"complete": 100
|
||||
}, {
|
||||
"unlock_key": "valhallazero|1|0",
|
||||
"complete": 1
|
||||
@@ -1207,9 +1338,15 @@ def arc_all_get(user_id):
|
||||
}, {
|
||||
"unlock_key": "gothiveofra|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "cyanine|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "tempestissimo|3|101",
|
||||
"complete": 100
|
||||
}, {
|
||||
"unlock_key": "overwhelm|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "chronostasis|2|0",
|
||||
"complete": 1
|
||||
@@ -1217,19 +1354,13 @@ def arc_all_get(user_id):
|
||||
"unlock_key": "gloryroad|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "supernova|1|0",
|
||||
"unlock_key": "etherstrike|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",
|
||||
"unlock_key": "buchigireberserker|2|3|gothiveofra|2",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "genesis|1|0",
|
||||
@@ -1240,9 +1371,15 @@ def arc_all_get(user_id):
|
||||
}, {
|
||||
"unlock_key": "freefall|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "revixy|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "fractureray|2|101",
|
||||
"complete": 100
|
||||
}, {
|
||||
"unlock_key": "goodtek|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "monochromeprincess|2|0",
|
||||
"complete": 1
|
||||
@@ -1258,29 +1395,29 @@ def arc_all_get(user_id):
|
||||
}, {
|
||||
"unlock_key": "clotho|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "quon|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "gou|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "felis|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "cyaegha|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "qualia|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "buchigireberserker|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "etherstrike|2|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",
|
||||
"unlock_key": "flyburg|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "shadesoflight|2|0",
|
||||
@@ -1289,26 +1426,23 @@ def arc_all_get(user_id):
|
||||
"unlock_key": "espebranch|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "tempestissimo|1|101",
|
||||
"complete": 100
|
||||
}, {
|
||||
"unlock_key": "nhelv|1|0",
|
||||
"unlock_key": "aterlbus|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "conflict|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "espebranch|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "lostcivilization|1|0",
|
||||
"unlock_key": "dreaminattraction|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "goodtek|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "infinityheaven|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "dandelion|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "blrink|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "suomi|2|0",
|
||||
"complete": 1
|
||||
@@ -1321,104 +1455,104 @@ def arc_all_get(user_id):
|
||||
}, {
|
||||
"unlock_key": "cyberneciacatharsis|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "quon|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "chronostasis|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "bookmaker|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "heavensdoor|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "tempestissimo|2|101",
|
||||
"complete": 100
|
||||
}, {
|
||||
"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": "corpssansorganes|0|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": "ignotus|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "nirvluce|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "monochromeprincess|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "lethaeus|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "clotho|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "aterlbus|2|0",
|
||||
"unlock_key": "heavensdoor|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "dreaminattraction|2|0",
|
||||
"unlock_key": "chronostasis|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "solitarydream|1|0",
|
||||
"unlock_key": "lethaeus|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "ringedgenesis|1|0",
|
||||
"unlock_key": "amazingmightyyyy|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "aegleseeker|0|103",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "buchigireberserker|2|3|ouroboros|2",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "oshamascramble|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "gothiveofra|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "linearaccelerator|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "corpssansorganes|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "buchigireberserker|2|0",
|
||||
"unlock_key": "worldexecuteme|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "bookmaker|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "heavensdoor|2|0",
|
||||
"unlock_key": "fractureray|0|101",
|
||||
"complete": 100
|
||||
}, {
|
||||
"unlock_key": "singularity|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "genesis|2|0",
|
||||
"unlock_key": "blaster|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "halcyon|2|0",
|
||||
"unlock_key": "rise|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "axiumcrisis|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "tempestissimo|2|101",
|
||||
"complete": 100
|
||||
}, {
|
||||
"unlock_key": "solitarydream|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "aegleseeker|1|103",
|
||||
"complete": 103
|
||||
}, {
|
||||
"unlock_key": "amazingmightyyyy|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "cyaegha|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "linearaccelerator|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "tempestissimo|1|101",
|
||||
"complete": 100
|
||||
}, {
|
||||
"unlock_key": "conflict|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "grievouslady|0|101",
|
||||
"complete": 100
|
||||
}, {
|
||||
"unlock_key": "dreaminattraction|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "saikyostronger|2|3|izana|2",
|
||||
@@ -1432,6 +1566,9 @@ def arc_all_get(user_id):
|
||||
}, {
|
||||
"unlock_key": "felis|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "overwhelm|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "toaliceliddell|2|0",
|
||||
"complete": 1
|
||||
@@ -1439,50 +1576,17 @@ def arc_all_get(user_id):
|
||||
"unlock_key": "blrink|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "grievouslady|0|101",
|
||||
"complete": 100
|
||||
}, {
|
||||
"unlock_key": "buchigireberserker|2|3|gothiveofra|2",
|
||||
"unlock_key": "heavensdoor|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "kanagawa|1|0",
|
||||
"unlock_key": "genesis|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "darakunosono|2|0",
|
||||
"unlock_key": "viyellastears|1|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": "goodtek|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "buchigireberserker|2|3|ouroboros|2",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "fractureray|0|101",
|
||||
"complete": 100
|
||||
}, {
|
||||
"unlock_key": "blaster|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "dreaminattraction|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "toaliceliddell|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "oshamascramble|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "gothiveofra|2|0",
|
||||
"complete": 1
|
||||
"unlock_key": "aegleseeker|2|103",
|
||||
"complete": 103
|
||||
}, {
|
||||
"unlock_key": "tiferet|2|0",
|
||||
"complete": 1
|
||||
@@ -1490,37 +1594,46 @@ def arc_all_get(user_id):
|
||||
"unlock_key": "grimheart|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "amazingmightyyyy|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "lethaeus|2|0",
|
||||
"complete": 1
|
||||
"unlock_key": "aegleseeker|2|3|farawaylight|2",
|
||||
"complete": 10
|
||||
}, {
|
||||
"unlock_key": "rugie|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "gou|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "sheriruth|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "aegleseeker|2|3|paperwitch|2",
|
||||
"complete": 10
|
||||
}, {
|
||||
"unlock_key": "sheriruth|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "babaroque|2|0",
|
||||
"unlock_key": "aegleseeker|2|3|loschen|2",
|
||||
"complete": 10
|
||||
}, {
|
||||
"unlock_key": "cyberneciacatharsis|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "aiueoon|2|0",
|
||||
"unlock_key": "essenceoftwilight|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "gloryroad|1|0",
|
||||
"unlock_key": "syro|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "cyaegha|1|0",
|
||||
"unlock_key": "anokumene|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "amazingmightyyyy|2|0",
|
||||
"unlock_key": "freefall|1|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "anokumene|1|0",
|
||||
"unlock_key": "darakunosono|2|0",
|
||||
"complete": 1
|
||||
}, {
|
||||
"unlock_key": "nirvluce|2|0",
|
||||
"complete": 1
|
||||
}]
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import hashlib
|
||||
import time
|
||||
import server.arcworld
|
||||
from server.sql import Connect
|
||||
import functools
|
||||
from setting import Config
|
||||
from flask import jsonify
|
||||
|
||||
|
||||
def arc_login(name: str, password: str, device_id: str): # 登录判断
|
||||
def arc_login(name: str, password: str, device_id: str, ip: str): # 登录判断
|
||||
# 查询数据库中的user表,验证账号密码,返回并记录token,多返回个error code
|
||||
# token采用user_id和时间戳连接后hash生成(真的是瞎想的,没用bear)
|
||||
# 密码和token的加密方式为 SHA-256
|
||||
@@ -43,8 +43,8 @@ def arc_login(name: str, password: str, device_id: str): # 登录判断
|
||||
|
||||
if not Config.ALLOW_LOGIN_SAME_DEVICE:
|
||||
if device_id in device_list: # 对相同设备进行删除
|
||||
c.execute('''delete from login where login_device=:a''', {
|
||||
'a': device_id})
|
||||
c.execute('''delete from login where login_device=:a and user_id=:b''', {
|
||||
'a': device_id, 'b': user_id})
|
||||
should_delete_num = len(
|
||||
device_list) + 1 - device_list.count(device_id) - Config.LOGIN_DEVICE_NUMBER_LIMIT
|
||||
|
||||
@@ -52,8 +52,8 @@ def arc_login(name: str, password: str, device_id: str): # 登录判断
|
||||
c.execute('''delete from login where rowid in (select rowid from login where user_id=:user_id limit :a);''',
|
||||
{'user_id': user_id, 'a': int(should_delete_num)})
|
||||
|
||||
c.execute('''insert into login(access_token, user_id, login_device) values(:access_token, :user_id, :device_id)''', {
|
||||
'user_id': user_id, 'access_token': token, 'device_id': device_id})
|
||||
c.execute('''insert into login values(:access_token, :user_id, :time, :ip, :device_id)''', {
|
||||
'user_id': user_id, 'access_token': token, 'device_id': device_id, 'time': now, 'ip': ip})
|
||||
error_code = None
|
||||
else:
|
||||
# 密码错误
|
||||
@@ -65,8 +65,8 @@ def arc_login(name: str, password: str, device_id: str): # 登录判断
|
||||
return token, error_code
|
||||
|
||||
|
||||
def arc_register(name: str, password: str, device_id: str): # 注册
|
||||
# 账号注册,只记录hash密码和用户名,生成user_id和user_code,自动登录返回token
|
||||
def arc_register(name: str, password: str, device_id: str, email: str, ip: str): # 注册
|
||||
# 账号注册,记录hash密码、用户名和邮箱,生成user_id和user_code,自动登录返回token
|
||||
# token和密码的处理同登录部分
|
||||
|
||||
def build_user_code(c):
|
||||
@@ -107,23 +107,28 @@ def arc_register(name: str, password: str, device_id: str): # 注册
|
||||
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, current_map, ticket, prog_boost)
|
||||
values(:user_id, :name, :password, :join_date, :user_code, 0, 0, 0, 0, 0, 0, -1, 0, '', :memories, 0)
|
||||
''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd, 'memories': Config.DEFAULT_MEMORIES})
|
||||
c.execute('''insert into recent30(user_id) values(:user_id)''', {
|
||||
'user_id': user_id})
|
||||
c.execute(
|
||||
'''select exists(select * from user where email = :email)''', {'email': email})
|
||||
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, current_map, ticket, prog_boost, email)
|
||||
values(:user_id, :name, :password, :join_date, :user_code, 0, 0, 0, 0, 0, 0, -1, 0, '', :memories, 0, :email)
|
||||
''', {'user_code': user_code, 'user_id': user_id, 'join_date': now, 'name': name, 'password': hash_pwd, 'memories': Config.DEFAULT_MEMORIES, 'email': email})
|
||||
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, login_device) values(:access_token, :user_id, :device_id)''', {
|
||||
'user_id': user_id, 'access_token': token, 'device_id': device_id})
|
||||
token = hashlib.sha256(
|
||||
(str(user_id) + str(now)).encode("utf8")).hexdigest()
|
||||
c.execute('''insert into login values(:access_token, :user_id, :time, :ip, :device_id)''', {
|
||||
'user_id': user_id, 'access_token': token, 'device_id': device_id, 'time': now, 'ip': ip})
|
||||
|
||||
insert_user_char(c, user_id)
|
||||
error_code = 0
|
||||
insert_user_char(c, user_id)
|
||||
error_code = 0
|
||||
else:
|
||||
error_code = 102
|
||||
else:
|
||||
error_code = 101
|
||||
|
||||
@@ -166,17 +171,16 @@ def auth_required(request):
|
||||
def wrapped_view(*args, **kwargs):
|
||||
|
||||
user_id = None
|
||||
with Connect() as c:
|
||||
headers = request.headers
|
||||
if 'Authorization' in headers:
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
user_id = token_get_id(token)
|
||||
headers = request.headers
|
||||
if 'Authorization' in headers:
|
||||
token = headers['Authorization']
|
||||
token = token[7:]
|
||||
user_id = token_get_id(token)
|
||||
|
||||
if user_id is not None:
|
||||
return view(user_id, *args, **kwargs)
|
||||
else:
|
||||
return '''{"success":false,"error_code":108}'''
|
||||
return jsonify({"success": False, "error_code": 108})
|
||||
|
||||
return wrapped_view
|
||||
return decorator
|
||||
|
||||
@@ -118,12 +118,16 @@ def get_user_friend(c, user_id):
|
||||
is_char_uncapped = int2b(z[0])
|
||||
is_char_uncapped_override = int2b(z[1])
|
||||
|
||||
rating = y[5]
|
||||
if int2b(y[10]):
|
||||
rating = -1
|
||||
|
||||
s.append({
|
||||
"is_mutual": is_mutual,
|
||||
"is_char_uncapped_override": is_char_uncapped_override,
|
||||
"is_char_uncapped": is_char_uncapped,
|
||||
"is_skill_sealed": int2b(y[7]),
|
||||
"rating": y[5],
|
||||
"rating": rating,
|
||||
"join_date": int(y[3]),
|
||||
"character": character,
|
||||
"recent_score": get_recent_score(c, i[0]),
|
||||
@@ -162,16 +166,34 @@ def get_user_packs(c, user_id):
|
||||
return re
|
||||
|
||||
|
||||
def get_value_0(c, user_id):
|
||||
# 构造value id=0的数据,返回字典
|
||||
def get_user_characters(c, user_id):
|
||||
# 获取用户所拥有角色,返回列表
|
||||
|
||||
c.execute('''select character_id from user_char where user_id = :user_id''',
|
||||
{'user_id': user_id})
|
||||
|
||||
x = c.fetchall()
|
||||
characters = []
|
||||
|
||||
if x:
|
||||
for i in x:
|
||||
characters.append(i[0])
|
||||
|
||||
return characters
|
||||
|
||||
|
||||
def get_user_me(c, user_id):
|
||||
# 构造user/me的数据,返回字典
|
||||
c.execute('''select * from user where user_id = :x''', {'x': user_id})
|
||||
x = c.fetchone()
|
||||
r = {}
|
||||
if x is not None:
|
||||
user_character = get_user_character(c, user_id)
|
||||
# 下面没有使用get_user_characters函数是为了节省一次查询
|
||||
characters = []
|
||||
for i in user_character:
|
||||
characters.append(i['character_id'])
|
||||
|
||||
prog_boost = 0
|
||||
if x[27] and x[27] != 0:
|
||||
prog_boost = 300
|
||||
@@ -199,7 +221,7 @@ def get_value_0(c, user_id):
|
||||
"max_stamina_ts": 1586274871917,
|
||||
"stamina": 12,
|
||||
"world_unlocks": ["scenery_chap1", "scenery_chap2", "scenery_chap3", "scenery_chap4", "scenery_chap5"],
|
||||
"world_songs": ["babaroque", "shadesoflight", "kanagawa", "lucifer", "anokumene", "ignotus", "rabbitintheblackroom", "qualia", "redandblue", "bookmaker", "darakunosono", "espebranch", "blacklotus", "givemeanightmare", "vividtheory", "onefr", "gekka", "vexaria3", "infinityheaven3", "fairytale3", "goodtek3", "suomi", "rugie", "faintlight", "harutopia", "goodtek", "dreaminattraction", "syro", "diode", "freefall", "grimheart", "blaster", "cyberneciacatharsis", "monochromeprincess", "revixy", "vector", "supernova", "nhelv", "purgatorium3", "dement3", "crossover", "guardina", "axiumcrisis", "worldvanquisher", "sheriruth", "pragmatism", "gloryroad", "etherstrike", "corpssansorganes", "lostdesire", "blrink", "essenceoftwilight", "lapis", "solitarydream", "lumia3", "purpleverse", "moonheart3", "glow", "enchantedlove", "take", "lifeispiano"],
|
||||
"world_songs": ["babaroque", "shadesoflight", "kanagawa", "lucifer", "anokumene", "ignotus", "rabbitintheblackroom", "qualia", "redandblue", "bookmaker", "darakunosono", "espebranch", "blacklotus", "givemeanightmare", "vividtheory", "onefr", "gekka", "vexaria3", "infinityheaven3", "fairytale3", "goodtek3", "suomi", "rugie", "faintlight", "harutopia", "goodtek", "dreaminattraction", "syro", "diode", "freefall", "grimheart", "blaster", "cyberneciacatharsis", "monochromeprincess", "revixy", "vector", "supernova", "nhelv", "purgatorium3", "dement3", "crossover", "guardina", "axiumcrisis", "worldvanquisher", "sheriruth", "pragmatism", "gloryroad", "etherstrike", "corpssansorganes", "lostdesire", "blrink", "essenceoftwilight", "lapis", "solitarydream", "lumia3", "purpleverse", "moonheart3", "glow", "enchantedlove", "take", "lifeispiano", "vandalism", "nexttoyou3", "lostcivilization3"],
|
||||
"singles": get_user_singles(c, user_id),
|
||||
"packs": get_user_packs(c, user_id),
|
||||
"characters": characters,
|
||||
@@ -207,7 +229,8 @@ def get_value_0(c, user_id):
|
||||
"recent_score": get_recent_score(c, user_id),
|
||||
"max_friend": 50,
|
||||
"rating": x[5],
|
||||
"join_date": int(x[3])
|
||||
"join_date": int(x[3]),
|
||||
"global_rank": 114514
|
||||
}
|
||||
|
||||
return r
|
||||
@@ -220,7 +243,7 @@ def arc_aggregate_small(user_id):
|
||||
r = {"success": True,
|
||||
"value": [{
|
||||
"id": 0,
|
||||
"value": get_value_0(c, user_id)
|
||||
"value": get_user_me(c, user_id)
|
||||
}]}
|
||||
|
||||
return r
|
||||
@@ -233,7 +256,7 @@ def arc_aggregate_big(user_id):
|
||||
r = {"success": True,
|
||||
"value": [{
|
||||
"id": 0,
|
||||
"value": get_value_0(c, user_id)
|
||||
"value": get_user_me(c, user_id)
|
||||
}, {
|
||||
"id": 1,
|
||||
"value": server.arcpurchase.get_item(c, 'pack')
|
||||
|
||||
@@ -1,4 +1,23 @@
|
||||
import os
|
||||
from shutil import copy, copy2
|
||||
from server.sql import Connect
|
||||
from database.database_initialize import main, ARCAEA_SERVER_VERSION
|
||||
from web.system import update_database
|
||||
|
||||
|
||||
def try_rename(path, new_path):
|
||||
# 尝试重命名文件,并尝试避免命名冲突,返回最终路径
|
||||
final_path = new_path
|
||||
if os.path.exists(new_path):
|
||||
i = 1
|
||||
while os.path.exists(new_path + str(i)):
|
||||
i += 1
|
||||
os.rename(path, new_path + str(i))
|
||||
final_path = new_path + str(i)
|
||||
else:
|
||||
os.rename(path, new_path)
|
||||
|
||||
return final_path
|
||||
|
||||
|
||||
def check_before_run(app):
|
||||
@@ -21,6 +40,56 @@ def check_before_run(app):
|
||||
if not os.path.exists('database/arcaea_database.db'):
|
||||
app.logger.warning('File `database/arcaea_database.db` is missing.')
|
||||
f = False
|
||||
try:
|
||||
app.logger.info(
|
||||
'Try to new the file `database/arcaea_database.db`.')
|
||||
main('./database/')
|
||||
app.logger.info(
|
||||
'Success to new the file `database/arcaea_database.db`.')
|
||||
f = True
|
||||
except:
|
||||
app.logger.warning(
|
||||
'Fail to new the file `database/arcaea_database.db`.')
|
||||
|
||||
else:
|
||||
with Connect() as c:
|
||||
try:
|
||||
c.execute('''select value from config where id="version"''')
|
||||
x = c.fetchone()
|
||||
except:
|
||||
x = None
|
||||
|
||||
# 数据库自动更新,不强求
|
||||
if not x or x[0] != ARCAEA_SERVER_VERSION:
|
||||
app.logger.warning(
|
||||
'Maybe the file `database/arcaea_database.db` is an old version.')
|
||||
try:
|
||||
app.logger.info(
|
||||
'Try to update the file `database/arcaea_database.db`.')
|
||||
|
||||
path = try_rename('database/arcaea_database.db',
|
||||
'database/arcaea_database.db.bak')
|
||||
|
||||
try:
|
||||
copy2(path, 'database/arcaea_database.db')
|
||||
except:
|
||||
copy(path, 'database/arcaea_database.db')
|
||||
|
||||
if os.path.isfile("database/old_arcaea_database.db"):
|
||||
os.remove('database/old_arcaea_database.db')
|
||||
|
||||
try_rename('database/arcaea_database.db',
|
||||
'database/old_arcaea_database.db')
|
||||
|
||||
main('./database/')
|
||||
update_database()
|
||||
|
||||
app.logger.info(
|
||||
'Success to update the file `database/arcaea_database.db`.')
|
||||
|
||||
except:
|
||||
app.logger.warning(
|
||||
'Fail to update the file `database/arcaea_database.db`.')
|
||||
|
||||
if not os.path.exists('database/arcsong.db'):
|
||||
app.logger.warning('File `database/arcsong.db` is missing.')
|
||||
|
||||
@@ -29,3 +29,52 @@ class Connect():
|
||||
traceback.format_exception(exc_type, exc_val, exc_tb))
|
||||
|
||||
return True
|
||||
|
||||
class Sql():
|
||||
|
||||
@staticmethod
|
||||
def select(c, table_name, target_column=[], limit=-1, offset=0, query={}, sort=[]):
|
||||
# 执行查询单句sql语句,返回fetchall数据
|
||||
# 使用准确查询,且在单表内
|
||||
|
||||
sql = 'select '
|
||||
sql_dict = {}
|
||||
if len(target_column) >= 2:
|
||||
sql += target_column[0]
|
||||
for i in range(1, len(target_column)):
|
||||
sql += ',' + target_column[i]
|
||||
sql += ' from ' + table_name
|
||||
elif len(target_column) == 1:
|
||||
sql += target_column[0] + ' from ' + table_name
|
||||
else:
|
||||
sql += '* from ' + table_name
|
||||
|
||||
where_field = []
|
||||
where_value = []
|
||||
for i in query:
|
||||
where_field.append(i)
|
||||
where_value.append(query[i])
|
||||
|
||||
if where_field and where_value:
|
||||
sql += ' where '
|
||||
sql += where_field[0] + '=:' + where_field[0]
|
||||
sql_dict[where_field[0]] = where_value[0]
|
||||
if len(where_field) >= 2:
|
||||
for i in range(1, len(where_field)):
|
||||
sql_dict[where_field[i]] = where_value[i]
|
||||
sql += ' and ' + where_field[i] + '=:' + where_field[i]
|
||||
|
||||
if sort:
|
||||
sql += ' order by ' + sort[0]['column'] + ' ' + sort[0]['order']
|
||||
if len(sort) >= 2:
|
||||
for i in range(1, len(sort)):
|
||||
sql += ', ' + sort[i]['column'] + ' ' + sort[i]['order']
|
||||
|
||||
if limit >= 0:
|
||||
sql += ' limit :limit offset :offset'
|
||||
sql_dict['limit'] = limit
|
||||
sql_dict['offset'] = offset
|
||||
|
||||
c.execute(sql, sql_dict)
|
||||
|
||||
return c.fetchall()
|
||||
|
||||
@@ -14,6 +14,16 @@ class Config():
|
||||
--------------------
|
||||
'''
|
||||
|
||||
'''
|
||||
--------------------
|
||||
游戏API地址前缀
|
||||
Game API's URL prefix
|
||||
'''
|
||||
GAME_API_PREFIX = '/blockchain/14'
|
||||
'''
|
||||
--------------------
|
||||
'''
|
||||
|
||||
'''
|
||||
--------------------
|
||||
SSL证书路径
|
||||
@@ -59,6 +69,17 @@ class Config():
|
||||
--------------------
|
||||
'''
|
||||
|
||||
'''
|
||||
--------------------
|
||||
API接口完全控制权限Token,留空则不使用
|
||||
API interface full control permission Token
|
||||
If you don't want to use it, leave it blank.
|
||||
'''
|
||||
API_TOKEN = ''
|
||||
'''
|
||||
--------------------
|
||||
'''
|
||||
|
||||
'''
|
||||
--------------------
|
||||
歌曲下载地址前缀,留空则自动获取
|
||||
|
||||
@@ -20,4 +20,4 @@
|
||||
{% endfor %} {% block content %}{% endblock %}
|
||||
</section>
|
||||
|
||||
<footer id="footer" class="footer">Made by Lost@2020</footer>
|
||||
<footer id="footer" class="footer">Made by Lost@2020-2021</footer>
|
||||
@@ -19,7 +19,7 @@
|
||||
<input name="rating_ftr" id="rating_ftr" required>
|
||||
<label for="rating_byd">Beyond chart const</label>
|
||||
<input name="rating_byd" id="rating_byd" required>
|
||||
<div class="content">如果没有某个铺面,应该填入-1。</div>
|
||||
<div class="content">如果没有某个谱面,应该填入-1。</div>
|
||||
<div class="content">If there is no some chart, fill in -1 please.</div>
|
||||
<input type="submit" value="Add">
|
||||
</form>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<a href="{{ url_for('index.single_player_score') }}">单个玩家成绩查询 Single player score</a></br></br>
|
||||
<a href="{{ url_for('index.single_player_ptt') }}">单个玩家PTT详情查询 Single player ptt</a></br></br>
|
||||
<a href="{{ url_for('index.all_player') }}">所有玩家信息查询 All players</a></br></br>
|
||||
<a href="{{ url_for('index.all_song') }}">铺面信息查询 All songs</a></br></br>
|
||||
<a href="{{ url_for('index.all_song') }}">谱面信息查询 All songs</a></br></br>
|
||||
<a href="{{ url_for('index.all_character') }}">角色信息查询 All characters</a></br></br>
|
||||
<a href="{{ url_for('index.all_item') }}">购买信息查询 All items</a></br></br>
|
||||
<a href="{{ url_for('index.all_present') }}">奖励信息查询 All presents</a></br></br>
|
||||
|
||||
@@ -18,4 +18,26 @@
|
||||
Uploadable files: arcaea_database.db & arcsong.db<br />
|
||||
Data that does not exist in the new database will be added and the existing duplicate data will also be changed.
|
||||
</div>
|
||||
<br />
|
||||
<hr />
|
||||
<form action="/web/updatedatabase/refreshsonghash" method="post">
|
||||
<div class="title">Refresh songs' hash</div>
|
||||
<br />
|
||||
<input type="submit" value="Refresh">
|
||||
|
||||
<div class="content">这里可以刷新储存在数据库中的songs文件夹下所有文件的Hash值。目的是应对歌曲谱面文件的更新。</div>
|
||||
<div class="content">Here you can refresh the hash values of all the files stored in the songs folder in the
|
||||
database. The purpose is to deal with the updating of songs' files.</div>
|
||||
</form>
|
||||
<br />
|
||||
<hr />
|
||||
<form action="/web/updatedatabase/refreshsongrating" method="post">
|
||||
<div class="title">Refresh songs' rating</div>
|
||||
<br />
|
||||
<input type="submit" value="Refresh">
|
||||
|
||||
<div class="content">这里可以刷新数据库中所有成绩的评分。目的是应对歌曲谱面定数的更新。</div>
|
||||
<div class="content">Here you can refresh the ratings of all scores in the database. The purpose is to deal
|
||||
with the updating of songs' chart consts.</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -10,6 +10,7 @@ import time
|
||||
import server.arcscore
|
||||
import os
|
||||
import json
|
||||
from server.arcdownload import initialize_songfile
|
||||
|
||||
UPLOAD_FOLDER = 'database'
|
||||
ALLOWED_EXTENSIONS = {'db'}
|
||||
@@ -277,6 +278,30 @@ def update_database():
|
||||
return render_template('web/updatedatabase.html')
|
||||
|
||||
|
||||
@bp.route('/updatedatabase/refreshsonghash', methods=['POST'])
|
||||
@login_required
|
||||
def update_song_hash():
|
||||
# 更新数据库内谱面文件hash值
|
||||
error = initialize_songfile()
|
||||
if error:
|
||||
flash(error)
|
||||
else:
|
||||
flash('数据刷新成功 Success refresh data.')
|
||||
return render_template('web/updatedatabase.html')
|
||||
|
||||
|
||||
@bp.route('/updatedatabase/refreshsongrating', methods=['POST'])
|
||||
@login_required
|
||||
def update_song_rating():
|
||||
# 更新所有分数的rating
|
||||
error = server.arcscore.refresh_all_score_rating()
|
||||
if error:
|
||||
flash(error)
|
||||
else:
|
||||
flash('数据刷新成功 Success refresh data.')
|
||||
return render_template('web/updatedatabase.html')
|
||||
|
||||
|
||||
@bp.route('/changesong', methods=['GET'])
|
||||
@login_required
|
||||
def change_song():
|
||||
|
||||
@@ -195,6 +195,11 @@ def update_database():
|
||||
update_one_table(c1, c2, 'user_present')
|
||||
update_one_table(c1, c2, 'redeem')
|
||||
update_one_table(c1, c2, 'user_redeem')
|
||||
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_user_char(c2)
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import time
|
||||
|
||||
|
||||
def get_user_score(c, user_id, limit=-1):
|
||||
def get_user_score(c, user_id, limit=-1, offset=0):
|
||||
# 返回用户的所有歌曲数据,带排名,返回字典列表
|
||||
if limit >= 0:
|
||||
c.execute('''select * from best_score where user_id =:a order by rating DESC limit :b''',
|
||||
{'a': user_id, 'b': limit})
|
||||
c.execute('''select * from best_score where user_id =:a order by rating DESC limit :b offset :c''',
|
||||
{'a': user_id, 'b': limit, 'c': offset})
|
||||
else:
|
||||
c.execute(
|
||||
'''select * from best_score where user_id =:a order by rating DESC''', {'a': user_id})
|
||||
@@ -77,7 +77,7 @@ def get_user(c, user_id):
|
||||
|
||||
|
||||
def get_user_recent30(c, user_id):
|
||||
# 获取玩家recent30信息并计算这一部分的ptt,返回字典列表和一个值
|
||||
# 获取玩家recent30信息并计算recent10的ptt,返回字典列表和一个值
|
||||
c.execute('''select * from recent30 where user_id=:a''', {'a': user_id})
|
||||
sumr = 0
|
||||
x = c.fetchone()
|
||||
|
||||
Reference in New Issue
Block a user