11 Commits
v2.6 ... v2.7.0

Author SHA1 Message Date
Lost-MSth
d0be49fe20 Update to v2.7.0 2021-11-14 21:35:34 +08:00
Lost-MSth
b494b93c14 Update to v2.6.6 without release
- Fix a bug about purchase discount
- Fix a bug about database synchronization, which may make 'api_login' table empty
- For Arcaea 3.8.8
- Update a logout api
2021-10-22 20:00:22 +08:00
Lost-MSth
a523ff5aae Update README.md
Add some download links.

close #28
2021-10-01 16:24:56 +08:00
Lost-MSth
acbe9fc4a1 Merge pull request #31 from superDXZ/master
Try to add some download links.
2021-10-01 16:19:53 +08:00
superDXZ
9422bf7182 Update README.md
Found another download site
2021-10-01 02:49:06 +08:00
superDXZ
53acad4ffb Update README.md
Found another download site
2021-10-01 02:46:39 +08:00
Lost-MSth
13048e57f4 Update to v2.6.5 without release
- Change something to make that purchase things can have some cores.
- Fix the download link of Arcaea client in README

> This is a small update.
2021-09-30 19:02:10 +08:00
Lost-MSth
39d3f073ba Update to v2.6.4 without release 2021-09-08 17:35:10 +08:00
Lost-MSth
2cf6595478 Update to v2.6.3 2021-08-25 14:31:06 +08:00
Lost-MSth
7c3bc99570 Update to v2.6.2 2021-08-11 18:45:32 +08:00
Lost-MSth
168e5f0b12 Update to v2.6.1 2021-07-21 18:14:26 +08:00
22 changed files with 2523 additions and 1216 deletions

View File

@@ -53,7 +53,9 @@ It is just so interesting. What it can do is under exploration.
## 下载 Download ## 下载 Download
[这里 Here](https://github.com/Lost-MSth/Arcaea-server/releases) [这里 Here](https://github.com/Lost-MSth/Arcaea-server/releases)
[Arcaea](https://konmai.cn/#arcaea) [Arcaea-CN official](https://arcaea.lowiro.com/zh)
[Arcaea-lowi.ro](https://lowi.ro)
[Arcaea-RhyDown](https://rhydown.com)
## 更新日志 Update log ## 更新日志 Update log
只保留最新版本 Only keep the latest version. 只保留最新版本 Only keep the latest version.
@@ -62,19 +64,25 @@ It is just so interesting. What it can do is under exploration.
> >
> Tips: When updating, please keep the original database in case of data loss. > Tips: When updating, please keep the original database in case of data loss.
### Version 2.6 ### Version 2.7.0
- 适用于Arcaea 3.6.4版本 For Arcaea 3.6.4 - 适用于Arcaea 3.9.0版本 For Arcaea 3.9.0
- 更新了歌曲数据库 Update the song database. - 更新了歌曲数据库 Update the song database.
-增体力系统 Add stamina system. -搭档 **爱丽丝 & 坦尼尔(小步舞曲)** 已解锁 Unlock the new character **Alice & Tenniel (Minuet)**.
- 完善了登陆奖励系统 Improve the login present system. - 新搭档 **对立(挽歌)** 已解锁 Unlock the new character **Tairitsu (Elegy)**.
- 完善了兑换码系统 Improve the redeem code system. - 搭档 **爱托** 已觉醒 Uncap the character **Eto**.
- 新增了多设备自动封号机制 Add multi device auto ban mechanism. - 搭档 **露娜** 已觉醒 Uncap the character **Luna**.
- 修复了一些Bug Fix some bugs. - 新增爱托和露娜的觉醒技能(可能有问题) Add the uncapped skills of Eto and Luna (There may be bugs.).
- 修复好友列表没有按照最近成绩日期排序的问题(Menci) Fix the friend list not sorted by last score date. (From Menci) - 新增是否同步角色表的设置选项 Add the setting option of whether updating the character table.
- 修复某些情况下跨目录运行失败的问题(MBRjun) Fix cross directory running problem in some cases. (From MBRjun)
- 以下是累积更新 The following are cumulative updates:
- 添加购买物品含有以太之滴的支持 Add support for purchasing items containing generic cores.
- 修复关于购买物品打折的问题 Fix a bug about purchase discount.
- 修复关于数据库同步的问题这可能导致api_login表为空 Fix a bug about database synchronization, which may make 'api_login' table empty.
- 新增登出API接口 Update a logout API.
> 提示:某些数据可能尚不完整,某个单曲的解锁和某两个角色的数据可能会有问题
> Tips: Some data may not be complete, so there may be problems with the unlocking of a single song and the data of two characters.
> 提醒使用新版本前可能需要清空redeemuser_redeempresentuser_present表
> Tips: Before using the new version, you may need to clear the redeem, user_redeem, present, user_present table.
## 运行环境与依赖 Running environment and requirements ## 运行环境与依赖 Running environment and requirements
- Windows/Linux/Mac OS/Android - Windows/Linux/Mac OS/Android

View File

@@ -1,5 +1,7 @@
import hashlib import hashlib
import base64
import time import time
import random
from server.sql import Connect from server.sql import Connect
import functools import functools
from setting import Config from setting import Config
@@ -14,14 +16,50 @@ class User():
self.power = power self.power = power
def login(): def login(auth: str, ip: str):
# 登录接口 # 登录接口,返回字典和错误码
return {'token': 1}, 0
try:
auth_decode = bytes.decode(base64.b64decode(auth))
except:
return {}, -100
if not ':' in auth_decode:
return {}, -100
name, password = auth_decode.split(':', 1)
with Connect() as c:
hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
c.execute('''select user_id, password from user where name = :name''', {
'name': name})
x = c.fetchone()
if x is None:
return {}, -201
if x[1] == '':
return {}, -202
if hash_pwd != x[1]:
return {}, -201
user_id = str(x[0])
now = int(time.time() * 1000)
token = hashlib.sha256(
(user_id + str(random.randint(10000, 99999)) + str(now)).encode("utf8")).hexdigest()
c.execute('''delete from api_login where user_id=?''', (user_id,))
c.execute('''insert into api_login values(?,?,?,?)''',
(user_id, token, now, ip))
return {'token': token, 'user_id': user_id}, 0
def logout(): def logout(user: User):
# 登出接口 # 登出接口,返回错误码
pass code = 999
with Connect() as c:
c.execute('''delete from api_login where user_id=?''', (user.user_id,))
code = 0
return code
def id_get_role_id(c, user_id): def id_get_role_id(c, user_id):
@@ -86,7 +124,7 @@ def role_required(request, power=[]):
return jsonify({'status': 400, 'code': -1, 'data': {}, 'msg': 'Payload must be a valid json'}) return jsonify({'status': 400, 'code': -1, 'data': {}, 'msg': 'Payload must be a valid json'})
if not 'Token' in request.headers: if not 'Token' in request.headers:
return jsonify({'status': 401, 'code': -1, 'data': {}, 'msg': 'No Token'}) return jsonify({'status': 401, 'code': -1, 'data': {}, 'msg': 'No token'})
user = User() user = User()
if Config.API_TOKEN == request.headers['Token'] and Config.API_TOKEN != '': if Config.API_TOKEN == request.headers['Token'] and Config.API_TOKEN != '':
@@ -98,7 +136,7 @@ def role_required(request, power=[]):
user.user_id = api_token_get_id( user.user_id = api_token_get_id(
c, request.headers['Token']) c, request.headers['Token'])
if user.user_id is None: if user.user_id is None:
return jsonify({'status': 404, 'code': -1, 'data': {}, 'msg': ''}) return jsonify({'status': 401, 'code': -1, 'data': {}, 'msg': 'No token'})
role_id = id_get_role_id(c, user.user_id) role_id = id_get_role_id(c, user.user_id)
user.role = role_id_get_role(c, role_id) user.role = role_id_get_role(c, role_id)

View File

@@ -6,10 +6,14 @@ def code_get_msg(code):
'-2': 'No data', '-2': 'No data',
'-3': 'No data or user', '-3': 'No data or user',
'-4': 'No user_id', '-4': 'No user_id',
'-100': 'Wrong post data',
'-101': 'Wrong data type', '-101': 'Wrong data type',
'-102': 'Wrong query parameter', '-102': 'Wrong query parameter',
'-103': 'Wrong sort parameter', '-103': 'Wrong sort parameter',
'-104': 'Wrong sort order parameter' '-104': 'Wrong sort order parameter',
'-201': 'Wrong username or password',
'-202': 'User is banned',
'-999': 'Unknown error'
} }
return msg[str(code)] return msg[str(code)]

View File

@@ -1,6 +1,7 @@
from flask import ( from flask import (
Blueprint, request, jsonify Blueprint, request, jsonify
) )
import functools
import api.api_auth import api.api_auth
import api.users import api.users
import api.songs import api.songs
@@ -10,93 +11,112 @@ from api.api_code import code_get_msg
bp = Blueprint('api', __name__, url_prefix='/api/v1') bp = Blueprint('api', __name__, url_prefix='/api/v1')
def get_query_parameter(request, query_able=[], sort_able=[]): class Query():
# 提取查询请求参数返回四个参数和code # 查询类,当查询附加参数的数据类型用
def __init__(self, limit=-1, offset=0, query={}, sort=[]) -> None:
self.limit = limit
self.offset = offset
self.query = query # {'name': 'admin'}
self.sort = sort # [{'column': 'user_id', 'order': 'ASC'}, ...]
limit = -1
offset = 0 def get_query_parameter(request, query_able=[], sort_able=[]):
query = {} # {'name': 'admin'} # 提取查询请求参数返回Query类查询参数写成修饰器
sort = [] # [{'column': 'user_id', 'order': 'ASC'}, ...]
def decorator(view):
@functools.wraps(view)
def wrapped_view(*args, **kwargs):
re = Query()
if 'limit' in request.json: if 'limit' in request.json:
try: try:
limit = int(request.json['limit']) re.limit = int(request.json['limit'])
except: except:
return -1, 0, {}, {}, -101 return jsonify({'status': 200, 'code': -101, 'data': {}, 'msg': code_get_msg(-101)})
if 'offset' in request.json: if 'offset' in request.json:
try: try:
offset = int(request.json['offset']) re.offset = int(request.json['offset'])
except: except:
return -1, 0, {}, {}, -101 return jsonify({'status': 200, 'code': -101, 'data': {}, 'msg': code_get_msg(-101)})
if 'query' in request.json: if 'query' in request.json:
query = request.json['query'] re.query = request.json['query']
for i in query: for i in re.query:
if i not in query_able: if i not in query_able:
return -1, 0, {}, {}, -102 return jsonify({'status': 200, 'code': -102, 'data': {}, 'msg': code_get_msg(-102)})
if 'sort' in request.json: if 'sort' in request.json:
sort = request.json['sort'] re.sort = request.json['sort']
for i in sort: for i in re.sort:
if 'column' not in i or i['column'] not in sort_able: if 'column' not in i or i['column'] not in sort_able:
return -1, 0, {}, {}, -103 return jsonify({'status': 200, 'code': -103, 'data': {}, 'msg': code_get_msg(-103)})
if not 'order' in i: if not 'order' in i:
i['order'] = 'ASC' i['order'] = 'ASC'
else: else:
if i['order'] not in ['ASC', 'DESC']: if i['order'] not in ['ASC', 'DESC']:
return -1, 0, {}, {}, -104 return jsonify({'status': 200, 'code': -104, 'data': {}, 'msg': code_get_msg(-104)})
return limit, offset, query, sort, 0 return view(re, *args, **kwargs)
return wrapped_view
return decorator
def return_encode(code: int = 0, data: dict = {}, status: int = 200, msg: str = ''):
# 构造返回返回jsonify处理过后的response_class
if msg == '':
msg = code_get_msg(code)
if code < 0:
return jsonify({'status': status, 'code': code, 'data': {}, 'msg': msg})
else:
return jsonify({'status': status, 'code': code, 'data': data, 'msg': msg})
@bp.route('/') @bp.route('/')
def ping(): def ping():
return jsonify({'status': 200, 'code': 0, 'data': {}, 'msg': ''}) return return_encode()
@bp.route('/token', methods=['POST']) @bp.route('/token', methods=['POST'])
def token_post(): def token_post():
# 登录获取token # 登录获取token
# {'auth': `base64(user_id:password)`}
if 'auth' in request.json: if 'auth' in request.json:
data, code = api.api_auth.login( data, code = api.api_auth.login(
request.json['auth'], request.remote_addr) str(request.json['auth']), request.remote_addr)
if code < 0: return return_encode(code, data)
return jsonify({'status': 200, 'code': code, 'data': {}, 'msg': code_get_msg(code)})
else: else:
return jsonify({'status': 200, 'code': 0, 'data': data, 'msg': ''}) return return_encode(-1, {}, 401, 'No authentication')
else:
return jsonify({'status': 401, 'code': -1, 'data': {}, 'msg': 'No authentication'})
@bp.route('/token', methods=['GET']) @bp.route('/token', methods=['GET'])
@api.api_auth.role_required(request, ['select_me', 'select']) @api.api_auth.role_required(request, ['select_me', 'select'])
def token_get(user): def token_get(user):
# 判断登录有效性 # 判断登录有效性
return jsonify({'status': 200, 'code': 0, 'data': {}, 'msg': ''}) return return_encode()
@bp.route('/token', methods=['DELETE']) @bp.route('/token', methods=['DELETE'])
@api.api_auth.role_required(request, ['change_me', 'select_me', 'select']) @api.api_auth.role_required(request, ['change_me', 'select_me', 'select'])
def token_delete(user): def token_delete(user):
# 登出 # 登出
return jsonify({'status': 200, 'code': 0, 'data': {}, 'msg': ''}) return return_encode(api.api_auth.logout(user))
@bp.route('/users', methods=['GET']) @bp.route('/users', methods=['GET'])
@api.api_auth.role_required(request, ['select']) @api.api_auth.role_required(request, ['select'])
def users_get(user): @get_query_parameter(request, ['user_id', 'name', 'user_code'], [
'user_id', 'name', 'user_code', 'join_date', 'rating_ptt', 'time_played', 'ticket', 'world_rank_score'])
def users_get(query, user):
# 查询全用户信息 # 查询全用户信息
limit, offset, query, sort, code = get_query_parameter(request, ['user_id', 'name', 'user_code'], [ data = api.users.get_users(query)
'user_id', 'name', 'user_code', 'join_date', 'rating_ptt', 'time_played', 'ticket', 'world_rank_score'])
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: if not data:
return jsonify({'status': 200, 'code': -2, 'data': {}, 'msg': code_get_msg(-2)}) return return_encode(-2)
return jsonify({'status': 200, 'code': 0, 'data': data, 'msg': ''}) return return_encode(0, data)
@bp.route('/users/<int:user_id>', methods=['GET']) @bp.route('/users/<int:user_id>', methods=['GET'])
@@ -108,17 +128,17 @@ def users_user_get(user, user_id):
user_id = user.user_id user_id = user.user_id
if user_id <= 0: if user_id <= 0:
return jsonify({'status': 200, 'code': -4, 'data': {}, 'msg': code_get_msg(-4)}) return return_encode(-4)
if user_id != user.user_id and not 'select' in user.power and user.user_id != 0: # 查别人需要select权限 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'}) return return_encode(-1, {}, 403, 'No permission')
data = api.users.get_user_info(user_id) data = api.users.get_user_info(user_id)
if not data: if not data:
return jsonify({'status': 200, 'code': -3, 'data': {}, 'msg': code_get_msg(-3)}) return return_encode(-3)
return jsonify({'status': 200, 'code': 0, 'data': data, 'msg': ''}) return return_encode(0, data)
@bp.route('/users/<int:user_id>/b30', methods=['GET']) @bp.route('/users/<int:user_id>/b30', methods=['GET'])
@@ -126,48 +146,39 @@ def users_user_get(user, user_id):
def users_user_b30_get(user, user_id): def users_user_b30_get(user, user_id):
# 查询用户b30 # 查询用户b30
if user_id == 'me':
user_id = user.user_id
if user_id <= 0: if user_id <= 0:
return jsonify({'status': 200, 'code': -4, 'data': {}, 'msg': code_get_msg(-4)}) return return_encode(-4)
if user_id != user.user_id and not 'select' in user.power and user.user_id != 0: # 查别人需要select权限 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'}) return return_encode(-1, {}, 403, 'No permission')
data = api.users.get_user_b30(user_id) data = api.users.get_user_b30(user_id)
if data['data'] == []: if data['data'] == []:
return jsonify({'status': 200, 'code': -3, 'data': {}, 'msg': code_get_msg(-3)}) return return_encode(-3)
return jsonify({'status': 200, 'code': 0, 'data': data, 'msg': ''}) return return_encode(0, data)
@bp.route('/users/<int:user_id>/best', methods=['GET']) @bp.route('/users/<int:user_id>/best', methods=['GET'])
@api.api_auth.role_required(request, ['select', 'select_me']) @api.api_auth.role_required(request, ['select', 'select_me'])
def users_user_best_get(user, user_id): @get_query_parameter(request, ['song_id', 'difficulty'], [
'song_id', 'difficulty', 'score', 'time_played', 'rating'])
def users_user_best_get(query, user, user_id):
# 查询用户所有best成绩 # 查询用户所有best成绩
if user_id == 'me':
user_id = user.user_id
if user_id <= 0: if user_id <= 0:
return jsonify({'status': 200, 'code': -4, 'data': {}, 'msg': code_get_msg(-4)}) return return_encode(-4)
if user_id != user.user_id and not 'select' in user.power and user.user_id != 0: # 查别人需要select权限 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'}) return return_encode(-1, {}, 403, 'No permission')
limit, offset, query, sort, code = get_query_parameter(request, ['song_id', 'difficulty'], [ data = api.users.get_user_best(user_id, query)
'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'] == []: if data['data'] == []:
return jsonify({'status': 200, 'code': -3, 'data': {}, 'msg': code_get_msg(-3)}) return return_encode(-3)
return jsonify({'status': 200, 'code': 0, 'data': data, 'msg': ''}) return return_encode(0, data)
@bp.route('/users/<int:user_id>/r30', methods=['GET']) @bp.route('/users/<int:user_id>/r30', methods=['GET'])
@@ -175,21 +186,18 @@ def users_user_best_get(user, user_id):
def users_user_r30_get(user, user_id): def users_user_r30_get(user, user_id):
# 查询用户r30 # 查询用户r30
if user_id == 'me':
user_id = user.user_id
if user_id <= 0: if user_id <= 0:
return jsonify({'status': 200, 'code': -4, 'data': {}, 'msg': code_get_msg(-4)}) return return_encode(-4)
if user_id != user.user_id and not 'select' in user.power and user.user_id != 0: # 查别人需要select权限 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'}) return return_encode(-1, {}, 403, 'No permission')
data = api.users.get_user_r30(user_id) data = api.users.get_user_r30(user_id)
if data['data'] == []: if data['data'] == []:
return jsonify({'status': 200, 'code': -3, 'data': {}, 'msg': code_get_msg(-3)}) return return_encode(-3)
return jsonify({'status': 200, 'code': 0, 'data': data, 'msg': ''}) return return_encode(0, data)
@bp.route('/songs/<string:song_id>', methods=['GET']) @bp.route('/songs/<string:song_id>', methods=['GET'])
@@ -200,24 +208,21 @@ def songs_song_get(user, song_id):
data = api.songs.get_song_info(song_id) data = api.songs.get_song_info(song_id)
if not data: if not data:
return jsonify({'status': 200, 'code': -2, 'data': {}, 'msg': code_get_msg(-2)}) return return_encode(-2)
return jsonify({'status': 200, 'code': 0, 'data': data, 'msg': ''}) return return_encode(0, data)
@bp.route('/songs', methods=['GET']) @bp.route('/songs', methods=['GET'])
@api.api_auth.role_required(request, ['select', 'select_song_info']) @api.api_auth.role_required(request, ['select', 'select_song_info'])
def songs_get(user): @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'])
def songs_get(query, user):
# 查询全歌曲信息 # 查询全歌曲信息
limit, offset, query, sort, code = get_query_parameter(request, ['sid', 'name_en', 'name_jp', 'pakset', 'artist'], [ data = api.songs.get_songs(query)
'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: if not data:
return jsonify({'status': 200, 'code': -2, 'data': {}, 'msg': code_get_msg(-2)}) return return_encode(-2)
return jsonify({'status': 200, 'code': 0, 'data': data, 'msg': ''}) return return_encode(0, data)

View File

@@ -30,12 +30,12 @@ def get_song_info(song_id):
return r return r
def get_songs(limit=-1, offset=0, query={}, sort=[]): def get_songs(query=None):
# 查询全部歌曲信息,返回字典列表 # 查询全部歌曲信息,返回字典列表
r = [] r = []
with Connect('./database/arcsong.db') as c: with Connect('./database/arcsong.db') as c:
x = Sql.select(c, 'songs', [], limit, offset, query, sort) x = Sql.select(c, 'songs', [], query)
if x: if x:
for i in x: for i in x:

View File

@@ -5,12 +5,12 @@ import web.webscore
import server.info import server.info
def get_users(limit=-1, offset=0, query={}, sort=[]): def get_users(query=None):
# 获取全用户信息,返回字典列表 # 获取全用户信息,返回字典列表
r = [] r = []
with Connect() as c: with Connect() as c:
x = Sql.select(c, 'user', [], limit, offset, query, sort) x = Sql.select(c, 'user', [], query)
if x: if x:
for i in x: for i in x:
@@ -62,12 +62,12 @@ def get_user_b30(user_id):
return {'user_id': user_id, 'b30_ptt': bestptt / 30, 'data': r} return {'user_id': user_id, 'b30_ptt': bestptt / 30, 'data': r}
def get_user_best(user_id, limit=-1, offset=0, query={}, sort=[]): def get_user_best(user_id, query=None):
# 获取用户b30信息返回字典 # 获取用户b30信息返回字典
r = [] r = []
with Connect() as c: with Connect() as c:
x = Sql.select(c, 'best_score', [], limit, offset, query, sort) x = Sql.select(c, 'best_score', [], query)
if x: if x:
for i in x: for i in x:
r.append({ r.append({

Binary file not shown.

View File

@@ -4,7 +4,7 @@ import json
# 数据库初始化文件删掉arcaea_database.db文件后运行即可谨慎使用 # 数据库初始化文件删掉arcaea_database.db文件后运行即可谨慎使用
ARCAEA_SERVER_VERSION = 'v2.6' ARCAEA_SERVER_VERSION = 'v2.7.0'
def main(path='./'): def main(path='./'):
@@ -228,6 +228,7 @@ def main(path='./'):
c.execute('''create table if not exists purchase_item(purchase_name text, c.execute('''create table if not exists purchase_item(purchase_name text,
item_id text, item_id text,
type text, type text,
amount int,
primary key(purchase_name, item_id, type) primary key(purchase_name, item_id, type)
);''') );''')
c.execute('''create table if not exists user_save(user_id int primary key, c.execute('''create table if not exists user_save(user_id int primary key,
@@ -298,46 +299,46 @@ def main(path='./'):
# 搭档初始化 # 搭档初始化
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', 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', '???', 'nami'] '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', 'linka', 'nami', 'Saya & Elizabeth', 'lily', 'kanae(midsummer)', 'alice&tenniel(minuet)', 'tairitsu(elegy)']
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', 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', 'gauge_safe_10', 'frags_nami'] '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', 'gauge_safe_10', 'frags_nami', 'skill_elizabeth', 'skill_lily', 'skill_kanae_midsummer', '', '']
skill_id_uncap = ['', '', 'frags_kou', '', 'visual_ink', '', '', '', '', '', '', '', '', 'shirabe_entry_fee', skill_id_uncap = ['', '', 'frags_kou', '', 'visual_ink', '', '', '', '', '', '', 'eto_uncap', 'luna_uncap', 'shirabe_entry_fee',
'', '', '', '', '', '', '', 'frags_yume', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''] '', '', '', '', '', '', '', 'frags_yume', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
skill_unlock_level = [0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 0, 0, 0, 0, 0, skill_unlock_level = [0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 0, 0, 0, 0, 0,
0, 0, 0, 8, 0, 14, 0, 0, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0] 0, 0, 0, 8, 0, 14, 0, 0, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
frag1 = [55, 55, 60, 50, 47, 0, 47, 57, 41, 22, 50, 54, 60, 56, 78, 42, 41, 61, 52, 50, 52, 32, frag1 = [55, 55, 60, 50, 47, 0, 47, 57, 41, 22, 50, 54, 60, 56, 78, 42, 41, 61, 52, 50, 52, 32,
42, 55, 45, 58, 43, 0.5, 68, 50, 62, 45, 45, 52, 44, 27, 59, 0, 45, 50, 50, 47, 47, 61, 43, 42, 50, 25] 42, 55, 45, 58, 43, 0.5, 68, 50, 62, 45, 45, 52, 44, 27, 59, 0, 45, 50, 50, 47, 47, 61, 43, 42, 50, 25, 58, 50, 61, 55, 55]
prog1 = [35, 55, 47, 50, 60, 0, 60, 70, 58, 45, 70, 45, 42, 46, 61, 67, 49, 44, 28, 45, 24, 46, 52, prog1 = [35, 55, 47, 50, 60, 0, 60, 70, 58, 45, 70, 45, 42, 46, 61, 67, 49, 44, 28, 45, 24, 46, 52,
59, 62, 33, 58, 25, 63, 69, 50, 45, 45, 51, 34, 70, 62, 70, 45, 32, 32, 61, 47, 47, 37, 42, 50, 50] 59, 62, 33, 58, 25, 63, 69, 50, 45, 45, 51, 34, 70, 62, 70, 45, 32, 32, 61, 47, 47, 37, 42, 50, 50, 45, 41, 61, 55, 55]
overdrive1 = [35, 55, 25, 50, 47, 0, 72, 57, 41, 7, 10, 32, 65, 31, 61, 53, 31, 47, 38, 12, 39, 18, overdrive1 = [35, 55, 25, 50, 47, 0, 72, 57, 41, 7, 10, 32, 65, 31, 61, 53, 31, 47, 38, 12, 39, 18,
48, 65, 45, 55, 44, 25, 46, 44, 33, 45, 45, 37, 25, 27, 50, 20, 45, 63, 21, 47, 61, 47, 65, 80, 50, 30] 48, 65, 45, 55, 44, 25, 46, 44, 33, 45, 45, 37, 25, 27, 50, 20, 45, 63, 21, 47, 61, 47, 65, 80, 50, 30, 49, 15, 34, 55, 55]
frag20 = [78, 80, 90, 75, 70, 0, 70, 79, 65, 40, 50, 80, 90, 82, 0, 61, 67, 92, 85, 50, 86, 52, frag20 = [78, 80, 90, 75, 70, 0, 70, 79, 65, 40, 50, 80, 90, 82, 0, 61, 67, 92, 85, 50, 86, 52,
65, 85, 67, 88, 64, 0.5, 95, 70, 95, 50, 80, 87, 71, 50, 85, 0, 80, 75, 50, 70, 70, 90, 65, 80, 100, 50] 65, 85, 67, 88, 64, 0.5, 95, 70, 95, 50, 80, 87, 71, 50, 85, 0, 80, 75, 50, 70, 70, 90, 65, 80, 100, 50, 68, 60, 90, 80, 80]
prog20 = [61, 80, 70, 75, 90, 0, 90, 102, 84, 78, 105, 67, 63, 68, 0, 99, 80, 66, 46, 83, 40, 73, prog20 = [61, 80, 70, 75, 90, 0, 90, 102, 84, 78, 105, 67, 63, 68, 0, 99, 80, 66, 46, 83, 40, 73,
80, 90, 93, 50, 86, 78, 89, 98, 75, 80, 50, 64, 55, 100, 90, 110, 80, 50, 74, 90, 70, 70, 56, 80, 100, 55] 80, 90, 93, 50, 86, 78, 89, 98, 75, 80, 50, 64, 55, 100, 90, 110, 80, 50, 74, 90, 70, 70, 56, 80, 100, 55, 65, 59, 90, 80, 80]
overdrive20 = [61, 80, 47, 75, 70, 0, 95, 79, 65, 31, 50, 59, 90, 58, 0, 78, 50, 70, 62, 49, 64, overdrive20 = [61, 80, 47, 75, 70, 0, 95, 79, 65, 31, 50, 59, 90, 58, 0, 78, 50, 70, 62, 49, 64,
46, 73, 95, 67, 84, 70, 78, 69, 70, 50, 80, 80, 63, 25, 50, 72, 55, 50, 95, 55, 70, 90, 70, 99, 80, 100, 40] 46, 73, 95, 67, 84, 70, 78, 69, 70, 50, 80, 80, 63, 25, 50, 72, 55, 50, 95, 55, 70, 90, 70, 99, 80, 100, 40, 69, 62, 51, 80, 80]
frag30 = [88, 90, 100, 75, 80, 0, 70, 79, 65, 40, 50, 80, 90, 92, 0, 61, 67, 92, 85, 50, 86, 62, frag30 = [88, 90, 100, 75, 80, 0, 70, 79, 65, 40, 50, 90, 100, 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, 80, 100, 50] 65, 85, 67, 88, 74, 0.5, 105, 80, 95, 50, 80, 87, 71, 50, 95, 0, 80, 75, 50, 70, 80, 100, 65, 80, 100, 50, 68, 60, 90, 80, 80]
prog30 = [71, 90, 80, 75, 100, 0, 90, 102, 84, 78, 105, 67, 63, 78, 0, 99, 80, 66, 46, 83, 40, 83, prog30 = [71, 90, 80, 75, 100, 0, 90, 102, 84, 78, 105, 77, 73, 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, 80, 100, 55] 80, 90, 93, 50, 96, 88, 99, 108, 75, 80, 50, 64, 55, 100, 100, 110, 80, 50, 74, 90, 80, 80, 56, 80, 100, 55, 65, 59, 90, 80, 80]
overdrive30 = [71, 90, 57, 75, 80, 0, 95, 79, 65, 31, 50, 59, 90, 68, 0, 78, 50, 70, 62, 49, 64, overdrive30 = [71, 90, 57, 75, 80, 0, 95, 79, 65, 31, 50, 69, 100, 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, 99, 80, 100, 40] 56, 73, 95, 67, 84, 80, 88, 79, 80, 50, 80, 80, 63, 25, 50, 82, 55, 50, 95, 55, 70, 100, 80, 99, 80, 100, 40, 69, 62, 51, 80, 80]
char_type = [1, 0, 0, 0, 0, 0, 0, 2, 0, 1, 2, 0, 0, 0, 2, 3, 1, 0, 0, 0, 1, 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, 0, 0] 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, 0, 0, 0, 0, 0, 0, 0]
char_core = { char_core = {
0: [{'core_id': 'core_hollow', 'amount': 25}, {'core_id': 'core_desolate', 'amount': 5}], 0: [{'core_id': 'core_hollow', 'amount': 25}, {'core_id': 'core_desolate', 'amount': 5}],
@@ -352,13 +353,15 @@ def main(path='./'):
29: [{'core_id': 'core_chunithm', 'amount': 15}], 29: [{'core_id': 'core_chunithm', 'amount': 15}],
36: [{'core_id': 'core_chunithm', 'amount': 15}], 36: [{'core_id': 'core_chunithm', 'amount': 15}],
42: [{'core_id': 'core_chunithm', 'amount': 15}], 42: [{'core_id': 'core_chunithm', 'amount': 15}],
43: [{'core_id': 'core_chunithm', 'amount': 15}] 43: [{'core_id': 'core_chunithm', 'amount': 15}],
11: [{'core_id': 'core_binary', 'amount': 25}, {'core_id': 'core_hollow', 'amount': 5}],
12: [{'core_id': 'core_binary', 'amount': 25}, {'core_id': 'core_desolate', 'amount': 5}]
} }
for i in range(0, 48): for i in range(0, 53):
skill_requires_uncap = 1 if i == 2 else 0 skill_requires_uncap = 1 if i == 2 else 0
if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21, 42, 43]: if i in [0, 1, 2, 4, 13, 26, 27, 28, 29, 36, 21, 42, 43, 11, 12]:
sql = '''insert into character values(?,?,30,?,?,?,?,?,?,?,?,?,?,?,?,?,?,1)''' sql = '''insert into character values(?,?,30,?,?,?,?,?,?,?,?,?,?,?,?,?,?,1)'''
c.execute(sql, (i, char[i], frag1[i], prog1[i], overdrive1[i], frag20[i], prog20[i], overdrive20[i], c.execute(sql, (i, char[i], frag1[i], prog1[i], overdrive1[i], frag20[i], prog20[i], overdrive20[i],
frag30[i], prog30[i], overdrive30[i], skill_id[i], skill_unlock_level[i], skill_requires_uncap, skill_id_uncap[i], char_type[i])) frag30[i], prog30[i], overdrive30[i], skill_id[i], skill_unlock_level[i], skill_requires_uncap, skill_id_uncap[i], char_type[i]))
@@ -373,13 +376,13 @@ def main(path='./'):
c.execute('''insert into char_item values(?,?,'core',?)''', c.execute('''insert into char_item values(?,?,'core',?)''',
(i, j['core_id'], j['amount'])) (i, j['core_id'], j['amount']))
cores = ['core_hollow', 'core_desolate', 'core_chunithm', 'core_crimson', cores = ['core_hollow', 'core_desolate', 'core_chunithm', 'core_crimson',
'core_ambivalent', 'core_scarlet', 'core_groove', 'core_generic'] 'core_ambivalent', 'core_scarlet', 'core_groove', 'core_generic', 'core_binary']
for i in cores: for i in cores:
c.execute('''insert into item values(?,"core",1,'')''', (i,)) c.execute('''insert into item values(?,"core",1,'')''', (i,))
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", 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", "turbocharger", "bookmaker3", "laqryma3"] "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", "turbocharger", "bookmaker3", "laqryma3", "kyogenkigo", "hivemind", "seclusion", "quonwacca3", "bluecomet", "energysynergymatrix", "gengaozo", "lastendconductor3"]
for i in world_songs: for i in world_songs:
c.execute('''insert into item values(?,"world_song",1,'')''', (i,)) c.execute('''insert into item values(?,"world_song",1,'')''', (i,))
@@ -411,10 +414,17 @@ def main(path='./'):
_id = '' _id = ''
else: else:
_id = j['_id'] _id = j['_id']
c.execute(
'''select exists(select * from item where item_id=?)''', (j['id'],))
if c.fetchone() == (0,):
c.execute('''insert into item values(?,?,?,?)''', c.execute('''insert into item values(?,?,?,?)''',
(j['id'], j['type'], j['is_available'], _id)) (j['id'], j['type'], j['is_available'], _id))
c.execute('''insert into purchase_item values(?,?,?)''', if 'amount' in j:
(i['name'], j['id'], j['type'])) amount = j['amount']
else:
amount = 1
c.execute('''insert into purchase_item values(?,?,?,?)''',
(i['name'], j['id'], j['type'], amount))
# item初始化 # item初始化
f = open(path+'singles.json', 'r') f = open(path+'singles.json', 'r')

View File

@@ -0,0 +1,376 @@
{
"map_id": "byd_bookmaker",
"is_legacy": false,
"chapter": 1001,
"available_from": -1,
"available_to": 9999999999999,
"is_repeatable": false,
"require_id": "bookmaker2",
"require_type": "chart_unlock",
"coordinate": "-650,-650",
"is_beyond": true,
"stamina_cost": 3,
"beyond_health": 300,
"character_affinity": [
23,
34,
47
],
"affinity_multiplier": [
1.3,
5,
3.8
],
"step_count": 31,
"custom_bg": "",
"curr_position": 3,
"curr_capture": 35.81730523472207,
"is_locked": false,
"steps": [
{
"map_id": "byd_bookmaker",
"position": 0,
"capture": 10
},
{
"map_id": "byd_bookmaker",
"position": 1,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 2,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 3,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
],
"restrict_ids": [
"bookmaker",
"viciousheroism",
"battlenoone",
"galaxyfriends",
"rekkaresonance"
],
"restrict_type": "song_id"
},
{
"map_id": "byd_bookmaker",
"position": 4,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 5,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 6,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 7,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 8,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 9,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 10,
"capture": 10,
"items": [
{
"type": "core",
"id": "core_generic",
"amount": 1
}
]
},
{
"map_id": "byd_bookmaker",
"position": 11,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 12,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 13,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 14,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 15,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 16,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 17,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 18,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 19,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 20,
"capture": 10,
"items": [
{
"type": "core",
"id": "core_generic",
"amount": 1
}
]
},
{
"map_id": "byd_bookmaker",
"position": 21,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 22,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 23,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 24,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 25,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 26,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 27,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 28,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 29,
"capture": 10,
"items": [
{
"type": "fragment",
"amount": 30
}
]
},
{
"map_id": "byd_bookmaker",
"position": 30,
"capture": 0,
"items": [
{
"id": "bookmaker3",
"type": "world_song"
}
]
}
]
}

View File

@@ -1,250 +1,515 @@
[{ [
{
"name": "core", "name": "core",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "core", "id": "core",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 5,
"id": "core_generic",
"is_available": true
}
],
"price": 500, "price": 500,
"orig_price": 500, "orig_price": 500,
"discount_from": 1615248000000, "discount_from": 1615248000000,
"discount_to": 1615852799000 "discount_to": 1615852799000
}, { },
{
"name": "shiawase", "name": "shiawase",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "shiawase", "id": "shiawase",
"is_available": true "is_available": true
}, { },
{
"type": "character", "type": "character",
"id": "kou", "id": "kou",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 5,
"id": "core_generic",
"is_available": true
}
],
"price": 500, "price": 500,
"orig_price": 500, "orig_price": 500,
"discount_from": 1615248000000, "discount_from": 1615248000000,
"discount_to": 1615852799000 "discount_to": 1615852799000
}, { },
{
"name": "dynamix", "name": "dynamix",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "dynamix", "id": "dynamix",
"is_available": true "is_available": true
}, { },
{
"type": "character", "type": "character",
"id": "sapphire", "id": "sapphire",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 5,
"id": "core_generic",
"is_available": true
}
],
"price": 500, "price": 500,
"orig_price": 500, "orig_price": 500,
"discount_from": 1615248000000, "discount_from": 1615248000000,
"discount_to": 1615852799000 "discount_to": 1615852799000
}, { },
{
"name": "mirai", "name": "mirai",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "mirai", "id": "mirai",
"is_available": true "is_available": true
}, { },
{
"type": "character", "type": "character",
"id": "lethe", "id": "lethe",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 5,
"id": "core_generic",
"is_available": true
}
],
"price": 500, "price": 500,
"orig_price": 500, "orig_price": 500,
"discount_from": 1615248000000, "discount_from": 1615248000000,
"discount_to": 1615852799000 "discount_to": 1615852799000
}, { },
{
"name": "yugamu", "name": "yugamu",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "yugamu", "id": "yugamu",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 5,
"id": "core_generic",
"is_available": true
}
],
"price": 500, "price": 500,
"orig_price": 500, "orig_price": 500,
"discount_from": 1615248000000, "discount_from": 1615248000000,
"discount_to": 1615852799000 "discount_to": 1615852799000
}, { },
{
"name": "lanota", "name": "lanota",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "lanota", "id": "lanota",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 5,
"id": "core_generic",
"is_available": true
}
],
"price": 500, "price": 500,
"orig_price": 500, "orig_price": 500,
"discount_from": 1615248000000, "discount_from": 1615248000000,
"discount_to": 1615852799000 "discount_to": 1615852799000
}, { },
{
"name": "nijuusei", "name": "nijuusei",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "nijuusei", "id": "nijuusei",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 5,
"id": "core_generic",
"is_available": true
}
],
"price": 500, "price": 500,
"orig_price": 500, "orig_price": 500,
"discount_from": 1615248000000, "discount_from": 1615248000000,
"discount_to": 1615852799000 "discount_to": 1615852799000
}, { },
{
"name": "rei", "name": "rei",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "rei", "id": "rei",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 5,
"id": "core_generic",
"is_available": true
}
],
"price": 500, "price": 500,
"orig_price": 500, "orig_price": 500,
"discount_from": 1615248000000, "discount_from": 1615248000000,
"discount_to": 1615852799000 "discount_to": 1615852799000
}, { },
{
"name": "tonesphere", "name": "tonesphere",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "tonesphere", "id": "tonesphere",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 5,
"id": "core_generic",
"is_available": true
}
],
"price": 500, "price": 500,
"orig_price": 500, "orig_price": 500,
"discount_from": 1615248000000, "discount_from": 1615248000000,
"discount_to": 1615852799000 "discount_to": 1615852799000
}, { },
{
"name": "groovecoaster", "name": "groovecoaster",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "groovecoaster", "id": "groovecoaster",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 5,
"id": "core_generic",
"is_available": true
}
],
"price": 500, "price": 500,
"orig_price": 500, "orig_price": 500,
"discount_from": 1615248000000, "discount_from": 1615248000000,
"discount_to": 1615852799000 "discount_to": 1615852799000
}, { },
{
"name": "zettai", "name": "zettai",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "zettai", "id": "zettai",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 5,
"id": "core_generic",
"is_available": true
}
],
"price": 500, "price": 500,
"orig_price": 500, "orig_price": 500,
"discount_from": 1615248000000, "discount_from": 1615248000000,
"discount_to": 1615852799000 "discount_to": 1615852799000
}, { },
{
"name": "chunithm", "name": "chunithm",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "chunithm", "id": "chunithm",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 3,
"id": "core_generic",
"is_available": true
}
],
"price": 300, "price": 300,
"orig_price": 300 "orig_price": 300
}, { },
{
"name": "prelude", "name": "prelude",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "prelude", "id": "prelude",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 4,
"id": "core_generic",
"is_available": true
}
],
"price": 400, "price": 400,
"orig_price": 400, "orig_price": 400,
"discount_from": 1615248000000, "discount_from": 1615248000000,
"discount_to": 1615852799000 "discount_to": 1615852799000
}, { },
{
"name": "omatsuri", "name": "omatsuri",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "omatsuri", "id": "omatsuri",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 5,
"id": "core_generic",
"is_available": true
}
],
"price": 500, "price": 500,
"orig_price": 500, "orig_price": 500,
"discount_from": 1615248000000, "discount_from": 1615248000000,
"discount_to": 1615852799000 "discount_to": 1615852799000
}, { },
{
"name": "vs", "name": "vs",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "vs", "id": "vs",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 5,
"id": "core_generic",
"is_available": true
}
],
"price": 500, "price": 500,
"orig_price": 500, "orig_price": 500,
"discount_from": 1615248000000, "discount_from": 1615248000000,
"discount_to": 1615852799000 "discount_to": 1615852799000
}, { },
{
"name": "extend", "name": "extend",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "extend", "id": "extend",
"is_available": true "is_available": true
}], },
"price": 700, {
"type": "core",
"amount": 7,
"id": "core_generic",
"is_available": true
}
],
"price": 0,
"orig_price": 700, "orig_price": 700,
"discount_from": 1615248000000, "discount_from": 1615248000000,
"discount_to": 1615852799000 "discount_to": 1615852799000
}, { },
{
"name": "alice", "name": "alice",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "alice", "id": "alice",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 5,
"id": "core_generic",
"is_available": true
}
],
"orig_price": 500, "orig_price": 500,
"price": 500 "price": 500
}, { },
{
"name": "alice_append_1", "name": "alice_append_1",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "alice_append_1", "id": "alice_append_1",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 3,
"id": "core_generic",
"is_available": true
}
],
"orig_price": 300, "orig_price": 300,
"price": 300 "price": 300
}, { },
{
"name": "ongeki", "name": "ongeki",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "ongeki", "id": "ongeki",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 4,
"id": "core_generic",
"is_available": true
}
],
"orig_price": 400, "orig_price": 400,
"price": 400 "price": 400
}, { },
{
"name": "maimai", "name": "maimai",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "maimai", "id": "maimai",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 4,
"id": "core_generic",
"is_available": true
}
],
"orig_price": 400, "orig_price": 400,
"price": 400 "price": 400
}, { },
{
"name": "chunithm_append_1", "name": "chunithm_append_1",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "chunithm_append_1", "id": "chunithm_append_1",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 3,
"id": "core_generic",
"is_available": true
}
],
"orig_price": 300, "orig_price": 300,
"price": 300 "price": 300
}, { },
{
"name": "observer_append_1", "name": "observer_append_1",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "observer_append_1", "id": "observer_append_1",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 3,
"id": "core_generic",
"is_available": true
}
],
"orig_price": 300, "orig_price": 300,
"price": 300 "price": 300
}, { },
{
"name": "observer", "name": "observer",
"items": [{ "items": [
{
"type": "pack", "type": "pack",
"id": "observer", "id": "observer",
"is_available": true "is_available": true
}], },
{
"type": "core",
"amount": 5,
"id": "core_generic",
"is_available": true
}
],
"orig_price": 500, "orig_price": 500,
"price": 500 "price": 500
}] },
{
"name": "observer_append_2",
"items": [
{
"type": "pack",
"id": "observer_append_2",
"is_available": true
},
{
"type": "core",
"amount": 3,
"id": "core_generic",
"is_available": true
}
],
"orig_price": 300,
"price": 300
},
{
"name": "wacca",
"items": [
{
"type": "pack",
"id": "wacca",
"is_available": true
},
{
"type": "core",
"amount": 5,
"id": "core_generic",
"is_available": true
}
],
"orig_price": 500,
"price": 500
},
{
"name": "nijuusei_append_1",
"items": [
{
"type": "pack",
"id": "nijuusei_append_1",
"is_available": true
},
{
"type": "core",
"amount": 3,
"id": "core_generic",
"is_available": true
}
],
"orig_price": 300,
"price": 300
}
]

File diff suppressed because it is too large Load Diff

View File

@@ -251,6 +251,15 @@ def aggregate(user_id):
return jsonify(r) return jsonify(r)
@app.route(add_url_prefix('/user/me'), methods=['GET']) # 用户信息给baa查分器用的
@server.auth.auth_required(request)
def user_me(user_id):
r = server.info.arc_aggregate_small(user_id)
if r['success']:
r['value'] = r['value'][0]['value']
return jsonify(r)
@app.route(add_url_prefix('/user/me/character'), methods=['POST']) # 角色切换 @app.route(add_url_prefix('/user/me/character'), methods=['POST']) # 角色切换
@server.auth.auth_required(request) @server.auth.auth_required(request)
def character_change(user_id): def character_change(user_id):
@@ -623,7 +632,7 @@ def world_all(user_id):
}) })
@app.route(add_url_prefix('/world/map/me/'), methods=['POST']) # 进入地图 @app.route(add_url_prefix('/world/map/me'), methods=['POST']) # 进入地图
@server.auth.auth_required(request) @server.auth.auth_required(request)
def world_in(user_id): def world_in(user_id):
map_id = request.form['map_id'] map_id = request.form['map_id']

View File

@@ -25,16 +25,36 @@ def get_purchase(c, type='pack'):
for i in x: for i in x:
items = [] items = []
c.execute( c.execute(
'''select a.* from item a, purchase_item b where a.item_id=b.item_id and a.type=b.type and b.purchase_name=:name''', {'name': i[0]}) '''select a.*, b.amount from item a, purchase_item b where a.item_id=b.item_id and a.type=b.type and b.purchase_name=:name''', {'name': i[0]})
y = c.fetchall() y = c.fetchall()
t = None
if y: if y:
for j in y: for j in y:
if j[3]:
amount = j[3]
else:
amount = 1
if i[0] == j[0]:
# 物品排序,否则客户端报错
t = {
"type": j[1],
"id": j[0],
"is_available": int2b(j[2]),
'amount': amount
}
else:
items.append({ items.append({
"type": j[1], "type": j[1],
"id": j[0], "id": j[0],
"is_available": int2b(j[2]) "is_available": int2b(j[2]),
"amount": amount
}) })
if t is not None:
# 放到列表头
items = [t, items]
r = {"name": i[0], r = {"name": i[0],
"items": items, "items": items,
"price": i[1], "price": i[1],
@@ -104,7 +124,7 @@ def buy_thing(user_id, purchase_id):
} }
c.execute( c.execute(
'''select item_id, type from purchase_item where purchase_name=:a''', {'a': purchase_id}) '''select item_id, type, amount from purchase_item where purchase_name=:a''', {'a': purchase_id})
x = c.fetchall() x = c.fetchall()
if x: if x:
now = int(time.time() * 1000) now = int(time.time() * 1000)
@@ -115,7 +135,11 @@ def buy_thing(user_id, purchase_id):
if flag: if flag:
for i in x: for i in x:
server.item.claim_user_item(c, user_id, i[0], i[1]) if i[2]:
amount = i[2]
else:
amount = 1
server.item.claim_user_item(c, user_id, i[0], i[1], amount)
success_flag = True success_flag = True
else: else:

View File

@@ -286,7 +286,8 @@ def get_user_ptt_float(c, user_id) -> float:
if x != []: if x != []:
for i in x: for i in x:
sumr += float(i[0]) sumr += float(i[0])
c.execute('''select * from recent30 where user_id = :a''', {'a': user_id}) c.execute('''select * from recent30 where user_id = :a''',
{'a': user_id})
x = c.fetchone() x = c.fetchone()
if x is not None: if x is not None:
r30 = [] r30 = []
@@ -298,7 +299,8 @@ def get_user_ptt_float(c, user_id) -> float:
else: else:
r30.append(0) r30.append(0)
s30.append('') s30.append('')
r30, s30 = (list(t) for t in zip(*sorted(zip(r30, s30), reverse=True))) r30, s30 = (list(t)
for t in zip(*sorted(zip(r30, s30), reverse=True)))
songs = [] songs = []
i = 0 i = 0
while len(songs) < 10 and i <= 29 and s30[i] != '' and s30[i] is not None: while len(songs) < 10 and i <= 29 and s30[i] != '' and s30[i] is not None:
@@ -882,6 +884,36 @@ def arc_all_get(user_id):
"mi": 6, "mi": 6,
"c": True, "c": True,
"r": True "r": True
}, {
"ma": 7,
"mi": 1,
"c": True,
"r": True
}, {
"ma": 7,
"mi": 2,
"c": True,
"r": True
}, {
"ma": 7,
"mi": 3,
"c": True,
"r": True
}, {
"ma": 7,
"mi": 4,
"c": True,
"r": True
}, {
"ma": 7,
"mi": 5,
"c": True,
"r": True
}, {
"ma": 7,
"mi": 6,
"c": True,
"r": True
}, { }, {
"ma": 9, "ma": 9,
"mi": 1, "mi": 1,
@@ -913,50 +945,50 @@ def arc_all_get(user_id):
"c": True, "c": True,
"r": True "r": True
}, { }, {
"ma": 6, "ma": 10,
"mi": 1, "mi": 1,
"c": True, "c": True,
"r": True "r": True
}, { }, {
"ma": 6, "ma": 10,
"mi": 2, "mi": 2,
"c": True, "c": True,
"r": True "r": True
}, { }, {
"ma": 6, "ma": 10,
"mi": 3, "mi": 3,
"c": True, "c": True,
"r": True "r": True
}, { }, {
"ma": 7, "ma": 10,
"mi": 1,
"c": True,
"r": True
}, {
"ma": 7,
"mi": 2,
"c": True,
"r": True
}, {
"ma": 7,
"mi": 3,
"c": True,
"r": True
}, {
"ma": 7,
"mi": 4, "mi": 4,
"c": True, "c": True,
"r": True "r": True
}, { }, {
"ma": 7, "ma": 10,
"mi": 5, "mi": 5,
"c": True, "c": True,
"r": True "r": True
}, { }, {
"ma": 7, "ma": 10,
"mi": 6, "mi": 6,
"c": True, "c": True,
"r": True "r": True
}, {
"ma": 6,
"mi": 1,
"c": True,
"r": True
}, {
"ma": 6,
"mi": 2,
"c": True,
"r": True
}, {
"ma": 6,
"mi": 3,
"c": True,
"r": True
}, { }, {
"ma": 8, "ma": 8,
"mi": 1, "mi": 1,
@@ -979,42 +1011,30 @@ def arc_all_get(user_id):
}, { }, {
"unlock_key": "worldexecuteme|2|0", "unlock_key": "worldexecuteme|2|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "viyellastears|2|0",
"complete": 1
}, { }, {
"unlock_key": "viciousheroism|2|0", "unlock_key": "viciousheroism|2|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "loschen|2|0", "unlock_key": "vector|1|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "vector|2|0", "unlock_key": "valhallazero|1|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "corpssansorganes|2|0", "unlock_key": "tiferet|2|0",
"complete": 1
}, {
"unlock_key": "valhallazero|2|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "tiferet|1|0", "unlock_key": "tiferet|1|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "ouroboros|2|0", "unlock_key": "tiemedowngently|2|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "tiemedowngently|1|0", "unlock_key": "tempestissimo|2|101",
"complete": 1
}, {
"unlock_key": "aegleseeker|2|3|crystalgravity|2",
"complete": 10
}, {
"unlock_key": "tempestissimo|0|101",
"complete": 100 "complete": 100
}, { }, {
"unlock_key": "syro|2|0", "unlock_key": "tempestissimo|1|101",
"complete": 1 "complete": 100
}, { }, {
"unlock_key": "ringedgenesis|2|0", "unlock_key": "ringedgenesis|2|0",
"complete": 1 "complete": 1
@@ -1024,11 +1044,14 @@ def arc_all_get(user_id):
}, { }, {
"unlock_key": "snowwhite|2|0", "unlock_key": "snowwhite|2|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "senkyou|1|0",
"complete": 1
}, { }, {
"unlock_key": "senkyou|2|0", "unlock_key": "senkyou|2|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "senkyou|1|0", "unlock_key": "seclusion|1|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "scarletlance|2|0", "unlock_key": "scarletlance|2|0",
@@ -1054,6 +1077,12 @@ def arc_all_get(user_id):
}, { }, {
"unlock_key": "reinvent|2|0", "unlock_key": "reinvent|2|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "felis|1|0",
"complete": 1
}, {
"unlock_key": "rekkaresonance|2|0",
"complete": 1
}, { }, {
"unlock_key": "reinvent|1|0", "unlock_key": "reinvent|1|0",
"complete": 1 "complete": 1
@@ -1101,7 +1130,7 @@ def arc_all_get(user_id):
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "saikyostronger|2|3|einherjar|2", "unlock_key": "saikyostronger|2|3|einherjar|2",
"complete": 3 "complete": 6
}, { }, {
"unlock_key": "cyanine|2|0", "unlock_key": "cyanine|2|0",
"complete": 1 "complete": 1
@@ -1112,7 +1141,10 @@ def arc_all_get(user_id):
"unlock_key": "purgatorium|1|0", "unlock_key": "purgatorium|1|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "pragmatism|2|0", "unlock_key": "tiemedowngently|1|0",
"complete": 1
}, {
"unlock_key": "ouroboros|2|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "ringedgenesis|1|0", "unlock_key": "ringedgenesis|1|0",
@@ -1162,6 +1194,12 @@ def arc_all_get(user_id):
}, { }, {
"unlock_key": "melodyoflove|1|0", "unlock_key": "melodyoflove|1|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "mazymetroplex|2|0",
"complete": 1
}, {
"unlock_key": "seclusion|2|0",
"complete": 1
}, { }, {
"unlock_key": "lucifer|2|0", "unlock_key": "lucifer|2|0",
"complete": 1 "complete": 1
@@ -1177,9 +1215,6 @@ def arc_all_get(user_id):
}, { }, {
"unlock_key": "lostdesire|2|0", "unlock_key": "lostdesire|2|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "tiemedowngently|2|0",
"complete": 1
}, { }, {
"unlock_key": "solitarydream|1|0", "unlock_key": "solitarydream|1|0",
"complete": 1 "complete": 1
@@ -1192,12 +1227,30 @@ def arc_all_get(user_id):
}, { }, {
"unlock_key": "loschen|1|0", "unlock_key": "loschen|1|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "syro|2|0",
"complete": 1
}, {
"unlock_key": "aegleseeker|2|3|paperwitch|2",
"complete": 10
}, {
"unlock_key": "livefastdieyoung|1|0",
"complete": 1
}, { }, {
"unlock_key": "shadesoflight|1|0", "unlock_key": "shadesoflight|1|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "kanagawa|2|0", "unlock_key": "kanagawa|2|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "ifi|2|0",
"complete": 1
}, {
"unlock_key": "kanagawa|1|0",
"complete": 1
}, {
"unlock_key": "jump|1|0",
"complete": 1
}, { }, {
"unlock_key": "grievouslady|1|101", "unlock_key": "grievouslady|1|101",
"complete": 100 "complete": 100
@@ -1214,28 +1267,7 @@ def arc_all_get(user_id):
"unlock_key": "ignotus|2|0", "unlock_key": "ignotus|2|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "snowwhite|1|0", "unlock_key": "ignotus|1|0",
"complete": 1
}, {
"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 "complete": 1
}, { }, {
"unlock_key": "nhelv|1|0", "unlock_key": "nhelv|1|0",
@@ -1246,9 +1278,6 @@ def arc_all_get(user_id):
}, { }, {
"unlock_key": "guardina|2|0", "unlock_key": "guardina|2|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "guardina|1|0",
"complete": 1
}, { }, {
"unlock_key": "lethaeus|1|0", "unlock_key": "lethaeus|1|0",
"complete": 1 "complete": 1
@@ -1258,9 +1287,6 @@ def arc_all_get(user_id):
}, { }, {
"unlock_key": "guardina|0|0", "unlock_key": "guardina|0|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "jump|1|0",
"complete": 1
}, { }, {
"unlock_key": "oshamascramble|2|0", "unlock_key": "oshamascramble|2|0",
"complete": 1 "complete": 1
@@ -1276,9 +1302,6 @@ def arc_all_get(user_id):
}, { }, {
"unlock_key": "darakunosono|1|0", "unlock_key": "darakunosono|1|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "valhallazero|1|0",
"complete": 1
}, { }, {
"unlock_key": "grimheart|1|0", "unlock_key": "grimheart|1|0",
"complete": 1 "complete": 1
@@ -1288,27 +1311,33 @@ def arc_all_get(user_id):
}, { }, {
"unlock_key": "gothiveofra|1|0", "unlock_key": "gothiveofra|1|0",
"complete": 1 "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
}, {
"unlock_key": "gloryroad|2|0",
"complete": 1
}, { }, {
"unlock_key": "etherstrike|1|0", "unlock_key": "etherstrike|1|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "singularity|2|0", "unlock_key": "singularity|2|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "viciousheroism|1|0",
"complete": 1
}, {
"unlock_key": "axiumcrisis|1|0",
"complete": 1
}, {
"unlock_key": "gloryroad|0|0",
"complete": 1
}, {
"unlock_key": "guardina|1|0",
"complete": 1
}, {
"unlock_key": "pragmatism|2|0",
"complete": 1
}, {
"unlock_key": "oracle|2|0",
"complete": 1
}, {
"unlock_key": "genocider|2|0",
"complete": 1
}, { }, {
"unlock_key": "buchigireberserker|2|3|gothiveofra|2", "unlock_key": "buchigireberserker|2|3|gothiveofra|2",
"complete": 1 "complete": 1
@@ -1339,9 +1368,6 @@ def arc_all_get(user_id):
}, { }, {
"unlock_key": "flyburg|2|0", "unlock_key": "flyburg|2|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "oracle|2|0",
"complete": 1
}, { }, {
"unlock_key": "clotho|2|0", "unlock_key": "clotho|2|0",
"complete": 1 "complete": 1
@@ -1375,12 +1401,39 @@ def arc_all_get(user_id):
}, { }, {
"unlock_key": "espebranch|2|0", "unlock_key": "espebranch|2|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "syro|1|0",
"complete": 1
}, {
"unlock_key": "anokumene|2|0",
"complete": 1
}, {
"unlock_key": "equilibrium_challenge|2|102",
"complete": 1
}, {
"unlock_key": "overwhelm|2|0",
"complete": 1
}, {
"unlock_key": "chronostasis|2|0",
"complete": 1
}, {
"unlock_key": "gloryroad|2|0",
"complete": 1
}, {
"unlock_key": "equilibrium_challenge|1|102",
"complete": 1
}, { }, {
"unlock_key": "aterlbus|2|0", "unlock_key": "aterlbus|2|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "dreaminattraction|2|0", "unlock_key": "dreaminattraction|2|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "dreaminattraction|1|0",
"complete": 1
}, {
"unlock_key": "divinelight|2|0",
"complete": 1
}, { }, {
"unlock_key": "goodtek|2|0", "unlock_key": "goodtek|2|0",
"complete": 1 "complete": 1
@@ -1399,24 +1452,27 @@ def arc_all_get(user_id):
}, { }, {
"unlock_key": "dandelion|1|0", "unlock_key": "dandelion|1|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "aegleseeker_challenge|0|102",
"complete": 1
}, { }, {
"unlock_key": "oblivia|1|0", "unlock_key": "oblivia|1|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "cyberneciacatharsis|1|0", "unlock_key": "cyberneciacatharsis|1|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "blrink|1|0",
"complete": 1
}, {
"unlock_key": "livefastdieyoung|2|0",
"complete": 1
}, { }, {
"unlock_key": "corpssansorganes|0|0", "unlock_key": "corpssansorganes|0|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "vector|1|0",
"complete": 1
}, { }, {
"unlock_key": "conflict|2|0", "unlock_key": "conflict|2|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "ignotus|1|0",
"complete": 1
}, { }, {
"unlock_key": "monochromeprincess|1|0", "unlock_key": "monochromeprincess|1|0",
"complete": 1 "complete": 1
@@ -1468,15 +1524,27 @@ def arc_all_get(user_id):
}, { }, {
"unlock_key": "blaster|1|0", "unlock_key": "blaster|1|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "genocider|1|0",
"complete": 1
}, { }, {
"unlock_key": "rise|1|0", "unlock_key": "rise|1|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "tempestissimo|0|101",
"complete": 100
}, {
"unlock_key": "aegleseeker|2|3|crystalgravity|2",
"complete": 10
}, {
"unlock_key": "tempestissimo|3|101",
"complete": 100
}, {
"unlock_key": "cyanine|1|0",
"complete": 1
}, { }, {
"unlock_key": "axiumcrisis|2|0", "unlock_key": "axiumcrisis|2|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "tempestissimo|2|101",
"complete": 100
}, { }, {
"unlock_key": "solitarydream|2|0", "unlock_key": "solitarydream|2|0",
"complete": 1 "complete": 1
@@ -1493,16 +1561,34 @@ def arc_all_get(user_id):
"unlock_key": "linearaccelerator|1|0", "unlock_key": "linearaccelerator|1|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "tempestissimo|1|101", "unlock_key": "valhallazero|2|0",
"complete": 100 "complete": 1
}, {
"unlock_key": "corpssansorganes|2|0",
"complete": 1
}, { }, {
"unlock_key": "conflict|1|0", "unlock_key": "conflict|1|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "mazymetroplex|1|0",
"complete": 1
}, {
"unlock_key": "viyellastears|2|0",
"complete": 1
}, {
"unlock_key": "equilibrium_challenge|0|102",
"complete": 1
}, { }, {
"unlock_key": "grievouslady|0|101", "unlock_key": "grievouslady|0|101",
"complete": 100 "complete": 100
}, { }, {
"unlock_key": "dreaminattraction|1|0", "unlock_key": "snowwhite|1|0",
"complete": 1
}, {
"unlock_key": "partyvinyl|1|0",
"complete": 1
}, {
"unlock_key": "jump|2|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "saikyostronger|2|3|izana|2", "unlock_key": "saikyostronger|2|3|izana|2",
@@ -1513,33 +1599,27 @@ def arc_all_get(user_id):
}, { }, {
"unlock_key": "halcyon|1|0", "unlock_key": "halcyon|1|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "felis|1|0",
"complete": 1
}, {
"unlock_key": "overwhelm|1|0",
"complete": 1
}, {
"unlock_key": "toaliceliddell|2|0",
"complete": 1
}, {
"unlock_key": "blrink|1|0",
"complete": 1
}, { }, {
"unlock_key": "heavensdoor|2|0", "unlock_key": "heavensdoor|2|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "genesis|2|0", "unlock_key": "genesis|2|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "vector|2|0",
"complete": 1
}, {
"unlock_key": "loschen|2|0",
"complete": 1
}, {
"unlock_key": "divinelight|1|0",
"complete": 1
}, { }, {
"unlock_key": "viyellastears|1|0", "unlock_key": "viyellastears|1|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "aegleseeker|2|103", "unlock_key": "aegleseeker|2|103",
"complete": 1 "complete": 1
}, {
"unlock_key": "tiferet|2|0",
"complete": 1
}, { }, {
"unlock_key": "grimheart|2|0", "unlock_key": "grimheart|2|0",
"complete": 1 "complete": 1
@@ -1555,42 +1635,34 @@ def arc_all_get(user_id):
}, { }, {
"unlock_key": "sheriruth|2|0", "unlock_key": "sheriruth|2|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "aegleseeker|2|3|paperwitch|2",
"complete": 10
}, { }, {
"unlock_key": "sheriruth|1|0", "unlock_key": "sheriruth|1|0",
"complete": 1 "complete": 1
}, { }, {
"unlock_key": "aegleseeker|2|3|loschen|2", "unlock_key": "aegleseeker|2|3|loschen|2",
"complete": 10 "complete": 10
}, {
"unlock_key": "cyberneciacatharsis|2|0",
"complete": 1
}, { }, {
"unlock_key": "essenceoftwilight|2|0", "unlock_key": "essenceoftwilight|2|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "syro|1|0",
"complete": 1
}, {
"unlock_key": "anokumene|2|0",
"complete": 1
}, {
"unlock_key": "freefall|1|0",
"complete": 1
}, { }, {
"unlock_key": "darakunosono|2|0", "unlock_key": "darakunosono|2|0",
"complete": 1 "complete": 1
}, {
"unlock_key": "freefall|1|0",
"complete": 1
}, {
"unlock_key": "toaliceliddell|2|0",
"complete": 1
}, {
"unlock_key": "overwhelm|1|0",
"complete": 1
}, { }, {
"unlock_key": "nirvluce|2|0", "unlock_key": "nirvluce|2|0",
"complete": 1 "complete": 1
}, }, {
{ "unlock_key": "cyberneciacatharsis|2|0",
"unlock_key": "aegleseeker_challenge|0|102",
"complete": 1 "complete": 1
} }]
]
return { return {
"user_id": user_id, "user_id": user_id,

View File

@@ -9,6 +9,10 @@ import os
import time import time
ETO_UNCAP_BONUS_PROGRESS = 7
LUNA_UNCAP_BONUS_PROGRESS = 7
def int2b(x): def int2b(x):
# int与布尔值转换 # int与布尔值转换
if x is None or x == 0: if x is None or x == 0:
@@ -90,8 +94,8 @@ def get_current_map(user_id):
def get_world_all(user_id): def get_world_all(user_id):
# 读取所有地图信息并处理,返回字典列表 # 读取所有地图信息并处理,返回字典列表
re = [] re = []
with Connect() as c:
worlds = get_world_name() worlds = get_world_name()
with Connect() as c:
for map_id in worlds: for map_id in worlds:
info = get_world_info(map_id) info = get_world_info(map_id)
steps = info['steps'] steps = info['steps']
@@ -121,6 +125,23 @@ def get_world_all(user_id):
return re return re
def get_available_maps():
# 获取当前可用图(用户设定的),返回字典列表
re = []
for i in Config.AVAILABLE_MAP:
info = get_world_info(i)
del info['steps']
try:
del info['is_locked']
del info['curr_position']
del info['curr_capture']
except:
pass
re.append(info)
return re
def get_user_world(user_id, map_id): def get_user_world(user_id, map_id):
# 获取用户图信息,返回字典 # 获取用户图信息,返回字典
re = {} re = {}
@@ -346,12 +367,23 @@ def world_update(c, user_id, song_id, difficulty, rating, clear_type, beyond_gau
'a': user_id, 'b': song_id, 'c': difficulty}) 'a': user_id, 'b': song_id, 'c': difficulty})
c.execute( c.execute(
'''select character_id, max_stamina_ts, stamina from user where user_id=?''', (user_id,)) '''select character_id, max_stamina_ts, stamina, is_skill_sealed, is_char_uncapped, is_char_uncapped_override from user where user_id=?''', (user_id,))
x = c.fetchone() x = c.fetchone()
character_id = x[0] if x and x[0] is not None else 0 character_id = x[0] if x and x[0] is not None else 0
max_stamina_ts = x[1] if x and x[1] is not None else 0 max_stamina_ts = x[1] if x and x[1] is not None else 0
stamina = x[2] if x and x[2] is not None else 12 stamina = x[2] if x and x[2] is not None else 12
c.execute('''select frag1,prog1,overdrive1,frag20,prog20,overdrive20,frag30,prog30,overdrive30 from character where character_id=?''', (character_id,)) is_skill_sealed = x[3] if x and x[3] is not None else 1
skill = False
skill_uncap = False
if not is_skill_sealed:
if x:
skill = True
if x[4] is not None and x[4] == 1:
skill_uncap = True
if x[5] is not None and x[5] == 1:
skill_uncap = False
c.execute('''select frag1,prog1,overdrive1,frag20,prog20,overdrive20,frag30,prog30,overdrive30,skill_id,skill_id_uncap from character where character_id=?''', (character_id,))
x = c.fetchone() x = c.fetchone()
if Config.CHARACTER_FULL_UNLOCK: if Config.CHARACTER_FULL_UNLOCK:
@@ -372,10 +404,20 @@ def world_update(c, user_id, song_id, difficulty, rating, clear_type, beyond_gau
flag = server.character.calc_char_value(level, x[0], x[3], x[6]) flag = server.character.calc_char_value(level, x[0], x[3], x[6])
prog = server.character.calc_char_value(level, x[1], x[4], x[7]) prog = server.character.calc_char_value(level, x[1], x[4], x[7])
overdrive = server.character.calc_char_value(level, x[2], x[5], x[8]) overdrive = server.character.calc_char_value(level, x[2], x[5], x[8])
if x[9] is not None and x[9] != '' and skill:
skill = x[9]
else:
skill = None
if x[10] is not None and x[9] != '' and skill_uncap:
skill_uncap = x[10]
else:
skill_uncap = None
else: else:
flag = 0 flag = 0
prog = 0 prog = 0
overdrive = 0 overdrive = 0
skill = None
skill_uncap = None
c.execute('''select current_map from user where user_id = :a''', { c.execute('''select current_map from user where user_id = :a''', {
'a': user_id}) 'a': user_id})
@@ -407,6 +449,37 @@ def world_update(c, user_id, song_id, difficulty, rating, clear_type, beyond_gau
rewards, steps, curr_position, curr_capture, info = climb_step( rewards, steps, curr_position, curr_capture, info = climb_step(
user_id, map_id, step, y[3], y[2]) user_id, map_id, step, y[3], y[2])
# Eto和Luna的技能
character_bonus_progress = None
skill_special = ''
if skill_uncap is not None and skill_uncap and skill_uncap in ['eto_uncap', 'luna_uncap']:
skill_special = skill_uncap
elif skill is not None and skill and skill in ['eto_uncap', 'luna_uncap']:
skill_special = skill
if skill_special == 'eto_uncap':
# eto觉醒技能获得残片奖励时世界模式进度加7
fragment_flag = False
for i in rewards:
for j in i['items']:
if j['type'] == 'fragment':
fragment_flag = True
break
if fragment_flag:
break
if fragment_flag:
character_bonus_progress = ETO_UNCAP_BONUS_PROGRESS
step += character_bonus_progress * step_times
rewards, steps, curr_position, curr_capture, info = climb_step(
user_id, map_id, step, y[3], y[2]) # 二次爬梯,重新计算
elif skill_special == 'luna_uncap':
# luna觉醒技能限制格开始时世界模式进度加7
if 'restrict_id' in steps[0] and 'restrict_type' in steps[0] and steps[0]['restrict_type'] != '' and steps[0]['restrict_id'] != '':
character_bonus_progress = LUNA_UNCAP_BONUS_PROGRESS
step += character_bonus_progress * step_times
rewards, steps, curr_position, curr_capture, info = climb_step(
user_id, map_id, step, y[3], y[2]) # 二次爬梯,重新计算
for i in rewards: # 物品分发 for i in rewards: # 物品分发
for j in i['items']: for j in i['items']:
amount = j['amount'] if 'amount' in j else 1 amount = j['amount'] if 'amount' in j else 1
@@ -482,6 +555,9 @@ def world_update(c, user_id, song_id, difficulty, rating, clear_type, beyond_gau
"max_stamina_ts": max_stamina_ts "max_stamina_ts": max_stamina_ts
} }
if character_bonus_progress is not None:
re['character_bonus_progress'] = character_bonus_progress
if stamina_multiply != 1: if stamina_multiply != 1:
re['stamina_multiply'] = stamina_multiply re['stamina_multiply'] = stamina_multiply
if fragment_multiply != 100: if fragment_multiply != 100:

View File

@@ -165,7 +165,7 @@ def get_user_me(c, user_id):
stamina = x[33] stamina = x[33]
r = {"is_aprilfools": Config.IS_APRILFOOLS, r = {"is_aprilfools": Config.IS_APRILFOOLS,
"curr_available_maps": [], "curr_available_maps": server.arcworld.get_available_maps(),
"character_stats": user_character, "character_stats": user_character,
"friends": get_user_friend(c, user_id), "friends": get_user_friend(c, user_id),
"settings": { "settings": {

View File

@@ -30,10 +30,11 @@ class Connect():
return True return True
class Sql(): class Sql():
@staticmethod @staticmethod
def select(c, table_name, target_column=[], limit=-1, offset=0, query={}, sort=[]): def select(c, table_name, target_column=[], query=None):
# 执行查询单句sql语句返回fetchall数据 # 执行查询单句sql语句返回fetchall数据
# 使用准确查询,且在单表内 # 使用准确查询,且在单表内
@@ -51,9 +52,10 @@ class Sql():
where_field = [] where_field = []
where_value = [] where_value = []
for i in query: if query:
for i in query.query:
where_field.append(i) where_field.append(i)
where_value.append(query[i]) where_value.append(query.query[i])
if where_field and where_value: if where_field and where_value:
sql += ' where ' sql += ' where '
@@ -64,16 +66,17 @@ class Sql():
sql_dict[where_field[i]] = where_value[i] sql_dict[where_field[i]] = where_value[i]
sql += ' and ' + where_field[i] + '=:' + where_field[i] sql += ' and ' + where_field[i] + '=:' + where_field[i]
if sort: if query and query.sort:
sql += ' order by ' + sort[0]['column'] + ' ' + sort[0]['order'] sql += ' order by ' + \
if len(sort) >= 2: query.sort[0]['column'] + ' ' + query.sort[0]['order']
for i in range(1, len(sort)): for i in range(1, len(query.sort)):
sql += ', ' + sort[i]['column'] + ' ' + sort[i]['order'] sql += ', ' + query.sort[i]['column'] + \
' ' + query.sort[i]['order']
if limit >= 0: if query and query.limit >= 0:
sql += ' limit :limit offset :offset' sql += ' limit :limit offset :offset'
sql_dict['limit'] = limit sql_dict['limit'] = query.limit
sql_dict['offset'] = offset sql_dict['offset'] = query.offset
c.execute(sql, sql_dict) c.execute(sql, sql_dict)

View File

@@ -8,7 +8,7 @@ class Config():
主机的地址和端口号 主机的地址和端口号
Host and port of your server Host and port of your server
''' '''
HOST = '192.168.1.101' HOST = '0.0.0.0'
PORT = '80' PORT = '80'
''' '''
-------------------- --------------------
@@ -19,7 +19,7 @@ class Config():
游戏API地址前缀 游戏API地址前缀
Game API's URL prefix Game API's URL prefix
''' '''
GAME_API_PREFIX = '/kusoatui/15' GAME_API_PREFIX = '/earlgrey/16'
''' '''
-------------------- --------------------
''' '''
@@ -30,7 +30,8 @@ class Config():
Allowed game versions Allowed game versions
If it is blank, all are allowed. If it is blank, all are allowed.
''' '''
ALLOW_APPVERSION = ['3.5.3', '3.5.3c', '3.6.4', '3.6.4c'] ALLOW_APPVERSION = ['3.5.3', '3.5.3c',
'3.9.0', '3.9.0c', '3.9.1', '3.9.1c']
''' '''
-------------------- --------------------
''' '''
@@ -68,6 +69,16 @@ class Config():
-------------------- --------------------
''' '''
'''
--------------------
世界模式当前活动图设置
Current available maps in world mode
'''
AVAILABLE_MAP = [] # Ex. ['test', 'test2']
'''
--------------------
'''
''' '''
-------------------- --------------------
Web后台管理页面的用户名和密码 Web后台管理页面的用户名和密码
@@ -96,7 +107,7 @@ class Config():
API interface full control permission Token API interface full control permission Token
If you don't want to use it, leave it blank. If you don't want to use it, leave it blank.
''' '''
API_TOKEN = '123' API_TOKEN = ''
''' '''
-------------------- --------------------
''' '''
@@ -169,6 +180,18 @@ class Config():
-------------------- --------------------
''' '''
'''
--------------------
数据库更新时,是否采用最新的角色数据,如果你想采用最新的官方角色数据
注意:如果是,旧的数据将丢失;如果否,某些角色的数据变动将无法同步
If using the latest character data when updating database. If you want to only keep newest official character data, please set it `True`.
Note: If `True`, the old data will be lost; If `False`, the data changes of some characters will not be synchronized.
'''
UPDATE_WITH_NEW_CHARACTER_DATA = True
'''
--------------------
'''
''' '''
-------------------- --------------------
是否全解锁搭档 是否全解锁搭档

View File

@@ -37,6 +37,10 @@
<span class="char-num">{{x['type']}}</span> <span class="char-num">{{x['type']}}</span>
<br /> <br />
<span>Amount: </span>
<span class="char-num">{{x['amount']}}</span>
<br />
{% if not loop.last %} {% if not loop.last %}

View File

@@ -17,8 +17,11 @@
<option value='pack'>Song pack</option> <option value='pack'>Song pack</option>
<option value='world_song'>World song</option> <option value='world_song'>World song</option>
<option value='character'>Character</option> <option value='character'>Character</option>
<option value='core'>Core</option>
</select> </select>
</div> </div>
<label for="amount">Amount</label>
<input name="amount" id="amount" value="1" required>
<br /> <br />
<input type="submit" value="Add"> <input type="submit" value="Add">
</form> </form>
@@ -36,6 +39,7 @@
<option value='pack'>Pack</option> <option value='pack'>Pack</option>
<option value='world_song'>World song</option> <option value='world_song'>World song</option>
<option value='character'>Character</option> <option value='character'>Character</option>
<option value='core'>Core</option>
</select> </select>
</div> </div>
<br /> <br />

View File

@@ -418,7 +418,7 @@ def all_character():
def change_character(): def change_character():
# 修改角色数据 # 修改角色数据
skill_ids = ['No_skill', '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', skill_ids = ['No_skill', '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', 'frags_kou', 'visual_ink', 'shirabe_entry_fee', 'frags_yume', 'note_mirror|visual_hide_far', 'frags_ongeki', 'gauge_areus', 'gauge_seele', 'gauge_isabelle', 'gauge_exhaustion', 'skill_lagrange', 'gauge_safe_10', 'frags_nami'] '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', 'frags_kou', 'visual_ink', 'shirabe_entry_fee', 'frags_yume', 'note_mirror|visual_hide_far', 'frags_ongeki', 'gauge_areus', 'gauge_seele', 'gauge_isabelle', 'gauge_exhaustion', 'skill_lagrange', 'gauge_safe_10', 'frags_nami', 'skill_elizabeth', 'skill_lily', 'skill_kanae_midsummer', 'eto_uncap', 'luna_uncap']
return render_template('web/changechar.html', skill_ids=skill_ids) return render_template('web/changechar.html', skill_ids=skill_ids)
@@ -777,12 +777,12 @@ def change_purchase():
discount_from = int(time.mktime(time.strptime( discount_from = int(time.mktime(time.strptime(
discount_from, "%Y-%m-%dT%H:%M"))) * 1000 discount_from, "%Y-%m-%dT%H:%M"))) * 1000
else: else:
discount_from = None discount_from = -1
if discount_to: if discount_to:
discount_to = int(time.mktime(time.strptime( discount_to = int(time.mktime(time.strptime(
discount_to, "%Y-%m-%dT%H:%M"))) * 1000 discount_to, "%Y-%m-%dT%H:%M"))) * 1000
else: else:
discount_to = None discount_to = -1
except: except:
error = '数据错误 Wrong data.' error = '数据错误 Wrong data.'
flash(error) flash(error)
@@ -847,6 +847,7 @@ def change_purchase_item():
purchase_name = request.form['purchase_name'] purchase_name = request.form['purchase_name']
item_id = request.form['item_id'] item_id = request.form['item_id']
item_type = request.form['type'] item_type = request.form['type']
amount = int(request.form['amount'])
except: except:
error = '数据错误 Wrong data.' error = '数据错误 Wrong data.'
flash(error) flash(error)
@@ -862,8 +863,8 @@ def change_purchase_item():
c.execute( c.execute(
'''select exists(select * from item where item_id=? and type=?)''', (item_id, item_type)) '''select exists(select * from item where item_id=? and type=?)''', (item_id, item_type))
if c.fetchone() == (1,): if c.fetchone() == (1,):
c.execute('''insert into purchase_item values(?,?,?)''', c.execute('''insert into purchase_item values(?,?,?,?)''',
(purchase_name, item_id, item_type)) (purchase_name, item_id, item_type, amount))
flash('''购买项目的物品添加成功 Successfully add the purchase's item.''') flash('''购买项目的物品添加成功 Successfully add the purchase's item.''')
else: else:
error = '''物品不存在 The item does not exist.''' error = '''物品不存在 The item does not exist.'''

View File

@@ -5,6 +5,7 @@ import json
import server.arcscore import server.arcscore
import hashlib import hashlib
from random import Random from random import Random
from setting import Config
def int2b(x): def int2b(x):
@@ -204,13 +205,13 @@ def update_database():
update_one_table(c1, c2, 'user_role') update_one_table(c1, c2, 'user_role')
update_one_table(c1, c2, 'power') update_one_table(c1, c2, 'power')
update_one_table(c1, c2, 'role_power') update_one_table(c1, c2, 'role_power')
update_one_table(c1, c2, 'api_auth') update_one_table(c1, c2, 'api_login')
update_one_table(c1, c2, 'user_char') update_one_table(c1, c2, 'user_char')
# ---You can comment this line by yourself, if you want to only keep newest official character data. if not Config.UPDATE_WITH_NEW_CHARACTER_DATA:
update_one_table(c1, c2, 'character') update_one_table(c1, c2, 'character')
# ---
update_user_char(c2) # 更新user_char_full update_user_char(c2) # 更新user_char_full
os.remove('database/old_arcaea_database.db') os.remove('database/old_arcaea_database.db')
@@ -301,7 +302,7 @@ def get_all_purchase():
items = [] items = []
if y: if y:
for j in y: for j in y:
items.append({'item_id': j[1], 'type': j[2]}) items.append({'item_id': j[1], 'type': j[2], 'amount':j[3]})
re.append({'purchase_name': i[0], re.append({'purchase_name': i[0],
'price': i[1], 'price': i[1],